Bug 1394591 - P4. Pass decoder description to RemoteVideoDecoder. r?mattwoodrow draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 01 Sep 2017 18:22:55 +0200
changeset 658325 6517d8730f70fa1c5d15688eff7d268236de79d2
parent 658324 1643c84f6ea58a970b96d808b0909ff2fa399254
child 658326 bd8d37f7a9d38a5e7c3028fc65d59b917b58be79
push id77716
push userbmo:jyavenard@mozilla.com
push dateSun, 03 Sep 2017 19:33:08 +0000
reviewersmattwoodrow
bugs1394591
milestone57.0a1
Bug 1394591 - P4. Pass decoder description to RemoteVideoDecoder. r?mattwoodrow This makes it easier to determine the actual decoder in use within the GPU process. MozReview-Commit-ID: 5TF6AsyXYWW
dom/media/ipc/PVideoDecoder.ipdl
dom/media/ipc/RemoteVideoDecoder.cpp
dom/media/ipc/RemoteVideoDecoder.h
dom/media/ipc/VideoDecoderChild.cpp
dom/media/ipc/VideoDecoderChild.h
dom/media/ipc/VideoDecoderParent.cpp
--- a/dom/media/ipc/PVideoDecoder.ipdl
+++ b/dom/media/ipc/PVideoDecoder.ipdl
@@ -54,17 +54,17 @@ parent:
   async Drain();
   async Shutdown();
 
   async SetSeekThreshold(int64_t time);
 
   async __delete__();
 
 child:
-  async InitComplete(bool hardware, nsCString hardwareReason, uint32_t conversion);
+  async InitComplete(nsCString decoderDescription, bool hardware, nsCString hardwareReason, uint32_t conversion);
   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
   // on the manager protocol.
--- a/dom/media/ipc/RemoteVideoDecoder.cpp
+++ b/dom/media/ipc/RemoteVideoDecoder.cpp
@@ -18,16 +18,17 @@ namespace dom {
 
 using base::Thread;
 using namespace ipc;
 using namespace layers;
 using namespace gfx;
 
 RemoteVideoDecoder::RemoteVideoDecoder()
   : mActor(new VideoDecoderChild())
+  , mDescription("RemoteVideoDecoder")
 {
 }
 
 RemoteVideoDecoder::~RemoteVideoDecoder()
 {
   // We're about to be destroyed and drop our ref to
   // VideoDecoderChild. Make sure we put a ref into the
   // task queue for the VideoDecoderChild thread to keep
@@ -40,25 +41,37 @@ RemoteVideoDecoder::~RemoteVideoDecoder(
       actor->DestroyIPDL();
     });
 
   // Drop out references to the actor so that the last ref
   // always gets released on the manager thread.
   actor = nullptr;
   mActor = nullptr;
 
-  VideoDecoderManagerChild::GetManagerThread()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
+  VideoDecoderManagerChild::GetManagerThread()->Dispatch(task.forget(),
+                                                         NS_DISPATCH_NORMAL);
 }
 
 RefPtr<MediaDataDecoder::InitPromise>
 RemoteVideoDecoder::Init()
 {
   RefPtr<RemoteVideoDecoder> self = this;
   return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
-                     __func__, [self, this]() { return mActor->Init(); });
+                     __func__,
+                     [self, this]() { return mActor->Init(); })
+    ->Then(VideoDecoderManagerChild::GetManagerAbstractThread(),
+           __func__,
+           [self, this](TrackType aTrack) {
+             mDescription =
+               mActor->GetDescriptionName() + NS_LITERAL_CSTRING(" (remote)");
+             return InitPromise::CreateAndResolve(aTrack, __func__);
+           },
+           [self, this](const MediaResult& aError) {
+             return InitPromise::CreateAndReject(aError, __func__);
+           });
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
 RemoteVideoDecoder::Decode(MediaRawData* aSample)
 {
   RefPtr<RemoteVideoDecoder> self = this;
   RefPtr<MediaRawData> sample = aSample;
   return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
@@ -178,10 +191,16 @@ RemoteDecoderModule::CreateVideoDecoder(
 
   if (!success) {
     return nullptr;
   }
 
   return object.forget();
 }
 
+nsCString
+RemoteVideoDecoder::GetDescriptionName() const
+{
+  return mDescription;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/ipc/RemoteVideoDecoder.h
+++ b/dom/media/ipc/RemoteVideoDecoder.h
@@ -29,31 +29,30 @@ public:
   // MediaDataDecoder
   RefPtr<InitPromise> Init() override;
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
   void SetSeekThreshold(const media::TimeUnit& aTime) override;
-
-  nsCString GetDescriptionName() const override
-  {
-    return NS_LITERAL_CSTRING("RemoteVideoDecoder");
-  }
+  nsCString GetDescriptionName() const override;
   ConversionRequired NeedsConversion() const override;
 
 private:
   RemoteVideoDecoder();
   ~RemoteVideoDecoder();
 
   // Only ever written to from the reader task queue (during the constructor and
   // destructor when we can guarantee no other threads are accessing it). Only
   // read from the manager thread.
   RefPtr<VideoDecoderChild> mActor;
+  // Only ever written/modified during decoder initialisation.
+  // As such can be accessed from any threads after that.
+  nsCString mDescription;
 };
 
 // A PDM implementation that creates RemoteVideoDecoders.
 // We currently require a 'wrapped' PDM in order to be able to answer SupportsMimeType
 // and DecoderNeedsConversion. Ideally we'd check these over IPDL using the manager
 // protocol
 class RemoteDecoderModule : public PlatformDecoderModule
 {
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -102,23 +102,25 @@ VideoDecoderChild::RecvError(const nsres
   mDecodedData.Clear();
   mDecodePromise.RejectIfExists(aError, __func__);
   mDrainPromise.RejectIfExists(aError, __func__);
   mFlushPromise.RejectIfExists(aError, __func__);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-VideoDecoderChild::RecvInitComplete(const bool& aHardware,
+VideoDecoderChild::RecvInitComplete(const nsCString& aDecoderDescription,
+                                    const bool& aHardware,
                                     const nsCString& aHardwareReason,
                                     const uint32_t& aConversion)
 {
   AssertOnManagerThread();
   mInitPromise.ResolveIfExists(TrackInfo::kVideoTrack, __func__);
   mInitialized = true;
+  mDescription = aDecoderDescription;
   mIsHardwareAccelerated = aHardware;
   mHardwareAcceleratedReason = aHardwareReason;
   mConversion = static_cast<MediaDataDecoder::ConversionRequired>(aConversion);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 VideoDecoderChild::RecvInitFailed(const nsresult& aReason)
@@ -324,16 +326,23 @@ VideoDecoderChild::Shutdown()
 
 bool
 VideoDecoderChild::IsHardwareAccelerated(nsACString& aFailureReason) const
 {
   aFailureReason = mHardwareAcceleratedReason;
   return mIsHardwareAccelerated;
 }
 
+nsCString
+VideoDecoderChild::GetDescriptionName() const
+{
+  AssertOnManagerThread();
+  return mDescription;
+}
+
 void
 VideoDecoderChild::SetSeekThreshold(const media::TimeUnit& aTime)
 {
   AssertOnManagerThread();
   if (mCanSend) {
     SendSetSeekThreshold(aTime.ToMicroseconds());
   }
 }
--- a/dom/media/ipc/VideoDecoderChild.h
+++ b/dom/media/ipc/VideoDecoderChild.h
@@ -24,30 +24,32 @@ public:
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoDecoderChild)
 
   // PVideoDecoderChild
   mozilla::ipc::IPCResult RecvOutput(const VideoDataIPDL& aData) override;
   mozilla::ipc::IPCResult RecvInputExhausted() override;
   mozilla::ipc::IPCResult RecvDrainComplete() override;
   mozilla::ipc::IPCResult RecvError(const nsresult& aError) override;
-  mozilla::ipc::IPCResult RecvInitComplete(const bool& aHardware,
+  mozilla::ipc::IPCResult RecvInitComplete(const nsCString& aDecoderDescription,
+                                           const bool& aHardware,
                                            const nsCString& aHardwareReason,
                                            const uint32_t& aConversion) override;
   mozilla::ipc::IPCResult RecvInitFailed(const nsresult& aReason) override;
   mozilla::ipc::IPCResult RecvFlushComplete() override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
   RefPtr<MediaDataDecoder::InitPromise> Init();
   RefPtr<MediaDataDecoder::DecodePromise> Decode(MediaRawData* aSample);
   RefPtr<MediaDataDecoder::DecodePromise> Drain();
   RefPtr<MediaDataDecoder::FlushPromise> Flush();
   void Shutdown();
   bool IsHardwareAccelerated(nsACString& aFailureReason) const;
+  nsCString GetDescriptionName() const;
   void SetSeekThreshold(const media::TimeUnit& aTime);
   MediaDataDecoder::ConversionRequired NeedsConversion() const;
 
   MOZ_IS_CLASS_INIT
   bool InitIPDL(const VideoInfo& aVideoInfo,
                 const layers::TextureFactoryIdentifier& aIdentifier);
   void DestroyIPDL();
 
@@ -65,27 +67,28 @@ private:
   RefPtr<nsIThread> mThread;
 
   MozPromiseHolder<MediaDataDecoder::InitPromise> mInitPromise;
   MozPromiseHolder<MediaDataDecoder::DecodePromise> mDecodePromise;
   MozPromiseHolder<MediaDataDecoder::DecodePromise> mDrainPromise;
   MozPromiseHolder<MediaDataDecoder::FlushPromise> mFlushPromise;
 
   nsCString mHardwareAcceleratedReason;
+  nsCString mDescription;
   bool mCanSend;
   bool mInitialized;
   Atomic<bool> mIsHardwareAccelerated;
   Atomic<MediaDataDecoder::ConversionRequired> mConversion;
 
   // Set to true if the actor got destroyed and we haven't yet notified the
   // caller.
   bool mNeedNewDecoder;
   MediaDataDecoder::DecodedData mDecodedData;
 
-  nsCString mBlacklistedD3D11Driver;
+  nsCString mBlacklistedD3D11Driver;
   nsCString mBlacklistedD3D9Driver;
   TimeStamp mGPUCrashTime;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // include_dom_ipc_VideoDecoderChild_h
--- a/dom/media/ipc/VideoDecoderParent.cpp
+++ b/dom/media/ipc/VideoDecoderParent.cpp
@@ -107,18 +107,20 @@ VideoDecoderParent::RecvInit()
   mDecoder->Init()->Then(mManagerTaskQueue, __func__,
     [self] (TrackInfo::TrackType aTrack) {
       if (self->mDecoder) {
         nsCString hardwareReason;
         bool hardwareAccelerated =
           self->mDecoder->IsHardwareAccelerated(hardwareReason);
         uint32_t conversion =
           static_cast<uint32_t>(self->mDecoder->NeedsConversion());
-        Unused << self->SendInitComplete(
-          hardwareAccelerated, hardwareReason, conversion);
+        Unused << self->SendInitComplete(self->mDecoder->GetDescriptionName(),
+                                         hardwareAccelerated,
+                                         hardwareReason,
+                                         conversion);
       }
     },
     [self] (MediaResult aReason) {
       if (!self->mDestroyed) {
         Unused << self->SendInitFailed(aReason);
       }
     });
   return IPC_OK();