From 91b414a778cfc8fcee55f72352043aade2582627 Mon Sep 17 00:00:00 2001 From: Mladen Milinkovic Date: Thu, 1 Aug 2024 10:46:54 +0200 Subject: [PATCH 04/11] VideoPlayer: stop using AVFrame.pkt_pos This field is ad-hoc and will be deprecated. Use the recently-added AV_CODEC_FLAG_COPY_OPAQUE to pass arbitrary user data from packets to frames. --- src/videoplayer/backend/audiodecoder.cpp | 4 +++- src/videoplayer/backend/decoder.cpp | 17 +++++++++++++---- src/videoplayer/backend/decoder.h | 4 ++++ src/videoplayer/backend/videodecoder.cpp | 4 +++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/videoplayer/backend/audiodecoder.cpp b/src/videoplayer/backend/audiodecoder.cpp index 8c0b943e..35144965 100644 --- a/src/videoplayer/backend/audiodecoder.cpp +++ b/src/videoplayer/backend/audiodecoder.cpp @@ -490,8 +490,10 @@ AudioDecoder::run() if(!(af->frame = av_frame_alloc())) break; + Decoder::FrameData *fd = reinterpret_cast(frame->opaque_ref ? frame->opaque_ref->data : nullptr); + af->pts = frame->pts == AV_NOPTS_VALUE ? NAN : double(frame->pts) / frame->sample_rate; - af->pos = frame->pkt_pos; + af->pos = fd ? fd->pkt_pos : -1; af->serial = m_pktSerial; af->duration = double(frame->nb_samples) / frame->sample_rate; diff --git a/src/videoplayer/backend/decoder.cpp b/src/videoplayer/backend/decoder.cpp index 80fb993f..222056d0 100644 --- a/src/videoplayer/backend/decoder.cpp +++ b/src/videoplayer/backend/decoder.cpp @@ -133,10 +133,19 @@ Decoder::decodeFrame(AVFrame *frame, AVSubtitle *sub) } else { ret = pkt->data ? AVERROR(EAGAIN) : AVERROR_EOF; } - } else if(avcodec_send_packet(m_avCtx, pkt) == AVERROR(EAGAIN)) { - av_log(m_avCtx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n"); - m_pkt = pkt; - pkt = nullptr; + } else { + if(pkt->buf && !pkt->opaque_ref) { + pkt->opaque_ref = av_buffer_allocz(sizeof(Decoder::FrameData)); + if(!pkt->opaque_ref) + return AVERROR(ENOMEM); + Decoder::FrameData *fd = reinterpret_cast(pkt->opaque_ref->data); + fd->pkt_pos = pkt->pos; + } + if(avcodec_send_packet(m_avCtx, pkt) == AVERROR(EAGAIN)) { + av_log(m_avCtx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n"); + m_pkt = pkt; + pkt = nullptr; + } } av_packet_free(&pkt); } diff --git a/src/videoplayer/backend/decoder.h b/src/videoplayer/backend/decoder.h index 55970668..f4dd8c7e 100644 --- a/src/videoplayer/backend/decoder.h +++ b/src/videoplayer/backend/decoder.h @@ -55,6 +55,10 @@ protected: AVRational m_startPtsTb; int64_t m_nextPts; AVRational m_nextPtsTb; + + struct FrameData { + int64_t pkt_pos; + }; }; } diff --git a/src/videoplayer/backend/videodecoder.cpp b/src/videoplayer/backend/videodecoder.cpp index 851f6268..d5bd111e 100644 --- a/src/videoplayer/backend/videodecoder.cpp +++ b/src/videoplayer/backend/videodecoder.cpp @@ -101,8 +101,10 @@ VideoDecoder::run() if(!ret) continue; + Decoder::FrameData *fd = reinterpret_cast(frame->opaque_ref ? frame->opaque_ref->data : nullptr); + double pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * m_timeBase; - ret = queuePicture(frame, pts, frameDuration, frame->pkt_pos, pktSerial()); + ret = queuePicture(frame, pts, frameDuration, fd ? fd->pkt_pos : -1, pktSerial()); av_frame_unref(frame); if(ret < 0) -- 2.46.0