FFmpeg
Loading...
Searching...
No Matches
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"
32#include "libavutil/imgutils.h"
33
34#include "avcodec.h"
35#include "bytestream.h"
36#include "codec_internal.h"
37#include "decode.h"
38#include "itut35.h"
39#include "libaom.h"
40#include "profiles.h"
41
42typedef struct AV1DecodeContext {
43 struct aom_codec_ctx decoder;
45
47 const struct aom_codec_iface *iface)
48{
50 struct aom_codec_dec_cfg deccfg = {
51 .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16)
52 };
53
54 av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_version_str());
55 av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config());
56
57 if (aom_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != AOM_CODEC_OK) {
58 const char *error = aom_codec_error(&ctx->decoder);
59 av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
60 error);
61 return AVERROR(EINVAL);
62 }
63
64 return 0;
65}
66
67// returns 0 on success, AVERROR_INVALIDDATA otherwise
68static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
69{
70 static const enum AVColorRange color_ranges[] = {
72 };
73 avctx->color_range = color_ranges[img->range];
74 if (img->cp != AOM_CICP_CP_UNSPECIFIED)
75 avctx->color_primaries = (enum AVColorPrimaries)img->cp;
76 if (img->mc != AOM_CICP_MC_UNSPECIFIED)
77 avctx->colorspace = (enum AVColorSpace)img->mc;
78 if (img->tc != AOM_CICP_TC_UNSPECIFIED)
80
81 switch (img->fmt) {
82 case AOM_IMG_FMT_I420:
83 case AOM_IMG_FMT_I42016:
84 if (img->bit_depth == 8) {
85 avctx->pix_fmt = img->monochrome ?
88 return 0;
89 } else if (img->bit_depth == 10) {
90 avctx->pix_fmt = img->monochrome ?
93 return 0;
94 } else if (img->bit_depth == 12) {
95 avctx->pix_fmt = img->monochrome ?
98 return 0;
99 } else {
100 return AVERROR_INVALIDDATA;
101 }
102 case AOM_IMG_FMT_I422:
103 case AOM_IMG_FMT_I42216:
104 if (img->bit_depth == 8) {
107 return 0;
108 } else if (img->bit_depth == 10) {
111 return 0;
112 } else if (img->bit_depth == 12) {
115 return 0;
116 } else {
117 return AVERROR_INVALIDDATA;
118 }
119 case AOM_IMG_FMT_I444:
120 case AOM_IMG_FMT_I44416:
121 if (img->bit_depth == 8) {
122 avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
125 return 0;
126 } else if (img->bit_depth == 10) {
128 avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
131 return 0;
132 } else if (img->bit_depth == 12) {
133 avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
136 return 0;
137 } else {
138 return AVERROR_INVALIDDATA;
139 }
140
141 default:
142 return AVERROR_INVALIDDATA;
143 }
144}
145
147 const uint8_t *buffer, size_t buffer_size)
148{
149 FFITUTT35 itut35 = { 0 };
150 int ret;
151
152 if (buffer_size < 6)
153 return AVERROR(EINVAL);
154
155 ret = ff_itut_t35_parse_buffer(&itut35, buffer, buffer_size, 0);
156 if (ret <= 0)
157 return ret;
158
159 ret = ff_itut_t35_parse_payload_to_frame(&itut35, NULL, avctx, frame);
160 if (ret < 0)
161 return ret;
162
163 return 0;
164}
165
167 const struct aom_image *img)
168{
169 const size_t num_metadata = aom_img_num_metadata(img);
170 for (size_t i = 0; i < num_metadata; ++i) {
171 const aom_metadata_t *metadata = aom_img_get_metadata(img, i);
172 if (!metadata)
173 continue;
174
175 switch (metadata->type) {
176 case OBU_METADATA_TYPE_ITUT_T35: {
177 int res = decode_metadata_itu_t_t35(avctx, frame, metadata->payload, metadata->sz);
178 if (res < 0)
179 return res;
180 break;
181 }
182 default:
183 break;
184 }
185 }
186 return 0;
187}
188
189static int aom_decode(AVCodecContext *avctx, AVFrame *picture,
190 int *got_frame, AVPacket *avpkt)
191{
193 const void *iter = NULL;
194 struct aom_image *img;
195 int ret;
196
197 if (aom_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL) !=
198 AOM_CODEC_OK) {
199 const char *error = aom_codec_error(&ctx->decoder);
200 const char *detail = aom_codec_error_detail(&ctx->decoder);
201
202 av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error);
203 if (detail)
204 av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n",
205 detail);
206 return AVERROR_INVALIDDATA;
207 }
208
209 if ((img = aom_codec_get_frame(&ctx->decoder, &iter))) {
210 if (img->d_w > img->w || img->d_h > img->h) {
211 av_log(avctx, AV_LOG_ERROR, "Display dimensions %dx%d exceed storage %dx%d\n",
212 img->d_w, img->d_h, img->w, img->h);
213 return AVERROR_EXTERNAL;
214 }
215
216 if ((ret = set_pix_fmt(avctx, img)) < 0) {
217 av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n",
218 img->fmt, img->bit_depth);
219 return ret;
220 }
221
222 if ((int)img->d_w != avctx->width || (int)img->d_h != avctx->height) {
223 av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
224 avctx->width, avctx->height, img->d_w, img->d_h);
225 ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
226 if (ret < 0)
227 return ret;
228 }
229 if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
230 return ret;
231
232#ifdef AOM_CTRL_AOMD_GET_FRAME_FLAGS
233 {
234 aom_codec_frame_flags_t flags;
235 ret = aom_codec_control(&ctx->decoder, AOMD_GET_FRAME_FLAGS, &flags);
236 if (ret == AOM_CODEC_OK) {
237 if (flags & AOM_FRAME_IS_KEY)
238 picture->flags |= AV_FRAME_FLAG_KEY;
239 else
240 picture->flags &= ~AV_FRAME_FLAG_KEY;
241 if (flags & (AOM_FRAME_IS_KEY | AOM_FRAME_IS_INTRAONLY))
242 picture->pict_type = AV_PICTURE_TYPE_I;
243 else if (flags & AOM_FRAME_IS_SWITCH)
244 picture->pict_type = AV_PICTURE_TYPE_SP;
245 else
246 picture->pict_type = AV_PICTURE_TYPE_P;
247 }
248 }
249#endif
250
252 &picture->sample_aspect_ratio.den,
253 picture->height * img->r_w,
254 picture->width * img->r_h,
255 INT_MAX);
256 ff_set_sar(avctx, picture->sample_aspect_ratio);
257
258 if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img->bit_depth == 8)
260 else {
261 const uint8_t *planes[4] = { img->planes[0], img->planes[1], img->planes[2] };
262 const int stride[4] = { img->stride[0], img->stride[1], img->stride[2] };
263
264 av_image_copy(picture->data, picture->linesize, planes,
265 stride, avctx->pix_fmt, img->d_w, img->d_h);
266 }
267 ret = decode_metadata(avctx, picture, img);
268 if (ret < 0) {
269 av_log(avctx, AV_LOG_ERROR, "Failed to decode metadata\n");
270 return ret;
271 }
272 *got_frame = 1;
273 }
274 return avpkt->size;
275}
276
278{
280 aom_codec_destroy(&ctx->decoder);
281 return 0;
282}
283
285{
286 return aom_init(avctx, aom_codec_av1_dx());
287}
288
290 .p.name = "libaom-av1",
291 CODEC_LONG_NAME("libaom AV1"),
292 .p.type = AVMEDIA_TYPE_VIDEO,
293 .p.id = AV_CODEC_ID_AV1,
294 .priv_data_size = sizeof(AV1DecodeContext),
295 .init = av1_init,
296 .close = aom_free,
299 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
302 .p.wrapper_name = "libaom",
303};
const FFCodec ff_libaom_av1_decoder
Definition libaomdec.c:289
static AVFormatContext * ctx
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
Libavcodec external API header.
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
common internal and external API header
#define NULL
Definition coverity.c:32
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
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:106
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Definition utils.c:91
#define AV_PROFILE_AV1_HIGH
Definition defs.h:170
#define AV_PROFILE_AV1_MAIN
Definition defs.h:169
#define AV_PROFILE_AV1_PROFESSIONAL
Definition defs.h:171
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
Definition codec.h:112
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:687
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
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
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
void av_image_copy(uint8_t *const dst_data[4], const int dst_linesizes[4], const uint8_t *const 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
@ AV_PICTURE_TYPE_I
Intra.
Definition avutil.h:278
@ AV_PICTURE_TYPE_SP
Switching Predicted.
Definition avutil.h:283
@ AV_PICTURE_TYPE_P
Predicted.
Definition avutil.h:279
misc image utilities
int ff_itut_t35_parse_buffer(FFITUTT35 *const itut_t35, const uint8_t *buf, size_t buf_size, int flags)
Parse a raw ITU-T T35 buffer to get the country code, provider code, and set them plus the pointer an...
Definition itut35.c:34
int ff_itut_t35_parse_payload_to_frame(FFITUTT35 *const itut_t35, FFITUTT35Aux *const aux, AVCodecContext *const avctx, AVFrame *const frame)
Parse a pre-processed ITU-T T35 payload to fill a frame's side data.
Definition itut35.c:322
void ff_aom_image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
Definition libaom.c:27
AOM common functions.
static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
Definition libaomdec.c:68
static av_cold int av1_init(AVCodecContext *avctx)
Definition libaomdec.c:284
static int decode_metadata_itu_t_t35(AVCodecContext *avctx, AVFrame *frame, const uint8_t *buffer, size_t buffer_size)
Definition libaomdec.c:146
static av_cold int aom_free(AVCodecContext *avctx)
Definition libaomdec.c:277
static av_cold int aom_init(AVCodecContext *avctx, const struct aom_codec_iface *iface)
Definition libaomdec.c:46
static int decode_metadata(AVCodecContext *avctx, AVFrame *frame, const struct aom_image *img)
Definition libaomdec.c:166
static int aom_decode(AVCodecContext *avctx, AVFrame *picture, int *got_frame, AVPacket *avpkt)
Definition libaomdec.c:189
#define av_cold
Definition attributes.h:117
int av_cpu_count(void)
Definition cpu.c:228
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static const struct @257111027162314367033347246032313251342043035002 planes[]
#define FFMIN(a, b)
Definition macros.h:49
#define AV_PIX_FMT_YUV444P12
Definition pixfmt.h:552
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
AVColorRange
Visual content value range.
Definition pixfmt.h:748
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_YUV420P12
Definition pixfmt.h:549
#define AV_PIX_FMT_YUV422P12
Definition pixfmt.h:550
#define AV_PIX_FMT_GBRP10
Definition pixfmt.h:564
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
#define AV_PIX_FMT_GRAY12
Definition pixfmt.h:526
#define AV_PIX_FMT_GBRP12
Definition pixfmt.h:565
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition pixfmt.h:165
#define AV_PIX_FMT_GRAY10
Definition pixfmt.h:525
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition pixfmt.h:642
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition pixfmt.h:672
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:548
AVColorSpace
YUV colorspace type.
Definition pixfmt.h:706
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition pixfmt.h:707
const AVProfile ff_av1_profiles[]
Definition profiles.c:163
struct aom_codec_ctx decoder
Definition libaomdec.c:43
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition avcodec.h:681
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
int profile
profile
Definition avcodec.h:1636
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int width
Definition frame.h:544
int height
Definition frame.h:544
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:716
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition frame.h:569
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:517
enum AVPictureType pict_type
Picture type of the frame.
Definition frame.h:564
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
#define stride
#define av_log(a,...)
static void error(const char *err)
static char buffer[20]
Definition seek.c:32
#define img