[FFmpeg-devel] [PATCH v3 3/5] avcodec/avs2_parser: parse more info
hwren
hwrenx at 126.com
Tue Jun 21 05:45:54 EEST 2022
At 2022-06-13 11:36:34, "Zhao Zhili" <quinkblack at foxmail.com> wrote:
>Including video resolution, framerate and picture type, etc.
>
>Signed-off-by: Zhao Zhili <zhilizhao at tencent.com>
>---
> libavcodec/Makefile | 2 +-
> libavcodec/avs2.c | 42 ++++++++++++++++
> libavcodec/avs2.h | 10 ++++
> libavcodec/avs2_parser.c | 105 +++++++++++++++++++++++++++++++++++++++
> 4 files changed, 158 insertions(+), 1 deletion(-)
> create mode 100644 libavcodec/avs2.c
>
>diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>index 3b8f7b5e01..6cc6f8437c 100644
>--- a/libavcodec/Makefile
>+++ b/libavcodec/Makefile
>@@ -1114,7 +1114,7 @@ OBJS-$(CONFIG_AC3_PARSER) += aac_ac3_parser.o ac3tab.o \
> OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o
> OBJS-$(CONFIG_AMR_PARSER) += amr_parser.o
> OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o
>-OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o
>+OBJS-$(CONFIG_AVS2_PARSER) += avs2.o avs2_parser.o
> OBJS-$(CONFIG_AVS3_PARSER) += avs3_parser.o
> OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o
> OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o
>diff --git a/libavcodec/avs2.c b/libavcodec/avs2.c
>new file mode 100644
>index 0000000000..ead8687d0a
>--- /dev/null
>+++ b/libavcodec/avs2.c
>@@ -0,0 +1,42 @@
>+/*
>+ * AVS2 related definitions
>+ *
>+ * Copyright (C) 2022 Zhao Zhili, <zhilizhao at tencent.com>
>+ *
>+ * This file is part of FFmpeg.
>+ *
>+ * FFmpeg is free software; you can redistribute it and/or
>+ * modify it under the terms of the GNU Lesser General Public
>+ * License as published by the Free Software Foundation; either
>+ * version 2.1 of the License, or (at your option) any later version.
>+ *
>+ * FFmpeg is distributed in the hope that it will be useful,
>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>+ * Lesser General Public License for more details.
>+ *
>+ * You should have received a copy of the GNU Lesser General Public
>+ * License along with FFmpeg; if not, write to the Free Software
>+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>+ */
>+
>+#include "avs2.h"
>+
>+const AVRational ff_avs2_frame_rate_tab[16] = {
>+ { 0 , 0 }, // forbid
>+ { 24000, 1001},
>+ { 24 , 1 },
>+ { 25 , 1 },
>+ { 30000, 1001},
>+ { 30 , 1 },
>+ { 50 , 1 },
>+ { 60000, 1001},
>+ { 60 , 1 },
>+ { 100 , 1 },
>+ { 120 , 1 },
>+ { 200 , 1 },
>+ { 240 , 1 },
>+ { 300 , 1 },
>+ { 0 , 0 }, // reserved
>+ { 0 , 0 } // reserved
>+};
That table seems to appear only in avs2 decoder. If so, they are supposed to be declared in libdavs2.c.
If not, please point out the usage of this separate source file.
Persionally, the frame_rate table can be used in both encoder and decoder. So it is what should be
defined in the avs2.h (with related enc/dec changes).
>diff --git a/libavcodec/avs2.h b/libavcodec/avs2.h
>index f342ba52a0..544cf502d7 100644
>--- a/libavcodec/avs2.h
>+++ b/libavcodec/avs2.h
>@@ -23,6 +23,8 @@
> #ifndef AVCODEC_AVS2_H
> #define AVCODEC_AVS2_H
>
>+#include "libavutil/rational.h"
>+
> #define AVS2_SLICE_MAX_START_CODE 0x000001AF
>
> enum {
>@@ -38,4 +40,12 @@ enum {
> #define AVS2_ISPIC(x) ((x) == AVS2_INTRA_PIC_START_CODE || (x) == AVS2_INTER_PIC_START_CODE)
> #define AVS2_ISUNIT(x) ((x) == AVS2_SEQ_START_CODE || AVS2_ISPIC(x))
>
Same as above. Mentioned definitions now are only used in avs2_parser.c. If so, they are supposed to be
kept in avs2_parser.c.
>+enum AVS2Profile {
>+ AVS2_PROFILE_MAIN_PIC = 0x12,
>+ AVS2_PROFILE_MAIN = 0x20,
>+ AVS2_PROFILE_MAIN10 = 0x22,
>+};
Not mentioned elsewhere. If they are to work in the encoder/decoder, please package them with related changes.
>+
>+extern const AVRational ff_avs2_frame_rate_tab[16];
>+
> #endif
>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;
>
>--
>2.35.3
Best Regards,
Huiwen Ren
>
>_______________________________________________
>ffmpeg-devel mailing list
>ffmpeg-devel at ffmpeg.org
>https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>To unsubscribe, visit link above, or email
>ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list