怎样建设门户网站,网站开发所需费用支出有哪些,重庆360网络推广,贵阳商城网站建设一、引言
从《音视频入门基础#xff1a;H.264专题#xff08;18#xff09;——AVCDecoderConfigurationRecord简介》中可以知道#xff0c;avcC跟AnnexB不一样#xff0c;avcC包装的H.264码流中#xff0c;每个NALU前面没有起始码。avcC通过在每个NALU前加上NALUnitL…一、引言
从《音视频入门基础H.264专题18——AVCDecoderConfigurationRecord简介》中可以知道avcC跟AnnexB不一样avcC包装的H.264码流中每个NALU前面没有起始码。avcC通过在每个NALU前加上NALUnitLength在读取某个NALU之前先把该NALU前面的NALUnitLength读取出来拿到该NALU的总长度然后根据该长度读取相应的字节数读取出整个NALU。
而FFmpeg源码内部使用get_nalsize函数读取出某个NALU前面的NALUnitLength。 二、get_nalsize函数的定义
get_nalsize函数定义在FFmpeg源码本文演示用的FFmpeg源码版本为7.0.1的头文件libavcodec/h2645_parse.h中
static inline int get_nalsize(int nal_length_size, const uint8_t *buf,int buf_size, int *buf_index, void *logctx)
{int i, nalsize 0;if (*buf_index buf_size - nal_length_size) {// the end of the buffer is reached, refill itreturn AVERROR_INVALIDDATA;}for (i 0; i nal_length_size; i)nalsize ((unsigned)nalsize 8) | buf[(*buf_index)];if (nalsize 0 || nalsize buf_size - *buf_index) {av_log(logctx, AV_LOG_ERROR,Invalid NAL unit size (%d %d).\n, nalsize, buf_size - *buf_index);return AVERROR_INVALIDDATA;}return nalsize;
}
该函数作用是读取avcC封装的H.264码流中某个NALU前面的NALUnitLength或者读取AVCDecoderConfigurationRecord中某个SPS前面的sequenceParameterSetLength或者读取AVCDecoderConfigurationRecord中某个PPS前面的pictureParameterSetLength。由于SPS和PPS都属于一种特殊的NALU所以sequenceParameterSetLength和pictureParameterSetLength也算是一种NALUnitLength。只是存贮每个sequenceParameterSetLength和pictureParameterSetLength需要固定2字节空间而存贮每个NALUnitLength所需的空间由AVCDecoderConfigurationRecord中的lengthSizeMinusOne属性决定而已。 形参nal_length_size输入型参数。如果是要读取某个NALU前面的NALUnitLength形参nal_length_size的值为“存贮该NALU对应NALUnitLength所需的以字节为单位的空间”如果是要读取sequenceParameterSetLength或pictureParameterSetLength形参nal_length_size的值固定为2。 形参buf输入型参数指向某个缓冲区。
1.如果是要读取某个NALU前面的NALUnitLength该缓冲区存放该NALU对应的NALUnitLength NALU Header EBSP
2.如果是要读取某个SPS前面的sequenceParameterSetLength该缓冲区存放该SPS对应的sequenceParameterSetLength NALU Header 该SPS实际的NALU数据该SPS的EBSP
3.如果是要读取某个PPS前面的pictureParameterSetLength该缓冲区存放该PPS对应的pictureParameterSetLength NALU Header 该PPS实际的NALU数据该PPS的EBSP 形参buf_size形参buf指向的缓冲区的长度单位为字节。 形参buf_index既是输入型参数也是输出型参数。表示读取到形参buf指向的缓冲区的第几个字节了。 形参logctx输入型参数。用来输出日志可忽略。 返回值执行成功返回读取到的NALUnitLength或sequenceParameterSetLength或pictureParameterSetLength失败返回一个负数。 三、get_nalsize函数的内部实现分析
get_nalsize函数中首先判断是否读到了形参buf指向的缓冲区的末尾。如果已经读到了末尾返回AVERROR_INVALIDDATA if (*buf_index buf_size - nal_length_size) {// the end of the buffer is reached, refill itreturn AVERROR_INVALIDDATA;} 如果还没读到末尾继续执行。通过下面语句读取NALUnitLength或sequenceParameterSetLength或pictureParameterSetLength存贮到局部变量nalsize中 for (i 0; i nal_length_size; i)nalsize ((unsigned)nalsize 8) | buf[(*buf_index)]; 如果读取到的该NALU的总长度小于0或者读取到的该NALU的总长度大于形参buf指向的缓冲区中剩下的还未被读取的空间打印日志Invalid NAL unit size”并返回AVERROR_INVALIDDATA if (nalsize 0 || nalsize buf_size - *buf_index) {av_log(logctx, AV_LOG_ERROR,Invalid NAL unit size (%d %d).\n, nalsize, buf_size - *buf_index);return AVERROR_INVALIDDATA;} 读取成功返回NALUnitLength或sequenceParameterSetLength或pictureParameterSetLength的值 return nalsize;