diff options
author | Deb Mukherjee <debargha@google.com> | 2014-09-14 07:43:27 -0700 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-09-14 20:27:28 +0200 |
commit | 04b0dda853198980a14158809e560ea9ca9d7e33 (patch) | |
tree | 58a6ed62d757e1f6126294b01d7b048698c697e3 | |
parent | b24d74e44ae5fecba51d79cd0d0a1d1dffcaf771 (diff) | |
download | ffmpeg-04b0dda853198980a14158809e560ea9ca9d7e33.tar.gz |
avcodec/libvpxdec: Adds decode support for formats other than 420
Handles decoding of new VP9 profiles 1-3 with different color sampling
and bit-depths.
For high bitdepth (profiles 2 and 3) support, we currently need to link
with the highbitdepth branch of libvpx with --enable-experimental
and --enable-vp9-high config options on. But eventually this branch will
be merged into master, whereafter to enable high bitdepth
support you will need to link with libvpx with configure option
--enable-vp9-highbitdepth on.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/libvpxdec.c | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index 94e1e4d1ef..8312460f53 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -60,6 +60,57 @@ static av_cold int vpx_init(AVCodecContext *avctx, return 0; } +// returns 0 on success, AVERROR_INVALIDDATA otherwise +static int set_pix_fmt(AVCodecContext *avctx, struct vpx_image *img) { + if (avctx->codec_id == AV_CODEC_ID_VP8 && img->fmt != VPX_IMG_FMT_I420) + return AVERROR_INVALIDDATA; + switch (img->fmt) { + case VPX_IMG_FMT_I420: + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + return 0; + case VPX_IMG_FMT_I422: + avctx->pix_fmt = AV_PIX_FMT_YUV422P; + return 0; + case VPX_IMG_FMT_I444: + avctx->pix_fmt = AV_PIX_FMT_YUV444P; + return 0; +#ifdef VPX_IMG_FMT_HIGHBITDEPTH + case VPX_IMG_FMT_I42016: + if (img->bit_depth == 10) { + avctx->pix_fmt = AV_PIX_FMT_YUV420P10LE; + return 0; + } else if (img->bit_depth == 12) { + avctx->pix_fmt = AV_PIX_FMT_YUV420P12LE; + return 0; + } else { + return AVERROR_INVALIDDATA; + } + case VPX_IMG_FMT_I42216: + if (img->bit_depth == 10) { + avctx->pix_fmt = AV_PIX_FMT_YUV422P10LE; + return 0; + } else if (img->bit_depth == 12) { + avctx->pix_fmt = AV_PIX_FMT_YUV422P12LE; + return 0; + } else { + return AVERROR_INVALIDDATA; + } + case VPX_IMG_FMT_I44416: + if (img->bit_depth == 10) { + avctx->pix_fmt = AV_PIX_FMT_YUV444P10LE; + return 0; + } else if (img->bit_depth == 12) { + avctx->pix_fmt = AV_PIX_FMT_YUV444P12LE; + return 0; + } else { + return AVERROR_INVALIDDATA; + } +#endif + default: + return AVERROR_INVALIDDATA; + } +} + static int vp8_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -82,10 +133,15 @@ static int vp8_decode(AVCodecContext *avctx, } if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) { - if (img->fmt != VPX_IMG_FMT_I420) { - av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n", - img->fmt); - return AVERROR_INVALIDDATA; + if ((ret = set_pix_fmt(avctx, img)) < 0) { +#ifdef VPX_IMG_FMT_HIGHBITDEPTH + av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n", + img->fmt, img->bit_depth); +#else + av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n", + img->fmt, 8); +#endif + return ret; } if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) { |