Я хочу закодировать прямой эфир в webm
, но ffmpeg
застревает в живом замке через 5 секунд, заявив
[webm @ 0x1d81940] Starting new cluster at offset 0 bytes, pts 5040dts 5040
Я пытался увеличить связанный AVFormatContext
Титулы
av_opt_set_int(oc->priv_data, "chunk_duration", INT_MAX, 0);
av_opt_set_int(oc->priv_data, "cluster_time_limit", INT_MAX, 0);
av_opt_set_int(oc->priv_data, "cluster_size_limit", INT_MAX, 0);
что позволяет избежать ошибки в течение 30 секунд, но затем снова ffmpeg
виснет
[webm @ 0xbc9940] Starting new cluster due to timestamp
[webm @ 0xbc9940] Starting new cluster at offset 0 bytes, pts 32800dts 32800
Ошибка может быть воспроизведена на официальном примере doc/examples/muxing.c
просто записав в буфер вместо файла, как это
oc = avformat_alloc_context();
oc->oformat = av_guess_format("webm", NULL, NULL);
oc->oformat->flags |= AVFMT_NOFILE;
и для фактического написания
uint8_t *output_buf;
avio_open_dyn_buf(&oc->pb);
avformat_write_header(oc, &opt);
/* or */
av_interleaved_write_frame(fmt_ctx, pkt);
avio_close_dyn_buf(oc->pb, &output_buf);
av_free(output_buf);
Как я могу закодировать webm в буфер?
(И почему это работает для файлов?)
Наверное, webm
Формат выполняет какие-то асинхронные операции записи, которые каким-то образом отделены от av_write_frame
звонки.
Тем не менее, я смог решить мою проблему путем реализации надлежащего AVIOContext
.
Чтобы настроить пользовательский ввод-вывод, вам нужна функция обратного вызова, которая должна выглядеть примерно так:
static int dispatch_output_packet(void* opaque, uint8_t* buffer, int buffer_size)
{
YourOutputType *out = (YourOutputType*) opaque;
int result = out->do_something(buffer, buffer_size);
return 0;
}
Затем создайте AVIOContext
и подключите его:
size_t io_buffer_size = 3 * 1024 * 1024;
io_buffer = new unsigned char[io_buffer_size];
AVIOContext* io_ctx = avio_alloc_context(io_buffer, io_buffer_size, AVIO_FLAG_WRITE, &your_output_object, NULL, dispatch_output_packet, NULL);
io_ctx->seekable = 0;
format_context_->oformat->flags |= AVFMT_FLAG_CUSTOM_IO;
format_context_->oformat->flags |= AVFMT_NOFILE;
format_context_->pb = io_ctx;
Других решений пока нет …