PTS не установлен после декодирования потока H264 / RTSP

Вопрос: Что нужно конвейеру декодирования Libav / FFmpeg для создания действительных временных меток представления (PTS) в декодированных кадрах AVFrames?

Я декодирую поток H264, полученный по RTSP. Я использую Live555 для синтаксического анализа H264 и передачи потока моему декодеру LibAV. Декодирование и отображение работают нормально, за исключением того, что я не использую информацию о времени и получаю некоторые заикания.

После получения кадра с avcodec_decode_video2 отметка времени представления (PTS) не устанавливается.

Мне нужен PTS, чтобы узнать, как долго должен отображаться каждый кадр, и избежать заикания.

Заметки о моем конвейере

  • Я получаю информацию о SPS / PPS через Live555, копирую эти значения в свой AVCodecContext->extradata.
  • Я также отправляю на мой декодер SPS и PPS как блоки NAL с добавленным стартовым кодом {0,0,0,1}.
  • Live555 предоставляет временные метки представления для каждого пакета, в большинстве случаев они не увеличиваются монотонно. Поток содержит B-кадры.
  • Мой AVCodecContext->time_base недействителен, значение 0/2.

Не понятно:

  • Где именно я должен установить NAL PTS, поступающий из моего приемника H264 (Live555)? Как AVPacket- ›dts, pts, none или оба?
  • Почему мое time_basevalue недействительно? Где эта информация?
  • Согласно спецификации полезной нагрузки RTP. Кажется, что

Метка времени RTP устанавливается равной метке времени выборки контента. ДОЛЖНА использоваться тактовая частота 90 кГц.

  • Означает ли это, что я всегда должен использовать для декодера временную развертку 1/90000? Что делать, если в SPS указано другое значение?

person Sergio Basurco    schedule 22.09.2017    source источник


Ответы (2)


Скопируйте live555 pts в avpacket pts. Обработайте пакет с помощью avcodec_decode_video2, а затем извлеките pts из avframe-> pkt_pts, они будут монотонно увеличиваться.

Нет необходимости устанавливать что-либо в контексте кодека, кроме настройки SPS и PPS в дополнительных данных AVCodecContex.

Вы можете найти хороший пример в VLC на github: Настройка AVPacket pts: https://github.com/videolan/vlc/blob/master/modules/codec/avcodec/video.c#L983

Декодирование AVPacket в AVFrame: https://github.com/videolan/vlc/blob/master/modules/codec/avcodec/video.c#L1014.

Получение из точек AVFrame: https://github.com/videolan/vlc/blob/master/modules/codec/avcodec/video.c#L1078.

person Hennio    schedule 29.09.2017

avcodec_decode_video2 () переупорядочивает кадры так, чтобы порядок декодирования и порядок представления были одинаковыми. Даже если вы каким-то образом убедите ffmpeg дать вам PTS в декодированном кадре, он должен быть таким же, как DTS.

//
// decode a video frame
//

avcodec_decode_video2
(
    ctxt->video_st->codec,
    frame,
    &is_finished,
    buffer
);

if (buffer->dts != AV_NOPTS_VALUE)
{
    //
    // you should end up here
    //
    pts = buffer->dts;
}
else
{
    pts = 0;
}

//
// adjust time base
//
pts *= av_q2d(ctxt->video_st->time_base);
person Markus Schumann    schedule 25.09.2017
comment
Что делать, если time_base моего контекста недействительна? Как упоминалось в вопросе, его значение 0/2 - person Sergio Basurco; 26.09.2017
comment
Кроме того, в моем случае значение buffer-dts равно AV_NOPTS_VALUE. - person Sergio Basurco; 26.09.2017