Invalid NAL unit 1, skipping.  0B f=0/0

Invalid NAL unit 1, skipping.  0B f=0/0
[h264 @ 000001fb8ebf2040] no frame!
[h264 @ 000001fb8ea6b540] Invalid NAL unit 1, skipping.  0B f=0/0
[h264 @ 000001fb8ea6b540] no frame!
[h264 @ 000001fb8f360980] no frame!0KB vq=  371KB sq=    0B f=0/0
[h264 @ 000001fb8ea6b540] no frame!0KB vq=   59KB sq=    0B f=0/0
[h264 @ 000001fb8f360980] Invalid NAL unit 21, skipping. 0B f=0/0
[h264 @ 000001fb8f360980] no frame!
[h264 @ 000001fb8ea6b0c0] no frame!0KB vq=   69KB sq=    0B f=0/0
[h264 @ 000001fb8f460a40] Invalid NAL unit 1, skipping.  0B f=0/0
[h264 @ 000001fb8f460a40] no frame!
[NULL @ 000001fb8804f600] missing picture in access unit with size 321
[h264 @ 000001fb8ea6b0c0] no frame!0KB vq=   75KB sq=    0B f=0/0
[h264 @ 000001fb8f460a40] no frame!0KB vq=   84KB sq=    0B f=0/0
[NULL @ 000001fb8804f600] missing picture in access unit with size 321
[NULL @ 000001fb8804f600] missing picture in access unit with size 641
[h264 @ 000001fb8ea6b0c0] no frame!0KB vq=   85KB sq=    0B f=0/0
[NULL @ 000001fb8804f600] missing picture in access unit with size 321
[h264 @ 000001fb8f460a40] Invalid NAL unit 21, skipping. 0B f=0/0
[h264 @ 000001fb8f460a40] no frame!

分析解决

当前报文中的NALU单元类型不合法,类型不正确,导致解码失败,检查其是否有音频数据混合编码不正确导致。

目前原因是FLV中的视频数据杂糅了音频,通过搜索视频文件中27 01 00 00 00 00后面的NALU单元类型发现异常,出现3d或者5d类型,正常的类型应该是67 68 65 61


top block unavailable for requested intra mode

[h264 @ 04241fc0] top block unavailable for requested intra mode
[h264 @ 04241fc0] error while decoding MB 2 0, bytestream 243592
[h264 @ 04241fc0] concealing 8160 DC, 8160 AC, 8160 MV errors in I frame
[h264 @ 036da7a0] top block unavailable for requested intra mode
[h264 @ 036da7a0] error while decoding MB 87 0, bytestream 13676
[h264 @ 036da7a0] concealing 8122 DC, 8122 AC, 8122 MV errors in P frame
[swscaler @ 054140c0] deprecated pixel format used, make sure you did set range correctly
[h264 @ 0447a540] concealing 7913 DC, 7913 AC, 7913 MV errors in P frame
[h264 @ 0447a960] top block unavailable for requested intra modetop block unavailable for requested intra mode -1
[h264 @ 0447a960] error while decoding MB 52 0, bytestream 18938

背景知识

IDR: 在H.264中,图像以序列为单位进行组织。一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像。H.264 引入 IDR 图像是为了解码的重同步,当×××解码到 IDR 图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。IDR 图像一定是 I 图像,但 I 图像不一定是 IDR 图像。I帧之后的图像有可能会使用I帧之前的图像做运动参考。


NALU类型
       标识NAL单元中的RBSP数据类型,其中,nal_unit_type为1, 2, 3, 4, 5及12的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL单元。
0:未规定
1:非IDR图像中不采用数据划分的片段
2:非IDR图像中A类数据划分片段
3:非IDR图像中B类数据划分片段
4:非IDR图像中C类数据划分片段
5:IDR图像的片段
6:补充增强信息 (SEI)
7:序列参数集
8:图像参数集
9:分割符
10:序列结束符
11:流结束符
12:填充数据
13 – 23:保留
24 – 31:未规定

av_read_frame函数打印当前接收的NALU单元的类型
nal_unit_type: 7, nal_ref_idc: 3
nal_unit_type: 8, nal_ref_idc: 3
nal_unit_type: 6, nal_ref_idc: 0
nal_unit_type: 5, nal_ref_idc: 3
说明I帧前面就会有SPS/PPS图像参数的相关信息,实际上当收到I帧,也就可以解码出图像(会根据前面的SPS/PPS参数进行解码参数的设置),虽然FFmpeg内部会缓冲几帧,但是缓冲的帧速度还是很快的根本不需要考虑延时
当然,如果是播放文件的话,在播放结束后,要想取出来就需要传递空的AVPacket进去,需要调用avcodec_send_packet(pAVCodecContext, NULL)才能够播放完毕


decode_slice_header error

场景

华为摄像机取流成功后,保存的原始码流,ffplay播放提示出错

[h264 @ 000001df367612c0] concealing 57 DC, 57 AC, 57 MV errors in P frame
[h264 @ 000001df2f97d4c0] error while decoding MB 106 67, bytestream -5
[h264 @ 000001df2f97d4c0] slice type 32 too large at 410367
[h264 @ 000001df2f97d4c0] decode_slice_header error

尚未解决


Frame num change from 0 to 1

尚未解决


non-existing PPS 0 referenced

问题描述:

I:2018-01-06 14:35:33 ms:313:nal_unit_type: 1, nal_ref_idc: 3
I:2018-01-06 14:35:33 ms:313:non-existing PPS 0 referenced
I:2018-01-06 14:35:33 ms:313:decode_slice_header error
I:2018-01-06 14:35:33 ms:313:no frame!

 

出现该问题的原因有两个

1.初始化解码器的时候extdata内容为空,导致解析SPS/PPS失败,这种情况下,如果收到一个不是I帧的数据包,解码出错提示如上

2.收到的I帧,没有包含SPS/PPS,无法初始化解码器

 

解决方案

第一:确保avcodec_send_packet函数第一次调用传递包含SPS/PPS报文的I帧数据,就可以正常初始化解码器,进行解码


查看所有的函数引用
1)static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, const H2645NAL *nal)

    if (!h->ps.pps_list[sl->pps_id]) {
        av_log(h->avctx, AV_LOG_ERROR,
               "non-existing PPS %u referenced\n",
               sl->pps_id);
        return AVERROR_INVALIDDATA;
    }
2)static inline int parse_nal_units(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t * const buf, int buf_size)

            if (!p->ps.pps_list[pps_id]) {
                av_log(avctx, AV_LOG_ERROR,
                       "non-existing PPS %u referenced\n", pps_id);
                goto fail;
            }


avcodec_send_packet函数返回-1094995529错误,根据FFmpeg的错误信息,得知为AVERROR_INVALIDDATA,猜测是第一种情况
在调用h264_slice_header_parse函数的时候,出现了错误,无法定位PPS

函数的调用逻辑
static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
    int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal)
        static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, const H2645NAL *nal)

结构体的获取
H264Context* pH264Context = AVCodecContext->priv_data
H264SliceContext *sl = H264Context->slice_ctx + H264Context->nb_slice_ctx_queued;