gecko/content/media/dash/DASHReader.h
Chris Pearce 216fe28466 Bug 811381 - Remove ns prefix from media code. r=roc
--HG--
rename : content/media/nsAudioAvailableEventManager.cpp => content/media/AudioAvailableEventManager.cpp
rename : content/media/nsAudioAvailableEventManager.h => content/media/AudioAvailableEventManager.h
rename : content/media/nsAudioStream.cpp => content/media/AudioStream.cpp
rename : content/media/nsAudioStream.h => content/media/AudioStream.h
rename : content/media/nsMediaCache.cpp => content/media/MediaCache.cpp
rename : content/media/nsMediaCache.h => content/media/MediaCache.h
rename : content/media/nsBuiltinDecoder.cpp => content/media/MediaDecoder.cpp
rename : content/media/nsBuiltinDecoder.h => content/media/MediaDecoder.h
rename : content/media/nsBuiltinDecoderReader.cpp => content/media/MediaDecoderReader.cpp
rename : content/media/nsBuiltinDecoderReader.h => content/media/MediaDecoderReader.h
rename : content/media/nsBuiltinDecoderStateMachine.cpp => content/media/MediaDecoderStateMachine.cpp
rename : content/media/nsBuiltinDecoderStateMachine.h => content/media/MediaDecoderStateMachine.h
rename : content/media/dash/nsDASHDecoder.cpp => content/media/dash/DASHDecoder.cpp
rename : content/media/dash/nsDASHDecoder.h => content/media/dash/DASHDecoder.h
rename : content/media/dash/nsDASHReader.cpp => content/media/dash/DASHReader.cpp
rename : content/media/dash/nsDASHReader.h => content/media/dash/DASHReader.h
rename : content/media/dash/nsDASHRepDecoder.cpp => content/media/dash/DASHRepDecoder.cpp
rename : content/media/dash/nsDASHRepDecoder.h => content/media/dash/DASHRepDecoder.h
rename : content/media/gstreamer/nsGStreamerDecoder.cpp => content/media/gstreamer/GStreamerDecoder.cpp
rename : content/media/gstreamer/nsGStreamerDecoder.h => content/media/gstreamer/GStreamerDecoder.h
rename : content/media/gstreamer/nsGStreamerReader.cpp => content/media/gstreamer/GStreamerReader.cpp
rename : content/media/gstreamer/nsGStreamerReader.h => content/media/gstreamer/GStreamerReader.h
rename : content/media/ogg/nsOggCodecState.cpp => content/media/ogg/OggCodecState.cpp
rename : content/media/ogg/nsOggCodecState.h => content/media/ogg/OggCodecState.h
rename : content/media/ogg/nsOggDecoder.cpp => content/media/ogg/OggDecoder.cpp
rename : content/media/ogg/nsOggDecoder.h => content/media/ogg/OggDecoder.h
rename : content/media/ogg/nsOggReader.cpp => content/media/ogg/OggReader.cpp
rename : content/media/ogg/nsOggReader.h => content/media/ogg/OggReader.h
rename : content/media/omx/nsMediaOmxDecoder.cpp => content/media/omx/MediaOmxDecoder.cpp
rename : content/media/omx/nsMediaOmxDecoder.h => content/media/omx/MediaOmxDecoder.h
rename : content/media/omx/nsMediaOmxReader.cpp => content/media/omx/MediaOmxReader.cpp
rename : content/media/omx/nsMediaOmxReader.h => content/media/omx/MediaOmxReader.h
rename : content/media/plugins/nsMediaPluginDecoder.cpp => content/media/plugins/MediaPluginDecoder.cpp
rename : content/media/plugins/nsMediaPluginDecoder.h => content/media/plugins/MediaPluginDecoder.h
rename : content/media/plugins/nsMediaPluginHost.cpp => content/media/plugins/MediaPluginHost.cpp
rename : content/media/plugins/nsMediaPluginHost.h => content/media/plugins/MediaPluginHost.h
rename : content/media/plugins/nsMediaPluginReader.cpp => content/media/plugins/MediaPluginReader.cpp
rename : content/media/plugins/nsMediaPluginReader.h => content/media/plugins/MediaPluginReader.h
rename : content/media/raw/nsRawDecoder.cpp => content/media/raw/RawDecoder.cpp
rename : content/media/raw/nsRawDecoder.h => content/media/raw/RawDecoder.h
rename : content/media/raw/nsRawReader.cpp => content/media/raw/RawReader.cpp
rename : content/media/raw/nsRawReader.h => content/media/raw/RawReader.h
rename : content/media/raw/nsRawStructs.h => content/media/raw/RawStructs.h
rename : content/media/wave/nsWaveDecoder.cpp => content/media/wave/WaveDecoder.cpp
rename : content/media/wave/nsWaveDecoder.h => content/media/wave/WaveDecoder.h
rename : content/media/wave/nsWaveReader.cpp => content/media/wave/WaveReader.cpp
rename : content/media/wave/nsWaveReader.h => content/media/wave/WaveReader.h
rename : content/media/webm/nsWebMBufferedParser.cpp => content/media/webm/WebMBufferedParser.cpp
rename : content/media/webm/nsWebMBufferedParser.h => content/media/webm/WebMBufferedParser.h
rename : content/media/webm/nsWebMDecoder.cpp => content/media/webm/WebMDecoder.cpp
rename : content/media/webm/nsWebMDecoder.h => content/media/webm/WebMDecoder.h
rename : content/media/webm/nsWebMReader.cpp => content/media/webm/WebMReader.cpp
rename : content/media/webm/nsWebMReader.h => content/media/webm/WebMReader.h
2012-11-14 11:46:40 -08:00

316 lines
11 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form Is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* DASH - Dynamic Adaptive Streaming over HTTP
*
* DASH is an adaptive bitrate streaming technology where a multimedia file is
* partitioned into one or more segments and delivered to a client using HTTP.
*
* see DASHDecoder.cpp for comments on DASH object interaction
*/
#if !defined(DASHReader_h_)
#define DASHReader_h_
#include "MediaDecoderReader.h"
namespace mozilla {
class DASHReader : public MediaDecoderReader
{
public:
DASHReader(MediaDecoder* aDecoder) :
MediaDecoderReader(aDecoder),
mReadMetadataMonitor("media.dashreader.readmetadata"),
mReadyToReadMetadata(false),
mDecoderIsShuttingDown(false),
mAudioReader(this),
mVideoReader(this),
mAudioReaders(this),
mVideoReaders(this)
{
MOZ_COUNT_CTOR(DASHReader);
}
~DASHReader()
{
MOZ_COUNT_DTOR(DASHReader);
}
// Adds a pointer to a audio/video reader for a media |Representation|.
// Called on the main thread only.
void AddAudioReader(MediaDecoderReader* aAudioReader);
void AddVideoReader(MediaDecoderReader* aVideoReader);
// Waits for metadata bytes to be downloaded, then reads and parses them.
// Called on the decode thread only.
nsresult ReadMetadata(nsVideoInfo* aInfo,
MetadataTags** aTags);
// Waits for |ReadyToReadMetadata| or |NotifyDecoderShuttingDown|
// notification, whichever comes first. Ensures no attempt to read metadata
// during |DASHDecoder|::|Shutdown|. Called on decode thread only.
nsresult WaitForMetadata() {
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
ReentrantMonitorAutoEnter mon(mReadMetadataMonitor);
while (true) {
// Abort if the decoder has started shutting down.
if (mDecoderIsShuttingDown) {
return NS_ERROR_ABORT;
} else if (mReadyToReadMetadata) {
break;
}
mon.Wait();
}
return NS_OK;
}
// Called on the main thread by |DASHDecoder| to notify that metadata bytes
// have been downloaded.
void ReadyToReadMetadata() {
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
ReentrantMonitorAutoEnter mon(mReadMetadataMonitor);
mReadyToReadMetadata = true;
mon.NotifyAll();
}
// Called on the main thread by |DASHDecoder| when it starts Shutdown. Will
// wake metadata monitor if waiting for a silent return from |ReadMetadata|.
void NotifyDecoderShuttingDown() {
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
ReentrantMonitorAutoEnter metadataMon(mReadMetadataMonitor);
mDecoderIsShuttingDown = true;
// Notify |ReadMetadata| of the shutdown if it's waiting.
metadataMon.NotifyAll();
}
// Audio/video status are dependent on the presence of audio/video readers.
// Call on decode thread only.
bool HasAudio() {
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
return mAudioReader ? mAudioReader->HasAudio() : false;
}
bool HasVideo() {
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
return mVideoReader ? mVideoReader->HasVideo() : false;
}
// Returns references to the audio/video queues of sub-readers. Called on
// decode, state machine and audio threads.
MediaQueue<AudioData>& AudioQueue();
MediaQueue<VideoData>& VideoQueue();
// Called from MediaDecoderStateMachine on the main thread.
nsresult Init(MediaDecoderReader* aCloneDonor);
// Used by |MediaMemoryReporter|.
int64_t VideoQueueMemoryInUse();
int64_t AudioQueueMemoryInUse();
// Called on the decode thread.
bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold);
bool DecodeAudioData();
// Converts seek time to byte offset. Called on the decode thread only.
nsresult Seek(int64_t aTime,
int64_t aStartTime,
int64_t aEndTime,
int64_t aCurrentTime);
// Called by state machine on multiple threads.
nsresult GetBuffered(nsTimeRanges* aBuffered, int64_t aStartTime);
// Called on the state machine or decode threads.
VideoData* FindStartTime(int64_t& aOutStartTime);
// Call by state machine on multiple threads.
bool IsSeekableInBufferedRanges();
private:
// Similar to |ReentrantMonitorAutoEnter|, this class enters the supplied
// monitor in its constructor, but only if the conditional value |aEnter| is
// true. Used here to allow read access on the sub-readers' owning thread,
// i.e. the decode thread, while locking write accesses from all threads,
// and read accesses from non-decode threads.
class ReentrantMonitorConditionallyEnter
{
public:
ReentrantMonitorConditionallyEnter(bool aEnter,
ReentrantMonitor &aReentrantMonitor) :
mReentrantMonitor(nullptr)
{
MOZ_COUNT_CTOR(DASHReader::ReentrantMonitorConditionallyEnter);
if (aEnter) {
mReentrantMonitor = &aReentrantMonitor;
NS_ASSERTION(mReentrantMonitor, "null monitor");
mReentrantMonitor->Enter();
}
}
~ReentrantMonitorConditionallyEnter(void)
{
if (mReentrantMonitor) {
mReentrantMonitor->Exit();
}
MOZ_COUNT_DTOR(DASHReader::ReentrantMonitorConditionallyEnter);
}
private:
// Restrict to constructor and destructor defined above.
ReentrantMonitorConditionallyEnter();
ReentrantMonitorConditionallyEnter(const ReentrantMonitorConditionallyEnter&);
ReentrantMonitorConditionallyEnter& operator =(const ReentrantMonitorConditionallyEnter&);
static void* operator new(size_t) CPP_THROW_NEW;
static void operator delete(void*);
// Ptr to the |ReentrantMonitor| object. Null if |aEnter| in constructor
// was false.
ReentrantMonitor* mReentrantMonitor;
};
// Monitor and booleans used to wait for metadata bytes to be downloaded, and
// skip reading metadata if |DASHDecoder|'s shutdown is in progress.
ReentrantMonitor mReadMetadataMonitor;
bool mReadyToReadMetadata;
bool mDecoderIsShuttingDown;
// Wrapper class protecting accesses to sub-readers. Asserts that the
// decoder monitor has been entered for write access on all threads and read
// access on all threads that are not the decode thread. Read access on the
// decode thread does not need to be protected.
class MonitoredSubReader
{
public:
// Main constructor takes a pointer to the owning |DASHReader| to verify
// correct entry into the decoder's |ReentrantMonitor|.
MonitoredSubReader(DASHReader* aReader) :
mReader(aReader),
mSubReader(nullptr)
{
MOZ_COUNT_CTOR(DASHReader::MonitoredSubReader);
NS_ASSERTION(mReader, "Reader is null!");
}
// Note: |mSubReader|'s refcount will be decremented in this destructor.
~MonitoredSubReader()
{
MOZ_COUNT_DTOR(DASHReader::MonitoredSubReader);
}
// Override '=' to always assert thread is "in monitor" for writes/changes
// to |mSubReader|.
MonitoredSubReader& operator=(MediaDecoderReader* rhs)
{
NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
mSubReader = rhs;
return *this;
}
// Override '*' to assert threads other than the decode thread are "in
// monitor" for ptr reads.
operator MediaDecoderReader*() const
{
NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
if (!mReader->GetDecoder()->OnDecodeThread()) {
mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
}
return mSubReader;
}
// Override '->' to assert threads other than the decode thread are "in
// monitor" for |mSubReader| function calls.
MediaDecoderReader* operator->() const
{
return *this;
}
private:
// Pointer to |DASHReader| object which owns this |MonitoredSubReader|.
DASHReader* mReader;
// Ref ptr to the sub reader.
nsRefPtr<MediaDecoderReader> mSubReader;
};
// Wrapped ref ptrs to current sub-readers of individual media
// |Representation|s. Decoder monitor must be entered for write access on all
// threads and read access on all threads that are not the decode thread.
// Read access on the decode thread does not need to be protected.
// Note: |MonitoredSubReader| class will assert correct monitor use.
MonitoredSubReader mAudioReader;
MonitoredSubReader mVideoReader;
// Wrapper class protecting accesses to sub-reader list. Asserts that the
// decoder monitor has been entered for write access on all threads and read
// access on all threads that are not the decode thread. Read access on the
// decode thread does not need to be protected.
// Note: Elems accessed via operator[] are not protected with monitor
// assertion checks once obtained.
class MonitoredSubReaderList
{
public:
// Main constructor takes a pointer to the owning |DASHReader| to verify
// correct entry into the decoder's |ReentrantMonitor|.
MonitoredSubReaderList(DASHReader* aReader) :
mReader(aReader)
{
MOZ_COUNT_CTOR(DASHReader::MonitoredSubReaderList);
NS_ASSERTION(mReader, "Reader is null!");
}
// Note: Elements in |mSubReaderList| will have their refcounts decremented
// in this destructor.
~MonitoredSubReaderList()
{
MOZ_COUNT_DTOR(DASHReader::MonitoredSubReaderList);
}
// Returns Length of |mSubReaderList| array. Will assert threads other than
// the decode thread are "in monitor".
uint32_t Length() const
{
NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
if (!mReader->GetDecoder()->OnDecodeThread()) {
mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
}
return mSubReaderList.Length();
}
// Override '[]' to assert threads other than the decode thread are "in
// monitor" for accessing individual elems. Note: elems returned do not
// have monitor assertions builtin like |MonitoredSubReader| objects.
nsRefPtr<MediaDecoderReader>& operator[](uint32_t i)
{
NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
if (!mReader->GetDecoder()->OnDecodeThread()) {
mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
}
return mSubReaderList[i];
}
// Appends a reader to the end of |mSubReaderList|. Will always assert that
// the thread is "in monitor".
void
AppendElement(MediaDecoderReader* aReader)
{
NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
mSubReaderList.AppendElement(aReader);
}
private:
// Pointer to |DASHReader| object which owns this |MonitoredSubReader|.
DASHReader* mReader;
// Ref ptrs to the sub readers.
nsTArray<nsRefPtr<MediaDecoderReader> > mSubReaderList;
};
// Ref ptrs to all sub-readers of individual media |Representation|s.
// Decoder monitor must be entered for write access on all threads and read
// access on all threads that are not the decode thread. Read acces on the
// decode thread does not need to be protected.
MonitoredSubReaderList mAudioReaders;
MonitoredSubReaderList mVideoReaders;
};
} // namespace mozilla
#endif