History

avcodec: add an AV1 parser

Simple parser to set keyframes, frame type, structure, width, height, and pixel format, plus stream profile and level.

James Almer committed 8 years ago

Commit ebc3d041 parent af2acbd6 files · +234 −2Browse files

Unified · Split

6 files
  1. Changelog +1 −0
  2. configure +1 −0
  3. libavcodec/Makefile +1 −0
  4. libavcodec/av1_parser.c +228 −0
  5. libavcodec/parsers.c +1 −0
  6. libavcodec/version.h +2 −2
Changelog+1−0
@@ -32,6 +32,7 @@ version <next>: · 31 unmodified lines
3232 - acrossover filter
3333 - ilbc decoder
3434 - audio denoiser as afftdn filter
35+- AV1 parser
3536
3637
3738 version 4.0:
configure+1−0
@@ -3020,6 +3020,7 @@ wmv3_crystalhd_decoder_select="crystalhd" · 3019 unmodified lines
30203020
30213021 # parsers
30223022 aac_parser_select="adts_header"
3023+av1_parser_select="cbs_av1"
30233024 h264_parser_select="golomb h264dsp h264parse"
30243025 hevc_parser_select="hevcparse"
30253026 mpegaudio_parser_select="mpegaudioheader"
libavcodec/Makefile+1−0
@@ -1006,6 +1006,7 @@ OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \ · 1005 unmodified lines
10061006 mpeg4audio.o
10071007 OBJS-$(CONFIG_AC3_PARSER) += ac3tab.o aac_ac3_parser.o
10081008 OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o
1009+OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o av1_parse.o
10091010 OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o
10101011 OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o
10111012 OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o
libavcodec/av1_parser.c+228−0
@@ -0,0 +1,228 @@
1+/*
2+ * AV1 parser
3+ *
4+ * Copyright (C) 2018 James Almer <jamrial@gmail.com>
5+ *
6+ * This file is part of FFmpeg.
7+ *
8+ * FFmpeg is free software; you can redistribute it and/or
9+ * modify it under the terms of the GNU Lesser General Public
10+ * License as published by the Free Software Foundation; either
11+ * version 2.1 of the License, or (at your option) any later version.
12+ *
13+ * FFmpeg is distributed in the hope that it will be useful,
14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+ * Lesser General Public License for more details.
17+ *
18+ * You should have received a copy of the GNU Lesser General Public
19+ * License along with FFmpeg; if not, write to the Free Software
20+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+ */
22+
23+#include "av1_parse.h"
24+#include "cbs.h"
25+#include "cbs_av1.h"
26+#include "parser.h"
27+
28+typedef struct AV1ParseContext {
29+ CodedBitstreamContext *cbc;
30+ CodedBitstreamFragment temporal_unit;
31+ int parsed_extradata;
32+} AV1ParseContext;
33+
34+static const enum AVPixelFormat pix_fmts_8bit[2][2] = {
35+ { AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE },
36+ { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P },
37+};
38+static const enum AVPixelFormat pix_fmts_10bit[2][2] = {
39+ { AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE },
40+ { AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10 },
41+};
42+static const enum AVPixelFormat pix_fmts_12bit[2][2] = {
43+ { AV_PIX_FMT_YUV444P12, AV_PIX_FMT_NONE },
44+ { AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12 },
45+};
46+
47+static int av1_parser_parse(AVCodecParserContext *ctx,
48+ AVCodecContext *avctx,
49+ const uint8_t **out_data, int *out_size,
50+ const uint8_t *data, int size)
51+{
52+ AV1ParseContext *s = ctx->priv_data;
53+ CodedBitstreamFragment *td = &s->temporal_unit;
54+ CodedBitstreamAV1Context *av1 = s->cbc->priv_data;
55+ int ret;
56+
57+ *out_data = data;
58+ *out_size = size;
59+
60+ ctx->key_frame = -1;
61+ ctx->pict_type = AV_PICTURE_TYPE_NONE;
62+ ctx->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
63+
64+ s->cbc->log_ctx = avctx;
65+
66+ if (avctx->extradata_size && !s->parsed_extradata) {
67+ s->parsed_extradata = 1;
68+
69+ ret = ff_cbs_read(s->cbc, td, avctx->extradata, avctx->extradata_size);
70+ if (ret < 0) {
71+ av_log(avctx, AV_LOG_ERROR, "Failed to parse extradata.\n");
72+ goto end;
73+ }
74+
75+ ff_cbs_fragment_uninit(s->cbc, td);
76+ }
77+
78+ ret = ff_cbs_read(s->cbc, td, data, size);
79+ if (ret < 0) {
80+ av_log(avctx, AV_LOG_ERROR, "Failed to parse temporal unit.\n");
81+ goto end;
82+ }
83+
84+ if (!av1->sequence_header) {
85+ av_log(avctx, AV_LOG_ERROR, "No sequence header available\n");
86+ goto end;
87+ }
88+
89+ for (int i = 0; i < td->nb_units; i++) {
90+ CodedBitstreamUnit *unit = &td->units[i];
91+ AV1RawOBU *obu = unit->content;
92+ AV1RawSequenceHeader *seq = av1->sequence_header;
93+ AV1RawColorConfig *color = &seq->color_config;
94+ AV1RawFrameHeader *frame;
95+ int frame_type;
96+
97+ if (unit->type == AV1_OBU_FRAME)
98+ frame = &obu->obu.frame.header;
99+ else if (unit->type == AV1_OBU_FRAME_HEADER)
100+ frame = &obu->obu.frame_header;
101+ else
102+ continue;
103+
104+ if (frame->show_existing_frame) {
105+ AV1ReferenceFrameState *ref = &av1->ref[frame->frame_to_show_map_idx];
106+
107+ if (!ref->valid) {
108+ av_log(avctx, AV_LOG_ERROR, "Invalid reference frame\n");
109+ goto end;
110+ }
111+
112+ ctx->width = ref->frame_width;
113+ ctx->height = ref->frame_height;
114+ frame_type = ref->frame_type;
115+
116+ ctx->key_frame = 0;
117+ } else if (!frame->show_frame) {
118+ continue;
119+ } else {
120+ ctx->width = av1->frame_width;
121+ ctx->height = av1->frame_height;
122+ frame_type = frame->frame_type;
123+
124+ ctx->key_frame = frame_type == AV1_FRAME_KEY;
125+ }
126+
127+ avctx->profile = seq->seq_profile;
128+ avctx->level = seq->seq_level_idx[0];
129+
130+ switch (frame_type) {
131+ case AV1_FRAME_KEY:
132+ case AV1_FRAME_INTRA_ONLY:
133+ ctx->pict_type = AV_PICTURE_TYPE_I;
134+ break;
135+ case AV1_FRAME_INTER:
136+ ctx->pict_type = AV_PICTURE_TYPE_P;
137+ break;
138+ case AV1_FRAME_SWITCH:
139+ ctx->pict_type = AV_PICTURE_TYPE_SP;
140+ break;
141+ }
142+ ctx->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
143+
144+ switch (av1->bit_depth) {
145+ case 8:
146+ ctx->format = color->mono_chrome ? AV_PIX_FMT_GRAY8
147+ : pix_fmts_8bit [color->subsampling_x][color->subsampling_y];
148+ break;
149+ case 10:
150+ ctx->format = color->mono_chrome ? AV_PIX_FMT_GRAY10
151+ : pix_fmts_10bit[color->subsampling_x][color->subsampling_y];
152+ break;
153+ case 12:
154+ ctx->format = color->mono_chrome ? AV_PIX_FMT_GRAY12
155+ : pix_fmts_12bit[color->subsampling_x][color->subsampling_y];
156+ break;
157+ }
158+ av_assert2(ctx->format != AV_PIX_FMT_NONE);
159+ }
160+
161+end:
162+ ff_cbs_fragment_uninit(s->cbc, td);
163+
164+ s->cbc->log_ctx = NULL;
165+
166+ return size;
167+}
168+
169+static const CodedBitstreamUnitType decompose_unit_types[] = {
170+ AV1_OBU_TEMPORAL_DELIMITER,
171+ AV1_OBU_SEQUENCE_HEADER,
172+ AV1_OBU_FRAME_HEADER,
173+ AV1_OBU_TILE_GROUP,
174+ AV1_OBU_FRAME,
175+};
176+
177+static av_cold int av1_parser_init(AVCodecParserContext *ctx)
178+{
179+ AV1ParseContext *s = ctx->priv_data;
180+ int ret;
181+
182+ ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_AV1, NULL);
183+ if (ret < 0)
184+ return ret;
185+
186+ s->cbc->decompose_unit_types = (CodedBitstreamUnitType *)decompose_unit_types;
187+ s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types);
188+
189+ return 0;
190+}
191+
192+static void av1_parser_close(AVCodecParserContext *ctx)
193+{
194+ AV1ParseContext *s = ctx->priv_data;
195+
196+ ff_cbs_close(&s->cbc);
197+}
198+
199+static int av1_parser_split(AVCodecContext *avctx,
200+ const uint8_t *buf, int buf_size)
201+{
202+ AV1OBU obu;
203+ const uint8_t *ptr = buf, *end = buf + buf_size;
204+
205+ while (ptr < end) {
206+ int len = ff_av1_extract_obu(&obu, ptr, buf_size, avctx);
207+ if (len < 0)
208+ break;
209+
210+ if (obu.type == AV1_OBU_FRAME_HEADER ||
211+ obu.type == AV1_OBU_FRAME) {
212+ return ptr - buf;
213+ }
214+ ptr += len;
215+ buf_size -= len;
216+ }
217+
218+ return 0;
219+}
220+
221+AVCodecParser ff_av1_parser = {
222+ .codec_ids = { AV_CODEC_ID_AV1 },
223+ .priv_data_size = sizeof(AV1ParseContext),
224+ .parser_init = av1_parser_init,
225+ .parser_close = av1_parser_close,
226+ .parser_parse = av1_parser_parse,
227+ .split = av1_parser_split,
228+};
libavcodec/parsers.c+1−0
@@ -26,6 +26,7 @@ extern AVCodecParser ff_aac_parser; · 25 unmodified lines
2626 extern AVCodecParser ff_aac_latm_parser;
2727 extern AVCodecParser ff_ac3_parser;
2828 extern AVCodecParser ff_adx_parser;
29+extern AVCodecParser ff_av1_parser;
2930 extern AVCodecParser ff_avs2_parser;
3031 extern AVCodecParser ff_bmp_parser;
3132 extern AVCodecParser ff_cavsvideo_parser;
libavcodec/version.h+2−2
@@ -28,8 +28,8 @@ · 27 unmodified lines
2828 #include "libavutil/version.h"
2929
3030 #define LIBAVCODEC_VERSION_MAJOR 58
31−#define LIBAVCODEC_VERSION_MINOR 31
32−#define LIBAVCODEC_VERSION_MICRO 102
31+#define LIBAVCODEC_VERSION_MINOR 32
32+#define LIBAVCODEC_VERSION_MICRO 100
3333
3434 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
3535 LIBAVCODEC_VERSION_MINOR, \

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