Буду очень признателен за помощь в решении следующей проблемы:
У меня есть гаджет с камерой, производящий сжатые видеокадры H264, эти кадры отправляются в мое приложение. Эти кадры не находятся в контейнере, просто необработанные данные.
Я хочу использовать функции ffmpeg и libav для создания видеофайла, который можно использовать позже.
Если я декодирую кадры, затем кодирую их, все работает нормально, я получаю действительный видеофайл. (шаги декодирования / кодирования - это обычные команды libav, здесь ничего особенного, я взял их из всемогущего интернета, они потрясающие) ... Однако я трачу много времени на декодирование и кодирование, поэтому я хотел бы пропустите этот шаг и непосредственно поместите кадры в выходной поток. Теперь проблемы приходят.
Вот код, который я придумал для создания кодировки:
AVFrame* picture;
avpicture_fill((AVPicture*) picture, (uint8_t*)frameData,
codecContext->pix_fmt, codecContext->width,
codecContext->height);
int outSize = avcodec_encode_video(codecContext, videoOutBuf,
sizeof(videoOutBuf), picture);
if (outSize > 0)
{
AVPacket packet;
av_init_packet(&packet);
packet.pts = av_rescale_q(codecContext->coded_frame->pts,
codecContext->time_base, videoStream->time_base);
if (codecContext->coded_frame->key_frame)
{
packet.flags |= PKT_FLAG_KEY;
}
packet.stream_index = videoStream->index;
packet.data = videoOutBuf;
packet.size = outSize;
av_interleaved_write_frame(context, &packet);
put_flush_packet(context->pb);
}
Где переменные похожи:
frameData
- это данные декодированного кадра, полученные с камеры, они были декодированы на предыдущем шаге, а videoOutBuf
- простой буфер uint8_t для хранения данных
Я изменил приложение, чтобы не декодировать кадры, а просто передавать данные, например:
AVPacket packet;
av_init_packet(&packet);
packet.stream_index = videoStream->index;
packet.data = (uint8_t*)frameData;
packet.size = currentFrameSize;
av_interleaved_write_frame(context, &packet);
put_flush_packet(context->pb);
, где
frameData
- это необработанный кадр H264
currentFrameSize
- размер необработанного кадра H264, т.е. количество байтов, которые я получаю от гаджета для каждого кадра.
И вдруг приложение больше не работает корректно, созданное видео не воспроизводится. Это очевидно, так как я не устанавливал правильный PTS для пакета. То, что я сделал, было следующим (я в отчаянии, вы можете видеть это из этого подхода :))
packet.pts = timestamps[timestamp_counter ++];
где timestamps
- это фактически список PTS, созданный с помощью приведенного выше рабочего кода и записанный в файл (да, вы прочитали его правильно, я зарегистрировал все PTS за 10-минутный сеанс и хотел использовать их) .
Приложение по-прежнему не работает.
Теперь я понятия не имею, что делать, поэтому возникает вопрос:
Я хотел бы создать видеопоток "mpegts", используя функции libav, вставить в поток уже закодированные видеокадры и создать с ним видеофайл. Как мне это сделать?
Спасибо,
е.