Bug 1211335: Have FFMpegDecoderModule properly return if a codec is supported. r=cpearce a=lizzard
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 06 Oct 2015 22:55:18 +1100
changeset 296466 6787b57b02300454dc7e4c8a64f375c4d2956b51
parent 296465 e5871ff057719f6fa3e69677bfe5fb779d6f7832
child 296467 8990ce7755ed846a560c7731af59fee7177eb871
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, lizzard
bugs1211335
milestone43.0a2
Bug 1211335: Have FFMpegDecoderModule properly return if a codec is supported. r=cpearce a=lizzard
dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
@@ -65,34 +65,26 @@ ChoosePixelFormat(AVCodecContext* aCodec
 
   NS_WARNING("FFmpeg does not share any supported pixel formats.");
   return PIX_FMT_NONE;
 }
 
 nsresult
 FFmpegDataDecoder<LIBAV_VER>::InitDecoder()
 {
-  StaticMutexAutoLock mon(sMonitor);
-
   FFMPEG_LOG("Initialising FFmpeg decoder.");
 
-  if (!sFFmpegInitDone) {
-    avcodec_register_all();
-#ifdef DEBUG
-    av_log_set_level(AV_LOG_DEBUG);
-#endif
-    sFFmpegInitDone = true;
-  }
-
-  AVCodec* codec = avcodec_find_decoder(mCodecID);
+  AVCodec* codec = FindAVCodec(mCodecID);
   if (!codec) {
     NS_WARNING("Couldn't find ffmpeg decoder");
     return NS_ERROR_FAILURE;
   }
 
+  StaticMutexAutoLock mon(sMonitor);
+
   if (!(mCodecContext = avcodec_alloc_context3(codec))) {
     NS_WARNING("Couldn't init ffmpeg context");
     return NS_ERROR_FAILURE;
   }
 
   mCodecContext->opaque = this;
 
   // FFmpeg takes this as a suggestion for what format to use for audio samples.
@@ -235,9 +227,23 @@ FFmpegDataDecoder<LIBAV_VER>::PrepareFra
 #else
   delete mFrame;
   mFrame = new AVFrame;
   avcodec_get_frame_defaults(mFrame);
 #endif
   return mFrame;
 }
 
+/* static */ AVCodec*
+FFmpegDataDecoder<LIBAV_VER>::FindAVCodec(AVCodecID aCodec)
+{
+  StaticMutexAutoLock mon(sMonitor);
+  if (!sFFmpegInitDone) {
+    avcodec_register_all();
+#ifdef DEBUG
+    av_log_set_level(AV_LOG_DEBUG);
+#endif
+    sFFmpegInitDone = true;
+  }
+  return avcodec_find_decoder(aCodec);
+}
+  
 } // namespace mozilla
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
@@ -31,16 +31,18 @@ public:
   static bool Link();
 
   virtual nsRefPtr<InitPromise> Init() override = 0;
   virtual nsresult Input(MediaRawData* aSample) override = 0;
   virtual nsresult Flush() override;
   virtual nsresult Drain() override;
   virtual nsresult Shutdown() override;
 
+  static AVCodec* FindAVCodec(AVCodecID aCodec);
+
 protected:
   // Flush and Drain operation, always run
   virtual void ProcessFlush();
   virtual void ProcessDrain() = 0;
   virtual void ProcessShutdown();
   AVFrame*        PrepareFrame();
   nsresult        InitDecoder();
 
--- a/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
+++ b/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
@@ -57,18 +57,23 @@ public:
   {
     nsRefPtr<MediaDataDecoder> decoder =
       new FFmpegAudioDecoder<V>(aAudioTaskQueue, aCallback, aConfig);
     return decoder.forget();
   }
 
   virtual bool SupportsMimeType(const nsACString& aMimeType) override
   {
-    return FFmpegAudioDecoder<V>::GetCodecId(aMimeType) != AV_CODEC_ID_NONE ||
-      FFmpegH264Decoder<V>::GetCodecId(aMimeType) != AV_CODEC_ID_NONE;
+    AVCodecID audioCodec = FFmpegAudioDecoder<V>::GetCodecId(aMimeType);
+    AVCodecID videoCodec = FFmpegH264Decoder<V>::GetCodecId(aMimeType);
+    if (audioCodec == AV_CODEC_ID_NONE && videoCodec == AV_CODEC_ID_NONE) {
+      return false;
+    }
+    AVCodecID codec = audioCodec != AV_CODEC_ID_NONE ? audioCodec : videoCodec;
+    return !!FFmpegDataDecoder<V>::FindAVCodec(codec);
   }
 
   virtual ConversionRequired
   DecoderNeedsConversion(const TrackInfo& aConfig) const override
   {
     if (aConfig.IsVideo() &&
         (aConfig.mMimeType.EqualsLiteral("video/avc") ||
          aConfig.mMimeType.EqualsLiteral("video/mp4"))) {