做房产的一般用哪个网站好,站长网站被跳转怎么办,企业网站推广工具,谷歌网站地图在线生成音视频入门基础#xff1a;H.264专题系列文章#xff1a;
音视频入门基础#xff1a;H.264专题#xff08;1#xff09;——H.264官方文档下载
音视频入门基础#xff1a;H.264专题#xff08;2#xff09;——使用FFmpeg命令生成H.264裸流文件
音视频入门基础…
音视频入门基础H.264专题系列文章
音视频入门基础H.264专题1——H.264官方文档下载
音视频入门基础H.264专题2——使用FFmpeg命令生成H.264裸流文件
音视频入门基础H.264专题3——EBSP, RBSP和SODB
音视频入门基础H.264专题4——NALU Headerforbidden_zero_bit、nal_ref_idc、nal_unit_type简介
音视频入门基础H.264专题5——FFmpeg源码中 解析NALU Header的函数分析
音视频入门基础H.264专题6——FFmpeg源码从H.264码流中提取NALU Header、EBSP、RBSP和SODB
音视频入门基础H.264专题7——FFmpeg源码中 指数哥伦布编码的解码实现
音视频入门基础H.264专题8——H.264官方文档的描述符 一、引言
FFmpeg源码中 通过h264_parse_nal_header函数将H.264码流的NALU Header解析出来。下面对h264_parse_nal_header函数进行分析。 二、h264_parse_nal_header函数定义
h264_parse_nal_header函数定义在FFmpeg源码下面演示的FFmpeg源码版本是5.0.3的源文件libavcodec/h2645_parse.c 中
static int h264_parse_nal_header(H2645NAL *nal, void *logctx)
{GetBitContext *gb nal-gb;if (get_bits1(gb) ! 0)return AVERROR_INVALIDDATA;nal-ref_idc get_bits(gb, 2);nal-type get_bits(gb, 5);av_log(logctx, AV_LOG_DEBUG,nal_unit_type: %d(%s), nal_ref_idc: %d\n,nal-type, h264_nal_unit_name(nal-type), nal-ref_idc);return 0;
}
该函数作用是将NALU Header解析出来由形参nal返回。 形参nal
nal-gb输入型参数。((nal-gb))-buffer指向存放NALU Header RBSP 的缓冲区。
nal-ref_idc输出型参数。执行h264_parse_nal_header函数后nal-ref_idc的值为NALU Header中的nal_ref_idc。
nal-type输出型参数。执行h264_parse_nal_header函数后nal-type的值为NALU Header中的nal_unit_type。 形参logctx输入型参数。用来输出日志可以忽略。 返回值解析NALU Header成功返回0。失败返回AVERROR_INVALIDDATA。 三、h264_parse_nal_header函数的内部实现原理
h264_parse_nal_header函数中首先通过语句get_bits1(gb);拿到NALU Header中forbidden_zero_bit。关于get_bits1用法可以参考《FFmpeg中位操作相关的源码GetBitContext结构体init_get_bits函数、get_bits1函数和get_bits函数分析》。 由于forbidden_zero_bit 的值应为0如果它的值为1则意味着比特流语法出错了也就是FFmpeg头文件libavutil/error.h里面定义的“Invalid data found when processing input”
#define AVERROR_INVALIDDATA FFERRTAG( I,N,D,A) /// Invalid data found when processing input
所以如果forbidden_zero_bit的值不为0返回AVERROR_INVALIDDATA。
所以有下面语句
if (get_bits1(gb) ! 0)return AVERROR_INVALIDDATA; 然后通过下面语句读取NALU Header中的nal_ref_idc和nal_unit_type分别保存到nal-ref_idc和nal-type中。
nal-ref_idc get_bits(gb, 2);
nal-type get_bits(gb, 5); 最后通过
av_log(logctx, AV_LOG_DEBUG,nal_unit_type: %d(%s), nal_ref_idc: %d\n,nal-type, h264_nal_unit_name(nal-type), nal-ref_idc);
日志输出NALU Header的信息。 h264_nal_unit_name函数是用来得到nal_unit_type的名称。其定义如下
static const char *const h264_nal_type_name[32] {Unspecified 0, //H264_NAL_UNSPECIFIEDCoded slice of a non-IDR picture, // H264_NAL_SLICECoded slice data partition A, // H264_NAL_DPACoded slice data partition B, // H264_NAL_DPBCoded slice data partition C, // H264_NAL_DPCIDR, // H264_NAL_IDR_SLICESEI, // H264_NAL_SEISPS, // H264_NAL_SPSPPS, // H264_NAL_PPSAUD, // H264_NAL_AUDEnd of sequence, // H264_NAL_END_SEQUENCEEnd of stream, // H264_NAL_END_STREAMFiller data, // H264_NAL_FILLER_DATASPS extension, // H264_NAL_SPS_EXTPrefix, // H264_NAL_PREFIXSubset SPS, // H264_NAL_SUB_SPSDepth parameter set, // H264_NAL_DPSReserved 17, // H264_NAL_RESERVED17Reserved 18, // H264_NAL_RESERVED18Auxiliary coded picture without partitioning, // H264_NAL_AUXILIARY_SLICESlice extension, // H264_NAL_EXTEN_SLICESlice extension for a depth view or a 3D-AVC texture view, // H264_NAL_DEPTH_EXTEN_SLICEReserved 22, // H264_NAL_RESERVED22Reserved 23, // H264_NAL_RESERVED23Unspecified 24, // H264_NAL_UNSPECIFIED24Unspecified 25, // H264_NAL_UNSPECIFIED25Unspecified 26, // H264_NAL_UNSPECIFIED26Unspecified 27, // H264_NAL_UNSPECIFIED27Unspecified 28, // H264_NAL_UNSPECIFIED28Unspecified 29, // H264_NAL_UNSPECIFIED29Unspecified 30, // H264_NAL_UNSPECIFIED30Unspecified 31, // H264_NAL_UNSPECIFIED31
};static const char *h264_nal_unit_name(int nal_type)
{av_assert0(nal_type 0 nal_type 32);return h264_nal_type_name[nal_type];
}
可以看到h264_nal_unit_name函数内部通过nal_unit_type拿到数组h264_nal_type_name中对应的字符串名称。 h264_nal_type_name数组跟H.264官方文档《T-REC-H.264-202108-I!!PDF-E.pdf》第65页描述的nal_unit_type对应