解码H264/RTSP流之后未设置PT



问题 libav/ffmpeg解码管道需要什么才能在解码的AvFrames中产生有效的演示时间戳(PTS)?

我正在解码通过RTSP收到的H264流。我使用live555来解析H264,然后将流将流提供给我的libav解码器。解码和显示工作正常,除了我没有使用时间戳信息并遇到一些口吃。

使用avcodec_decode_video2帧后,未设置演示时间戳(PTS)。

我需要PTS才能找出需要显示每个帧的时间,并避免任何口吃。

我的管道上的注释

  • 我通过live555获取SPS/PPS信息,我将这些值复制到我的AVCodecContext->extradata
  • 我还将SPS和PPS发送给我的解码器,作为NAL单位,并附加{0,0,0,0,1} startCode。
  • live555为每个数据包提供演示时间戳,在大多数情况下,这些时间戳并非单调增加。该流包含B框架。
  • 我的AVCodecContext->time_base无效,值为0/2。

不清楚:

  • 我应该在哪里设置来自H264水槽(Live555)的NAL PT?作为avpacket-> dts,pts,无或两者兼而有之?
  • 为什么我的time_base值无效?此信息在哪里?
  • 根据RTP有效载荷规格。看来

RTP时间戳设置为内容的采样时间戳。必须使用90 kHz时钟速率。

  • 这是否意味着我必须始终为解码器的1/90000时数吗?如果SPS中指定了其他一些值?

将live555 pts复制到avpacket pts中。使用AVCODEC_DECODE_VIDEO2处理数据包,然后从AvFrame-> pkt_pts检索PTS,它们将单调增加。

除了在avcodeccontex extradata中设置SPS和PPS外,无需在编解码环境中设置任何内容

您可以在VLC的GitHub中找到一个很好的例子:设置AVPacket PTS:https://github.com/videolan/vlc/blob/master/modules/codec/avcodec/videeo.c#l983

将AVPacket解码为AvFrame:https://github.com/videolan/vlc/blob/master/master/modules/codec/codec/avcodec/video.c#l1014

从Avframe PTS检索:https://github.com/videolan/vlc/blob/master/modules/codec/avcodec/video.c#l1078

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);

最新更新