weixin_48522366 2024-07-23 10:35 采纳率: 0%
浏览 458
已结题

qt+ffmpeg报错non-existing PPS 0 referenced

使用qt+ffmpeg对来自UDP组播的网络视频流(采用h.264方式压缩的)进行解码并将其显示出来,在使用ffmpeg提供的函数之后,程序总是会报错:
[h264 @ 000000000bbf0a40] non-existing PPS 0 referenced
[h264 @ 000000000bbf0a40] non-existing PPS 0 referenced
[h264 @ 000000000bbf0a40] decode_slice_header error
[h264 @ 000000000bbf0a40] no frame!
下面是我的程序代码:

img

img

img

img

img

img

img

img


这是我的调试打印信息:

img


运行环境为qt5.12,ffmpeg的版本为官网下载的最新版本。

求指点,有没有什么解决办法

  • 写回答

28条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-07-23 10:38
    关注
    获得0.30元问题酬金

    引自免费微信小程序:皆我百晓生

    这个问题通常是因为解码器在尝试解码H.264流时找不到对应的PPS(Picture Parameter Set,图像参数集)和SPS(Sequence Parameter Set,序列参数集)。这些参数集包含了编码器使用的具体参数信息,如分辨率、帧率等,是解码过程中的关键部分。在收到实际的视频帧之前,H.264流应当首先包含SPS和PPS。你的错误提示表明解码器在尝试解码时找不到必要的PPS。

    解决方案:

    1. 确保完整的NAL单元:确保你从UDP流接收到的数据包含了完整的NAL单元(包括SPS、PPS和实际的视频帧)。H.264数据流通常以起始码(例如0x00000001或0x000001XX)分割不同的NAL单元。你需要确保你的代码正确地识别并处理这些起始码,以便将完整的NAL单元提取出来供解码器使用。

      代码示例:

      // 在处理H264数据前,添加逻辑来检测和分离NAL单元
      while (!video_queue.isEmpty()) {
          uint8_t byte = video_queue.dequeue();
          if (byte == 0x00 && !foundStartCode) {
              if (video_queue.peekFront() == 0x00 && video_queue.peekAt(1) == 0x00 && video_queue.peekAt(2) == 0x01) {
                  foundStartCode = true;
                  // 移除已检查的起始码前缀
                  video_queue.dequeue();
                  video_queue.dequeue();
                  video_queue.dequeue();
              }
          } else if (byte == 0x01 && foundStartCode) {
              // 发现新的NALU开始,处理之前的NALU
              handleNALUnit(videoarray);
              videoarray.clear(); // 准备存储新的NALU
              foundStartCode = false;
          } else {
              videoarray.append(byte);
          }
      }
      

      注意:这只是一个简化的示例,真实情况下还需考虑NALU类型的判断和处理。

    2. 初始化解码器上下文时设置extradata:在成功获取到SPS和PPS后,你需要将它们作为AVCodecContextextradata传递给解码器。这样解码器在遇到引用的PPS时就可以正确解析了。

      代码示例:

      // 假设已经正确提取了SPS和PPS,并存储在spsondata和ppsdata中
      uint8_t* extradata = (uint8_t*)malloc(spssondata.size() + ppsdata.size() + 3);
      memcpy(extradata, spssondata.data(), spssondata.size());
      extradata[spssondata.size()] = 0x01; // 分隔符
      memcpy(extradata + spssondata.size() + 1, ppsdata.data(), ppsdata.size());
      extradata[spssondata.size() + ppsdata.size() + 1] = 0x00; // 结束标志
      codecContext->extradata_size = spssondata.size() + ppsdata.size() + 3;
      codecContext->extradata = extradata;
      
    3. 处理NALU类型:在解析NALU时,特别注意对SPS和PPS的处理。一旦发现它们,就应该先保存下来,并且不将它们发送给解码器。只有当收到I、P、B帧时才调用avcodec_send_packet进行解码。

    综上所述,重点在于确保你正确地处理了H.264流中的NAL单元,特别是SPS和PPS的提取与应用。上述示例代码仅提供了一个基本思路,实际应用中可能需要根据具体情况调整和完善。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 7月31日
  • 修改了问题 7月23日
  • 修改了问题 7月23日
  • 创建了问题 7月23日