#è§é¢ç¼ç ä¹H.264ï¼3ï¼
### ç®å说说ç¼ç
å½æ们ææå头ééç»é¢ç´æ¥åå
¥å°æ件ä¸æ¶ï¼æ们ä¼åç°æ²¡ä¸ä¼æ件已ç»é常大äºãè¿å¯¼è´å¾ä¸éåä¿ååä¼ è¾ï¼æ以éè¦ç¼ç ï¼æç»é¢æ°æ®è¿è¡å缩ãè§é¢ç¼ç æ åæå¾å¤ï¼èæ们è¿é讲çæ¯H.264ç¼ç ãå
¶ä»è¯·çï¼[è§é¢ç¼ç æ åæ±æ»åæ¯è¾](https://blog.csdn.net/leixiaohua1020/article/details/84483343) ã
### H.264ç¼ç
å¶è®¢H.264ç主è¦ç®æ æ两个ï¼
ï¼1ï¼è§é¢ç¼ç å±(VCLï¼å
¨ç§°ï¼Video Coding Layer)ï¼å¾å°é«çè§é¢å缩æ¯ã
ï¼2ï¼ç½ç»æåå±(NALï¼å
¨ç§°ï¼Network Abstraction Layer)ï¼å
·æè¯å¥½çç½ç»äº²åæ§ï¼å³å¯éç¨äºåç§ä¼ è¾ç½ç»ãèNALåæ¯ä»¥NALUï¼NAL Unitï¼ä¸ºåå
æ¥æ¯æç¼ç æ°æ®å¨åºäºå
交æ¢ææ¯ç½ç»ä¸ä¼ è¾çã
#### H.264ç¼ç å¨

ä¸é¢æ¯H264çç¼ç å¨åçå¾ï¼ç¼ç æ¶è¿è¡å¸§å
ç¼ç å帧é´ç¼ç ãç¨ç¸æºå½å举ä¾ï¼å½ç¸æºå½åè¿ç¨å¸§åºç°ä¸å¸§å¸§ç»é¢ï¼æ²¡æå缩ä¹é´é½æ¯å¯ä»¥åç¬ä½ä¸ºä¸å¼ å®æ´çç
§çï¼ç»è¿H264ç¼ç å¨åä¼åºç°ï¼
- 1.SPSãPPSï¼çæå¾ççä¸äºåæ°ä¿¡æ¯ï¼æ¯å¦å®½é«çãä¸è¬æ¯å¼å¯ç¼ç å¨åç第ä¸æ¬¡I帧åè¾åºä¸æ¬¡ã
- 2.I帧ï¼ç¼ç å第ä¸ä¸ªå®æ´å¸§ï¼å
å«ä¸å¼ å¾ççå®æ´ä¿¡æ¯ï¼ä½æ¯ä¹æ¯å缩çã主è¦æ¯è¿è¡å¸§å
å缩ï¼æä¸å¸§å¾çåå为å¾å¤`å®å`ï¼å¦ï¼16x16ã8x16ã8x8ã4x4ççï¼è®°å½å®å顶é¨å左侧åç´ ç¹æ°æ®ï¼ä»¥åé¢æµçæ¹åã
- 3.B帧ï¼å«ååé¢æµå¸§ãç¼ç å¨éå°ä¸ä¸å¸§ç»é¢ä¸åé¢å¸§ååé常é常å°ï¼ç¸ä¼¼åº¦å¨95%ä¹å
ï¼ï¼æ¯å¦å¨å½åä¸ç人å¨ååï¼å½éå°ååç¥å¾®æç¹å¤§çP帧æåæ¢ï¼è¿ä¼åºç°å¤å¼ B帧ï¼ä¸ºäºå°½å¯è½çåå¨æ´å°çä¿¡æ¯ï¼å°åèåé¢çIååé¢çP帧ï¼æä¸é´ååçæ°æ®åå¨ä¸æ¥ï¼è¿æ ·ç¼ç è®°å½è¿å¨ç¢éåæ®å·®æ°æ®å³å¯ãæ以ç¼ç å¨å½éå°è¿äºå¸§æ¶ï¼å
çå¾
P帧ç¼ç ç»æåæè¿è¡ç¼ç B帧ï¼å æ¤è¾åºé¡ºåºå¨P帧ä¹åã
- 4.P帧ï¼æäºI帧ä½ä¸ºåºç¡ï¼På°±æåèç对象ãè·åé¢I帧çååé常å°ï¼ç¸ä¼¼åº¦70%ä¹å
ï¼ã
- 5.GOFï¼æä¸é¢è¯´å½å人å¨åååºæ¯æ¶ï¼å°ä¸ç»æ°æ®ç¸å·®è¾å°çå¾çè¿è¡ç¼ç ï¼è¿å°±æäºGOFï¼å³ï¼`group of picture`ï¼å³ä¸ç»å¾çï¼ä¹å«ä¸ä¸ªåºæ¯çä¸ç»å¾çãæ¯ä»ä¸ä¸ªI帧å¼å§å°ä¸ä¸ä¸ªI帧åçä¸ç»æ°æ®ãæ¥çç¼ç å°±æ¯è¿æ ·çä¸ä¸ªä¸ªGOFçè½®åã
å¦æä¸è¿½æ±å
¶ä¸çç»èï¼æä»çæä¸ä¸ª"é»ç"çè¯ï¼ç¼ç æäºï¼

解ç æäºï¼

ç¼è§£ç å¨å·¥ä½å
·ä½ç»èæ们å¯ä»¥ä¸ç¨æ·±ç©¶ï¼ä½æ¯è¾å
¥åè¾åºçç»æä¸å®è¦ç¥éï¼å 为æä»¬æ ¹æ®è¿ä¸ªå¯ä»¥åå¾å¤äºæ
ï¼æ¯å¦ï¼
> ç´ææ¯è¿å¤çè¾åºB帧ä¼æä»ä¹å½±åï¼ä¼åºç°å»¶è¿ï¼ï¼ï¼
#### ç¼ç çè¾å
¥ä¸è¾åº
ä¸å¼ å¼ ç»é¢éè¿ä»¥H.264ç¼ç æ åçç¼ç å¨(å¦x264)ç¼ç åï¼è¾åºä¸æ®µå
å«N个NALUçæ°æ®ï¼æ¯ä¸ªNALUä¹é´éè¿`èµ·å§ç `æ¥åéï¼å¦å¾ï¼

- **èµ·å§ç ï¼** 0x00 00 01 æè
0x00 00 00 01ã
å¨ç½ç»ä¼ è¾ï¼å¦RTMPï¼æè
ä¸äºå®¹å¨ä¸ï¼å¦FLVï¼ï¼é常ä¼æNALUæ´åå°è§é¢åºåçæ°æ®ä¸ãå¦ä¸å¾çflvæ ¼å¼ï¼

æ以è¿ç¯æç« ä¸»è¦å¦ä¹ NALUçåºæ¬ç¥è¯ï¼å¦ä¼å¦ä½å»åæä¸æ®µNALUæ°æ®ã
#### NALUï¼NAL åå
ï¼
NALU(NAL Unitï¼NAL åå
)çç»æé¨åå¦ä¸å¾ãå
¶ä¸ï¼f(0)å 1bitï¼u(2)å 2bitï¼u(5)å 5bitï¼æä¸å¦æåºç°ç±»ä¼¼æ述符请ç[H.264æ述符](./h264-descriptor.md) ã

`forbidden_zero_bit`ï¼ç¦æ¢ä½ï¼åå§ä¸º0ãå½å®¢æ·ç«¯æ¥åå°è¯¥ä½ä¸º1æ¶ï¼åä¼ä¸¢å¼è¯¥NALåå
ç解ç ï¼è¡¨ç¤ºå¼å¸¸æ°æ®ã
`nal_ref_idc`ï¼ä¼å
级ï¼è¶å¤§ä¼å
级è¶é«ãæ¯å¦ï¼I帧ä¼å
级大äºB帧ï¼DPSè¯çä¼ä¼å
解ç éè¦æ§é«çã
ä»ä¸å¾å¯ä»¥çåºæ¥ï¼å½åNALåå
å±äºä»ä¹æ ·çç±»åï¼è¿åå³äºRBSPå
·ä½æ¯ä»ä¹æ ·çç±»åï¼èRBSPçç±»åæ¯æ ¹æ®`nal_unit_type`çå¼æ¥å®ä¹çã
â å½`nal_unit_type`为1~5æ¶ï¼RBSP为åçç±»åï¼æ5ç§åçç±»åï¼ï¼æ´ä¸ªNALåå
ç±»å为VCL NALåå
ï¼VCLæ¯ä¸é¢è¯´çè§é¢ç¼ç å±ï¼éé¢æç¼ç åç»é¢æ°æ®ã
â¡å½`nal_unit_type`为å
¶ä»æ¶ï¼RBSP为åºååæ°éç±»åãå¾ååæ°éç±»åççï¼æ´ä¸ªNALåå
ç±»å为éVCL NALåå
ã
å
·ä½ç`nal_unit_type`æ对åºçRBSPç±»åå¦ä¸è¡¨æ示ï¼
| nal_unit_type | NAL åå
å RBSP è¯æ³ç»æçå
容 |
| ------------- | ------------------------------------------------------------ |
| 0 | æªæå® |
| 1 | ä¸ä¸ªéIDRå¾åçç¼ç æ¡å¸¦
slice_layer_without_partitioning_rbsp( ) |
| 2 | ç¼ç æ¡å¸¦æ°æ®åå²åA
slice_data_partition_a_layer_rbsp( ) |
| 3 | ç¼ç æ¡å¸¦æ°æ®åå²åB
slice_data_partition_b_layer_rbsp( ) |
| 4 | ç¼ç æ¡å¸¦æ°æ®åå²åC
slice_data_partition_c_layer_rbsp( ) |
| 5 | IDRå¾åçç¼ç æ¡å¸¦
slice_layer_without_partitioning_rbsp( ) |
| 6 | è¾
å©å¢å¼ºä¿¡æ¯ (SEI)
sei_rbsp( ) |
| 7 | åºååæ°éï¼SPSï¼
seq_parameter_set_rbsp( ) |
| 8 | å¾ååæ°é(PPS)
pic_parameter_set_rbsp( ) |
| 9 | 访é®åå
åé符
access_unit_delimiter_rbsp( ) |
| 10 | åºåç»å°¾
end_of_seq_rbsp( ) |
| 11 | æµç»å°¾
end_of_stream_rbsp( ) |
| 12 | å¡«å
æ°æ®
filler_data_rbsp( ) |
| 13 | åºååæ°éæ©å±
seq_parameter_set_extension_rbsp( ) |
| 14..18 | ä¿ç |
| 19 | æªåå²çè¾
å©ç¼ç å¾åçç¼ç æ¡å¸¦
slice_layer_without_partitioning_rbsp( ) |
| 20..23 | ä¿ç |
| 24..31 | æªæå® |
### SPSï¼åºååæ°éï¼
SPSå
¨ç§° `Sequence parameter set`(åºååæ°é)ï¼å½`nal_unit_type`=7æ¶ï¼RBSPå°±æ¯SPSç±»åï¼ä¹å¯ä»¥è¯´NALåå
为SPSçNALåå
ãSPS主è¦å
å«çæ¯é对ä¸è¿ç»ç¼ç è§é¢åºåçåæ°ï¼å¦å¸§æ°ãå¾å尺寸çï¼è¯¦è§ä¸è¡¨ *åºååæ°éRBSP è¯æ³*ï¼

ä¸é¢ä¸ç主è¦åæ°çå«ä¹ï¼
####profile_idc
- **profile_idc** 档次ï¼H.264ç¼ç æ åæå 个档次ï¼ç级è¶é«è§é¢è¶æ¸
æ°ï¼ï¼
| å¼ï¼åè¿å¶ï¼ | 表示çæä¹ |
| ------------ | ------------------ |
| *66* | Baselineï¼ç´æï¼ |
| *77* | Mainï¼ä¸è¬åºæ¯ï¼ |
| *88* | Extended |
| *100* | High (FRExt) |
| *110* | High 10 (FRExt) |
| *122* | High 4:2:2 (FRExt) |
| *144* | High 4:4:4 (FRExt) |
####level_idc
- **level_idc** æ大æ¯æç æµèå´ï¼
æ è¯å½åç æµçLevelãç¼ç çLevelå®ä¹äºæç§æ¡ä»¶ä¸çæ大è§é¢å辨çãæ大è§é¢å¸§ççåæ°ï¼ç æµæéµä»çlevelç±level_idcæå®ã
| å¼(åè¿å¶) | 表示æ大æ¯ææ¯ç§ç æµå¤§å° |
| --------------------- | ------------------------------------------------------------ |
| *10* | 1 (supports only QCIF format and below with 380160 samples/sec) |
| *11* | 1.1 (CIF and below. 768000 samples/sec) |
| *12* | 1.2 (CIF and below. 1536000 samples/sec) |
| *13* | 1.3 (CIF and below. 3041280 samples/sec) |
| *20* | 2 (CIF and below. 3041280 samples/sec) |
| *21* | 2.1 (Supports HHR formats. Enables Interlace support. 5 068 800 samples/sec) |
| *22* | 2.2 (Supports SD/4CIF formats. Enables Interlace support. 5184000 samples/sec) |
| *30* | 3 (Supports SD/4CIF formats. Enables Interlace support. 10368000 samples/sec) |
| *31* | 3.1 (Supports 720p HD format. Enables Interlace support. 27648000 samples/sec) |
| *32* | 3.2 (Supports SXGA format. Enables Interlace support. 55296000 samples/sec) |
| *40* | 4 (Supports 2Kx1K format. Enables Interlace support. 62914560 samples/sec) |
| *41* | 4.1 (Supports 2Kx1K format. Enables Interlace support. 62914560 samples/sec) |
| *42* | 4.2 (Supports 2Kx1K format. Frame coding only. 125829120 samples/sec) |
| *50* | 5 (Supports 3672x1536 format. Frame coding only. 150994944 samples/sec) |
| *51* | 5.1 (Supports 4096x2304 format. Frame coding only. 251658240 samples/sec) |
####seq_parameter_set_id
- **seq_parameter_set_id** æ è¯ç¬¦ï¼æ¬åºåçidå·ï¼ä¼è¢«PPSå¼ç¨ã
####chroma_format_idc
- **chroma_format_idc** ä¸äº®åº¦åæ ·å¯¹åºçè²åº¦åæ ·
chroma_format_idc çå¼åºè¯¥å¨ 0å° 3çèå´å
ï¼å
æ¬ 0å 3ï¼ã**å½ chroma_format_idcä¸åå¨æ¶ï¼åºæ¨æå
¶å¼ä¸º 1ï¼4ï¼2ï¼0çè²åº¦æ ¼å¼ï¼ã**
è²åº¦éæ ·ç»æ
| chroma_format_idc | è²å½©æ ¼å¼ | SubWidthC | SubHeightC |
|---------------------|-----------|-------------|---------------|
|0 | åè² |- | - |
|1 | 4:2:0 |2 | 2 |
|2 | 4:2:2 |2 | 1 |
|3 | 4:4:4 |1 | 1 |
####num_ref_frames
è§å®äºå¯è½å¨è§é¢åºåä¸ä»»ä½å¾å帧é´é¢æµç解ç è¿ç¨ä¸ç¨å°ççæåè帧åé¿æåè
帧ãäºè¡¥åèåºå¯¹ä»¥åä¸æ对çåèåºçæ大æ°éãnum_ref_frames å段ä¹å³å®äº 8.2.5.3 èè§å®çæ»å¨çªå£æä½
ç大å°ãnum_ref_frames çåå¼èå´åºè¯¥å¨ 0 å° MaxDpbSize ï¼åè§ A.3.1 æ A.3.2 èçå®ä¹ï¼èå´å
ï¼å
æ¬ 0 å
MaxDpbSize ã
####pic_width_in_mbs_minus1
- **pic_width_in_mbs_minus1** å 1æ¯æ以å®å为åå
çæ¯ä¸ªè§£ç å¾åç宽度ã
> æ¬å¥æ³å
ç´ å 1 åææå¾å宽度ï¼ä»¥å®å为åä½ï¼PicWidthInMbs = pic_width_in_mbs_minus1 + 1
> éè¿è¿ä¸ªå¥æ³å
ç´ è§£ç å¨å¯ä»¥è®¡ç®å¾å°äº®åº¦åé以åç´ ä¸ºåä½çå¾å宽度ï¼
> PicWidthInSamplesL = PicWidthInMbs * 16
> ä»èä¹å¯ä»¥å¾å°è²åº¦åé以åç´ ä¸ºåä½çå¾å宽度ï¼
> PicWidthInSamplesC = PicWidthInMbs * 8
> 以ä¸åé PicWidthInSamplesLã PicWidthInSamplesC åå«è¡¨ç¤ºå¾åç亮度ãè²åº¦åé以åç´ ä¸ºåä½ç宽ã
>
> H.264 å°å¾åç大å°å¨åºååæ°éä¸å®ä¹ï¼æå³çå¯ä»¥å¨éä¿¡è¿ç¨ä¸éçåºååæ°éå¨æå°æ¹åå¾åç大å°ï¼çè³å¯ä»¥å°ä¼ éçå¾ååªè£åè¾åºã
>
> ```cpp
> frame_width = 16 Ã (pic_width_in_mbs_minus1 + 1);
> ```
#### pic_height_in_map_units_minus1
- **pic_height_in_map_units_minus1** å 1表示以æ¡å¸¦ç»æ å°ä¸ºåä½çä¸ä¸ªè§£ç 帧æåºçé«åº¦ã
> æ¬å¥æ³å
ç´ å 1 åææå¾åé«åº¦ï¼
> PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1
> PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits
> å¾åçé«åº¦ç计ç®è¦æ¯å®½åº¦ç计ç®å¤æï¼å 为ä¸ä¸ªå¾åå¯ä»¥æ¯å¸§ä¹å¯ä»¥æ¯åºï¼ä»è¿ä¸ªå¥æ³å
ç´ å¯ä»¥å¨å¸§æ¨¡å¼ååºæ¨¡å¼ä¸åå«è®¡ç®åºåºäº®åº¦ãè²åº¦çé«ãå¼å¾æ³¨æçæ¯ï¼è¿é以 map_unit 为åä½ï¼ map_unitçå«ä¹ç±åæåè¿°ã
>
> ```cpp
> PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1;
> frame_height = 16 Ã (pic_height_in_map_units_minus1 + 1);
> ```
####ææSPS
ä¸é¢ä¸ºä»ä¸ä¸ªåªæ¾h.264è§é¢ç¼ç æ件çä¸æ®µï¼SPSï¼ï¼

ue(v)åse(v)ç计ç®å
¬å¼è§ [H.264æ述符](./h264-descriptor.md) ã
```shell
# 00000001 6764001E ACD940A0 2FF96100 00030001 00000300 320F162D 96
00000001 #èµ·å§ç
#NALåå
头---0x67 0110 0111 --------------
0... .... # forbidden_zero_bit -->u(1)
.11. .... # nal_ref_idc -->u(2) -->HIGHEST
...0 0111 # nal_unit_type -->u(5) -->SPS
64 # profile_idc=103 -->u(8)
#---0x00 0000 0000 --------------
0... .... #constraint_set0_flag
.0.. .... #constraint_set1_flag
..0. .... #constraint_set2_flag
...0 .... #constraint_set3_flag
.... 0000 #reserved_zero_4bits
1E # level_idc -->u(8) --> 30
#-----------0xAC 1010 1100 --------------
1... .... # seq_parameter_set_id --> ue(v) --> 0
.010 .... # log2_max_frame_num_minus4 --> ue(v) --> 1
.... 1... # pic_order_cnt_type --> ue(v) -->1 æ§è¡else if( pic_order_cnt_type == 1 )
.... .1..#delta_pic_order_always_zero_flag -->u(1)
#----------0xACD9 (1010 11)00 1101 1001 ====== æ¬å·éé¢çbitä¸é¢å·²ä½¿ç¨
.... ..00 110. .... #offset_for_non_ref_pic -->se(v)->codeNum=5->value=3
.... .... ...1 .... #offset_for_top_to_bottom_field -->se(v)->codeNum=0->value=0
.... .... .... 1... #num_ref_frames_in_pic_order_cnt_cycle -->ue(v)->0
#----------0xD940 (1101 1)001 0100 0000 ====== æ¬å·éé¢çbitä¸é¢å·²ä½¿ç¨
.... .001 01.. .... #num_ref_frames -->ue(v)->4
.... .... ..0. .... #gaps_in_frame_num_value_allowed_flag -->u(1)->0
#----------0x40A0 (010)0 0000 1010 0000 ====== æ¬å·éé¢çbitä¸é¢å·²ä½¿ç¨
...0 0000 1010 00.. #pic_width_in_mbs_minus1 -->ue(v)->32-1+8=39 --> è§é¢å®½ = (å®å + 1) X 16 = (39 + 1)X16 = 640
#----------0xA02F (1010 00)00 0010 1111 ====== æ¬å·éé¢çbitä¸é¢å·²ä½¿ç¨
.... ..00 0010 111. #pic_height_in_map_units_minus1 -->ue(v)->16-1+7=22--> è§é¢é« = (å®å + 1) X 16 = (22 + 1)X16 = 368
â¦â¦â¦â¦å°±å°è¿éäºï¼å·ä¸ªæï¼æå
´è¶£å¤§å®¶èªå·±åæä¸å»ï¼åå
```
### PPSï¼å¾ååæ°éï¼
PPSå
¨ç§°`picture parameter set`(å¾ååæ°é)ï¼å½`nal_unit_type`=8æ¶ï¼RBSPå°±æ¯PPSç±»åï¼ä¹å¯ä»¥è¯´NALåå
为SPSçNALåå
ãä¸ä¸ªåºåä¸æä¸å¹
å¾åæè
æå å¹
å¾åï¼å
¶åæ°å¦æ è¯ç¬¦pic_parameter_set_idãå¯éçseq_parameter_set_idãçµç¼ç 模å¼éæ©æ è¯ãçç»æ°ç®ãåå§éååæ°åå»æ¹å滤波系æ°è°æ´æ è¯çï¼è¯¦è§ä¸è¡¨ *å¾ååæ°éRBSP è¯æ³*ï¼

### å
¶ä»å¸¸è§å称缩å
| åè¯ç¼©å | ä¸æå«ä¹ |
| --------------------- | ------------------------------------------------------------ |
| *CABAC* | åºäºä¸ä¸æçèªéåºäºè¿å¶ç®æ¯ç¼ç |
| *CAVLC* | åºäºä¸ä¸æçèªéåºåé¿ç¼ç |
| *CBR* | æå®æ¯ç¹ç |
| *CPB* | ç¼ç å¾åç¼ååº |
| *DPB* | 解ç å¾åç¼ååº |
| *DUT* | 被æµè§£ç å¨ |
| *FIFO* | å
è¿å
åº |
| *HRD* | åæ³åè解ç å¨ |
| *HSS* | åæ³ç æµè°åº¦å¨ |
| *IDR* | å³æ¶è§£ç å·æ°ï¼Iå¸§ï¼ |
| *LSB* | æä½ææä½ |
| *MB* | å®å |
| *MBAFF* | å®åèªéåºå¸§ï¼åºç¼ç |
| *MSB* | æé«ææä½ |
| *NAL* | ç½ç»æ½è±¡å± |
| *RBSP* | åå§åèåºåè½½è· |
| *SEI* | è¡¥å
çå¢å¼ºä¿¡æ¯ |
| *SODB* | æ°æ®æ¯ç¹ä¸² |
| *UUID* | éç¨å¯ä¸æ§æ è¯ç¬¦ |
| *VBR* | å¯åæ¯ç¹ç |
| *VCL* | è§é¢ç¼ç å± |
| *VLC* | åé¿ç¼ç |
### X264
è¿æ¯å½é
好è¯çH.264åè®®æ åçç¼ç å·¥å
·ï¼è¿éç®åä»ç»ä¸ä¸å¦ä½ä½¿ç¨ã
ï¼1ï¼ä¸è½½ï¼https://www.videolan.org/developers/x264.html
ï¼2ï¼ç¼è¯ï¼androidç交åç¼è¯ï¼å¹³å°ï¼Macï¼
```shell
#!/bin/sh
##########èæ¬å¿è®°æ¯åèåªä½å¤§ç¥çäº##########
#ndkçè·¯å¾
NDK=/Users/Qincji/Desktop/develop/android/source/sdk/ndk/android-ndk-r17c
API=17 #æä½æ¯æAndroidçæ¬
#ç¼è¯å¹³å°darwin-x86_64为macï¼linux-x86_64为linux
HOST_PLATFORM=darwin-x86_64
function build_x264 {
OUTPUT=$(pwd)/"android"/"$CPU"
./configure \
--prefix=$OUTPUT \
--cross-prefix=$CROSS_PREFIX \
--sysroot=$SYSROOT \
--host=$HOST \
--disable-asm \
--disable-shared \
--enable-static \
--disable-opencl \
--enable-pic \
--disable-cli \
--extra-cflags="$EXTRA_CFLAGS" \
--extra-ldflags="$EXTRA_LDFLAGS"
make clean
make install
echo "ç¼è¯ç»æï¼è·¯å¾å¦ä¸ï¼"
echo "$OUTPUT"
}
CPU="armeabi-v7a"
CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-
SYSROOT=$NDK/platforms/android-$API/arch-arm/
EXTRA_CFLAGS="-D__ANDROID_API__=$API -isysroot $NDK/sysroot -I$NDK/sysroot/usr/include/arm-linux-androideabi -Os -fPIC -marm"
EXTRA_LDFLAGS="-marm"
HOST=arm-linux
build_x264
```
ï¼3ï¼æç¼è¯çæçéæåºç§»å
¥android studio

å¨CMakeList.txtæ件ä¸æ·»å ï¼
```cmake
...
include_directories(include)
...
target_link_libraries(
...
x264
)
```
ï¼4ï¼APIç®å使ç¨
```c++
/**
å
³é®æ¥éª¤ï¼æ¥èªé·ç¥ï¼https://blog.csdn.net/leixiaohua1020/article/details/42078645
x264_param_default()ï¼è®¾ç½®åæ°éç»æä½x264_param_tç缺çå¼ã
x264_picture_alloc()ï¼ä¸ºå¾åç»æä½x264_picture_tåé
å
åã
x264_encoder_open()ï¼æå¼ç¼ç å¨ã
x264_encoder_encode()ï¼ç¼ç ä¸å¸§å¾åã
x264_encoder_close()ï¼å
³éç¼ç å¨ã
x264_picture_clean()ï¼éæ¾x264_picture_alloc()ç³è¯·çèµæºã
åå¨æ°æ®çç»æä½å¦ä¸æ示ã
x264_picture_tï¼åå¨å缩ç¼ç åçåç´ æ°æ®ã
x264_nal_tï¼åå¨å缩ç¼ç åçç æµæ°æ®ã
*/
int X264Rtmp::encode(const char *url, int width, int height, int bitRate, int fps) {
//计ç®ä¸å¸§çä¿¡æ¯
int ySize = width * height;
int uvSize = ySize / 4;
FILE *fp_src = fopen(url, "rb");
//åå§åVLCå¾çç¼ç å±çåæ°
x264_picture_t *pic_in = (x264_picture_t *) malloc(sizeof(x264_picture_t));
x264_t *videoCodec = 0;
x264_param_t param;
x264_param_default(¶m);
//æ ¹æ®åºç¨åºæ¯è®¾ç½®ç¼ç é度ï¼ä»¥åç¼ç è´¨éã2ï¼x264_preset_namesï¼3ï¼x264_tune_names
x264_param_default_preset(¶m, x264_preset_names[0], x264_tune_names[7]);
//è¾å
¥æ°æ®æ ¼å¼ï¼ yuv 4:2:0
param.i_csp = X264_CSP_I420;
param.i_width = width;
param.i_height = height;
//base_line 3.2 ç¼ç è§æ ¼ï¼å½±åç½ç»å¸¦å®½ï¼å¾åå辨ççã -- https://en.wikipedia.org/wiki/Advanced_Video_Coding
param.i_level_idc = 32;
//ä¸¤å¼ åèå¾çé´b帧çæ°é
param.i_bframe = 0;
//åæ°i_rc_method表示ç çæ§å¶ï¼CQP(æå®è´¨é)ï¼CRF(æå®ç ç)ï¼ABR(å¹³åç ç)
param.rc.i_rc_method = X264_RC_ABR;
//æ¯ç¹ç(ç ç, åä½Kbps)
param.rc.i_bitrate = bitRate / 1000;
//ç¬æ¶æ大ç ç
param.rc.i_vbv_max_bitrate = bitRate / 1000 * 1.2;
//设置äºi_vbv_max_bitrateå¿
须设置æ¤åæ°ï¼ç çæ§å¶åºå¤§å°,åä½kbps
param.rc.i_vbv_buffer_size = bitRate / 1000;
//帧çï¼æ¯ç§æ¾ç¤ºå¤å°å¼ ç»é¢ï¼
param.i_fps_num = fps;
param.i_fps_den = 1;
param.i_timebase_den = param.i_fps_num;
param.i_timebase_num = param.i_fps_den;
// param.pf_log = x264_log_default2;
//ç¨fpsèä¸æ¯æ¶é´æ³æ¥è®¡ç®å¸§é´è·ç¦»
param.b_vfr_input = 0;
//帧è·ç¦»(å
³é®å¸§) 2sä¸ä¸ªå
³é®å¸§
param.i_keyint_max = fps * 2;
// æ¯å¦å¤å¶spsåppsæ¾å¨æ¯ä¸ªå
³é®å¸§çåé¢ è¯¥åæ°è®¾ç½®æ¯è®©æ¯ä¸ªå
³é®å¸§(I帧)é½é带sps/ppsã
param.b_repeat_headers = 1;
//å¤çº¿ç¨
param.i_threads = 1;
x264_param_apply_profile(¶m, "baseline");
//æå¼ç¼ç å¨
videoCodec = x264_encoder_open(¶m);
x264_picture_alloc(pic_in, X264_CSP_I420, width, height);
//ç¼ç ï¼h264ç æµ
while (!feof(fp_src)) {
//yæ°æ®
fread(pic_in->img.plane[0], ySize, 1, fp_src); //Y
fread(pic_in->img.plane[1], uvSize, 1, fp_src); //U
fread(pic_in->img.plane[2], uvSize, 1, fp_src); //V
//ç¼ç åºæ¥çæ°æ® ï¼å¸§æ°æ®ï¼
x264_nal_t *pp_nal;
//ç¼ç åºæ¥æå 个æ°æ® ï¼å¤å°å¸§ï¼
int pi_nal;
x264_picture_t pic_out;
x264_encoder_encode(videoCodec, &pp_nal, &pi_nal, pic_in, &pic_out);
//å¦ææ¯å
³é®å¸§ 3
int sps_len;
int pps_len;
uint8_t sps[100];
uint8_t pps[100];
// chroma_format_idc
for (int i = 0; i < pi_nal; ++i) {
x264_nal_t &nal = pp_nal[i];
if (nal.i_type == NAL_SPS) {
} else if (nal.i_type == NAL_PPS) {
} else {
}
}
}
}
```
### åè
- [è§é¢ç¼ç æ åæ±æ»åæ¯è¾](https://blog.csdn.net/leixiaohua1020/article/details/84483343)
- [H.264-AVC-ISO_IEC_14496-10](http://103.23.20.16/srs/trunk/doc/H.264-AVC-ISO_IEC_14496-10.pdf)
- æ°ä¸ä»£è§é¢å缩ç¼ç æ å-H.264_AVC(第äºç)
- H.264å®æ¹ä¸æç.pdf
- https://stackoverflow.com/questions/28421375/usage-of-start-code-for-h264-video/29103276
- https://blog.csdn.net/engineer_james/article/details/81750864
- [x264æµç¨](https://blog.csdn.net/leixiaohua1020/article/details/42078645)
- [x264åæ°æ³¨é](https://www.lagou.com/lgeduarticle/76946.html)