Bug 1241677: P1. Add MediaDataDecoder::GetDescriptionName() method. r=cpearce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 22 Jan 2016 12:29:51 +1100
changeset 281453 13a942af5b86aa9a03137fc8c1101221d94c299b
parent 281452 29271e7d0c2362109080fb8cfbbbbadba0c4f0f6
child 281454 4ea6060b39285038ae811da6b5b343393dc69d90
push id29940
push usercbook@mozilla.com
push dateMon, 25 Jan 2016 10:50:21 +0000
treeherdermozilla-central@67c66c2878ae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1241677
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1241677: P1. Add MediaDataDecoder::GetDescriptionName() method. r=cpearce
dom/media/platforms/PlatformDecoderModule.h
dom/media/platforms/agnostic/BlankDecoderModule.cpp
dom/media/platforms/agnostic/OpusDecoder.h
dom/media/platforms/agnostic/VPXDecoder.h
dom/media/platforms/agnostic/VorbisDecoder.h
dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
dom/media/platforms/agnostic/gmp/GMPAudioDecoder.h
dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.h
dom/media/platforms/android/AndroidDecoderModule.cpp
dom/media/platforms/android/AndroidDecoderModule.h
dom/media/platforms/apple/AppleATDecoder.h
dom/media/platforms/apple/AppleVDADecoder.h
dom/media/platforms/apple/AppleVTDecoder.h
dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
dom/media/platforms/gonk/GonkAudioDecoderManager.h
dom/media/platforms/gonk/GonkMediaDataDecoder.h
dom/media/platforms/gonk/GonkVideoDecoderManager.h
dom/media/platforms/omx/OmxDataDecoder.h
dom/media/platforms/wmf/WMFAudioMFTManager.h
dom/media/platforms/wmf/WMFMediaDataDecoder.h
dom/media/platforms/wmf/WMFVideoMFTManager.h
dom/media/platforms/wrappers/FuzzingWrapper.h
dom/media/platforms/wrappers/H264Converter.h
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -215,13 +215,18 @@ public:
   // If video decoder, aConfig will be a VideoInfo object.
   // If audio decoder, aConfig will be a AudioInfo object.
   // It is not safe to store a reference to this object and the decoder must
   // make a copy.
   virtual nsresult ConfigurationChanged(const TrackInfo& aConfig)
   {
     return NS_OK;
   }
+
+  // Return the name of the MediaDataDecoder, only used for decoding.
+  // Only return a static const string, as the information may be accessed
+  // in a non thread-safe fashion.
+  virtual const char* GetDescriptionName() const = 0;
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp
@@ -88,16 +88,21 @@ public:
     return NS_OK;
   }
 
   nsresult Drain() override {
     mCallback->DrainComplete();
     return NS_OK;
   }
 
+  const char* GetDescriptionName() const override
+  {
+    return "blank media data decoder";
+  }
+
 private:
   nsAutoPtr<BlankMediaDataCreator> mCreator;
   RefPtr<FlushableTaskQueue> mTaskQueue;
   MediaDataDecoderCallback* mCallback;
   TrackInfo::TrackType mType;
 };
 
 class BlankVideoDataCreator {
--- a/dom/media/platforms/agnostic/OpusDecoder.h
+++ b/dom/media/platforms/agnostic/OpusDecoder.h
@@ -22,16 +22,20 @@ public:
                   MediaDataDecoderCallback* aCallback);
   ~OpusDataDecoder();
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
+  const char* GetDescriptionName() const override
+  {
+    return "opus audio decoder";
+  }
 
   // Return true if mimetype is Opus
   static bool IsOpus(const nsACString& aMimeType);
 
 private:
   nsresult DecodeHeader(const unsigned char* aData, size_t aLength);
 
   void Decode (MediaRawData* aSample);
--- a/dom/media/platforms/agnostic/VPXDecoder.h
+++ b/dom/media/platforms/agnostic/VPXDecoder.h
@@ -28,16 +28,20 @@ public:
 
   ~VPXDecoder();
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
+  const char* GetDescriptionName() const override
+  {
+    return "libvpx video decoder";
+  }
 
   // Return true if mimetype is a VPX codec
   static bool IsVPX(const nsACString& aMimeType);
 
   enum Codec {
     VP8,
     VP9
   };
--- a/dom/media/platforms/agnostic/VorbisDecoder.h
+++ b/dom/media/platforms/agnostic/VorbisDecoder.h
@@ -25,16 +25,20 @@ public:
                 MediaDataDecoderCallback* aCallback);
   ~VorbisDataDecoder();
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
+  const char* GetDescriptionName() const override
+  {
+    return "vorbis audio decoder";
+  }
 
   // Return true if mimetype is Vorbis
   static bool IsVorbis(const nsACString& aMimeType);
 
 private:
   nsresult DecodeHeader(const unsigned char* aData, size_t aLength);
 
   void Decode (MediaRawData* aSample);
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -132,16 +132,20 @@ public:
     mSamplesWaitingForKey->BreakCycles();
     mSamplesWaitingForKey = nullptr;
     mDecoder = nullptr;
     mProxy = nullptr;
     mCallback = nullptr;
     return rv;
   }
 
+  const char* GetDescriptionName() const override {
+    return mDecoder->GetDescriptionName();
+  }
+
 private:
 
   RefPtr<MediaDataDecoder> mDecoder;
   MediaDataDecoderCallback* mCallback;
   RefPtr<TaskQueue> mTaskQueue;
   RefPtr<CDMProxy> mProxy;
   nsClassHashtable<nsRefPtrHashKey<MediaRawData>, DecryptPromiseRequestHolder> mDecrypts;
   RefPtr<SamplesWaitingForKey> mSamplesWaitingForKey;
--- a/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.h
+++ b/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.h
@@ -69,16 +69,20 @@ public:
   {
   }
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
+  const char* GetDescriptionName() const override
+  {
+    return "GMP audio decoder";
+  }
 
 protected:
   virtual void InitTags(nsTArray<nsCString>& aTags);
   virtual nsCString GetNodeId();
 
 private:
 
   class GMPInitDoneCallback : public GetGMPAudioDecoderCallback
--- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
+++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
@@ -84,16 +84,20 @@ public:
   {
   }
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
+  const char* GetDescriptionName() const override
+  {
+    return "GMP video decoder";
+  }
 
 protected:
   virtual void InitTags(nsTArray<nsCString>& aTags);
   virtual nsCString GetNodeId();
   virtual GMPUniquePtr<GMPVideoEncodedFrame> CreateFrame(MediaRawData* aSample);
 
 private:
 
--- a/dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.h
+++ b/dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.h
@@ -133,16 +133,21 @@ public:
   // asynchronously and responded to via the MediaDataDecoderCallback.
   // Note: the nsresults returned by the proxied decoder are lost.
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
 
+  const char* GetDescriptionName() const override
+  {
+    return "GMP proxy data decoder";
+  }
+
   // Called by MediaDataDecoderCallbackProxy.
   void FlushComplete();
 
 private:
   RefPtr<InitPromise> InternalInit();
 
 #ifdef DEBUG
   bool IsOnProxyThread() {
--- a/dom/media/platforms/android/AndroidDecoderModule.cpp
+++ b/dom/media/platforms/android/AndroidDecoderModule.cpp
@@ -80,16 +80,21 @@ public:
     : MediaCodecDataDecoder(MediaData::Type::VIDEO_DATA, aConfig.mMimeType,
                             aFormat, aCallback)
     , mImageContainer(aImageContainer)
     , mConfig(aConfig)
   {
 
   }
 
+  const char* GetDescriptionName() const override
+  {
+    return "android video decoder";
+  }
+
   RefPtr<InitPromise> Init() override
   {
     mSurfaceTexture = AndroidSurfaceTexture::Create();
     if (!mSurfaceTexture) {
       NS_WARNING("Failed to create SurfaceTexture for video decode\n");
       return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
     }
 
@@ -184,16 +189,21 @@ public:
       buffer = jni::Object::LocalRef::Adopt(
           env, env->NewDirectByteBuffer(aConfig.mCodecSpecificConfig->Elements(),
           aConfig.mCodecSpecificConfig->Length()));
       NS_ENSURE_SUCCESS_VOID(aFormat->SetByteBuffer(NS_LITERAL_STRING("csd-0"),
                                                     buffer));
     }
   }
 
+  const char* GetDescriptionName() const override
+  {
+    return "android audio decoder";
+  }
+
   nsresult Output(BufferInfo::Param aInfo, void* aBuffer,
                   MediaFormat::Param aFormat, const TimeUnit& aDuration)
   {
     // The output on Android is always 16-bit signed
     nsresult rv;
     int32_t numChannels;
     NS_ENSURE_SUCCESS(rv =
         aFormat->GetInteger(NS_LITERAL_STRING("channel-count"), &numChannels), rv);
--- a/dom/media/platforms/android/AndroidDecoderModule.h
+++ b/dom/media/platforms/android/AndroidDecoderModule.h
@@ -52,16 +52,20 @@ public:
 
   virtual ~MediaCodecDataDecoder();
 
   RefPtr<MediaDataDecoder::InitPromise> Init() override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
   nsresult Input(MediaRawData* aSample) override;
+  const char* GetDescriptionName() const override
+  {
+    return "android decoder";
+  }
 
 protected:
   enum ModuleState {
     kDecoding = 0,
     kFlushing,
     kDrainQueue,
     kDrainDecoder,
     kDrainWaitEOS,
--- a/dom/media/platforms/apple/AppleATDecoder.h
+++ b/dom/media/platforms/apple/AppleATDecoder.h
@@ -26,16 +26,21 @@ public:
   virtual ~AppleATDecoder();
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
 
+  const char* GetDescriptionName() const override
+  {
+    return "apple CoreMedia decoder";
+  }
+
   // Callbacks also need access to the config.
   const AudioInfo& mConfig;
 
   // Use to extract magic cookie for HE-AAC detection.
   nsTArray<uint8_t> mMagicCookie;
   // Will be set to true should an error occurred while attempting to retrieve
   // the magic cookie property.
   bool mFileStreamError;
--- a/dom/media/platforms/apple/AppleVDADecoder.h
+++ b/dom/media/platforms/apple/AppleVDADecoder.h
@@ -76,16 +76,21 @@ public:
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override
   {
     return true;
   }
 
+  const char* GetDescriptionName() const override
+  {
+    return "apple VDA decoder";
+  }
+
   // Access from the taskqueue and the decoder's thread.
   // OutputFrame is thread-safe.
   nsresult OutputFrame(CVPixelBufferRef aImage,
                        AppleFrameRef aFrameRef);
 
 protected:
   // Flush and Drain operation, always run
   virtual void ProcessFlush();
--- a/dom/media/platforms/apple/AppleVTDecoder.h
+++ b/dom/media/platforms/apple/AppleVTDecoder.h
@@ -22,30 +22,37 @@ public:
   virtual ~AppleVTDecoder();
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override
   {
     return mIsHardwareAccelerated;
   }
 
+  const char* GetDescriptionName() const override
+  {
+    return mIsHardwareAccelerated
+      ? "apple hardware VT decoder"
+      : "apple software VT decoder";
+  }
+
 protected:
   void ProcessFlush() override;
   void ProcessDrain() override;
   void ProcessShutdown() override;
 
 private:
   CMVideoFormatDescriptionRef mFormat;
   VTDecompressionSessionRef mSession;
 
   // Method to pass a frame to VideoToolbox for decoding.
   nsresult SubmitFrame(MediaRawData* aSample);
   // Method to set up the decompression session.
   nsresult InitializeSession();
   nsresult WaitForAsynchronousFrames();
   CFDictionaryRef CreateDecoderSpecification();
   CFDictionaryRef CreateDecoderExtensions();
-  bool mIsHardwareAccelerated;
+  Atomic<bool> mIsHardwareAccelerated;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_AppleVTDecoder_h
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
@@ -26,16 +26,20 @@ public:
                      const AudioInfo& aConfig);
   virtual ~FFmpegAudioDecoder();
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   void ProcessDrain() override;
   void InitCodecContext() override;
   static AVCodecID GetCodecId(const nsACString& aMimeType);
+  const char* GetDescriptionName() const override
+  {
+    return "ffmpeg audio decoder";
+  }
 
 private:
   void DecodePacket(MediaRawData* aSample);
 };
 
 } // namespace mozilla
 
 #endif // __FFmpegAACDecoder_h__
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -39,16 +39,24 @@ public:
                      ImageContainer* aImageContainer);
   virtual ~FFmpegVideoDecoder();
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   void ProcessDrain() override;
   void ProcessFlush() override;
   void InitCodecContext() override;
+  const char* GetDescriptionName() const override
+  {
+#ifdef USING_MOZFFVPX
+    return "ffvpx video decoder";
+#else
+    return "ffmpeg video decoder";
+#endif
+  }
   static AVCodecID GetCodecId(const nsACString& aMimeType);
 
 private:
   void DecodeFrame(MediaRawData* aSample);
   DecodeResult DoDecodeFrame(MediaRawData* aSample);
   DecodeResult DoDecodeFrame(MediaRawData* aSample, uint8_t* aData, int aSize);
   void DoDrain();
   void OutputDelayedFrames();
--- a/dom/media/platforms/gonk/GonkAudioDecoderManager.h
+++ b/dom/media/platforms/gonk/GonkAudioDecoderManager.h
@@ -28,16 +28,21 @@ public:
 
   RefPtr<InitPromise> Init() override;
 
   nsresult Output(int64_t aStreamOffset,
                           RefPtr<MediaData>& aOutput) override;
 
   void ProcessFlush() override;
 
+  const char* GetDescriptionName() const override
+  {
+    return "gonk audio decoder";
+  }
+
 private:
   bool InitMediaCodecProxy();
 
   nsresult CreateAudioData(MediaBuffer* aBuffer, int64_t aStreamOffset);
 
   uint32_t mAudioChannels;
   uint32_t mAudioRate;
   const uint32_t mAudioProfile;
--- a/dom/media/platforms/gonk/GonkMediaDataDecoder.h
+++ b/dom/media/platforms/gonk/GonkMediaDataDecoder.h
@@ -23,16 +23,17 @@ class GonkDecoderManager : public androi
 public:
   typedef TrackInfo::TrackType TrackType;
   typedef MediaDataDecoder::InitPromise InitPromise;
   typedef MediaDataDecoder::DecoderFailureReason DecoderFailureReason;
 
   virtual ~GonkDecoderManager() {}
 
   virtual RefPtr<InitPromise> Init() = 0;
+  virtual const char* GetDescriptionName() const = 0;
 
   // Asynchronously send sample into mDecoder. If out of input buffer, aSample
   // will be queued for later re-send.
   nsresult Input(MediaRawData* aSample);
 
   // Flush the queued samples and signal decoder to throw all pending input/output away.
   nsresult Flush();
 
@@ -194,16 +195,21 @@ public:
   nsresult Input(MediaRawData* aSample) override;
 
   nsresult Flush() override;
 
   nsresult Drain() override;
 
   nsresult Shutdown() override;
 
+  const char* GetDescriptionName() const override
+  {
+    return "gonk decoder";
+  }
+
 private:
 
   android::sp<GonkDecoderManager> mManager;
 };
 
 } // namespace mozilla
 
 #endif // GonkMediaDataDecoder_h_
--- a/dom/media/platforms/gonk/GonkVideoDecoderManager.h
+++ b/dom/media/platforms/gonk/GonkVideoDecoderManager.h
@@ -45,16 +45,21 @@ public:
 
   RefPtr<InitPromise> Init() override;
 
   nsresult Output(int64_t aStreamOffset,
                           RefPtr<MediaData>& aOutput) override;
 
   nsresult Shutdown() override;
 
+  const char* GetDescriptionName() const override
+  {
+    return "gonk video decoder";
+  }
+
   static void RecycleCallback(TextureClient* aClient, void* aClosure);
 
 protected:
   // Bug 1199809: workaround to avoid sending the graphic buffer by making a
   // copy of output buffer after calling flush(). Bug 1203859 was created to
   // reimplementing Gonk PDM on top of OpenMax IL directly. Its buffer
   // management will work better with Gecko and solve problems like this.
   void ProcessFlush() override
--- a/dom/media/platforms/omx/OmxDataDecoder.h
+++ b/dom/media/platforms/omx/OmxDataDecoder.h
@@ -66,16 +66,21 @@ public:
   nsresult Input(MediaRawData* aSample) override;
 
   nsresult Flush() override;
 
   nsresult Drain() override;
 
   nsresult Shutdown() override;
 
+  const char* GetDescriptionName() const override
+  {
+    return "omx decoder";
+  }
+
   // Return true if event is handled.
   bool Event(OMX_EVENTTYPE aEvent, OMX_U32 aData1, OMX_U32 aData2);
 
 protected:
   void InitializationTask();
 
   void ResolveInitPromise(const char* aMethodName);
 
--- a/dom/media/platforms/wmf/WMFAudioMFTManager.h
+++ b/dom/media/platforms/wmf/WMFAudioMFTManager.h
@@ -33,16 +33,21 @@ public:
                          RefPtr<MediaData>& aOutput) override;
 
   void Shutdown() override;
 
   TrackInfo::TrackType GetType() override {
     return TrackInfo::kAudioTrack;
   }
 
+  const char* GetDescriptionName() const override
+  {
+    return "wmf audio decoder";
+  }
+
 private:
 
   HRESULT UpdateOutputType();
 
   uint32_t mAudioChannels;
   uint32_t mAudioRate;
   nsTArray<BYTE> mUserData;
 
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.h
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
@@ -49,16 +49,18 @@ public:
   virtual void Shutdown() = 0;
 
   virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const { return false; }
 
   virtual TrackInfo::TrackType GetType() = 0;
 
   virtual void ConfigurationChanged(const TrackInfo& aConfig) {}
 
+  virtual const char* GetDescriptionName() const = 0;
+
 protected:
   // IMFTransform wrapper that performs the decoding.
   RefPtr<MFTDecoder> mDecoder;
 };
 
 // Decodes audio and video using Windows Media Foundation. Samples are decoded
 // using the MFTDecoder created by the MFTManager. This class implements
 // the higher-level logic that drives mapping the MFT to the async
@@ -80,16 +82,21 @@ public:
   nsresult Drain() override;
 
   nsresult Shutdown() override;
 
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
 
   nsresult ConfigurationChanged(const TrackInfo& aConfig) override;
 
+  const char* GetDescriptionName() const override
+  {
+    return mMFTManager ? mMFTManager->GetDescriptionName() : "";
+  }
+
 private:
 
   // Called on the task queue. Inserts the sample into the decoder, and
   // extracts output if available.
   void ProcessDecode(MediaRawData* aSample);
 
   // Called on the task queue. Extracts output if available, and delivers
   // it to the reader. Called after ProcessDecode() and ProcessDrain().
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.h
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.h
@@ -36,16 +36,23 @@ public:
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
 
   TrackInfo::TrackType GetType() override {
     return TrackInfo::kVideoTrack;
   }
 
   void ConfigurationChanged(const TrackInfo& aConfig) override;
 
+  const char* GetDescriptionName() const override
+  {
+    nsCString failureReason;
+    return IsHardwareAccelerated(failureReason)
+      ? "wmf hardware video decoder" : "wmf software video decoder";
+  }
+
 private:
 
   bool InitializeDXVA(bool aForceD3D9);
 
   bool InitInternal(bool aForceD3D9);
 
   HRESULT ConfigureVideoFrameGeometry();
 
--- a/dom/media/platforms/wrappers/FuzzingWrapper.h
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.h
@@ -106,16 +106,20 @@ private:
   // MediaDataDecoder implementation.
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
   nsresult ConfigurationChanged(const TrackInfo& aConfig) override;
+  const char* GetDescriptionName() const override
+  {
+    return mDecoder->GetDescriptionName();
+  }
 
   RefPtr<MediaDataDecoder> mDecoder;
   RefPtr<DecoderCallbackFuzzingWrapper> mCallbackWrapper;
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/media/platforms/wrappers/H264Converter.h
+++ b/dom/media/platforms/wrappers/H264Converter.h
@@ -30,16 +30,23 @@ public:
   virtual ~H264Converter();
 
   RefPtr<InitPromise> Init() override;
   nsresult Input(MediaRawData* aSample) override;
   nsresult Flush() override;
   nsresult Drain() override;
   nsresult Shutdown() override;
   bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
+  const char* GetDescriptionName() const override
+  {
+    if (mDecoder) {
+      return mDecoder->GetDescriptionName();
+    }
+    return "H264Converter decoder (pending)";
+  }
 
   // Return true if mimetype is H.264.
   static bool IsH264(const TrackInfo& aConfig);
   nsresult GetLastError() const { return mLastError; }
 
 private:
   // Will create the required MediaDataDecoder if need AVCC and we have a SPS NAL.
   // Returns NS_ERROR_FAILURE if error is permanent and can't be recovered and