JM8.6中NALU(此处指VCL式的NALU)是如何写进码流的?
来源:互联网 发布:网络共享 win10 编辑:程序博客网 时间:2024/05/18 14:27
在lencod.c的main函数中调用了encode_one_slice函数,在encode_one_slice函数中调用了frame_picture函数,调用了frame_picture函数后(frame_picture还会继续调用其他重要函数) 就实现了对第一帧的编码,这样全局变量frame_pic就发生了变化,得到了它想得到的码流,现在要写码流,怎么写呢?
在encode_one_frame中接着就调用到了writeout_picture函数,调用形式是:
writeout_picture (frame_pic);
可见,把代码码流信息的frame_pic穿进去了,进入writeout_picture函数看看:
static int writeout_picture(Picture *pic){ Bitstream *currStream; int partition, slice; Slice *currSlice; img->currentPicture=pic; // 遍历slice,通常,一个frame对应一个slice for (slice=0; slice<pic->no_slices; slice++) { currSlice = pic->slices[slice]; // 目前都发现currSlice->max_part_nr为1for (partition=0; partition<currSlice->max_part_nr; partition++) { currStream = (currSlice->partArr[partition]).bitstream; // currStream->bits_to_go相当于标记,必须为8 assert (currStream->bits_to_go == 8); //! should always be the case, the //! byte alignment is done in terminate_slice // writeUnit函数的第一参数类型是Bitstream* writeUnit (currSlice->partArr[partition].bitstream,partition); } // partition loop } // slice loop return 0; }
可以看到,把一个picture对应的码流分成slice和数据分块来传给writeUnit的形参(一般认为:一个slice对应一个数据分块),进入到writeUnit函数看看:
static void writeUnit(Bitstream* currStream,int partition){ NALU_t *nalu; // 实际上currStream->bits_to_go就是一个标记 // 如果不为8, 则表明往下继续执行会有错误 assert (currStream->bits_to_go == 8); // 分配堆空间, *4是为了安全起见 nalu = AllocNALU(img->width*img->height*4); nalu->startcodeprefix_len = 2+(img->current_mb_nr == 0?ZEROBYTES_SHORTSTARTCODE+1:ZEROBYTES_SHORTSTARTCODE);//printf ("nalu->startcodeprefix_len %d\n", nalu->startcodeprefix_len); nalu->len = currStream->byte_pos +1; // add one for the first byte of the NALU//printf ("nalu->len %d\n", nalu->len); // 内存数据复制,这个是最重要的. memcpy (&nalu->buf[1], currStream->streamBuffer, nalu->len-1); // 下面对nalu的一些参数进行赋值 // 其实就是对nalu header的8个比特赋值 if (img->currentPicture->idr_flag) { nalu->nal_unit_type = NALU_TYPE_IDR; nalu->nal_reference_idc = NALU_PRIORITY_HIGHEST; } else if (img->type == B_SLICE) {//different nal header for different partitions if(input->partition_mode == 0){ nalu->nal_unit_type = NALU_TYPE_SLICE;}else{ nalu->nal_unit_type = NALU_TYPE_DPA + partition;} if (img->nal_reference_idc !=0){nalu->nal_reference_idc = NALU_PRIORITY_HIGH;} else { nalu->nal_reference_idc = NALU_PRIORITY_DISPOSABLE; } } else // non-b frame, non IDR slice {//different nal header for different partitions if(input->partition_mode == 0) { nalu->nal_unit_type = NALU_TYPE_SLICE;}else{ nalu->nal_unit_type = NALU_TYPE_DPA + partition;} if (img->nal_reference_idc !=0) { nalu->nal_reference_idc = NALU_PRIORITY_HIGH; } else { nalu->nal_reference_idc = NALU_PRIORITY_DISPOSABLE; } } nalu->forbidden_bit = 0; // 必须为0 // WriteNALU是指向函数的全局指针(提前赋值了), // 所以要想用鼠标进入WriteNALU“函数”是不可能的 // 真正调用到的函数是:WriteAnnexbNALU // 而WriteAnnexbNALU函数就是写码流函数 stat->bit_ctr += WriteNALU (nalu); // 写码流 FreeNALU(nalu);}
不用再进入WriteAnnexbNALU函数了,因为,对这个函数太熟悉了.
- JM8.6中NALU(此处指VCL式的NALU)是如何写进码流的?
- JM8.6中NALU(此处指非VCL式的NALU,如SPS和PPS)是如何写进码流的?
- 获取H264的NALU
- NALU RBSP SODB的区别
- ffmpeg从MP4中提取h264的NALU
- SVC中SEI NALU
- 关于h264的图像、帧、片、NALU
- NALU(NAL单元)的顺序要求
- NALU(NAL单元)的顺序要求
- 对PES NALU 帧的疑惑
- NALU(NAL单元)的顺序要求
- h264 NALU的获取与分析
- JM8.6代码中究竟是如何把码流写进test.264文件的?
- 关于x264编码帧,单个nalu还是多个nalu的问题
- H.264中NALU、RBSP、SODB的关系 (弄清码流结构)
- H.264中NALU、RBSP、SODB的关系 (弄清码流结构)
- H.264中NALU、RBSP、SODB的关系 (弄清码流结构)
- H.264中NALU、RBSP、SODB的关系 (弄清码流结构)
- 互联网产品“冷启动”问题浅析
- API Hooking (LoadLibrary)
- 关于函数返回值的一些理解
- ASP.NET 安全认证(三)—— 用Form 表单认证实现单点登录(Single Sign On)
- [Happy DSA] 将已排序的元素序列快速的插入到stl set中
- JM8.6中NALU(此处指VCL式的NALU)是如何写进码流的?
- Java:JComboBox 用法
- 【C++11】随机数函数库random
- Eclipse 自动生成 Ant的Build.xml 配置文件
- 安装SQL Server2008的示例数据库AdventureWorks 2008
- (转)LuaPlus C++ 函数互调
- 面向对象纯JS 导出Excel,拥有它,你所需要做的就是setup数据格式(目前仅提供单个Sheet的导出,持续更新中...)。
- 程序员的八个级别
- 在写计算器时学到的