>On 08/12/2020 05:43, s...@jkqxz.net wrote:>Typo "paeser" in the title.>On >05/08/2020 17:18, hwr...@126.com wrote:>> From: hwren <hwr...@126.com>>> >> >Signed-off-by: hbj <ha...@pku.edu.cn>>> Signed-off-by: hwren ><hwr...@126.com>>> --->> libavcodec/Makefile | 1 +>> libavcodec/avs3_parser.c >| 184 +++++++++++++++++++++++++++++++++++++++>> libavcodec/parsers.c | 1 +>> 3 >files changed, 186 insertions(+)>> create mode 100644 >libavcodec/avs3_parser.c>> >> diff --git a/libavcodec/Makefile >b/libavcodec/Makefile>> index 5a6ea59715..f1512779be 100644>> --- >a/libavcodec/Makefile>> +++ b/libavcodec/Makefile>> @@ -1053,6 +1053,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..7a7f826c59>> --- /dev/null>> +++ >b/libavcodec/avs3_parser.c>> @@ -0,0 +1,184 @@>> +/*>> + * AVS3-P2/IEEE1857.10 >video parser.>> + * Copyright (c) 2020 Zhenyu Wang <wangzhe...@pkusz.edu.cn>>> >+ * Bingjie Han <ha...@pkusz.edu.cn>>> + * Huiwen Ren <hwr...@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 >"parser.h">> +>> +#define SLICE_MAX_START_CODE 0x000001af>> +>> +#define >ISPIC(x) ((x) == 0xB3 || (x) == 0xB6)>> +#define ISUNIT(x) ((x) == 0xB0 || >ISPIC(x))>Perhaps give the magic numbers here symbolic constants? (Sequence >header, etc.) Thanks, we will define the constants as bellow:#define AVS3_VIDEO_SEQ_START_CODE 0xB0#define AVS3_INTRA_PIC_START_CODE 0xB3#define AVS3_INTER_PIC_START_CODE 0xB6 >> +>> +static av_cold int avs3_find_frame_end(ParseContext *pc, const uint8_t >> *buf, int buf_size)>This function doesn't look cold. Sorry, the av_cold will be removed. >> +{>> + 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 unsigned int read_bits(const >> char** ppbuf, int *pidx, int bits)>> +{>> + const char* p = *ppbuf;>> + int >> idx = *pidx;>> + unsigned int val = 0;>> +>> + while (bits) {>> + bits--;>> >> + val = (val << 1) | (((*p) >> idx) & 0x1);>> + if (--idx < 0) {>> + idx = >> 7;>> + p++;>> + }>> + }>> +>> + *ppbuf = p;>> + *pidx = idx;>> +>> + return >> val;>> +}>> +>> +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] == 0xB0) {>> + static const int >> avs3_fps_num[9] = {0, 240000, 24, 25, 30000, 30, 50, 60000, 60 };>> + static >> const int avs3_fps_den[9] = {1, 1001, 1, 1, 1001, 1, 1, 1001, 1 };>Is this >> meant to be the MPEG-1 frame rate code table? (It looks the same other than >> num[1], which looks like a typo.) If so, there is a global >> ff_mpeg12_frame_rate_tab already containing the values. The AVS3 frame rate code table is not same to the MPEG-1, we will use the next table: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 }; >> + int profile,ratecode;>> + const char* p = buf + 4;>> + int idx = 7;>> +>> >> + s->key_frame = 1;>> + s->pict_type = AV_PICTURE_TYPE_I;>> +>> + profile = >> read_bits(&p, &idx, 8);>> + // level(8) + progressive(1) + field(1) + >> library(2) + resv(1) + width(14) + resv(1) + height(14) + chroma(2) + >> sampe_precision(3)>> + read_bits(&p, &idx, 47);>This ad-hoc reimplementation >> of get_bits does not seem like a good idea - it's reading one bit at a time >> and lacks any checks for overflow. Please just use get_bits(). Thanks for your advice, we will use get_bits() in the next version. >> +>> + if (profile == 0x22) {>> + avctx->pix_fmt = read_bits(&p, &idx, 3) == >> 1 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10LE;>> + }>Are other values of >> profile likely to be valid in future, requiring different parsing? Is it >> worth rejecting these here?>> +>> + // resv(1) + aspect(4)>> + read_bits(&p, >> &idx, 5);>> +>> + ratecode = read_bits(&p, &idx, 4);>> +>> + // resv(1) + >> bitrate_low(18) + resv(1) + bitrate_high(12)>> + read_bits(&p, &idx, 32);>> >> +>> + avctx->has_b_frames = !read_bits(&p, &idx, 1);>> +>> + >> avctx->framerate.num = avctx->time_base.den = avs3_fps_num[ratecode];>> + >> avctx->framerate.den = avctx->time_base.num = >> avs3_fps_den[ratecode];>ratecode isn't checked, so might overflow the array. ratecode is in range of [0, 15], it will not be overflowed for the new table avs3_frame_rate_tab. >> +>> + 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] == 0xB3) {>> + s->key_frame = 1;>> + s->pict_type = >> AV_PICTURE_TYPE_I;>> + } else if (buf[3] == 0xB6){>> + 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;>> + >> }>> + }>> + }>What happens if you don't get a sequence header before seeing >> some frames? Even if the sequence header is not got in the first several frames, it will be decoded again in the next decoding process in libuavs3d.c. >> + }>> +}>> +>> +>> +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/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;>> >- >> Mark>_______________________________________________>ffmpeg-devel mailing >> list>ffmpeg-devel@ffmpeg.org>https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>To >> unsubscribe, visit link above, or email>ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".