2017.11.1开始学习FFMPEG音视频编解码,通过学习雷霄骅文章

来源:互联网 发布:mac上怎样打开pdf文件 编辑:程序博客网 时间:2024/06/05 15:52

NAL Header由三部分组成:forbidden_bit,nal_reference_bit(优先级)2bit,nal_unit_type(类型)5bit。

补充一下NAL_HEADER里的nal_unit_type一字节的类型有哪些:

  • 0:未规定                                                                  
  • 1:非IDR图像中不采用数据划分的片段                (NALU_TYPE_SLICE)
  • 2:非IDR图像中A类数据划分片段                          (NALU_TYPE_DPA
  • 3:非IDR图像中B类数据划分片段                          (NALU_TYPE_DPB
  • 4:非IDR图像中C类数据划分片段                          (NALU_TYPE_DPC
  • 5:IDR图像的片段                                                     (NALU_TYPE_IDR
  • 6:补充增强信息(SEI)                                          (NALU_TYPE_SEI
  • 7:序列参数集(SPS)                                            (NALU_TYPE_SPS
  • 8:图像参数集(PPS)                                            (NALU_TYPE_PPS)
  • 9:分割符                                                                    (NALU_TYPE_AUD)
  • 10:序列结束符                                                          (NALU_TYPE_EOSEQ
  • 11:流结束符                                                              (NALU_TYPE_EOSTREAM
  • 12:填充数据                                                              (NALU_TYPE_FILL
  • 13:序列参数集扩展
  • 14:带前缀的NAL单元
  • 15:子序列参数集
  • 16 – 18:保留
  • 19:不采用数据划分的辅助编码图像片段
  • 20:编码片段扩展
  • 21 – 23:保留
  • 24 – 31:未规定
补充一下NAL_HEADER里的nal_reference_bit有哪些:

            从0到3,3为最高优先级。

          

  1. NALU_PRIORITY_DISPOSABLE = 0,  
  2.     NALU_PRIRITY_LOW         = 1,  
  3.     NALU_PRIORITY_HIGH       = 2,  
  4.     NALU_PRIORITY_HIGHEST    = 3
一般一字节的NAL HEADER :0AABBBBB,常用的NAL HEADER 取值

有:

              

0x67: SPS 0x68: PPS 0x65: IDR   0x61: non-IDR Slice0x01: B Slice0x06: SEI0x09: AU Delimiter
--------------------------------------------------------------------------------------------------------------------------------------------------------------------

上一阶段视频码流解析告一段落,上一段的程序主要实现了:从H264视频原始码流中提取NALU单元,并简单的解析NALU首部的字段,它的类型,程序稍后加上。

下一阶段主要学习AAC音频码流解析,得到它的基本单元ADTS frame以及简单解析基本单元ADTS frame首部的字段。


1.AAC原始码流是由一个个的ADTS frame组成:

                                         AAC原始码流:  

                                                                            ADTS frame+ADTS frame+ADTS frame+ADTS frame

2.每个ADTS frame单元之间通过同步字(sync word)进行分隔,同步字为0xFFF,二进制为:“1111 1111 1111”。

3.AAC码流解析的步骤就是:先搜索同步字,分离出ADTS frame单元,再解析ADTS frame首部的各个字段。

4.对关于音频码流的一些基本知识的普及:

                              AAC的英文名称是:Advenced Audio Coding,高级音频编码,是基于MPEG-2的音频编码技术。

                              原理:

                                          AAC原始码流是由一个个的ADTS frame组成,每个ADTS frame之间通过同步字进行分隔,同步字为0xFFF,二进制为“1111 1111 1111”。

                                          AAC音频码流解析的步骤是:首先从码流中搜索0xFFF,分离出ADTS frame,再解析ADTS frame首部的各个字段。

                                          ADTS 全称是:Audio Data Transport Stream,是AAC的一种十分常见的传输格式。

                                          可以把ADTS头看作是AAC的Frame Header:

                                                                                    ADTS_header+AAC ES+ADTS_header+AAC ES+ADTS_header+AAC ES

                                         ADTS头中有用的信息:采样率,声道数,帧长度。

                                         一般ADTS_Header的头信息都是7个字节,分为两部分:

                                         adts_fixed_header();

                                        adts_variable_header();

                                      

                              

syncword :同步头 总是0xFFF, all bits must be 1,代表着一个ADTS帧的开始

ID:MPEG Version: 0 for MPEG-4, 1 for MPEG-2

Layer:always: '00'

profile:表示使用哪个级别的AAC,有些芯片只支持AAC LC 。在MPEG-2 AAC中定义了3种:



sampling_frequency_index:表示使用的采样率下标,通过这个下标在 Sampling Frequencies[ ]数组中查找得知采样率的值。

There are 13 supported frequencies:

  • 0: 96000 Hz
  • 1: 88200 Hz
  • 2: 64000 Hz
  • 3: 48000 Hz
  • 4: 44100 Hz
  • 5: 32000 Hz
  • 6: 24000 Hz
  • 7: 22050 Hz
  • 8: 16000 Hz
  • 9: 12000 Hz
  • 10: 11025 Hz
  • 11: 8000 Hz
  • 12: 7350 Hz
  • 13: Reserved
  • 14: Reserved
  • 15: frequency is written explictly
channel_configuration: 表示声道数 

  • 0: Defined in AOT Specifc Config
  • 1: 1 channel: front-center
  • 2: 2 channels: front-left, front-right
  • 3: 3 channels: front-center, front-left, front-right
  • 4: 4 channels: front-center, front-left, front-right, back-center
  • 5: 5 channels: front-center, front-left, front-right, back-left, back-right
  • 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
  • 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
  • 8-15: Reserved

frame_length : 一个ADTS帧的长度包括ADTS头和AAC原始流.

adts_buffer_fullness:0x7FF 说明是码率可变的码流


将AAC ES流打包成ADTS格式,实际上就是在AAC原始流前面加上ADTS头就行了。

添加ffmpeg添加ADTS头的代码:

  1. int ff_adts_write_frame_header(ADTSContext *ctx,  
  2.                                uint8_t *buf, int size, int pce_size)  
  3. {  
  4.     PutBitContext pb;  
  5.   
  6.     init_put_bits(&pb, buf, ADTS_HEADER_SIZE);  
  7.   
  8.     /* adts_fixed_header */  
  9.     put_bits(&pb, 12, 0xfff);   /* syncword */  
  10.     put_bits(&pb, 1, 0);        /* ID */  
  11.     put_bits(&pb, 2, 0);        /* layer */  
  12.     put_bits(&pb, 1, 1);        /* protection_absent */  
  13.     put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */  
  14.     put_bits(&pb, 4, ctx->sample_rate_index);  
  15.     put_bits(&pb, 1, 0);        /* private_bit */  
  16.     put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */  
  17.     put_bits(&pb, 1, 0);        /* original_copy */  
  18.     put_bits(&pb, 1, 0);        /* home */  
  19.   
  20.     /* adts_variable_header */  
  21.     put_bits(&pb, 1, 0);        /* copyright_identification_bit */  
  22.     put_bits(&pb, 1, 0);        /* copyright_identification_start */  
  23.     put_bits(&pb, 13, ADTS_HEADER_SIZE + size + pce_size); /* aac_frame_length */  
  24.     put_bits(&pb, 11, 0x7ff);   /* adts_buffer_fullness */  
  25.     put_bits(&pb, 2, 0);        /* number_of_raw_data_blocks_in_frame */  
  26.   
  27.     flush_put_bits(&pb);  
  28.   
  29.     return 0;  

//最近感冒很严重,流行感冒,还打了针吃了药,所以中间间断了


阅读全文
0 0
原创粉丝点击