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".
prev parent 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