1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #if !defined(MediaMetadataManager_h__)
8 # define MediaMetadataManager_h__
10 # include "mozilla/AbstractThread.h"
11 # include "mozilla/LinkedList.h"
13 # include "MediaEventSource.h"
14 # include "TimeUnits.h"
15 # include "VideoUtils.h"
20 typedef MediaEventProducerExc
<TimedMetadata
> TimedMetadataEventProducer
;
21 typedef MediaEventSourceExc
<TimedMetadata
> TimedMetadataEventSource
;
23 // A struct that contains the metadata of a media, and the time at which those
24 // metadata should start to be reported.
25 class TimedMetadata
: public LinkedListElement
<TimedMetadata
> {
27 TimedMetadata(const media::TimeUnit
& aPublishTime
,
28 UniquePtr
<MetadataTags
>&& aTags
, UniquePtr
<MediaInfo
>&& aInfo
)
29 : mPublishTime(aPublishTime
),
30 mTags(std::move(aTags
)),
31 mInfo(std::move(aInfo
)) {}
33 // Define our move constructor because we don't want to move the members of
34 // LinkedListElement to change the list.
35 TimedMetadata(TimedMetadata
&& aOther
)
36 : mPublishTime(aOther
.mPublishTime
),
37 mTags(std::move(aOther
.mTags
)),
38 mInfo(std::move(aOther
.mInfo
)) {}
40 // The time, in microseconds, at which those metadata should be available.
41 media::TimeUnit mPublishTime
;
42 // The metadata. The ownership is transfered to the element when dispatching
43 // to the main threads.
44 UniquePtr
<MetadataTags
> mTags
;
45 // The media info, including the info of audio tracks and video tracks.
46 // The ownership is transfered to MediaDecoder when dispatching to the
48 UniquePtr
<MediaInfo
> mInfo
;
51 // This class encapsulate the logic to give the metadata from the reader to
52 // the content, at the right time.
53 class MediaMetadataManager
{
55 ~MediaMetadataManager() {
56 TimedMetadata
* element
;
57 while ((element
= mMetadataQueue
.popFirst()) != nullptr) {
62 // Connect to an event source to receive TimedMetadata events.
63 void Connect(TimedMetadataEventSource
& aEvent
, AbstractThread
* aThread
) {
65 aEvent
.Connect(aThread
, this, &MediaMetadataManager::OnMetadataQueued
);
68 // Stop receiving TimedMetadata events.
69 void Disconnect() { mListener
.Disconnect(); }
71 // Return an event source through which we will send TimedMetadata events
72 // when playback position reaches the publish time.
73 TimedMetadataEventSource
& TimedMetadataEvent() { return mTimedMetadataEvent
; }
75 void DispatchMetadataIfNeeded(const media::TimeUnit
& aCurrentTime
) {
76 TimedMetadata
* metadata
= mMetadataQueue
.getFirst();
77 while (metadata
&& aCurrentTime
>= metadata
->mPublishTime
) {
78 // Our listener will figure out what to do with TimedMetadata.
79 mTimedMetadataEvent
.Notify(std::move(*metadata
));
80 delete mMetadataQueue
.popFirst();
81 metadata
= mMetadataQueue
.getFirst();
86 void OnMetadataQueued(TimedMetadata
&& aMetadata
) {
87 mMetadataQueue
.insertBack(new TimedMetadata(std::move(aMetadata
)));
90 LinkedList
<TimedMetadata
> mMetadataQueue
;
91 MediaEventListener mListener
;
92 TimedMetadataEventProducer mTimedMetadataEvent
;
95 } // namespace mozilla