Backed out changesets ae63e2dda6e0, a9ca0113db3c, and d0a6757e24bd (bug 1097823) for bustage.

DONTBUILD CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-12-08 15:00:02 -05:00
parent 2899d41945
commit b04ae532a6
14 changed files with 50 additions and 415 deletions

View File

@ -20,6 +20,8 @@ class MediaData;
template<class Target>
class MediaDataDecodedListener : public RequestSampleCallback {
public:
using RequestSampleCallback::NotDecodedReason;
MediaDataDecodedListener(Target* aTarget,
MediaTaskQueue* aTaskQueue)
: mMonitor("MediaDataDecodedListener")
@ -50,8 +52,7 @@ public:
mTaskQueue->Dispatch(task);
}
virtual void OnNotDecoded(MediaData::Type aType,
MediaDecoderReader::NotDecodedReason aReason) MOZ_OVERRIDE {
virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) MOZ_OVERRIDE {
MonitorAutoLock lock(mMonitor);
if (!mTarget || !mTaskQueue) {
// We've been shutdown, abort.
@ -132,7 +133,7 @@ private:
class DeliverNotDecodedTask : public nsRunnable {
public:
DeliverNotDecodedTask(MediaData::Type aType,
MediaDecoderReader::NotDecodedReason aReason,
RequestSampleCallback::NotDecodedReason aReason,
Target* aTarget)
: mType(aType)
, mReason(aReason)
@ -152,7 +153,7 @@ private:
}
private:
MediaData::Type mType;
MediaDecoderReader::NotDecodedReason mReason;
RequestSampleCallback::NotDecodedReason mReason;
RefPtr<Target> mTarget;
};

View File

@ -461,6 +461,7 @@ MediaDecoder::MediaDecoder() :
gMediaDecoderLog = PR_NewLogModule("MediaDecoder");
}
#endif
mAudioChannel = AudioChannelService::GetDefaultAudioChannel();
}

View File

@ -27,16 +27,6 @@ extern PRLogModuleInfo* gMediaDecoderLog;
#define DECODER_LOG(x, ...)
#endif
PRLogModuleInfo* gMediaPromiseLog;
void
EnsureMediaPromiseLog()
{
if (!gMediaPromiseLog) {
gMediaPromiseLog = PR_NewLogModule("MediaPromise");
}
}
class VideoQueueMemoryFunctor : public nsDequeFunctor {
public:
VideoQueueMemoryFunctor() : mSize(0) {}
@ -79,7 +69,6 @@ MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder)
, mShutdown(false)
{
MOZ_COUNT_CTOR(MediaDecoderReader);
EnsureMediaPromiseLog();
}
MediaDecoderReader::~MediaDecoderReader()
@ -215,7 +204,7 @@ MediaDecoderReader::RequestVideoData(bool aSkipToNextKeyframe,
}
GetCallback()->OnVideoDecoded(v);
} else if (VideoQueue().IsFinished()) {
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, END_OF_STREAM);
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::END_OF_STREAM);
}
}
@ -248,7 +237,7 @@ MediaDecoderReader::RequestAudioData()
GetCallback()->OnAudioDecoded(a);
return;
} else if (AudioQueue().IsFinished()) {
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, END_OF_STREAM);
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::END_OF_STREAM);
return;
}
}
@ -318,13 +307,12 @@ AudioDecodeRendezvous::OnAudioDecoded(AudioData* aSample)
}
void
AudioDecodeRendezvous::OnNotDecoded(MediaData::Type aType,
MediaDecoderReader::NotDecodedReason aReason)
AudioDecodeRendezvous::OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason)
{
MOZ_ASSERT(aType == MediaData::AUDIO_DATA);
MonitorAutoLock mon(mMonitor);
mSample = nullptr;
mStatus = aReason == MediaDecoderReader::DECODE_ERROR ? NS_ERROR_FAILURE : NS_OK;
mStatus = aReason == DECODE_ERROR ? NS_ERROR_FAILURE : NS_OK;
mHaveResult = true;
mon.NotifyAll();
}

View File

@ -30,13 +30,6 @@ class SharedDecoderManager;
// be accessed on the decode task queue.
class MediaDecoderReader {
public:
enum NotDecodedReason {
END_OF_STREAM,
DECODE_ERROR,
WAITING_FOR_DATA,
CANCELED
};
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
explicit MediaDecoderReader(AbstractMediaDecoder* aDecoder);
@ -297,6 +290,13 @@ class RequestSampleCallback {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RequestSampleCallback)
enum NotDecodedReason {
END_OF_STREAM,
DECODE_ERROR,
WAITING_FOR_DATA,
CANCELED
};
// Receives the result of a RequestAudioData() call.
virtual void OnAudioDecoded(AudioData* aSample) = 0;
@ -305,8 +305,7 @@ public:
// Called when a RequestAudioData() or RequestVideoData() call can't be
// fulfiled. The reason is passed as aReason.
virtual void OnNotDecoded(MediaData::Type aType,
MediaDecoderReader::NotDecodedReason aReason) = 0;
virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) = 0;
virtual void OnSeekCompleted(nsresult aResult) = 0;
@ -323,6 +322,8 @@ protected:
// model of the MediaDecoderReader to a synchronous model.
class AudioDecodeRendezvous : public RequestSampleCallback {
public:
using RequestSampleCallback::NotDecodedReason;
AudioDecodeRendezvous();
~AudioDecodeRendezvous();
@ -330,8 +331,7 @@ public:
// Note: aSample is null at end of stream.
virtual void OnAudioDecoded(AudioData* aSample) MOZ_OVERRIDE;
virtual void OnVideoDecoded(VideoData* aSample) MOZ_OVERRIDE {}
virtual void OnNotDecoded(MediaData::Type aType,
MediaDecoderReader::NotDecodedReason aReason) MOZ_OVERRIDE;
virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) MOZ_OVERRIDE;
virtual void OnSeekCompleted(nsresult aResult) MOZ_OVERRIDE {};
virtual void BreakCycles() MOZ_OVERRIDE {};
void Reset();

View File

@ -805,7 +805,7 @@ MediaDecoderStateMachine::Push(VideoData* aSample)
void
MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
MediaDecoderReader::NotDecodedReason aReason)
RequestSampleCallback::NotDecodedReason aReason)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
SAMPLE_LOG("OnNotDecoded (aType=%u, aReason=%u)", aType, aReason);
@ -820,7 +820,7 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
}
// If this is a decode error, delegate to the generic error path.
if (aReason == MediaDecoderReader::DECODE_ERROR) {
if (aReason == RequestSampleCallback::DECODE_ERROR) {
DecodeError();
return;
}
@ -828,7 +828,7 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
// If the decoder is waiting for data, we need to make sure that the requests
// are cleared, which happened above. Additionally, if we're out of decoded
// samples, we need to switch to buffering mode.
if (aReason == MediaDecoderReader::WAITING_FOR_DATA) {
if (aReason == RequestSampleCallback::WAITING_FOR_DATA) {
bool outOfSamples = isAudio ? !AudioQueue().GetSize() : !VideoQueue().GetSize();
if (outOfSamples) {
StartBuffering();
@ -837,14 +837,14 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
return;
}
if (aReason == MediaDecoderReader::CANCELED) {
if (aReason == RequestSampleCallback::CANCELED) {
DispatchDecodeTasksIfNeeded();
return;
}
// This is an EOS. Finish off the queue, and then handle things based on our
// state.
MOZ_ASSERT(aReason == MediaDecoderReader::END_OF_STREAM);
MOZ_ASSERT(aReason == RequestSampleCallback::END_OF_STREAM);
if (!isAudio && mState == DECODER_STATE_SEEKING &&
mCurrentSeekTarget.IsValid() && mFirstVideoFrameAfterSeek) {
// Null sample. Hit end of stream. If we have decoded a frame,

View File

@ -373,7 +373,7 @@ public:
void OnAudioDecoded(AudioData* aSample);
void OnVideoDecoded(VideoData* aSample);
void OnNotDecoded(MediaData::Type aType, MediaDecoderReader::NotDecodedReason aReason);
void OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason);
void OnSeekCompleted(nsresult aResult);
private:

View File

@ -1,322 +0,0 @@
/* -*- 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/. */
#if !defined(MediaPromise_h_)
#define MediaPromise_h_
#include "prlog.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Maybe.h"
#include "mozilla/Mutex.h"
#include "mozilla/Monitor.h"
#include "MediaTaskQueue.h"
#include "nsIEventTarget.h"
/* Polyfill __func__ on MSVC for consumers to pass to the MediaPromise API. */
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif
namespace mozilla {
extern PRLogModuleInfo* gMediaPromiseLog;
void EnsureMediaPromiseLog();
#define PROMISE_LOG(x, ...) \
MOZ_ASSERT(gMediaPromiseLog); \
PR_LOG(gMediaPromiseLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
/*
* A promise manages an asynchronous request that may or may not be able to be
* fulfilled immediately. When an API returns a promise, the consumer may attach
* callbacks to be invoked (asynchronously, on a specified thread) when the
* request is either completed (resolved) or cannot be completed (rejected).
*
* By default, resolve and reject callbacks are always invoked on the same thread
* where Then() was invoked.
*/
template<typename T> class MediaPromiseHolder;
template<typename ResolveValueT, typename RejectValueT>
class MediaPromise
{
public:
typedef ResolveValueT ResolveValueType;
typedef RejectValueT RejectValueType;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaPromise)
MediaPromise(const char* aCreationSite)
: mCreationSite(aCreationSite)
, mMutex("MediaPromise Mutex")
{
MOZ_COUNT_CTOR(MediaPromise);
PROMISE_LOG("%s creating MediaPromise (%p)", mCreationSite, this);
}
protected:
/*
* A ThenValue tracks a single consumer waiting on the promise. When a consumer
* invokes promise->Then(...), a ThenValue is created. Once the Promise is
* resolved or rejected, a ThenValueRunnable is dispatched, which invokes the
* resolve/reject method and then deletes the ThenValue.
*/
class ThenValueBase
{
public:
class ThenValueRunnable : public nsRunnable
{
public:
ThenValueRunnable(ThenValueBase* aThenValue, ResolveValueType aResolveValue)
: mThenValue(aThenValue)
{
MOZ_COUNT_CTOR(ThenValueRunnable);
mResolveValue.emplace(aResolveValue);
}
ThenValueRunnable(ThenValueBase* aThenValue, RejectValueType aRejectValue)
: mThenValue(aThenValue)
{
MOZ_COUNT_CTOR(ThenValueRunnable);
mRejectValue.emplace(aRejectValue);
}
~ThenValueRunnable()
{
MOZ_COUNT_DTOR(ThenValueRunnable);
MOZ_ASSERT(!mThenValue);
}
NS_IMETHODIMP Run()
{
PROMISE_LOG("ThenValueRunnable::Run() [this=%p]", this);
if (mResolveValue.isSome()) {
mThenValue->DoResolve(mResolveValue.ref());
} else {
mThenValue->DoReject(mRejectValue.ref());
}
delete mThenValue;
mThenValue = nullptr;
return NS_OK;
}
private:
ThenValueBase* mThenValue;
Maybe<ResolveValueType> mResolveValue;
Maybe<RejectValueType> mRejectValue;
};
ThenValueBase(const char* aCallSite) : mCallSite(aCallSite)
{
MOZ_COUNT_CTOR(ThenValueBase);
}
virtual void Dispatch(MediaPromise *aPromise) = 0;
protected:
// This may only be deleted by ThenValueRunnable::Run.
virtual ~ThenValueBase() { MOZ_COUNT_DTOR(ThenValueBase); }
virtual void DoResolve(ResolveValueType aResolveValue) = 0;
virtual void DoReject(RejectValueType aRejectValue) = 0;
const char* mCallSite;
};
template<typename TargetType, typename ThisType,
typename ResolveMethodType, typename RejectMethodType>
class ThenValue : public ThenValueBase
{
public:
ThenValue(TargetType* aResponseTarget, ThisType* aThisVal,
ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod,
const char* aCallSite)
: ThenValueBase(aCallSite)
, mResponseTarget(aResponseTarget)
, mThisVal(aThisVal)
, mResolveMethod(aResolveMethod)
, mRejectMethod(aRejectMethod) {}
void Dispatch(MediaPromise *aPromise) MOZ_OVERRIDE
{
aPromise->mMutex.AssertCurrentThreadOwns();
MOZ_ASSERT(!aPromise->IsPending());
bool resolved = aPromise->mResolveValue.isSome();
nsRefPtr<nsRunnable> runnable =
resolved ? new (typename ThenValueBase::ThenValueRunnable)(this, aPromise->mResolveValue.ref())
: new (typename ThenValueBase::ThenValueRunnable)(this, aPromise->mRejectValue.ref());
PROMISE_LOG("%s Then() call made from %s [Runnable=%p, Promise=%p, ThenValue=%p]",
resolved ? "Resolving" : "Rejecting", ThenValueBase::mCallSite,
runnable.get(), aPromise, this);
DebugOnly<nsresult> rv = DoDispatch(mResponseTarget, runnable);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
protected:
virtual void DoResolve(ResolveValueType aResolveValue)
{
((*mThisVal).*mResolveMethod)(aResolveValue);
}
virtual void DoReject(RejectValueType aRejectValue)
{
((*mThisVal).*mRejectMethod)(aRejectValue);
}
static nsresult DoDispatch(MediaTaskQueue* aTaskQueue, nsIRunnable* aRunnable)
{
return aTaskQueue->ForceDispatch(aRunnable);
}
static nsresult DoDispatch(nsIEventTarget* aEventTarget, nsIRunnable* aRunnable)
{
return aEventTarget->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
}
virtual ~ThenValue() {}
private:
nsRefPtr<TargetType> mResponseTarget;
nsRefPtr<ThisType> mThisVal;
ResolveMethodType mResolveMethod;
RejectMethodType mRejectMethod;
};
public:
template<typename TargetType, typename ThisType,
typename ResolveMethodType, typename RejectMethodType>
void Then(TargetType* aResponseTarget, ThisType* aThisVal,
ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod,
const char* aCallSite)
{
MutexAutoLock lock(mMutex);
ThenValueBase* thenValue = new ThenValue<TargetType, ThisType, ResolveMethodType,
RejectMethodType>(aResponseTarget, aThisVal,
aResolveMethod, aRejectMethod,
aCallSite);
PROMISE_LOG("%s invoking Then() [this=%p, thenValue=%p, aThisVal=%p, isPending=%d]",
aCallSite, this, thenValue, aThisVal, (int) IsPending());
if (!IsPending()) {
thenValue->Dispatch(this);
} else {
mThenValues.AppendElement(thenValue);
}
}
private:
// Resolve and Reject may only be invoked via MediaPromiseHolder.
friend class MediaPromiseHolder<MediaPromise<ResolveValueType, RejectValueType>>;
void Resolve(ResolveValueType aResolveValue, const char* aResolveSite)
{
MutexAutoLock lock(mMutex);
MOZ_ASSERT(IsPending());
PROMISE_LOG("%s resolving MediaPromise (%p created at %s)", aResolveSite, this, mCreationSite);
mResolveValue.emplace(aResolveValue);
DispatchAll();
}
void Reject(RejectValueType aRejectValue, const char* aRejectSite)
{
MutexAutoLock lock(mMutex);
MOZ_ASSERT(IsPending());
PROMISE_LOG("%s rejecting MediaPromise (%p created at %s)", aRejectSite, this, mCreationSite);
mRejectValue.emplace(aRejectValue);
DispatchAll();
}
protected:
bool IsPending() { return mResolveValue.isNothing() && mRejectValue.isNothing(); }
void DispatchAll()
{
mMutex.AssertCurrentThreadOwns();
for (size_t i = 0; i < mThenValues.Length(); ++i)
mThenValues[i]->Dispatch(this);
mThenValues.Clear();
}
~MediaPromise()
{
MOZ_COUNT_DTOR(MediaPromise);
PROMISE_LOG("MediaPromise::~MediaPromise [this=%p]", this);
MOZ_ASSERT(!IsPending());
};
const char* mCreationSite; // For logging
Mutex mMutex;
Maybe<ResolveValueType> mResolveValue;
Maybe<RejectValueType> mRejectValue;
nsTArray<ThenValueBase*> mThenValues;
};
/*
* Class to encapsulate a promise for a particular role. Use this as the member
* variable for a class whose method returns a promise.
*/
template<typename PromiseType>
class MediaPromiseHolder
{
public:
MediaPromiseHolder()
: mMonitor(nullptr) {}
~MediaPromiseHolder() { MOZ_ASSERT(!mPromise); }
already_AddRefed<PromiseType> Ensure(const char* aMethodName) {
if (mMonitor) {
mMonitor->AssertCurrentThreadOwns();
}
if (!mPromise) {
mPromise = new PromiseType(aMethodName);
}
nsRefPtr<PromiseType> p = mPromise;
return p.forget();
}
// Provide a Monitor that should always be held when accessing this instance.
void SetMonitor(Monitor* aMonitor) { mMonitor = aMonitor; }
bool IsEmpty()
{
if (mMonitor) {
mMonitor->AssertCurrentThreadOwns();
}
return !mPromise;
}
void Resolve(typename PromiseType::ResolveValueType aResolveValue,
const char* aMethodName)
{
if (mMonitor) {
mMonitor->AssertCurrentThreadOwns();
}
MOZ_ASSERT(mPromise);
mPromise->Resolve(aResolveValue, aMethodName);
mPromise = nullptr;
}
void Reject(typename PromiseType::RejectValueType aRejectValue,
const char* aMethodName)
{
if (mMonitor) {
mMonitor->AssertCurrentThreadOwns();
}
MOZ_ASSERT(mPromise);
mPromise->Reject(aRejectValue, aMethodName);
mPromise = nullptr;
}
private:
Monitor* mMonitor;
nsRefPtr<PromiseType> mPromise;
};
#undef PROMISE_LOG
} // namespace mozilla
#endif

View File

@ -34,13 +34,6 @@ MediaTaskQueue::Dispatch(TemporaryRef<nsIRunnable> aRunnable)
return DispatchLocked(aRunnable, AbortIfFlushing);
}
nsresult
MediaTaskQueue::ForceDispatch(TemporaryRef<nsIRunnable> aRunnable)
{
MonitorAutoLock mon(mQueueMonitor);
return DispatchLocked(aRunnable, Forced);
}
nsresult
MediaTaskQueue::DispatchLocked(TemporaryRef<nsIRunnable> aRunnable,
DispatchMode aMode)
@ -52,7 +45,7 @@ MediaTaskQueue::DispatchLocked(TemporaryRef<nsIRunnable> aRunnable,
if (mIsShutdown) {
return NS_ERROR_FAILURE;
}
mTasks.push(TaskQueueEntry(aRunnable, aMode == Forced));
mTasks.push(aRunnable);
if (mIsRunning) {
return NS_OK;
}
@ -147,7 +140,9 @@ MediaTaskQueue::FlushAndDispatch(TemporaryRef<nsIRunnable> aRunnable)
{
MonitorAutoLock mon(mQueueMonitor);
AutoSetFlushing autoFlush(this);
FlushLocked();
while (!mTasks.empty()) {
mTasks.pop();
}
nsresult rv = DispatchLocked(aRunnable, IgnoreFlushing);
NS_ENSURE_SUCCESS(rv, rv);
AwaitIdleLocked();
@ -159,25 +154,10 @@ MediaTaskQueue::Flush()
{
MonitorAutoLock mon(mQueueMonitor);
AutoSetFlushing autoFlush(this);
FlushLocked();
AwaitIdleLocked();
}
void
MediaTaskQueue::FlushLocked()
{
mQueueMonitor.AssertCurrentThreadOwns();
MOZ_ASSERT(mIsFlushing);
// Clear the tasks, but preserve those with mForceDispatch by re-appending
// them to the queue.
size_t numTasks = mTasks.size();
for (size_t i = 0; i < numTasks; ++i) {
if (mTasks.front().mForceDispatch) {
mTasks.push(mTasks.front());
}
while (!mTasks.empty()) {
mTasks.pop();
}
AwaitIdleLocked();
}
bool
@ -211,7 +191,7 @@ MediaTaskQueue::Runner::Run()
mon.NotifyAll();
return NS_OK;
}
event = mQueue->mTasks.front().mRunnable;
event = mQueue->mTasks.front();
mQueue->mTasks.pop();
}
MOZ_ASSERT(event);

View File

@ -34,10 +34,6 @@ public:
nsresult Dispatch(TemporaryRef<nsIRunnable> aRunnable);
// This should only be used for things that absolutely can't afford to be
// flushed. Normal operations should use Dispatch.
nsresult ForceDispatch(TemporaryRef<nsIRunnable> aRunnable);
nsresult SyncDispatch(TemporaryRef<nsIRunnable> aRunnable);
nsresult FlushAndDispatch(TemporaryRef<nsIRunnable> aRunnable);
@ -72,27 +68,18 @@ private:
// mQueueMonitor must be held.
void AwaitIdleLocked();
enum DispatchMode { AbortIfFlushing, IgnoreFlushing, Forced };
enum DispatchMode { AbortIfFlushing, IgnoreFlushing };
nsresult DispatchLocked(TemporaryRef<nsIRunnable> aRunnable,
DispatchMode aMode);
void FlushLocked();
RefPtr<SharedThreadPool> mPool;
// Monitor that protects the queue and mIsRunning;
Monitor mQueueMonitor;
struct TaskQueueEntry {
RefPtr<nsIRunnable> mRunnable;
bool mForceDispatch;
TaskQueueEntry(TemporaryRef<nsIRunnable> aRunnable, bool aForceDispatch = false)
: mRunnable(aRunnable), mForceDispatch(aForceDispatch) {}
};
// Queue of tasks to run.
std::queue<TaskQueueEntry> mTasks;
std::queue<RefPtr<nsIRunnable>> mTasks;
// The thread currently running the task queue. We store a reference
// to this so that IsCurrentThreadIn() can tell if the current thread

View File

@ -100,7 +100,7 @@ MediaSourceReader::RequestAudioData()
MSE_DEBUGV("MediaSourceReader(%p)::RequestAudioData", this);
if (!mAudioReader) {
MSE_DEBUG("MediaSourceReader(%p)::RequestAudioData called with no audio reader", this);
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, DECODE_ERROR);
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
return;
}
mAudioIsSeeking = false;
@ -139,7 +139,7 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
this, aSkipToNextKeyframe, aTimeThreshold);
if (!mVideoReader) {
MSE_DEBUG("MediaSourceReader(%p)::RequestVideoData called with no video reader", this);
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, DECODE_ERROR);
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::DECODE_ERROR);
return;
}
if (aSkipToNextKeyframe) {
@ -177,16 +177,17 @@ MediaSourceReader::OnVideoDecoded(VideoData* aSample)
}
void
MediaSourceReader::OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason)
MediaSourceReader::OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason)
{
MSE_DEBUG("MediaSourceReader(%p)::OnNotDecoded aType=%u aReason=%u IsEnded: %d", this, aType, aReason, IsEnded());
if (aReason == DECODE_ERROR || aReason == CANCELED) {
if (aReason == RequestSampleCallback::DECODE_ERROR ||
aReason == RequestSampleCallback::CANCELED) {
GetCallback()->OnNotDecoded(aType, aReason);
return;
}
// End of stream. Force switching past this stream to another reader by
// switching to the end of the buffered range.
MOZ_ASSERT(aReason == END_OF_STREAM);
MOZ_ASSERT(aReason == RequestSampleCallback::END_OF_STREAM);
nsRefPtr<MediaDecoderReader> reader = aType == MediaData::AUDIO_DATA ?
mAudioReader : mVideoReader;
@ -227,13 +228,13 @@ MediaSourceReader::OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason)
// If the entire MediaSource is done, generate an EndOfStream.
if (IsEnded()) {
GetCallback()->OnNotDecoded(aType, END_OF_STREAM);
GetCallback()->OnNotDecoded(aType, RequestSampleCallback::END_OF_STREAM);
return;
}
// We don't have the data the caller wants. Tell that we're waiting for JS to
// give us more data.
GetCallback()->OnNotDecoded(aType, WAITING_FOR_DATA);
GetCallback()->OnNotDecoded(aType, RequestSampleCallback::WAITING_FOR_DATA);
}
void

View File

@ -54,7 +54,7 @@ public:
void OnVideoDecoded(VideoData* aSample);
void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason);
void OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason);
void OnSeekCompleted(nsresult aResult);

View File

@ -105,7 +105,6 @@ EXPORTS += [
'MediaDecoderStateMachine.h',
'MediaInfo.h',
'MediaMetadataManager.h',
'MediaPromise.h',
'MediaQueue.h',
'MediaRecorder.h',
'MediaResource.h',

View File

@ -488,7 +488,7 @@ MediaCodecReader::DecodeAudioDataTask()
}
}
if (AudioQueue().AtEndOfStream()) {
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, END_OF_STREAM);
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::END_OF_STREAM);
}
return result;
}
@ -508,7 +508,7 @@ MediaCodecReader::DecodeVideoFrameTask(int64_t aTimeThreshold)
}
}
if (VideoQueue().AtEndOfStream()) {
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, END_OF_STREAM);
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::END_OF_STREAM);
}
return result;
}

View File

@ -743,7 +743,7 @@ bool WebMReader::DecodeOpus(const unsigned char* aData, size_t aLength,
// Discard padding should be used only on the final packet, so
// decoding after a padding discard is invalid.
LOG(PR_LOG_DEBUG, ("Opus error, discard padding on interstitial packet"));
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, DECODE_ERROR);
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
return false;
}
@ -797,7 +797,7 @@ bool WebMReader::DecodeOpus(const unsigned char* aData, size_t aLength,
if (discardPadding < 0) {
// Negative discard padding is invalid.
LOG(PR_LOG_DEBUG, ("Opus error, negative discard padding"));
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, DECODE_ERROR);
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
return false;
}
if (discardPadding > 0) {
@ -810,7 +810,7 @@ bool WebMReader::DecodeOpus(const unsigned char* aData, size_t aLength,
if (discardFrames.value() > frames) {
// Discarding more than the entire packet is invalid.
LOG(PR_LOG_DEBUG, ("Opus error, discard padding larger than packet"));
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, DECODE_ERROR);
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
return false;
}
LOG(PR_LOG_DEBUG, ("Opus decoder discarding %d of %d frames",