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 1AE7643D12 for ; Mon, 8 Aug 2022 12:45:08 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CC5FF68A417; Mon, 8 Aug 2022 15:45:05 +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 268C868B44E for ; Mon, 8 Aug 2022 15:44:58 +0300 (EEST) Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20220808124457euoutp02afd6cf7fe7f5a094f7b9355e759d715d~JX0dXrQZ92269822698euoutp023 for ; Mon, 8 Aug 2022 12:44:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20220808124457euoutp02afd6cf7fe7f5a094f7b9355e759d715d~JX0dXrQZ92269822698euoutp023 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1659962697; bh=OmBt4XrkLiuZDS+5xzlD/YfrG3GbPV3B/qkvqDKahIU=; h=From:To:In-Reply-To:Subject:Date:References:From; b=X7RIz0srk2kBmONxbFK77RzhQDXyGXqEub8vCBuej76VbC2duESn46qY347KCu9fc KMhb7SFw45UHXMdqpalEViUDLrd2Tkpk15PCAk/VhmKzycLuiV7JEWyxoAsIBNaHWl jd5Va1Z6+nShPfKOQ2WYQnrEo2PK9j2fsWL7hn40= Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20220808124457eucas1p110981a068efd40180883760cf5b7edb9~JX0dBRu5V3077430774eucas1p1y for ; Mon, 8 Aug 2022 12:44:57 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id C5.2E.10067.94501F26; Mon, 8 Aug 2022 13:44:57 +0100 (BST) Received: from eusmtrp2.samsung.com (unknown [182.198.249.139]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20220808124456eucas1p22a2c6f8c36b4d358665154420dcf7c5a~JX0crg0vH1549715497eucas1p2n for ; Mon, 8 Aug 2022 12:44:56 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp2.samsung.com (KnoxPortal) with ESMTP id 20220808124456eusmtrp23d1a1281abe83c307f4e5b60d909b9c0~JX0cq9JGN3004930049eusmtrp2O for ; Mon, 8 Aug 2022 12:44:56 +0000 (GMT) X-AuditID: cbfec7f4-dc1ff70000002753-bf-62f105494e0e Received: from eusmtip1.samsung.com ( [203.254.199.221]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 73.38.09038.84501F26; Mon, 8 Aug 2022 13:44:56 +0100 (BST) Received: from AMDN3260 (unknown [106.210.132.171]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20220808124456eusmtip1c8f4b5d724e222096c3dfff4d80ae2ef~JX0cY-JD01911119111eusmtip1_ for ; Mon, 8 Aug 2022 12:44:56 +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: Date: Mon, 8 Aug 2022 14:44:56 +0200 Message-ID: <011701d8ab24$aa044ad0$fe0ce070$@samsung.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQKDEgguu0wJMq2x9k1s9cTE31uzDAJ9zcVXAfIVRgSsLKSsIA== Content-Language: pl X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrGIsWRmVeSWpSXmKPExsWy7djPc7qerB+TDM6f4LP49ukMswOjx59F m1kCGKO4bFJSczLLUov07RK4Mo52axV8WsJYsfdGcgPjpKouRk4OCQETif2TvjB1MXJxCAms YJR41LmQFSQhJDCJSWLZAhuIxEQmiTUPZjHDdOzYdYcRIrGcUeLf113MEB1tTBK3LheAJNgE ZjJKzP26hhEkISLgI9G9fj3YWE4BW4m3D1+xgNjCAhkSyy8tAqthEVCRWLPrLlgNr4ClxLvL b9ghbEGJkzOfgNUzC2hLLFv4GuoKBYmfT5exQsx3kpi/ch5UjYjEjUctjBA1EzkketqrIWwX iSlT7zNB2MISr45vYYewZST+75wPFOcAsoslDvU7QJg1Eod+pENUWEu8bTzOCBJmFtCUWL9L HyLsKPF+xSUWiGo+iRtvBSH280lM2jadGSLMK9HRJgRhqkj0dYpBNEpJPF02h3kCo9IsJA/O QvLgLCSPzEJYu4CRZRWjeGppcW56arFRXmq5XnFibnFpXrpecn7uJkZgUjj97/iXHYzLX33U O8TIxMF4iFGCg1lJhPfI2vdJQrwpiZVVqUX58UWlOanFhxilOViUxHmTMzckCgmkJ5akZqem FqQWwWSZODilGpg4Lq6f58yTxHT/u4Xu07gvYdovn4fkLN9WdaEhSdDB4pCChafIm6aodaJ7 3l71Td0e0ybnp3k+xVqg9GBI84yeD+0cfU533wmXlTm4NfTP+DN/0m0OuxdOSw+FnFlavsCe 4WqWhXv09zQHx+Anvyfv63t5b4fXn6eXvJbe39D2zD7upxZXaMBGKxa9jz2fjr57zGopdLsg 7EaWUO77bsWmHbGHWubMMH2xUO7z7Va51sMRKa4XXujP/tPnuPwFd7991ErGY5ZMpseUtSpZ ltxJjMu8mfTFkj/FdIum49rFNi9awu9yLc+vurL2+98ZLtfDT9gbhi+ZJmuxcY6AE/dz/Rpz ZutermeGK9qEHiuxFGckGmoxFxUnAgA5TRfAeQMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpikeLIzCtJLcpLzFFi42I5/e/4XV0P1o9JBj9vGll8+3SG2YHR48+i zSwBjFF6NkX5pSWpChn5xSW2StGGFkZ6hpYWekYmlnqGxuaxVkamSvp2NimpOZllqUX6dgl6 GZsvLmEvuDqTseL+jieMDYwf8roYOTkkBEwkduy6w9jFyMUhJLCUUeLa7N+sEAkpiaVLFzFC 2MISf651sUEUtTBJzJz/nRnEYROYzihx8mAfE0iViICPRPf69awQVXsYJXrOz2MBSXAK2Eq8 ffgKzBYWSJM4s6WRGcRmEVCRWLPrLtg6XgFLiXeX37BD2IISJ2c+AatnFtCWeHrzKZy9bOFr ZoiTFCR+Pl3GCrHYSWL+ynlQNSISNx61ME5gFJqFZNQsJKNmIRk1C0nLAkaWVYwiqaXFuem5 xUZ6xYm5xaV56XrJ+bmbGIGRse3Yzy07GFe++qh3iJGJg/EQowQHs5II75G175OEeFMSK6tS i/Lji0pzUosPMZoC/TaRWUo0OR8Ym3kl8YZmBqaGJmaWBqaWZsZK4ryeBR2JQgLpiSWp2amp BalFMH1MHJxSDUxxLxuXb1y6vZ9/04sclgkn1hdv/LG70vtV/Zq0uVaf3RYeelnJI7gw0lP2 6SE+y1vbzMI7z/k+XVo77eZ2HpHApOT3Z3mv9m/PWNjB+Yvzsc/LVd9rM3ZMC0nSPl+xs6vt UvzJ4oI4h62hd5dsKr3/KN+3fZ2B7Hq1+9Jyl1MU1xvYXZL5/vFB56kLzIffzeHkOcP07sbq 6D/P7/r5fOhtnRnC9vDnqquOUceznupPCrkzZb9g1exU6dbs8sV6L/bF3zE43zPdQmtV07Z6 Wc2yJk+uHX811+5d+mdFqvTu4yFinKVZa6uOmEzbNUPB5vPiBBkZrqILO6serP8WEBDs9Kaw dnncCsvVDxMfza1pV2Ipzkg01GIuKk4EAJXiP+AVAwAA X-CMS-MailID: 20220808124456eucas1p22a2c6f8c36b4d358665154420dcf7c5a X-Msg-Generator: CA X-RootMTR: 20220801092858eucas1p2eb2d2732543be955865cc083ebf582b3 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20220801092858eucas1p2eb2d2732543be955865cc083ebf582b3 References: <001f01d8a589$20ad4ac0$6207e040$@samsung.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 just uploaded 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 5:09 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/libxevd.c b/libavcodec/libxevd.c > new file mode 100644 > index 0000000000..8ba2d89cbd > --- /dev/null > +++ b/libavcodec/libxevd.c > @@ -0,0 +1,436 @@ > +/* > + * libxevd decoder > + * EVC (MPEG-5 Essential Video Coding) decoding using XEVD MPEG-5 EVC decoder library > + * > + * 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 > + > +#include > + > +#include "libavutil/internal.h" > +#include "libavutil/common.h" > +#include "libavutil/opt.h" > +#include "libavutil/pixdesc.h" > +#include "libavutil/pixfmt.h" > +#include "libavutil/imgutils.h" > +#include "libavutil/cpu.h" > + > +#include "avcodec.h" > +#include "internal.h" > +#include "packet_internal.h" > +#include "codec_internal.h" > + > +#define XEVD_PARAM_BAD_NAME -1 > +#define XEVD_PARAM_BAD_VALUE -2 > + > +#define EVC_NAL_HEADER_SIZE 2 /* byte */ > + > +/** > + * The structure stores all the states associated with the instance of Xeve MPEG-5 EVC decoder > + */ > +typedef struct XevdContext { > + const AVClass *class; > + > + XEVD id; // XEVD instance identifier @see xevd.h > + XEVD_CDSC cdsc; // decoding parameters @see xevd.h > + > + int decod_frames; // number of decoded frames > + int packet_count; // number of packets created by decoder > +} XevdContext; > + > +/** > + * The function returns a pointer to a variable of type XEVD_CDSC. This doesn't seem to be the case. #################### DONE #################### > + * XEVD_CDSC contains all decoder parameters that should be initialized before its use. > + * > + * The field values of the XEVD_CDSC structure are populated based on: > + * - the corresponding field values of the AvCodecConetxt structure, > + * - the xevd decoder specific option values, > + * (the full list of options available for the xevd encoder is displayed after executing the command ./ffmpeg --help decoder = libxevd) > + * - and the xevd encoder options specified as a list of key-value pairs following the xevd-params option > + * > + * Order of input processing and populating the XEVD_CDSC structure > + * 1. first, the corresponding fields of the AVCodecContext structure are processed, (i.e -threads 4) > + * 2. then xevd-specific options are added as AVOption to the xevd AVCodec implementation (i.e -threads 3) > + * 3. finally, the options specified after the xevd-params option as the parameter list of type key value are processed (i.e -xevd-params "m=2") I don't see a xevd-params option. #################### DONE #################### > + * > + * Some options can be set in different ways. In this case, please follow the above-mentioned order of processing. > + * The most recent assignments overwrite the previous values. > + * > + * @param[in] avctx codec context > + * @param[out] cdsc contains all encoder parameters that should be initialized before its use > + * > + * @return 0 on success, negative error code on failure I don't see a failure path below, so might as well just make this a void function. #################### DONE #################### > + */ > +static int get_conf(AVCodecContext *avctx, XEVD_CDSC *cdsc) > +{ > + int cpu_count = av_cpu_count(); > + > + /* clear XEVS_CDSC structure */ > + memset(cdsc, 0, sizeof(XEVD_CDSC)); > + > + /* init XEVD_CDSC */ > + if (avctx->thread_count <= 0) > + cdsc->threads = (cpu_count < XEVD_MAX_TASK_CNT) ? cpu_count : XEVD_MAX_TASK_CNT; > + else if (avctx->thread_count > XEVD_MAX_TASK_CNT) > + cdsc->threads = XEVD_MAX_TASK_CNT; > + else > + cdsc->threads = avctx->thread_count; > + > + return 0; > +} > + > +/** > + * Read NAL unit length > + * @param bs input data (bitstream) > + * @return the length of NAL unit on success, 0 value on failure > + */ > +static uint32_t read_nal_unit_length(const uint8_t *bs, int bs_size, AVCodecContext *avctx) > +{ > + uint32_t len = 0; > + XEVD_INFO info; > + int ret; > + > + if (bs_size == XEVD_NAL_UNIT_LENGTH_BYTE) { > + ret = xevd_info((void *)bs, XEVD_NAL_UNIT_LENGTH_BYTE, 1, &info); > + if (XEVD_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "Cannot get bitstream information\n"); > + return 0; > + } > + len = info.nalu_len; > + if (len == 0) { > + av_log(avctx, AV_LOG_ERROR, "Invalid bitstream size! [%d]\n", bs_size); > + return 0; > + } > + } > + > + return len; > +} > + > +/** > + * @param[in] xectx the structure that stores all the state associated with the instance of Xeve MPEG-5 EVC decoder > + * @param[out] avctx codec context > + * @return 0 on success, negative value on failure > + */ > +static int export_stream_params(const XevdContext *xectx, AVCodecContext *avctx) > +{ > + int ret; > + int size; > + int color_space; > + > + avctx->pix_fmt = AV_PIX_FMT_YUV420P10; > + > + size = 4; > + ret = xevd_config(xectx->id, XEVD_CFG_GET_CODED_WIDTH, &avctx->coded_width, &size); > + if (XEVD_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to get coded_width\n"); > + return AVERROR_EXTERNAL; > + } > + > + ret = xevd_config(xectx->id, XEVD_CFG_GET_CODED_HEIGHT, &avctx->coded_height, &size); > + if (XEVD_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to get coded_height\n"); > + return AVERROR_EXTERNAL; > + } > + > + ret = xevd_config(xectx->id, XEVD_CFG_GET_WIDTH, &avctx->width, &size); > + if (XEVD_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to get width\n"); > + return AVERROR_EXTERNAL; > + } > + > + ret = xevd_config(xectx->id, XEVD_CFG_GET_HEIGHT, &avctx->height, &size); > + if (XEVD_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to get height\n"); > + return AVERROR_EXTERNAL; > + } > + > + ret = xevd_config(xectx->id, XEVD_CFG_GET_COLOR_SPACE, &color_space, &size); > + if (XEVD_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to get color_space\n"); > + return AVERROR_EXTERNAL; > + } > + switch(color_space) { > + case XEVD_CS_YCBCR400_10LE: > + avctx->pix_fmt = AV_PIX_FMT_GRAY10LE; > + break; > + case XEVD_CS_YCBCR420_10LE: > + avctx->pix_fmt = AV_PIX_FMT_YUV420P10LE; > + break; > + case XEVD_CS_YCBCR422_10LE: > + avctx->pix_fmt = AV_PIX_FMT_YUV422P10LE; > + break; > + case XEVD_CS_YCBCR444_10LE: > + avctx->pix_fmt = AV_PIX_FMT_YUV444P10LE; > + break; > + default: > + av_log(avctx, AV_LOG_ERROR, "Unknown color space\n"); > + avctx->pix_fmt = AV_PIX_FMT_NONE; > + return AVERROR_INVALIDDATA; > + } > + > + // the function returns sps->num_reorder_pics > + ret = xevd_config(xectx->id, XEVD_CFG_GET_MAX_CODING_DELAY, &avctx->max_b_frames, &size); > + if (XEVD_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to get max_coding_delay\n"); > + return AVERROR_EXTERNAL; > + } > + > + avctx->has_b_frames = (avctx->max_b_frames) ? 1 : 0; > + > + avctx->color_primaries = AVCOL_PRI_UNSPECIFIED; > + avctx->color_trc = AVCOL_TRC_UNSPECIFIED; > + avctx->colorspace = AVCOL_SPC_UNSPECIFIED; > + > + return 0; > +} > + > +/** > + * Initialize decoder > + * Create a decoder instance and allocate all the needed resources > + * > + * @param avctx codec context > + * @return 0 on success, negative error code on failure > + */ > +static av_cold int libxevd_init(AVCodecContext *avctx) > +{ > + XevdContext *xectx = avctx->priv_data; > + int ret = 0; > + XEVD_CDSC *cdsc = &(xectx->cdsc); > + > + /* read configurations and set values for created descriptor (XEVD_CDSC) */ > + ret = get_conf(avctx, cdsc); > + if (ret != 0) { > + av_log(avctx, AV_LOG_ERROR, "Cannot get configuration\n"); > + return AVERROR_INVALIDDATA; > + } > + > + /* create decoder */ > + xectx->id = xevd_create(&(xectx->cdsc), NULL); > + if (xectx->id == NULL) { > + av_log(avctx, AV_LOG_ERROR, "Cannot create XEVD encoder\n"); > + return AVERROR_EXTERNAL; > + } > + > + xectx->packet_count = 0; > + xectx->decod_frames = 0; > + > + return 0; > +} > + > +/** > + * Decode picture > + * > + * @param avctx codec context > + * @param[out] frame decoded frame > + * @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that a > + * non-empty frame or subtitle was returned in > + * outdata. > + * @param[in] avpkt AVPacket containing encoded data to be decoded > + * > + * @return amount of bytes read from the packet on success, negative error > + * code on failure > + */ > +static int libxevd_decode(struct AVCodecContext *avctx, struct AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) > +{ > + XevdContext *xectx = NULL; > + XEVD_IMGB *imgb = NULL; > + XEVD_STAT stat; > + XEVD_BITB bitb; > + int xevd_ret, nalu_size, bs_read_pos; > + int ret = 0; > + > + if (avctx == NULL) { > + av_log(avctx, AV_LOG_ERROR, "Invalid input parameter: AVCodecContext\n"); > + return AVERROR(EINVAL); > + } > + xectx = avctx->priv_data; > + if (xectx == NULL) { > + av_log(avctx, AV_LOG_ERROR, "Invalid XEVD context\n"); > + return AVERROR(EINVAL); This can't happen, just remove the check. #################### DONE #################### > + } > + > + if (avpkt->size > 0) { > + bs_read_pos = 0; > + imgb = NULL; > + while(avpkt->size > (bs_read_pos + XEVD_NAL_UNIT_LENGTH_BYTE)) { > + > + memset(&stat, 0, sizeof(XEVD_STAT)); > + memset(&bitb, 0, sizeof(XEVD_BITB)); > + > + nalu_size = read_nal_unit_length(avpkt->data + bs_read_pos, XEVD_NAL_UNIT_LENGTH_BYTE, avctx); > + if (nalu_size == 0) { > + av_log(avctx, AV_LOG_ERROR, "Invalid bitstream\n"); > + ret = AVERROR_INVALIDDATA; > + goto ERR; > + } > + bs_read_pos += XEVD_NAL_UNIT_LENGTH_BYTE; > + > + bitb.addr = avpkt->data + bs_read_pos; > + bitb.ssize = nalu_size; > + > + /* main decoding block */ > + xevd_ret = xevd_decode(xectx->id, &bitb, &stat); > + if (XEVD_FAILED(xevd_ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to decode bitstream\n"); > + ret = AVERROR_EXTERNAL; > + goto ERR; > + } > + > + bs_read_pos += nalu_size; > + > + if (stat.nalu_type == XEVD_NUT_SPS) { // EVC stream parameters changed > + if ((ret = export_stream_params(xectx, avctx)) != 0) > + goto ERR; > + } > + > + if (stat.read != nalu_size) > + av_log(avctx, AV_LOG_INFO, "Different reading of bitstream (in:%d,read:%d)\n,", nalu_size, stat.read); > + if (stat.fnum >= 0) { > + // already has a decoded image > + if (imgb) { > + // xevd_pull uses pool of objects of type XEVD_IMGB. > + // The pool size is equal MAX_PB_SIZE (26), so release object when it is no more needed > + imgb->release(imgb); > + imgb = NULL; > + } > + xevd_ret = xevd_pull(xectx->id, &imgb); > + if (XEVD_FAILED(xevd_ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to pull the decoded image (xevd error code: %d, frame#=%d)\n", xevd_ret, stat.fnum); > + ret = AVERROR_EXTERNAL; > + goto ERR; > + } else if (xevd_ret == XEVD_OK_FRM_DELAYED) { > + if (imgb) { > + // xevd_pull uses pool of objects of type XEVD_IMGB. > + // The pool size is equal MAX_PB_SIZE (26), so release object when it is no more needed > + imgb->release(imgb); > + imgb = NULL; > + } > + } So if the packet has more than one frame, you'll drop the oldest? #################### DONE #################### Maybe you should write this decoder using the decouple Input/Output API, FF_CODEC_RECEIVE_FRAME_CB() callback instead of FF_CODEC_DECODE_CB(). With it, you can request a packet as needed with ff_decode_get_packet(), so for example only when libxevd has run out of frames to output you actually request another. > + } > + } > + } else { // bumping > + xevd_ret = xevd_pull(xectx->id, &(imgb)); > + if (xevd_ret == XEVD_ERR_UNEXPECTED) { // bumping process completed Shouldn't this be XEVD_OK_NO_MORE_FRM? -------------------- No. It should't be XEVD_OK_NO_MORE_FRM. It means that bumping process has completed -------------------- > + *got_frame_ptr = 0; > + return 0; > + } else if (XEVD_FAILED(xevd_ret)) { > + av_log(avctx, AV_LOG_ERROR, "Failed to pull the decoded image (xevd error code: %d)\n", xevd_ret); > + ret = AVERROR_EXTERNAL; > + goto ERR; > + } > + } > + > + if (imgb) { > + // @todo supports other color space and bit depth > + if (imgb->cs != XEVD_CS_YCBCR420_10LE) { > + av_log(avctx, AV_LOG_ERROR, "Not supported pixel format: %s\n", av_get_pix_fmt_name(avctx->pix_fmt)); > + ret = AVERROR_INVALIDDATA; > + goto ERR; > + } > + > + if (imgb->w[0] != avctx->width || imgb->h[0] != avctx->height) { // stream resolution changed > + if (ff_set_dimensions(avctx, imgb->w[0], imgb->h[0]) < 0) { > + av_log(avctx, AV_LOG_ERROR, "Cannot set new dimension\n"); > + ret = AVERROR_INVALIDDATA; > + goto ERR; > + } > + } > + > + frame->coded_picture_number++; > + frame->display_picture_number++; As is, these two will always be 1. If you want to set these fields, you need to keep track of total decoded frames elsewhere. stat.fnum looks like what you need, or maybe xectx->decod_frames. #################### DONE -------------------- Removed #################### > + frame->format = AV_PIX_FMT_YUV420P10LE; No need to set this here. ff_get_buffer() will handle it for you. #################### DONE -------------------- Removed #################### > + > + if (ff_get_buffer(avctx, frame, 0) < 0) { > + av_log(avctx, AV_LOG_ERROR, "Cannot get AV buffer\n"); ff_get_buffer() already prints an error, so remove this one. > + ret = AVERROR(ENOMEM); It also returns an error code you should propagate. #################### DONE #################### > + goto ERR; > + } > + > + frame->pts = avpkt->pts; > + > + av_image_copy(frame->data, frame->linesize, (const uint8_t **)imgb->a, > + imgb->s, avctx->pix_fmt, > + imgb->w[0], imgb->h[0]); > + > + xectx->decod_frames++; Write only variable. #################### DONE #################### > + *got_frame_ptr = 1; > + > + // xevd_pull uses pool of objects of type XEVD_IMGB. > + // The pool size is equal MAX_PB_SIZE (26), so release object when it is no more needed > + imgb->release(imgb); > + imgb = NULL; > + } else > + *got_frame_ptr = 0; > + > + xectx->packet_count++; Same. #################### DONE #################### > + > + return avpkt->size; > + > +ERR: > + if (imgb) { > + imgb->release(imgb); > + imgb = NULL; > + } > + *got_frame_ptr = 0; > + > + return ret; > +} > + > +/** > + * Destroy decoder > + * > + * @param avctx codec context > + * @return 0 on success > + */ > +static av_cold int libxevd_close(AVCodecContext *avctx) > +{ > + XevdContext *xectx = avctx->priv_data; > + if (xectx->id) { > + xevd_delete(xectx->id); > + xectx->id = NULL; > + } > + > + return 0; > +} > + > +#define OFFSET(x) offsetof(XevdContext, x) > +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM > + > +static const AVClass libxevd_class = { > + .class_name = "libxevd", > + .item_name = av_default_item_name, > + .version = LIBAVUTIL_VERSION_INT, > +}; > + > +const FFCodec ff_libxevd_decoder = { > + .p.name = "evc", > + .p.long_name = NULL_IF_CONFIG_SMALL("EVC / MPEG-5 Essential Video Coding (EVC)"), > + .p.type = AVMEDIA_TYPE_VIDEO, > + .p.id = AV_CODEC_ID_EVC, > + .init = libxevd_init, > + FF_CODEC_DECODE_CB(libxevd_decode), > + .close = libxevd_close, > + .priv_data_size = sizeof(XevdContext), > + .p.priv_class = &libxevd_class, > + .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_DR1, Use AV_CODEC_CAP_OTHER_THREADS, not AV_CODEC_CAP_AUTO_THREADS. And set caps_internal to FF_CODEC_CAP_AUTO_THREADS. #################### DONE #################### > + .p.wrapper_name = "libxevd", > +}; _______________________________________________ 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".