|
@@ -123,6 +123,7 @@ const char *const forced_keyframes_const_names[] = {
|
|
|
static void do_video_stats(OutputStream *ost, int frame_size);
|
|
|
static int64_t getutime(void);
|
|
|
static int64_t getmaxrss(void);
|
|
|
+static int ifilter_has_all_input_formats(FilterGraph *fg);
|
|
|
|
|
|
static int run_as_daemon = 0;
|
|
|
static int nb_frames_dup = 0;
|
|
@@ -472,6 +473,13 @@ static void ffmpeg_cleanup(int ret)
|
|
|
FilterGraph *fg = filtergraphs[i];
|
|
|
avfilter_graph_free(&fg->graph);
|
|
|
for (j = 0; j < fg->nb_inputs; j++) {
|
|
|
+ while (av_fifo_size(fg->inputs[j]->frame_queue)) {
|
|
|
+ AVFrame *frame;
|
|
|
+ av_fifo_generic_read(fg->inputs[j]->frame_queue, &frame,
|
|
|
+ sizeof(frame), NULL);
|
|
|
+ av_frame_free(&frame);
|
|
|
+ }
|
|
|
+ av_fifo_free(fg->inputs[j]->frame_queue);
|
|
|
av_buffer_unref(&fg->inputs[j]->hw_frames_ctx);
|
|
|
av_freep(&fg->inputs[j]->name);
|
|
|
av_freep(&fg->inputs[j]);
|
|
@@ -1377,6 +1385,8 @@ static void do_video_stats(OutputStream *ost, int frame_size)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static int init_output_stream(OutputStream *ost, char *error, int error_len);
|
|
|
+
|
|
|
static void finish_output_stream(OutputStream *ost)
|
|
|
{
|
|
|
OutputFile *of = output_files[ost->file_index];
|
|
@@ -1409,10 +1419,20 @@ static int reap_filters(int flush)
|
|
|
AVCodecContext *enc = ost->enc_ctx;
|
|
|
int ret = 0;
|
|
|
|
|
|
- if (!ost->filter)
|
|
|
+ if (!ost->filter || !ost->filter->graph->graph)
|
|
|
continue;
|
|
|
filter = ost->filter->filter;
|
|
|
|
|
|
+ if (!ost->initialized) {
|
|
|
+ char error[1024];
|
|
|
+ ret = init_output_stream(ost, error, sizeof(error));
|
|
|
+ if (ret < 0) {
|
|
|
+ av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n",
|
|
|
+ ost->file_index, ost->index, error);
|
|
|
+ exit_program(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) {
|
|
|
return AVERROR(ENOMEM);
|
|
|
}
|
|
@@ -1813,6 +1833,54 @@ static void flush_encoders(void)
|
|
|
if (!ost->encoding_needed)
|
|
|
continue;
|
|
|
|
|
|
+ // Try to enable encoding with no input frames.
|
|
|
+ // Maybe we should just let encoding fail instead.
|
|
|
+ if (!ost->initialized) {
|
|
|
+ FilterGraph *fg = ost->filter->graph;
|
|
|
+ char error[1024];
|
|
|
+
|
|
|
+ av_log(NULL, AV_LOG_WARNING,
|
|
|
+ "Finishing stream %d:%d without any data written to it.\n",
|
|
|
+ ost->file_index, ost->st->index);
|
|
|
+
|
|
|
+ if (ost->filter && !fg->graph) {
|
|
|
+ int x;
|
|
|
+ for (x = 0; x < fg->nb_inputs; x++) {
|
|
|
+ InputFilter *ifilter = fg->inputs[x];
|
|
|
+ if (ifilter->format < 0) {
|
|
|
+ AVCodecParameters *par = ifilter->ist->st->codecpar;
|
|
|
+ // We never got any input. Set a fake format, which will
|
|
|
+ // come from libavformat.
|
|
|
+ ifilter->format = par->format;
|
|
|
+ ifilter->sample_rate = par->sample_rate;
|
|
|
+ ifilter->channels = par->channels;
|
|
|
+ ifilter->channel_layout = par->channel_layout;
|
|
|
+ ifilter->width = par->width;
|
|
|
+ ifilter->height = par->height;
|
|
|
+ ifilter->sample_aspect_ratio = par->sample_aspect_ratio;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ifilter_has_all_input_formats(fg))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ ret = configure_filtergraph(fg);
|
|
|
+ if (ret < 0) {
|
|
|
+ av_log(NULL, AV_LOG_ERROR, "Error configuring filter graph\n");
|
|
|
+ exit_program(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ finish_output_stream(ost);
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = init_output_stream(ost, error, sizeof(error));
|
|
|
+ if (ret < 0) {
|
|
|
+ av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n",
|
|
|
+ ost->file_index, ost->index, error);
|
|
|
+ exit_program(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (enc->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1)
|
|
|
continue;
|
|
|
#if FF_API_LAVF_FMT_RAWPICTURE
|
|
@@ -2044,6 +2112,102 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// Filters can be configured only if the formats of all inputs are known.
|
|
|
+static int ifilter_has_all_input_formats(FilterGraph *fg)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ for (i = 0; i < fg->nb_inputs; i++) {
|
|
|
+ if (fg->inputs[i]->format < 0 && (fg->inputs[i]->type == AVMEDIA_TYPE_AUDIO ||
|
|
|
+ fg->inputs[i]->type == AVMEDIA_TYPE_VIDEO))
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
|
|
+{
|
|
|
+ FilterGraph *fg = ifilter->graph;
|
|
|
+ int need_reinit, ret, i;
|
|
|
+
|
|
|
+ /* determine if the parameters for this input changed */
|
|
|
+ need_reinit = ifilter->format != frame->format;
|
|
|
+ if (!!ifilter->hw_frames_ctx != !!frame->hw_frames_ctx ||
|
|
|
+ (ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data))
|
|
|
+ need_reinit = 1;
|
|
|
+
|
|
|
+ switch (ifilter->ist->st->codecpar->codec_type) {
|
|
|
+ case AVMEDIA_TYPE_AUDIO:
|
|
|
+ need_reinit |= ifilter->sample_rate != frame->sample_rate ||
|
|
|
+ ifilter->channels != frame->channels ||
|
|
|
+ ifilter->channel_layout != frame->channel_layout;
|
|
|
+ break;
|
|
|
+ case AVMEDIA_TYPE_VIDEO:
|
|
|
+ need_reinit |= ifilter->width != frame->width ||
|
|
|
+ ifilter->height != frame->height;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (need_reinit) {
|
|
|
+ ret = ifilter_parameters_from_frame(ifilter, frame);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* (re)init the graph if possible, otherwise buffer the frame and return */
|
|
|
+ if (need_reinit || !fg->graph) {
|
|
|
+ for (i = 0; i < fg->nb_inputs; i++) {
|
|
|
+ if (!ifilter_has_all_input_formats(fg)) {
|
|
|
+ AVFrame *tmp = av_frame_clone(frame);
|
|
|
+ if (!tmp)
|
|
|
+ return AVERROR(ENOMEM);
|
|
|
+ av_frame_unref(frame);
|
|
|
+
|
|
|
+ if (!av_fifo_space(ifilter->frame_queue)) {
|
|
|
+ ret = av_fifo_realloc2(ifilter->frame_queue, 2 * av_fifo_size(ifilter->frame_queue));
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ av_fifo_generic_write(ifilter->frame_queue, &tmp, sizeof(tmp), NULL);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = reap_filters(1);
|
|
|
+ if (ret < 0 && ret != AVERROR_EOF) {
|
|
|
+ char errbuf[128];
|
|
|
+ av_strerror(ret, errbuf, sizeof(errbuf));
|
|
|
+
|
|
|
+ av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", errbuf);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = configure_filtergraph(fg);
|
|
|
+ if (ret < 0) {
|
|
|
+ av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < fg->nb_inputs; i++) {
|
|
|
+ while (av_fifo_size(fg->inputs[i]->frame_queue)) {
|
|
|
+ AVFrame *tmp;
|
|
|
+ av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL);
|
|
|
+ ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp);
|
|
|
+ av_frame_free(&tmp);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = av_buffersrc_add_frame_flags(ifilter->filter, frame, AV_BUFFERSRC_FLAG_PUSH);
|
|
|
+ if (ret < 0) {
|
|
|
+ av_log(NULL, AV_LOG_ERROR, "Error while filtering\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2.
|
|
|
// There is the following difference: if you got a frame, you must call
|
|
|
// it again with pkt=NULL. pkt==NULL is treated differently from pkt.size==0
|
|
@@ -2085,8 +2249,7 @@ static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame)
|
|
|
break;
|
|
|
} else
|
|
|
f = decoded_frame;
|
|
|
- ret = av_buffersrc_add_frame_flags(ist->filters[i]->filter, f,
|
|
|
- AV_BUFFERSRC_FLAG_PUSH);
|
|
|
+ ret = ifilter_send_frame(ist->filters[i], f);
|
|
|
if (ret == AVERROR_EOF)
|
|
|
ret = 0; /* ignore */
|
|
|
if (ret < 0) {
|
|
@@ -2102,7 +2265,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
|
|
{
|
|
|
AVFrame *decoded_frame;
|
|
|
AVCodecContext *avctx = ist->dec_ctx;
|
|
|
- int i, ret, err = 0, resample_changed;
|
|
|
+ int ret, err = 0;
|
|
|
AVRational decoded_frame_tb;
|
|
|
|
|
|
if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc()))
|
|
@@ -2138,59 +2301,6 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
|
|
avctx->sample_rate;
|
|
|
#endif
|
|
|
|
|
|
- resample_changed = ist->resample_sample_fmt != decoded_frame->format ||
|
|
|
- ist->resample_channels != avctx->channels ||
|
|
|
- ist->resample_channel_layout != decoded_frame->channel_layout ||
|
|
|
- ist->resample_sample_rate != decoded_frame->sample_rate;
|
|
|
- if (resample_changed) {
|
|
|
- char layout1[64], layout2[64];
|
|
|
-
|
|
|
- if (!guess_input_channel_layout(ist)) {
|
|
|
- av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
|
|
|
- "layout for Input Stream #%d.%d\n", ist->file_index,
|
|
|
- ist->st->index);
|
|
|
- exit_program(1);
|
|
|
- }
|
|
|
- decoded_frame->channel_layout = avctx->channel_layout;
|
|
|
-
|
|
|
- av_get_channel_layout_string(layout1, sizeof(layout1), ist->resample_channels,
|
|
|
- ist->resample_channel_layout);
|
|
|
- av_get_channel_layout_string(layout2, sizeof(layout2), avctx->channels,
|
|
|
- decoded_frame->channel_layout);
|
|
|
-
|
|
|
- av_log(NULL, AV_LOG_INFO,
|
|
|
- "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d chl:%s to rate:%d fmt:%s ch:%d chl:%s\n",
|
|
|
- ist->file_index, ist->st->index,
|
|
|
- ist->resample_sample_rate, av_get_sample_fmt_name(ist->resample_sample_fmt),
|
|
|
- ist->resample_channels, layout1,
|
|
|
- decoded_frame->sample_rate, av_get_sample_fmt_name(decoded_frame->format),
|
|
|
- avctx->channels, layout2);
|
|
|
-
|
|
|
- ist->resample_sample_fmt = decoded_frame->format;
|
|
|
- ist->resample_sample_rate = decoded_frame->sample_rate;
|
|
|
- ist->resample_channel_layout = decoded_frame->channel_layout;
|
|
|
- ist->resample_channels = avctx->channels;
|
|
|
-
|
|
|
- for (i = 0; i < ist->nb_filters; i++) {
|
|
|
- err = ifilter_parameters_from_frame(ist->filters[i], decoded_frame);
|
|
|
- if (err < 0) {
|
|
|
- av_log(NULL, AV_LOG_ERROR,
|
|
|
- "Error reconfiguring input stream %d:%d filter %d\n",
|
|
|
- ist->file_index, ist->st->index, i);
|
|
|
- goto fail;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for (i = 0; i < nb_filtergraphs; i++)
|
|
|
- if (ist_in_filtergraph(filtergraphs[i], ist)) {
|
|
|
- FilterGraph *fg = filtergraphs[i];
|
|
|
- if (configure_filtergraph(fg) < 0) {
|
|
|
- av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
|
|
|
- exit_program(1);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
if (decoded_frame->pts != AV_NOPTS_VALUE) {
|
|
|
decoded_frame_tb = ist->st->time_base;
|
|
|
} else if (pkt && pkt->pts != AV_NOPTS_VALUE) {
|
|
@@ -2206,9 +2316,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
|
|
(AVRational){1, avctx->sample_rate});
|
|
|
ist->nb_samples = decoded_frame->nb_samples;
|
|
|
err = send_frame_to_filters(ist, decoded_frame);
|
|
|
- decoded_frame->pts = AV_NOPTS_VALUE;
|
|
|
|
|
|
-fail:
|
|
|
av_frame_unref(ist->filter_frame);
|
|
|
av_frame_unref(decoded_frame);
|
|
|
return err < 0 ? err : ret;
|
|
@@ -2217,7 +2325,7 @@ fail:
|
|
|
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eof)
|
|
|
{
|
|
|
AVFrame *decoded_frame;
|
|
|
- int i, ret = 0, err = 0, resample_changed;
|
|
|
+ int i, ret = 0, err = 0;
|
|
|
int64_t best_effort_timestamp;
|
|
|
int64_t dts = AV_NOPTS_VALUE;
|
|
|
AVPacket avpkt;
|
|
@@ -2332,39 +2440,6 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eo
|
|
|
if (ist->st->sample_aspect_ratio.num)
|
|
|
decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio;
|
|
|
|
|
|
- resample_changed = ist->resample_width != decoded_frame->width ||
|
|
|
- ist->resample_height != decoded_frame->height ||
|
|
|
- ist->resample_pix_fmt != decoded_frame->format;
|
|
|
- if (resample_changed) {
|
|
|
- av_log(NULL, AV_LOG_INFO,
|
|
|
- "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
|
|
|
- ist->file_index, ist->st->index,
|
|
|
- ist->resample_width, ist->resample_height, av_get_pix_fmt_name(ist->resample_pix_fmt),
|
|
|
- decoded_frame->width, decoded_frame->height, av_get_pix_fmt_name(decoded_frame->format));
|
|
|
-
|
|
|
- ist->resample_width = decoded_frame->width;
|
|
|
- ist->resample_height = decoded_frame->height;
|
|
|
- ist->resample_pix_fmt = decoded_frame->format;
|
|
|
-
|
|
|
- for (i = 0; i < ist->nb_filters; i++) {
|
|
|
- err = ifilter_parameters_from_frame(ist->filters[i], decoded_frame);
|
|
|
- if (err < 0) {
|
|
|
- av_log(NULL, AV_LOG_ERROR,
|
|
|
- "Error reconfiguring input stream %d:%d filter %d\n",
|
|
|
- ist->file_index, ist->st->index, i);
|
|
|
- goto fail;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for (i = 0; i < nb_filtergraphs; i++) {
|
|
|
- if (ist_in_filtergraph(filtergraphs[i], ist) && ist->reinit_filters &&
|
|
|
- configure_filtergraph(filtergraphs[i]) < 0) {
|
|
|
- av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
|
|
|
- exit_program(1);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
err = send_frame_to_filters(ist, decoded_frame);
|
|
|
|
|
|
fail:
|
|
@@ -2434,11 +2509,18 @@ out:
|
|
|
|
|
|
static int send_filter_eof(InputStream *ist)
|
|
|
{
|
|
|
- int i, ret;
|
|
|
+ int i, j, ret;
|
|
|
for (i = 0; i < ist->nb_filters; i++) {
|
|
|
- ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
+ if (ist->filters[i]->filter) {
|
|
|
+ ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+ } else {
|
|
|
+ // the filtergraph was never configured
|
|
|
+ FilterGraph *fg = ist->filters[i]->graph;
|
|
|
+ for (j = 0; j < fg->nb_outputs; j++)
|
|
|
+ finish_output_stream(fg->outputs[j]->ost);
|
|
|
+ }
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -2544,6 +2626,9 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+ if (got_output)
|
|
|
+ ist->got_output = 1;
|
|
|
+
|
|
|
if (!got_output)
|
|
|
break;
|
|
|
|
|
@@ -2721,17 +2806,9 @@ static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
|
|
|
|
|
|
static int init_input_stream(int ist_index, char *error, int error_len)
|
|
|
{
|
|
|
- int i, ret;
|
|
|
+ int ret;
|
|
|
InputStream *ist = input_streams[ist_index];
|
|
|
|
|
|
- for (i = 0; i < ist->nb_filters; i++) {
|
|
|
- ret = ifilter_parameters_from_decoder(ist->filters[i], ist->dec_ctx);
|
|
|
- if (ret < 0) {
|
|
|
- av_log(NULL, AV_LOG_FATAL, "Error initializing filter input\n");
|
|
|
- return ret;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
if (ist->decoding_needed) {
|
|
|
AVCodec *codec = ist->dec;
|
|
|
if (!codec) {
|
|
@@ -3125,17 +3202,6 @@ static int init_output_stream_encode(OutputStream *ost)
|
|
|
ost->st->disposition = AV_DISPOSITION_DEFAULT;
|
|
|
}
|
|
|
|
|
|
- if ((enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
|
|
|
- enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
|
|
|
- filtergraph_is_simple(ost->filter->graph)) {
|
|
|
- FilterGraph *fg = ost->filter->graph;
|
|
|
-
|
|
|
- if (configure_filtergraph(fg)) {
|
|
|
- av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
|
|
|
- exit_program(1);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
if (enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
|
|
if (!ost->frame_rate.num)
|
|
|
ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter);
|
|
@@ -3475,10 +3541,6 @@ static int transcode_init(void)
|
|
|
ost = output_streams[i];
|
|
|
|
|
|
if (!ost->stream_copy) {
|
|
|
-#if CONFIG_LIBMFX
|
|
|
- if (qsv_transcode_init(ost))
|
|
|
- exit_program(1);
|
|
|
-#endif
|
|
|
|
|
|
#if CONFIG_CUVID
|
|
|
if (cuvid_transcode_init(ost))
|
|
@@ -3499,6 +3561,10 @@ static int transcode_init(void)
|
|
|
|
|
|
/* open each encoder */
|
|
|
for (i = 0; i < nb_output_streams; i++) {
|
|
|
+ // skip streams fed from filtergraphs until we have a frame for them
|
|
|
+ if (output_streams[i]->filter)
|
|
|
+ continue;
|
|
|
+
|
|
|
ret = init_output_stream(output_streams[i], error, sizeof(error));
|
|
|
if (ret < 0)
|
|
|
goto dump_format;
|
|
@@ -3669,6 +3735,9 @@ static OutputStream *choose_output(void)
|
|
|
if (ost->st->cur_dts == AV_NOPTS_VALUE)
|
|
|
av_log(NULL, AV_LOG_DEBUG, "cur_dts is invalid (this is harmless if it occurs once at the start per stream)\n");
|
|
|
|
|
|
+ if (!ost->initialized && !ost->inputs_done)
|
|
|
+ return ost;
|
|
|
+
|
|
|
if (!ost->finished && opts < opts_min) {
|
|
|
opts_min = opts;
|
|
|
ost_min = ost->unavailable ? NULL : ost;
|
|
@@ -4326,7 +4395,7 @@ static int transcode_from_filter(FilterGraph *graph, InputStream **best_ist)
|
|
|
static int transcode_step(void)
|
|
|
{
|
|
|
OutputStream *ost;
|
|
|
- InputStream *ist;
|
|
|
+ InputStream *ist = NULL;
|
|
|
int ret;
|
|
|
|
|
|
ost = choose_output();
|
|
@@ -4340,11 +4409,34 @@ static int transcode_step(void)
|
|
|
return AVERROR_EOF;
|
|
|
}
|
|
|
|
|
|
- if (ost->filter) {
|
|
|
+ if (ost->filter && !ost->filter->graph->graph) {
|
|
|
+ if (ifilter_has_all_input_formats(ost->filter->graph)) {
|
|
|
+ ret = configure_filtergraph(ost->filter->graph);
|
|
|
+ if (ret < 0) {
|
|
|
+ av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ost->filter && ost->filter->graph->graph) {
|
|
|
if ((ret = transcode_from_filter(ost->filter->graph, &ist)) < 0)
|
|
|
return ret;
|
|
|
if (!ist)
|
|
|
return 0;
|
|
|
+ } else if (ost->filter) {
|
|
|
+ int i;
|
|
|
+ for (i = 0; i < ost->filter->graph->nb_inputs; i++) {
|
|
|
+ InputFilter *ifilter = ost->filter->graph->inputs[i];
|
|
|
+ if (!ifilter->ist->got_output && !input_files[ifilter->ist->file_index]->eof_reached) {
|
|
|
+ ist = ifilter->ist;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!ist) {
|
|
|
+ ost->inputs_done = 1;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
} else {
|
|
|
av_assert0(ost->source_index >= 0);
|
|
|
ist = input_streams[ost->source_index];
|