• 周三. 4 月 22nd, 2026

物嫩软件资讯网

软件资讯来物嫩

FFmpeg 开发记录—H264编码,avi封装,暴风影音,qq影音播放有声无画

admin@wunen

4 月 1, 2025


使用

ffmpeg

编码视频文件时,视频编码为


H264


,音频编码为


MP3


,封装格式为


avi


,发现输出的文件用


vlc





mkplayer


等能正常播放,但是用暴风影音或者


QQ


影音等无法正常播放,有声音无画面。后来发现,在创建封装格式为


avi


时候,是需要指定


video codec





fourcc


的。目前代码中


H264


编码时指定了


codec_tag





H264


,但是为什么要指定


H264


呢?这个


codec_tag


到底有什么用呢?

—>




codec_tag


的用处:


跟到头文件

avcodec.h

中,看此变量解释:





这里有个词很关键:

work around

,看来是用来绕过一些编码器的


bug




编码时由使用者设置,如果没有设置就用默认的,我们之前没有设置或者设置的有问题,所以导致没有播出画面,但是好像还没有找到关键性原因,这个

codec_tag

到底是做什么的?影响了什么?


看源码,在

avienc.c




avi_write_packet


函数中如果设置了


H264


的话,会调用


ff_check_h264_startcode










但是



ff_check_h264_startcode



内部并未做其他操作




参考:



https://en.wikipedia.org/wiki/FourCC



但是设置后确实是可以播放了,怀疑跟

videostream

里的


AVCodec


参数中的


flags

有关系。代码中搜索

AV_CODEC_FLAG_GLOBAL_HEADER






发现


因为

avi

文件


flag





0


,所以没有去置


pCodecCtxEnc


(也就是


videostream


中的


codec


)的


flags


。查看这


2





flag


分别为


—-




avformat.h





#define




AVFMT_GLOBALHEADER




0x0040



Format wants global header.



—->avcodec.h




#define




AV_CODEC_FLAG_GLOBAL_HEADER




(


1




<<




22


)


Place global headers in extradata instead of every keyframe.


告知在

extradata

中以


global headers


取代每个关键帧。继续搜索


AV_CODEC_FLAG_GLOBAL_HEADER


,发现


x264


编码中



如果

flag

中有


AV_CODEC_FLAG_GLOBAL_HEADER

标识,则


b_repeat_headers





0



b_repeat_header

: 在每个关键帧前面


put SPS/PPS




这么下来,应该就明白了,如果设置了

videosteam




codec


中设置了


AV_CODEC_FLAG_GLOBAL_HEADER


就会导致


x264_param_t



参数中的


b_repeat_header

赋值为


0


,这样每个关键帧前面就不会


put SPS/PPS


导致解码失败。


注:使用实时视频传输时,需要实时发送

sps/pps

数据

param.b_repeat_headers = 1;  //

重复


SPS/PPS


放到关键帧前面

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注