解码H264 / RTSP流后未设置PTS

时间:2017-09-22 06:35:22

标签: c++ ffmpeg h.264 libav live555

问题为了在解码的AVFrame中生成有效的演示时间戳(PTS),Libav / FFmpeg解码管道需要什么?

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

获取avcodec_decode_video2的帧后,未设置演示时间戳(PTS)。

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

关于我的管道的说明

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

不清楚:

  • 我应该在哪里设置来自H264接收器(Live555)的NAL PTS?作为AVPacket-> dts,pts,none或两者兼而有之?
  • 为什么我的time_base值无效?这个信息在哪里?
  • 根据RTP payload spec。好像
  

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

  • 这是否意味着我必须始终为解码器设置1/90000时基?如果在SPS中指定了其他值,该怎么办?

2 个答案:

答案 0 :(得分:1)

将live555点复制到avpacket点。使用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/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

答案 1 :(得分:0)

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