【FFmpeg】警告:[mpegts] H.264 bitstream error, startcode missing, size 0

1、问题描述

在使用FFmpeg编程,编码成h.264后,再封装成hls时,报警告

[mpegts] H.264 bitstream error, startcode missing, size 0
2、原因分析

根据警告提示信息可知:264位流错误,开始码丢失,大小为0。
根据警告信息搜索源码,在 FFmpeg-n4.2.2/libavformat/mpegtsenc.c文件的函数ff_check_h264_startcode中,打印该警告信息。源码如下:

int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt)
{
    if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001 && AV_RB24(pkt->data) != 0x000001) {
        if (!st->nb_frames) {
            av_log(s, AV_LOG_ERROR, "H.264 bitstream malformed, "
                   "no startcode found, use the video bitstream filter 'h264_mp4toannexb' to fix it "
                   "('-bsf:v h264_mp4toannexb' option with ffmpeg)\n");
            return AVERROR_INVALIDDATA;
        }
        av_log(s, AV_LOG_WARNING, "H.264 bitstream error, startcode missing, size %d", pkt->size);
        if (pkt->size)
            av_log(s, AV_LOG_WARNING, " data %08"PRIX32, AV_RB32(pkt->data));
        av_log(s, AV_LOG_WARNING, "\n");
    }
    return 0;
}

对应打印信息和源码可知,size 0是指AVPacket.size,即AVPacket包中没有数据,当然要报警告了。

3、拓展

在分析这段源码中,有个宏定义AV_RB32,功能是将连续的4个uint8_t合成一个uint32_t的值。
下面分析它的源码实现

1> AV_RB32的宏定义

#ifndef AV_RB32
#   define AV_RB32(p)    AV_RB(32, p)

2> AV_RB的宏定义

#   define AV_RB(s, p)    av_bswap##s(AV_RN##s(p))

代码展开,即:av_bswap32(AV_RN32§)
3> AV_RN32的宏定义

#   define AV_RN32(p) AV_RN(32, p)
#   define AV_RN(s, p) (((const union unaligned_##s *) (p))->l)
union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias;
#   define av_alias __attribute__((may_alias))

代码展开后,实际意思是uint32_t
4>、真正调用的是av_bswap32(uint32_t x) ,函数功能是将4字节x的字节序改变顺序后返回,如,将“0x12345678”改成“0x78563412”后返回。

static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
{
    return AV_BSWAP32C(x);
}

#define AV_BSWAP16C(x) (((x) << 8 & 0xff00)  | ((x) >> 8 & 0x00ff))		// 将高八位和低八位互换
#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C(   (x)>>16)  )	// 换字节序

你可能感兴趣的:(视频)