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/imgutils.h"
31 
32 #include "avcodec.h"
33 #include "internal.h"
34 #include "profiles.h"
35 
36 typedef struct AV1DecodeContext {
37  struct aom_codec_ctx decoder;
39 
40 static av_cold int aom_init(AVCodecContext *avctx,
41  const struct aom_codec_iface *iface)
42 {
43  AV1DecodeContext *ctx = avctx->priv_data;
44  struct aom_codec_dec_cfg deccfg = {
45  .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16)
46  };
47 
48  av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str());
49  av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config());
50 
51  if (aom_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != AOM_CODEC_OK) {
52  const char *error = aom_codec_error(&ctx->decoder);
53  av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
54  error);
55  return AVERROR(EINVAL);
56  }
57 
58  return 0;
59 }
60 
61 static void image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
62 {
64  int i;
65 
66  for (i = 0; i < desc->nb_components; i++) {
67  int w = img->d_w;
68  int h = img->d_h;
69  int x, y;
70 
71  if (i) {
72  w = (w + img->x_chroma_shift) >> img->x_chroma_shift;
73  h = (h + img->y_chroma_shift) >> img->y_chroma_shift;
74  }
75 
76  for (y = 0; y < h; y++) {
77  uint16_t *src = (uint16_t *)(img->planes[i] + y * img->stride[i]);
78  uint8_t *dst = pic->data[i] + y * pic->linesize[i];
79  for (x = 0; x < w; x++)
80  *dst++ = *src++;
81  }
82  }
83 }
84 
85 // returns 0 on success, AVERROR_INVALIDDATA otherwise
86 static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
87 {
88  static const enum AVColorRange color_ranges[] = {
90  };
91  avctx->color_range = color_ranges[img->range];
92  avctx->color_primaries = img->cp;
93  avctx->colorspace = img->mc;
94  avctx->color_trc = img->tc;
95 
96  switch (img->fmt) {
97  case AOM_IMG_FMT_I420:
98  case AOM_IMG_FMT_I42016:
99  if (img->bit_depth == 8) {
100  avctx->pix_fmt = img->monochrome ?
102  avctx->profile = FF_PROFILE_AV1_MAIN;
103  return 0;
104  } else if (img->bit_depth == 10) {
105  avctx->pix_fmt = img->monochrome ?
107  avctx->profile = FF_PROFILE_AV1_MAIN;
108  return 0;
109  } else if (img->bit_depth == 12) {
110  avctx->pix_fmt = img->monochrome ?
113  return 0;
114  } else {
115  return AVERROR_INVALIDDATA;
116  }
117  case AOM_IMG_FMT_I422:
118  case AOM_IMG_FMT_I42216:
119  if (img->bit_depth == 8) {
120  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
122  return 0;
123  } else if (img->bit_depth == 10) {
124  avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
126  return 0;
127  } else if (img->bit_depth == 12) {
128  avctx->pix_fmt = AV_PIX_FMT_YUV422P12;
130  return 0;
131  } else {
132  return AVERROR_INVALIDDATA;
133  }
134  case AOM_IMG_FMT_I444:
135  case AOM_IMG_FMT_I44416:
136  if (img->bit_depth == 8) {
137  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
138  avctx->profile = FF_PROFILE_AV1_HIGH;
139  return 0;
140  } else if (img->bit_depth == 10) {
141  avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
142  avctx->profile = FF_PROFILE_AV1_HIGH;
143  return 0;
144  } else if (img->bit_depth == 12) {
145  avctx->pix_fmt = AV_PIX_FMT_YUV444P12;
147  return 0;
148  } else {
149  return AVERROR_INVALIDDATA;
150  }
151 
152  default:
153  return AVERROR_INVALIDDATA;
154  }
155 }
156 
157 static int aom_decode(AVCodecContext *avctx, void *data, int *got_frame,
158  AVPacket *avpkt)
159 {
160  AV1DecodeContext *ctx = avctx->priv_data;
161  AVFrame *picture = data;
162  const void *iter = NULL;
163  struct aom_image *img;
164  int ret;
165 
166  if (aom_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL) !=
167  AOM_CODEC_OK) {
168  const char *error = aom_codec_error(&ctx->decoder);
169  const char *detail = aom_codec_error_detail(&ctx->decoder);
170 
171  av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error);
172  if (detail)
173  av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n",
174  detail);
175  return AVERROR_INVALIDDATA;
176  }
177 
178  if ((img = aom_codec_get_frame(&ctx->decoder, &iter))) {
179  if (img->d_w > img->w || img->d_h > img->h) {
180  av_log(avctx, AV_LOG_ERROR, "Display dimensions %dx%d exceed storage %dx%d\n",
181  img->d_w, img->d_h, img->w, img->h);
182  return AVERROR_EXTERNAL;
183  }
184 
185  if ((ret = set_pix_fmt(avctx, img)) < 0) {
186  av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n",
187  img->fmt, img->bit_depth);
188  return ret;
189  }
190 
191  if ((int)img->d_w != avctx->width || (int)img->d_h != avctx->height) {
192  av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
193  avctx->width, avctx->height, img->d_w, img->d_h);
194  ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
195  if (ret < 0)
196  return ret;
197  }
198  if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
199  return ret;
200 
202  &picture->sample_aspect_ratio.den,
203  picture->height * img->r_w,
204  picture->width * img->r_h,
205  INT_MAX);
206  ff_set_sar(avctx, picture->sample_aspect_ratio);
207 
208  if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img->bit_depth == 8)
209  image_copy_16_to_8(picture, img);
210  else
211  av_image_copy(picture->data, picture->linesize, (const uint8_t **)img->planes,
212  img->stride, avctx->pix_fmt, img->d_w, img->d_h);
213  *got_frame = 1;
214  }
215  return avpkt->size;
216 }
217 
218 static av_cold int aom_free(AVCodecContext *avctx)
219 {
220  AV1DecodeContext *ctx = avctx->priv_data;
221  aom_codec_destroy(&ctx->decoder);
222  return 0;
223 }
224 
225 static av_cold int av1_init(AVCodecContext *avctx)
226 {
227  return aom_init(avctx, &aom_codec_av1_dx_algo);
228 }
229 
231  .name = "libaom-av1",
232  .long_name = NULL_IF_CONFIG_SMALL("libaom AV1"),
233  .type = AVMEDIA_TYPE_VIDEO,
234  .id = AV_CODEC_ID_AV1,
235  .priv_data_size = sizeof(AV1DecodeContext),
236  .init = av1_init,
237  .close = aom_free,
238  .decode = aom_decode,
241  .wrapper_name = "libaom",
242 };
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
This structure describes decoded (raw) audio or video data.
Definition: frame.h:308
static av_cold int aom_free(AVCodecContext *avctx)
Definition: libaomdec.c:218
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
int av_cpu_count(void)
Definition: cpu.c:275
static av_cold int aom_init(AVCodecContext *avctx, const struct aom_codec_iface *iface)
Definition: libaomdec.c:40
const char * desc
Definition: libsvtav1.c:79
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
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:106
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static int aom_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: libaomdec.c:157
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:1161
int num
Numerator.
Definition: rational.h:59
int size
Definition: packet.h:364
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:736
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:403
static void error(const char *err)
#define AV_CODEC_CAP_AUTO_THREADS
Codec supports avctx->thread_count == 0 (auto).
Definition: codec.h:118
struct aom_codec_ctx decoder
Definition: libaomdec.c:37
int profile
profile
Definition: avcodec.h:1859
AVCodec.
Definition: codec.h:190
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:380
#define img
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:381
uint8_t
#define av_cold
Definition: attributes.h:88
uint8_t * data
Definition: packet.h:363
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:121
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
AVColorRange
MPEG vs JPEG YUV range.
Definition: pixfmt.h:535
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
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:404
#define av_log(a,...)
#define src
Definition: vp8dsp.c:254
int width
Definition: frame.h:366
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
const char * name
Name of the codec implementation.
Definition: codec.h:197
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:402
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
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:83
#define FFMIN(a, b)
Definition: common.h:96
int width
picture width / height.
Definition: avcodec.h:699
uint8_t w
Definition: llviddspenc.c:38
AVCodec ff_libaom_av1_decoder
Definition: libaomdec.c:230
AVFormatContext * ctx
Definition: movenc.c:48
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:1140
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:1785
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:538
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:381
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
static void image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
Definition: libaomdec.c:61
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:339
const AVProfile ff_av1_profiles[]
Definition: profiles.c:141
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
main external API structure.
Definition: avcodec.h:526
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:396
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1872
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
static const AVProfile profiles[]
#define FF_PROFILE_AV1_PROFESSIONAL
Definition: avcodec.h:1954
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1154
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:1147
static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
Definition: libaomdec.c:86
#define FF_PROFILE_AV1_MAIN
Definition: avcodec.h:1952
static av_cold int av1_init(AVCodecContext *avctx)
Definition: libaomdec.c:225
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:406
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:322
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:537
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
Y , 8bpp.
Definition: pixfmt.h:74
common internal api header.
common internal and external API header
int den
Denominator.
Definition: rational.h:60
void * priv_data
Definition: avcodec.h:553
int height
Definition: frame.h:366
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
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
This structure stores compressed data.
Definition: packet.h:340
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
int i
Definition: input.c:407
#define FF_PROFILE_AV1_HIGH
Definition: avcodec.h:1953