diff options
author | Anton Khirnov <anton@khirnov.net> | 2024-09-11 16:37:07 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2024-09-13 11:56:53 +0200 |
commit | b53800691c121150e75dfa0ba76899d3692af57f (patch) | |
tree | f31991d50989ae4e974d7b0b2488152c6bd21e3c | |
parent | bb91425eb89affd45dfcdb004bd361e0630a7ece (diff) | |
download | ffmpeg-b53800691c121150e75dfa0ba76899d3692af57f.tar.gz |
lavc/hevcdec: set output frame pkt_dts
pkt_dts needs to be set manually when using the receive_frame() callback, so
it was unset after 2fdecbb239714b6203e37067fda2521f80e19d47.
Fixes PTS guessing for certain files with broken timestamps. Cf.
https://github.com/mpv-player/mpv/issues/14806
Reported-by: llyyr <llyyr.public@gmail.com>
-rw-r--r-- | libavcodec/hevc/hevcdec.c | 4 | ||||
-rw-r--r-- | libavcodec/hevc/hevcdec.h | 3 | ||||
-rw-r--r-- | libavcodec/hevc/refs.c | 10 |
3 files changed, 13 insertions, 4 deletions
diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index c8c425fd71..d67730418b 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -3444,6 +3444,8 @@ static int hevc_receive_frame(AVCodecContext *avctx, AVFrame *frame) uint8_t *sd; size_t sd_size; + s->pkt_dts = AV_NOPTS_VALUE; + if (ff_container_fifo_can_read(s->output_fifo)) goto do_output; @@ -3457,6 +3459,8 @@ static int hevc_receive_frame(AVCodecContext *avctx, AVFrame *frame) } else if (ret < 0) return ret; + s->pkt_dts = avpkt->dts; + sd = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &sd_size); if (sd && sd_size > 0) { ret = hevc_decode_extradata(s, sd, sd_size, 0); diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h index e43f2d0201..e3194fd87e 100644 --- a/libavcodec/hevc/hevcdec.h +++ b/libavcodec/hevc/hevcdec.h @@ -545,6 +545,9 @@ typedef struct HEVCContext { int film_grain_warning_shown; + // dts of the packet currently being decoded + int64_t pkt_dts; + AVBufferRef *rpu_buf; ///< 0 or 1 Dolby Vision RPUs. DOVIContext dovi_ctx; ///< Dolby Vision decoding context } HEVCContext; diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index 09d759f936..20fdbb5794 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -182,7 +182,7 @@ int ff_hevc_output_frames(HEVCContext *s, HEVCLayerContext *l, int nb_dpb = 0; int nb_output = 0; int min_poc = INT_MAX; - int i, min_idx, ret; + int i, min_idx, ret = 0; for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { HEVCFrame *frame = &l->DPB[i]; @@ -199,10 +199,12 @@ int ff_hevc_output_frames(HEVCContext *s, HEVCLayerContext *l, if (nb_output > max_output || (nb_output && nb_dpb > max_dpb)) { HEVCFrame *frame = &l->DPB[min_idx]; + AVFrame *f = frame->needs_fg ? frame->frame_grain : frame->f; - ret = discard ? 0 : - ff_container_fifo_write(s->output_fifo, - frame->needs_fg ? frame->frame_grain : frame->f); + if (!discard) { + f->pkt_dts = s->pkt_dts; + ret = ff_container_fifo_write(s->output_fifo, f); + } ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT); if (ret < 0) return ret; |