MP4的视频H264封装有2种格式:h264和avc1 AVC1 描述:H.264 bitstream without start codes.一般通过ffmpeg转码生成的视频,是不带起始码0x00000001的。 H264 描述:H.264 bitstream with start codes.一般对于一下HDVD等电影的压制格式,是带有起始码0x00000001的。 如何区分呢,网上有好多一模一样的帖子都说是比较pkt.data头4个字节是否是0x00000001,实际上h264的NAL有两种,即:0x00000001或0x000001,还有首帧的pkt.data不是0x00000001,但第二帧开始就是0x00000001,后面还有0x000001的情况,所以判断头也不靠谱。 本人通过比较两种文件中in_stream->codec发现在AVC1模式时in_stream->codec->codec_tag = 0x31637661,翻译成字符串就是"1cva",这个codec_tag是int型,那么内存中的值应该是:0x61 0x76 0x63 0x31,也主是"avc1",而且输出流out_stream->codec->code_id = AV_CODEC_ID_H264时,这个out_stream->codec->code_tag的值是0x34363248,在内存中就是"H264",所以没错就是用这个字段来判断了。
is_annexb = false; AVPacket pkt = {0}; const char start_code[4] = { 0, 0, 0, 1 }; //判断H264的NAL是否需要annexb过滤(读个几帧,看看头数据是否是0x00000001,若全都不是,则需要annexb过滤) if(in_stream->codec->codec_id == AV_CODEC_ID_H264) { if(in_stream->codec->codec_tag == 0x31637661)//avc1 is_annexb = true; else { int n = 0, t = 0; while(n < 5) { n++; ret = av_read_frame(ifmt_ctx, &pkt); if(ret < 0) continue; if(memcmp(pkt.data, start_code, 4) == 0) t++; av_packet_unref(&pkt); } if(t==0) is_annexb = true; av_seek_frame(ifmt_ctx, vid, 0, AVSEEK_FLAG_BYTE);//重定位到第0帧 } }