X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=4afc55b40c384e59f0d762c5dda7d7324ec6b248;hb=744bd8d08c18d68d92ead091c7e335b4b07459aa;hp=dea93e528e9b7c19cd7354d0f1fea59cd22e50aa;hpb=20a8dca57fc579dbb0641ccd6dec2686d0ffdf1b;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index dea93e528e9..4afc55b40c3 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -882,7 +882,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index); ret = avfilter_graph_create_filter(&ofilter->filter, - avfilter_get_by_name("abuffersink_old"), + avfilter_get_by_name("abuffersink"), name, NULL, NULL, fg->graph); if (ret < 0) return ret; @@ -1077,7 +1077,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s" ":channel_layout=0x%"PRIx64, - ist->st->time_base.num, ist->st->time_base.den, + 1, ist->st->codec->sample_rate, ist->st->codec->sample_rate, av_get_sample_fmt_name(ist->st->codec->sample_fmt), ist->st->codec->channel_layout); @@ -1570,10 +1570,10 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; -#if 0 + if (!check_recording_time(ost)) return; -#endif + if (frame->pts == AV_NOPTS_VALUE || audio_sync_method < 0) frame->pts = ost->sync_opts; ost->sync_opts = frame->pts + frame->nb_samples; @@ -1681,6 +1681,8 @@ static void do_subtitle_out(AVFormatContext *s, for (i = 0; i < nb; i++) { ost->sync_opts = av_rescale_q(pts, ist->st->time_base, enc->time_base); + if (!check_recording_time(ost)) + return; sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q); // start_display_time is required to be 0 @@ -1770,6 +1772,11 @@ static void do_video_out(AVFormatContext *s, av_log(NULL, AV_LOG_VERBOSE, "*** drop!\n"); return; } else if (nb_frames > 1) { + if (nb_frames > dts_error_threshold * 30) { + av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skiping\n", nb_frames - 1); + nb_frames_drop++; + return; + } nb_frames_dup += nb_frames - 1; av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1); } @@ -1782,6 +1789,9 @@ duplicate_frame: in_picture->pts = ost->sync_opts; + if (!check_recording_time(ost)) + return; + if (s->oformat->flags & AVFMT_RAWPICTURE && enc->codec->id == CODEC_ID_RAWVIDEO) { /* raw pictures are written as AVPicture structure to @@ -1938,16 +1948,9 @@ static int poll_filters(void) avcodec_get_frame_defaults(ost->filtered_frame); filtered_frame = ost->filtered_frame; - while (!ost->is_past_recording_time) { - if (ost->enc->type == AVMEDIA_TYPE_AUDIO && - !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) - ret = av_buffersink_read_samples(ost->filter->filter, &picref, - ost->st->codec->frame_size); - else if(ost->enc->type == AVMEDIA_TYPE_AUDIO) - ret = av_buffersink_read(ost->filter->filter, &picref); - else - ret = av_buffersink_get_buffer_ref(ost->filter->filter, &picref, - AV_BUFFERSINK_FLAG_NO_REQUEST); + while (1) { + ret = av_buffersink_get_buffer_ref(ost->filter->filter, &picref, + AV_BUFFERSINK_FLAG_NO_REQUEST); if (ret < 0) { if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { char buf[256]; @@ -2244,13 +2247,6 @@ static int check_output_constraints(InputStream *ist, OutputStream *ost) if (of->start_time && ist->pts < of->start_time) return 0; - if (of->recording_time != INT64_MAX && - av_compare_ts(ist->pts, AV_TIME_BASE_Q, of->recording_time + of->start_time, - (AVRational){ 1, 1000000 }) >= 0) { - ost->is_past_recording_time = 1; - return 0; - } - return 1; } @@ -2267,6 +2263,12 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p !ost->copy_initial_nonkeyframes) return; + if (of->recording_time != INT64_MAX && + ist->pts >= of->recording_time + of->start_time) { + ost->is_past_recording_time = 1; + return; + } + /* force the input stream PTS */ if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) audio_size += pkt->size; @@ -2355,6 +2357,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) else avcodec_get_frame_defaults(ist->decoded_frame); decoded_frame = ist->decoded_frame; + av_codec_set_pkt_timebase(avctx, ist->st->time_base); update_benchmark(NULL); ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt); @@ -2432,13 +2435,27 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) ist->resample_channels = avctx->channels; for (i = 0; i < nb_filtergraphs; i++) - if (ist_in_filtergraph(filtergraphs[i], ist) && - configure_filtergraph(filtergraphs[i]) < 0) { - av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); - exit_program(1); + if (ist_in_filtergraph(filtergraphs[i], ist)) { + FilterGraph *fg = filtergraphs[i]; + int j; + if (configure_filtergraph(fg) < 0) { + av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); + exit_program(1); + } + for (j = 0; j < fg->nb_outputs; j++) { + OutputStream *ost = fg->outputs[j]->ost; + if (ost->enc->type == AVMEDIA_TYPE_AUDIO && + !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) + av_buffersink_set_frame_size(ost->filter->filter, + ost->st->codec->frame_size); + } } } + if (decoded_frame->pts != AV_NOPTS_VALUE) + decoded_frame->pts = av_rescale_q(decoded_frame->pts, + ist->st->time_base, + (AVRational){1, ist->st->codec->sample_rate}); for (i = 0; i < ist->nb_filters; i++) av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame, 0); @@ -2460,6 +2477,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) avcodec_get_frame_defaults(ist->decoded_frame); decoded_frame = ist->decoded_frame; pkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ist->st->time_base); + av_codec_set_pkt_timebase(ist->st->codec, ist->st->time_base); update_benchmark(NULL); ret = avcodec_decode_video2(ist->st->codec, @@ -2484,6 +2502,16 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) if(best_effort_timestamp != AV_NOPTS_VALUE) ist->next_pts = ist->pts = av_rescale_q(decoded_frame->pts = best_effort_timestamp, ist->st->time_base, AV_TIME_BASE_Q); + if (debug_ts) { + av_log(NULL, AV_LOG_INFO, "decoder -> ist_index:%d type:video " + "frame_pts:%s frame_pts_time:%s best_effort_ts:%"PRId64" best_effort_ts_time:%s keyframe:%d frame_type:%d \n", + ist->st->index, av_ts2str(decoded_frame->pts), + av_ts2timestr(decoded_frame->pts, &ist->st->time_base), + best_effort_timestamp, + av_ts2timestr(best_effort_timestamp, &ist->st->time_base), + decoded_frame->key_frame, decoded_frame->pict_type); + } + pkt->size = 0; pre_process_video_frame(ist, (AVPicture *)decoded_frame, &buffer_to_free); @@ -2792,12 +2820,17 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost, av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n"); exit_program(1); } + p = kf; for (i = 0; i < n; i++) { char *next = strchr(p, ','); - if (next) *next++ = 0; + + if (next) + *next++ = 0; + t = parse_time_or_die("force_key_frames", p, 1); ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); + p = next; } } @@ -3108,6 +3141,10 @@ static int transcode_init(void) ret = AVERROR(EINVAL); goto dump_format; } + if (ost->enc->type == AVMEDIA_TYPE_AUDIO && + !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) + av_buffersink_set_frame_size(ost->filter->filter, + ost->st->codec->frame_size); assert_codec_experimental(ost->st->codec, 1); assert_avoptions(ost->opts); if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000) @@ -4142,7 +4179,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) ist->file_index = nb_input_files; ist->discard = 1; st->discard = AVDISCARD_ALL; - ist->opts = filter_codec_opts(codec_opts, choose_decoder(o, ic, st), ic, st); + ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st, choose_decoder(o, ic, st)); ist->ts_scale = 1.0; MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st); @@ -4498,7 +4535,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e st->codec->codec_type = type; choose_encoder(o, oc, ost); if (ost->enc) { - ost->opts = filter_codec_opts(codec_opts, ost->enc, oc, st); + ost->opts = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc); } avcodec_get_context_defaults3(st->codec, ost->enc);