diff mbox series

[FFmpeg-devel,v4,2/4] lavc/avs3_parser: add avs3 parser

Message ID 20200818164506.2006-3-hwrenx@126.com
State Superseded
Headers show
Series Supplement AVS3-P2/IEEE1857.10 video decoding via libuavs3d | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate fail Make fate failed

Commit Message

hwren Aug. 18, 2020, 4:45 p.m. UTC
From: hwren <hwrenx@126.com>

Signed-off-by: hbj <hanbj@pku.edu.cn>
Signed-off-by: hwren <hwrenx@126.com>
---
 libavcodec/Makefile      |   1 +
 libavcodec/avs3_parser.c | 179 +++++++++++++++++++++++++++++++++++++++
 libavcodec/avs3_parser.h |  64 ++++++++++++++
 libavcodec/parsers.c     |   1 +
 4 files changed, 245 insertions(+)
 create mode 100644 libavcodec/avs3_parser.c
 create mode 100644 libavcodec/avs3_parser.h

Comments

Andreas Rheinhardt Aug. 18, 2020, 5 p.m. UTC | #1
hwrenx@126.com:
> From: hwren <hwrenx@126.com>
> 
> Signed-off-by: hbj <hanbj@pku.edu.cn>
> Signed-off-by: hwren <hwrenx@126.com>
> ---
> diff --git a/libavcodec/avs3_parser.h b/libavcodec/avs3_parser.h
> new file mode 100644
> index 0000000000..afc6d235b9
> --- /dev/null
> +++ b/libavcodec/avs3_parser.h
> @@ -0,0 +1,64 @@
> +/*
> + * AVS3-P2/IEEE1857.10 video parser.
> + * Copyright (c) 2020 Zhenyu Wang <wangzhenyu@pkusz.edu.cn>
> + *                    Bingjie Han <hanbj@pkusz.edu.cn>
> + *                    Huiwen Ren  <hwrenx@gmail.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
> + */
> +
> +#ifndef AVCODEC_AVS3PARSER_H
> +#define AVCODEC_AVS3PARSER_H
> +
> +#include "parser.h"
> +
> +#define AVS3_NAL_START_CODE          0x010000
> +#define AVS3_SEQ_START_CODE          0xB0
> +#define AVS3_SEQ_END_CODE            0xB1
> +#define AVS3_USER_DATA_START_CODE    0xB2
> +#define AVS3_INTRA_PIC_START_CODE    0xB3
> +#define AVS3_UNDEF_START_CODE        0xB4
> +#define AVS3_EXTENSION_START_CODE    0xB5
> +#define AVS3_INTER_PIC_START_CODE    0xB6
> +#define AVS3_VIDEO_EDIT_CODE         0xB7
> +#define AVS3_FIRST_SLICE_START_CODE  0x00
> +#define AVS3_PROFILE_BASELINE_MAIN   0x20
> +#define AVS3_PROFILE_BASELINE_MAIN10 0x22
> +
> +#define ISPIC(x) ((x) == AVS3_INTRA_PIC_START_CODE || (x) == AVS3_INTER_PIC_START_CODE)
> +#define ISUNIT(x) ((x) == AVS3_SEQ_START_CODE || ISPIC(x))
> +
> +static const AVRational avs3_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
> +};
> +
> +#endif /* AVCODEC_AVS3PARSER_H */

None of the stuff in this header file (except the '#include "parser.h"')
is parser-specific. It should be part of a generic avs3 header file. And
the frame rate table should not be defined in said header file, as this
will lead to duplications of the table. If it is used in more than one
place, it should be declared via extern in this header file; if not, it
should just be declared inside the file that uses it (right now, only
the parser uses it).
(If it is used in more than one library, then it needs to exist in these
libraries separately (or it needs to be avpriv).)

- Andreas
hwren Aug. 19, 2020, 6:18 a.m. UTC | #2
At 2020-08-19 01:00:57, "Andreas Rheinhardt" <andreas.rheinhardt@gmail.com> wrote:
>hwrenx@126.com:
>> From: hwren <hwrenx@126.com>
>> 
>> Signed-off-by: hbj <hanbj@pku.edu.cn>
>> Signed-off-by: hwren <hwrenx@126.com>
>> ---
>> diff --git a/libavcodec/avs3_parser.h b/libavcodec/avs3_parser.h
>> new file mode 100644
>> index 0000000000..afc6d235b9
>> --- /dev/null
>> +++ b/libavcodec/avs3_parser.h
>> @@ -0,0 +1,64 @@
>> +/*
>> + * AVS3-P2/IEEE1857.10 video parser.
>> + * Copyright (c) 2020 Zhenyu Wang <wangzhenyu@pkusz.edu.cn>
>> + *                    Bingjie Han <hanbj@pkusz.edu.cn>
>> + *                    Huiwen Ren  <hwrenx@gmail.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
>> + */
>> +
>> +#ifndef AVCODEC_AVS3PARSER_H
>> +#define AVCODEC_AVS3PARSER_H
>> +
>> +#include "parser.h"
>> +
>> +#define AVS3_NAL_START_CODE          0x010000
>> +#define AVS3_SEQ_START_CODE          0xB0
>> +#define AVS3_SEQ_END_CODE            0xB1
>> +#define AVS3_USER_DATA_START_CODE    0xB2
>> +#define AVS3_INTRA_PIC_START_CODE    0xB3
>> +#define AVS3_UNDEF_START_CODE        0xB4
>> +#define AVS3_EXTENSION_START_CODE    0xB5
>> +#define AVS3_INTER_PIC_START_CODE    0xB6
>> +#define AVS3_VIDEO_EDIT_CODE         0xB7
>> +#define AVS3_FIRST_SLICE_START_CODE  0x00
>> +#define AVS3_PROFILE_BASELINE_MAIN   0x20
>> +#define AVS3_PROFILE_BASELINE_MAIN10 0x22
>> +
>> +#define ISPIC(x) ((x) == AVS3_INTRA_PIC_START_CODE || (x) == AVS3_INTER_PIC_START_CODE)
>> +#define ISUNIT(x) ((x) == AVS3_SEQ_START_CODE || ISPIC(x))
>> +
>> +static const AVRational avs3_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
>> +};
>> +
>> +#endif /* AVCODEC_AVS3PARSER_H */
>
>None of the stuff in this header file (except the '#include "parser.h"')
>is parser-specific. It should be part of a generic avs3 header file. And
>the frame rate table should not be defined in said header file, as this
>will lead to duplications of the table. If it is used in more than one
>place, it should be declared via extern in this header file; if not, it
>should just be declared inside the file that uses it (right now, only
>the parser uses it).
>(If it is used in more than one library, then it needs to exist in these
>libraries separately (or it needs to be avpriv).)

Indeed. There would be a new file as avs3.h including all those common
definitions. avs3_parser.h will be removed.

Thanks.

>
>- Andreas
>_______________________________________________
>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 3431ba2dca..5c031f7777 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1059,6 +1059,7 @@  OBJS-$(CONFIG_AC3_PARSER)              += ac3tab.o aac_ac3_parser.o
 OBJS-$(CONFIG_ADX_PARSER)              += adx_parser.o adx.o
 OBJS-$(CONFIG_AV1_PARSER)              += av1_parser.o av1_parse.o
 OBJS-$(CONFIG_AVS2_PARSER)             += avs2_parser.o
+OBJS-$(CONFIG_AVS3_PARSER)             += avs3_parser.o
 OBJS-$(CONFIG_BMP_PARSER)              += bmp_parser.o
 OBJS-$(CONFIG_CAVSVIDEO_PARSER)        += cavs_parser.o
 OBJS-$(CONFIG_COOK_PARSER)             += cook_parser.o
diff --git a/libavcodec/avs3_parser.c b/libavcodec/avs3_parser.c
new file mode 100644
index 0000000000..f04f696a89
--- /dev/null
+++ b/libavcodec/avs3_parser.c
@@ -0,0 +1,179 @@ 
+/*
+ * AVS3-P2/IEEE1857.10 video parser.
+ * Copyright (c) 2020 Zhenyu Wang <wangzhenyu@pkusz.edu.cn>
+ *                    Bingjie Han <hanbj@pkusz.edu.cn>
+ *                    Huiwen Ren  <hwrenx@gmail.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 "avs3_parser.h"
+#include "get_bits.h"
+
+static int avs3_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
+{
+    int pic_found  = pc->frame_start_found;
+    uint32_t state = pc->state;
+    int cur = 0;
+
+    if (!pic_found) {
+        for (; cur < buf_size; ++cur) {
+            state = (state << 8) | buf[cur];
+            if (ISPIC(buf[cur])){
+                ++cur;
+                pic_found = 1;
+                break;
+            }
+        }
+    }
+
+    if (pic_found) {
+        if (!buf_size)
+            return END_NOT_FOUND;
+        for (; cur < buf_size; ++cur) {
+            state = (state << 8) | buf[cur];
+            if ((state & 0xFFFFFF00) == 0x100 && ISUNIT(state & 0xFF)) {
+                pc->frame_start_found = 0;
+                pc->state = -1;
+                return cur - 3;
+            }
+        }
+    }
+
+    pc->frame_start_found = pic_found;
+    pc->state = state;
+
+    return END_NOT_FOUND;
+}
+
+static void parse_avs3_nal_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) {
+        if (buf[3] == AVS3_SEQ_START_CODE) {
+            GetBitContext gb;
+            int profile, ratecode;
+
+            init_get_bits(&gb, buf + 4, buf_size - 4);
+
+            s->key_frame = 1;
+            s->pict_type = AV_PICTURE_TYPE_I;
+
+            profile = get_bits(&gb, 8);
+            // Skip bits: level(8)
+            //            progressive(1)
+            //            field(1)
+            //            library(2)
+            //            resv(1)
+            //            width(14)
+            //            resv(1)
+            //            height(14)
+            //            chroma(2)
+            //            sampe_precision(3)
+            skip_bits(&gb, 47);
+
+            if (profile == AVS3_PROFILE_BASELINE_MAIN10) {
+                int sample_precision = get_bits(&gb, 3);
+                if (sample_precision == 1) {
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+                } else if (sample_precision == 2) {
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P10LE;
+                } else {
+                    avctx->pix_fmt = AV_PIX_FMT_NONE;
+                }
+            }
+
+            // Skip bits: resv(1)
+            //            aspect(4)
+            skip_bits(&gb, 5);
+
+            ratecode = get_bits(&gb, 4);
+
+            // Skip bits: resv(1)
+            //            bitrate_low(18)
+            //            resv(1)
+            //            bitrate_high(12)
+            //            low_delay
+            skip_bits(&gb, 32);
+
+            avctx->has_b_frames = !get_bits(&gb, 1);
+
+            avctx->framerate.num = avctx->time_base.den = avs3_frame_rate_tab[ratecode].num;
+            avctx->framerate.den = avctx->time_base.num = avs3_frame_rate_tab[ratecode].den;
+
+            s->width  = s->coded_width = avctx->width;
+            s->height = s->coded_height = avctx->height;
+
+            av_log(avctx, AV_LOG_DEBUG,
+                       "avs3 parse seq hdr: profile %d; coded wxh: %dx%d; "
+                       "frame_rate_code %d\n", profile, avctx->width, avctx->height, ratecode);
+
+        } else if (buf[3] == AVS3_INTRA_PIC_START_CODE) {
+            s->key_frame = 1;
+            s->pict_type = AV_PICTURE_TYPE_I;
+        } else if (buf[3] == AVS3_INTER_PIC_START_CODE){
+            s->key_frame = 0;
+            if (buf_size > 9) {
+                int pic_code_type = buf[8] & 0x3;
+                if (pic_code_type == 1 || pic_code_type == 3) {
+                    s->pict_type = AV_PICTURE_TYPE_P;
+                } else {
+                    s->pict_type = AV_PICTURE_TYPE_B;
+                }
+            }
+        }
+    }
+}
+
+
+static int avs3_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+                      const uint8_t **poutbuf, int *poutbuf_size,
+                      const uint8_t *buf, int buf_size)
+{
+    ParseContext *pc = s->priv_data;
+    int next;
+
+    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES)  {
+        next = buf_size;
+    } else {
+        next = avs3_find_frame_end(pc, buf, buf_size);
+        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+            *poutbuf = NULL;
+            *poutbuf_size = 0;
+            return buf_size;
+        }
+    }
+
+    parse_avs3_nal_units(s, buf, buf_size, avctx);
+
+    *poutbuf = buf;
+    *poutbuf_size = buf_size;
+
+    return next;
+}
+
+AVCodecParser ff_avs3_parser = {
+    .codec_ids      = { AV_CODEC_ID_AVS3 },
+    .priv_data_size = sizeof(ParseContext),
+    .parser_parse   = avs3_parse,
+    .parser_close   = ff_parse_close,
+    .split          = ff_mpeg4video_split,
+};
diff --git a/libavcodec/avs3_parser.h b/libavcodec/avs3_parser.h
new file mode 100644
index 0000000000..afc6d235b9
--- /dev/null
+++ b/libavcodec/avs3_parser.h
@@ -0,0 +1,64 @@ 
+/*
+ * AVS3-P2/IEEE1857.10 video parser.
+ * Copyright (c) 2020 Zhenyu Wang <wangzhenyu@pkusz.edu.cn>
+ *                    Bingjie Han <hanbj@pkusz.edu.cn>
+ *                    Huiwen Ren  <hwrenx@gmail.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
+ */
+
+#ifndef AVCODEC_AVS3PARSER_H
+#define AVCODEC_AVS3PARSER_H
+
+#include "parser.h"
+
+#define AVS3_NAL_START_CODE          0x010000
+#define AVS3_SEQ_START_CODE          0xB0
+#define AVS3_SEQ_END_CODE            0xB1
+#define AVS3_USER_DATA_START_CODE    0xB2
+#define AVS3_INTRA_PIC_START_CODE    0xB3
+#define AVS3_UNDEF_START_CODE        0xB4
+#define AVS3_EXTENSION_START_CODE    0xB5
+#define AVS3_INTER_PIC_START_CODE    0xB6
+#define AVS3_VIDEO_EDIT_CODE         0xB7
+#define AVS3_FIRST_SLICE_START_CODE  0x00
+#define AVS3_PROFILE_BASELINE_MAIN   0x20
+#define AVS3_PROFILE_BASELINE_MAIN10 0x22
+
+#define ISPIC(x) ((x) == AVS3_INTRA_PIC_START_CODE || (x) == AVS3_INTER_PIC_START_CODE)
+#define ISUNIT(x) ((x) == AVS3_SEQ_START_CODE || ISPIC(x))
+
+static const AVRational avs3_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
+};
+
+#endif /* AVCODEC_AVS3PARSER_H */
diff --git a/libavcodec/parsers.c b/libavcodec/parsers.c
index 7d75cea830..aab1d5e3e5 100644
--- a/libavcodec/parsers.c
+++ b/libavcodec/parsers.c
@@ -28,6 +28,7 @@  extern AVCodecParser ff_ac3_parser;
 extern AVCodecParser ff_adx_parser;
 extern AVCodecParser ff_av1_parser;
 extern AVCodecParser ff_avs2_parser;
+extern AVCodecParser ff_avs3_parser;
 extern AVCodecParser ff_bmp_parser;
 extern AVCodecParser ff_cavsvideo_parser;
 extern AVCodecParser ff_cook_parser;