summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fftools/ffmpeg.c18
-rw-r--r--fftools/ffmpeg.h8
-rw-r--r--fftools/ffmpeg_demux.c7
-rw-r--r--fftools/ffmpeg_filter.c59
4 files changed, 67 insertions, 25 deletions
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index b1914822b4..929470f3f3 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -769,24 +769,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
first_report = 0;
}
-int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
-{
- int ret;
-
- // 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->width = par->width;
- ifilter->height = par->height;
- ifilter->sample_aspect_ratio = par->sample_aspect_ratio;
- ret = av_channel_layout_copy(&ifilter->ch_layout, &par->ch_layout);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
static void check_decode_result(InputStream *ist, int *got_output, int ret)
{
if (*got_output || ret<0)
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index b30f0758ec..602005f071 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -788,7 +788,13 @@ void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub);
int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference);
int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb);
-int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par);
+/**
+ * Set up fallback filtering parameters from a decoder context. They will only
+ * be used if no frames are ever sent on this input, otherwise the actual
+ * parameters are taken from the frame.
+ */
+int ifilter_parameters_from_dec(InputFilter *ifilter, const AVCodecContext *dec);
+
int ifilter_has_all_input_formats(FilterGraph *fg);
/**
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 9eea5a4eec..a0ef68a8a3 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -586,10 +586,17 @@ void ist_output_add(InputStream *ist, OutputStream *ost)
void ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple)
{
+ int ret;
+
ist_use(ist, is_simple ? DECODING_FOR_OST : DECODING_FOR_FILTER);
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = ifilter;
+
+ // initialize fallback parameters for filtering
+ ret = ifilter_parameters_from_dec(ifilter, ist->dec_ctx);
+ if (ret < 0)
+ report_and_exit(ret);
}
static const AVCodec *choose_decoder(const OptionsContext *o, AVFormatContext *s, AVStream *st,
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 8c408eb7c4..3fad38f782 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -58,6 +58,19 @@ typedef struct InputFilterPriv {
AVRational time_base;
AVFifo *frame_queue;
+
+ // fallback parameters to use when no input is ever sent
+ struct {
+ int format;
+
+ int width;
+ int height;
+ AVRational sample_aspect_ratio;
+
+ int sample_rate;
+ AVChannelLayout ch_layout;
+ } fallback;
+
} InputFilterPriv;
static InputFilterPriv *ifp_from_ifilter(InputFilter *ifilter)
@@ -225,6 +238,8 @@ static InputFilter *ifilter_alloc(FilterGraph *fg)
ifilter->graph = fg;
ifilter->format = -1;
+ ifp->fallback.format = -1;
+
ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifp->frame_queue)
report_and_exit(AVERROR(ENOMEM));
@@ -260,6 +275,9 @@ void fg_free(FilterGraph **pfg)
avsubtitle_free(&sub);
av_fifo_freep2(&ist->sub2video.sub_queue);
}
+
+ av_channel_layout_uninit(&ifp->fallback.ch_layout);
+
av_buffer_unref(&ifilter->hw_frames_ctx);
av_freep(&ifilter->name);
av_freep(&fg->inputs[j]);
@@ -1361,6 +1379,29 @@ fail:
return ret;
}
+int ifilter_parameters_from_dec(InputFilter *ifilter, const AVCodecContext *dec)
+{
+ InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
+
+ if (dec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ ifp->fallback.format = dec->pix_fmt;
+ ifp->fallback.width = dec->width;
+ ifp->fallback.height = dec->height;
+ ifp->fallback.sample_aspect_ratio = dec->sample_aspect_ratio;
+ } else {
+ int ret;
+
+ ifp->fallback.format = dec->sample_fmt;
+ ifp->fallback.sample_rate = dec->sample_rate;
+
+ ret = av_channel_layout_copy(&ifp->fallback.ch_layout, &dec->ch_layout);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
{
AVFrameSideData *sd;
@@ -1469,12 +1510,18 @@ int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb)
if (ret < 0)
return ret;
} else {
- // the filtergraph was never configured
- if (ifilter->format < 0) {
- ret = ifilter_parameters_from_codecpar(ifilter, ifilter->ist->par);
- if (ret < 0)
- return ret;
- }
+ // the filtergraph was never configured, use the fallback parameters
+ ifilter->format = ifp->fallback.format;
+ ifilter->sample_rate = ifp->fallback.sample_rate;
+ ifilter->width = ifp->fallback.width;
+ ifilter->height = ifp->fallback.height;
+ ifilter->sample_aspect_ratio = ifp->fallback.sample_aspect_ratio;
+
+ ret = av_channel_layout_copy(&ifilter->ch_layout,
+ &ifp->fallback.ch_layout);
+ if (ret < 0)
+ return ret;
+
if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) {
av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index);
return AVERROR_INVALIDDATA;