aboutsummaryrefslogtreecommitdiffstats
path: root/ffmpeg.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-05-27 12:04:29 +0200
committerwm4 <nfxjfg@googlemail.com>2017-03-03 08:45:43 +0100
commit4ee5aed122ba7d289c1686eca6eba161d5d62304 (patch)
tree3daf3a3d530b96a8958a02d2b5ed38c58de18f18 /ffmpeg.c
parent33580a8625c77591919b6155a48da04dccc8d398 (diff)
downloadffmpeg-4ee5aed122ba7d289c1686eca6eba161d5d62304.tar.gz
ffmpeg: do packet ts rescaling in write_packet()
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 are some changes with how/when the mux_timebase field is set, because the Libav approach often causes a too imprecise time base to be set. This is hard, because the muxer's write_header function can readjust the timebase, at which point we might already have encoded packets buffered. (It might be better to buffer them after the encoder, instead of after all the timestamp handling logic before muxing.) The two FATE tests change because the output time base is raised for subtitles. (Needed to avoid certain rounding issues in other cases.) Includes a minor merge fix by Mark Thompson, and avconv: Move rescale to stream timebase before monotonisation also by Mark Thompson <sw@jkqxz.net>. Signed-off-by: wm4 <nfxjfg@googlemail.com>
Diffstat (limited to 'ffmpeg.c')
-rw-r--r--ffmpeg.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/ffmpeg.c b/ffmpeg.c
index 5adec2b290..983e2fb486 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -713,10 +713,12 @@ 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);
}
}
+ av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
+
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
if (pkt->dts != AV_NOPTS_VALUE &&
pkt->pts != AV_NOPTS_VALUE &&
@@ -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,15 +995,15 @@ 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 */
if (i == 0)
- pkt.pts += 90 * sub->start_display_time;
+ pkt.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
else
- pkt.pts += 90 * sub->end_display_time;
+ pkt.pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
}
pkt.dts = pkt.pts;
output_packet(of, &pkt, ost);
@@ -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,7 +1864,7 @@ static void flush_encoders(void)
av_packet_unref(&pkt);
continue;
}
- av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
+ av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase);
pkt_size = pkt.size;
output_packet(of, &pkt, ost);
if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {
@@ -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
@@ -2822,6 +2825,10 @@ static int check_init_output_file(OutputFile *of, int file_index)
for (i = 0; i < of->ctx->nb_streams; i++) {
OutputStream *ost = output_streams[of->ost_index + i];
+ /* try to improve muxing time_base (only possible if nothing has been written yet) */
+ if (!av_fifo_size(ost->muxing_queue))
+ ost->mux_timebase = ost->st->time_base;
+
while (av_fifo_size(ost->muxing_queue)) {
AVPacket pkt;
av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
@@ -2981,6 +2988,8 @@ static int init_output_stream_streamcopy(OutputStream *ost)
break;
}
+ ost->mux_timebase = ist->st->time_base;
+
return 0;
}
@@ -3236,7 +3245,7 @@ static int init_output_stream_encode(OutputStream *ost)
}
break;
case AVMEDIA_TYPE_SUBTITLE:
- enc_ctx->time_base = (AVRational){1, 1000};
+ enc_ctx->time_base = AV_TIME_BASE_Q;
if (!enc_ctx->width) {
enc_ctx->width = input_streams[ost->source_index]->st->codecpar->width;
enc_ctx->height = input_streams[ost->source_index]->st->codecpar->height;
@@ -3249,6 +3258,8 @@ static int init_output_stream_encode(OutputStream *ost)
break;
}
+ ost->mux_timebase = enc_ctx->time_base;
+
return 0;
}