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 8A0F343F09 for ; Thu, 18 Aug 2022 09:00:01 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BD4F168B9C0; Thu, 18 Aug 2022 11:59:57 +0300 (EEST) Received: from mailout1.w1.samsung.com (mailout1.w1.samsung.com [210.118.77.11]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1EE2968B994 for ; Thu, 18 Aug 2022 11:59:50 +0300 (EEST) Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20220818085948euoutp01490ed40309c20b1262e223cc7ab1b1a1~MZMukIvUL1588415884euoutp01T for ; Thu, 18 Aug 2022 08:59:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20220818085948euoutp01490ed40309c20b1262e223cc7ab1b1a1~MZMukIvUL1588415884euoutp01T DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1660813188; bh=yzKUo9E67SVyaax+X1pqzewbPDY2lYo3URX3ed678Qk=; h=From:To:In-Reply-To:Subject:Date:References:From; b=pFcpSCcuoiUdSg7xQofKOFeENV4qRZKfMkCAnqbiCkz21/uARkX6O0XUBA8QZBeyz imlJUT3dZXB4KHq4gHfEP8yKJFVmG+l1T6midDPGv7FT9KJ1rYSDP2q6ypPqsunHkC MXC6bV1wlqyCfMsCuTAcI9ZBqxVsQSNt/xyJDgPY= Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20220818085948eucas1p13ac6d8d0bf943c4f23fe98936b0d4789~MZMub-PH61746317463eucas1p1N for ; Thu, 18 Aug 2022 08:59:48 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id 15.65.10067.48FFDF26; Thu, 18 Aug 2022 09:59:48 +0100 (BST) Received: from eusmtrp2.samsung.com (unknown [182.198.249.139]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20220818085947eucas1p2230f5329c6e9c29106568cb854fe0f88~MZMuFz2hO0697306973eucas1p2m for ; Thu, 18 Aug 2022 08:59:47 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp2.samsung.com (KnoxPortal) with ESMTP id 20220818085947eusmtrp202ce61fd04347186736914588f617659~MZMuFOZvR2374323743eusmtrp2q for ; Thu, 18 Aug 2022 08:59:47 +0000 (GMT) X-AuditID: cbfec7f4-dd7ff70000002753-2e-62fdff84e5f8 Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id DD.F7.09095.38FFDF26; Thu, 18 Aug 2022 09:59:47 +0100 (BST) Received: from AMDN3260 (unknown [106.210.132.171]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20220818085947eusmtip2a5d94b396b3241927a429d7381ce745b~MZMty1mho1916219162eusmtip2A for ; Thu, 18 Aug 2022 08:59:47 +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: Thu, 18 Aug 2022 10:59:47 +0200 Message-ID: <01e201d8b2e0$de21b8c0$9a652a40$@samsung.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQKDEgguu0wJMq2x9k1s9cTE31uzDAJ9zcVXAfIVRgSsPBxpkA== Content-Language: pl X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrFIsWRmVeSWpSXmKPExsWy7djPc7ot//8mGXRt4rL49ukMswOjx59F m1kCGKO4bFJSczLLUov07RK4MnbfPspYcGwuY8XMM2+ZGhjXFXUxcnJICJhI/L+1hK2LkYtD SGAFo8Tntm4WCGcSk8SHvzehMhOZJN48uA2U4QBraXvJChFfzijx4+QlJginjUmi7/pzsAyb wExGiblf1zCCLBER8JHoXr+eFcTmFLCVePvwFQuILSyQIbH80iKwGhYBVYnP09rAangFLCVm HH3LAmELSpyc+QTMZhbQlli28DUzxOEKEj+fLmOFmO8k8eF4JyNEjYjEjUctjCBHSAhM5JDo XfuBFaLBReLm2q1QtrDEq+Nb2CFsGYn/O+czQbxWLHGo3wHCrJE49CMdosJa4m3jcUaQMLOA psT6XfoQYUeJ9ysuQcOET+LGW0GIA/gkJm2bzgwR5pXoaBOCMFUk+jrFIBqlJJ4um8M8gVFp FpIPZyH5cBaST2YhrF3AyLKKUTy1tDg3PbXYKC+1XK84Mbe4NC9dLzk/dxMjMDmc/nf8yw7G 5a8+6h1iZOJgPMQowcGsJMJ7486fJCHelMTKqtSi/Pii0pzU4kOM0hwsSuK8yZkbEoUE0hNL UrNTUwtSi2CyTBycUg1MImnNkbtO7P92f/YqyfJN4m9Xz/bg3Lju3+LH813ebJ9aUnhlxlLv xb2KEtN5FytwCKTaM99x7bl63J71w84Tk5KSzCJeJV+v8GqbvueL7KzlPb1HRC+Jtd2x/P8s 45et4Yez7I+/fNCLuCWlvtrIriFa4P3Ex/+nOzAL9JzkWP2SP0Z49n+z0G+TP0xVmPvvvHHx nsCu2DOHHPPnLrwsePBPlm3U5w/Sz//fS8gM1ZY54P/85MIbT/blVW7bc5pN/65Cl4xpNdNj leQzYoVzmwKNOYUe6OzIVtBd9y1pqXjdc5d+C5Pp3R3NeobfLr3p0/iy6WHrpx4D5u7XyYum hF/Z6p9xK0NX/uYn9ard15VYijMSDbWYi4oTAYjh2r19AwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpkkeLIzCtJLcpLzFFi42I5/e/4Pd3m/3+TDF6e0Lf49ukMswOjx59F m1kCGKP0bIryS0tSFTLyi0tslaINLYz0DC0t9IxMLPUMjc1jrYxMlfTtbFJSczLLUov07RL0 MlZ+3MdUMHMmY8XNq7OYGxj/5HYxcnBICJhItL1k7WLk4hASWMoo0fniH3sXIydQXEpi6dJF jBC2sMSfa11sEEUtTBIXXvWDdbAJTGeUOHmwjwmkSkTAR6J7/XqoUXsYJXrOz2MBSXAK2Eq8 ffgKzBYWSJM4s6WRGcRmEVCV+DytjRXE5hWwlJhx9C0LhC0ocXLmEzCbWUBb4unNp3D2soWv mSFOUpD4+XQZK8RiJ4kPxzsZIWpEJG48amGcwCg0C8moWUhGzUIyahaSlgWMLKsYRVJLi3PT c4sN9YoTc4tL89L1kvNzNzEC42LbsZ+bdzDOe/VR7xAjEwfjIUYJDmYlEd4bd/4kCfGmJFZW pRblxxeV5qQWH2I0BfptIrOUaHI+MDLzSuINzQxMDU3MLA1MLc2MlcR5PQs6EoUE0hNLUrNT UwtSi2D6mDg4pRqYWM/U7+Dy1twhtmnt+tj/a7+/cj3XlLfz74kSB+W7l/9UhaxL1J5hEjPH ++x6PrWaX1WzP168s3D9KdPgNxe23fCq8s2+eTpVSNVxYr2FSOb2T3YPKhecPPzyj3+xZdd+ R4n5zZFdydvbfD1Z2D26J6o+qpnxIGO+3pHixr+LDKsapr2XNlfUFz1cdel9g/yLh3fefZW8 rigfMfOVbqz4ejl3k4wPqw5y2VTKTTm1e5+sZIfSp5/2TvqsxW/3brXfmZqcXvFUdO3VU/yx m9L/3TLs8E2Ynuj9o8rKjlWuQc9S6b5V/vFDax9Ytzd8uxzhpfeu7sDGbcuyWqO3S6uudp51 uJG702PnxIuSwTphSizFGYmGWsxFxYkA8v3lfhQDAAA= X-CMS-MailID: 20220818085947eucas1p2230f5329c6e9c29106568cb854fe0f88 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: Hi, Thank you for your code review and for all your valuable comments and remarks. We have done a lot of changes to our EVC wrapper implementation following them, and I think each of these changes have moved our wrapper one step forwards toward a final community-acceptable solution. A few days ago I submitted new patches providing EVC wrapper implementation. If there is still something we have to change or improve, please let me know. I'm looking forward to receiving your feedback. As I mentioned before we would like to start getting closer to the point where we can be able to merge our code into the FFmpeg master branch. :) Once again, thank you for your effort and for supporting us and we are waiting for your feedback. Best regards Dawid -----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. > + * 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. > + * > + * 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. > + */ > +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. > + } > + > + 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? 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? > + *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. > + frame->format = AV_PIX_FMT_YUV420P10LE; No need to set this here. ff_get_buffer() will handle it for you. > + > + 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. > + 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. > + *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. > + > + 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. > + .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".