Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: "Dawid Kozinski/Multimedia \(PLT\) /SRPOL/Staff Engineer/Samsung Electronics" <d.kozinski@samsung.com>
To: "'FFmpeg development discussions and patches'" <ffmpeg-devel@ffmpeg.org>
Subject: Re: [FFmpeg-devel] [PATCH v18 06/10] avcodec/evc_decoder: Provided support for EVC decoder
Date: Thu, 30 Mar 2023 12:09:14 +0200
Message-ID: <000001d962ef$aecce670$0c66b350$@samsung.com> (raw)
In-Reply-To: <62f45ea9-aa27-e1dd-a8c0-f3cc80f32ff0@gmail.com>




> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of James
> Almer
> Sent: środa, 29 marca 2023 14:17
> To: ffmpeg-devel@ffmpeg.org
> Subject: Re: [FFmpeg-devel] [PATCH v18 06/10] avcodec/evc_decoder:
Provided
> support for EVC decoder
> 
> On 3/28/2023 10:50 AM, Dawid Kozinski wrote:
> > +static int libxevd_receive_frame(AVCodecContext *avctx, AVFrame
> > +*frame) {
> > +    XevdContext *xectx = NULL;
> > +    AVPacket *pkt = NULL;
> > +    XEVD_IMGB *imgb = NULL;
> > +
> > +    int xevd_ret = 0;
> > +    int ret = 0;
> > +
> > +    xectx = avctx->priv_data;
> > +
> > +    pkt = av_packet_alloc();
> > +    if (!pkt)
> > +        return AVERROR(ENOMEM);
> 
> This is very inefficient. Just keep an AVPacket in the XevdContext,
allocating it on
> init(), unrefing it after being used in this function, and freeing it on
close().
> 
> > +
> > +    // obtain input data
> > +    ret = ff_decode_get_packet(avctx, pkt);
> > +    if (ret < 0 && ret != AVERROR_EOF) {
> > +        av_packet_free(&pkt);
> > +        return ret;
> > +    } else if(ret == AVERROR_EOF && xectx->draining_mode == 0) { //
> > + End of stream situations. Enter draining mode
> > +
> > +        frame = NULL;
> > +        xectx->draining_mode = 1;
> > +
> > +        av_packet_free(&pkt);
> > +
> > +        return AVERROR_EOF;
> 
> By returning EOF here you're effectively ending the decoding process. No
> draining is taking place. This function is not going to be called again
for the
> xectx->draining_mode == 1 to take effect.
> 
> > +    }
> > +
> > +    if (pkt->size > 0) {
> > +        int bs_read_pos = 0;
> > +        XEVD_STAT stat;
> > +        XEVD_BITB bitb;
> > +        int nalu_size;
> > +
> > +        imgb = NULL;
> > +
> > +        while(pkt->size > (bs_read_pos + XEVD_NAL_UNIT_LENGTH_BYTE)) {
> > +            memset(&stat, 0, sizeof(XEVD_STAT));
> > +
> > +            nalu_size = read_nal_unit_length(pkt->data + bs_read_pos,
> XEVD_NAL_UNIT_LENGTH_BYTE, avctx);
> > +            if (nalu_size == 0) {
> > +                av_log(avctx, AV_LOG_ERROR, "Invalid bitstream\n");
> > +                av_packet_free(&pkt);
> > +                ret = AVERROR_INVALIDDATA;
> > +                return ret;
> > +            }
> > +            bs_read_pos += XEVD_NAL_UNIT_LENGTH_BYTE;
> > +
> > +            bitb.addr = pkt->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");
> > +                av_packet_free(&pkt);
> > +                ret = AVERROR_EXTERNAL;
> > +                return ret;
> > +            }
> > +
> > +            bs_read_pos += nalu_size;
> > +
> > +            if (stat.nalu_type == XEVD_NUT_SPS) { // EVC stream
parameters
> changed
> > +                if ((ret = export_stream_params(xectx, avctx)) != 0) {
> > +                    av_log(avctx, AV_LOG_ERROR, "Failed to export
stream
> params\n");
> > +                    av_packet_free(&pkt);
> > +                    return ret;
> > +                }
> > +            }
> > +            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;
> 
> Aren't you dropping an image you should be propagating instead with this?
> 
> > +                }
> > +                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;
> > +                    av_packet_free(&pkt);
> > +
> > +                    return ret;
> > +                }  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;
> 
> Can an image be returned when xevd_ret == XEVD_OK_FRM_DELAYED? If so,
> shouldn't you propagate it?
> 
> > +                    }
> > +                    av_packet_free(&pkt);
> > +
> > +                    return AVERROR(EAGAIN);
> > +                }
> > +                if (imgb) { // got frame
> > +                    int ret = libxevd_image_copy(avctx, imgb, frame);
> > +                    if(ret < 0) {
> > +                        av_log(avctx, AV_LOG_ERROR, "Image copying
error\n");
> > +                        if (imgb) {
> > +                            imgb->release(imgb);
> > +                            imgb = NULL;
> > +                        }
> > +                        av_packet_free(&pkt);
> > +
> > +                        return ret;
> > +                    }
> > +
> > +                    // use ff_decode_frame_props() to fill frame
properties
> > +                    ret = ff_decode_frame_props(avctx, frame);
> > +                    if (ret < 0) {
> > +                        if (imgb) {
> > +                            imgb->release(imgb);
> > +                            imgb = NULL;
> > +                        }
> > +                        av_packet_free(&pkt);
> > +                        av_frame_unref(frame);
> > +
> > +                        return ret;
> > +                    }
> > +                    // match timestamps and packet size
> > +                    ret = ff_decode_frame_props_from_pkt(avctx, frame,
pkt);
> > +                    pkt->opaque = NULL;
> 
> You copy-pasted this from libdav1d.c without knowing what it's doing.
> You don't need to clear opaque, and you don't need to call
> ff_decode_frame_props_from_pkt() with the current packet when
> ff_decode_frame_props() is already doing it for you. The former function
is only
> needed when you need props from a packet other than the last one fed to
the
> decoder.
> 
> > +                    if (ret < 0) {
> > +                        if (imgb) {
> > +                            imgb->release(imgb);
> > +                            imgb = NULL;
> > +                        }
> > +                        av_packet_free(&pkt);
> > +                        av_frame_unref(frame);
> > +
> > +                        return ret;
> > +                    }
> > +
> > +                    frame->pkt_dts = pkt->dts;
> > +
> > +                    // 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;
> > +
> > +                    return 0;
> > +                } else
> > +                    return  AVERROR(EAGAIN);
> > +            }
> > +        }
> > +    } else { // decoder draining mode handling
> > +        xevd_ret = xevd_pull(xectx->id, &imgb);
> > +        if (xevd_ret == XEVD_ERR_UNEXPECTED)   // draining process
completed
> > +            return AVERROR_EOF;
> > +        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);
> > +
> > +            if (imgb) {
> > +                imgb->release(imgb);
> > +                imgb = NULL;
> > +            }
> > +
> > +            av_packet_free(&pkt);
> > +
> > +            return AVERROR_EXTERNAL;
> > +        }
> > +        if (imgb) { // got frame
> > +            int ret = libxevd_image_copy(avctx, imgb, frame);
> > +            if(ret < 0) {
> > +                if (imgb) {
> > +                    imgb->release(imgb);
> > +                    imgb = NULL;
> > +                }
> > +                av_packet_free(&pkt);
> > +            }
> > +
> > +            frame->pkt_dts = pkt->dts;
> > +
> > +            // 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;
> > +
> > +            return 0;
> > +        }
> > +        return AVERROR_EOF;
> > +    }
> > +    return ret;
> > +}
> ___


I'm sorry for not replying earlier but I've been experiencing an internet
connection issue since yesterday. I had an outage and no network connection.

I will make all the necessary changes in the code and upload new patches as
fast as possible.

____________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://protect2.fireeye.com/v1/url?k=a9b4cba4-c83fde97-a9b540eb-
> 000babff9bb7-057645cded2a2511&q=1&e=a107ddf9-a9a2-4d0b-ac05-
> 20a74e0f8ff9&u=https%3A%2F%2Fffmpeg.org%2Fmailman%2Flistinfo%2Fffmpe
> g-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".

      reply	other threads:[~2023-03-30 10:09 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20230328135026eucas1p1abe4dd2289ba01bb018f7b37d1a147a7@eucas1p1.samsung.com>
2023-03-28 13:50 ` Dawid Kozinski
2023-03-29 12:16   ` James Almer
2023-03-30 10:09     ` Dawid Kozinski/Multimedia (PLT) /SRPOL/Staff Engineer/Samsung Electronics [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='000001d962ef$aecce670$0c66b350$@samsung.com' \
    --to=d.kozinski@samsung.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git