mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1090991 - Refactor RequestSampleCallback to use a single callback for all "not decoded" message. r=cpearce,r=cajbir
I'm going to add another one, and want this API to scale better than it does.
This commit is contained in:
parent
3dc6ad728a
commit
4a2b081603
@ -20,6 +20,8 @@ class MediaData;
|
||||
template<class Target>
|
||||
class MediaDataDecodedListener : public RequestSampleCallback {
|
||||
public:
|
||||
using RequestSampleCallback::NotDecodedReason;
|
||||
|
||||
MediaDataDecodedListener(Target* aTarget,
|
||||
MediaTaskQueue* aTaskQueue)
|
||||
: mMonitor("MediaDataDecodedListener")
|
||||
@ -41,18 +43,6 @@ public:
|
||||
mTaskQueue->Dispatch(task);
|
||||
}
|
||||
|
||||
virtual void OnAudioEOS() MOZ_OVERRIDE {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (!mTarget || !mTaskQueue) {
|
||||
// We've been shutdown, abort.
|
||||
return;
|
||||
}
|
||||
RefPtr<nsIRunnable> task(NS_NewRunnableMethod(mTarget, &Target::OnAudioEOS));
|
||||
if (NS_FAILED(mTaskQueue->Dispatch(task))) {
|
||||
NS_WARNING("Failed to dispatch OnAudioEOS task");
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnVideoDecoded(VideoData* aSample) MOZ_OVERRIDE {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
nsAutoPtr<VideoData> sample(aSample);
|
||||
@ -64,28 +54,14 @@ public:
|
||||
mTaskQueue->Dispatch(task);
|
||||
}
|
||||
|
||||
virtual void OnVideoEOS() MOZ_OVERRIDE {
|
||||
virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) MOZ_OVERRIDE {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (!mTarget || !mTaskQueue) {
|
||||
// We've been shutdown, abort.
|
||||
return;
|
||||
}
|
||||
RefPtr<nsIRunnable> task(NS_NewRunnableMethod(mTarget, &Target::OnVideoEOS));
|
||||
if (NS_FAILED(mTaskQueue->Dispatch(task))) {
|
||||
NS_WARNING("Failed to dispatch OnVideoEOS task");
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnDecodeError() MOZ_OVERRIDE {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (!mTarget || !mTaskQueue) {
|
||||
// We've been shutdown, abort.
|
||||
return;
|
||||
}
|
||||
RefPtr<nsIRunnable> task(NS_NewRunnableMethod(mTarget, &Target::OnDecodeError));
|
||||
if (NS_FAILED(mTaskQueue->Dispatch(task))) {
|
||||
NS_WARNING("Failed to dispatch OnAudioDecoded task");
|
||||
}
|
||||
RefPtr<nsIRunnable> task(new DeliverNotDecodedTask(aType, aReason, mTarget));
|
||||
mTaskQueue->Dispatch(task);
|
||||
}
|
||||
|
||||
void BreakCycles() {
|
||||
@ -142,11 +118,38 @@ private:
|
||||
RefPtr<Target> mTarget;
|
||||
};
|
||||
|
||||
class DeliverNotDecodedTask : public nsRunnable {
|
||||
public:
|
||||
DeliverNotDecodedTask(MediaData::Type aType,
|
||||
RequestSampleCallback::NotDecodedReason aReason,
|
||||
Target* aTarget)
|
||||
: mType(aType)
|
||||
, mReason(aReason)
|
||||
, mTarget(aTarget)
|
||||
{
|
||||
MOZ_COUNT_CTOR(DeliverNotDecodedTask);
|
||||
}
|
||||
protected:
|
||||
~DeliverNotDecodedTask()
|
||||
{
|
||||
MOZ_COUNT_DTOR(DeliverNotDecodedTask);
|
||||
}
|
||||
public:
|
||||
NS_METHOD Run() {
|
||||
mTarget->OnNotDecoded(mType, mReason);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
MediaData::Type mType;
|
||||
RequestSampleCallback::NotDecodedReason mReason;
|
||||
RefPtr<Target> mTarget;
|
||||
};
|
||||
|
||||
Monitor mMonitor;
|
||||
RefPtr<MediaTaskQueue> mTaskQueue;
|
||||
RefPtr<Target> mTarget;
|
||||
};
|
||||
|
||||
}
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif // MediaDataDecodedListener_h_
|
||||
|
@ -193,7 +193,7 @@ MediaDecoderReader::RequestVideoData(bool aSkipToNextKeyframe,
|
||||
}
|
||||
GetCallback()->OnVideoDecoded(v);
|
||||
} else if (VideoQueue().IsFinished()) {
|
||||
GetCallback()->OnVideoEOS();
|
||||
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::END_OF_STREAM);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ MediaDecoderReader::RequestAudioData()
|
||||
GetCallback()->OnAudioDecoded(a);
|
||||
return;
|
||||
} else if (AudioQueue().IsFinished()) {
|
||||
GetCallback()->OnAudioEOS();
|
||||
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::END_OF_STREAM);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -280,21 +280,12 @@ AudioDecodeRendezvous::OnAudioDecoded(AudioData* aSample)
|
||||
}
|
||||
|
||||
void
|
||||
AudioDecodeRendezvous::OnAudioEOS()
|
||||
AudioDecodeRendezvous::OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason)
|
||||
{
|
||||
MOZ_ASSERT(aType == MediaData::AUDIO_DATA);
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mSample = nullptr;
|
||||
mStatus = NS_OK;
|
||||
mHaveResult = true;
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
AudioDecodeRendezvous::OnDecodeError()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mSample = nullptr;
|
||||
mStatus = NS_ERROR_FAILURE;
|
||||
mStatus = aReason == DECODE_ERROR ? NS_ERROR_FAILURE : NS_OK;
|
||||
mHaveResult = true;
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
@ -255,23 +255,20 @@ class RequestSampleCallback {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RequestSampleCallback)
|
||||
|
||||
enum NotDecodedReason {
|
||||
END_OF_STREAM,
|
||||
DECODE_ERROR
|
||||
};
|
||||
|
||||
// Receives the result of a RequestAudioData() call.
|
||||
virtual void OnAudioDecoded(AudioData* aSample) = 0;
|
||||
|
||||
// Called when a RequestAudioData() call can't be fulfiled as we've
|
||||
// reached the end of stream.
|
||||
virtual void OnAudioEOS() = 0;
|
||||
|
||||
// Receives the result of a RequestVideoData() call.
|
||||
virtual void OnVideoDecoded(VideoData* aSample) = 0;
|
||||
|
||||
// Called when a RequestVideoData() call can't be fulfiled as we've
|
||||
// reached the end of stream.
|
||||
virtual void OnVideoEOS() = 0;
|
||||
|
||||
// Called when there's a decode error. No more sample requests
|
||||
// will succeed.
|
||||
virtual void OnDecodeError() = 0;
|
||||
// Called when a RequestAudioData() or RequestVideoData() call can't be
|
||||
// fulfiled. The reason is passed as aReason.
|
||||
virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) = 0;
|
||||
|
||||
// Called during shutdown to break any reference cycles.
|
||||
virtual void BreakCycles() = 0;
|
||||
@ -286,16 +283,16 @@ protected:
|
||||
// model of the MediaDecoderReader to a synchronous model.
|
||||
class AudioDecodeRendezvous : public RequestSampleCallback {
|
||||
public:
|
||||
using RequestSampleCallback::NotDecodedReason;
|
||||
|
||||
AudioDecodeRendezvous();
|
||||
~AudioDecodeRendezvous();
|
||||
|
||||
// RequestSampleCallback implementation. Called when decode is complete.
|
||||
// Note: aSample is null at end of stream.
|
||||
virtual void OnAudioDecoded(AudioData* aSample) MOZ_OVERRIDE;
|
||||
virtual void OnAudioEOS() MOZ_OVERRIDE;
|
||||
virtual void OnVideoDecoded(VideoData* aSample) MOZ_OVERRIDE {}
|
||||
virtual void OnVideoEOS() MOZ_OVERRIDE {}
|
||||
virtual void OnDecodeError() MOZ_OVERRIDE;
|
||||
virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) MOZ_OVERRIDE;
|
||||
virtual void BreakCycles() MOZ_OVERRIDE {};
|
||||
void Reset();
|
||||
|
||||
|
@ -835,6 +835,24 @@ MediaDecoderStateMachine::Push(VideoData* aSample)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
|
||||
RequestSampleCallback::NotDecodedReason aReason)
|
||||
{
|
||||
if (aReason == RequestSampleCallback::DECODE_ERROR) {
|
||||
OnDecodeError();
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aReason == RequestSampleCallback::END_OF_STREAM);
|
||||
if (aType == MediaData::AUDIO_DATA) {
|
||||
OnAudioEOS();
|
||||
} else {
|
||||
MOZ_ASSERT(aType == MediaData::VIDEO_DATA);
|
||||
OnVideoEOS();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnDecodeError()
|
||||
{
|
||||
|
@ -340,8 +340,13 @@ public:
|
||||
void SetMinimizePrerollUntilPlaybackStarts();
|
||||
|
||||
void OnAudioDecoded(AudioData* aSample);
|
||||
void OnAudioEOS();
|
||||
void OnVideoDecoded(VideoData* aSample);
|
||||
void OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason);
|
||||
|
||||
private:
|
||||
// XXXbholley - We leave these as helper functions to keep this patch small.
|
||||
// They go away in the next patch.
|
||||
void OnAudioEOS();
|
||||
void OnVideoEOS();
|
||||
void OnDecodeError();
|
||||
|
||||
|
@ -80,7 +80,7 @@ MediaSourceReader::RequestAudioData()
|
||||
MSE_DEBUGV("MediaSourceReader(%p)::RequestAudioData", this);
|
||||
if (!mAudioReader) {
|
||||
MSE_DEBUG("MediaSourceReader(%p)::RequestAudioData called with no audio reader", this);
|
||||
GetCallback()->OnDecodeError();
|
||||
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
|
||||
return;
|
||||
}
|
||||
mAudioIsSeeking = false;
|
||||
@ -113,22 +113,6 @@ MediaSourceReader::OnAudioDecoded(AudioData* aSample)
|
||||
GetCallback()->OnAudioDecoded(aSample);
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnAudioEOS()
|
||||
{
|
||||
MSE_DEBUG("MediaSourceReader(%p)::OnAudioEOS reader=%p (decoders=%u)",
|
||||
this, mAudioReader.get(), mAudioTrack->Decoders().Length());
|
||||
if (SwitchAudioReader(mLastAudioTime)) {
|
||||
// Success! Resume decoding with next audio decoder.
|
||||
RequestAudioData();
|
||||
} else if (IsEnded()) {
|
||||
// End of stream.
|
||||
MSE_DEBUG("MediaSourceReader(%p)::OnAudioEOS reader=%p EOS (decoders=%u)",
|
||||
this, mAudioReader.get(), mAudioTrack->Decoders().Length());
|
||||
GetCallback()->OnAudioEOS();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold)
|
||||
{
|
||||
@ -136,7 +120,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()->OnDecodeError();
|
||||
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::DECODE_ERROR);
|
||||
return;
|
||||
}
|
||||
if (aSkipToNextKeyframe) {
|
||||
@ -175,27 +159,29 @@ MediaSourceReader::OnVideoDecoded(VideoData* aSample)
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnVideoEOS()
|
||||
MediaSourceReader::OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason)
|
||||
{
|
||||
// End of stream. See if we can switch to another video decoder.
|
||||
MSE_DEBUG("MediaSourceReader(%p)::OnVideoEOS reader=%p (decoders=%u)",
|
||||
this, mVideoReader.get(), mVideoTrack->Decoders().Length());
|
||||
if (SwitchVideoReader(mLastVideoTime)) {
|
||||
// Success! Resume decoding with next video decoder.
|
||||
RequestVideoData(false, 0);
|
||||
} else if (IsEnded()) {
|
||||
// End of stream.
|
||||
MSE_DEBUG("MediaSourceReader(%p)::OnVideoEOS reader=%p EOS (decoders=%u)",
|
||||
this, mVideoReader.get(), mVideoTrack->Decoders().Length());
|
||||
GetCallback()->OnVideoEOS();
|
||||
MSE_DEBUG("MediaSourceReader(%p)::OnNotDecoded aType=%u aReason=%u IsEnded: %d", this, aType, aReason, IsEnded());
|
||||
if (aReason == RequestSampleCallback::DECODE_ERROR) {
|
||||
GetCallback()->OnNotDecoded(aType, aReason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnDecodeError()
|
||||
{
|
||||
MSE_DEBUG("MediaSourceReader(%p)::OnDecodeError", this);
|
||||
GetCallback()->OnDecodeError();
|
||||
MOZ_ASSERT(aReason == RequestSampleCallback::END_OF_STREAM);
|
||||
if (aType == MediaData::AUDIO_DATA && SwitchAudioReader(mLastAudioTime)) {
|
||||
RequestAudioData();
|
||||
return;
|
||||
}
|
||||
if (aType == MediaData::VIDEO_DATA && SwitchVideoReader(mLastVideoTime)) {
|
||||
RequestVideoData(false, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsEnded()) {
|
||||
GetCallback()->OnNotDecoded(aType, aReason);
|
||||
}
|
||||
|
||||
// Drop anything else on the floor. This gets fixed in the next patch.
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -50,15 +50,11 @@ public:
|
||||
|
||||
void OnAudioDecoded(AudioData* aSample);
|
||||
|
||||
void OnAudioEOS();
|
||||
|
||||
void RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) MOZ_OVERRIDE;
|
||||
|
||||
void OnVideoDecoded(VideoData* aSample);
|
||||
|
||||
void OnVideoEOS();
|
||||
|
||||
void OnDecodeError();
|
||||
void OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason);
|
||||
|
||||
bool HasVideo() MOZ_OVERRIDE
|
||||
{
|
||||
|
@ -480,7 +480,7 @@ MediaCodecReader::DecodeAudioDataTask()
|
||||
}
|
||||
}
|
||||
if (AudioQueue().AtEndOfStream()) {
|
||||
GetCallback()->OnAudioEOS();
|
||||
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::END_OF_STREAM);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -500,7 +500,7 @@ MediaCodecReader::DecodeVideoFrameTask(int64_t aTimeThreshold)
|
||||
}
|
||||
}
|
||||
if (VideoQueue().AtEndOfStream()) {
|
||||
GetCallback()->OnVideoEOS();
|
||||
GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::END_OF_STREAM);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -688,7 +688,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()->OnDecodeError();
|
||||
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -742,7 +742,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()->OnDecodeError();
|
||||
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
|
||||
return false;
|
||||
}
|
||||
if (discardPadding > 0) {
|
||||
@ -755,7 +755,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()->OnDecodeError();
|
||||
GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
|
||||
return false;
|
||||
}
|
||||
LOG(PR_LOG_DEBUG, ("Opus decoder discarding %d of %d frames",
|
||||
|
Loading…
Reference in New Issue
Block a user