diff options
-rw-r--r-- | fftools/ffmpeg.c | 18 | ||||
-rw-r--r-- | fftools/ffmpeg.h | 8 | ||||
-rw-r--r-- | fftools/ffmpeg_demux.c | 7 | ||||
-rw-r--r-- | fftools/ffmpeg_filter.c | 59 |
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; |