Bug 1316506 - Make RemoteVideoDecoder::Flush synchronous. r=billm

--HG--
extra : rebase_source : 1e0b6991a629de72248ac80dd64c30126d0c10fd
This commit is contained in:
Matt Woodrow 2016-11-22 15:50:46 +13:00
parent 50c5379ac8
commit 89ee34ca75
5 changed files with 42 additions and 6 deletions

View File

@ -62,6 +62,8 @@ child:
async InitComplete(bool hardware, nsCString hardwareReason); async InitComplete(bool hardware, nsCString hardwareReason);
async InitFailed(nsresult reason); async InitFailed(nsresult reason);
async FlushComplete();
// Each output includes a SurfaceDescriptorGPUVideo that represents the decoded // Each output includes a SurfaceDescriptorGPUVideo that represents the decoded
// frame. This SurfaceDescriptor can be used on the Layers IPDL protocol, but // frame. This SurfaceDescriptor can be used on the Layers IPDL protocol, but
// must be released explicitly using DeallocateSurfaceDescriptorGPUVideo // must be released explicitly using DeallocateSurfaceDescriptorGPUVideo

View File

@ -75,11 +75,12 @@ void
RemoteVideoDecoder::Flush() RemoteVideoDecoder::Flush()
{ {
MOZ_ASSERT(mCallback->OnReaderTaskQueue()); MOZ_ASSERT(mCallback->OnReaderTaskQueue());
RefPtr<RemoteVideoDecoder> self = this; SynchronousTask task("Decoder flush");
VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([self]() { VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([&]() {
MOZ_ASSERT(self->mActor); MOZ_ASSERT(this->mActor);
self->mActor->Flush(); this->mActor->Flush(&task);
}), NS_DISPATCH_NORMAL); }), NS_DISPATCH_NORMAL);
task.Wait();
} }
void void

View File

@ -10,6 +10,7 @@
#include "MediaInfo.h" #include "MediaInfo.h"
#include "ImageContainer.h" #include "ImageContainer.h"
#include "GPUVideoImage.h" #include "GPUVideoImage.h"
#include "mozilla/layers/SynchronousTask.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -107,6 +108,15 @@ VideoDecoderChild::RecvInitFailed(const nsresult& aReason)
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult
VideoDecoderChild::RecvFlushComplete()
{
MOZ_ASSERT(mFlushTask);
AutoCompleteTask complete(mFlushTask);
mFlushTask = nullptr;
return IPC_OK();
}
void void
VideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy) VideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy)
{ {
@ -122,6 +132,10 @@ VideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy)
} }
})); }));
} }
if (mFlushTask) {
AutoCompleteTask complete(mFlushTask);
mFlushTask = nullptr;
}
mCanSend = false; mCanSend = false;
} }
@ -212,11 +226,14 @@ VideoDecoderChild::Input(MediaRawData* aSample)
} }
void void
VideoDecoderChild::Flush() VideoDecoderChild::Flush(SynchronousTask* aTask)
{ {
AssertOnManagerThread(); AssertOnManagerThread();
if (mCanSend) { if (mCanSend) {
SendFlush(); SendFlush();
mFlushTask = aTask;
} else {
AutoCompleteTask complete(aTask);
} }
} }

View File

@ -12,6 +12,9 @@
#include "PlatformDecoderModule.h" #include "PlatformDecoderModule.h"
namespace mozilla { namespace mozilla {
namespace layers {
class SynchronousTask;
}
namespace dom { namespace dom {
class RemoteVideoDecoder; class RemoteVideoDecoder;
@ -32,12 +35,13 @@ public:
mozilla::ipc::IPCResult RecvError(const nsresult& aError) override; mozilla::ipc::IPCResult RecvError(const nsresult& aError) override;
mozilla::ipc::IPCResult RecvInitComplete(const bool& aHardware, const nsCString& aHardwareReason) override; mozilla::ipc::IPCResult RecvInitComplete(const bool& aHardware, const nsCString& aHardwareReason) override;
mozilla::ipc::IPCResult RecvInitFailed(const nsresult& aReason) override; mozilla::ipc::IPCResult RecvInitFailed(const nsresult& aReason) override;
mozilla::ipc::IPCResult RecvFlushComplete() override;
void ActorDestroy(ActorDestroyReason aWhy) override; void ActorDestroy(ActorDestroyReason aWhy) override;
RefPtr<MediaDataDecoder::InitPromise> Init(); RefPtr<MediaDataDecoder::InitPromise> Init();
void Input(MediaRawData* aSample); void Input(MediaRawData* aSample);
void Flush(); void Flush(layers::SynchronousTask* Task);
void Drain(); void Drain();
void Shutdown(); void Shutdown();
bool IsHardwareAccelerated(nsACString& aFailureReason) const; bool IsHardwareAccelerated(nsACString& aFailureReason) const;
@ -66,6 +70,8 @@ private:
MozPromiseHolder<MediaDataDecoder::InitPromise> mInitPromise; MozPromiseHolder<MediaDataDecoder::InitPromise> mInitPromise;
layers::SynchronousTask* mFlushTask;
nsCString mHardwareAcceleratedReason; nsCString mHardwareAcceleratedReason;
bool mCanSend; bool mCanSend;
bool mInitialized; bool mInitialized;

View File

@ -141,6 +141,16 @@ VideoDecoderParent::RecvFlush()
if (mDecoder) { if (mDecoder) {
mDecoder->Flush(); mDecoder->Flush();
} }
// Dispatch a runnable to our own event queue so that
// it will be processed after anything that got dispatched
// during the Flush call.
RefPtr<VideoDecoderParent> self = this;
mManagerTaskQueue->Dispatch(NS_NewRunnableFunction([self]() {
if (!self->mDestroyed) {
Unused << self->SendFlushComplete();
}
}));
return IPC_OK(); return IPC_OK();
} }