Handles new VP9 profiles 1-3 with different color sampling and bit-depths. --- libavcodec/libvpxdec.c | 69 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 9 deletions(-)
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index 94e1e4d..7c397fb 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -60,7 +60,58 @@ static av_cold int vpx_init(AVCodecContext *avctx, return 0; } -static int vp8_decode(AVCodecContext *avctx, +// returns 0 on success, 1 on unsupported +static int set_pix_fmt(AVCodecContext *avctx, struct vpx_image *img) { + int ret = 0; + if (avctx->codec_id == AV_CODEC_ID_VP8) { + if (img->fmt != VPX_IMG_FMT_I420) + return 1; + } + switch (img->fmt) { + case VPX_IMG_FMT_I420: + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + break; + case VPX_IMG_FMT_I422: + avctx->pix_fmt = AV_PIX_FMT_YUV422P; + break; + case VPX_IMG_FMT_I444: + avctx->pix_fmt = AV_PIX_FMT_YUV444P; + break; + case VPX_IMG_FMT_I42016: + if (img->bit_depth == 10) { + avctx->pix_fmt = AV_PIX_FMT_YUV420P10LE; + } else if (img->bit_depth == 12) { + avctx->pix_fmt = AV_PIX_FMT_YUV420P12LE; + } else { + ret = 1; + } + break; + case VPX_IMG_FMT_I42216: + if (img->bit_depth == 10) { + avctx->pix_fmt = AV_PIX_FMT_YUV422P10LE; + } else if (img->bit_depth == 12) { + avctx->pix_fmt = AV_PIX_FMT_YUV422P12LE; + } else { + ret = 1; + } + break; + case VPX_IMG_FMT_I44416: + if (img->bit_depth == 10) { + avctx->pix_fmt = AV_PIX_FMT_YUV444P10LE; + } else if (img->bit_depth == 12) { + avctx->pix_fmt = AV_PIX_FMT_YUV444P12LE; + } else { + ret = 1; + } + break; + default: + ret = 1; + break; + } + return ret; +} + +static int vpx_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { VP8Context *ctx = avctx->priv_data; @@ -82,9 +133,9 @@ 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); + if (set_pix_fmt(avctx, img)) { + av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n", + img->fmt, img->bit_depth); return AVERROR_INVALIDDATA; } @@ -104,7 +155,7 @@ static int vp8_decode(AVCodecContext *avctx, return avpkt->size; } -static av_cold int vp8_free(AVCodecContext *avctx) +static av_cold int vpx_free(AVCodecContext *avctx) { VP8Context *ctx = avctx->priv_data; vpx_codec_destroy(&ctx->decoder); @@ -124,8 +175,8 @@ AVCodec ff_libvpx_vp8_decoder = { .id = AV_CODEC_ID_VP8, .priv_data_size = sizeof(VP8Context), .init = vp8_init, - .close = vp8_free, - .decode = vp8_decode, + .close = vpx_free, + .decode = vpx_decode, .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1, }; #endif /* CONFIG_LIBVPX_VP8_DECODER */ @@ -143,8 +194,8 @@ AVCodec ff_libvpx_vp9_decoder = { .id = AV_CODEC_ID_VP9, .priv_data_size = sizeof(VP8Context), .init = vp9_init, - .close = vp8_free, - .decode = vp8_decode, + .close = vpx_free, + .decode = vpx_decode, .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1, .init_static_data = ff_vp9_init_static, }; -- 2.1.0.rc2.206.gedb03e5 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel