X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=698fea49970dcd501b82f5f62d2545aaadcf7537;hb=012559f2bb59366331f5ab77de6ce8c3f833b1bc;hp=ddf42726d9df2aa36d3214a2d24584ae52218885;hpb=983778f1f68a12b1e307572f48390428c0421a8e;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index ddf42726d9d..698fea49970 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -458,8 +458,8 @@ static void ffmpeg_cleanup(int ret) 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); @@ -883,23 +883,29 @@ static void do_subtitle_out(AVFormatContext *s, 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 && @@ -909,7 +915,6 @@ static void do_video_out(AVFormatContext *s, 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; @@ -939,7 +944,10 @@ static void do_video_out(AVFormatContext *s, 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; @@ -1214,7 +1222,6 @@ static int reap_filters(void) { 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++) { @@ -1234,6 +1241,7 @@ static int reap_filters(void) 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) { @@ -1247,10 +1255,20 @@ static int reap_filters(void) 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); } @@ -1259,20 +1277,19 @@ static int reap_filters(void) 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, @@ -1526,10 +1543,15 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti 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); @@ -1560,8 +1582,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti 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); } } @@ -2293,7 +2314,7 @@ static void print_sdp(void) 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); } } @@ -2543,7 +2564,7 @@ static int transcode_init(void) AVFormatContext *oc; OutputStream *ost; InputStream *ist; - char error[1024]; + char error[1024] = {0}; int want_sdp = 1; for (i = 0; i < nb_filtergraphs; i++) { @@ -2907,6 +2928,8 @@ static int transcode_init(void) enc_ctx->height = input_streams[ost->source_index]->st->codec->height; } break; + case AVMEDIA_TYPE_DATA: + break; default: abort(); break;