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