From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 116A143D0F for ; Mon, 8 Aug 2022 12:39:18 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2EBB168B744; Mon, 8 Aug 2022 15:39:16 +0300 (EEST) Received: from mailout2.w1.samsung.com (mailout2.w1.samsung.com [210.118.77.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A1D1568B6EB for ; Mon, 8 Aug 2022 15:39:09 +0300 (EEST) Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20220808123908euoutp02febae6db4998f69ba31fbf834a7bc7ef~JXvX1a3tY1716817168euoutp021 for ; Mon, 8 Aug 2022 12:39:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20220808123908euoutp02febae6db4998f69ba31fbf834a7bc7ef~JXvX1a3tY1716817168euoutp021 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1659962348; bh=2ScRz2byRufHfLMR3Crd4mhjwcUChTSQtN0AqLvS44w=; h=From:To:In-Reply-To:Subject:Date:References:From; b=tavmmmTBHl8aDqZuAzWBnHvHIWc7nEMHZcbs7DIo1Bpqk6fQXynf+d9P1AjhJw4qD 5gvKvRUAMun5UUmF3n5oDRHMQVurEy3opNScBbot57yNhBhFt7meVdakWth9IfNSz9 bclv0TMChJZIRfvbg97bB9Mug3otXPvtXMIrGuMU= Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20220808123907eucas1p1dcbe0f740b5e7dad7253c3879f87f27f~JXvXhd-Aa0068900689eucas1p1T for ; Mon, 8 Aug 2022 12:39:07 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id C8.A9.09580.BE301F26; Mon, 8 Aug 2022 13:39:07 +0100 (BST) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20220808123907eucas1p103a38b8d26bb38a1690790388e290a5c~JXvXB3UfA2013120131eucas1p1I for ; Mon, 8 Aug 2022 12:39:07 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20220808123907eusmtrp1112dbc17ab8949460a5e464b6de7b2ee~JXvXBRLBi3233432334eusmtrp1D for ; Mon, 8 Aug 2022 12:39:07 +0000 (GMT) X-AuditID: cbfec7f5-9adff7000000256c-d8-62f103eb56c1 Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 3D.27.09038.BE301F26; Mon, 8 Aug 2022 13:39:07 +0100 (BST) Received: from AMDN3260 (unknown [106.210.132.171]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20220808123907eusmtip29aee6ac10125dfdae95c2948887a853f~JXvWyOmLs0464804648eusmtip2v for ; Mon, 8 Aug 2022 12:39:06 +0000 (GMT) From: =?utf-8?Q?Dawid_Kozinski/Robot_SDK_=28PLT=29_/?= =?utf-8?Q?SRPOL/Staff_Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= To: "'FFmpeg development discussions and patches'" In-Reply-To: <0966ebb5-e4c9-7c1f-0023-a95f48c12ac4@gmail.com> Date: Mon, 8 Aug 2022 14:39:06 +0200 Message-ID: <011601d8ab23$d9a0d1b0$8ce27510$@samsung.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQKDEgguu0wJMq2x9k1s9cTE31uzDAJ9zcVXAreK34CsJndMIA== Content-Language: pl X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrJIsWRmVeSWpSXmKPExsWy7djPc7qvmT8mGfQe1LP49ukMswOjx59F m1kCGKO4bFJSczLLUov07RK4MhpX7WEvWLeJsWL/Ma8GxhW1XYycHBICJhKXJ89g6mLk4hAS WMEoMeXaVxYIZxKTxMbGM4wQzkQmiWk3LjHDtLz6NJUZIrGcUaJxxU2oqjYmiVcNEC1sAjMZ JeZ+XcMI0iIi4CPRvX49K4jNKWArsev/NyYQW1ggQ2L5pUVgNSwCKhJ3dv0Fs3kFLCUm31jB DGELSpyc+YQFxGYWkJfY/nYO1BkKEj+fLmOFmO8k8f7GfEaIGhGJG49aGCFqJnJITFpSAWG7 SLT0fWWFsIUlXh3fwg5hy0icntwDNJ8DyC6WONTvAGHWSBz6kQ5RYS3xtvE4I0iYWUBTYv0u fYiwo8T7FZegGvkkbrwVhNjPJzFp23RmiDCvREebEISpItHXKQbRKCXxdNkc5gmMSrOQPDgL yYOzkDwyC2HtAkaWVYziqaXFuempxcZ5qeV6xYm5xaV56XrJ+bmbGIGp4fS/4193MK549VHv ECMTB+MhRgkOZiUR3iNr3ycJ8aYkVlalFuXHF5XmpBYfYpTmYFES503O3JAoJJCeWJKanZpa kFoEk2Xi4JRqYPJSkww68FqlRfm409ewazGdU8xyr/poP61YE7rou/V6L8+Ui8J1vYZtHW8u vn/cEtW2M3Ce8Iv9hzY4zJ3HNaGpT+ySzea9u69vmLt0rbqzYUGzrNq1uHPFXqeEVu/LzEq+ +ODXG9tdD66y1nzp3mWn2/6jbW0wO3fWGs9f1ydv+C1za4qH6Zk2i8VZVuktmj8DhatTbfWX 99UsvHOHY3rX2TtTSiaEbt2k+dV/qdVl7qvxefUhMlX+mz2UWy0OfKqT0Xh89eslM2Hrhf3T avWUvR6/XDyz1d5D9doa6f73ArondkXUv7m+szghtUZ95efe1+s2v3yn4PD5nvuqR+s+/HnW zaitYpz88fW3815KLMUZiYZazEXFiQCSGwfQfAMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpkkeLIzCtJLcpLzFFi42I5/e/4Pd3XzB+TDM7f5rH49ukMswOjx59F m1kCGKP0bIryS0tSFTLyi0tslaINLYz0DC0t9IxMLPUMjc1jrYxMlfTtbFJSczLLUov07RL0 MhpX7WEvWLeJsWL/Ma8GxhW1XYycHBICJhKvPk1l7mLk4hASWMoocWR5FyNEQkpi6dJFULaw xJ9rXWwQRS1MEjvvLWABcdgEpjNKnDzYxwRSJSLgI9G9fj0rRNUeRon2fW/AEpwCthK7/n8D s4UF0iTObGlkBrFZBFQk7uz6C7aCV8BSYvKNFcwQtqDEyZlPWEBsZgFtiac3n0LZ8hLb385h hjhJQeLn02WsEIudJN7fmM8IUSMiceNRC+MERqFZSEbNQjJqFpJRs5C0LGBkWcUoklpanJue W2ykV5yYW1yal66XnJ+7iREYF9uO/dyyg3Hlq496hxiZOBgPMUpwMCuJ8B5Z+z5JiDclsbIq tSg/vqg0J7X4EKMp0G8TmaVEk/OBkZlXEm9oZmBqaGJmaWBqaWasJM7rWdCRKCSQnliSmp2a WpBaBNPHxMEp1cAkE89dc43N/lXYu1IOMac1ieor5+g1+6gy7Istuxs66ahZyekV/HobIg7V 3mefr75EWik25MolH+GuZZm/77PlrbifGerAppSWcM25d4K3jUunwtIVVXvWiJ9me8WT5frc TIb3Q/RXP60LSmayarsCAtp1OmvdfxkcFz72YL+832f/J+Ynmpom/+30+JJ3RfPGj9ffZl0U +vFD0Zh/7UnR1dfd0lifLHfdlfk+KO/Vyvbs3aKX+SZX/Oo2aMlM/iV/+qyEqdGnaypc7rnJ eRvz2qedjZtXsPvSvE11rwqUF/550XHx6bqkspDGqX3rkpj2n3185uO12phla7n9zE4YHmVP T3zkkL/85qP1gQeUWIozEg21mIuKEwEs5KedFAMAAA== X-CMS-MailID: 20220808123907eucas1p103a38b8d26bb38a1690790388e290a5c X-Msg-Generator: CA X-RootMTR: 20220801092858eucas1p2eb2d2732543be955865cc083ebf582b3 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20220801092858eucas1p2eb2d2732543be955865cc083ebf582b3 References: <001f01d8a589$20ad4ac0$6207e040$@samsung.com> <0966ebb5-e4c9-7c1f-0023-a95f48c12ac4@gmail.com> Subject: Re: [FFmpeg-devel] [PATCH 1/2] Provided support for MPEG-5 EVC (Essential Video Coding) codec X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: I've just submitted new patches that were made based on your requests and suggestions. Please find below my comments. -----Original Message----- From: ffmpeg-devel On Behalf Of James Almer Sent: Monday, August 1, 2022 2:29 PM To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH 1/2] Provided support for MPEG-5 EVC (Essential Video Coding) codec On 8/1/2022 6:28 AM, Dawid Kozinski wrote: > diff --git a/libavcodec/evc_parser.c b/libavcodec/evc_parser.c > new file mode 100644 > index 0000000000..b2136a6b45 > --- /dev/null > +++ b/libavcodec/evc_parser.c > @@ -0,0 +1,526 @@ > +/* > + * EVC format parser > + * > + * Copyright (C) 2021 Dawid Kozinski > + * > + * 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 > + > +#include "libavutil/common.h" > + > +#include "parser.h" > +#include "golomb.h" > + > +// The length field that indicates the length in bytes of the following NAL unit is configured to be of 4 bytes > +#define EVC_NAL_UNIT_LENGTH_BYTE (4) /* byte */ > + > +#define EVC_NAL_HEADER_SIZE (2) /* byte */ > +#define MAX_SPS_CNT (16) /* defined value in EVC standard */ > + > +// NALU types > +// @see ISO_IEC_23094-1_2020 7.4.2.2 NAL unit header semantics > +// > +#define EVC_NUT_NONIDR (0) /* Coded slice of a non-IDR picture */ > +#define EVC_NUT_IDR (1) /* Coded slice of an IDR picture */ > +#define EVC_NUT_SPS (24) /* Sequence parameter set */ > +#define EVC_NUT_PPS (25) /* Picture paremeter set */ > +#define EVC_NUT_APS (26) /* Adaptation parameter set */ > +#define EVC_NUT_FD (27) /* Filler data */ > +#define EVC_NUT_SEI (28) /* Supplemental enhancement information */ > + > +// The sturcture reflects SPS RBSP(raw byte sequence payload) layout > +// @see ISO_IEC_23094-1 section 7.3.2.1 > +// > +// The following descriptors specify the parsing process of each element > +// u(n) - unsigned integer using n bits > +// ue(v) - unsigned integer 0-th order Exp_Golomb-coded syntax element with the left bit first > +typedef struct EVCParserSPS { > + int sps_seq_parameter_set_id; // ue(v) > + int profile_idc; // u(8) > + int level_idc; // u(8) > + int toolset_idc_h; // u(32) > + int toolset_idc_l; // u(32) > + int chroma_format_idc; // ue(v) > + int pic_width_in_luma_samples; // ue(v) > + int pic_height_in_luma_samples; // ue(v) > + int bit_depth_luma_minus8; // ue(v) > + int bit_depth_chroma_minus8; // ue(v) > + > + int sps_btt_flag; // u(1) > + int log2_ctu_size_minus5; // ue(v) > + int log2_min_cb_size_minus2; // ue(v) > + int log2_diff_ctu_max_14_cb_size; // ue(v) > + int log2_diff_ctu_max_tt_cb_size; // ue(v) > + int log2_diff_min_cb_min_tt_cb_size_minus2; // ue(v) > + > + int sps_suco_flag; // u(1) > + int log2_diff_ctu_size_max_suco_cb_size; // ue(v) > + int log2_diff_max_suco_min_suco_cb_size; // ue(v) > + > + int sps_admvp_flag; // u(1) > + int sps_affine_flag; // u(1) > + int sps_amvr_flag; // u(1) > + int sps_dmvr_flag; // u(1) > + int sps_mmvd_flag; // u(1) > + int sps_hmvp_flag; // u(1) > + > + int sps_eipd_flag; // u(1) > + int sps_ibc_flag; // u(1) > + int log2_max_ibc_cand_size_minus2; // ue(v) > + > + int sps_cm_init_flag; // u(1) > + int sps_adcc_flag; // u(1) > + > + int sps_iqt_flag; // u(1) > + int sps_ats_flag; // u(1) > + > + int sps_addb_flag; // u(1) > + int sps_alf_flag; // u(1) > + int sps_htdf_flag; // u(1) > + int sps_rpl_flag; // u(1) > + int sps_pocs_flag; // u(1) > + int sps_dquant_flag; // u(1) > + int sps_dra_flag; // u(1) > + > + int log2_max_pic_order_cnt_lsb_minus4; // ue(v) > + int log2_sub_gop_length; // ue(v) > + int log2_ref_pic_gap_length; // ue(v) > + > + int max_num_tid0_ref_pics; // ue(v) > + > + int sps_max_dec_pic_buffering_minus1; // ue(v) > + int long_term_ref_pic_flag; // u(1) > + int rpl1_same_as_rpl0_flag; // u(1) > + int num_ref_pic_list_in_sps[2]; // ue(v) > + > + int picture_cropping_flag; // u(1) > + int picture_crop_left_offset; // ue(v) > + int picture_crop_right_offset; // ue(v) > + int picture_crop_top_offset; // ue(v) > + int picture_crop_bottom_offset; // ue(v) > + > +} EVCParserSPS; > + > +typedef struct EVCParserContext { > + ParseContext pc; > + EVCParserSPS sps[MAX_SPS_CNT]; > + int is_avc; > + int nal_length_size; > + int to_read; > + int incomplete_nalu_prefix_read; // The flag is set to 1 when an incomplete NAL unit prefix has been read > + > + int got_sps; > + int got_pps; > + int got_sei; > + int got_slice; > +} EVCParserContext; > + > +static int get_nalu_type(const uint8_t *bits, int bits_size, AVCodecContext *avctx) > +{ > + int unit_type_plus1 = 0; > + > + if(bits_size >= EVC_NAL_HEADER_SIZE) { > + unsigned char *p = (unsigned char *)bits; > + // forbidden_zero_bit > + if ((p[0] & 0x80) != 0) { > + av_log(avctx, AV_LOG_ERROR, "Cannot get bitstream information. Malformed bitstream.\n"); > + return -1; > + } > + > + // nal_unit_type > + unit_type_plus1 = (p[0] >> 1) & 0x3F; > + } > + > + return unit_type_plus1 - 1; > +} > + > +static uint32_t read_nal_unit_length(const uint8_t *bits, int bits_size, AVCodecContext *avctx) > +{ > + uint32_t nalu_len = 0; > + > + if(bits_size >= EVC_NAL_UNIT_LENGTH_BYTE) { > + > + int t = 0; > + unsigned char *p = (unsigned char *)bits; > + > + for(int i = 0; i < EVC_NAL_UNIT_LENGTH_BYTE; i++) > + t = (t << 8) | p[i]; > + > + nalu_len = t; > + if(nalu_len == 0) { > + av_log(avctx, AV_LOG_ERROR, "Invalid bitstream size!\n"); > + return 0; > + } > + } > + > + return nalu_len; > +} > + > +// @see ISO_IEC_23094-1 (7.3.2.1 SPS RBSP syntax) > +static EVCParserSPS *parse_sps(const uint8_t *bs, int bs_size, EVCParserContext *ev) > +{ > + GetBitContext gb; > + EVCParserSPS *sps; > + int sps_seq_parameter_set_id; > + > + if(init_get_bits8(&gb, bs, bs_size) < 0) > + return NULL; > + > + sps_seq_parameter_set_id = get_ue_golomb(&gb); > + > + if(sps_seq_parameter_set_id >= MAX_SPS_CNT) > + return NULL; > + > + sps = &ev->sps[sps_seq_parameter_set_id]; > + sps->sps_seq_parameter_set_id = sps_seq_parameter_set_id; > + > + // the Baseline profile is indicated by profile_idc eqal to 0 > + // the Main profile is indicated by profile_idc eqal to 1 > + sps->profile_idc = get_bits(&gb, 8); > + > + sps->level_idc = get_bits(&gb, 8); > + > + skip_bits_long(&gb, 32); /* skip toolset_idc_h */ > + skip_bits_long(&gb, 32); /* skip toolset_idc_l */ > + > + // 0 - monochrome > + // 1 - 4:2:0 > + // 2 - 4:2:2 > + // 3 - 4:4:4 > + sps->chroma_format_idc = get_ue_golomb(&gb); > + > + sps->pic_width_in_luma_samples = get_ue_golomb(&gb); > + sps->pic_height_in_luma_samples = get_ue_golomb(&gb); > + > + sps->bit_depth_luma_minus8 = get_ue_golomb(&gb); > + sps->bit_depth_chroma_minus8 = get_ue_golomb(&gb); > + > + sps->sps_btt_flag = get_bits(&gb, 1); > + if(sps->sps_btt_flag) { > + sps->log2_ctu_size_minus5 = get_ue_golomb(&gb); > + sps->log2_min_cb_size_minus2 = get_ue_golomb(&gb); > + sps->log2_diff_ctu_max_14_cb_size = get_ue_golomb(&gb); > + sps->log2_diff_ctu_max_tt_cb_size = get_ue_golomb(&gb); > + sps->log2_diff_min_cb_min_tt_cb_size_minus2 = get_ue_golomb(&gb); > + } > + > + sps->sps_suco_flag = get_bits(&gb, 1); > + if(sps->sps_suco_flag) { > + sps->log2_diff_ctu_size_max_suco_cb_size = get_ue_golomb(&gb); > + sps->log2_diff_max_suco_min_suco_cb_size = get_ue_golomb(&gb); > + } > + > + sps->sps_admvp_flag = get_bits(&gb, 1); > + if(sps->sps_admvp_flag) { > + sps->sps_affine_flag = get_bits(&gb, 1); > + sps->sps_amvr_flag = get_bits(&gb, 1); > + sps->sps_dmvr_flag = get_bits(&gb, 1); > + sps->sps_mmvd_flag = get_bits(&gb, 1); > + sps->sps_hmvp_flag = get_bits(&gb, 1); > + } > + > + sps->sps_eipd_flag = get_bits(&gb, 1); > + if(sps->sps_eipd_flag) { > + sps->sps_ibc_flag = get_bits(&gb, 1); > + if(sps->sps_ibc_flag) > + sps->log2_max_ibc_cand_size_minus2 = get_ue_golomb(&gb); > + } > + > + sps->sps_cm_init_flag = get_bits(&gb, 1); > + if(sps->sps_cm_init_flag) > + sps->sps_adcc_flag = get_bits(&gb, 1); > + > + sps->sps_iqt_flag = get_bits(&gb, 1); > + if(sps->sps_iqt_flag) > + sps->sps_ats_flag = get_bits(&gb, 1); > + > + sps->sps_addb_flag = get_bits(&gb, 1); > + sps->sps_alf_flag = get_bits(&gb, 1); > + sps->sps_htdf_flag = get_bits(&gb, 1); > + sps->sps_rpl_flag = get_bits(&gb, 1); > + sps->sps_pocs_flag = get_bits(&gb, 1); > + sps->sps_dquant_flag = get_bits(&gb, 1); > + sps->sps_dra_flag = get_bits(&gb, 1); > + > + if(sps->sps_pocs_flag) > + sps->log2_max_pic_order_cnt_lsb_minus4 = get_ue_golomb(&gb); > + > + if(!sps->sps_pocs_flag || !sps->sps_rpl_flag) { > + sps->log2_sub_gop_length = get_ue_golomb(&gb); > + if(sps->log2_sub_gop_length == 0) > + sps->log2_ref_pic_gap_length = get_ue_golomb(&gb); > + } > + > + return sps; > +} > + > +static int parse_nal_units(AVCodecParserContext *s, const uint8_t *bs, > + int bs_size, AVCodecContext *avctx) > +{ > + EVCParserContext *ev = s->priv_data; > + int nalu_type, nalu_size; > + unsigned char *bits = (unsigned char *)bs; > + int bits_size = bs_size; > + > + avctx->codec_id = AV_CODEC_ID_EVC; > + > + nalu_size = read_nal_unit_length(bits, bits_size, avctx); > + if(nalu_size == 0) { > + av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit size: (%d)\n", nalu_size); > + return -1; > + } > + > + bits += EVC_NAL_UNIT_LENGTH_BYTE; > + bits_size -= EVC_NAL_UNIT_LENGTH_BYTE; > + > + nalu_type = get_nalu_type(bits, bits_size, avctx); > + > + bits += EVC_NAL_HEADER_SIZE; > + bits_size -= EVC_NAL_HEADER_SIZE; > + > + if (nalu_type == EVC_NUT_SPS) { // NAL Unit type: SPS (Sequence Parameter Set) > + EVCParserSPS *sps; > + > + sps = parse_sps(bits, bits_size, ev); > + > + avctx->coded_width = sps->pic_width_in_luma_samples; > + avctx->coded_height = sps->pic_height_in_luma_samples; > + avctx->width = sps->pic_width_in_luma_samples; > + avctx->height = sps->pic_height_in_luma_samples; These should be set in the AVCodecParserContext, not the AVCodecContext. #################### DONE #################### > + > + if(sps->profile_idc == 0) avctx->profile = FF_PROFILE_EVC_BASELINE; > + else if (sps->profile_idc == 1) avctx->profile = FF_PROFILE_EVC_MAIN; Setting these two is ok. > + else { > + av_log(avctx, AV_LOG_ERROR, "Not supported profile (%d)\n", sps->profile_idc); > + return -1; Do you really need to abort here? Not recognizing the profile can't possibly mean the bitstream can't be parsed further to fetch other information. #################### DONE #################### > + } > + > + // Currently XEVD decoder supports ony YCBCR420_10LE chroma format for EVC stream > + switch(sps->chroma_format_idc) { > + case 0: /* YCBCR400_10LE */ > + av_log(avctx, AV_LOG_ERROR, "YCBCR400_10LE: Not supported chroma format\n"); > + avctx->pix_fmt = AV_PIX_FMT_GRAY10LE; > + return -1; > + case 1: /* YCBCR420_10LE */ > + avctx->pix_fmt = AV_PIX_FMT_YUV420P10LE; > + break; > + case 2: /* YCBCR422_10LE */ > + av_log(avctx, AV_LOG_ERROR, "YCBCR422_10LE: Not supported chroma format\n"); > + avctx->pix_fmt = AV_PIX_FMT_YUV422P10LE; > + return -1; > + case 3: /* YCBCR444_10LE */ > + av_log(avctx, AV_LOG_ERROR, "YCBCR444_10LE: Not supported chroma format\n"); > + avctx->pix_fmt = AV_PIX_FMT_YUV444P10LE; > + return -1; > + default: > + avctx->pix_fmt = AV_PIX_FMT_NONE; Fill s->format instead of avctx->pix_fmt. #################### DONE #################### > + av_log(avctx, AV_LOG_ERROR, "Unknown supported chroma format\n"); > + return -1; > + } > + > + // The current implementation of parse_sps function doesn't handle VUI parameters parsing, > + // so at the moment it's impossible to initialize has_b_frames and max_b_frames AVCodecContex fields here. > + // Currently, initialization of has_b_frames and max_b_frames AVCodecContex fields have been moved to > + // libxevd_decode function where we can use xevd_config function being a part of xevd library API > + // to get the needed information. > + // However, if it will be needed, parse_sps function should be extended to handle VUI parameters parsing > + // and the following lines should be used to initialize has_b_frames and max_b_frames fields of the AVCodecContex. There's no need no fill any of those field in this parser. What you can fill is avctx->color{space,_primaries,_trc,_range}, so mention that to add VUI parsing at some point. > + // > + // sps->vui_parameters.num_reorder_pics > + // if (sps->bitstream_restriction_flag && sps->vui_parameters.num_reorder_pics) { > + // avctx->has_b_frames = sps->vui_parameters.num_reorder_pics; > + // } > + > + ev->got_sps = 1; > + > + } else if (nalu_type == EVC_NUT_PPS) // NAL Unit type: PPS (Video Parameter Set) > + ev->got_pps = 1; > + else if(nalu_type == EVC_NUT_SEI) // NAL unit type: SEI (Supplemental Enhancement Information) > + ev->got_sei = 1; These got_* variables seem to be write only. #################### DONE #################### > + else if (nalu_type == EVC_NUT_IDR || nalu_type == EVC_NUT_NONIDR) // NAL Unit type: Coded slice of a IDR or non-IDR picture In here you should parse enough data to get the picture type (I, P, B) and set s->pict_type, and based on (i suppose) nalu_type, also set s->key_frame to 1 or 0. #################### DONE #################### At the start of this function, you'd ideally set them to AV_PICTURE_TYPE_NONE and -1 respectively, as "safe" defaults. #################### DONE #################### s->picture_structure should also be always set to AV_PICTURE_STRUCTURE_FRAME, as i assume this codec does not support interlacing. #################### DONE #################### > + ev->got_slice++; > + else { > + av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit type: %d\n", nalu_type); > + return -1; > + } > + > + return 0; > +} > + > +/** > + * Find the end of the current frame in the bitstream. > + * @return the position of the first byte of the next frame, or END_NOT_FOUND > + */ > +static int evc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, > + int buf_size, AVCodecContext *avctx) > +{ > + EVCParserContext *ev = s->priv_data; > + > + if(!ev->to_read) { > + int nal_unit_size = 0; > + int next = END_NOT_FOUND; > + > + // This is the case when buffer size is not enough for buffer to store NAL unit length > + if(buf_size < EVC_NAL_UNIT_LENGTH_BYTE) { > + ev->to_read = EVC_NAL_UNIT_LENGTH_BYTE; > + ev->nal_length_size = buf_size; > + ev->incomplete_nalu_prefix_read = 1; > + > + return END_NOT_FOUND; > + } > + > + nal_unit_size = read_nal_unit_length(buf, buf_size, avctx); > + ev->nal_length_size = EVC_NAL_UNIT_LENGTH_BYTE; > + > + next = nal_unit_size + EVC_NAL_UNIT_LENGTH_BYTE; > + ev->to_read = next; > + if(next < buf_size) > + return next; > + else > + return END_NOT_FOUND; > + } else if(ev->to_read > buf_size) > + return END_NOT_FOUND; > + else { > + if(ev->incomplete_nalu_prefix_read == 1) { > + EVCParserContext *ev = s->priv_data; > + ParseContext *pc = &ev->pc; > + uint8_t nalu_len[EVC_NAL_UNIT_LENGTH_BYTE] = {0}; > + int nal_unit_size = 0; > + > + // 1. pc->buffer contains previously read bytes of NALU prefix > + // 2. buf contains the rest of NAL unit prefix bytes > + // > + // ~~~~~~~ > + // EXAMPLE > + // ~~~~~~~ > + // > + // In the following example we assumed that the number of already read NAL Unit prefix bytes is equal 1 > + // > + // ---------- > + // pc->buffer -> conatins already read bytes > + // ---------- > + // __ pc->index == 1 > + // | > + // V > + // ------------------------------------------------------- > + // | 0 | 1 | 2 | 3 | 4 | ... | N | > + // ------------------------------------------------------- > + // | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX | ... | 0xXX | > + // ------------------------------------------------------- > + // > + // ---------- > + // buf -> contains newly read bytes > + // ---------- > + // ------------------------------------------------------- > + // | 0 | 1 | 2 | 3 | 4 | ... | N | > + // ------------------------------------------------------- > + // | 0x00 | 0x00 | 0x3C | 0xXX | 0xXX | ... | 0xXX | > + // ------------------------------------------------------- > + // > + for(int i = 0; i < EVC_NAL_UNIT_LENGTH_BYTE; i++) { > + if(i < pc->index) > + nalu_len[i] = pc->buffer[i]; > + else > + nalu_len[i] = buf[i - pc->index]; > + } > + > + // ---------- > + // nalu_len > + // ---------- > + // --------------------------------- > + // | 0 | 1 | 2 | 3 | > + // --------------------------------- > + // | 0x00 | 0x00 | 0x00 | 0x3C | > + // --------------------------------- > + // | NALU LENGTH | > + // --------------------------------- > + // NAL Unit lenght = 60 (0x0000003C) > + > + nal_unit_size = read_nal_unit_length(nalu_len, EVC_NAL_UNIT_LENGTH_BYTE, avctx); > + > + ev->to_read = nal_unit_size + EVC_NAL_UNIT_LENGTH_BYTE - pc->index; > + > + ev->incomplete_nalu_prefix_read = 0; > + > + if(ev->to_read > buf_size) > + return END_NOT_FOUND; > + else > + return ev->to_read; > + } > + return ev->to_read; > + } > + > + return END_NOT_FOUND; > +} > + > +static int evc_parser_init(AVCodecParserContext *s) > +{ > + EVCParserContext *ev = s->priv_data; > + > + ev->got_sps = 0; > + ev->got_pps = 0; > + ev->got_sei = 0; > + ev->got_slice = 0; > + ev->nal_length_size = EVC_NAL_UNIT_LENGTH_BYTE; > + ev->incomplete_nalu_prefix_read = 0; > + > + return 0; > +} > + > +static int evc_parse(AVCodecParserContext *s, AVCodecContext *avctx, > + const uint8_t **poutbuf, int *poutbuf_size, > + const uint8_t *buf, int buf_size) > +{ > + int next; > + EVCParserContext *ev = s->priv_data; > + ParseContext *pc = &ev->pc; > + int is_dummy_buf = !buf_size; > + const uint8_t *dummy_buf = buf; > + > + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) > + next = buf_size; > + else { > + next = evc_find_frame_end(s, buf, buf_size, avctx); > + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { > + *poutbuf = NULL; > + *poutbuf_size = 0; > + ev->to_read -= buf_size; > + return buf_size; > + } > + } > + > + is_dummy_buf &= (dummy_buf == buf); > + > + if (!is_dummy_buf) > + parse_nal_units(s, buf, buf_size, avctx); > + > + *poutbuf = buf; > + *poutbuf_size = buf_size; > + ev->to_read -= next; > + > + return next; > +} > + > +const AVCodecParser ff_evc_parser = { > + .codec_ids = { AV_CODEC_ID_EVC }, > + .priv_data_size = sizeof(EVCParserContext), > + .parser_init = evc_parser_init, > + .parser_parse = evc_parse, > + .parser_close = ff_parse_close, > +}; _______________________________________________ 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".