Я очень благодарен за помощь в следующей проблеме:
У меня есть гаджет с камерой, создающий сжатые видеокадры 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, вставить в уже закодированные потоковые кадры и создать с ним видеофайл. Как это сделать?
Спасибо, е.