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 InitFailed(nsresult reason);
async FlushComplete();
// Each output includes a SurfaceDescriptorGPUVideo that represents the decoded
// frame. This SurfaceDescriptor can be used on the Layers IPDL protocol, but
// must be released explicitly using DeallocateSurfaceDescriptorGPUVideo

View File

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

View File

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

View File

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

View File

@ -141,6 +141,16 @@ VideoDecoderParent::RecvFlush()
if (mDecoder) {
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();
}