[5/6] Add AV1 video decoding support through libaom

Message ID 1472138898-16470-5-git-send-email-diego@biurrun.de
State New
Headers show

Commit Message

Diego Biurrun Aug. 25, 2016, 3:28 p.m.
From: Luca Barbato <lu_zero@gentoo.org>

Signed-off-by: Diego Biurrun <diego@biurrun.de>
---

some minor changes, version bump

 Changelog              |   1 +
 configure              |   4 ++
 doc/general.texi       |  10 ++++
 libavcodec/Makefile    |   2 +
 libavcodec/allcodecs.c |   1 +
 libavcodec/libaom.c    |  75 +++++++++++++++++++++++++++
 libavcodec/libaom.h    |  31 +++++++++++
 libavcodec/libaomdec.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/version.h   |   2 +-
 9 files changed, 262 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/libaom.c
 create mode 100644 libavcodec/libaom.h
 create mode 100644 libavcodec/libaomdec.c

Comments

Harfe Leier Aug. 25, 2016, 4:10 p.m. | #1
Hi,

I tested this patch with videos encoded by aomenc, and found that for
10/12-bit av1 videos this patch decodes incorrectly. I found that
ff_aom_imgfmt_to_pixfmt might not work as supposed for high bit depth. Like
libvpx, avctx->pix_fmt should be set by both img->fmt and img->bit_depth.
Also it seems that AV_PIX_FMT_YUV4XXP10/12/16 should use LE instead of BE.
So after I change ff_aom_imgfmt_to_pixfmt to the following one:

+enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img, unsigned int
bit_depth)
+{
+    switch (img) {
+    case AOM_IMG_FMT_RGB24:     return AV_PIX_FMT_RGB24;
+    case AOM_IMG_FMT_RGB565:    return AV_PIX_FMT_RGB565BE;  // I didn't
test RGB565 if it uses BE
+    case AOM_IMG_FMT_RGB555:    return AV_PIX_FMT_RGB555BE;  // I didn't
test RGB555 if it uses BE
+    case AOM_IMG_FMT_UYVY:      return AV_PIX_FMT_UYVY422;
+    case AOM_IMG_FMT_YUY2:      return AV_PIX_FMT_YUYV422;
+    case AOM_IMG_FMT_YVYU:      return AV_PIX_FMT_YVYU422;
+    case AOM_IMG_FMT_BGR24:     return AV_PIX_FMT_BGR24;
+    case AOM_IMG_FMT_ARGB:      return AV_PIX_FMT_ARGB;
+    case AOM_IMG_FMT_ARGB_LE:   return AV_PIX_FMT_BGRA;
+    case AOM_IMG_FMT_RGB565_LE: return AV_PIX_FMT_RGB565LE;
+    case AOM_IMG_FMT_RGB555_LE: return AV_PIX_FMT_RGB555LE;
+    case AOM_IMG_FMT_I420:      return AV_PIX_FMT_YUV420P;
+    case AOM_IMG_FMT_I422:      return AV_PIX_FMT_YUV422P;
+    case AOM_IMG_FMT_I444:      return AV_PIX_FMT_YUV444P;
+    case AOM_IMG_FMT_444A:      return AV_PIX_FMT_YUVA444P;
+#if AOM_IMAGE_ABI_VERSION >= 3
+    case AOM_IMG_FMT_I440:      return AV_PIX_FMT_YUV440P;
+    case AOM_IMG_FMT_I42016:
+        switch (bit_depth) {
+            case 10: return AV_PIX_FMT_YUV420P10;
+            case 12: return AV_PIX_FMT_YUV420P12;
+        }
+    case AOM_IMG_FMT_I42216:
+        switch (bit_depth) {
+            case 10: return AV_PIX_FMT_YUV422P10;
+            case 12: return AV_PIX_FMT_YUV422P12;
+        }
+    case AOM_IMG_FMT_I44416:
+        switch (bit_depth) {
+            case 10: return AV_PIX_FMT_YUV444P10;
+            case 12: return AV_PIX_FMT_YUV444P12;
+        }
+#endif
+    default:                    return AV_PIX_FMT_NONE;
+    }
+}

and use
+        avctx->pix_fmt = ff_aom_imgfmt_to_pixfmt(img->fmt, img->bit_depth);
in libaomdec, the decoding result is identical to aomdec.

If it is correct to do this, ff_aom_pixfmt_to_imgfmt might also need to be
re-defined. While libaom can be built with or without high bit depth
support (--enable/disable-aom-highbitdepth), it does not expose a macro
like AOM_IMG_FMT_HIGHBITDEPTH. It only defines CONFIG_AOM_HIGHBITDEPTH in
aom_config.h which is used for building aom reference tools only. I'm not
sure if we should add further check on the pixel format conversion above.

Lucien


On 25 August 2016 at 23:28, Diego Biurrun <diego@biurrun.de> wrote:

> From: Luca Barbato <lu_zero@gentoo.org>
>
> Signed-off-by: Diego Biurrun <diego@biurrun.de>
> ---
>
> some minor changes, version bump
>
>  Changelog              |   1 +
>  configure              |   4 ++
>  doc/general.texi       |  10 ++++
>  libavcodec/Makefile    |   2 +
>  libavcodec/allcodecs.c |   1 +
>  libavcodec/libaom.c    |  75 +++++++++++++++++++++++++++
>  libavcodec/libaom.h    |  31 +++++++++++
>  libavcodec/libaomdec.c | 137 ++++++++++++++++++++++++++++++
> +++++++++++++++++++
>  libavcodec/version.h   |   2 +-
>  9 files changed, 262 insertions(+), 1 deletion(-)
>  create mode 100644 libavcodec/libaom.c
>  create mode 100644 libavcodec/libaom.h
>  create mode 100644 libavcodec/libaomdec.c
>
> diff --git a/Changelog b/Changelog
> index 0d04f47..5ee2346 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -62,6 +62,7 @@ version <next>:
>  - Intel QSV video scaling and deinterlacing filter
>  - OpenH264 decoder wrapper
>  - Removed the legacy X11 screen grabber, use XCB instead
> +- Alliance for Open Media AV1 decoding support using libaom
>
>
>  version 11:
> diff --git a/configure b/configure
> index 8049d90..9cf7a1c 100755
> --- a/configure
> +++ b/configure
> @@ -188,6 +188,7 @@ External library support:
>    --enable-bzlib             bzip2 compression [autodetect]
>    --enable-frei0r            video filtering plugins
>    --enable-gnutls            crypto
> +  --enable-libaom            AV1 video encoding/decoding
>    --enable-libbs2b           Bauer stereophonic-to-binaural DSP
>    --enable-libcdio           audio CD input
>    --enable-libdc1394         IEEE 1394/Firewire camera input
> @@ -1264,6 +1265,7 @@ EXTERNAL_LIBRARY_LIST="
>      bzlib
>      frei0r
>      gnutls
> +    libaom
>      libbs2b
>      libdc1394
>      libdcadec
> @@ -2236,6 +2238,7 @@ vc1_parser_select="vc1dsp"
>  mjpeg2jpeg_bsf_select="jpegtables"
>
>  # external libraries
> +libaom_av1_decoder_deps="libaom"
>  libdcadec_decoder_deps="libdcadec"
>  libfaac_encoder_deps="libfaac"
>  libfaac_encoder_select="audio_frame_queue"
> @@ -4597,6 +4600,7 @@ enabled avisynth          && { check_lib2
> "avisynth/avisynth_c.h windows.h" Load
>  enabled cuda              && check_lib cuda.h cuInit -lcuda
>  enabled frei0r            && { check_header frei0r.h || die "ERROR:
> frei0r.h header not found"; }
>  enabled gnutls            && require_pkg_config gnutls gnutls/gnutls.h
> gnutls_global_init
> +enabled libaom            && require_pkg_config "aom >= 0.1.0"
> aom/aom_codec.h aom_codec_version
>  enabled libbs2b           && require_pkg_config libbs2b bs2b.h bs2b_open
>  enabled libdcadec         && require libdcadec libdcadec/dca_context.h
> dcadec_context_create -ldcadec
>  enabled libfaac           && require2 libfaac "stdint.h faac.h"
> faacEncGetVersion -lfaac
> diff --git a/doc/general.texi b/doc/general.texi
> index ea56bef..63b1afd 100644
> --- a/doc/general.texi
> +++ b/doc/general.texi
> @@ -16,6 +16,14 @@ for more formats. None of them are used by default,
> their use has to be
>  explicitly requested by passing the appropriate flags to
>  @command{./configure}.
>
> +@section Alliance for Open Media libaom
> +
> +Libav can make use of the libaom library for AV1 decoding.
> +
> +Go to @url{http://aomedia.org/} and follow the instructions for
> +installing the library. Then pass @code{--enable-libaom} to configure to
> +enable it.
> +
>  @section OpenCORE and VisualOn libraries
>
>  Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer
> @@ -576,6 +584,8 @@ following image formats are supported:
>  @item Autodesk Animator Flic video  @tab     @tab  X
>  @item Autodesk RLE           @tab     @tab  X
>      @tab fourcc: AASC
> +@item AV1                    @tab     @tab  E
> +    @tab Supported through external library libaom
>  @item AVS (Audio Video Standard) video  @tab     @tab  X
>      @tab Video encoding used by the Creature Shock game.
>  @item Beam Software VB       @tab     @tab  X
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 8eb7d36..65e95f3 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -653,6 +653,7 @@ OBJS-$(CONFIG_TAK_DEMUXER)             += tak.o
>  OBJS-$(CONFIG_WEBM_MUXER)              += mpeg4audio.o
>
>  # external codec libraries
> +OBJS-$(CONFIG_LIBAOM_AV1_DECODER)         += libaomdec.o libaom.o
>  OBJS-$(CONFIG_LIBDCADEC_DECODER)          += libdcadec.o dca.o
>  OBJS-$(CONFIG_LIBFAAC_ENCODER)            += libfaac.o
>  OBJS-$(CONFIG_LIBFDK_AAC_DECODER)         += libfdk-aacdec.o
> @@ -770,6 +771,7 @@ SKIPHEADERS                            +=
> %_tablegen.h                  \
>
>  SKIPHEADERS-$(CONFIG_D3D11VA)          += d3d11va.h dxva2_internal.h
>  SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
> +SKIPHEADERS-$(CONFIG_LIBAOM)           += libaom.h
>  SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.h
>  SKIPHEADERS-$(CONFIG_LIBVPX)           += libvpx.h
>  SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index e259de2..e3ccd55 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -458,6 +458,7 @@ void avcodec_register_all(void)
>      REGISTER_ENCDEC (XSUB,              xsub);
>
>      /* external libraries */
> +    REGISTER_DECODER(LIBAOM_AV1,        libaom_av1);
>      REGISTER_DECODER(LIBDCADEC,         libdcadec)
>      REGISTER_ENCODER(LIBFAAC,           libfaac);
>      REGISTER_ENCDEC (LIBFDK_AAC,        libfdk_aac);
> diff --git a/libavcodec/libaom.c b/libavcodec/libaom.c
> new file mode 100644
> index 0000000..f8bcc37
> --- /dev/null
> +++ b/libavcodec/libaom.c
> @@ -0,0 +1,75 @@
> +/*
> + * Copyright (c) 2013 Guillaume Martres <smarter@ubuntu.com>
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +#include <aom/aom_image.h>
> +
> +#include "libaom.h"
> +
> +enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img)
> +{
> +    switch (img) {
> +    case AOM_IMG_FMT_RGB24:     return AV_PIX_FMT_RGB24;
> +    case AOM_IMG_FMT_RGB565:    return AV_PIX_FMT_RGB565BE;
> +    case AOM_IMG_FMT_RGB555:    return AV_PIX_FMT_RGB555BE;
> +    case AOM_IMG_FMT_UYVY:      return AV_PIX_FMT_UYVY422;
> +    case AOM_IMG_FMT_YUY2:      return AV_PIX_FMT_YUYV422;
> +    case AOM_IMG_FMT_YVYU:      return AV_PIX_FMT_YVYU422;
> +    case AOM_IMG_FMT_BGR24:     return AV_PIX_FMT_BGR24;
> +    case AOM_IMG_FMT_ARGB:      return AV_PIX_FMT_ARGB;
> +    case AOM_IMG_FMT_ARGB_LE:   return AV_PIX_FMT_BGRA;
> +    case AOM_IMG_FMT_RGB565_LE: return AV_PIX_FMT_RGB565LE;
> +    case AOM_IMG_FMT_RGB555_LE: return AV_PIX_FMT_RGB555LE;
> +    case AOM_IMG_FMT_I420:      return AV_PIX_FMT_YUV420P;
> +    case AOM_IMG_FMT_I422:      return AV_PIX_FMT_YUV422P;
> +    case AOM_IMG_FMT_I444:      return AV_PIX_FMT_YUV444P;
> +    case AOM_IMG_FMT_444A:      return AV_PIX_FMT_YUVA444P;
> +    case AOM_IMG_FMT_I440:      return AV_PIX_FMT_YUV440P;
> +    case AOM_IMG_FMT_I42016:    return AV_PIX_FMT_YUV420P16BE;
> +    case AOM_IMG_FMT_I42216:    return AV_PIX_FMT_YUV422P16BE;
> +    case AOM_IMG_FMT_I44416:    return AV_PIX_FMT_YUV444P16BE;
> +    default:                    return AV_PIX_FMT_NONE;
> +    }
> +}
> +
> +aom_img_fmt_t ff_aom_pixfmt_to_imgfmt(enum AVPixelFormat pix)
> +{
> +    switch (pix) {
> +    case AV_PIX_FMT_RGB24:        return AOM_IMG_FMT_RGB24;
> +    case AV_PIX_FMT_RGB565BE:     return AOM_IMG_FMT_RGB565;
> +    case AV_PIX_FMT_RGB555BE:     return AOM_IMG_FMT_RGB555;
> +    case AV_PIX_FMT_UYVY422:      return AOM_IMG_FMT_UYVY;
> +    case AV_PIX_FMT_YUYV422:      return AOM_IMG_FMT_YUY2;
> +    case AV_PIX_FMT_YVYU422:      return AOM_IMG_FMT_YVYU;
> +    case AV_PIX_FMT_BGR24:        return AOM_IMG_FMT_BGR24;
> +    case AV_PIX_FMT_ARGB:         return AOM_IMG_FMT_ARGB;
> +    case AV_PIX_FMT_BGRA:         return AOM_IMG_FMT_ARGB_LE;
> +    case AV_PIX_FMT_RGB565LE:     return AOM_IMG_FMT_RGB565_LE;
> +    case AV_PIX_FMT_RGB555LE:     return AOM_IMG_FMT_RGB555_LE;
> +    case AV_PIX_FMT_YUV420P:      return AOM_IMG_FMT_I420;
> +    case AV_PIX_FMT_YUV422P:      return AOM_IMG_FMT_I422;
> +    case AV_PIX_FMT_YUV444P:      return AOM_IMG_FMT_I444;
> +    case AV_PIX_FMT_YUVA444P:     return AOM_IMG_FMT_444A;
> +    case AV_PIX_FMT_YUV440P:      return AOM_IMG_FMT_I440;
> +    case AV_PIX_FMT_YUV420P16BE:  return AOM_IMG_FMT_I42016;
> +    case AV_PIX_FMT_YUV422P16BE:  return AOM_IMG_FMT_I42216;
> +    case AV_PIX_FMT_YUV444P16BE:  return AOM_IMG_FMT_I44416;
> +    default:                      return AOM_IMG_FMT_NONE;
> +    }
> +}
> diff --git a/libavcodec/libaom.h b/libavcodec/libaom.h
> new file mode 100644
> index 0000000..7a7b8db
> --- /dev/null
> +++ b/libavcodec/libaom.h
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (c) 2013 Guillaume Martres <smarter@ubuntu.com>
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +#ifndef AVCODEC_LIBAOM_H
> +#define AVCODEC_LIBAOM_H
> +
> +#include <aom/aom_codec.h>
> +
> +#include "libavutil/pixfmt.h"
> +
> +enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img);
> +aom_img_fmt_t ff_aom_pixfmt_to_imgfmt(enum AVPixelFormat pix);
> +
> +#endif /* AVCODEC_LIBAOM_H */
> diff --git a/libavcodec/libaomdec.c b/libavcodec/libaomdec.c
> new file mode 100644
> index 0000000..e975b63
> --- /dev/null
> +++ b/libavcodec/libaomdec.c
> @@ -0,0 +1,137 @@
> +/*
> + * Copyright (c) 2010, Google, Inc.
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +/**
> + * @file
> + * AV1 decoder support via libaom
> + */
> +
> +#include <aom/aom_decoder.h>
> +#include <aom/aomdx.h>
> +
> +#include "libavutil/common.h"
> +#include "libavutil/imgutils.h"
> +
> +#include "avcodec.h"
> +#include "internal.h"
> +#include "libaom.h"
> +
> +typedef struct AV1DecodeContext {
> +    struct aom_codec_ctx decoder;
> +} AV1DecodeContext;
> +
> +static av_cold int aom_init(AVCodecContext *avctx,
> +                            const struct aom_codec_iface *iface)
> +{
> +    AV1DecodeContext *ctx = avctx->priv_data;
> +    struct aom_codec_dec_cfg deccfg = {
> +        /* token partitions+1 would be a decent choice */
> +        .threads = FFMIN(avctx->thread_count, 16)
> +    };
> +
> +    av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str());
> +    av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config());
> +
> +    if (aom_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) !=
> AOM_CODEC_OK) {
> +        const char *error = aom_codec_error(&ctx->decoder);
> +        av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
> +               error);
> +        return AVERROR(EINVAL);
> +    }
> +
> +    return 0;
> +}
> +
> +static int aom_decode(AVCodecContext *avctx, void *data, int *got_frame,
> +                      AVPacket *avpkt)
> +{
> +    AV1DecodeContext *ctx = avctx->priv_data;
> +    AVFrame *picture = data;
> +    const void *iter = NULL;
> +    struct aom_image *img;
> +    int ret;
> +
> +    if (aom_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL,
> 0) !=
> +        AOM_CODEC_OK) {
> +        const char *error  = aom_codec_error(&ctx->decoder);
> +        const char *detail = aom_codec_error_detail(&ctx->decoder);
> +
> +        av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n",
> error);
> +        if (detail)
> +            av_log(avctx, AV_LOG_ERROR, "  Additional information: %s\n",
> +                   detail);
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    if ((img = aom_codec_get_frame(&ctx->decoder, &iter))) {
> +        avctx->pix_fmt = ff_aom_imgfmt_to_pixfmt(img->fmt);
> +        if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
> +            av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace
> (%d)\n",
> +                   img->fmt);
> +            return AVERROR_INVALIDDATA;
> +        }
> +
> +        if ((int) img->d_w != avctx->width || (int) img->d_h !=
> avctx->height) {
> +            av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d ->
> %dx%d\n",
> +                   avctx->width, avctx->height, img->d_w, img->d_h);
> +            ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
> +            if (ret < 0)
> +                return ret;
> +        }
> +        if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
> +            return ret;
> +        av_image_copy(picture->data, picture->linesize, (const uint8_t
> **) img->planes,
> +                      img->stride, avctx->pix_fmt, img->d_w, img->d_h);
> +        switch (img->range) {
> +        case AOM_CR_STUDIO_RANGE:
> +            picture->color_range = AVCOL_RANGE_MPEG;
> +            break;
> +        case AOM_CR_FULL_RANGE:
> +            picture->color_range = AVCOL_RANGE_JPEG;
> +            break;
> +        }
> +        *got_frame           = 1;
> +    }
> +    return avpkt->size;
> +}
> +
> +static av_cold int aom_free(AVCodecContext *avctx)
> +{
> +    AV1DecodeContext *ctx = avctx->priv_data;
> +    aom_codec_destroy(&ctx->decoder);
> +    return 0;
> +}
> +
> +static av_cold int av1_init(AVCodecContext *avctx)
> +{
> +    return aom_init(avctx, &aom_codec_av1_dx_algo);
> +}
> +
> +AVCodec ff_libaom_av1_decoder = {
> +    .name           = "libaom",
> +    .long_name      = NULL_IF_CONFIG_SMALL("libaom AV1"),
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_AV1,
> +    .priv_data_size = sizeof(AV1DecodeContext),
> +    .init           = av1_init,
> +    .close          = aom_free,
> +    .decode         = aom_decode,
> +    .capabilities   = AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_DR1,
> +};
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index f944709..c6eea8d 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -28,7 +28,7 @@
>  #include "libavutil/version.h"
>
>  #define LIBAVCODEC_VERSION_MAJOR 57
> -#define LIBAVCODEC_VERSION_MINOR 25
> +#define LIBAVCODEC_VERSION_MINOR 27
>  #define LIBAVCODEC_VERSION_MICRO  0
>
>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR,
> \
> --
> 2.7.3
>
> _______________________________________________
> libav-devel mailing list
> libav-devel@libav.org
> https://lists.libav.org/mailman/listinfo/libav-devel
>
Harfe Leier Aug. 25, 2016, 4:43 p.m. | #2
Ah I see the following patch templatizing the sharing img<->pix fmt
conversion between vpx and aom. But it seems to be a problem here.

On 26 August 2016 at 00:10, Harfe Leier <astrataro@gmail.com> wrote:

> Hi,
>
> I tested this patch with videos encoded by aomenc, and found that for
> 10/12-bit av1 videos this patch decodes incorrectly. I found that
> ff_aom_imgfmt_to_pixfmt might not work as supposed for high bit depth. Like
> libvpx, avctx->pix_fmt should be set by both img->fmt and img->bit_depth.
> Also it seems that AV_PIX_FMT_YUV4XXP10/12/16 should use LE instead of BE.
> So after I change ff_aom_imgfmt_to_pixfmt to the following one:
>
> +enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img, unsigned
> int bit_depth)
> +{
> +    switch (img) {
> +    case AOM_IMG_FMT_RGB24:     return AV_PIX_FMT_RGB24;
> +    case AOM_IMG_FMT_RGB565:    return AV_PIX_FMT_RGB565BE;  // I didn't
> test RGB565 if it uses BE
> +    case AOM_IMG_FMT_RGB555:    return AV_PIX_FMT_RGB555BE;  // I didn't
> test RGB555 if it uses BE
> +    case AOM_IMG_FMT_UYVY:      return AV_PIX_FMT_UYVY422;
> +    case AOM_IMG_FMT_YUY2:      return AV_PIX_FMT_YUYV422;
> +    case AOM_IMG_FMT_YVYU:      return AV_PIX_FMT_YVYU422;
> +    case AOM_IMG_FMT_BGR24:     return AV_PIX_FMT_BGR24;
> +    case AOM_IMG_FMT_ARGB:      return AV_PIX_FMT_ARGB;
> +    case AOM_IMG_FMT_ARGB_LE:   return AV_PIX_FMT_BGRA;
> +    case AOM_IMG_FMT_RGB565_LE: return AV_PIX_FMT_RGB565LE;
> +    case AOM_IMG_FMT_RGB555_LE: return AV_PIX_FMT_RGB555LE;
> +    case AOM_IMG_FMT_I420:      return AV_PIX_FMT_YUV420P;
> +    case AOM_IMG_FMT_I422:      return AV_PIX_FMT_YUV422P;
> +    case AOM_IMG_FMT_I444:      return AV_PIX_FMT_YUV444P;
> +    case AOM_IMG_FMT_444A:      return AV_PIX_FMT_YUVA444P;
> +#if AOM_IMAGE_ABI_VERSION >= 3
> +    case AOM_IMG_FMT_I440:      return AV_PIX_FMT_YUV440P;
> +    case AOM_IMG_FMT_I42016:
> +        switch (bit_depth) {
> +            case 10: return AV_PIX_FMT_YUV420P10;
> +            case 12: return AV_PIX_FMT_YUV420P12;
> +        }
> +    case AOM_IMG_FMT_I42216:
> +        switch (bit_depth) {
> +            case 10: return AV_PIX_FMT_YUV422P10;
> +            case 12: return AV_PIX_FMT_YUV422P12;
> +        }
> +    case AOM_IMG_FMT_I44416:
> +        switch (bit_depth) {
> +            case 10: return AV_PIX_FMT_YUV444P10;
> +            case 12: return AV_PIX_FMT_YUV444P12;
> +        }
> +#endif
> +    default:                    return AV_PIX_FMT_NONE;
> +    }
> +}
>
> and use
> +        avctx->pix_fmt = ff_aom_imgfmt_to_pixfmt(img->fmt, img->bit_depth
> );
> in libaomdec, the decoding result is identical to aomdec.
>
> If it is correct to do this, ff_aom_pixfmt_to_imgfmt might also need to be
> re-defined. While libaom can be built with or without high bit depth
> support (--enable/disable-aom-highbitdepth), it does not expose a macro
> like AOM_IMG_FMT_HIGHBITDEPTH. It only defines CONFIG_AOM_HIGHBITDEPTH in
> aom_config.h which is used for building aom reference tools only. I'm not
> sure if we should add further check on the pixel format conversion above.
>
> Lucien
>
>
> On 25 August 2016 at 23:28, Diego Biurrun <diego@biurrun.de> wrote:
>
>> From: Luca Barbato <lu_zero@gentoo.org>
>>
>> Signed-off-by: Diego Biurrun <diego@biurrun.de>
>> ---
>>
>> some minor changes, version bump
>>
>>  Changelog              |   1 +
>>  configure              |   4 ++
>>  doc/general.texi       |  10 ++++
>>  libavcodec/Makefile    |   2 +
>>  libavcodec/allcodecs.c |   1 +
>>  libavcodec/libaom.c    |  75 +++++++++++++++++++++++++++
>>  libavcodec/libaom.h    |  31 +++++++++++
>>  libavcodec/libaomdec.c | 137 ++++++++++++++++++++++++++++++
>> +++++++++++++++++++
>>  libavcodec/version.h   |   2 +-
>>  9 files changed, 262 insertions(+), 1 deletion(-)
>>  create mode 100644 libavcodec/libaom.c
>>  create mode 100644 libavcodec/libaom.h
>>  create mode 100644 libavcodec/libaomdec.c
>>
>> diff --git a/Changelog b/Changelog
>> index 0d04f47..5ee2346 100644
>> --- a/Changelog
>> +++ b/Changelog
>> @@ -62,6 +62,7 @@ version <next>:
>>  - Intel QSV video scaling and deinterlacing filter
>>  - OpenH264 decoder wrapper
>>  - Removed the legacy X11 screen grabber, use XCB instead
>> +- Alliance for Open Media AV1 decoding support using libaom
>>
>>
>>  version 11:
>> diff --git a/configure b/configure
>> index 8049d90..9cf7a1c 100755
>> --- a/configure
>> +++ b/configure
>> @@ -188,6 +188,7 @@ External library support:
>>    --enable-bzlib             bzip2 compression [autodetect]
>>    --enable-frei0r            video filtering plugins
>>    --enable-gnutls            crypto
>> +  --enable-libaom            AV1 video encoding/decoding
>>    --enable-libbs2b           Bauer stereophonic-to-binaural DSP
>>    --enable-libcdio           audio CD input
>>    --enable-libdc1394         IEEE 1394/Firewire camera input
>> @@ -1264,6 +1265,7 @@ EXTERNAL_LIBRARY_LIST="
>>      bzlib
>>      frei0r
>>      gnutls
>> +    libaom
>>      libbs2b
>>      libdc1394
>>      libdcadec
>> @@ -2236,6 +2238,7 @@ vc1_parser_select="vc1dsp"
>>  mjpeg2jpeg_bsf_select="jpegtables"
>>
>>  # external libraries
>> +libaom_av1_decoder_deps="libaom"
>>  libdcadec_decoder_deps="libdcadec"
>>  libfaac_encoder_deps="libfaac"
>>  libfaac_encoder_select="audio_frame_queue"
>> @@ -4597,6 +4600,7 @@ enabled avisynth          && { check_lib2
>> "avisynth/avisynth_c.h windows.h" Load
>>  enabled cuda              && check_lib cuda.h cuInit -lcuda
>>  enabled frei0r            && { check_header frei0r.h || die "ERROR:
>> frei0r.h header not found"; }
>>  enabled gnutls            && require_pkg_config gnutls gnutls/gnutls.h
>> gnutls_global_init
>> +enabled libaom            && require_pkg_config "aom >= 0.1.0"
>> aom/aom_codec.h aom_codec_version
>>  enabled libbs2b           && require_pkg_config libbs2b bs2b.h bs2b_open
>>  enabled libdcadec         && require libdcadec libdcadec/dca_context.h
>> dcadec_context_create -ldcadec
>>  enabled libfaac           && require2 libfaac "stdint.h faac.h"
>> faacEncGetVersion -lfaac
>> diff --git a/doc/general.texi b/doc/general.texi
>> index ea56bef..63b1afd 100644
>> --- a/doc/general.texi
>> +++ b/doc/general.texi
>> @@ -16,6 +16,14 @@ for more formats. None of them are used by default,
>> their use has to be
>>  explicitly requested by passing the appropriate flags to
>>  @command{./configure}.
>>
>> +@section Alliance for Open Media libaom
>> +
>> +Libav can make use of the libaom library for AV1 decoding.
>> +
>> +Go to @url{http://aomedia.org/} and follow the instructions for
>> +installing the library. Then pass @code{--enable-libaom} to configure to
>> +enable it.
>> +
>>  @section OpenCORE and VisualOn libraries
>>
>>  Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer
>> @@ -576,6 +584,8 @@ following image formats are supported:
>>  @item Autodesk Animator Flic video  @tab     @tab  X
>>  @item Autodesk RLE           @tab     @tab  X
>>      @tab fourcc: AASC
>> +@item AV1                    @tab     @tab  E
>> +    @tab Supported through external library libaom
>>  @item AVS (Audio Video Standard) video  @tab     @tab  X
>>      @tab Video encoding used by the Creature Shock game.
>>  @item Beam Software VB       @tab     @tab  X
>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>> index 8eb7d36..65e95f3 100644
>> --- a/libavcodec/Makefile
>> +++ b/libavcodec/Makefile
>> @@ -653,6 +653,7 @@ OBJS-$(CONFIG_TAK_DEMUXER)             += tak.o
>>  OBJS-$(CONFIG_WEBM_MUXER)              += mpeg4audio.o
>>
>>  # external codec libraries
>> +OBJS-$(CONFIG_LIBAOM_AV1_DECODER)         += libaomdec.o libaom.o
>>  OBJS-$(CONFIG_LIBDCADEC_DECODER)          += libdcadec.o dca.o
>>  OBJS-$(CONFIG_LIBFAAC_ENCODER)            += libfaac.o
>>  OBJS-$(CONFIG_LIBFDK_AAC_DECODER)         += libfdk-aacdec.o
>> @@ -770,6 +771,7 @@ SKIPHEADERS                            +=
>> %_tablegen.h                  \
>>
>>  SKIPHEADERS-$(CONFIG_D3D11VA)          += d3d11va.h dxva2_internal.h
>>  SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
>> +SKIPHEADERS-$(CONFIG_LIBAOM)           += libaom.h
>>  SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.h
>>  SKIPHEADERS-$(CONFIG_LIBVPX)           += libvpx.h
>>  SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
>> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
>> index e259de2..e3ccd55 100644
>> --- a/libavcodec/allcodecs.c
>> +++ b/libavcodec/allcodecs.c
>> @@ -458,6 +458,7 @@ void avcodec_register_all(void)
>>      REGISTER_ENCDEC (XSUB,              xsub);
>>
>>      /* external libraries */
>> +    REGISTER_DECODER(LIBAOM_AV1,        libaom_av1);
>>      REGISTER_DECODER(LIBDCADEC,         libdcadec)
>>      REGISTER_ENCODER(LIBFAAC,           libfaac);
>>      REGISTER_ENCDEC (LIBFDK_AAC,        libfdk_aac);
>> diff --git a/libavcodec/libaom.c b/libavcodec/libaom.c
>> new file mode 100644
>> index 0000000..f8bcc37
>> --- /dev/null
>> +++ b/libavcodec/libaom.c
>> @@ -0,0 +1,75 @@
>> +/*
>> + * Copyright (c) 2013 Guillaume Martres <smarter@ubuntu.com>
>> + *
>> + * This file is part of Libav.
>> + *
>> + * Libav is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2.1 of the License, or (at your option) any later version.
>> + *
>> + * Libav is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with Libav; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301 USA
>> + */
>> +
>> +#include <aom/aom_image.h>
>> +
>> +#include "libaom.h"
>> +
>> +enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img)
>> +{
>> +    switch (img) {
>> +    case AOM_IMG_FMT_RGB24:     return AV_PIX_FMT_RGB24;
>> +    case AOM_IMG_FMT_RGB565:    return AV_PIX_FMT_RGB565BE;
>> +    case AOM_IMG_FMT_RGB555:    return AV_PIX_FMT_RGB555BE;
>> +    case AOM_IMG_FMT_UYVY:      return AV_PIX_FMT_UYVY422;
>> +    case AOM_IMG_FMT_YUY2:      return AV_PIX_FMT_YUYV422;
>> +    case AOM_IMG_FMT_YVYU:      return AV_PIX_FMT_YVYU422;
>> +    case AOM_IMG_FMT_BGR24:     return AV_PIX_FMT_BGR24;
>> +    case AOM_IMG_FMT_ARGB:      return AV_PIX_FMT_ARGB;
>> +    case AOM_IMG_FMT_ARGB_LE:   return AV_PIX_FMT_BGRA;
>> +    case AOM_IMG_FMT_RGB565_LE: return AV_PIX_FMT_RGB565LE;
>> +    case AOM_IMG_FMT_RGB555_LE: return AV_PIX_FMT_RGB555LE;
>> +    case AOM_IMG_FMT_I420:      return AV_PIX_FMT_YUV420P;
>> +    case AOM_IMG_FMT_I422:      return AV_PIX_FMT_YUV422P;
>> +    case AOM_IMG_FMT_I444:      return AV_PIX_FMT_YUV444P;
>> +    case AOM_IMG_FMT_444A:      return AV_PIX_FMT_YUVA444P;
>> +    case AOM_IMG_FMT_I440:      return AV_PIX_FMT_YUV440P;
>> +    case AOM_IMG_FMT_I42016:    return AV_PIX_FMT_YUV420P16BE;
>> +    case AOM_IMG_FMT_I42216:    return AV_PIX_FMT_YUV422P16BE;
>> +    case AOM_IMG_FMT_I44416:    return AV_PIX_FMT_YUV444P16BE;
>> +    default:                    return AV_PIX_FMT_NONE;
>> +    }
>> +}
>> +
>> +aom_img_fmt_t ff_aom_pixfmt_to_imgfmt(enum AVPixelFormat pix)
>> +{
>> +    switch (pix) {
>> +    case AV_PIX_FMT_RGB24:        return AOM_IMG_FMT_RGB24;
>> +    case AV_PIX_FMT_RGB565BE:     return AOM_IMG_FMT_RGB565;
>> +    case AV_PIX_FMT_RGB555BE:     return AOM_IMG_FMT_RGB555;
>> +    case AV_PIX_FMT_UYVY422:      return AOM_IMG_FMT_UYVY;
>> +    case AV_PIX_FMT_YUYV422:      return AOM_IMG_FMT_YUY2;
>> +    case AV_PIX_FMT_YVYU422:      return AOM_IMG_FMT_YVYU;
>> +    case AV_PIX_FMT_BGR24:        return AOM_IMG_FMT_BGR24;
>> +    case AV_PIX_FMT_ARGB:         return AOM_IMG_FMT_ARGB;
>> +    case AV_PIX_FMT_BGRA:         return AOM_IMG_FMT_ARGB_LE;
>> +    case AV_PIX_FMT_RGB565LE:     return AOM_IMG_FMT_RGB565_LE;
>> +    case AV_PIX_FMT_RGB555LE:     return AOM_IMG_FMT_RGB555_LE;
>> +    case AV_PIX_FMT_YUV420P:      return AOM_IMG_FMT_I420;
>> +    case AV_PIX_FMT_YUV422P:      return AOM_IMG_FMT_I422;
>> +    case AV_PIX_FMT_YUV444P:      return AOM_IMG_FMT_I444;
>> +    case AV_PIX_FMT_YUVA444P:     return AOM_IMG_FMT_444A;
>> +    case AV_PIX_FMT_YUV440P:      return AOM_IMG_FMT_I440;
>> +    case AV_PIX_FMT_YUV420P16BE:  return AOM_IMG_FMT_I42016;
>> +    case AV_PIX_FMT_YUV422P16BE:  return AOM_IMG_FMT_I42216;
>> +    case AV_PIX_FMT_YUV444P16BE:  return AOM_IMG_FMT_I44416;
>> +    default:                      return AOM_IMG_FMT_NONE;
>> +    }
>> +}
>> diff --git a/libavcodec/libaom.h b/libavcodec/libaom.h
>> new file mode 100644
>> index 0000000..7a7b8db
>> --- /dev/null
>> +++ b/libavcodec/libaom.h
>> @@ -0,0 +1,31 @@
>> +/*
>> + * Copyright (c) 2013 Guillaume Martres <smarter@ubuntu.com>
>> + *
>> + * This file is part of Libav.
>> + *
>> + * Libav is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2.1 of the License, or (at your option) any later version.
>> + *
>> + * Libav is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with Libav; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301 USA
>> + */
>> +
>> +#ifndef AVCODEC_LIBAOM_H
>> +#define AVCODEC_LIBAOM_H
>> +
>> +#include <aom/aom_codec.h>
>> +
>> +#include "libavutil/pixfmt.h"
>> +
>> +enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img);
>> +aom_img_fmt_t ff_aom_pixfmt_to_imgfmt(enum AVPixelFormat pix);
>> +
>> +#endif /* AVCODEC_LIBAOM_H */
>> diff --git a/libavcodec/libaomdec.c b/libavcodec/libaomdec.c
>> new file mode 100644
>> index 0000000..e975b63
>> --- /dev/null
>> +++ b/libavcodec/libaomdec.c
>> @@ -0,0 +1,137 @@
>> +/*
>> + * Copyright (c) 2010, Google, Inc.
>> + *
>> + * This file is part of Libav.
>> + *
>> + * Libav is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2.1 of the License, or (at your option) any later version.
>> + *
>> + * Libav is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with Libav; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301 USA
>> + */
>> +
>> +/**
>> + * @file
>> + * AV1 decoder support via libaom
>> + */
>> +
>> +#include <aom/aom_decoder.h>
>> +#include <aom/aomdx.h>
>> +
>> +#include "libavutil/common.h"
>> +#include "libavutil/imgutils.h"
>> +
>> +#include "avcodec.h"
>> +#include "internal.h"
>> +#include "libaom.h"
>> +
>> +typedef struct AV1DecodeContext {
>> +    struct aom_codec_ctx decoder;
>> +} AV1DecodeContext;
>> +
>> +static av_cold int aom_init(AVCodecContext *avctx,
>> +                            const struct aom_codec_iface *iface)
>> +{
>> +    AV1DecodeContext *ctx = avctx->priv_data;
>> +    struct aom_codec_dec_cfg deccfg = {
>> +        /* token partitions+1 would be a decent choice */
>> +        .threads = FFMIN(avctx->thread_count, 16)
>> +    };
>> +
>> +    av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str());
>> +    av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config());
>> +
>> +    if (aom_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) !=
>> AOM_CODEC_OK) {
>> +        const char *error = aom_codec_error(&ctx->decoder);
>> +        av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
>> +               error);
>> +        return AVERROR(EINVAL);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int aom_decode(AVCodecContext *avctx, void *data, int *got_frame,
>> +                      AVPacket *avpkt)
>> +{
>> +    AV1DecodeContext *ctx = avctx->priv_data;
>> +    AVFrame *picture = data;
>> +    const void *iter = NULL;
>> +    struct aom_image *img;
>> +    int ret;
>> +
>> +    if (aom_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL,
>> 0) !=
>> +        AOM_CODEC_OK) {
>> +        const char *error  = aom_codec_error(&ctx->decoder);
>> +        const char *detail = aom_codec_error_detail(&ctx->decoder);
>> +
>> +        av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n",
>> error);
>> +        if (detail)
>> +            av_log(avctx, AV_LOG_ERROR, "  Additional information: %s\n",
>> +                   detail);
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +
>> +    if ((img = aom_codec_get_frame(&ctx->decoder, &iter))) {
>> +        avctx->pix_fmt = ff_aom_imgfmt_to_pixfmt(img->fmt);
>> +        if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
>> +            av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace
>> (%d)\n",
>> +                   img->fmt);
>> +            return AVERROR_INVALIDDATA;
>> +        }
>> +
>> +        if ((int) img->d_w != avctx->width || (int) img->d_h !=
>> avctx->height) {
>> +            av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d ->
>> %dx%d\n",
>> +                   avctx->width, avctx->height, img->d_w, img->d_h);
>> +            ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
>> +            if (ret < 0)
>> +                return ret;
>> +        }
>> +        if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
>> +            return ret;
>> +        av_image_copy(picture->data, picture->linesize, (const uint8_t
>> **) img->planes,
>> +                      img->stride, avctx->pix_fmt, img->d_w, img->d_h);
>> +        switch (img->range) {
>> +        case AOM_CR_STUDIO_RANGE:
>> +            picture->color_range = AVCOL_RANGE_MPEG;
>> +            break;
>> +        case AOM_CR_FULL_RANGE:
>> +            picture->color_range = AVCOL_RANGE_JPEG;
>> +            break;
>> +        }
>> +        *got_frame           = 1;
>> +    }
>> +    return avpkt->size;
>> +}
>> +
>> +static av_cold int aom_free(AVCodecContext *avctx)
>> +{
>> +    AV1DecodeContext *ctx = avctx->priv_data;
>> +    aom_codec_destroy(&ctx->decoder);
>> +    return 0;
>> +}
>> +
>> +static av_cold int av1_init(AVCodecContext *avctx)
>> +{
>> +    return aom_init(avctx, &aom_codec_av1_dx_algo);
>> +}
>> +
>> +AVCodec ff_libaom_av1_decoder = {
>> +    .name           = "libaom",
>> +    .long_name      = NULL_IF_CONFIG_SMALL("libaom AV1"),
>> +    .type           = AVMEDIA_TYPE_VIDEO,
>> +    .id             = AV_CODEC_ID_AV1,
>> +    .priv_data_size = sizeof(AV1DecodeContext),
>> +    .init           = av1_init,
>> +    .close          = aom_free,
>> +    .decode         = aom_decode,
>> +    .capabilities   = AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_DR1,
>> +};
>> diff --git a/libavcodec/version.h b/libavcodec/version.h
>> index f944709..c6eea8d 100644
>> --- a/libavcodec/version.h
>> +++ b/libavcodec/version.h
>> @@ -28,7 +28,7 @@
>>  #include "libavutil/version.h"
>>
>>  #define LIBAVCODEC_VERSION_MAJOR 57
>> -#define LIBAVCODEC_VERSION_MINOR 25
>> +#define LIBAVCODEC_VERSION_MINOR 27
>>  #define LIBAVCODEC_VERSION_MICRO  0
>>
>>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR,
>> \
>> --
>> 2.7.3
>>
>> _______________________________________________
>> libav-devel mailing list
>> libav-devel@libav.org
>> https://lists.libav.org/mailman/listinfo/libav-devel
>>
>
>
Diego Biurrun Aug. 25, 2016, 5:30 p.m. | #3
Please don't top-post.

On Fri, Aug 26, 2016 at 12:43:08AM +0800, Harfe Leier wrote:
> Ah I see the following patch templatizing the sharing img<->pix fmt
> conversion between vpx and aom. But it seems to be a problem here.

"it"?  What is the problem?

Diego
Harfe Leier Aug. 25, 2016, 5:54 p.m. | #4
Seems you didn't see another post above....

I tested this patch with videos encoded by aomenc, and found that for
10/12-bit av1 videos this patch decodes incorrectly. I found that
ff_aom_imgfmt_to_pixfmt might not work as supposed for high bit depth. Like
libvpx, avctx->pix_fmt should be set by both img->fmt and img->bit_depth.
Also it seems that AV_PIX_FMT_YUV4XXP10/12/16 should use LE instead of BE.
So after I change ff_aom_imgfmt_to_pixfmt to the following one:

+enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img, unsigned int
bit_depth)
+{
+    switch (img) {
+    case AOM_IMG_FMT_RGB24:     return AV_PIX_FMT_RGB24;
+    case AOM_IMG_FMT_RGB565:    return AV_PIX_FMT_RGB565BE;
+    case AOM_IMG_FMT_RGB555:    return AV_PIX_FMT_RGB555BE;
+    case AOM_IMG_FMT_UYVY:      return AV_PIX_FMT_UYVY422;
+    case AOM_IMG_FMT_YUY2:      return AV_PIX_FMT_YUYV422;
+    case AOM_IMG_FMT_YVYU:      return AV_PIX_FMT_YVYU422;
+    case AOM_IMG_FMT_BGR24:     return AV_PIX_FMT_BGR24;
+    case AOM_IMG_FMT_ARGB:      return AV_PIX_FMT_ARGB;
+    case AOM_IMG_FMT_ARGB_LE:   return AV_PIX_FMT_BGRA;
+    case AOM_IMG_FMT_RGB565_LE: return AV_PIX_FMT_RGB565LE;
+    case AOM_IMG_FMT_RGB555_LE: return AV_PIX_FMT_RGB555LE;
+    case AOM_IMG_FMT_I420:      return AV_PIX_FMT_YUV420P;
+    case AOM_IMG_FMT_I422:      return AV_PIX_FMT_YUV422P;
+    case AOM_IMG_FMT_I444:      return AV_PIX_FMT_YUV444P;
+    case AOM_IMG_FMT_444A:      return AV_PIX_FMT_YUVA444P;
+#if AOM_IMAGE_ABI_VERSION >= 3
+    case AOM_IMG_FMT_I440:      return AV_PIX_FMT_YUV440P;
+    case AOM_IMG_FMT_I42016:
+        switch (bit_depth) {
+            case 10: return AV_PIX_FMT_YUV420P10;
+            case 12: return AV_PIX_FMT_YUV420P12;
+        }
+    case AOM_IMG_FMT_I42216:
+        switch (bit_depth) {
+            case 10: return AV_PIX_FMT_YUV422P10;
+            case 12: return AV_PIX_FMT_YUV422P12;
+        }
+    case AOM_IMG_FMT_I44416:
+        switch (bit_depth) {
+            case 10: return AV_PIX_FMT_YUV444P10;
+            case 12: return AV_PIX_FMT_YUV444P12;
+        }
+#endif
+    default:                    return AV_PIX_FMT_NONE;
+    }
+}

and use
+        avctx->pix_fmt = ff_aom_imgfmt_to_pixfmt(img->fmt, img->bit_depth);
in libaomdec, the decoding result is identical to aomdec.

If it is correct to do this, ff_aom_pixfmt_to_imgfmt might also need to be
re-defined. While libaom can be built with or without high bit depth
support (--enable/disable-aom-highbitdepth), it does not expose a macro
like AOM_IMG_FMT_HIGHBITDEPTH. It only defines CONFIG_AOM_HIGHBITDEPTH in
aom_config.h which is used for building aom reference tools only. I'm not
sure if we should add further check on the pixel format conversion above.

Lucien
Luca Barbato Sept. 4, 2016, 2:01 p.m. | #5
On 25/08/16 19:54, Lucien AT wrote:
> Seems you didn't see another post above....
> 
> I tested this patch with videos encoded by aomenc, and found that for
> 10/12-bit av1 videos this patch decodes incorrectly. I found that
> ff_aom_imgfmt_to_pixfmt might not work as supposed for high bit depth. Like
> libvpx, avctx->pix_fmt should be set by both img->fmt and img->bit_depth.
> Also it seems that AV_PIX_FMT_YUV4XXP10/12/16 should use LE instead of BE.
> So after I change ff_aom_imgfmt_to_pixfmt to the following one:
> 
> +enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img, unsigned int
> bit_depth)
> +{
> +    switch (img) {
> +    case AOM_IMG_FMT_RGB24:     return AV_PIX_FMT_RGB24;
> +    case AOM_IMG_FMT_RGB565:    return AV_PIX_FMT_RGB565BE;
> +    case AOM_IMG_FMT_RGB555:    return AV_PIX_FMT_RGB555BE;
> +    case AOM_IMG_FMT_UYVY:      return AV_PIX_FMT_UYVY422;
> +    case AOM_IMG_FMT_YUY2:      return AV_PIX_FMT_YUYV422;
> +    case AOM_IMG_FMT_YVYU:      return AV_PIX_FMT_YVYU422;
> +    case AOM_IMG_FMT_BGR24:     return AV_PIX_FMT_BGR24;
> +    case AOM_IMG_FMT_ARGB:      return AV_PIX_FMT_ARGB;
> +    case AOM_IMG_FMT_ARGB_LE:   return AV_PIX_FMT_BGRA;
> +    case AOM_IMG_FMT_RGB565_LE: return AV_PIX_FMT_RGB565LE;
> +    case AOM_IMG_FMT_RGB555_LE: return AV_PIX_FMT_RGB555LE;
> +    case AOM_IMG_FMT_I420:      return AV_PIX_FMT_YUV420P;
> +    case AOM_IMG_FMT_I422:      return AV_PIX_FMT_YUV422P;
> +    case AOM_IMG_FMT_I444:      return AV_PIX_FMT_YUV444P;
> +    case AOM_IMG_FMT_444A:      return AV_PIX_FMT_YUVA444P;
> +#if AOM_IMAGE_ABI_VERSION >= 3
> +    case AOM_IMG_FMT_I440:      return AV_PIX_FMT_YUV440P;
> +    case AOM_IMG_FMT_I42016:
> +        switch (bit_depth) {
> +            case 10: return AV_PIX_FMT_YUV420P10;
> +            case 12: return AV_PIX_FMT_YUV420P12;
> +        }
> +    case AOM_IMG_FMT_I42216:
> +        switch (bit_depth) {
> +            case 10: return AV_PIX_FMT_YUV422P10;
> +            case 12: return AV_PIX_FMT_YUV422P12;
> +        }
> +    case AOM_IMG_FMT_I44416:
> +        switch (bit_depth) {
> +            case 10: return AV_PIX_FMT_YUV444P10;
> +            case 12: return AV_PIX_FMT_YUV444P12;
> +        }
> +#endif
> +    default:                    return AV_PIX_FMT_NONE;
> +    }
> +}
> 
> and use
> +        avctx->pix_fmt = ff_aom_imgfmt_to_pixfmt(img->fmt, img->bit_depth);
> in libaomdec, the decoding result is identical to aomdec.
> 
> If it is correct to do this, ff_aom_pixfmt_to_imgfmt might also need to be
> re-defined. While libaom can be built with or without high bit depth
> support (--enable/disable-aom-highbitdepth), it does not expose a macro
> like AOM_IMG_FMT_HIGHBITDEPTH. It only defines CONFIG_AOM_HIGHBITDEPTH in
> aom_config.h which is used for building aom reference tools only. I'm not
> sure if we should add further check on the pixel format conversion above.

Thank you a lot =) I eventually found time to rebuild aom with the
correct flags to test it. I'm updating my patch accordingly.

lu

Patch

diff --git a/Changelog b/Changelog
index 0d04f47..5ee2346 100644
--- a/Changelog
+++ b/Changelog
@@ -62,6 +62,7 @@  version <next>:
 - Intel QSV video scaling and deinterlacing filter
 - OpenH264 decoder wrapper
 - Removed the legacy X11 screen grabber, use XCB instead
+- Alliance for Open Media AV1 decoding support using libaom
 
 
 version 11:
diff --git a/configure b/configure
index 8049d90..9cf7a1c 100755
--- a/configure
+++ b/configure
@@ -188,6 +188,7 @@  External library support:
   --enable-bzlib             bzip2 compression [autodetect]
   --enable-frei0r            video filtering plugins
   --enable-gnutls            crypto
+  --enable-libaom            AV1 video encoding/decoding
   --enable-libbs2b           Bauer stereophonic-to-binaural DSP
   --enable-libcdio           audio CD input
   --enable-libdc1394         IEEE 1394/Firewire camera input
@@ -1264,6 +1265,7 @@  EXTERNAL_LIBRARY_LIST="
     bzlib
     frei0r
     gnutls
+    libaom
     libbs2b
     libdc1394
     libdcadec
@@ -2236,6 +2238,7 @@  vc1_parser_select="vc1dsp"
 mjpeg2jpeg_bsf_select="jpegtables"
 
 # external libraries
+libaom_av1_decoder_deps="libaom"
 libdcadec_decoder_deps="libdcadec"
 libfaac_encoder_deps="libfaac"
 libfaac_encoder_select="audio_frame_queue"
@@ -4597,6 +4600,7 @@  enabled avisynth          && { check_lib2 "avisynth/avisynth_c.h windows.h" Load
 enabled cuda              && check_lib cuda.h cuInit -lcuda
 enabled frei0r            && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; }
 enabled gnutls            && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init
+enabled libaom            && require_pkg_config "aom >= 0.1.0" aom/aom_codec.h aom_codec_version
 enabled libbs2b           && require_pkg_config libbs2b bs2b.h bs2b_open
 enabled libdcadec         && require libdcadec libdcadec/dca_context.h dcadec_context_create -ldcadec
 enabled libfaac           && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
diff --git a/doc/general.texi b/doc/general.texi
index ea56bef..63b1afd 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -16,6 +16,14 @@  for more formats. None of them are used by default, their use has to be
 explicitly requested by passing the appropriate flags to
 @command{./configure}.
 
+@section Alliance for Open Media libaom
+
+Libav can make use of the libaom library for AV1 decoding.
+
+Go to @url{http://aomedia.org/} and follow the instructions for
+installing the library. Then pass @code{--enable-libaom} to configure to
+enable it.
+
 @section OpenCORE and VisualOn libraries
 
 Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer
@@ -576,6 +584,8 @@  following image formats are supported:
 @item Autodesk Animator Flic video  @tab     @tab  X
 @item Autodesk RLE           @tab     @tab  X
     @tab fourcc: AASC
+@item AV1                    @tab     @tab  E
+    @tab Supported through external library libaom
 @item AVS (Audio Video Standard) video  @tab     @tab  X
     @tab Video encoding used by the Creature Shock game.
 @item Beam Software VB       @tab     @tab  X
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 8eb7d36..65e95f3 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -653,6 +653,7 @@  OBJS-$(CONFIG_TAK_DEMUXER)             += tak.o
 OBJS-$(CONFIG_WEBM_MUXER)              += mpeg4audio.o
 
 # external codec libraries
+OBJS-$(CONFIG_LIBAOM_AV1_DECODER)         += libaomdec.o libaom.o
 OBJS-$(CONFIG_LIBDCADEC_DECODER)          += libdcadec.o dca.o
 OBJS-$(CONFIG_LIBFAAC_ENCODER)            += libfaac.o
 OBJS-$(CONFIG_LIBFDK_AAC_DECODER)         += libfdk-aacdec.o
@@ -770,6 +771,7 @@  SKIPHEADERS                            += %_tablegen.h                  \
 
 SKIPHEADERS-$(CONFIG_D3D11VA)          += d3d11va.h dxva2_internal.h
 SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
+SKIPHEADERS-$(CONFIG_LIBAOM)           += libaom.h
 SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.h
 SKIPHEADERS-$(CONFIG_LIBVPX)           += libvpx.h
 SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index e259de2..e3ccd55 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -458,6 +458,7 @@  void avcodec_register_all(void)
     REGISTER_ENCDEC (XSUB,              xsub);
 
     /* external libraries */
+    REGISTER_DECODER(LIBAOM_AV1,        libaom_av1);
     REGISTER_DECODER(LIBDCADEC,         libdcadec)
     REGISTER_ENCODER(LIBFAAC,           libfaac);
     REGISTER_ENCDEC (LIBFDK_AAC,        libfdk_aac);
diff --git a/libavcodec/libaom.c b/libavcodec/libaom.c
new file mode 100644
index 0000000..f8bcc37
--- /dev/null
+++ b/libavcodec/libaom.c
@@ -0,0 +1,75 @@ 
+/*
+ * Copyright (c) 2013 Guillaume Martres <smarter@ubuntu.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <aom/aom_image.h>
+
+#include "libaom.h"
+
+enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img)
+{
+    switch (img) {
+    case AOM_IMG_FMT_RGB24:     return AV_PIX_FMT_RGB24;
+    case AOM_IMG_FMT_RGB565:    return AV_PIX_FMT_RGB565BE;
+    case AOM_IMG_FMT_RGB555:    return AV_PIX_FMT_RGB555BE;
+    case AOM_IMG_FMT_UYVY:      return AV_PIX_FMT_UYVY422;
+    case AOM_IMG_FMT_YUY2:      return AV_PIX_FMT_YUYV422;
+    case AOM_IMG_FMT_YVYU:      return AV_PIX_FMT_YVYU422;
+    case AOM_IMG_FMT_BGR24:     return AV_PIX_FMT_BGR24;
+    case AOM_IMG_FMT_ARGB:      return AV_PIX_FMT_ARGB;
+    case AOM_IMG_FMT_ARGB_LE:   return AV_PIX_FMT_BGRA;
+    case AOM_IMG_FMT_RGB565_LE: return AV_PIX_FMT_RGB565LE;
+    case AOM_IMG_FMT_RGB555_LE: return AV_PIX_FMT_RGB555LE;
+    case AOM_IMG_FMT_I420:      return AV_PIX_FMT_YUV420P;
+    case AOM_IMG_FMT_I422:      return AV_PIX_FMT_YUV422P;
+    case AOM_IMG_FMT_I444:      return AV_PIX_FMT_YUV444P;
+    case AOM_IMG_FMT_444A:      return AV_PIX_FMT_YUVA444P;
+    case AOM_IMG_FMT_I440:      return AV_PIX_FMT_YUV440P;
+    case AOM_IMG_FMT_I42016:    return AV_PIX_FMT_YUV420P16BE;
+    case AOM_IMG_FMT_I42216:    return AV_PIX_FMT_YUV422P16BE;
+    case AOM_IMG_FMT_I44416:    return AV_PIX_FMT_YUV444P16BE;
+    default:                    return AV_PIX_FMT_NONE;
+    }
+}
+
+aom_img_fmt_t ff_aom_pixfmt_to_imgfmt(enum AVPixelFormat pix)
+{
+    switch (pix) {
+    case AV_PIX_FMT_RGB24:        return AOM_IMG_FMT_RGB24;
+    case AV_PIX_FMT_RGB565BE:     return AOM_IMG_FMT_RGB565;
+    case AV_PIX_FMT_RGB555BE:     return AOM_IMG_FMT_RGB555;
+    case AV_PIX_FMT_UYVY422:      return AOM_IMG_FMT_UYVY;
+    case AV_PIX_FMT_YUYV422:      return AOM_IMG_FMT_YUY2;
+    case AV_PIX_FMT_YVYU422:      return AOM_IMG_FMT_YVYU;
+    case AV_PIX_FMT_BGR24:        return AOM_IMG_FMT_BGR24;
+    case AV_PIX_FMT_ARGB:         return AOM_IMG_FMT_ARGB;
+    case AV_PIX_FMT_BGRA:         return AOM_IMG_FMT_ARGB_LE;
+    case AV_PIX_FMT_RGB565LE:     return AOM_IMG_FMT_RGB565_LE;
+    case AV_PIX_FMT_RGB555LE:     return AOM_IMG_FMT_RGB555_LE;
+    case AV_PIX_FMT_YUV420P:      return AOM_IMG_FMT_I420;
+    case AV_PIX_FMT_YUV422P:      return AOM_IMG_FMT_I422;
+    case AV_PIX_FMT_YUV444P:      return AOM_IMG_FMT_I444;
+    case AV_PIX_FMT_YUVA444P:     return AOM_IMG_FMT_444A;
+    case AV_PIX_FMT_YUV440P:      return AOM_IMG_FMT_I440;
+    case AV_PIX_FMT_YUV420P16BE:  return AOM_IMG_FMT_I42016;
+    case AV_PIX_FMT_YUV422P16BE:  return AOM_IMG_FMT_I42216;
+    case AV_PIX_FMT_YUV444P16BE:  return AOM_IMG_FMT_I44416;
+    default:                      return AOM_IMG_FMT_NONE;
+    }
+}
diff --git a/libavcodec/libaom.h b/libavcodec/libaom.h
new file mode 100644
index 0000000..7a7b8db
--- /dev/null
+++ b/libavcodec/libaom.h
@@ -0,0 +1,31 @@ 
+/*
+ * Copyright (c) 2013 Guillaume Martres <smarter@ubuntu.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_LIBAOM_H
+#define AVCODEC_LIBAOM_H
+
+#include <aom/aom_codec.h>
+
+#include "libavutil/pixfmt.h"
+
+enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img);
+aom_img_fmt_t ff_aom_pixfmt_to_imgfmt(enum AVPixelFormat pix);
+
+#endif /* AVCODEC_LIBAOM_H */
diff --git a/libavcodec/libaomdec.c b/libavcodec/libaomdec.c
new file mode 100644
index 0000000..e975b63
--- /dev/null
+++ b/libavcodec/libaomdec.c
@@ -0,0 +1,137 @@ 
+/*
+ * Copyright (c) 2010, Google, Inc.
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AV1 decoder support via libaom
+ */
+
+#include <aom/aom_decoder.h>
+#include <aom/aomdx.h>
+
+#include "libavutil/common.h"
+#include "libavutil/imgutils.h"
+
+#include "avcodec.h"
+#include "internal.h"
+#include "libaom.h"
+
+typedef struct AV1DecodeContext {
+    struct aom_codec_ctx decoder;
+} AV1DecodeContext;
+
+static av_cold int aom_init(AVCodecContext *avctx,
+                            const struct aom_codec_iface *iface)
+{
+    AV1DecodeContext *ctx = avctx->priv_data;
+    struct aom_codec_dec_cfg deccfg = {
+        /* token partitions+1 would be a decent choice */
+        .threads = FFMIN(avctx->thread_count, 16)
+    };
+
+    av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str());
+    av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config());
+
+    if (aom_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != AOM_CODEC_OK) {
+        const char *error = aom_codec_error(&ctx->decoder);
+        av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
+               error);
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+static int aom_decode(AVCodecContext *avctx, void *data, int *got_frame,
+                      AVPacket *avpkt)
+{
+    AV1DecodeContext *ctx = avctx->priv_data;
+    AVFrame *picture = data;
+    const void *iter = NULL;
+    struct aom_image *img;
+    int ret;
+
+    if (aom_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) !=
+        AOM_CODEC_OK) {
+        const char *error  = aom_codec_error(&ctx->decoder);
+        const char *detail = aom_codec_error_detail(&ctx->decoder);
+
+        av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error);
+        if (detail)
+            av_log(avctx, AV_LOG_ERROR, "  Additional information: %s\n",
+                   detail);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((img = aom_codec_get_frame(&ctx->decoder, &iter))) {
+        avctx->pix_fmt = ff_aom_imgfmt_to_pixfmt(img->fmt);
+        if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
+            av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n",
+                   img->fmt);
+            return AVERROR_INVALIDDATA;
+        }
+
+        if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) {
+            av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
+                   avctx->width, avctx->height, img->d_w, img->d_h);
+            ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
+            if (ret < 0)
+                return ret;
+        }
+        if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
+            return ret;
+        av_image_copy(picture->data, picture->linesize, (const uint8_t **) img->planes,
+                      img->stride, avctx->pix_fmt, img->d_w, img->d_h);
+        switch (img->range) {
+        case AOM_CR_STUDIO_RANGE:
+            picture->color_range = AVCOL_RANGE_MPEG;
+            break;
+        case AOM_CR_FULL_RANGE:
+            picture->color_range = AVCOL_RANGE_JPEG;
+            break;
+        }
+        *got_frame           = 1;
+    }
+    return avpkt->size;
+}
+
+static av_cold int aom_free(AVCodecContext *avctx)
+{
+    AV1DecodeContext *ctx = avctx->priv_data;
+    aom_codec_destroy(&ctx->decoder);
+    return 0;
+}
+
+static av_cold int av1_init(AVCodecContext *avctx)
+{
+    return aom_init(avctx, &aom_codec_av1_dx_algo);
+}
+
+AVCodec ff_libaom_av1_decoder = {
+    .name           = "libaom",
+    .long_name      = NULL_IF_CONFIG_SMALL("libaom AV1"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_AV1,
+    .priv_data_size = sizeof(AV1DecodeContext),
+    .init           = av1_init,
+    .close          = aom_free,
+    .decode         = aom_decode,
+    .capabilities   = AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_DR1,
+};
diff --git a/libavcodec/version.h b/libavcodec/version.h
index f944709..c6eea8d 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,7 +28,7 @@ 
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 57
-#define LIBAVCODEC_VERSION_MINOR 25
+#define LIBAVCODEC_VERSION_MINOR 27
 #define LIBAVCODEC_VERSION_MICRO  0
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \