Line data Source code
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/. */
6 :
7 : #if !defined(MediaMetadataManager_h__)
8 : #define MediaMetadataManager_h__
9 :
10 : #include "mozilla/AbstractThread.h"
11 : #include "mozilla/LinkedList.h"
12 :
13 : #include "nsAutoPtr.h"
14 : #include "AbstractMediaDecoder.h"
15 : #include "MediaEventSource.h"
16 : #include "TimeUnits.h"
17 : #include "VideoUtils.h"
18 :
19 : namespace mozilla {
20 :
21 : class TimedMetadata;
22 : typedef MediaEventProducerExc<TimedMetadata> TimedMetadataEventProducer;
23 : typedef MediaEventSourceExc<TimedMetadata> TimedMetadataEventSource;
24 :
25 : // A struct that contains the metadata of a media, and the time at which those
26 : // metadata should start to be reported.
27 0 : class TimedMetadata : public LinkedListElement<TimedMetadata> {
28 : public:
29 0 : TimedMetadata(const media::TimeUnit& aPublishTime,
30 : nsAutoPtr<MetadataTags>&& aTags,
31 : nsAutoPtr<MediaInfo>&& aInfo)
32 0 : : mPublishTime(aPublishTime)
33 0 : , mTags(Move(aTags))
34 0 : , mInfo(Move(aInfo)) {}
35 :
36 : // Define our move constructor because we don't want to move the members of
37 : // LinkedListElement to change the list.
38 0 : TimedMetadata(TimedMetadata&& aOther)
39 0 : : mPublishTime(aOther.mPublishTime)
40 0 : , mTags(Move(aOther.mTags))
41 0 : , mInfo(Move(aOther.mInfo)) {}
42 :
43 : // The time, in microseconds, at which those metadata should be available.
44 : media::TimeUnit mPublishTime;
45 : // The metadata. The ownership is transfered to the element when dispatching to
46 : // the main threads.
47 : nsAutoPtr<MetadataTags> mTags;
48 : // The media info, including the info of audio tracks and video tracks.
49 : // The ownership is transfered to MediaDecoder when dispatching to the
50 : // main thread.
51 : nsAutoPtr<MediaInfo> mInfo;
52 : };
53 :
54 : // This class encapsulate the logic to give the metadata from the reader to
55 : // the content, at the right time.
56 0 : class MediaMetadataManager {
57 : public:
58 0 : ~MediaMetadataManager() {
59 : TimedMetadata* element;
60 0 : while((element = mMetadataQueue.popFirst()) != nullptr) {
61 0 : delete element;
62 : }
63 0 : }
64 :
65 : // Connect to an event source to receive TimedMetadata events.
66 0 : void Connect(TimedMetadataEventSource& aEvent, AbstractThread* aThread) {
67 0 : mListener = aEvent.Connect(
68 0 : aThread, this, &MediaMetadataManager::OnMetadataQueued);
69 0 : }
70 :
71 : // Stop receiving TimedMetadata events.
72 0 : void Disconnect() {
73 0 : mListener.Disconnect();
74 0 : }
75 :
76 : // Return an event source through which we will send TimedMetadata events
77 : // when playback position reaches the publish time.
78 0 : TimedMetadataEventSource& TimedMetadataEvent() {
79 0 : return mTimedMetadataEvent;
80 : }
81 :
82 0 : void DispatchMetadataIfNeeded(const media::TimeUnit& aCurrentTime) {
83 0 : TimedMetadata* metadata = mMetadataQueue.getFirst();
84 0 : while (metadata && aCurrentTime >= metadata->mPublishTime) {
85 : // Our listener will figure out what to do with TimedMetadata.
86 0 : mTimedMetadataEvent.Notify(Move(*metadata));
87 0 : delete mMetadataQueue.popFirst();
88 0 : metadata = mMetadataQueue.getFirst();
89 : }
90 0 : }
91 :
92 : protected:
93 0 : void OnMetadataQueued(TimedMetadata&& aMetadata) {
94 0 : mMetadataQueue.insertBack(new TimedMetadata(Move(aMetadata)));
95 0 : }
96 :
97 : LinkedList<TimedMetadata> mMetadataQueue;
98 : MediaEventListener mListener;
99 : TimedMetadataEventProducer mTimedMetadataEvent;
100 : };
101 :
102 : } // namespace mozilla
103 :
104 : #endif
|