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 614E347591 for ; Tue, 12 Sep 2023 12:30:55 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D39A068C985; Tue, 12 Sep 2023 15:30:52 +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 B2BC868C94D for ; Tue, 12 Sep 2023 15:30:46 +0300 (EEST) Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20230912123044euoutp010ed4c95d9157c892901a2cd057ea20e3~EJqOr9QVn2143421434euoutp01s for ; Tue, 12 Sep 2023 12:30:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20230912123044euoutp010ed4c95d9157c892901a2cd057ea20e3~EJqOr9QVn2143421434euoutp01s DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1694521844; bh=ZD4DzvfOyK+HeJXrKW6ql8RxRjihPfyMMNgLLxFHvMY=; h=From:To:In-Reply-To:Subject:Date:References:From; b=T4CETVVZWJJ0lowH4tuLmLqrWpSGxhRuHrlyDHSLChlS6aoQoOjjA7CSYDaBECPTK zdTp5ZPMaModqcxdkD/BMOz2TBmD7KbJUeUNnNUwWGeVic4/4zzZ4s+wDqCioGmVlj GuuWFQ/avYZ3raW4/ncE0dV9hGOrxfLEOJgIxPCI= Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20230912123044eucas1p1b23f03b6f90a666cfe4ca4056d09ca22~EJqOinAlE2924529245eucas1p1r for ; Tue, 12 Sep 2023 12:30:44 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id 23.5A.37758.3F950056; Tue, 12 Sep 2023 13:30:43 +0100 (BST) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20230912123043eucas1p2ae1479fc217223ac09917c2645cebfcc~EJqOOekTF3075030750eucas1p2Q for ; Tue, 12 Sep 2023 12:30:43 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20230912123043eusmtrp1283cc88940b6e40d3c0345f78b4bae3d~EJqOOCQ0b1295512955eusmtrp1e for ; Tue, 12 Sep 2023 12:30:43 +0000 (GMT) X-AuditID: cbfec7f5-815ff7000002937e-e8-650059f32d00 Received: from eusmtip1.samsung.com ( [203.254.199.221]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id C1.6E.10549.3F950056; Tue, 12 Sep 2023 13:30:43 +0100 (BST) Received: from AMDN5164 (unknown [106.210.132.171]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20230912123043eusmtip14646147387b148e4e02c4f3b08656736~EJqN9BUga2905029050eusmtip1N for ; Tue, 12 Sep 2023 12:30:43 +0000 (GMT) From: "Dawid Kozinski/Multimedia \(PLT\) /SRPOL/Staff Engineer/Samsung Electronics" To: "'FFmpeg development discussions and patches'" In-Reply-To: <9b63cd1e-414e-4614-f2a0-bc29a5c427ea@gmail.com> Date: Tue, 12 Sep 2023 14:30:42 +0200 Message-ID: <024701d9e574$f2ac85a0$d80590e0$@samsung.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQH4cirN+3nxLmpdLbCd+zwopdMKpwIdZZtWAUYtB4avvud10A== Content-Language: pl X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrFIsWRmVeSWpSXmKPExsWy7djP87qfIxlSDVb1WFh8+3SG2YHR48+i zSwBjFFcNimpOZllqUX6dglcGb+2P2Up+PCIsWJC4ySWBsZPdxi7GDk5JARMJD40z2fqYuTi EBJYwSjRtu4FM4QziUmiadUHVpAqIYGJTBJz5ifDdCx93MIGUbScUeL6upusEE4bk0R/7xOw DjaBPInHn9cyg9giAj4S3evXg8U5BWwljsy7zg5iCwskS5x5cZgNxGYRUJX4t/c8WJxXwFLi yo+LULagxMmZT1hAbGYBPYlnp2ZB2doSyxa+Zoa4SEHi59NlQPM5gHY5Sdza6AtRIiJx41EL I8htEgK9HBK/+i6B1UgIuEgcnSoI0Sos8er4FnYIW0bi9OQeFoiSYolD/Q4QZo3EoR/pEBXW Em8bj0MDzlHi853XjBAlfBI33gpCLOWTmLRtOjNEmFeio00IwlSR6OsUg2iUkni6bA7zBEal WUgenIXkwVlIHpyF5JMFjCyrGMVTS4tz01OLjfNSy/WKE3OLS/PS9ZLzczcxApPD6X/Hv+5g XPHqo94hRiYOxkOMEhzMSiK8JYf+pgjxpiRWVqUW5ccXleakFh9ilOZgURLn1bY9mSwkkJ5Y kpqdmlqQWgSTZeLglGpgkgo+waTyRjf8k3RrvXLmP3H3L+J6935fn9ygxNDgb9n/SVzRM+RO 5x6X9qQZf7yWcG9dGSr+YpWMxR7PqJJVR07qCHXYs+idrT60tbSj+8vmww2WOod3a17V2pb7 9v3t1omWhT+nnhMryb6c+npH4aXTKRPtdryujDxyiK944QzlWxwNBWe7lbyn6TVxfw7zDTv3 KGqCXLjp+ss5ea5Wtmn3xM4tdZj66e96nj8fD+lyBk/UWBzccXrdqZCzhvPdlz8+8IcnaG7J i3tGHeGrz94T3FjA37L5ZJJQ96pFHlPXsR3Wvbf0sO9JkXq/LEnHczvmzXqSX/ee022y4cOT d/683fAt07JF/mdrSrzYGSWW4oxEQy3mouJEAN3sDhN9AwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrLLMWRmVeSWpSXmKPExsVy+t/xu7qfIxlSDRoWqFl8+3SG2YHR48+i zSwBjFF6NkX5pSWpChn5xSW2StGGFkZ6hpYWekYmlnqGxuaxVkamSvp2NimpOZllqUX6dgl6 GRd2VBZcbGCs6Ps9h7GB8UpwFyMnh4SAicTSxy1sXYxcHEICSxklrl7YyQ6RkJJYunQRI4Qt LPHnWhdUUQuTxKKja5hAEmwCORJrZ08Es0UEfCS6169nhSjawyhxceUSsG5OAVuJI/OuA01l 5xAWSJT44AgSZRFQlfi39zzYLl4BS4krPy5C2YISJ2c+YQGxmQUMJJYs/MUEYWtLLFv4mhni HgWJn0+XAa3iAFrrJHFroy9EiYjEjUctjBMYhWYhmTQLyaRZSCbNQtKygJFlFaNIamlxbnpu saFecWJucWleul5yfu4mRmA8bDv2c/MOxnmvPuodYmTiYDzEKMHBrCTCW3Lob4oQb0piZVVq UX58UWlOavEhRlOg1yYyS4km5wMjMq8k3tDMwNTQxMzSwNTSzFhJnNezoCNRSCA9sSQ1OzW1 ILUIpo+Jg1OqganTZGvak67jl1k186xTnRzFpr0tElmhc4HhqcqfqqzKOst3alvfte5cWiR4 YO8Mg4Xu8xkPWB2Q/ZZ/LmXKPN6nvcc2Clc/UltvcXFNm9hRQabfwhzv9K0Duzw7+MOXb1vo 9ip2m9LWfw+4N4QqlF1cOXmT1lXh0PaGIlHZ4q3fbEOWTJ3P4/b/lzH/M/PtQprlaX1veRdk qJZ+1Zu2Sa5Q56zcn1lRyw0MY2fuC1mk2KzaHam7KZDtAZ+trtxll62afgUxa1ZYh98/w6W1 qyVoyVavBX+aflT+mFFyXv2C1LyMbbERvbsOHlYUF5edV56gXuR7x0riUM2lrw9/VJXI8b2p /3zlxKy+MrVf0kosxRmJhlrMRcWJAH1JmbQQAwAA X-CMS-MailID: 20230912123043eucas1p2ae1479fc217223ac09917c2645cebfcc X-Msg-Generator: CA X-RootMTR: 20230816111208eucas1p1cd471546a2fce47a1e0d970999e29d87 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20230816111208eucas1p1cd471546a2fce47a1e0d970999e29d87 References: <20230816111131.494-1-d.kozinski@samsung.com> <9b63cd1e-414e-4614-f2a0-bc29a5c427ea@gmail.com> Subject: Re: [FFmpeg-devel] [PATCH v27 2/2] avcodec/evc_decoder: Provided support for EVC decoder 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="iso-8859-2" Content-Transfer-Encoding: quoted-printable Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: > -----Original Message----- > From: ffmpeg-devel On Behalf Of James > Almer > Sent: poniedzia=B3ek, 11 wrze=B6nia 2023 00:56 > To: ffmpeg-devel@ffmpeg.org > Subject: Re: [FFmpeg-devel] [PATCH v27 2/2] avcodec/evc_decoder: Provided > support for EVC decoder > = > On 8/16/2023 8:11 AM, Dawid Kozinski wrote: > > +/** > > + * 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 =3D avctx->priv_data; > > + XEVD_CDSC *cdsc =3D &(xectx->cdsc); > > + > > + /* read configurations and set values for created descriptor (XEVD_CDSC) > */ > > + get_conf(avctx, cdsc); > > + > > + /* create decoder */ > > + xectx->id =3D xevd_create(&(xectx->cdsc), NULL); > > + if (xectx->id =3D=3D NULL) { > > + av_log(avctx, AV_LOG_ERROR, "Cannot create XEVD encoder\n"); > > + return AVERROR_EXTERNAL; > > + } > > + > > + xectx->draining_mode =3D 0; > > + xectx->pkt =3D av_packet_alloc(); > = > Unchecked allocation. > = > > + > > + return 0; > > +} > > + > > +/** > > + * Decode frame with decoupled packet/frame dataflow > > + * > > + * @param avctx codec context > > + * @param[out] frame decoded frame > > + * > > + * @return 0 on success, negative error code on failure > > + */ > > +static int libxevd_receive_frame(AVCodecContext *avctx, AVFrame > > +*frame) { > > + XevdContext *xectx =3D avctx->priv_data; > > + AVPacket *pkt =3D xectx->pkt; > > + XEVD_IMGB *imgb =3D NULL; > > + > > + int xevd_ret =3D 0; > > + int ret =3D 0; > > + > > + if (!pkt) > > + return AVERROR(ENOMEM); > = > This check should be in libxevd_init(), like i said above. > = > > + > > + // obtain access unit (input data) - a set of NAL units that are consecutive in > decoding order and containing exactly one encoded image > > + ret =3D ff_decode_get_packet(avctx, pkt); > = > You're unconditionally fetching a new packet every time receive_frame() is > called. Is it guaranteed that the previous packet was fully consumed and freed? > = > > + if (ret < 0 && ret !=3D AVERROR_EOF) { > > + av_packet_unref(pkt); > > + > > + return ret; > > + } else if(ret =3D=3D AVERROR_EOF && xectx->draining_mode =3D=3D 0)= { // > > + End of stream situations. Enter draining mode > > + > > + xectx->draining_mode =3D 1; > > + av_packet_unref(pkt); > > + } > > + > > + if (pkt->size > 0) { > > + int bs_read_pos =3D 0; > > + XEVD_STAT stat; > > + XEVD_BITB bitb; > > + int nalu_size; > > + AVPacket* pkt_au; > > + imgb =3D NULL; > > + > > + pkt_au =3D av_packet_clone(pkt); > = > Unchecked allocation. > = > > + av_packet_unref(pkt); > = > You're unreferencing this packet here but then you check its fields below. > = > > + > > + // get all nal units from AU > > + while(pkt_au->size > (bs_read_pos + XEVD_NAL_UNIT_LENGTH_BYTE)) { > > + memset(&stat, 0, sizeof(XEVD_STAT)); > > + > > + nalu_size =3D read_nal_unit_length(pkt_au->data + bs_read_pos, > XEVD_NAL_UNIT_LENGTH_BYTE, avctx); > > + if (nalu_size =3D=3D 0) { > > + av_log(avctx, AV_LOG_ERROR, "Invalid bitstream\n"); > > + av_packet_free(&pkt_au); > > + ret =3D AVERROR_INVALIDDATA; > > + > > + return ret; > > + } > > + bs_read_pos +=3D XEVD_NAL_UNIT_LENGTH_BYTE; > > + > > + bitb.addr =3D pkt_au->data + bs_read_pos; > > + bitb.ssize =3D nalu_size; > > + bitb.pdata[0] =3D pkt_au; > > + bitb.ts[XEVD_TS_DTS] =3D pkt_au->dts; > > + > > + /* main decoding block */ > > + xevd_ret =3D xevd_decode(xectx->id, &bitb, &stat); > > + if (XEVD_FAILED(xevd_ret)) { > > + av_log(avctx, AV_LOG_ERROR, "Failed to decode bitstream\n"); > > + av_packet_free(&pkt_au); > > + ret =3D AVERROR_EXTERNAL; > = > You can just do return AVERROR_EXTERNAL; > = > > + > > + return ret; > > + } > > + > > + bs_read_pos +=3D nalu_size; > > + > > + if (stat.nalu_type =3D=3D XEVD_NUT_SPS) { // EVC stream parameters > changed > > + if ((ret =3D export_stream_params(xectx, avctx)) !=3D = 0) { > > + av_log(avctx, AV_LOG_ERROR, "Failed to export stream > params\n"); > > + av_packet_free(&pkt_au); > > + > > + return ret; > > + } > > + } > > + > > + if (stat.read !=3D nalu_size) > > + av_log(avctx, AV_LOG_INFO, "Different reading of > > + bitstream (in:%d,read:%d)\n,", nalu_size, stat.read); > > + > > + // stat.fnum - has negative value if the decoded data is not frame > > + if (stat.fnum >=3D 0) { > = > This means there can be more than one frame after a call to > xevd_decode() with one AU, right? Shouldn't you call xevd_pull() in a loop before > you call xevd_decode() again, or attempt to fetch another packet/AU? > = No, this doesn't mean that there can be more than one frame after a call to xevd_decode() with one AU. One AU can only contain a single frame. Additionally, it may contain NAL units of other types, such as SPS or PPS. Each AU is broken down into into NAL units. If a NAL unit contains a frame, stat.fnum has a value other than -1. If the NAL unit containing the frame has stat.fnum set, it can be interpreted as an index for the decoded frame. > > + > > + xevd_ret =3D xevd_pull(xectx->id, &imgb); // The > > + function returns a valid image only if the return code is XEVD_OK > > + > > + if (XEVD_FAILED(xevd_ret)) { > > + av_log(avctx, AV_LOG_ERROR, "Failed to pull the decoded image > (xevd error code: %d, frame#=3D%d)\n", xevd_ret, stat.fnum); > > + ret =3D AVERROR_EXTERNAL; > > + av_packet_free(&pkt_au); > > + > > + return ret; > > + } else if (xevd_ret =3D=3D XEVD_OK_FRM_DELAYED) { > > + if(bs_read_pos =3D=3D pkt->size) { > = > This is the check i was talking about being done with an empty packet. > pkt->size will always be 0. > = > > + return AVERROR(EAGAIN); > > + } > > + } else { // XEVD_OK > > + if (!imgb) { > > + if(bs_read_pos =3D=3D pkt->size) { > > + av_log(avctx, AV_LOG_ERROR, "Invalid > > + decoded image data\n"); > > + > > + av_packet_free(&pkt_au); > > + return AVERROR(EAGAIN); > > + } > > + } else { > > + // got frame > > + AVPacket* pkt_au_imgb =3D (AVPacket*)imgb->pdata[0]; > > + if(!pkt_au_imgb) { > > + av_log(avctx, AV_LOG_ERROR, "Invalid data > > + needed to fill frame properties\n"); > > + > > + ret =3D AVERROR_INVALIDDATA; > > + > > + av_packet_free(&pkt_au); > > + > > + imgb->release(imgb); > > + imgb =3D NULL; > > + > > + av_frame_unref(frame); > > + > > + return ret; > > + } > > + > > + ret =3D libxevd_image_copy(avctx, imgb, frame); > > + if(ret < 0) { > > + av_log(avctx, AV_LOG_ERROR, "Image > > + copying error\n"); > > + > > + av_packet_free(&pkt_au); > > + av_packet_free(&pkt_au_imgb); > = > pkt_au and pkt_au_imgb both point to the same memory. This second > av_packet_free() call will end in a use after free. > = That is not like this. = pkt_au (an AVPacket containing AU) is used as input for the decoder while the xevd_decode() function is called, while pkt_au_imgb is got from the decoder while the xevd_pull() function is called. = The sequence of NAL units containing frame data that we put into the decoder may not match the order of frames exiting the decoder (decoding sequence vs presentation sequnce). Therefore, the concern about the av_packet_free() call resulting in a use-after-free issue may not be valid, as these packets do not necessarily point to the same memory. > > + > > + imgb->release(imgb); > > + imgb =3D NULL; > > + > > + av_frame_unref(frame); > > + > > + return ret; > > + } > > + > > + // use ff_decode_frame_props_from_pkt() to fill frame > properties > > + ret =3D ff_decode_frame_props_from_pkt(avctx, > > + frame, pkt_au_imgb); > = > You attached the packet to imgb in order to fetch its props here, but are you > sure it makes sense as is? This entire loop always uses the same packet you > fetched at the start of the function. pkt_au_imgb will be the last packet the > decoder saw and thus ff_get_buffer() will have set the frame with the same > props already. > = > Using ff_decode_frame_props_from_pkt() with a packet you attached to some > encoder handled struct is for the cases where the last packet you fetched is not > the one with the props you want to use to fill this frame. > = During the decoding of an EVC stream, the libxevd_receive_frame decoder function is called (for the sake of precision, this is just the decoder wrapper, not the decoder itself as the actual decoding is delegated to the libxevd library). Inside this function, the ff_decode_get_packet() function is called, and it is in charge of providing data to the decoder. In the case of the EVC stream, the ff_decode_get_packet() function returns a pointer to an AU (which is essentially a set of NAL units that are consecutive in decoding order and contains exactly one encoded image) that is provided in the data field of the AVPacket structure. Then, in a while loop, the AU is decomposed into NAL units, which are sequentially passed to the xevd_decode() function. Along with the NAL unit, the xevd_decode() function also receives a pointer to the AVPacket structure containing the AU to which the NAL unit belongs. Each AU contains only one NAL unit containing an image. If the decoder is able to provide a decoded frame, the xevd_decode() function returns 0 and sets the fnum field of the XEVD_STAT structure to a value greater than or equal to 0. fnum values can be considered as indices for subsequent decoded frames. Therefore, since there can be only one NAL unit containing encoded frame data present in an AU, the xevd_decode() function will return only once fnum which will be greater than or equal to 0. As a result, the ff_decode_frame_props_from_pkt() function is called only once inside libxevd_receive_frame, after the NAL unit containing frame data is extracted from the AU. > > + if (ret < 0) { > > + av_log(avctx, AV_LOG_ERROR, > > + "ff_decode_frame_props_from_pkt error\n"); > > + > > + av_packet_free(&pkt_au); > > + av_packet_free(&pkt_au_imgb); > > + > > + imgb->release(imgb); > > + imgb =3D NULL; > > + > > + av_frame_unref(frame); > > + > > + return ret; > > + } > > + > > + frame->pkt_dts =3D imgb->ts[XEVD_TS_DTS]; > > + frame->pts =3D imgb->ts[XEVD_TS_PTS]; > > + > > + // 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 =3D NULL; > > + > > + if(bs_read_pos =3D=3D pkt->size) { > > + av_packet_free(&pkt_au); > > + av_packet_free(&pkt_au_imgb); > > + > > + av_frame_unref(frame); > > + return 0; > > + } > > + } > > + } > > + } > > + } > > + } else { // decoder draining mode handling > > + > > + xevd_ret =3D xevd_pull(xectx->id, &imgb); > > + > > + if (xevd_ret =3D=3D XEVD_ERR_UNEXPECTED) { // draining process completed > > + av_log(avctx, AV_LOG_DEBUG, "Draining process > > + completed\n"); > > + > > + return AVERROR_EOF; > > + } else if (XEVD_FAILED(xevd_ret)) { // handle all other errors > > + av_log(avctx, AV_LOG_ERROR, "Failed to pull the decoded > > + image (xevd error code: %d)\n", xevd_ret); > > + > > + return AVERROR_EXTERNAL; > > + } else { // XEVD_OK > > + AVPacket* pkt_au_imgb; > > + if (!imgb) { > > + av_log(avctx, AV_LOG_ERROR, "Invalid decoded image > > + data\n"); > > + > > + return AVERROR_EXTERNAL; > > + } > > + > > + pkt_au_imgb =3D (AVPacket*)imgb->pdata[0]; > > + if(!pkt_au_imgb) { > > + av_log(avctx, AV_LOG_ERROR, "Invalid data needed to fill frame > properties\n"); > > + ret =3D AVERROR_INVALIDDATA; > > + > > + imgb->release(imgb); > > + imgb =3D NULL; > > + > > + av_frame_unref(frame); > > + > > + return ret; > > + } > > + > > + // got frame > > + ret =3D libxevd_image_copy(avctx, imgb, frame); > > + if(ret < 0) { > > + av_packet_free(&pkt_au_imgb); > > + av_frame_unref(frame); > > + > > + imgb->release(imgb); > > + imgb =3D NULL; > > + > > + return ret; > > + } > > + // use ff_decode_frame_props_from_pkt() to fill frame properties > > + ret =3D ff_decode_frame_props_from_pkt(avctx, frame, pkt_au_imgb); > > + if (ret < 0) { > > + av_log(avctx, AV_LOG_ERROR, > > + "ff_decode_frame_props_from_pkt error\n"); > > + > > + av_packet_free(&pkt_au_imgb); > > + av_frame_unref(frame); > > + > > + imgb->release(imgb); > > + imgb =3D NULL; > > + > > + return ret; > > + } > > + > > + frame->pkt_dts =3D imgb->ts[XEVD_TS_DTS]; > > + frame->pts =3D imgb->ts[XEVD_TS_PTS]; > > + > > + av_packet_free(&pkt_au_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 =3D NULL; > > + > > + return 0; > > + } > > + } > > + > > + return ret; > > +} > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://protect2.fireeye.com/v1/url?k=3Da3c34be9-c2bea395-a3c2c0a6- > 74fe485cc33c-700162d83aeb15df&q=3D1&e=3D5bb81d7a-0d7d-43d7-ad83- > 76da98475fdc&u=3Dhttps%3A%2F%2Fffmpeg.org%2Fmailman%2Flistinfo%2Fffmp > eg-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".