mirror of https://git.ffmpeg.org/ffmpeg.git
avconv: decouple configuring filtergraphs and setting input parameters
Currently, calling configure_filtergraph() will pull in the input parameters from the corresponding decoder context. This has the following disadvantages: - the decoded frame is a more proper source for this information - a filter accessing decoder data breaks proper layering Add functions for explicitly sending the input stream parameters to a filtergraph input - currently from a frame and a decoder. The decoder one will be dropped in future commits after some more restructuring.
This commit is contained in:
parent
398f015f07
commit
722ec3eb35
30
avconv.c
30
avconv.c
|
@ -147,6 +147,7 @@ static void avconv_cleanup(int ret)
|
|||
FilterGraph *fg = filtergraphs[i];
|
||||
avfilter_graph_free(&fg->graph);
|
||||
for (j = 0; j < fg->nb_inputs; j++) {
|
||||
av_buffer_unref(&fg->inputs[j]->hw_frames_ctx);
|
||||
av_freep(&fg->inputs[j]->name);
|
||||
av_freep(&fg->inputs[j]);
|
||||
}
|
||||
|
@ -1252,6 +1253,16 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
|||
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) &&
|
||||
configure_filtergraph(filtergraphs[i]) < 0) {
|
||||
|
@ -1279,6 +1290,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
|||
break;
|
||||
}
|
||||
|
||||
fail:
|
||||
av_frame_unref(ist->filter_frame);
|
||||
av_frame_unref(decoded_frame);
|
||||
return err < 0 ? err : ret;
|
||||
|
@ -1336,6 +1348,16 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
|
|||
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) &&
|
||||
configure_filtergraph(filtergraphs[i]) < 0) {
|
||||
|
@ -2061,6 +2083,14 @@ static int transcode_init(void)
|
|||
enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
|
||||
filtergraph_is_simple(ost->filter->graph)) {
|
||||
FilterGraph *fg = ost->filter->graph;
|
||||
|
||||
ret = ifilter_parameters_from_decoder(fg->inputs[0],
|
||||
dec_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error initializing filter input\n");
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
if (configure_filtergraph(fg)) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
|
||||
exit_program(1);
|
||||
|
|
14
avconv.h
14
avconv.h
|
@ -199,6 +199,17 @@ typedef struct InputFilter {
|
|||
struct InputStream *ist;
|
||||
struct FilterGraph *graph;
|
||||
uint8_t *name;
|
||||
|
||||
// parameters configured for this input
|
||||
int format;
|
||||
|
||||
int width, height;
|
||||
AVRational sample_aspect_ratio;
|
||||
|
||||
int sample_rate;
|
||||
uint64_t channel_layout;
|
||||
|
||||
AVBufferRef *hw_frames_ctx;
|
||||
} InputFilter;
|
||||
|
||||
typedef struct OutputFilter {
|
||||
|
@ -468,6 +479,9 @@ int filtergraph_is_simple(FilterGraph *fg);
|
|||
int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
|
||||
int init_complex_filtergraph(FilterGraph *fg);
|
||||
|
||||
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
|
||||
int ifilter_parameters_from_decoder(InputFilter *ifilter, const AVCodecContext *avctx);
|
||||
|
||||
int avconv_parse_options(int argc, char **argv);
|
||||
|
||||
int vdpau_init(AVCodecContext *s);
|
||||
|
|
|
@ -97,6 +97,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
|
|||
exit(1);
|
||||
fg->inputs[0]->ist = ist;
|
||||
fg->inputs[0]->graph = fg;
|
||||
fg->inputs[0]->format = -1;
|
||||
|
||||
GROW_ARRAY(ist->filters, ist->nb_filters);
|
||||
ist->filters[ist->nb_filters - 1] = fg->inputs[0];
|
||||
|
@ -172,6 +173,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
|
|||
exit(1);
|
||||
fg->inputs[fg->nb_inputs - 1]->ist = ist;
|
||||
fg->inputs[fg->nb_inputs - 1]->graph = fg;
|
||||
fg->inputs[fg->nb_inputs - 1]->format = -1;
|
||||
|
||||
GROW_ARRAY(ist->filters, ist->nb_filters);
|
||||
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
|
||||
|
@ -505,15 +507,12 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
|||
if (!par)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
par->sample_aspect_ratio = ist->st->sample_aspect_ratio.num ?
|
||||
ist->st->sample_aspect_ratio :
|
||||
ist->dec_ctx->sample_aspect_ratio;
|
||||
par->width = ist->dec_ctx->width;
|
||||
par->height = ist->dec_ctx->height;
|
||||
par->format = ist->hwaccel_retrieve_data ?
|
||||
ist->hwaccel_retrieved_pix_fmt : ist->dec_ctx->pix_fmt;
|
||||
par->sample_aspect_ratio = ifilter->sample_aspect_ratio;
|
||||
par->width = ifilter->width;
|
||||
par->height = ifilter->height;
|
||||
par->format = ifilter->format;
|
||||
par->time_base = tb;
|
||||
par->hw_frames_ctx = ist->hw_frames_ctx;
|
||||
par->hw_frames_ctx = ifilter->hw_frames_ctx;
|
||||
|
||||
ret = av_buffersrc_parameters_set(ifilter->filter, par);
|
||||
av_freep(&par);
|
||||
|
@ -597,10 +596,10 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
|||
if (!par)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
par->time_base = (AVRational){ 1, ist->dec_ctx->sample_rate };
|
||||
par->sample_rate = ist->dec_ctx->sample_rate;
|
||||
par->format = ist->dec_ctx->sample_fmt;
|
||||
par->channel_layout = ist->dec_ctx->channel_layout;
|
||||
par->time_base = (AVRational){ 1, ifilter->sample_rate };
|
||||
par->sample_rate = ifilter->sample_rate;
|
||||
par->format = ifilter->format;
|
||||
par->channel_layout = ifilter->channel_layout;
|
||||
|
||||
ret = av_buffersrc_parameters_set(ifilter->filter, par);
|
||||
av_freep(&par);
|
||||
|
@ -751,6 +750,53 @@ int configure_filtergraph(FilterGraph *fg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
|
||||
{
|
||||
av_buffer_unref(&ifilter->hw_frames_ctx);
|
||||
|
||||
ifilter->format = frame->format;
|
||||
|
||||
ifilter->width = frame->width;
|
||||
ifilter->height = frame->height;
|
||||
ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
|
||||
|
||||
ifilter->sample_rate = frame->sample_rate;
|
||||
ifilter->channel_layout = frame->channel_layout;
|
||||
|
||||
if (frame->hw_frames_ctx) {
|
||||
ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);
|
||||
if (!ifilter->hw_frames_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ifilter_parameters_from_decoder(InputFilter *ifilter, const AVCodecContext *avctx)
|
||||
{
|
||||
av_buffer_unref(&ifilter->hw_frames_ctx);
|
||||
|
||||
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
ifilter->format = avctx->pix_fmt;
|
||||
else
|
||||
ifilter->format = avctx->sample_fmt;
|
||||
|
||||
ifilter->width = avctx->width;
|
||||
ifilter->height = avctx->height;
|
||||
ifilter->sample_aspect_ratio = avctx->sample_aspect_ratio;
|
||||
|
||||
ifilter->sample_rate = avctx->sample_rate;
|
||||
ifilter->channel_layout = avctx->channel_layout;
|
||||
|
||||
if (avctx->hw_frames_ctx) {
|
||||
ifilter->hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx);
|
||||
if (!ifilter->hw_frames_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
|
||||
{
|
||||
int i;
|
||||
|
|
24
avconv_opt.c
24
avconv_opt.c
|
@ -1498,12 +1498,28 @@ static int init_complex_filters(void)
|
|||
|
||||
static int configure_complex_filters(void)
|
||||
{
|
||||
int i, ret = 0;
|
||||
int i, j, ret = 0;
|
||||
|
||||
for (i = 0; i < nb_filtergraphs; i++)
|
||||
if (!filtergraph_is_simple(filtergraphs[i]) &&
|
||||
(ret = configure_filtergraph(filtergraphs[i])) < 0)
|
||||
for (i = 0; i < nb_filtergraphs; i++) {
|
||||
FilterGraph *fg = filtergraphs[i];
|
||||
|
||||
if (filtergraph_is_simple(fg))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < fg->nb_inputs; j++) {
|
||||
ret = ifilter_parameters_from_decoder(fg->inputs[j],
|
||||
fg->inputs[j]->ist->dec_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Error initializing filtergraph %d input %d\n", i, j);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = configure_filtergraph(filtergraphs[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue