fftools/ffmpeg_filter: add an AVClass to FilterGraph

Use it for logging.
pull/389/head
Anton Khirnov 1 year ago
parent a934392db0
commit a7aa05c599
  1. 1
      fftools/ffmpeg.h
  2. 59
      fftools/ffmpeg_filter.c

@ -311,6 +311,7 @@ typedef struct OutputFilter {
} OutputFilter; } OutputFilter;
typedef struct FilterGraph { typedef struct FilterGraph {
const AVClass *class;
int index; int index;
AVFilterGraph *graph; AVFilterGraph *graph;

@ -41,6 +41,9 @@
typedef struct FilterGraphPriv { typedef struct FilterGraphPriv {
FilterGraph fg; FilterGraph fg;
// name used for logging
char log_name[32];
int is_simple; int is_simple;
const char *graph_desc; const char *graph_desc;
@ -692,7 +695,7 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
ret = configure_filtergraph(fg); ret = configure_filtergraph(fg);
if (ret < 0) { if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error configuring filter graph: %s\n", av_log(fg, AV_LOG_ERROR, "Error configuring filter graph: %s\n",
av_err2str(ret)); av_err2str(ret));
exit_program(1); exit_program(1);
} }
@ -775,6 +778,20 @@ void fg_free(FilterGraph **pfg)
av_freep(pfg); av_freep(pfg);
} }
static const char *fg_item_name(void *obj)
{
const FilterGraphPriv *fgp = obj;
return fgp->log_name;
}
static const AVClass fg_class = {
.class_name = "FilterGraph",
.version = LIBAVUTIL_VERSION_INT,
.item_name = fg_item_name,
.category = AV_CLASS_CATEGORY_FILTER,
};
FilterGraph *fg_create(char *graph_desc) FilterGraph *fg_create(char *graph_desc)
{ {
FilterGraphPriv *fgp = allocate_array_elem(&filtergraphs, sizeof(*fgp), &nb_filtergraphs); FilterGraphPriv *fgp = allocate_array_elem(&filtergraphs, sizeof(*fgp), &nb_filtergraphs);
@ -784,9 +801,12 @@ FilterGraph *fg_create(char *graph_desc)
AVFilterGraph *graph; AVFilterGraph *graph;
int ret = 0; int ret = 0;
fg->class = &fg_class;
fg->index = nb_filtergraphs - 1; fg->index = nb_filtergraphs - 1;
fgp->graph_desc = graph_desc; fgp->graph_desc = graph_desc;
snprintf(fgp->log_name, sizeof(fgp->log_name), "fc#%d", fg->index);
fgp->frame = av_frame_alloc(); fgp->frame = av_frame_alloc();
if (!fgp->frame) if (!fgp->frame)
report_and_exit(AVERROR(ENOMEM)); report_and_exit(AVERROR(ENOMEM));
@ -850,8 +870,12 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost,
fgp->is_simple = 1; fgp->is_simple = 1;
snprintf(fgp->log_name, sizeof(fgp->log_name), "%cf#%d:%d",
av_get_media_type_string(ost->type)[0],
ost->file_index, ost->index);
if (fg->nb_inputs != 1 || fg->nb_outputs != 1) { if (fg->nb_inputs != 1 || fg->nb_outputs != 1) {
av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' was expected " av_log(fg, AV_LOG_ERROR, "Simple filtergraph '%s' was expected "
"to have exactly 1 input and 1 output. " "to have exactly 1 input and 1 output. "
"However, it had %d input(s) and %d output(s). Please adjust, " "However, it had %d input(s) and %d output(s). Please adjust, "
"or use a complex filtergraph (-filter_complex) instead.\n", "or use a complex filtergraph (-filter_complex) instead.\n",
@ -880,7 +904,7 @@ static void init_input_filter(FilterGraph *fg, InputFilter *ifilter)
// TODO: support other filter types // TODO: support other filter types
if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) { if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported " av_log(fg, AV_LOG_FATAL, "Only video and audio filters supported "
"currently.\n"); "currently.\n");
exit_program(1); exit_program(1);
} }
@ -892,7 +916,7 @@ static void init_input_filter(FilterGraph *fg, InputFilter *ifilter)
int file_idx = strtol(ifp->linklabel, &p, 0); int file_idx = strtol(ifp->linklabel, &p, 0);
if (file_idx < 0 || file_idx >= nb_input_files) { if (file_idx < 0 || file_idx >= nb_input_files) {
av_log(NULL, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n", av_log(fg, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
file_idx, fgp->graph_desc); file_idx, fgp->graph_desc);
exit_program(1); exit_program(1);
} }
@ -910,7 +934,7 @@ static void init_input_filter(FilterGraph *fg, InputFilter *ifilter)
} }
} }
if (!st) { if (!st) {
av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s " av_log(fg, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
"matches no streams.\n", p, fgp->graph_desc); "matches no streams.\n", p, fgp->graph_desc);
exit_program(1); exit_program(1);
} }
@ -918,7 +942,7 @@ static void init_input_filter(FilterGraph *fg, InputFilter *ifilter)
} else { } else {
ist = ist_find_unused(type); ist = ist_find_unused(type);
if (!ist) { if (!ist) {
av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for " av_log(fg, AV_LOG_FATAL, "Cannot find a matching stream for "
"unlabeled input pad %s\n", ifilter->name); "unlabeled input pad %s\n", ifilter->name);
exit_program(1); exit_program(1);
} }
@ -927,7 +951,7 @@ static void init_input_filter(FilterGraph *fg, InputFilter *ifilter)
ret = ifilter_bind_ist(ifilter, ist); ret = ifilter_bind_ist(ifilter, ist);
if (ret < 0) { if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, av_log(fg, AV_LOG_ERROR,
"Error binding an input stream to complex filtergraph input %s.\n", "Error binding an input stream to complex filtergraph input %s.\n",
ifilter->name); ifilter->name);
exit_program(1); exit_program(1);
@ -1111,7 +1135,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
#define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \ #define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
AVFilterContext *filt_ctx; \ AVFilterContext *filt_ctx; \
\ \
av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi " \ av_log(fg, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
"similarly to -af " filter_name "=%s.\n", arg); \ "similarly to -af " filter_name "=%s.\n", arg); \
\ \
ret = avfilter_graph_create_filter(&filt_ctx, \ ret = avfilter_graph_create_filter(&filt_ctx, \
@ -1200,7 +1224,7 @@ static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter,
AVFilterInOut *out) AVFilterInOut *out)
{ {
if (!ofilter->ost) { if (!ofilter->ost) {
av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name); av_log(fg, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name);
exit_program(1); exit_program(1);
} }
@ -1219,7 +1243,8 @@ void check_filter_outputs(void)
for (n = 0; n < filtergraphs[i]->nb_outputs; n++) { for (n = 0; n < filtergraphs[i]->nb_outputs; n++) {
OutputFilter *output = filtergraphs[i]->outputs[n]; OutputFilter *output = filtergraphs[i]->outputs[n];
if (!output->ost) { if (!output->ost) {
av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", output->name); av_log(filtergraphs[i], AV_LOG_FATAL,
"Filter %s has an unconnected output\n", output->name);
exit_program(1); exit_program(1);
} }
} }
@ -1261,7 +1286,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
par->format = AV_PIX_FMT_NONE; par->format = AV_PIX_FMT_NONE;
if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
av_log(NULL, AV_LOG_ERROR, "Cannot connect video filter to audio input\n"); av_log(fg, AV_LOG_ERROR, "Cannot connect video filter to audio input\n");
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto fail; goto fail;
} }
@ -1376,7 +1401,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
int64_t tsoffset = 0; int64_t tsoffset = 0;
if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_AUDIO) { if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_AUDIO) {
av_log(NULL, AV_LOG_ERROR, "Cannot connect audio filter to non audio input\n"); av_log(fg, AV_LOG_ERROR, "Cannot connect audio filter to non audio input\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
@ -1685,7 +1710,7 @@ int reap_filters(int flush)
AV_BUFFERSINK_FLAG_NO_REQUEST); AV_BUFFERSINK_FLAG_NO_REQUEST);
if (ret < 0) { if (ret < 0) {
if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
av_log(NULL, AV_LOG_WARNING, av_log(fgp, AV_LOG_WARNING,
"Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret)); "Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret));
} else if (flush && ret == AVERROR_EOF) { } else if (flush && ret == AVERROR_EOF) {
if (av_buffersink_get_type(filter) == AVMEDIA_TYPE_VIDEO) if (av_buffersink_get_type(filter) == AVMEDIA_TYPE_VIDEO)
@ -1705,7 +1730,7 @@ int reap_filters(int flush)
filtered_frame->time_base = tb; filtered_frame->time_base = tb;
if (debug_ts) if (debug_ts)
av_log(NULL, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n", av_log(fgp, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n",
av_ts2str(filtered_frame->pts), av_ts2str(filtered_frame->pts),
av_ts2timestr(filtered_frame->pts, &tb), av_ts2timestr(filtered_frame->pts, &tb),
tb.num, tb.den); tb.num, tb.den);
@ -1896,13 +1921,13 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference)
ret = reap_filters(0); ret = reap_filters(0);
if (ret < 0 && ret != AVERROR_EOF) { if (ret < 0 && ret != AVERROR_EOF) {
av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret)); av_log(fg, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
return ret; return ret;
} }
ret = configure_filtergraph(fg); ret = configure_filtergraph(fg);
if (ret < 0) { if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n"); av_log(fg, AV_LOG_ERROR, "Error reinitializing filters!\n");
return ret; return ret;
} }
} }
@ -1929,7 +1954,7 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference)
if (ret < 0) { if (ret < 0) {
av_frame_unref(frame); av_frame_unref(frame);
if (ret != AVERROR_EOF) if (ret != AVERROR_EOF)
av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret)); av_log(fg, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
return ret; return ret;
} }

Loading…
Cancel
Save