diff mbox series

[FFmpeg-devel,v3,3/5] avcodec/avs2_parser: parse more info

Message ID tencent_D9FA1643CD0AA026CDD1CF93D524A75C3807@qq.com
State New
Headers show
Series [FFmpeg-devel,v3,1/5] avcodec/avs2: add AVS2 related definitions | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

zhilizhao(赵志立) June 13, 2022, 3:36 a.m. UTC
Including video resolution, framerate and picture type, etc.

Signed-off-by: Zhao Zhili <zhilizhao@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

Comments

hwren June 21, 2022, 2:45 a.m. UTC | #1
At 2022-06-13 11:36:34, "Zhao Zhili" <quinkblack@foxmail.com> wrote:
>Including video resolution, framerate and picture type, etc.
>
>Signed-off-by: Zhao Zhili <zhilizhao@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@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@ffmpeg.org
>https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>To unsubscribe, visit link above, or email
>ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
zhilizhao(赵志立) June 21, 2022, 8:25 a.m. UTC | #2
> On Jun 21, 2022, at 10:45 AM, hwren <hwrenx@126.com> wrote:
> 
> At 2022-06-13 11:36:34, "Zhao Zhili" <quinkblack@foxmail.com> wrote:
>> Including video resolution, framerate and picture type, etc.
>> 
>> Signed-off-by: Zhao Zhili <zhilizhao@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@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.

It’s used in this patch, parse_avs2_seq_header().

> 
> 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).

It’s declared in avs2.h, so it can be used by enc/dec.
It’s defined in .c to reduce binary size.

> 
>> 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.

It’s not the same as ff_avs2_frame_rate_tab. Firstly, define enum
and macros doesn’t generate binary. Secondly, they are be used
by avs2 parser/decoder/encoder and so on, the same as avs3.h.

They are only used by avs2 parser now, but they are handy when debug
decoder, for example, and future proof.

> 
> 
>> +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.

AVS2_PROFILE_MAIN10 is used in this patch.

> 
>> +
>> +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@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
zhilizhao(赵志立) June 21, 2022, 8:28 a.m. UTC | #3
> On Jun 21, 2022, at 4:25 PM, zhilizhao(赵志立) <quinkblack@foxmail.com> wrote:
> 
>> On Jun 21, 2022, at 10:45 AM, hwren <hwrenx@126.com> wrote:
>> 
>> At 2022-06-13 11:36:34, "Zhao Zhili" <quinkblack@foxmail.com> wrote:
>>> Including video resolution, framerate and picture type, etc.
>>> 
>>> Signed-off-by: Zhao Zhili <zhilizhao@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@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.
> 
> It’s used in this patch, parse_avs2_seq_header().
> 
>> 
>> 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).
> 
> It’s declared in avs2.h, so it can be used by enc/dec.
> It’s defined in .c to reduce binary size.
> 
>> 
>>> 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.
> 
> It’s not the same as ff_avs2_frame_rate_tab. Firstly, define enum
> and macros doesn’t generate binary. Secondly, they are be used
> by avs2 parser/decoder/encoder and so on, the same as avs3.h.

I mean they ‘can’ be used by avs2 parser/decoder/encoder.

> 
> They are only used by avs2 parser now, but they are handy when debug
> decoder, for example, and future proof.
> 
>> 
>> 
>>> +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.
> 
> AVS2_PROFILE_MAIN10 is used in this patch.
> 
>> 
>>> +
>>> +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@ffmpeg.org
>>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>> 
>>> To unsubscribe, visit link above, or email
>>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>> 
>> 
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> 
>> On Jun 21, 2022, at 10:45 AM, hwren <hwrenx@126.com> wrote:
>> 
>> At 2022-06-13 11:36:34, "Zhao Zhili" <quinkblack@foxmail.com> wrote:
>>> Including video resolution, framerate and picture type, etc.
>>> 
>>> Signed-off-by: Zhao Zhili <zhilizhao@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@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.
> 
> It’s used in this patch, parse_avs2_seq_header().
> 
>> 
>> 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).
> 
> It’s declared in avs2.h, so it can be used by enc/dec.
> It’s defined in .c to reduce binary size.
> 
>> 
>>> 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.
> 
> It’s not the same as ff_avs2_frame_rate_tab. Firstly, define enum
> and macros doesn’t generate binary. Secondly, they are be used
> by avs2 parser/decoder/encoder and so on, the same as avs3.h.
> 
> They are only used by avs2 parser now, but they are handy when debug
> decoder, for example, and future proof.
> 
>> 
>> 
>>> +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.
> 
> AVS2_PROFILE_MAIN10 is used in this patch.
> 
>> 
>>> +
>>> +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@ffmpeg.org
>>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>> 
>>> To unsubscribe, visit link above, or email
>>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>> 
>> 
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
hwren June 21, 2022, 8:57 a.m. UTC | #4
在 2022-06-21 16:28:37,"\"zhilizhao(赵志立)\"" <quinkblack@foxmail.com> 写道:
>
>
>> On Jun 21, 2022, at 4:25 PM, zhilizhao(赵志立) <quinkblack@foxmail.com> wrote:
>> 
>>> On Jun 21, 2022, at 10:45 AM, hwren <hwrenx@126.com> wrote:
>>> 
>>> At 2022-06-13 11:36:34, "Zhao Zhili" <quinkblack@foxmail.com> wrote:
>>>> Including video resolution, framerate and picture type, etc.
>>>> 
>>>> Signed-off-by: Zhao Zhili <zhilizhao@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@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.
>> 
>> It’s used in this patch, parse_avs2_seq_header().

LGTM if it is used in multiple files and need to be optimized to reduce binary size.

>> 
>>> 
>>> 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).
>> 
>> It’s declared in avs2.h, so it can be used by enc/dec.
>> It’s defined in .c to reduce binary size.
>> 
>>> 
>>>> 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.
>> 
>> It’s not the same as ff_avs2_frame_rate_tab. Firstly, define enum
>> and macros doesn’t generate binary. Secondly, they are be used
>> by avs2 parser/decoder/encoder and so on, the same as avs3.h.
>
>I mean they ‘can’ be used by avs2 parser/decoder/encoder.

LGTM

>
>> 
>> They are only used by avs2 parser now, but they are handy when debug
>> decoder, for example, and future proof.
>> 
>>> 
>>> 
>>>> +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.
>> 
>> AVS2_PROFILE_MAIN10 is used in this patch.

Got it. No more questions.

>> 
>>> 
>>>> +
>>>> +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@ffmpeg.org
>>>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>>> 
>>>> To unsubscribe, visit link above, or email
>>>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>>> 
>>> 
>>> _______________________________________________
>>> ffmpeg-devel mailing list
>>> ffmpeg-devel@ffmpeg.org
>>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>> 
>>> To unsubscribe, visit link above, or email
>>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

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@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
+};
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))
 
+enum AVS2Profile {
+    AVS2_PROFILE_MAIN_PIC   = 0x12,
+    AVS2_PROFILE_MAIN       = 0x20,
+    AVS2_PROFILE_MAIN10     = 0x22,
+};
+
+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;