Bug 1215089 - P4: Add support to 10 and 12 bits YUV images to FFmpeg decoder. r?kentuckyfriedtakahe draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 29 Jun 2017 23:11:06 +0200
changeset 675221 492cb88347db300c3bba1fdbe2584d78a2bc55bd
parent 675220 05e935df28a6794e107be5ab3ee15c3b0264b643
child 675222 607a0b583147c2cb0b927cbc339a371d24255ffa
push id83072
push userbmo:jyavenard@mozilla.com
push dateThu, 05 Oct 2017 01:30:32 +0000
reviewerskentuckyfriedtakahe
bugs1215089
milestone58.0a1
Bug 1215089 - P4: Add support to 10 and 12 bits YUV images to FFmpeg decoder. r?kentuckyfriedtakahe This allows for decoding VP9 profile 2 and 3. At this stage, it is not possible to render the decoded frames. MozReview-Commit-ID: DFXMvaM8Ynb
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -14,16 +14,18 @@
 
 #include "libavutil/pixfmt.h"
 #if LIBAVCODEC_VERSION_MAJOR < 54
 #define AVPixelFormat PixelFormat
 #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
 #define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
 #define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
 #define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P
+#define AV_PIX_FMT_YUV420P10LE PIX_FMT_YUV420P10LE
+#define AV_PIX_FMT_YUV444P10LE PIX_FMT_YUV444P10LE
 #define AV_PIX_FMT_NONE PIX_FMT_NONE
 #endif
 #include "mozilla/PodOperations.h"
 #include "mozilla/TaskQueue.h"
 #include "nsThreadUtils.h"
 #include "prsystem.h"
 
 
@@ -53,16 +55,27 @@ ChoosePixelFormat(AVCodecContext* aCodec
         FFMPEG_LOG("Requesting pixel format YUV422P.");
         return AV_PIX_FMT_YUV422P;
       case AV_PIX_FMT_YUV420P:
         FFMPEG_LOG("Requesting pixel format YUV420P.");
         return AV_PIX_FMT_YUV420P;
       case AV_PIX_FMT_YUVJ420P:
         FFMPEG_LOG("Requesting pixel format YUVJ420P.");
         return AV_PIX_FMT_YUVJ420P;
+      case AV_PIX_FMT_YUV420P10LE:
+        FFMPEG_LOG("Requesting pixel format YUV420P10LE.");
+        return AV_PIX_FMT_YUV420P10LE;
+      case AV_PIX_FMT_YUV444P10LE:
+        FFMPEG_LOG("Requesting pixel format YUV444P10LE.");
+        return AV_PIX_FMT_YUV444P10LE;
+#if LIBAVCODEC_VERSION_MAJOR >= 57
+      case AV_PIX_FMT_YUV444P12LE:
+        FFMPEG_LOG("Requesting pixel format YUV444P12LE.");
+        return AV_PIX_FMT_YUV444P12LE;
+#endif
       default:
         break;
     }
   }
 
   NS_WARNING("FFmpeg does not share any supported pixel formats.");
   return AV_PIX_FMT_NONE;
 }
@@ -316,25 +329,42 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
   b.mPlanes[2].mStride = mFrame->linesize[2];
 
   b.mPlanes[0].mOffset = b.mPlanes[0].mSkip = 0;
   b.mPlanes[1].mOffset = b.mPlanes[1].mSkip = 0;
   b.mPlanes[2].mOffset = b.mPlanes[2].mSkip = 0;
 
   b.mPlanes[0].mWidth = mFrame->width;
   b.mPlanes[0].mHeight = mFrame->height;
-  if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P) {
+  if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P ||
+      mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P10LE
+#if LIBAVCODEC_VERSION_MAJOR >= 57
+      ||
+      mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P12LE
+#endif
+      ) {
     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = mFrame->width;
     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height;
+    if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P10LE) {
+      b.mBitDepth = 10;
+    }
+#if LIBAVCODEC_VERSION_MAJOR >= 57
+    else if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P12LE) {
+      b.mBitDepth = 12;
+    }
+#endif
   } else if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV422P) {
     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height;
   } else {
     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = (mFrame->height + 1) >> 1;
+    if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV420P10LE) {
+      b.mBitDepth = 10;
+    }
   }
   if (mLib->av_frame_get_colorspace) {
     switch (mLib->av_frame_get_colorspace(mFrame)) {
       case AVCOL_SPC_BT709:
         b.mYUVColorSpace = YUVColorSpace::BT709;
         break;
       case AVCOL_SPC_SMPTE170M:
       case AVCOL_SPC_BT470BG: