[FFmpeg-devel] [PATCH] Adds decode support for formats other than 420
James Almer
jamrial at gmail.com
Sat Aug 23 00:34:16 CEST 2014
On 22/08/14 5:31 PM, Deb Mukherjee wrote:
> 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
0 on success, AVERROR_INVALIDDATA otherwise.
> +static int set_pix_fmt(AVCodecContext *avctx, struct vpx_image *img) {
> + int ret = 0;
No need for this variable. Just return the corresponding value directly.
> + 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:
Fails to compile with libvpx 1.3.0 and older.
A quick solution would be to check if VPX_IMG_FMT_HIGH is defined and put all
these inside pre-processor guards.
> + 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)) {
if ((ret = set_pix_fmt(avctx, img)) < 0)
Then use "return ret;" below to propagate the value returned by set_pix_fmt();
> + av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n",
> + img->fmt, img->bit_depth);
Same here, bit_depth is not available in the vpx_image struct in libvpx <= 1.3.0.
Either remove it, or hardcode an 8 if VPX_IMG_FMT_HIGH is not defined.
More information about the ffmpeg-devel
mailing list