1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-03-28 12:32:17 +02:00

Add AV1 video decoding support through libaom

Signed-off-by: Diego Biurrun <diego@biurrun.de>
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
This commit is contained in:
Luca Barbato 2016-08-25 17:28:17 +02:00
parent 44a1731011
commit c438899a70
8 changed files with 342 additions and 0 deletions

View File

@ -20,6 +20,7 @@ version <next>:
- Intel QSV-accelerated MJPEG encoding - Intel QSV-accelerated MJPEG encoding
- NVIDIA CUVID-accelerated H.264 and HEVC decoding - NVIDIA CUVID-accelerated H.264 and HEVC decoding
- Intel QSV-accelerated overlay filter - Intel QSV-accelerated overlay filter
- AV1 Support through libaom
version 12: version 12:

4
configure vendored
View File

@ -187,6 +187,7 @@ External library support:
--enable-bzlib bzip2 compression [autodetect] --enable-bzlib bzip2 compression [autodetect]
--enable-frei0r video filtering plugins --enable-frei0r video filtering plugins
--enable-gnutls crypto --enable-gnutls crypto
--enable-libaom AV1 video encoding/decoding
--enable-libbs2b Bauer stereophonic-to-binaural DSP --enable-libbs2b Bauer stereophonic-to-binaural DSP
--enable-libcdio audio CD input --enable-libcdio audio CD input
--enable-libdc1394 IEEE 1394/Firewire camera input --enable-libdc1394 IEEE 1394/Firewire camera input
@ -1349,6 +1350,7 @@ EXTERNAL_LIBRARY_LIST="
avxsynth avxsynth
frei0r frei0r
gnutls gnutls
libaom
libbs2b libbs2b
libdc1394 libdc1394
libdcadec libdcadec
@ -2363,6 +2365,7 @@ avisynth_deps="LoadLibrary"
avxsynth_deps="libdl" avxsynth_deps="libdl"
avisynth_demuxer_deps_any="avisynth avxsynth" avisynth_demuxer_deps_any="avisynth avxsynth"
avisynth_demuxer_select="riffdec" avisynth_demuxer_select="riffdec"
libaom_av1_decoder_deps="libaom"
libdcadec_decoder_deps="libdcadec" libdcadec_decoder_deps="libdcadec"
libfaac_encoder_deps="libfaac" libfaac_encoder_deps="libfaac"
libfaac_encoder_select="audio_frame_queue" libfaac_encoder_select="audio_frame_queue"
@ -4641,6 +4644,7 @@ enabled cuvid && require cuvid cuviddec.h cuvidCreateDecoder -lnvcuv
enabled frei0r && require_header frei0r.h enabled frei0r && require_header frei0r.h
enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init && enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init &&
check_lib gmp gmp.h mpz_export -lgmp check_lib gmp gmp.h mpz_export -lgmp
enabled libaom && require_pkg_config libaom "aom >= 0.1.0" aom/aom_codec.h aom_codec_version
enabled libbs2b && require_pkg_config libbs2b libbs2b bs2b.h bs2b_open enabled libbs2b && require_pkg_config libbs2b libbs2b bs2b.h bs2b_open
enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new
enabled libdcadec && require libdcadec libdcadec/dca_context.h dcadec_context_create -ldcadec enabled libdcadec && require libdcadec libdcadec/dca_context.h dcadec_context_create -ldcadec

View File

@ -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 explicitly requested by passing the appropriate flags to
@command{./configure}. @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 @section OpenCORE and VisualOn libraries
Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer
@ -617,6 +625,8 @@ following image formats are supported:
@item Autodesk Animator Flic video @tab @tab X @item Autodesk Animator Flic video @tab @tab X
@item Autodesk RLE @tab @tab X @item Autodesk RLE @tab @tab X
@tab fourcc: AASC @tab fourcc: AASC
@item AV1 @tab @tab E
@tab Supported through external library libaom
@item AVS (Audio Video Standard) video @tab @tab X @item AVS (Audio Video Standard) video @tab @tab X
@tab Video encoding used by the Creature Shock game. @tab Video encoding used by the Creature Shock game.
@item Beam Software VB @tab @tab X @item Beam Software VB @tab @tab X

View File

@ -687,6 +687,7 @@ OBJS-$(CONFIG_TAK_DEMUXER) += tak.o
OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o
# external codec libraries # external codec libraries
OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o libaom.o
OBJS-$(CONFIG_LIBDCADEC_DECODER) += libdcadec.o dca.o OBJS-$(CONFIG_LIBDCADEC_DECODER) += libdcadec.o dca.o
OBJS-$(CONFIG_LIBFAAC_ENCODER) += libfaac.o OBJS-$(CONFIG_LIBFAAC_ENCODER) += libfaac.o
OBJS-$(CONFIG_LIBFDK_AAC_DECODER) += libfdk-aacdec.o OBJS-$(CONFIG_LIBFDK_AAC_DECODER) += libfdk-aacdec.o
@ -814,6 +815,7 @@ SKIPHEADERS-$(CONFIG_CUVID) += cuvid.h
SKIPHEADERS-$(CONFIG_AMF) += amfenc.h SKIPHEADERS-$(CONFIG_AMF) += amfenc.h
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_LIBAOM) += libaom.h
SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h
SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h
SKIPHEADERS-$(CONFIG_NVENC) += nvenc.h SKIPHEADERS-$(CONFIG_NVENC) += nvenc.h

View File

@ -421,6 +421,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (XSUB, xsub); REGISTER_ENCDEC (XSUB, xsub);
/* external libraries */ /* external libraries */
REGISTER_DECODER(LIBAOM_AV1, libaom_av1);
REGISTER_DECODER(LIBDCADEC, libdcadec) REGISTER_DECODER(LIBDCADEC, libdcadec)
REGISTER_ENCODER(LIBFAAC, libfaac); REGISTER_ENCODER(LIBFAAC, libfaac);
REGISTER_ENCDEC (LIBFDK_AAC, libfdk_aac); REGISTER_ENCDEC (LIBFDK_AAC, libfdk_aac);

133
libavcodec/libaom.c Normal file
View File

@ -0,0 +1,133 @@
/*
* 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"
#define HIGH_DEPTH(fmt) \
case AOM_IMG_FMT_I ## fmt ## 16: \
switch (depth) { \
case 8: \
return AV_PIX_FMT_YUV ## fmt ## P; \
case 10: \
return AV_PIX_FMT_YUV ## fmt ## P10; \
case 12: \
return AV_PIX_FMT_YUV ## fmt ## P12; \
default: \
return AV_PIX_FMT_NONE; \
}
enum AVPixelFormat ff_aom_imgfmt_to_pixfmt(aom_img_fmt_t img, int 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;
case AOM_IMG_FMT_I440:
return AV_PIX_FMT_YUV440P;
HIGH_DEPTH(420)
HIGH_DEPTH(422)
HIGH_DEPTH(444)
default:
return AV_PIX_FMT_NONE;
}
}
#undef HIGH_DEPTH
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_YUV420P10:
return AOM_IMG_FMT_I42016;
case AV_PIX_FMT_YUV422P10:
return AOM_IMG_FMT_I42216;
case AV_PIX_FMT_YUV444P10:
return AOM_IMG_FMT_I44416;
case AV_PIX_FMT_YUV420P12:
return AOM_IMG_FMT_I42016;
case AV_PIX_FMT_YUV422P12:
return AOM_IMG_FMT_I42216;
case AV_PIX_FMT_YUV444P12:
return AOM_IMG_FMT_I44416;
default:
return AOM_IMG_FMT_NONE;
}
}

31
libavcodec/libaom.h Normal file
View File

@ -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, int depth);
aom_img_fmt_t ff_aom_pixfmt_to_imgfmt(enum AVPixelFormat pix);
#endif /* AVCODEC_LIBAOM_H */

160
libavcodec/libaomdec.c Normal file
View File

@ -0,0 +1,160 @@
/*
* 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)
{
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)
};
const struct aom_codec_iface *iface = &aom_codec_av1_dx_algo;
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 void image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
{
int i;
for (i = 0; i < 3; i++) {
int w = img->d_w;
int h = img->d_h;
int x, y;
if (i) {
w = (w + img->x_chroma_shift) >> img->x_chroma_shift;
h = (h + img->y_chroma_shift) >> img->y_chroma_shift;
}
for (y = 0; y < h; y++) {
uint16_t *src = (uint16_t *)(img->planes[i] + y * img->stride[i]);
uint8_t *dst = pic->data[i] + y * pic->linesize[i];
for (x = 0; x < w; x++)
*dst++ = *src++;
}
}
}
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) !=
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, img->bit_depth);
if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (0x%02x %dbits)\n",
img->fmt, img->bit_depth);
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;
if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img->bit_depth == 8)
image_copy_16_to_8(picture, img);
else
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;
}
AVCodec ff_libaom_av1_decoder = {
.name = "libaom-av1",
.long_name = NULL_IF_CONFIG_SMALL("libaom AV1"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_AV1,
.priv_data_size = sizeof(AV1DecodeContext),
.init = aom_init,
.close = aom_free,
.decode = aom_decode,
.capabilities = AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_DR1,
.wrapper_name = "libaom",
};