Необработанные кадры H264 в контейнере mpegts с использованием libavcodec

Я был бы очень признателен за помощь в решении следующей проблемы:

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

И вдруг приложение перестает работать правильно, созданное видео невозможно воспроизвести. Это очевидно, поскольку я не устанавливал правильный PTS для пакета. Я сделал следующее (я в отчаянии, это видно из этого подхода :))

    packet.pts = timestamps[timestamp_counter ++];

где отметки времени на самом деле являются списком PTS, созданных с помощью приведенного выше рабочего кода и записанных в (да, вы прочитали его правильно, я зарегистрировал все PTS за 10-минутный сеанс и хотел их использовать).

Приложение все еще не работает.

Теперь я не знаю, что делать do, поэтому вот вопрос:

Я хотел бы создать видеопоток "mpegts", используя функции libav, вставить в поток уже закодированные видеокадры и создать с ним видеофайл. Как мне это сделать?

Спасибо, f.

35
задан Ferenc Deak 11 May 2011 в 12:29
поделиться