History

avcodec: add AV1 hardware accelerated decoder

This AV1 decoder is currently only used for hardware accelerated decoding. It can be extended into a native decoder in the future, so set its name to "av1" and temporarily give it the lowest priority in the codec list.

Fei Wang committed 6 years ago

Commit 47be5a51 parent bab3c3210 files · +938 −6Browse files

Unified · Split

10 files
  1. Changelog +1 −0
  2. configure +1 −0
  3. libavcodec/Makefile +1 −0
  4. libavcodec/allcodecs.c +2 −0
  5. libavcodec/av1dec.c +852 −0
  6. libavcodec/av1dec.h +75 −0
  7. libavcodec/version.h +1 −1
  8. tests/ref/fate/av1-annexb-demux +1 −1
  9. tests/ref/lavf-fate/av1.mkv +2 −2
  10. tests/ref/lavf-fate/av1.mp4 +2 −2
Changelog+1−0
@@ -22,6 +22,7 @@ version <next>: · 21 unmodified lines
2222 - MODS demuxer
2323 - PhotoCD decoder
2424 - MCA demuxer
25+- AV1 decoder (Hardware acceleration used only)
2526
2627
2728 version 4.3:
configure+1−0
@@ -2685,6 +2685,7 @@ atrac3al_decoder_select="mdct" · 2684 unmodified lines
26852685 atrac3p_decoder_select="mdct sinewin"
26862686 atrac3pal_decoder_select="mdct sinewin"
26872687 atrac9_decoder_select="mdct"
2688+av1_decoder_select="cbs_av1"
26882689 avrn_decoder_select="exif jpegtables"
26892690 bink_decoder_select="blockdsp hpeldsp"
26902691 binkaudio_dct_decoder_select="mdct rdft dct sinewin wma_freqs"
libavcodec/Makefile+1−0
@@ -228,6 +228,7 @@ OBJS-$(CONFIG_ATRAC3PAL_DECODER) += atrac3plusdec.o atrac3plus.o \ · 227 unmodified lines
228228 OBJS-$(CONFIG_ATRAC9_DECODER) += atrac9dec.o
229229 OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
230230 OBJS-$(CONFIG_AURA2_DECODER) += aura.o
231+OBJS-$(CONFIG_AV1_DECODER) += av1dec.o
231232 OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o mjpegdec.o
232233 OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o
233234 OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o
libavcodec/allcodecs.c+2−0
@@ -768,6 +768,8 @@ extern AVCodec ff_aac_mf_encoder; · 767 unmodified lines
768768 extern AVCodec ff_ac3_mf_encoder;
769769 extern AVCodec ff_h263_v4l2m2m_encoder;
770770 extern AVCodec ff_libaom_av1_decoder;
771+/* hwaccel hooks only, so prefer external decoders */
772+extern AVCodec ff_av1_decoder;
771773 extern AVCodec ff_libopenh264_encoder;
772774 extern AVCodec ff_libopenh264_decoder;
773775 extern AVCodec ff_h264_amf_encoder;
libavcodec/av1dec.c+852−0
@@ -0,0 +1,852 @@
1+/*
2+ * AV1 video decoder
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+#include "libavutil/pixdesc.h"
22+#include "avcodec.h"
23+#include "av1dec.h"
24+#include "get_bits.h"
25+#include "hwconfig.h"
26+#include "internal.h"
27+#include "profiles.h"
28+
29+static void setup_past_independence(AV1Frame *f)
30+{
31+ f->loop_filter_delta_enabled = 1;
32+
33+ f->loop_filter_ref_deltas[AV1_REF_FRAME_INTRA] = 1;
34+ f->loop_filter_ref_deltas[AV1_REF_FRAME_LAST] = 0;
35+ f->loop_filter_ref_deltas[AV1_REF_FRAME_LAST2] = 0;
36+ f->loop_filter_ref_deltas[AV1_REF_FRAME_LAST3] = 0;
37+ f->loop_filter_ref_deltas[AV1_REF_FRAME_GOLDEN] = -1;
38+ f->loop_filter_ref_deltas[AV1_REF_FRAME_BWDREF] = 0;
39+ f->loop_filter_ref_deltas[AV1_REF_FRAME_ALTREF2] = -1;
40+ f->loop_filter_ref_deltas[AV1_REF_FRAME_ALTREF] = -1;
41+
42+ f->loop_filter_mode_deltas[0] = 0;
43+ f->loop_filter_mode_deltas[1] = 0;
44+}
45+
46+static void load_previous_and_update(AV1DecContext *s)
47+{
48+ uint8_t primary_frame, prev_frame;
49+
50+ primary_frame = s->raw_frame_header->primary_ref_frame;
51+ prev_frame = s->raw_frame_header->ref_frame_idx[primary_frame];
52+ memcpy(s->cur_frame.loop_filter_ref_deltas,
53+ s->ref[prev_frame].loop_filter_ref_deltas,
54+ AV1_NUM_REF_FRAMES * sizeof(int8_t));
55+ memcpy(s->cur_frame.loop_filter_mode_deltas,
56+ s->ref[prev_frame].loop_filter_mode_deltas,
57+ 2 * sizeof(int8_t));
58+
59+ if (s->raw_frame_header->loop_filter_delta_update) {
60+ for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) {
61+ if (s->raw_frame_header->update_ref_delta[i])
62+ s->cur_frame.loop_filter_ref_deltas[i] =
63+ s->raw_frame_header->loop_filter_ref_deltas[i];
64+ }
65+
66+ for (int i = 0; i < 2; i++) {
67+ if (s->raw_frame_header->update_mode_delta[i])
68+ s->cur_frame.loop_filter_mode_deltas[i] =
69+ s->raw_frame_header->loop_filter_mode_deltas[i];
70+ }
71+ }
72+
73+ s->cur_frame.loop_filter_delta_enabled =
74+ s->raw_frame_header->loop_filter_delta_enabled;
75+}
76+
77+static uint32_t inverse_recenter(int r, uint32_t v)
78+{
79+ if (v > 2 * r)
80+ return v;
81+ else if (v & 1)
82+ return r - ((v + 1) >> 1);
83+ else
84+ return r + (v >> 1);
85+}
86+
87+static uint32_t decode_unsigned_subexp_with_ref(uint32_t sub_exp,
88+ int mx, int r)
89+{
90+ if ((r << 1) <= mx) {
91+ return inverse_recenter(r, sub_exp);
92+ } else {
93+ return mx - 1 - inverse_recenter(mx - 1 - r, sub_exp);
94+ }
95+}
96+
97+static int32_t decode_signed_subexp_with_ref(uint32_t sub_exp, int low,
98+ int high, int r)
99+{
100+ int32_t x = decode_unsigned_subexp_with_ref(sub_exp, high - low, r - low);
101+ return x + low;
102+}
103+
104+static void read_global_param(AV1DecContext *s, int type, int ref, int idx)
105+{
106+ uint8_t primary_frame, prev_frame;
107+ uint32_t abs_bits, prec_bits, round, prec_diff, sub, mx;
108+ int32_t r;
109+
110+ primary_frame = s->raw_frame_header->primary_ref_frame;
111+ prev_frame = s->raw_frame_header->ref_frame_idx[primary_frame];
112+ abs_bits = AV1_GM_ABS_ALPHA_BITS;
113+ prec_bits = AV1_GM_ALPHA_PREC_BITS;
114+
115+ if (idx < 2) {
116+ if (type == AV1_WARP_MODEL_TRANSLATION) {
117+ abs_bits = AV1_GM_ABS_TRANS_ONLY_BITS -
118+ !s->raw_frame_header->allow_high_precision_mv;
119+ prec_bits = AV1_GM_TRANS_ONLY_PREC_BITS -
120+ !s->raw_frame_header->allow_high_precision_mv;
121+ } else {
122+ abs_bits = AV1_GM_ABS_TRANS_BITS;
123+ prec_bits = AV1_GM_TRANS_PREC_BITS;
124+ }
125+ }
126+ round = (idx % 3) == 2 ? (1 << AV1_WARPEDMODEL_PREC_BITS) : 0;
127+ prec_diff = AV1_WARPEDMODEL_PREC_BITS - prec_bits;
128+ sub = (idx % 3) == 2 ? (1 << prec_bits) : 0;
129+ mx = 1 << abs_bits;
130+ r = (s->ref[prev_frame].gm_params[ref][idx] >> prec_diff) - sub;
131+
132+ s->cur_frame.gm_params[ref][idx] =
133+ (decode_signed_subexp_with_ref(s->raw_frame_header->gm_params[ref][idx],
134+ -mx, mx + 1, r) << prec_diff) + round;
135+}
136+
137+/**
138+* update gm type/params, since cbs already implemented part of this funcation,
139+* so we don't need to full implement spec.
140+*/
141+static void global_motion_params(AV1DecContext *s)
142+{
143+ const AV1RawFrameHeader *header = s->raw_frame_header;
144+ int type, ref;
145+
146+ for (ref = AV1_REF_FRAME_LAST; ref <= AV1_REF_FRAME_ALTREF; ref++) {
147+ s->cur_frame.gm_type[ref] = AV1_WARP_MODEL_IDENTITY;
148+ for (int i = 0; i < 6; i++)
149+ s->cur_frame.gm_params[ref][i] = (i % 3 == 2) ?
150+ 1 << AV1_WARPEDMODEL_PREC_BITS : 0;
151+ }
152+ if (header->frame_type == AV1_FRAME_KEY ||
153+ header->frame_type == AV1_FRAME_INTRA_ONLY)
154+ return;
155+
156+ for (ref = AV1_REF_FRAME_LAST; ref <= AV1_REF_FRAME_ALTREF; ref++) {
157+ if (header->is_global[ref]) {
158+ if (header->is_rot_zoom[ref]) {
159+ type = AV1_WARP_MODEL_ROTZOOM;
160+ } else {
161+ type = header->is_translation[ref] ? AV1_WARP_MODEL_TRANSLATION
162+ : AV1_WARP_MODEL_AFFINE;
163+ }
164+ } else {
165+ type = AV1_WARP_MODEL_IDENTITY;
166+ }
167+ s->cur_frame.gm_type[ref] = type;
168+
169+ if (type >= AV1_WARP_MODEL_ROTZOOM) {
170+ read_global_param(s, type, ref, 2);
171+ read_global_param(s, type, ref, 3);
172+ if (type == AV1_WARP_MODEL_AFFINE) {
173+ read_global_param(s, type, ref, 4);
174+ read_global_param(s, type, ref, 5);
175+ } else {
176+ s->cur_frame.gm_params[ref][4] = -s->cur_frame.gm_params[ref][3];
177+ s->cur_frame.gm_params[ref][5] = s->cur_frame.gm_params[ref][2];
178+ }
179+ }
180+ if (type >= AV1_WARP_MODEL_TRANSLATION) {
181+ read_global_param(s, type, ref, 0);
182+ read_global_param(s, type, ref, 1);
183+ }
184+ }
185+}
186+
187+static int init_tile_data(AV1DecContext *s)
188+
189+{
190+ int cur_tile_num =
191+ s->raw_frame_header->tile_cols * s->raw_frame_header->tile_rows;
192+ if (s->tile_num < cur_tile_num) {
193+ int ret = av_reallocp_array(&s->tile_group_info, cur_tile_num,
194+ sizeof(TileGroupInfo));
195+ if (ret < 0) {
196+ s->tile_num = 0;
197+ return ret;
198+ }
199+ }
200+ s->tile_num = cur_tile_num;
201+
202+ return 0;
203+}
204+
205+static int get_tiles_info(AVCodecContext *avctx, const AV1RawTileGroup *tile_group)
206+{
207+ AV1DecContext *s = avctx->priv_data;
208+ GetBitContext gb;
209+ uint16_t tile_num, tile_row, tile_col;
210+ uint32_t size = 0, size_bytes = 0, offset = 0;
211+ int ret;
212+
213+ if ((ret = init_get_bits8(&gb,
214+ tile_group->tile_data.data,
215+ tile_group->tile_data.data_size)) < 0) {
216+ av_log(avctx, AV_LOG_ERROR, "Failed to initialize bitstream reader.\n");
217+ return ret;
218+ }
219+
220+ s->tg_start = tile_group->tg_start;
221+ s->tg_end = tile_group->tg_end;
222+
223+ for (tile_num = tile_group->tg_start; tile_num <= tile_group->tg_end; tile_num++) {
224+ tile_row = tile_num / s->raw_frame_header->tile_cols;
225+ tile_col = tile_num % s->raw_frame_header->tile_cols;
226+
227+ if (tile_num == tile_group->tg_end) {
228+ s->tile_group_info[tile_num].tile_size = get_bits_left(&gb) / 8;
229+ s->tile_group_info[tile_num].tile_offset = offset;
230+ s->tile_group_info[tile_num].tile_row = tile_row;
231+ s->tile_group_info[tile_num].tile_column = tile_col;
232+ return 0;
233+ }
234+ size_bytes = s->raw_frame_header->tile_size_bytes_minus1 + 1;
235+ size = get_bits_le(&gb, size_bytes * 8) + 1;
236+ skip_bits(&gb, size * 8);
237+
238+ offset += size_bytes;
239+
240+ s->tile_group_info[tile_num].tile_size = size;
241+ s->tile_group_info[tile_num].tile_offset = offset;
242+ s->tile_group_info[tile_num].tile_row = tile_row;
243+ s->tile_group_info[tile_num].tile_column = tile_col;
244+
245+ offset += size;
246+ }
247+
248+ return 0;
249+
250+}
251+
252+static int get_pixel_format(AVCodecContext *avctx)
253+{
254+ AV1DecContext *s = avctx->priv_data;
255+ const AV1RawSequenceHeader *seq = s->raw_seq;
256+ uint8_t bit_depth;
257+ int ret;
258+ enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
259+#define HWACCEL_MAX (0)
260+ enum AVPixelFormat pix_fmts[HWACCEL_MAX + 1], *fmtp = pix_fmts;
261+
262+ /**
263+ * check if the HW accel is inited correctly. If not, return un-implemented.
264+ * Since now the av1 decoder doesn't support native decode, if it will be
265+ * implemented in the future, need remove this check.
266+ */
267+ if (!avctx->hwaccel) {
268+ av_log(avctx, AV_LOG_ERROR, "Your platform doesn't suppport"
269+ " hardware accelerated AV1 decoding.\n");
270+ return AVERROR(ENOSYS);
271+ }
272+
273+ if (seq->seq_profile == 2 && seq->color_config.high_bitdepth)
274+ bit_depth = seq->color_config.twelve_bit ? 12 : 10;
275+ else if (seq->seq_profile <= 2)
276+ bit_depth = seq->color_config.high_bitdepth ? 10 : 8;
277+ else {
278+ av_log(avctx, AV_LOG_ERROR,
279+ "Unknown AV1 profile %d.\n", seq->seq_profile);
280+ return -1;
281+ }
282+
283+ if (!seq->color_config.mono_chrome) {
284+ // 4:4:4 x:0 y:0, 4:2:2 x:1 y:0, 4:2:0 x:1 y:1
285+ if (seq->color_config.subsampling_x == 0 &&
286+ seq->color_config.subsampling_y == 0) {
287+ if (bit_depth == 8)
288+ pix_fmt = AV_PIX_FMT_YUV444P;
289+ else if (bit_depth == 10)
290+ pix_fmt = AV_PIX_FMT_YUV444P10;
291+ else if (bit_depth == 12)
292+ pix_fmt = AV_PIX_FMT_YUV444P12;
293+ else
294+ av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n");
295+ } else if (seq->color_config.subsampling_x == 1 &&
296+ seq->color_config.subsampling_y == 0) {
297+ if (bit_depth == 8)
298+ pix_fmt = AV_PIX_FMT_YUV422P;
299+ else if (bit_depth == 10)
300+ pix_fmt = AV_PIX_FMT_YUV422P10;
301+ else if (bit_depth == 12)
302+ pix_fmt = AV_PIX_FMT_YUV422P12;
303+ else
304+ av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n");
305+ } else if (seq->color_config.subsampling_x == 1 &&
306+ seq->color_config.subsampling_y == 1) {
307+ if (bit_depth == 8)
308+ pix_fmt = AV_PIX_FMT_YUV420P;
309+ else if (bit_depth == 10)
310+ pix_fmt = AV_PIX_FMT_YUV420P10;
311+ else if (bit_depth == 12)
312+ pix_fmt = AV_PIX_FMT_YUV420P12;
313+ else
314+ av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n");
315+ }
316+ } else {
317+ if (seq->color_config.subsampling_x == 1 &&
318+ seq->color_config.subsampling_y == 1)
319+ pix_fmt = AV_PIX_FMT_YUV440P;
320+ else
321+ av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n");
322+ }
323+
324+ av_log(avctx, AV_LOG_DEBUG, "AV1 decode get format: %s.\n",
325+ av_get_pix_fmt_name(pix_fmt));
326+
327+ if (pix_fmt == AV_PIX_FMT_NONE)
328+ return -1;
329+ s->pix_fmt = pix_fmt;
330+
331+ *fmtp = AV_PIX_FMT_NONE;
332+ avctx->sw_pix_fmt = s->pix_fmt;
333+ ret = ff_thread_get_format(avctx, pix_fmts);
334+ if (ret < 0)
335+ return ret;
336+
337+ avctx->pix_fmt = ret;
338+
339+ return 0;
340+}
341+
342+static void av1_frame_unref(AVCodecContext *avctx, AV1Frame *f)
343+{
344+ ff_thread_release_buffer(avctx, &f->tf);
345+ av_buffer_unref(&f->hwaccel_priv_buf);
346+ f->hwaccel_picture_private = NULL;
347+}
348+
349+static int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *src)
350+{
351+ int ret;
352+
353+ ret = ff_thread_ref_frame(&dst->tf, &src->tf);
354+ if (ret < 0)
355+ return ret;
356+
357+ if (src->hwaccel_picture_private) {
358+ dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
359+ if (!dst->hwaccel_priv_buf)
360+ goto fail;
361+ dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
362+ }
363+
364+ dst->loop_filter_delta_enabled = src->loop_filter_delta_enabled;
365+ memcpy(dst->loop_filter_ref_deltas,
366+ src->loop_filter_ref_deltas,
367+ AV1_NUM_REF_FRAMES * sizeof(int8_t));
368+ memcpy(dst->loop_filter_mode_deltas,
369+ src->loop_filter_mode_deltas,
370+ 2 * sizeof(int8_t));
371+ memcpy(dst->gm_type,
372+ src->gm_type,
373+ AV1_NUM_REF_FRAMES * sizeof(uint8_t));
374+ memcpy(dst->gm_params,
375+ src->gm_params,
376+ AV1_NUM_REF_FRAMES * 6 * sizeof(int32_t));
377+
378+ return 0;
379+
380+fail:
381+ av1_frame_unref(avctx, dst);
382+ return AVERROR(ENOMEM);
383+}
384+
385+static av_cold int av1_decode_free(AVCodecContext *avctx)
386+{
387+ AV1DecContext *s = avctx->priv_data;
388+
389+ for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
390+ if (s->ref[i].tf.f->buf[0])
391+ av1_frame_unref(avctx, &s->ref[i]);
392+ av_frame_free(&s->ref[i].tf.f);
393+ }
394+ if (s->cur_frame.tf.f->buf[0])
395+ av1_frame_unref(avctx, &s->cur_frame);
396+ av_frame_free(&s->cur_frame.tf.f);
397+
398+ av_buffer_unref(&s->seq_ref);
399+ av_buffer_unref(&s->header_ref);
400+ av_freep(&s->tile_group_info);
401+
402+ ff_cbs_fragment_free(&s->current_obu);
403+ ff_cbs_close(&s->cbc);
404+
405+ return 0;
406+}
407+
408+static int set_context_with_sequence(AVCodecContext *avctx,
409+ const AV1RawSequenceHeader *seq)
410+{
411+ avctx->profile = seq->seq_profile;
412+ avctx->level = seq->seq_level_idx[0];
413+
414+ avctx->color_range =
415+ seq->color_config.color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
416+ avctx->color_primaries = seq->color_config.color_primaries;
417+ avctx->colorspace = seq->color_config.color_primaries;
418+ avctx->color_trc = seq->color_config.transfer_characteristics;
419+
420+ if (seq->timing_info.num_units_in_display_tick &&
421+ seq->timing_info.time_scale) {
422+ av_reduce(&avctx->framerate.den, &avctx->framerate.num,
423+ seq->timing_info.num_units_in_display_tick,
424+ seq->timing_info.time_scale,
425+ INT_MAX);
426+ if (seq->timing_info.equal_picture_interval)
427+ avctx->ticks_per_frame = seq->timing_info.num_ticks_per_picture_minus_1 + 1;
428+ }
429+
430+ return 0;
431+}
432+
433+static int update_context_with_frame_header(AVCodecContext *avctx,
434+ const AV1RawFrameHeader *header)
435+{
436+ AVRational aspect_ratio;
437+ int width = header->frame_width_minus_1 + 1;
438+ int height = header->frame_height_minus_1 + 1;
439+ int r_width = header->render_width_minus_1 + 1;
440+ int r_height = header->render_height_minus_1 + 1;
441+ int ret;
442+
443+ if (avctx->width != width || avctx->height != height) {
444+ ret = ff_set_dimensions(avctx, width, height);
445+ if (ret < 0)
446+ return ret;
447+ }
448+
449+ av_reduce(&aspect_ratio.num, &aspect_ratio.den,
450+ (int64_t)height * r_width,
451+ (int64_t)width * r_height,
452+ INT_MAX);
453+
454+ if (avctx->sample_aspect_ratio.num != aspect_ratio.num ||
455+ avctx->sample_aspect_ratio.den != aspect_ratio.den) {
456+ ret = ff_set_sar(avctx, aspect_ratio);
457+ if (ret < 0)
458+ return ret;
459+ }
460+
461+ return 0;
462+}
463+
464+static av_cold int av1_decode_init(AVCodecContext *avctx)
465+{
466+ AV1DecContext *s = avctx->priv_data;
467+ AV1RawSequenceHeader *seq;
468+ int ret;
469+
470+ s->avctx = avctx;
471+ s->pix_fmt = AV_PIX_FMT_NONE;
472+
473+ for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
474+ s->ref[i].tf.f = av_frame_alloc();
475+ if (!s->ref[i].tf.f) {
476+ av1_decode_free(avctx);
477+ av_log(avctx, AV_LOG_ERROR,
478+ "Failed to allocate reference frame buffer %d.\n", i);
479+ return AVERROR(ENOMEM);
480+ }
481+ }
482+
483+ s->cur_frame.tf.f = av_frame_alloc();
484+ if (!s->cur_frame.tf.f) {
485+ av1_decode_free(avctx);
486+ av_log(avctx, AV_LOG_ERROR,
487+ "Failed to allocate current frame buffer.\n");
488+ return AVERROR(ENOMEM);
489+ }
490+
491+ ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_AV1, avctx);
492+ if (ret < 0)
493+ return ret;
494+
495+ if (avctx->extradata && avctx->extradata_size) {
496+ ret = ff_cbs_read(s->cbc, &s->current_obu, avctx->extradata,
497+ avctx->extradata_size);
498+ if (ret < 0) {
499+ av_log(avctx, AV_LOG_WARNING, "Failed to read extradata.\n");
500+ goto end;
501+ }
502+
503+ seq = ((CodedBitstreamAV1Context *)(s->cbc->priv_data))->sequence_header;
504+ if (!seq) {
505+ av_log(avctx, AV_LOG_WARNING, "No sequence header available.\n");
506+ goto end;
507+ }
508+
509+ ret = set_context_with_sequence(avctx, seq);
510+ if (ret < 0) {
511+ av_log(avctx, AV_LOG_WARNING, "Failed to set decoder context.\n");
512+ goto end;
513+ }
514+
515+ end:
516+ ff_cbs_fragment_reset(&s->current_obu);
517+ }
518+
519+ return ret;
520+}
521+
522+static int av1_frame_alloc(AVCodecContext *avctx, AV1Frame *f)
523+{
524+ AV1DecContext *s = avctx->priv_data;
525+ AV1RawFrameHeader *header= s->raw_frame_header;
526+ AVFrame *frame;
527+ int ret;
528+
529+ ret = update_context_with_frame_header(avctx, header);
530+ if (ret < 0) {
531+ av_log(avctx, AV_LOG_ERROR, "Failed to update context with frame header\n");
532+ return ret;
533+ }
534+
535+ if ((ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0)
536+ return ret;
537+
538+ frame = f->tf.f;
539+ frame->key_frame = header->frame_type == AV1_FRAME_KEY;
540+
541+ switch (header->frame_type) {
542+ case AV1_FRAME_KEY:
543+ case AV1_FRAME_INTRA_ONLY:
544+ frame->pict_type = AV_PICTURE_TYPE_I;
545+ break;
546+ case AV1_FRAME_INTER:
547+ frame->pict_type = AV_PICTURE_TYPE_P;
548+ break;
549+ case AV1_FRAME_SWITCH:
550+ frame->pict_type = AV_PICTURE_TYPE_SP;
551+ break;
552+ }
553+
554+ if (avctx->hwaccel) {
555+ const AVHWAccel *hwaccel = avctx->hwaccel;
556+ if (hwaccel->frame_priv_data_size) {
557+ f->hwaccel_priv_buf =
558+ av_buffer_allocz(hwaccel->frame_priv_data_size);
559+ if (!f->hwaccel_priv_buf)
560+ goto fail;
561+ f->hwaccel_picture_private = f->hwaccel_priv_buf->data;
562+ }
563+ }
564+ return 0;
565+
566+fail:
567+ av1_frame_unref(avctx, f);
568+ return AVERROR(ENOMEM);
569+}
570+
571+static int set_output_frame(AVCodecContext *avctx, AVFrame *frame,
572+ const AVPacket *pkt, int *got_frame)
573+{
574+ AV1DecContext *s = avctx->priv_data;
575+ const AV1RawFrameHeader *header = s->raw_frame_header;
576+ const AVFrame *srcframe;
577+ int ret;
578+
579+ if (header->show_existing_frame)
580+ srcframe = s->ref[header->frame_to_show_map_idx].tf.f;
581+ else
582+ srcframe = s->cur_frame.tf.f;
583+
584+ ret = av_frame_ref(frame, srcframe);
585+ if (ret < 0)
586+ return ret;
587+
588+ frame->pts = pkt->pts;
589+ frame->pkt_dts = pkt->dts;
590+ frame->pkt_size = pkt->size;
591+
592+ *got_frame = 1;
593+
594+ return 0;
595+}
596+
597+static int update_reference_list(AVCodecContext *avctx)
598+{
599+ AV1DecContext *s = avctx->priv_data;
600+ const AV1RawFrameHeader *header = s->raw_frame_header;
601+ int ret;
602+
603+ for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) {
604+ if (header->refresh_frame_flags & (1 << i)) {
605+ if (s->ref[i].tf.f->buf[0])
606+ av1_frame_unref(avctx, &s->ref[i]);
607+ if ((ret = av1_frame_ref(avctx, &s->ref[i], &s->cur_frame)) < 0) {
608+ av_log(avctx, AV_LOG_ERROR,
609+ "Failed to update frame %d in reference list\n", i);
610+ return ret;
611+ }
612+ }
613+ }
614+ return 0;
615+}
616+
617+static int get_current_frame(AVCodecContext *avctx)
618+{
619+ AV1DecContext *s = avctx->priv_data;
620+ int ret;
621+
622+ if (s->cur_frame.tf.f->buf[0])
623+ av1_frame_unref(avctx, &s->cur_frame);
624+
625+ ret = av1_frame_alloc(avctx, &s->cur_frame);
626+ if (ret < 0) {
627+ av_log(avctx, AV_LOG_ERROR,
628+ "Failed to allocate space for current frame.\n");
629+ return ret;
630+ }
631+
632+ ret = init_tile_data(s);
633+ if (ret < 0) {
634+ av_log(avctx, AV_LOG_ERROR, "Failed to init tile data.\n");
635+ return ret;
636+ }
637+
638+ if (s->raw_frame_header->primary_ref_frame == AV1_PRIMARY_REF_NONE)
639+ setup_past_independence(&s->cur_frame);
640+ else
641+ load_previous_and_update(s);
642+
643+ global_motion_params(s);
644+
645+ return ret;
646+}
647+
648+static int av1_decode_frame(AVCodecContext *avctx, void *frame,
649+ int *got_frame, AVPacket *pkt)
650+{
651+ AV1DecContext *s = avctx->priv_data;
652+ AV1RawTileGroup *raw_tile_group = NULL;
653+ int ret;
654+
655+ ret = ff_cbs_read_packet(s->cbc, &s->current_obu, pkt);
656+ if (ret < 0) {
657+ av_log(avctx, AV_LOG_ERROR, "Failed to read packet.\n");
658+ goto end;
659+ }
660+ av_log(avctx, AV_LOG_DEBUG, "Total obu for this frame:%d.\n",
661+ s->current_obu.nb_units);
662+
663+ for (int i = 0; i < s->current_obu.nb_units; i++) {
664+ CodedBitstreamUnit *unit = &s->current_obu.units[i];
665+ AV1RawOBU *obu = unit->content;
666+ av_log(avctx, AV_LOG_DEBUG, "Obu idx:%d, obu type:%d.\n", i, unit->type);
667+
668+ switch (unit->type) {
669+ case AV1_OBU_SEQUENCE_HEADER:
670+ av_buffer_unref(&s->seq_ref);
671+ s->seq_ref = av_buffer_ref(unit->content_ref);
672+ if (!s->seq_ref) {
673+ ret = AVERROR(ENOMEM);
674+ goto end;
675+ }
676+
677+ s->raw_seq = &obu->obu.sequence_header;
678+
679+ ret = set_context_with_sequence(avctx, s->raw_seq);
680+ if (ret < 0) {
681+ av_log(avctx, AV_LOG_ERROR, "Failed to set context.\n");
682+ goto end;
683+ }
684+
685+ if (s->pix_fmt == AV_PIX_FMT_NONE) {
686+ ret = get_pixel_format(avctx);
687+ if (ret < 0) {
688+ av_log(avctx, AV_LOG_ERROR,
689+ "Failed to get pixel format.\n");
690+ goto end;
691+ }
692+ }
693+
694+ if (avctx->hwaccel && avctx->hwaccel->decode_params) {
695+ ret = avctx->hwaccel->decode_params(avctx, unit->type, unit->data,
696+ unit->data_size);
697+ if (ret < 0) {
698+ av_log(avctx, AV_LOG_ERROR, "HW accel decode params fail.\n");
699+ goto end;
700+ }
701+ }
702+ break;
703+ case AV1_OBU_REDUNDANT_FRAME_HEADER:
704+ if (s->raw_frame_header)
705+ break;
706+ // fall-through
707+ case AV1_OBU_FRAME:
708+ case AV1_OBU_FRAME_HEADER:
709+ if (!s->seq_ref) {
710+ av_log(avctx, AV_LOG_ERROR, "Missing Sequence Header.\n");
711+ ret = AVERROR_INVALIDDATA;
712+ goto end;
713+ }
714+
715+ av_buffer_unref(&s->header_ref);
716+ s->header_ref = av_buffer_ref(unit->content_ref);
717+ if (!s->header_ref) {
718+ ret = AVERROR(ENOMEM);
719+ goto end;
720+ }
721+
722+ if (unit->type == AV1_OBU_FRAME)
723+ s->raw_frame_header = &obu->obu.frame.header;
724+ else
725+ s->raw_frame_header = &obu->obu.frame_header;
726+
727+ if (s->raw_frame_header->show_existing_frame) {
728+ ret = set_output_frame(avctx, frame, pkt, got_frame);
729+ if (ret < 0)
730+ av_log(avctx, AV_LOG_ERROR, "Set output frame error.\n");
731+
732+ s->raw_frame_header = NULL;
733+
734+ goto end;
735+ }
736+
737+ ret = get_current_frame(avctx);
738+ if (ret < 0) {
739+ av_log(avctx, AV_LOG_ERROR, "Get current frame error\n");
740+ goto end;
741+ }
742+
743+ if (avctx->hwaccel) {
744+ ret = avctx->hwaccel->start_frame(avctx, unit->data,
745+ unit->data_size);
746+ if (ret < 0) {
747+ av_log(avctx, AV_LOG_ERROR, "HW accel start frame fail.\n");
748+ goto end;
749+ }
750+ }
751+ if (unit->type != AV1_OBU_FRAME)
752+ break;
753+ // fall-through
754+ case AV1_OBU_TILE_GROUP:
755+ if (!s->raw_frame_header) {
756+ av_log(avctx, AV_LOG_ERROR, "Missing Frame Header.\n");
757+ ret = AVERROR_INVALIDDATA;
758+ goto end;
759+ }
760+
761+ if (unit->type == AV1_OBU_FRAME)
762+ raw_tile_group = &obu->obu.frame.tile_group;
763+ else
764+ raw_tile_group = &obu->obu.tile_group;
765+
766+ get_tiles_info(avctx, raw_tile_group);
767+
768+ if (avctx->hwaccel) {
769+ ret = avctx->hwaccel->decode_slice(avctx,
770+ raw_tile_group->tile_data.data,
771+ raw_tile_group->tile_data.data_size);
772+ if (ret < 0) {
773+ av_log(avctx, AV_LOG_ERROR,
774+ "HW accel decode slice fail.\n");
775+ goto end;
776+ }
777+ }
778+ break;
779+ case AV1_OBU_TILE_LIST:
780+ case AV1_OBU_TEMPORAL_DELIMITER:
781+ case AV1_OBU_PADDING:
782+ case AV1_OBU_METADATA:
783+ break;
784+ default:
785+ av_log(avctx, AV_LOG_DEBUG,
786+ "Unknown obu type: %d (%"SIZE_SPECIFIER" bits).\n",
787+ unit->type, unit->data_size);
788+ }
789+
790+ if (raw_tile_group && (s->tile_num == raw_tile_group->tg_end + 1)) {
791+ if (avctx->hwaccel) {
792+ ret = avctx->hwaccel->end_frame(avctx);
793+ if (ret < 0) {
794+ av_log(avctx, AV_LOG_ERROR, "HW accel end frame fail.\n");
795+ goto end;
796+ }
797+ }
798+
799+ ret = update_reference_list(avctx);
800+ if (ret < 0) {
801+ av_log(avctx, AV_LOG_ERROR, "Failed to update reference list.\n");
802+ goto end;
803+ }
804+
805+ if (s->raw_frame_header->show_frame) {
806+ ret = set_output_frame(avctx, frame, pkt, got_frame);
807+ if (ret < 0) {
808+ av_log(avctx, AV_LOG_ERROR, "Set output frame error\n");
809+ goto end;
810+ }
811+ }
812+ raw_tile_group = NULL;
813+ s->raw_frame_header = NULL;
814+ }
815+ }
816+
817+end:
818+ ff_cbs_fragment_reset(&s->current_obu);
819+ return ret;
820+}
821+
822+static void av1_decode_flush(AVCodecContext *avctx)
823+{
824+ AV1DecContext *s = avctx->priv_data;
825+
826+ for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++)
827+ av1_frame_unref(avctx, &s->ref[i]);
828+
829+ av1_frame_unref(avctx, &s->cur_frame);
830+ s->raw_frame_header = NULL;
831+ s->raw_seq = NULL;
832+}
833+
834+AVCodec ff_av1_decoder = {
835+ .name = "av1",
836+ .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"),
837+ .type = AVMEDIA_TYPE_VIDEO,
838+ .id = AV_CODEC_ID_AV1,
839+ .priv_data_size = sizeof(AV1DecContext),
840+ .init = av1_decode_init,
841+ .close = av1_decode_free,
842+ .decode = av1_decode_frame,
843+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING,
844+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
845+ FF_CODEC_CAP_INIT_CLEANUP |
846+ FF_CODEC_CAP_SETS_PKT_DTS,
847+ .flush = av1_decode_flush,
848+ .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
849+ .hw_configs = (const AVCodecHWConfigInternal * []) {
850+ NULL
851+ },
852+};
libavcodec/av1dec.h+75−0
@@ -0,0 +1,75 @@
1+/*
2+ * AV1 video decoder
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+#ifndef AVCODEC_AV1DEC_H
22+#define AVCODEC_AV1DEC_H
23+
24+#include <stdint.h>
25+
26+#include "libavutil/buffer.h"
27+#include "libavutil/pixfmt.h"
28+#include "avcodec.h"
29+#include "cbs.h"
30+#include "cbs_av1.h"
31+#include "thread.h"
32+
33+typedef struct AV1Frame {
34+ ThreadFrame tf;
35+
36+ AVBufferRef *hwaccel_priv_buf;
37+ void *hwaccel_picture_private;
38+
39+ uint8_t loop_filter_delta_enabled;
40+ int8_t loop_filter_ref_deltas[AV1_NUM_REF_FRAMES];
41+ int8_t loop_filter_mode_deltas[2];
42+ uint8_t gm_type[AV1_NUM_REF_FRAMES];
43+ int32_t gm_params[AV1_NUM_REF_FRAMES][6];
44+} AV1Frame;
45+
46+typedef struct TileGroupInfo {
47+ uint32_t tile_offset;
48+ uint32_t tile_size;
49+ uint16_t tile_row;
50+ uint16_t tile_column;
51+} TileGroupInfo;
52+
53+typedef struct AV1DecContext {
54+ const AVClass *class;
55+ AVCodecContext *avctx;
56+
57+ enum AVPixelFormat pix_fmt;
58+ CodedBitstreamContext *cbc;
59+ CodedBitstreamFragment current_obu;
60+
61+ AVBufferRef *seq_ref;
62+ AV1RawSequenceHeader *raw_seq;
63+ AVBufferRef *header_ref;
64+ AV1RawFrameHeader *raw_frame_header;
65+ TileGroupInfo *tile_group_info;
66+ uint16_t tile_num;
67+ uint16_t tg_start;
68+ uint16_t tg_end;
69+
70+ AV1Frame ref[AV1_NUM_REF_FRAMES];
71+ AV1Frame cur_frame;
72+
73+} AV1DecContext;
74+
75+#endif /* AVCODEC_AV1DEC_H */
libavcodec/version.h+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
2828 #include "libavutil/version.h"
2929
3030 #define LIBAVCODEC_VERSION_MAJOR 58
31−#define LIBAVCODEC_VERSION_MINOR 105
31+#define LIBAVCODEC_VERSION_MINOR 106
3232 #define LIBAVCODEC_VERSION_MICRO 100
3333
3434 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
tests/ref/fate/av1-annexb-demux+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
33 #media_type 0: video
44 #codec_id 0: av1
55 #dimensions 0: 300x300
6−#sar 0: 0/1
6+#sar 0: 1/1
77 0, 0, 0, 48000, 12691, 0xf0adcc79
88 0, 48000, 48000, 48000, 4975, 0x1742a45f, F=0x0
99 0, 96000, 96000, 48000, 928, 0x7408be1a, F=0x0
tests/ref/lavf-fate/av1.mkv+2−2
@@ -1,3 +1,3 @@
1−bd676bfc89422755920099ec6ebdebe6 *tests/data/lavf-fate/lavf.av1.mkv
2−55657 tests/data/lavf-fate/lavf.av1.mkv
1+77138a0e07ebd1c6ff2f69305e2f5c79 *tests/data/lavf-fate/lavf.av1.mkv
2+55653 tests/data/lavf-fate/lavf.av1.mkv
33 tests/data/lavf-fate/lavf.av1.mkv CRC=0x7c27cc15
tests/ref/lavf-fate/av1.mp4+2−2
@@ -1,3 +1,3 @@
1−4eed679a1d3e18edfd95b268167d8060 *tests/data/lavf-fate/lavf.av1.mp4
2−55940 tests/data/lavf-fate/lavf.av1.mp4
1+1461be24bed65c04aab21659d6e7a3e1 *tests/data/lavf-fate/lavf.av1.mp4
2+55956 tests/data/lavf-fate/lavf.av1.mp4
33 tests/data/lavf-fate/lavf.av1.mp4 CRC=0x7c27cc15

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t