From: Anton Khirnov <anton@khirnov.net> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 04/18 v2] fftools/ffmpeg_mux: stop rescaling timestamps in of_streamcopy() Date: Sun, 27 Aug 2023 12:50:32 +0200 Message-ID: <20230827105032.22186-1-anton@khirnov.net> (raw) In-Reply-To: <20230826202027.GU7802@pb2> This function converts packet timestamps from the input stream timebase to OutputStream.mux_timebase, which may or may not be equal to the actual output AVStream timebase (and even when it is, this may not always be the optimal choice due to bitstream filtering). Just keep the timestamps in input stream timebase, they will be rescaled as needed before bitstream filtering and/or sending the packet to the muxer. Move the av_rescale_delta() call for audio (needed to preserve accuracy with coarse muxer timebases) to write_packet. Drop now-unused OutputStream.mux_timebase. --- fftools/ffmpeg.h | 2 -- fftools/ffmpeg_enc.c | 2 -- fftools/ffmpeg_mux.c | 44 ++++++++++++++++++++------------------- fftools/ffmpeg_mux.h | 2 +- fftools/ffmpeg_mux_init.c | 2 -- 5 files changed, 24 insertions(+), 28 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index d53181e427..ef5bb13908 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -523,8 +523,6 @@ typedef struct OutputStream { /* dts of the last packet sent to the muxing queue, in AV_TIME_BASE_Q */ int64_t last_mux_dts; - // the timebase of the packets sent to the muxer - AVRational mux_timebase; AVRational enc_timebase; Encoder *enc; diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c index 96424272bf..3c9fdd3237 100644 --- a/fftools/ffmpeg_enc.c +++ b/fftools/ffmpeg_enc.c @@ -463,8 +463,6 @@ int enc_open(OutputStream *ost, AVFrame *frame) if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1}); - ost->mux_timebase = enc_ctx->time_base; - ret = of_stream_init(of, ost); if (ret < 0) return ret; diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index ab9bb398c1..54410aac5c 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -76,7 +76,23 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt) if (ost->type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP) pkt->pts = pkt->dts = AV_NOPTS_VALUE; - av_packet_rescale_ts(pkt, pkt->time_base, ost->st->time_base); + // rescale timestamps to the stream timebase + if (ost->type == AVMEDIA_TYPE_AUDIO && !ost->enc) { + // use av_rescale_delta() for streamcopying audio, to preserve + // accuracy with coarse input timebases + int duration = av_get_audio_frame_duration2(ost->st->codecpar, pkt->size); + + if (!duration) + duration = ost->st->codecpar->frame_size; + + pkt->dts = av_rescale_delta(pkt->time_base, pkt->dts, + (AVRational){1, ost->st->codecpar->sample_rate}, duration, + &ms->ts_rescale_delta_last, ost->st->time_base); + pkt->pts = pkt->dts; + + pkt->duration = av_rescale_q(pkt->duration, pkt->time_base, ost->st->time_base); + } else + av_packet_rescale_ts(pkt, pkt->time_base, ost->st->time_base); pkt->time_base = ost->st->time_base; if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) { @@ -392,7 +408,7 @@ int of_streamcopy(OutputStream *ost, const AVPacket *pkt, int64_t dts) OutputFile *of = output_files[ost->file_index]; MuxStream *ms = ms_from_ost(ost); int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; - int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->mux_timebase); + int64_t ts_offset; AVPacket *opkt = ms->pkt; int ret; @@ -425,27 +441,17 @@ int of_streamcopy(OutputStream *ost, const AVPacket *pkt, int64_t dts) if (ret < 0) return ret; - opkt->time_base = ost->mux_timebase; + ts_offset = av_rescale_q(start_time, AV_TIME_BASE_Q, opkt->time_base); if (pkt->pts != AV_NOPTS_VALUE) - opkt->pts = av_rescale_q(pkt->pts, pkt->time_base, opkt->time_base) - ost_tb_start_time; + opkt->pts -= ts_offset; if (pkt->dts == AV_NOPTS_VALUE) { opkt->dts = av_rescale_q(dts, AV_TIME_BASE_Q, opkt->time_base); } else if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - int duration = av_get_audio_frame_duration2(ost->par_in, pkt->size); - if(!duration) - duration = ost->par_in->frame_size; - opkt->dts = av_rescale_delta(pkt->time_base, pkt->dts, - (AVRational){1, ost->par_in->sample_rate}, duration, - &ms->ts_rescale_delta_last, opkt->time_base); - /* dts will be set immediately afterwards to what pts is now */ - opkt->pts = opkt->dts - ost_tb_start_time; - } else - opkt->dts = av_rescale_q(pkt->dts, pkt->time_base, opkt->time_base); - opkt->dts -= ost_tb_start_time; - - opkt->duration = av_rescale_q(pkt->duration, pkt->time_base, opkt->time_base); + opkt->pts = opkt->dts - ts_offset; + } + opkt->dts -= ts_offset; { int ret = trigger_fix_sub_duration_heartbeat(ost, pkt); @@ -511,10 +517,6 @@ static int thread_start(Muxer *mux) MuxStream *ms = ms_from_ost(ost); AVPacket *pkt; - /* try to improve muxing time_base (only possible if nothing has been written yet) */ - if (!av_fifo_can_read(ms->muxing_queue)) - ost->mux_timebase = ost->st->time_base; - while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0) { ret = thread_submit_packet(mux, ost, pkt); if (pkt) { diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h index 7f34b86548..a2bb4dfc7d 100644 --- a/fftools/ffmpeg_mux.h +++ b/fftools/ffmpeg_mux.h @@ -75,7 +75,7 @@ typedef struct MuxStream { int64_t stream_duration; AVRational stream_duration_tb; - // audio streamcopy - state for av_rescale_delta() + // state for av_rescale_delta() call for audio in write_packet() int64_t ts_rescale_delta_last; // combined size of all the packets sent to the muxer diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 0289cdabad..cf4cd2d5b7 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -1090,8 +1090,6 @@ static int streamcopy_init(const Muxer *mux, OutputStream *ost) } } - ost->mux_timebase = ist->st->time_base; - fail: avcodec_free_context(&codec_ctx); av_dict_free(&codec_opts); -- 2.40.1 _______________________________________________ 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".
next prev parent reply other threads:[~2023-08-27 10:51 UTC|newest] Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-08-26 15:11 [FFmpeg-devel] [PATCH 01/18] fftools/ffmpeg: stop explicitly closing output streams on input EOF Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 02/18] fftools/ffmpeg: simplify handling input -t for streamcopy Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 03/18] fftools/ffmpeg_mux: use correct timebases for bitstream filtering Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 04/18] fftools/ffmpeg_mux: stop rescaling timestamps in of_streamcopy() Anton Khirnov 2023-08-26 20:20 ` Michael Niedermayer 2023-08-27 10:50 ` Anton Khirnov [this message] 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 05/18] fftools/ffmpeg_enc: factor out setting encoder timebase Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 06/18] fftools/ffmpeg_enc: reindent after previous commit Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 07/18] fftools/ffmpeg_enc: only use fallback framerate when encoding CFR Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 08/18] fftools/ffmpeg_enc: reindent after previous commit Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 09/18] fftools/ffmpeg_filter: sanitize framerate retrieved from the filtergraph Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 10/18] fftools/ffmpeg: move derivation of frame duration from filter framerate Anton Khirnov 2023-08-29 8:07 ` Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 11/18] fftools/ffmpeg_enc: move handling video frame duration to video_sync_process() Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 12/18] fftools/ffmpeg_filter: factor processing a single frame out of reap_filters() Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 13/18] fftools/ffmpeg_filter: reindent after previous commit Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 14/18] fftools/ffmpeg_filter: shorten a variable name Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 15/18] fftools/ffmpeg_enc: move remaining vsync-related code to video_sync_process() Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 16/18] fftools/ffmpeg_enc: simplify adjust_frame_pts_to_encoder_tb() signature Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 17/18] fftools/ffmpeg_mux: rename of_close() to of_free() Anton Khirnov 2023-08-26 15:11 ` [FFmpeg-devel] [PATCH 18/18] fftools/ffmpeg: move sending filtergraph commands to a separate function Anton Khirnov
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=20230827105032.22186-1-anton@khirnov.net \ --to=anton@khirnov.net \ --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