FFmpeg
libaomdec.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, Google, Inc.
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * AV1 decoder support via libaom
24  */
25 
26 #include <aom/aom_decoder.h>
27 #include <aom/aomdx.h>
28 
29 #include "libavutil/common.h"
30 #include "libavutil/cpu.h"
31 #include "libavutil/imgutils.h"
32 
33 #include "avcodec.h"
34 #include "internal.h"
35 #include "profiles.h"
36 
37 typedef struct AV1DecodeContext {
38  struct aom_codec_ctx decoder;
40 
41 static av_cold int aom_init(AVCodecContext *avctx,
42  const struct aom_codec_iface *iface)
43 {
44  AV1DecodeContext *ctx = avctx->priv_data;
45  struct aom_codec_dec_cfg deccfg = {
46  .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16)
47  };
48 
49  av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str());
50  av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config());
51 
52  if (aom_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != AOM_CODEC_OK) {
53  const char *error = aom_codec_error(&ctx->decoder);
54  av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
55  error);
56  return AVERROR(EINVAL);
57  }
58 
59  return 0;
60 }
61 
62 static void image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
63 {
65  int i;
66 
67  for (i = 0; i < desc->nb_components; i++) {
68  int w = img->d_w;
69  int h = img->d_h;
70  int x, y;
71 
72  if (i) {
73  w = (w + img->x_chroma_shift) >> img->x_chroma_shift;
74  h = (h + img->y_chroma_shift) >> img->y_chroma_shift;
75  }
76 
77  for (y = 0; y < h; y++) {
78  uint16_t *src = (uint16_t *)(img->planes[i] + y * img->stride[i]);
79  uint8_t *dst = pic->data[i] + y * pic->linesize[i];
80  for (x = 0; x < w; x++)
81  *dst++ = *src++;
82  }
83  }
84 }
85 
86 // returns 0 on success, AVERROR_INVALIDDATA otherwise
87 static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
88 {
89  static const enum AVColorRange color_ranges[] = {
91  };
92  avctx->color_range = color_ranges[img->range];
93  avctx->color_primaries = img->cp;
94  avctx->colorspace = img->mc;
95  avctx->color_trc = img->tc;
96 
97  switch (img->fmt) {
98  case AOM_IMG_FMT_I420:
99  case AOM_IMG_FMT_I42016:
100  if (img->bit_depth == 8) {
101  avctx->pix_fmt = img->monochrome ?
103  avctx->profile = FF_PROFILE_AV1_MAIN;
104  return 0;
105  } else if (img->bit_depth == 10) {
106  avctx->pix_fmt = img->monochrome ?
108  avctx->profile = FF_PROFILE_AV1_MAIN;
109  return 0;
110  } else if (img->bit_depth == 12) {
111  avctx->pix_fmt = img->monochrome ?
114  return 0;
115  } else {
116  return AVERROR_INVALIDDATA;
117  }
118  case AOM_IMG_FMT_I422:
119  case AOM_IMG_FMT_I42216:
120  if (img->bit_depth == 8) {
121  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
123  return 0;
124  } else if (img->bit_depth == 10) {
125  avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
127  return 0;
128  } else if (img->bit_depth == 12) {
129  avctx->pix_fmt = AV_PIX_FMT_YUV422P12;
131  return 0;
132  } else {
133  return AVERROR_INVALIDDATA;
134  }
135  case AOM_IMG_FMT_I444:
136  case AOM_IMG_FMT_I44416:
137  if (img->bit_depth == 8) {
138  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
139  avctx->profile = FF_PROFILE_AV1_HIGH;
140  return 0;
141  } else if (img->bit_depth == 10) {
142  avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
143  avctx->profile = FF_PROFILE_AV1_HIGH;
144  return 0;
145  } else if (img->bit_depth == 12) {
146  avctx->pix_fmt = AV_PIX_FMT_YUV444P12;
148  return 0;
149  } else {
150  return AVERROR_INVALIDDATA;
151  }
152 
153  default:
154  return AVERROR_INVALIDDATA;
155  }
156 }
157 
158 static int aom_decode(AVCodecContext *avctx, void *data, int *got_frame,
159  AVPacket *avpkt)
160 {
161  AV1DecodeContext *ctx = avctx->priv_data;
162  AVFrame *picture = data;
163  const void *iter = NULL;
164  struct aom_image *img;
165  int ret;
166 
167  if (aom_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL) !=
168  AOM_CODEC_OK) {
169  const char *error = aom_codec_error(&ctx->decoder);
170  const char *detail = aom_codec_error_detail(&ctx->decoder);
171 
172  av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error);
173  if (detail)
174  av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n",
175  detail);
176  return AVERROR_INVALIDDATA;
177  }
178 
179  if ((img = aom_codec_get_frame(&ctx->decoder, &iter))) {
180  if (img->d_w > img->w || img->d_h > img->h) {
181  av_log(avctx, AV_LOG_ERROR, "Display dimensions %dx%d exceed storage %dx%d\n",
182  img->d_w, img->d_h, img->w, img->h);
183  return AVERROR_EXTERNAL;
184  }
185 
186  if ((ret = set_pix_fmt(avctx, img)) < 0) {
187  av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n",
188  img->fmt, img->bit_depth);
189  return ret;
190  }
191 
192  if ((int)img->d_w != avctx->width || (int)img->d_h != avctx->height) {
193  av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
194  avctx->width, avctx->height, img->d_w, img->d_h);
195  ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
196  if (ret < 0)
197  return ret;
198  }
199  if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
200  return ret;
201 
202 #ifdef AOM_CTRL_AOMD_GET_FRAME_FLAGS
203  {
204  aom_codec_frame_flags_t flags;
205  ret = aom_codec_control(&ctx->decoder, AOMD_GET_FRAME_FLAGS, &flags);
206  if (ret == AOM_CODEC_OK) {
207  picture->key_frame = !!(flags & AOM_FRAME_IS_KEY);
208  if (flags & (AOM_FRAME_IS_KEY | AOM_FRAME_IS_INTRAONLY))
209  picture->pict_type = AV_PICTURE_TYPE_I;
210  else if (flags & AOM_FRAME_IS_SWITCH)
211  picture->pict_type = AV_PICTURE_TYPE_SP;
212  else
213  picture->pict_type = AV_PICTURE_TYPE_P;
214  }
215  }
216 #endif
217 
219  &picture->sample_aspect_ratio.den,
220  picture->height * img->r_w,
221  picture->width * img->r_h,
222  INT_MAX);
223  ff_set_sar(avctx, picture->sample_aspect_ratio);
224 
225  if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img->bit_depth == 8)
226  image_copy_16_to_8(picture, img);
227  else {
228  const uint8_t *planes[4] = { img->planes[0], img->planes[1], img->planes[2] };
229  const int stride[4] = { img->stride[0], img->stride[1], img->stride[2] };
230 
231  av_image_copy(picture->data, picture->linesize, planes,
232  stride, avctx->pix_fmt, img->d_w, img->d_h);
233  }
234  *got_frame = 1;
235  }
236  return avpkt->size;
237 }
238 
239 static av_cold int aom_free(AVCodecContext *avctx)
240 {
241  AV1DecodeContext *ctx = avctx->priv_data;
242  aom_codec_destroy(&ctx->decoder);
243  return 0;
244 }
245 
246 static av_cold int av1_init(AVCodecContext *avctx)
247 {
248  return aom_init(avctx, aom_codec_av1_dx());
249 }
250 
252  .name = "libaom-av1",
253  .long_name = NULL_IF_CONFIG_SMALL("libaom AV1"),
254  .type = AVMEDIA_TYPE_VIDEO,
255  .id = AV_CODEC_ID_AV1,
256  .priv_data_size = sizeof(AV1DecodeContext),
257  .init = av1_init,
258  .close = aom_free,
259  .decode = aom_decode,
261  .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
263  .wrapper_name = "libaom",
264 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
AVCodec
AVCodec.
Definition: codec.h:202
stride
int stride
Definition: mace.c:144
aom_free
static av_cold int aom_free(AVCodecContext *avctx)
Definition: libaomdec.c:239
aom_init
static av_cold int aom_init(AVCodecContext *avctx, const struct aom_codec_iface *iface)
Definition: libaomdec.c:41
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:960
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2660
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:953
AVFrame::width
int width
Definition: frame.h:389
w
uint8_t w
Definition: llviddspenc.c:38
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:597
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
set_pix_fmt
static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
Definition: libaomdec.c:87
data
const char data[16]
Definition: mxf.c:143
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:404
ff_libaom_av1_decoder
const AVCodec ff_libaom_av1_decoder
Definition: libaomdec.c:251
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:338
init
static int init
Definition: av_tx.c:47
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1440
AVFrame::key_frame
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:409
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
AVRational::num
int num
Numerator.
Definition: rational.h:59
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:407
AV1DecodeContext::decoder
struct aom_codec_ctx decoder
Definition: libaomdec.c:38
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:946
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
AV_CODEC_CAP_OTHER_THREADS
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
Definition: codec.h:127
ctx
AVFormatContext * ctx
Definition: movenc.c:48
ff_av1_profiles
const AVProfile ff_av1_profiles[]
Definition: profiles.c:147
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
planes
static const struct @321 planes[]
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:385
if
if(ret)
Definition: filter_design.txt:179
NULL
#define NULL
Definition: coverity.c:32
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:967
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:279
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
profiles.h
src
#define src
Definition: vp8dsp.c:255
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:405
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
AV_PICTURE_TYPE_SP
@ AV_PICTURE_TYPE_SP
Switching Predicted.
Definition: avutil.h:279
aom_decode
static int aom_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: libaomdec.c:158
av_cpu_count
int av_cpu_count(void)
Definition: cpu.c:191
FF_CODEC_CAP_AUTO_THREADS
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
Definition: internal.h:81
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:414
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1652
FF_PROFILE_AV1_MAIN
#define FF_PROFILE_AV1_MAIN
Definition: avcodec.h:1621
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:374
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
av1_init
static av_cold int av1_init(AVCodecContext *avctx)
Definition: libaomdec.c:246
cpu.h
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:409
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:411
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:404
img
#define img
Definition: vf_colormatrix.c:116
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
AVCodecContext::height
int height
Definition: avcodec.h:556
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:580
FF_PROFILE_AV1_PROFESSIONAL
#define FF_PROFILE_AV1_PROFESSIONAL
Definition: avcodec.h:1623
avcodec.h
ret
ret
Definition: filter_design.txt:187
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:419
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:408
image_copy_16_to_8
static void image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
Definition: libaomdec.c:62
ff_set_sar
int ff_set_sar(AVCodecContext *avctx, AVRational sar)
Check that the provided sample aspect ratio is valid and set it on the codec context.
Definition: utils.c:101
AVCodecContext
main external API structure.
Definition: avcodec.h:383
AVFrame::height
int height
Definition: frame.h:389
av_image_copy
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition: imgutils.c:422
AVRational::den
int den
Denominator.
Definition: rational.h:60
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1525
AV1DecodeContext
Definition: libaomdec.c:37
profiles
static const AVProfile profiles[]
Definition: libfdk-aacenc.c:429
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
desc
const char * desc
Definition: libsvtav1.c:79
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:86
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:362
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
FF_PROFILE_AV1_HIGH
#define FF_PROFILE_AV1_HIGH
Definition: avcodec.h:1622
h
h
Definition: vp9dsp_template.c:2038
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:386
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:562