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 <[email protected]> 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 <[email protected]> wrote: > >> From: Luca Barbato <[email protected]> >> >> Signed-off-by: Diego Biurrun <[email protected]> >> --- >> >> 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 <[email protected]> >> + * >> + * 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 <[email protected]> >> + * >> + * 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 >> [email protected] >> https://lists.libav.org/mailman/listinfo/libav-devel >> > > _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
