4 * Copyright (C) 2018 James Almer <jamrial@gmail.com>
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavutil/avassert.h"
28 typedef struct AV1ParseContext
{
29 CodedBitstreamContext
*cbc
;
30 CodedBitstreamFragment temporal_unit
;
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
},
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
},
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
},
47 static const enum AVPixelFormat pix_fmts_rgb
[3] = {
48 AV_PIX_FMT_GBRP
, AV_PIX_FMT_GBRP10
, AV_PIX_FMT_GBRP12
,
51 static int av1_parser_parse(AVCodecParserContext
*ctx
,
52 AVCodecContext
*avctx
,
53 const uint8_t **out_data
, int *out_size
,
54 const uint8_t *data
, int size
)
56 AV1ParseContext
*s
= ctx
->priv_data
;
57 CodedBitstreamFragment
*td
= &s
->temporal_unit
;
58 const CodedBitstreamAV1Context
*av1
= s
->cbc
->priv_data
;
59 const AV1RawSequenceHeader
*seq
;
60 const AV1RawColorConfig
*color
;
67 ctx
->pict_type
= AV_PICTURE_TYPE_NONE
;
68 ctx
->picture_structure
= AV_PICTURE_STRUCTURE_UNKNOWN
;
70 s
->cbc
->log_ctx
= avctx
;
72 if (avctx
->extradata_size
&& !s
->parsed_extradata
) {
73 s
->parsed_extradata
= 1;
75 ret
= ff_cbs_read_extradata_from_codec(s
->cbc
, td
, avctx
);
77 av_log(avctx
, AV_LOG_WARNING
, "Failed to parse extradata.\n");
80 ff_cbs_fragment_reset(td
);
83 ret
= ff_cbs_read(s
->cbc
, td
, data
, size
);
85 av_log(avctx
, AV_LOG_ERROR
, "Failed to parse temporal unit.\n");
89 if (!av1
->sequence_header
) {
90 av_log(avctx
, AV_LOG_ERROR
, "No sequence header available\n");
94 seq
= av1
->sequence_header
;
95 color
= &seq
->color_config
;
97 for (int i
= 0; i
< td
->nb_units
; i
++) {
98 const CodedBitstreamUnit
*unit
= &td
->units
[i
];
99 const AV1RawOBU
*obu
= unit
->content
;
100 const AV1RawFrameHeader
*frame
;
102 if (unit
->type
== AV1_OBU_FRAME
)
103 frame
= &obu
->obu
.frame
.header
;
104 else if (unit
->type
== AV1_OBU_FRAME_HEADER
)
105 frame
= &obu
->obu
.frame_header
;
109 if (obu
->header
.spatial_id
> 0)
112 if (!frame
->show_frame
&& !frame
->show_existing_frame
)
115 ctx
->width
= frame
->frame_width_minus_1
+ 1;
116 ctx
->height
= frame
->frame_height_minus_1
+ 1;
118 ctx
->key_frame
= frame
->frame_type
== AV1_FRAME_KEY
&& !frame
->show_existing_frame
;
120 switch (frame
->frame_type
) {
122 case AV1_FRAME_INTRA_ONLY
:
123 ctx
->pict_type
= AV_PICTURE_TYPE_I
;
125 case AV1_FRAME_INTER
:
126 ctx
->pict_type
= AV_PICTURE_TYPE_P
;
128 case AV1_FRAME_SWITCH
:
129 ctx
->pict_type
= AV_PICTURE_TYPE_SP
;
132 ctx
->picture_structure
= AV_PICTURE_STRUCTURE_FRAME
;
135 switch (av1
->bit_depth
) {
137 ctx
->format
= color
->mono_chrome
? AV_PIX_FMT_GRAY8
138 : pix_fmts_8bit
[color
->subsampling_x
][color
->subsampling_y
];
141 ctx
->format
= color
->mono_chrome
? AV_PIX_FMT_GRAY10
142 : pix_fmts_10bit
[color
->subsampling_x
][color
->subsampling_y
];
145 ctx
->format
= color
->mono_chrome
? AV_PIX_FMT_GRAY12
146 : pix_fmts_12bit
[color
->subsampling_x
][color
->subsampling_y
];
149 av_assert2(ctx
->format
!= AV_PIX_FMT_NONE
);
151 if (!color
->subsampling_x
&& !color
->subsampling_y
&&
152 color
->matrix_coefficients
== AVCOL_SPC_RGB
&&
153 color
->color_primaries
== AVCOL_PRI_BT709
&&
154 color
->transfer_characteristics
== AVCOL_TRC_IEC61966_2_1
)
155 ctx
->format
= pix_fmts_rgb
[color
->high_bitdepth
+ color
->twelve_bit
];
157 avctx
->profile
= seq
->seq_profile
;
158 avctx
->level
= seq
->seq_level_idx
[0];
160 avctx
->colorspace
= (enum AVColorSpace
) color
->matrix_coefficients
;
161 avctx
->color_primaries
= (enum AVColorPrimaries
) color
->color_primaries
;
162 avctx
->color_trc
= (enum AVColorTransferCharacteristic
) color
->transfer_characteristics
;
163 avctx
->color_range
= color
->color_range
? AVCOL_RANGE_JPEG
: AVCOL_RANGE_MPEG
;
165 if (avctx
->framerate
.num
)
166 avctx
->time_base
= av_inv_q(av_mul_q(avctx
->framerate
, (AVRational
){avctx
->ticks_per_frame
, 1}));
169 ff_cbs_fragment_reset(td
);
171 s
->cbc
->log_ctx
= NULL
;
176 static const CodedBitstreamUnitType decompose_unit_types
[] = {
177 AV1_OBU_TEMPORAL_DELIMITER
,
178 AV1_OBU_SEQUENCE_HEADER
,
179 AV1_OBU_FRAME_HEADER
,
184 static av_cold
int av1_parser_init(AVCodecParserContext
*ctx
)
186 AV1ParseContext
*s
= ctx
->priv_data
;
189 ret
= ff_cbs_init(&s
->cbc
, AV_CODEC_ID_AV1
, NULL
);
193 s
->cbc
->decompose_unit_types
= decompose_unit_types
;
194 s
->cbc
->nb_decompose_unit_types
= FF_ARRAY_ELEMS(decompose_unit_types
);
199 static void av1_parser_close(AVCodecParserContext
*ctx
)
201 AV1ParseContext
*s
= ctx
->priv_data
;
203 ff_cbs_fragment_free(&s
->temporal_unit
);
204 ff_cbs_close(&s
->cbc
);
207 const AVCodecParser ff_av1_parser
= {
208 .codec_ids
= { AV_CODEC_ID_AV1
},
209 .priv_data_size
= sizeof(AV1ParseContext
),
210 .parser_init
= av1_parser_init
,
211 .parser_close
= av1_parser_close
,
212 .parser_parse
= av1_parser_parse
,