[FFmpeg-devel] [PATCH 2/9] ffmpeg: do packet ts rescaling in write_packet()
wm4
nfxjfg at googlemail.com
Fri Feb 10 14:35:34 EET 2017
From: Anton Khirnov <anton at khirnov.net>
This will be useful in the following commit, after which the muxer
timebase is not always available when encoding.
This merges Libav commit 3e265ca. It was previously skipped.
There is a minor change with setting the mux_timebase field only after
the muxer's write_header function has been called, because it can
readjust the timebase.
Includes a minor merge fix by Mark Thompson.
Signed-off-by: wm4 <nfxjfg at googlemail.com>
---
ffmpeg.c | 39 ++++++++++++++++++++++-----------------
ffmpeg.h | 2 ++
2 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/ffmpeg.c b/ffmpeg.c
index 913c18d92b..8b829beb34 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -713,7 +713,7 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
if (pkt->duration > 0)
av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
- ost->st->time_base);
+ ost->mux_timebase);
}
}
@@ -759,6 +759,8 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
pkt->stream_index = ost->index;
+ av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
+
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s size:%d\n",
@@ -907,13 +909,13 @@ static void do_audio_out(OutputFile *of, OutputStream *ost,
update_benchmark("encode_audio %d.%d", ost->file_index, ost->index);
- av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
+ av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase);
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "encoder -> type:audio "
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
- av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base),
- av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
+ av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &enc->time_base),
+ av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base));
}
output_packet(of, &pkt, ost);
@@ -993,8 +995,8 @@ static void do_subtitle_out(OutputFile *of,
av_init_packet(&pkt);
pkt.data = subtitle_out;
pkt.size = subtitle_out_size;
- pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base);
- pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->st->time_base);
+ pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->mux_timebase);
+ pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
/* XXX: the pts correction is handled here. Maybe handling
it in the codec would be better */
@@ -1187,7 +1189,7 @@ static void do_video_out(OutputFile *of,
mux_par->field_order = AV_FIELD_PROGRESSIVE;
pkt.data = (uint8_t *)in_picture;
pkt.size = sizeof(AVPicture);
- pkt.pts = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base);
+ pkt.pts = av_rescale_q(in_picture->pts, enc->time_base, ost->mux_timebase);
pkt.flags |= AV_PKT_FLAG_KEY;
output_packet(of, &pkt, ost);
@@ -1283,13 +1285,13 @@ static void do_video_out(OutputFile *of,
if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & AV_CODEC_CAP_DELAY))
pkt.pts = ost->sync_opts;
- av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
+ av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase);
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "encoder -> type:video "
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
- av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base),
- av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
+ av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->mux_timebase),
+ av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->mux_timebase));
}
frame_size = pkt.size;
@@ -1862,8 +1864,8 @@ static void flush_encoders(void)
av_packet_unref(&pkt);
continue;
}
- av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
pkt_size = pkt.size;
+ av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase);
output_packet(of, &pkt, ost);
if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {
do_video_stats(ost, pkt_size);
@@ -1897,7 +1899,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
OutputFile *of = output_files[ost->file_index];
InputFile *f = input_files [ist->file_index];
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->st->time_base);
+ int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->mux_timebase);
AVPicture pict;
AVPacket opkt;
@@ -1938,14 +1940,14 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
ost->sync_opts++;
if (pkt->pts != AV_NOPTS_VALUE)
- opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time;
+ opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->mux_timebase) - ost_tb_start_time;
else
opkt.pts = AV_NOPTS_VALUE;
if (pkt->dts == AV_NOPTS_VALUE)
- opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->st->time_base);
+ opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->mux_timebase);
else
- opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
+ opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->mux_timebase);
opkt.dts -= ost_tb_start_time;
if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && pkt->dts != AV_NOPTS_VALUE) {
@@ -1954,10 +1956,11 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
duration = ist->dec_ctx->frame_size;
opkt.dts = opkt.pts = av_rescale_delta(ist->st->time_base, pkt->dts,
(AVRational){1, ist->dec_ctx->sample_rate}, duration, &ist->filter_in_rescale_delta_last,
- ost->st->time_base) - ost_tb_start_time;
+ ost->mux_timebase) - ost_tb_start_time;
}
- opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
+ opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->mux_timebase);
+
opkt.flags = pkt->flags;
// FIXME remove the following 2 lines they shall be replaced by the bitstream filters
if ( ost->st->codecpar->codec_id != AV_CODEC_ID_H264
@@ -3410,6 +3413,8 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
if (ret < 0)
return ret;
+ ost->mux_timebase = ost->st->time_base;
+
return ret;
}
diff --git a/ffmpeg.h b/ffmpeg.h
index 458bb8a3dc..ca35ccc260 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -446,6 +446,8 @@ typedef struct OutputStream {
int64_t first_pts;
/* dts of the last packet sent to the muxer */
int64_t last_mux_dts;
+ // the timebase of the packets sent to the muxer
+ AVRational mux_timebase;
int nb_bitstream_filters;
uint8_t *bsf_extradata_updated;
--
2.11.0
More information about the ffmpeg-devel
mailing list