diff options
author | Zhao Zhili <quinkblack@foxmail.com> | 2022-06-13 11:36:34 +0800 |
---|---|---|
committer | Zhao Zhili <zhilizhao@tencent.com> | 2022-06-24 15:37:23 +0800 |
commit | e0cddee277bca5061893834989730f64d171d6ac (patch) | |
tree | af18319dfbdcfc908675c21f017631e91ced7cda /libavcodec/avs2_parser.c | |
parent | b7eee211bc4c7897b538fb53d3ba9fad3a0b6832 (diff) | |
download | ffmpeg-e0cddee277bca5061893834989730f64d171d6ac.tar.gz |
avcodec/avs2_parser: parse more info
Including video resolution, framerate and picture type, etc.
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
Diffstat (limited to 'libavcodec/avs2_parser.c')
-rw-r--r-- | libavcodec/avs2_parser.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/libavcodec/avs2_parser.c b/libavcodec/avs2_parser.c index 71cf442903..0350517493 100644 --- a/libavcodec/avs2_parser.c +++ b/libavcodec/avs2_parser.c @@ -19,7 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avutil.h" #include "avs2.h" +#include "get_bits.h" #include "parser.h" static int avs2_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) @@ -58,6 +60,107 @@ static int avs2_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_siz return END_NOT_FOUND; } +static void parse_avs2_seq_header(AVCodecParserContext *s, const uint8_t *buf, + int buf_size, AVCodecContext *avctx) +{ + GetBitContext gb; + int profile, level; + int width, height; + int chroma, sample_precision, encoding_precision = 1; + // sample_precision and encoding_precision is 3 bits + static const uint8_t precision[8] = { 0, 8, 10 }; + unsigned aspect_ratio; + unsigned frame_rate_code; + int low_delay; + // update buf_size_min if parse more deeper + const int buf_size_min = 15; + + if (buf_size < buf_size_min) + return; + + init_get_bits8(&gb, buf, buf_size_min); + + s->key_frame = 1; + s->pict_type = AV_PICTURE_TYPE_I; + + profile = get_bits(&gb, 8); + level = get_bits(&gb, 8); + + // progressive_sequence u(1) + // field_coded_sequence u(1) + skip_bits(&gb, 2); + + width = get_bits(&gb, 14); + height = get_bits(&gb, 14); + + chroma = get_bits(&gb, 2); + sample_precision = get_bits(&gb, 3); + if (profile == AVS2_PROFILE_MAIN10) + encoding_precision = get_bits(&gb, 3); + + aspect_ratio = get_bits(&gb, 4); + frame_rate_code = get_bits(&gb, 4); + + // bit_rate_lower u(18) + // marker_bit f(1) + // bit_rate_upper u(12) + skip_bits(&gb, 31); + + low_delay = get_bits(&gb, 1); + + s->width = width; + s->height = height; + s->coded_width = FFALIGN(width, 8); + s->coded_height = FFALIGN(height, 8); + avctx->framerate.num = avctx->time_base.den = + ff_avs2_frame_rate_tab[frame_rate_code].num; + avctx->framerate.den = avctx->time_base.num = + ff_avs2_frame_rate_tab[frame_rate_code].den; + avctx->has_b_frames = FFMAX(avctx->has_b_frames, !low_delay); + + av_log(avctx, AV_LOG_DEBUG, + "AVS2 parse seq HDR: profile %x, level %x, " + "width %d, height %d, " + "chroma %d, sample_precision %d bits, encoding_precision %d bits, " + "aspect_ratio 0x%x, framerate %d/%d, low_delay %d\n", + profile, level, + width, height, + chroma, precision[sample_precision], precision[encoding_precision], + aspect_ratio, avctx->framerate.num, avctx->framerate.den, low_delay); +} + +static void parse_avs2_units(AVCodecParserContext *s, const uint8_t *buf, + int buf_size, AVCodecContext *avctx) +{ + if (buf_size < 5) + return; + + if (!(buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x1)) + return; + + switch (buf[3]) { + case AVS2_SEQ_START_CODE: + parse_avs2_seq_header(s, buf + 4, buf_size - 4, avctx); + return; + case AVS2_INTRA_PIC_START_CODE: + s->key_frame = 1; + s->pict_type = AV_PICTURE_TYPE_I; + return; + case AVS2_INTER_PIC_START_CODE: + s->key_frame = 0; + if (buf_size > 9) { + int pic_code_type = buf[8] & 0x3; + if (pic_code_type == 1) + s->pict_type = AV_PICTURE_TYPE_P; + else if (pic_code_type == 3) + s->pict_type = AV_PICTURE_TYPE_S; + else + s->pict_type = AV_PICTURE_TYPE_B; + } + return; + } +} + static int avs2_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) @@ -76,6 +179,8 @@ static int avs2_parse(AVCodecParserContext *s, AVCodecContext *avctx, } } + parse_avs2_units(s, buf, buf_size, avctx); + *poutbuf = buf; *poutbuf_size = buf_size; |