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
--- 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: