I am trying to use FFmpeg C api to create a filter to merge two audio streams. Trying to follow the code from here: Implementing a multiple input filter graph with the Libavfilter library in Android NDK
Everything seems to be alright.
However, as soon as I call av_buffersrc_write_frame (or av_buffersrc_add_frame or av_buffersrc_add_frame_flags, it doesn't matter), FFmpeg just reports "invalid argument" and nothing else - an utterly useless error message, as it could mean everything.
Which argument is invalid? What is wrong about it? Nobody knows.
I am initializing the graph and "grabbing" the contexts of the buffer sources for later use like this:
// Alloc filter graph
*filter_graph = avfilter_graph_alloc();
if ((*filter_graph) == NULL) {
os::log("Error: Cannot allocate filter graph.");
return AVERROR(ENOMEM);
}
// Building the filter string, ommitted
int result = avfilter_graph_parse2(*filter_graph, filterString.c_str(), &gis, &gos, NULL);
if (result < 0)
{
char errorBuf[1024];
av_make_error_string(errorBuf, 1024, result);
log("Error: Parsing filter string: %s", errorBuf);
return AVERROR_EXIT;
}
// Configure the graph
result = avfilter_graph_config(*filter_graph, NULL);
if (result < 0)
{
char errorBuf[1024];
av_make_error_string(errorBuf, 1024, result);
log("Error: Configuring filter graph: %s", errorBuf);
return AVERROR_EXIT;
}
// Get the buffer source and buffer sink contexts
for (unsigned int i = 0; i < (*filter_graph)->nb_filters; ++i) {
AVFilterContext* filterContext = (*filter_graph)->filters[i];
// The first two filters should be the abuffers
std::string name = filterContext->name;
if (name.find("abuffer") != name.npos && i < 2) {
inputs[i].buffer_source_context = filterContext;
}
// abuffersink is the one we need to get the converted frames from
if (name.find("abuffersink") != name.npos) {
*buffer_sink_context = filterContext;
}
}
There are absolutely no errors in the initialization. At least FFmpeg has only this to say about it, which I think looks good:
FFMPEG: [Parsed_abuffer_0 @ 0ddfe840] Setting 'time_base' to value '1/48000'
FFMPEG: [Parsed_abuffer_0 @ 0ddfe840] Setting 'sample_rate' to value '48000'
FFMPEG: [Parsed_abuffer_0 @ 0ddfe840] Setting 'sample_fmt' to value '1'
FFMPEG: [Parsed_abuffer_0 @ 0ddfe840] Setting 'channel_layout' to value '3'
FFMPEG: [Parsed_abuffer_0 @ 0ddfe840] Setting 'channels' to value '2'
FFMPEG: [Parsed_abuffer_0 @ 0ddfe840] tb:1/48000 samplefmt:s16 samplerate:48000 chlayout:3
FFMPEG: [Parsed_abuffer_1 @ 0ddfe500] Setting 'time_base' to value '1/44100'
FFMPEG: [Parsed_abuffer_1 @ 0ddfe500] Setting 'sample_rate' to value '44100'
FFMPEG: [Parsed_abuffer_1 @ 0ddfe500] Setting 'sample_fmt' to value '1'
FFMPEG: [Parsed_abuffer_1 @ 0ddfe500] Setting 'channel_layout' to value '3'
FFMPEG: [Parsed_abuffer_1 @ 0ddfe500] Setting 'channels' to value '2'
FFMPEG: [Parsed_abuffer_1 @ 0ddfe500] tb:1/44100 samplefmt:s16 samplerate:44100 chlayout:3
FFMPEG: [Parsed_volume_3 @ 0ddfe580] Setting 'volume' to value '2'
FFMPEG: [Parsed_aresample_4 @ 0ddfe660] Setting 'sample_rate' to value '48000'
FFMPEG: [Parsed_aformat_5 @ 0ddfe940] Setting 'sample_fmts' to value 'fltp'
FFMPEG: [Parsed_aformat_5 @ 0ddfe940] Setting 'channel_layouts' to value '3'
Then, I am trying to add a frame (that has been decoded beforehand) like this:
// "buffer_source_context" is one of the "inputs[i].buffer_source_context" from the code above
int result = av_buffersrc_write_frame( buffer_source_context,
input_frame);
if (result < 0) {
char errorBuf[1024];
av_make_error_string(errorBuf, 1024, result);
log("Error: While adding to buffer source: %s", errorBuf);
return AVERROR_EXIT;
}
And the result is the mentioned "invalid argument".
The buffer_source_context is one of those noted from the code above and the input_frame is perfectly fine as well. Before the filtering code was added, the same frame was passed to an encoder instead without a problem.
I am at a loss at what the error could be here. I log FFmpeg errors at the lowest possible level, but not a single error is shown. I am using FFmpeg 3.1.1.