解码H264/RTSP流后未设置PTS

3

问题: Libav/FFmpeg解码流程需要什么才能在解码后的AVFrame中产生有效的呈现时间戳(PTS)?

我正在解码通过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 sink(Live555)的NAL PTS?作为AVPacket->dts、pts、无,还是两者都有?
  • 为什么我的time_base值无效?这个信息在哪里?
  • 根据 RTP负载规范。似乎

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

  • 这是否意味着我必须始终假定解码器的时间基准为1/90000?如果SPS中指定了其他值怎么办?
2个回答

1

将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/video.c#L983

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

从AVFrame中检索pts: https://github.com/videolan/vlc/blob/master/modules/codec/avcodec/video.c#L1078


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

如果我的上下文时间基不合法怎么办?如问题中所述,它的值为0/2 - Sergio Basurco
此外,在我的情况下,“buffer-dts”值为“AV_NOPTS_VALUE”。 - Sergio Basurco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接