diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index ca6ff780c3..2a39d767cd 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1368,6 +1368,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo { InputFile *f = input_files[ist->file_index]; const AVCodecParameters *par = ist->par; + int64_t dts_est = AV_NOPTS_VALUE; int ret = 0; int repeating = 0; int eof_reached = 0; @@ -1463,6 +1464,11 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo if (!pkt && !ist->decoding_needed) eof_reached = 1; + if (pkt && pkt->opaque_ref) { + DemuxPktData *pd = (DemuxPktData*)pkt->opaque_ref->data; + dts_est = pd->dts_est; + } + duration_exceeded = 0; if (f->recording_time != INT64_MAX) { int64_t start_time = 0; @@ -1470,7 +1476,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo start_time += f->start_time != AV_NOPTS_VALUE ? f->start_time : 0; start_time += start_at_zero ? 0 : f->start_time_effective; } - if (ist->dts >= f->recording_time + start_time) + if (dts_est >= f->recording_time + start_time) duration_exceeded = 1; } @@ -1484,7 +1490,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo continue; } - of_streamcopy(ost, pkt, ist->dts); + of_streamcopy(ost, pkt, dts_est); } return !eof_reached; @@ -1900,6 +1906,18 @@ static void ist_dts_update(InputStream *ist, AVPacket *pkt) } break; } + + av_assert0(!pkt->opaque_ref); + if (ist->streamcopy_needed) { + DemuxPktData *pd; + + pkt->opaque_ref = av_buffer_allocz(sizeof(*pd)); + if (!pkt->opaque_ref) + report_and_exit(AVERROR(ENOMEM)); + pd = (DemuxPktData*)pkt->opaque_ref->data; + + pd->dts_est = ist->dts; + } } /* diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index b0319f0ed0..8a5d5b13c8 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -95,6 +95,12 @@ typedef struct { } AudioChannelMap; #endif +typedef struct DemuxPktData { + // estimated dts in AV_TIME_BASE_Q, + // to be used when real dts is missing + int64_t dts_est; +} DemuxPktData; + typedef struct OptionsContext { OptionGroup *g; @@ -337,6 +343,7 @@ typedef struct InputStream { int discard; /* true if stream data should be discarded */ int user_set_discard; int decoding_needed; /* non zero if the packets must be decoded in 'raw_fifo', see DECODING_FOR_* */ + int streamcopy_needed; #define DECODING_FOR_OST 1 #define DECODING_FOR_FILTER 2 // should attach FrameData as opaque_ref after decoding diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index b16a20a87b..eda838f84c 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -584,6 +584,7 @@ static void ist_use(InputStream *ist, int decoding_needed) ist->discard = 0; ist->st->discard = ist->user_set_discard; ist->decoding_needed |= decoding_needed; + ist->streamcopy_needed |= !decoding_needed; if (decoding_needed && !avcodec_is_open(ist->dec_ctx)) { int ret = dec_open(ist);