@@ -1142,26 +1142,8 @@ void enc_flush(void)
AVCodecContext *enc = ost->enc_ctx;
OutputFile *of = output_files[ost->file_index];
- if (!enc)
- continue;
-
- // Try to enable encoding with no input frames.
- // Maybe we should just let encoding fail instead.
- if (!e->opened) {
- FilterGraph *fg = ost->filter->graph;
-
- av_log(ost, AV_LOG_WARNING,
- "Finishing stream without any data written to it.\n");
-
- if (!fg->graph)
- continue;
-
- ret = enc_open(ost, NULL);
- if (ret < 0)
- exit_program(1);
- }
-
- if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO)
+ if (!enc || !e->opened ||
+ (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO))
continue;
ret = submit_encode_frame(of, ost, NULL);
@@ -143,11 +143,17 @@ typedef struct OutputFilterPriv {
int sample_rate;
AVChannelLayout ch_layout;
+ AVRational time_base;
+ AVRational sample_aspect_ratio;
+
// those are only set if no format is specified and the encoder gives us multiple options
// They point directly to the relevant lists of the encoder.
const int *formats;
const AVChannelLayout *ch_layouts;
const int *sample_rates;
+
+ // set to 1 after at least one frame passed through this output
+ int got_frame;
} OutputFilterPriv;
static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter)
@@ -1576,6 +1582,9 @@ static int configure_filtergraph(FilterGraph *fg)
ofp->width = av_buffersink_get_w(sink);
ofp->height = av_buffersink_get_h(sink);
+ ofp->time_base = av_buffersink_get_time_base(sink);
+ ofp->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink);
+
ofp->sample_rate = av_buffersink_get_sample_rate(sink);
av_channel_layout_uninit(&ofp->ch_layout);
ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
@@ -1688,6 +1697,7 @@ int reap_filters(int flush)
{
/* Reap all buffers present in the buffer sinks */
for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ OutputFilterPriv *ofp;
FilterGraphPriv *fgp;
AVFrame *filtered_frame;
AVFilterContext *filter;
@@ -1697,6 +1707,7 @@ int reap_filters(int flush)
continue;
filter = ost->filter->filter;
fgp = fgp_from_fg(ost->filter->graph);
+ ofp = ofp_from_ofilter(ost->filter);
filtered_frame = fgp->frame;
@@ -1749,6 +1760,7 @@ int reap_filters(int flush)
enc_frame(ost, filtered_frame);
av_frame_unref(filtered_frame);
+ ofp->got_frame = 1;
}
}
@@ -1961,6 +1973,7 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference)
int fg_transcode_step(FilterGraph *graph, InputStream **best_ist)
{
+ FilterGraphPriv *fgp = fgp_from_fg(graph);
int i, ret;
int nb_requests, nb_requests_max = 0;
InputStream *ist;
@@ -1988,10 +2001,43 @@ int fg_transcode_step(FilterGraph *graph, InputStream **best_ist)
return reap_filters(0);
if (ret == AVERROR_EOF) {
- ret = reap_filters(1);
- for (i = 0; i < graph->nb_outputs; i++)
- close_output_stream(graph->outputs[i]->ost);
- return ret;
+ reap_filters(1);
+ for (int i = 0; i < graph->nb_outputs; i++) {
+ OutputFilter *ofilter = graph->outputs[i];
+ OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
+
+ // we are finished and no frames were ever seen at this output,
+ // at least initialize the encoder with a dummy frame
+ if (!ofp->got_frame) {
+ AVFrame *frame = fgp->frame;
+
+ frame->time_base = ofp->time_base;
+ frame->format = ofp->format;
+
+ frame->width = ofp->width;
+ frame->height = ofp->height;
+ frame->sample_aspect_ratio = ofp->sample_aspect_ratio;
+
+ frame->sample_rate = ofp->sample_rate;
+ if (ofp->ch_layout.nb_channels) {
+ ret = av_channel_layout_copy(&frame->ch_layout, &ofp->ch_layout);
+ if (ret < 0)
+ return ret;
+ }
+
+ av_assert0(!frame->buf[0]);
+
+ av_log(ofilter->ost, AV_LOG_WARNING,
+ "No filtered frames for output stream, trying to "
+ "initialize anyway.\n");
+
+ enc_open(ofilter->ost, frame);
+ av_frame_unref(frame);
+ }
+
+ close_output_stream(ofilter->ost);
+ }
+ return 0;
}
if (ret != AVERROR(EAGAIN))
return ret;