Bug 1211335: Have FFMpegDecoderModule properly return if a codec is supported. r=cpearce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 06 Oct 2015 22:55:18 +1100
changeset 266524 fe514a4a22a35a50f01d5a8a9a8f0620d2ed6e40
parent 266523 aa355229d6b5c89bd635041d63661de7c5b3e65b
child 266525 4190ef9edc26d908419de71575f03d7592179a7f
push id66221
push userjyavenard@mozilla.com
push dateWed, 07 Oct 2015 13:35:19 +0000
treeherdermozilla-inbound@5c92ba05c3ba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1211335
milestone44.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 1211335: Have FFMpegDecoderModule properly return if a codec is supported. r=cpearce
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();
 
   nsRefPtr<InitPromise> Init() override = 0;
   nsresult Input(MediaRawData* aSample) override = 0;
   nsresult Flush() override;
   nsresult Drain() override;
   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
@@ -63,18 +63,23 @@ public:
   {
     nsRefPtr<MediaDataDecoder> decoder =
       new FFmpegAudioDecoder<V>(aAudioTaskQueue, aCallback, aConfig);
     return decoder.forget();
   }
 
   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);
   }
 
   ConversionRequired
   DecoderNeedsConversion(const TrackInfo& aConfig) const override
   {
     if (aConfig.IsVideo() &&
         (aConfig.mMimeType.EqualsLiteral("video/avc") ||
          aConfig.mMimeType.EqualsLiteral("video/mp4"))) {