Я пытаюсь использовать FFmpeg C api для создания фильтра для объединения двух аудиопотоков. Попытка выполнить код отсюда: Implementing a multiple input filter graph with the Libavfilter library in Android NDK«invalid argument» для av_buffersrc_write_frame/av_buffersrc_add_frame
Все, кажется, в порядке.
Однако, как только я называю av_buffersrc_write_frame (или av_buffersrc_add_frame или av_buffersrc_add_frame_flags, это не имеет значения), FFmpeg просто сообщает «недопустимый аргумент», и больше ничего - сообщение совершенно бесполезные ошибки, так как это может означать все.
Какой аргумент недействителен? Что в этом плохого? Никто не знает.
Я инициализация граф и «захват» контексты источников буфера для последующего использования, как это:
// 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;
}
}
Там нет абсолютно никаких ошибок инициализации. По крайней мере, FFmpeg только это, чтобы сказать об этом, что я думаю, что хорошо выглядит:
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'
Тогда я пытаюсь добавить рамку (которая была декодируется заранее), как это:
// "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;
}
И результатом является упомянутый «недопустимый аргумент».
Buff_source_context является одним из тех, что отмечены в коде выше, и input_frame отлично подходит. Перед добавлением кода фильтрации один и тот же кадр был передан вместо кодера без проблем.
Я в недоумении от того, что может быть здесь. Я регистрирую ошибки FFmpeg на минимально возможном уровне, но не отображается ни одна ошибка. Я использую FFmpeg 3.1.1.
A -1, закрытое голосование, удаление тега и отсутствие комментариев к нему. Почему, это ужасно полезно, спасибо;) – TheSHEEEP
Я не совсем уверен в внешности вашего кода, но разве это не «фильтрконтекст» или «buffer_source_context» при записи фрейма? – WLGfx
Я не уверен, что понимаю. AVFilterContext * - это тип «buffer_source_context». И вы должны добавить кадры в источник буфера графа фильтра, чтобы FFmpeg обрабатывал их. И, как я писал, «buffer_source_context» является одним из контекстов источника буфера из этой строки: «Входы [i] .buffer_source_context = filterContext;» – TheSHEEEP