Как вызвать av_read_frame(), если потоковые данные еще недоступны?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как вызвать av_read_frame(), если потоковые данные еще недоступны?

Сообщение Anonymous »

Я передаю аудиоданные в потоковом режиме и использую библиотеки ffmpeg/libav для их обработки на C++. Я создаю функцию CustomIOContext и read_packet для передачи потоковых данных в ffmpeg, а также создаю AVFormatContext, используя этот CustomIOContext.
Я хочу просмотреть все доступные данные и извлечь пакеты с помощью av_read_frame(), а затем, когда для создания пакета останется недостаточно данных, я хочу подождать, пока не получу больше данных, а затем снова пройтись по новым данным. Однако я не могу понять, что вернуть в моей функции read_packet ниже, чтобы указать ffmpeg подождать, пока не станет доступно больше данных. Кажется, что Ffmpeg требует, чтобы все данные были доступны сейчас. Когда у меня нет данных для возврата, ffmpeg, кажется, думает, что это конец файла, хотя на самом деле он еще не готов. Я попробовал вернуть AVERROR(EAGAIN), но проблемы остались. Похоже, я получаю случайные сообщения об ошибках, специфичных для декодера, потому что он считает, что ввод недействителен (хотя на самом деле он просто еще недоступен), а затем, когда я получаю ввод и пытаюсь снова вызвать av_read_frame(), он немедленно возвращает отрицательный код ошибки, поскольку он перешел в плохое состояние.
Что мне нужно сделать, чтобы иметь возможность просмотреть все доступные данные с помощью av_read_frame(), а затем сделать паузу и подождать, пока не поступят новые данные? Как мне сделать ffmpeg счастливым?
// -------- Set up --------
size_t ioContextBufferSize = 4096;
avioContextBuffer = avAllocateEmptyBuffer(ioContextBufferSize);
avioContext = avio_alloc_context(avioContextBuffer.ptr,
ioContextBufferSize,
0, // bWriteable (1=true,0=false)
&(opaque),
read_packet,
0, // Write callback function
0)}; // Seek function not provided

AVFormatContext* inContext = avformat_alloc_context();
inContext->pb = avioContext;
inContext->flags = AVFMT_FLAG_CUSTOM_IO;

avformat_open_input(&inContext, "", nullptr, nullptr);
inputPacket = av_packet_alloc();

// -------- Loop and read data -------
// (the second time we reach this while loop, it never enters the loop :(
//
while ((ret = av_read_frame(inContext, inputPacket)) >= 0) {
.. do stuff with inputPacket
}

// -------- read_packet function -----
// copies data into ffmpeg's internal buffer. What do I return here???
//
static int read_packet(void* opaque, uint8_t* avioContextBuffer, int ioContextBufferSize) {
OpaqueDataWrapper* streamedData = static_cast(opaque);

size_t bytesToRead = std::min((size_t)ioContextBufferSize, streamedData->remainingBytes());

if (!bytesToRead) {
// We need to wait for more data to arrive! What do I return here to tell ffmpeg to wait a while?
if (streamedData->streamStillOpen()) {
return AVERROR(EAGAIN);
} else {
return AVERROR_EOF;
}
}
... otherwise copy the next bit of data
}


Подробнее здесь: https://stackoverflow.com/questions/778 ... -available
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»