Основываясь на примере муксинга, который поставляется с документами FFmpeg, я изменил его, начиная с формата ввода S16 и заканчивая FLTP (плоское стерео), и выводя его в веб-формат (стерео).
Поскольку ввод теперь FLTP, я заполняю два массива, затем снова кодирую в FLTP. На экране нет явных ошибок, но получающееся в результате веб-видео не воспроизводит аудио (только видео-контент). Это просто доказательство концепции в понимании вещей; вот добавленная (неочищенная) функция для заполнения входного стереофонического буфера FLTP:
static void get_audio_frame_for_planar_stereo(int16_t **samples, int frame_size, int nb_channels)
{
int j, i, v[2];
int16_t *q1 = (int16_t *) samples[0];
int16_t *q2 = (int16_t *) samples[1];
for (j = 0; j < frame_size; j++)
{
v[0] = (int)(sin(t) * 10000);
v[1] = (int)(tan(t) * 10000);
*q1++ = v[0];
*q2++ = v[1];
t += tincr;
tincr += tincr2;
}
}
Который я вызываю изнутри функции write_audio_frame ().
Обратите внимание также, что везде, где код ссылался на AV_SAMPLE_FMT_S16 в качестве входных данных, я изменил на AV_SAMPLE_FMT_FLTP.
Весь работающий источник здесь:
https://gist.github.com/anonymous/05d1d7662e9feafc45a6
При запуске с ffprobe.exe, с этими инструкциями:
ffprobe -show_packets output.webm >output.txt
Я не вижу ничего необычного, все значения pts / dts, кажется, на месте:
https://gist.github.com/anonymous/3ed0d6308700ab991704
Может ли кто-то выделить причину этой неверной интерпретации?
Спасибо за ваше время…
постскриптум Я использую Zeranoe FFmpeg для Windows (32-битная версия), созданная 9 января 2014 года 22:04:35 с gcc 4.8.2. (GCC)
Редактировать: Основываясь на вашем руководстве в другом месте, я попробовал следующее:
/* set options */
//av_opt_set_int (swr_ctx, "in_channel_count", c->channels, 0);
//av_opt_set_int (swr_ctx, "in_sample_rate", c->sample_rate, 0);
//av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
//av_opt_set_int (swr_ctx, "out_channel_count", c->channels, 0);
//av_opt_set_int (swr_ctx, "out_sample_rate", c->sample_rate, 0);
//av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
av_opt_set_int(swr_ctx, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0);
av_opt_set_int(swr_ctx, "in_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
av_opt_set_int(swr_ctx, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
av_opt_set_int(swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
И пересмотренная функция:
static void get_audio_frame_for_planar_stereo(uint8_t **samples, int frame_size, int nb_channels)
{
int j, i;
float v[2];
float *q1 = (float *) samples[0];
float *q2 = (float *) samples[1];
for (j = 0; j < frame_size; j++)
{
v[0] = (tan(t) * 1);
v[1] = (sin(t) * 1);
*q1++ = v[0];
*q2++ = v[1];
t += tincr;
tincr += tincr2;
}
}
Теперь, похоже, работает правильно. Я попытался изменить параметры функции с uint8_t ** на float **, а также src_samples_data с uint8_t ** на float **, но в представлении не было никакой разницы.
Обновленный код: https://gist.github.com/anonymous/35371b2c106961029c3d
Спасибо за выделение мест, которые приводят к такому поведению!
С AV_SAMPLE_FMT_FLTP каждая выборка должна быть 32-битной поплавок значение (от -1,0 до 1,0). Вы также инициализируете ресамплер, чтобы принимать значения с плавающей точкой:
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
но наполняя его массивом целых чисел:
get_audio_frame_for_planar_stereo( (int16_t **)src_samples_data, src_nb_samples, c->channels );
Других решений пока нет …