for (i = 0; i < nb_output_files; i++) {
OutputFile *of = output_files[i];
AVFormatContext *s = of->ctx;
- if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE) && s->pb)
- avio_close(s->pb);
+ if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
+ avio_closep(&s->pb);
avformat_free_context(s);
av_dict_free(&of->opts);
static void do_video_out(AVFormatContext *s,
OutputStream *ost,
- AVFrame *next_picture)
+ AVFrame *next_picture,
+ double sync_ipts)
{
int ret, format_video_sync;
AVPacket pkt;
AVCodecContext *enc = ost->enc_ctx;
AVCodecContext *mux_enc = ost->st->codec;
int nb_frames, nb0_frames, i;
- double sync_ipts, delta, delta0;
+ double delta, delta0;
double duration = 0;
int frame_size = 0;
InputStream *ist = NULL;
+ AVFilterContext *filter = ost->filter->filter;
if (ost->source_index >= 0)
ist = input_streams[ost->source_index];
+ if (filter->inputs[0]->frame_rate.num > 0 &&
+ filter->inputs[0]->frame_rate.den > 0)
+ duration = 1/(av_q2d(filter->inputs[0]->frame_rate) * av_q2d(enc->time_base));
+
if(ist && ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE && ost->frame_rate.num)
- duration = 1/(av_q2d(ost->frame_rate) * av_q2d(enc->time_base));
+ duration = FFMIN(duration, 1/(av_q2d(ost->frame_rate) * av_q2d(enc->time_base)));
if (!ost->filters_script &&
!ost->filters &&
duration = lrintf(av_frame_get_pkt_duration(next_picture) * av_q2d(ist->st->time_base) / av_q2d(enc->time_base));
}
- sync_ipts = next_picture->pts;
delta0 = sync_ipts - ost->sync_opts;
delta = delta0 + duration;
format_video_sync != VSYNC_PASSTHROUGH &&
format_video_sync != VSYNC_DROP) {
double cor = FFMIN(-delta0, duration);
- av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
+ if (delta0 < -0.6) {
+ av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
+ } else
+ av_log(NULL, AV_LOG_DEBUG, "Cliping frame in rate conversion by %f\n", -delta0);
sync_ipts += cor;
duration -= cor;
delta0 += cor;
{
AVFrame *filtered_frame = NULL;
int i;
- int64_t frame_pts;
/* Reap all buffers present in the buffer sinks */
for (i = 0; i < nb_output_streams; i++) {
filtered_frame = ost->filtered_frame;
while (1) {
+ double float_pts = AV_NOPTS_VALUE; // this is identical to filtered_frame.pts but with higher precision
ret = av_buffersink_get_frame_flags(filter, filtered_frame,
AV_BUFFERSINK_FLAG_NO_REQUEST);
if (ret < 0) {
av_frame_unref(filtered_frame);
continue;
}
- frame_pts = AV_NOPTS_VALUE;
if (filtered_frame->pts != AV_NOPTS_VALUE) {
int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
- filtered_frame->pts = frame_pts =
+ AVRational tb = enc->time_base;
+ int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
+
+ tb.den <<= extra_bits;
+ float_pts =
+ av_rescale_q(filtered_frame->pts, filter->inputs[0]->time_base, tb) -
+ av_rescale_q(start_time, AV_TIME_BASE_Q, tb);
+ float_pts /= 1 << extra_bits;
+ // avoid exact midoints to reduce the chance of rounding differences, this can be removed in case the fps code is changed to work with integers
+ float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
+
+ filtered_frame->pts =
av_rescale_q(filtered_frame->pts, filter->inputs[0]->time_base, enc->time_base) -
av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base);
}
switch (filter->inputs[0]->type) {
case AVMEDIA_TYPE_VIDEO:
- filtered_frame->pts = frame_pts;
if (!ost->frame_aspect_ratio.num)
enc->sample_aspect_ratio = filtered_frame->sample_aspect_ratio;
if (debug_ts) {
- av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s time_base:%d/%d\n",
+ av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
av_ts2str(filtered_frame->pts), av_ts2timestr(filtered_frame->pts, &enc->time_base),
+ float_pts,
enc->time_base.num, enc->time_base.den);
}
- do_video_out(of->ctx, ost, filtered_frame);
+ do_video_out(of->ctx, ost, filtered_frame, float_pts);
break;
case AVMEDIA_TYPE_AUDIO:
- filtered_frame->pts = frame_pts;
if (!(enc->codec->capabilities & CODEC_CAP_PARAM_CHANGE) &&
enc->channels != av_frame_get_channels(filtered_frame)) {
av_log(NULL, AV_LOG_ERROR,
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"%02d:%02d:%02d.%02d ", hours, mins, secs,
(100 * us) / AV_TIME_BASE);
- if (bitrate < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "bitrate=N/A");
- else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "bitrate=%6.1fkbits/s", bitrate);
+
+ if (bitrate < 0) {
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),"bitrate=N/A");
+ av_bprintf(&buf_script, "bitrate=N/A\n");
+ }else{
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),"bitrate=%6.1fkbits/s", bitrate);
+ av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
+ }
+
if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
avio_flush(progress_avio);
av_bprint_finalize(&buf_script, NULL);
if (is_last_report) {
- avio_close(progress_avio);
- progress_avio = NULL;
+ avio_closep(&progress_avio);
}
}
av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
} else {
avio_printf(sdp_pb, "SDP:\n%s", sdp);
- avio_close(sdp_pb);
+ avio_closep(&sdp_pb);
av_freep(&sdp_filename);
}
}
AVFormatContext *oc;
OutputStream *ost;
InputStream *ist;
- char error[1024];
+ char error[1024] = {0};
int want_sdp = 1;
for (i = 0; i < nb_filtergraphs; i++) {
enc_ctx->height = input_streams[ost->source_index]->st->codec->height;
}
break;
+ case AVMEDIA_TYPE_DATA:
+ break;
default:
abort();
break;