H264/H265 PS 流分析
阿新 • • 發佈:2019-02-03
對於第一幀的第一個包開始為PS頭+系統頭+節目對映流
1) Pack start code:包起始碼欄位,值為0x000001BA的位串,用來標誌一個包的開始。
2) System clock reference base,system clock reference extenstion:系統時鐘參考欄位。
3) Pack stuffing length :包填充長度欄位,3 位整數,規定該欄位後填充位元組的個數
80 60 53 1f 00 94 89 00 00 0000 00 00 00 01 ba €`S..??........?
7e ff 3e fb 44 01 00 5f 6b f8 00 00 01 e0 14 53 ~.>?D.._k?...?.S
80 80 05 2f bf cf bed1 1c 42 56 7b 13 58 0a 1e €€./????.BV{.X..
08 b1 4f 33 69 35 0453 6d 33 a8 04 15 58 d9 21 .?O3i5.Sm3?..X?!
9741 b9 f1 75 3d 94 2b 1f bc 0b b2 b4 97 bf 93 ?A??u=?+.?.?????
前12位是RTP Header,這裡不再贅述;
000001ba是包頭起始碼;
接下來的9位包括了SCR,SCRE,MUXRate,具體看圖7
最後一位是保留位(0xf8),定義了是否有擴充套件,二進位制如下
1111 1000
前5位跳過,後3位指示了擴充套件長度,這裡是0.
000001ba5cd2cf388401028f63fe ffff00575ece PS頭
000001bb00 12 //長度
8147b104e17fe0e080c0c008bde080bfe080 系統頭
000001bc 004e//長度
eeff 0024(stream info len)
400e484b01001195a89df27700ffffff4112484b000102030405060708090a0b0c0d0e0f
0020(stream map len) 1b(stream type) e0(stream id) // stream id & stream type can detemine the codec
0x1b && e0 ----> h264
0x24 && e0 ----> H265
001c420e030810ea07800438111f00001c202a0a7fff000007081ffef0874b920c23 節目對映頭
000001e0 002a//長度
8c800a 2734b3ce21(TS) fffffffffc //OPTIONAL PES header
00000001674d00299a6603c0113f2cd404040500000303e80000c35004 // PES 頭
000001e0 000e
8c0003 fffffc // PES OPTIONAL header
0000000168ee3c80 // PES 頭
000001e0 97de
8c0002 fff8
00000001(H264 startcode) 65(NALU type) 8880100015ff006f984997ff0c71232680b211d922115395b10fc3baf38574a402bcc7b5cd2649859b01c669d1800c44c081111e5ed57cac965c829f4ab52bd940b486c3f641c2697e20c6f2a31f520a80a83a99eeed8ff1525ec5e1d32876de5041c2976459022f0a4f31ffd12591a6c4925ecf5284d17466f153ce43fb903bc0e63eb71368b9e19abd34597a62e7d153eda72c46d0e3a8231bce0d2dd580ff4804822a39664039e845fe6bf24276b98a053e29d11afc12a293ddaba75c1e829b4c3f458ed0572aa0e6f830a418f2dbbc0c20d634d51ccc683d134a55f6a38ac5174b324b02eebc6bbfa7ba94bddf524a6c944337ac7cc702726b2bd1f42b6a39108225ce4fc02e161af36ff0468953583870e4205383d94f076a42457f4806894a5ab1f293534e4f853783d9dab0b2376140b93d94cc1b3e872856dfab0547a7c68701ef9a2376ca1af2af68bdbc60ce213f93afe6d1ce67b7e2ec002fc2c03a2507d43bee5c6b467ca47d5a8d32b3974db81d4d365b93a1bd297e97d829f4da1ac006cafb33c2c513b62a6197705e86c44ed9be062cdd85a97e4239a640e70396c50b7506c98ed674594c71ea9f8a3f5634234edacedca6000182f813aa8fe0dd89439fc36d38b6c67bc46e00776713341cc837d029b69c8886a03274ce2675bc8c04d4a682861f169d8caf3dd752bf9377787a662e7ddaf0f5a31bdb5ef74a8aa1a7afc8824cadc9b190250915c15fab8f4bd9f721b9907732b0fbf5cab92048a846b1025c1f543da9edb91c0d5db1e93690e2e9867430658f9a6becf759d52c99e8711ecc366adcd27fe61ac230c2240fa6e2e502ad1feb4f322ebe7ffbc7a0aff2396a6c778edb05f703f1f1e35e89ec652fcc85104990c95888d4745a56008f2d7f1505b707813efcd168a9f5097b256b74c5f6263e8ac8848f6e0accbe0c46f6bcd0258e8d37f3d0254c5f29600dc046eea5ce31c2046d0f34a792045660e432cbe37ab26cd44fae7f7bc1ad639ce489eb8f7403344e3c2263dac1e333f6d36d8b84a42ffb3d41f7b9aa1aba12fec98dafb8066621ea833c3178b2d85b7312e46f50a921f394850dc826a92ee1da3539fd944a6ec69ab2aad230464f7bf752b859b0134980e4d39c1dd7df3bbf5feb1c40d37c6fad02fe9ee97d013299236ae597d2479cc9487b36ef271b382afb66af217d0410596e3bfe48ca3c8633addc9c6414396fe62199536800215b633438e3bfc50761ba6081c8ee465d5bd482a93c036bdb55a17d765cc912e3c2381e63b6947a8fe7fa14aeca8bdb501942be2c6d28bebed06d120c6a1422fc29588633ee11b000531e84e4a0fcbe33ecabcfc4e1d2c68a01426021e3359d24032319d500f1899fe96e735c7bd15f7914c6f51acea443243fb5b517b713bacf572d6d45790168d39179510041f7dc4f6026ce9db7bcb6588b74e95c37f0389cf407d4dc914c6d3c66b60f84e5e1188226eceed6a4462acb102d62403db27662775030195a87c60837f4b6e9d62190a017bfe00510f5fc7ba7687aff4d8118aa2bfbf0d32d388844079a0835d038fdced9c022f266a866ad8ca9d86ce8418d3d5b9d7f4d01bd3397685e5334e30bff63ff7e8a4520b1c2a0e770b3603bd0520c656c02fb02277a8667381626d8e0954e44e9afe597
startcode followed with:
其中0x67的二進位制碼為:
0110 0111
4-8為00111,轉為十進位制7,參考第二幅圖:7對應序列引數集SPS
其中0x68的二進位制碼為:
0110 1000
4-8為01000,轉為十進位制8,參考第二幅圖:8對應影象引數集PPS
其中0x65的二進位制碼為:
0110 0101
4-8為00101,轉為十進位制5,參考第二幅圖:5對應IDR影象中的片(I幀)
其中0x41的二進位制碼為:
0100 0001
4-8為00001,轉為十進位制1,參考第二幅圖:根據上圖可知道這段碼流是【不分割槽、非IDR影象的片】,在baseline的檔次中就是P幀,因為baseline沒有B幀。
所以判斷是否為I幀的演算法為: (NALU型別 & 0001 1111) = 5 即 NALU型別 & 31 = 5
比如0x65 & 31 = 5
PTS DTS標誌欄位 PTS_DTS_flags
2位欄位。當值為'10'時,PTS欄位應出現在PES分組標題中;當值為'11'時,PTS欄位和DTS欄位都應出現在PES分組標題中;當值為'00'時,PTS欄位和DTS欄位都不出現在PES分組標題中。值'01'是不允許的。
中間的某一些幀
000001ba5cd2d4198401028f63fe ffff00575ed0 //PS header
000001e0 0aa2
//1374+
8c80082734b50661fffff800000001619a02026a58af9412669b9edea574537bd2c084d4dbf498cf1543dcd217c43dbcb56adaa220651871c3061a5dc7065f3975e450f4554b99f718990ef5dea8f7aa9a89ec6a58911a6a39bac2d96fd9123699810500c5048d6d26940abc460d5259aed000efcd18bc2161cc6c2ea860030629fce38031df16aa500d89586c59a87873f2ce87d2680cc00ad5b7adaeec9b909a1127f1a93cf13050c3117a2fa39cb66d7d3b6732b68f02bbc92051381a6f322c556bfac2e9ce4ecae153f80e238e773b12552d2ff901e621c9a70d6ea71fae9076e35a455a1a5104443a71e9d1c86efa7932f8f90244b0a1a9e91512092f296b93c2784ece479f247c1f3e66a06371286f3dac2d9e9d64e1b981ffc66be467e06a65d90bebc4c5a2adbf2b44a65cf35190d5d2b298201e9597163c0885c97b976121f24cf581188f84fd32bea9899c95d4e7eb0cebf873eac665bd29bf0812ed819f972170d251372b2e47caf9d4f7873615f23161a1b2d089dad6c8d8928fe47ef06b63d300f5378e1b2317b2243db1495eefd89f9557a9ae18c387d8aa1d78be8713ebfde000d9bf2e07c6f5c11905f3f5d076cf4eae91e3f6d48c06d95b3a1dddda268ed5c78d2d209ec01a188da650af8daadb50693f0bf978139a130669d3f8ab0f366a91c56da46f18adbca973a8aadd03aa99bc46c847b2ce3f5221610aeab7950b8ab775c569128b8bdd7877ad817d3481663e94d9b9174e41efa28589860692b15f213649ad0e7f2ec426b07b927628ef828bda53b7c2639f99896db4840b2f0272c936954376c330b7e43dca7ddc63ec09954e08fc5364e4856547e2afe12e27b66a3b77f29ad10394fd364245b148f00b6899998d14e66303d9ab4084f1285fbb4294cd11d3dd78fc0bbacf3d67ee063e2bb37430793cd29c403d67af9c654af0ffa4c3c1ee84278985a48ed3f93d5ad07c77fe7fe976c238bf5634610ba95015f159c2547d6ba1ded171f77c83dd0ecbe6f7b714326ca0fff0da004bc350deffc4e8b33113b67702939b22a322d28c3b2adfc7a04c7193b5d6941fd9e4456be1a9f09885db9e13cfb005216e245869c77563d65855a64b6c54b9e6f1bdf5af2bf19271784ef451efe0fdf71388229b2a068159fc20418a745b8a95434b4d5aacd9136f8b56090ac6a0b6ed1ec15e3c3072870b0fe9e83b98f90d18aee6aaed3c4e3226b89fb970b30833b558ff583651dd7c473e33e844ea01599abc32f98b0e30e2f6d8b8868261dd133c0bc394b262dd8791db83630e37b3b17087d3cb6058976a6db1116da7c8dc4bdde87ebc96724b2d6b2d4f6d17de9f79b3683412210236859f5b869db41fdc39581546f185980c42bb009040383d1be7b40bec64979998e4ddb1d922a59401a2458e58db3dffb965cac11b41475451b8a67d25d65a91f0e125594733986089f2f958339de1becee46d248064c77570fc63770ff8fbc497a8c2b59bca67fab43e7297229728a0a78492b7a113786829ac8950404fbe2d5553110ba0e13de87dfb59812cf503989fe7616282ac79b69a23712f47aee96814fcb2d02f4f1f6f4ad4e842d326fae632938396f85a6bb1238554e0253c0e167fafda9b51c3b6bba6e692e6b35afc99b497b7a1cc3645217032e9d9a356692907a0e0e92bd3a8653ebcb0c158c09ad426f029f134c064d3e6b75925bc2ef4b14258820a97a5cfa6b05dcd81eb2cdffd241b7d28637b747befb421ac6bb6190072ff1b6d17b6c498c362ece43e460d527f67dfa707b9a902d7c43887c45b151cc03ab6c49e1f55edc174d8b86ce5aadd8fd290c46b451dd2f89a48b96152abcc3aaa4473cc8e3caa40f8b490ff629708336804158acc2f2d3b439e4df1e08a65d25d29e4959b1abb935f262fe93a101a9efd5515419ccc
//1348 +1374 == aa2
ea9d609e63b9ce925297385989c2f1270e66d7d34d586ae73569f319953012d7d6c8a28aebc3a0206883034dc298f1931550593d35d0b665bce1c27c2d485193a3f5894a81182219f2921e9df95f7f8501ba5371cf1f259d9c0b6fc98e37ea01884af42f91025ff12a5404b81ad4661cf4e49eb2cebabfd574047c4ddef68c084f2c5ae31eddd5a599b1508f99c8b38cedc70339989ca457084023e591e68b1c534479efb42d2ffa609fd280a92638ab00b5740699cd05ac8fa6f12092d8f411d62d0b58e3b27683c8fa067739d1ccb120fae3d1730b8af09b45ccfa4ac3a31ba9c50f732ef3d0f711b137bfb859fd8e32cdad74e6016ec19debc9a25998077b2f0329bf3f2bde703b4694be2ebc5c297c9fdbd28b21da45e6f66a652ef94a850b5ed927f4cef2b26d3ff5459bffbdfcac841eed478364ed678586ccd0c1d6cfb9e58593371684fd27b757648c7220d586ec0222c1c8813921ecb3533dc264f63d34f5ee3f817eda0876228a7850e1bbef2dc223bfca02957566d4c749e95debcb0e5b33d9cb24f85bb82d80ae0d8b0a776e8a0c5b93a8fa450fbbe8475c1c0726119ad78b42e0ab9c13113e27a298dcbc4415c4f727141fd723634b212fc88efbcbc6d0fcfbc8b057a4d3cf0860fd0e1f422fa9cd6c2ee0ae68cf1262ca752b8da1a5fdb2cee9070e827e4d96923b69faaf9b2a2f9313053512498937ce0a3d4f91adee9f8ea4854013f916f187c5b3d64a7b29e312391dfe2b5c8ee97f2a68c7f0d6dcb3959c202dbfbc618c1515a0fe998ee20719ec966922f0332d89e2b646c7dec72605fe7e9660bd6a7f604c99ee25bfc72984f3f455795cea4d14c882a893f94aa20bad51fb6df8e23e0d66de3a34ce73a1454939b75f467d1615824f6451b82aa2297ecf2e7bf44a5d40408b8ddce75093a1c33d8ffeabe690fd37e0e4ada695253287d8439c2a7124fb73109c191856df7a01603b7fb6b31c58b2ece9fd39e16fc98502a3bdc2699e8ec86bdd47ce4276f2cea41775c4cbc6a3a14823f57da339e46fe8c067e998e7e30eb95c308f4ae1c43ee45f7ec4970d1c8df8b028ca262f7baeb0272d590b3109641a398b1fd826ce66ad43cf961c7859e67c6f00f8f409304a544390ab91457f289aea167873d7d6ae8e7037ec0865816d447f139a2851e4089c76c6ac53de7902a44fd53a0308832ff678be4d279bc0bee34baaa16e8fc7039062b93bcd1fd515e959e8db8c958789f7aafaed790df3db2d8982ebebf79d029f2fe08fe0d2adea8c933aee24d2f564012d560e22fab7c15796ba41f46cdad1b854af44dfebb9c08d1c68f84b0e7cf926335e08d52ed542a224d13b0f717f6fd6e2a3dc1a6d220a03e7bf400485765fe5dcf9712c118edb6f8b98c84ed36187fe43d7dce8e5c898cc69a2c2f2891fa19dfa4dc849aabecc35c85ffb04f340bbf7d01a44ab50a93cdb8dadc06c6bfef243da7ef8f01073d3d7c068cd0db1f6ad24cd1b922f902b8809a5596cd484f1f6a18436e011a351595d5944005cbc10ab244980ede6f405a0fc5b151815024365a0a015371cc6858efd85271c6ce1e02bec7f05ba356f3d3c1ea51d357e96b1f6253af96767fa584f9562a92183fe41ccd0852162c245499c879852b7a32ec7f16c12c03864de9c894b4e28ebe8d3c855ac4fb88711a933e17b35865b48508f2ccb292fd01ab55ad81382459779b325803a067d620b9630e90a8fcfd50b936d528b40833500b20d9bd6daed361f81a575a346a86032b8c5385d8b012e5cda90b78c34082dd1e58c016b6035b2e80a68319ac2f1ec194215cf60a1a74b5f87a1d4ec2265597a68364a963e694908157bdb3de8213334dba597af90093beed7d1c68a70904e879ca9a9a5faf1baa0
1) Pack start code:包起始碼欄位,值為0x000001BA的位串,用來標誌一個包的開始。
2) System clock reference base,system clock reference extenstion:系統時鐘參考欄位。
3) Pack stuffing length :包填充長度欄位,3 位整數,規定該欄位後填充位元組的個數
80 60 53 1f 00 94 89 00 00 0000 00 00 00 01 ba €`S..??........?
7e ff 3e fb 44 01 00 5f 6b f8 00 00 01 e0 14 53 ~.>?D.._k?...?.S
80 80 05 2f bf cf bed1 1c 42 56 7b 13 58 0a 1e €€./????.BV{.X..
08 b1 4f 33 69 35 0453 6d 33 a8 04 15 58 d9 21 .?O3i5.Sm3?..X?!
9741 b9 f1 75 3d 94 2b 1f bc 0b b2 b4 97 bf 93 ?A??u=?+.?.?????
前12位是RTP Header,這裡不再贅述;
000001ba是包頭起始碼;
接下來的9位包括了SCR,SCRE,MUXRate,具體看圖7
最後一位是保留位(0xf8),定義了是否有擴充套件,二進位制如下
1111 1000
前5位跳過,後3位指示了擴充套件長度,這裡是0.
000001ba5cd2cf388401028f63fe ffff00575ece PS頭
000001bb00 12 //長度
8147b104e17fe0e080c0c008bde080bfe080 系統頭
000001bc 004e//長度
eeff 0024(stream info len)
400e484b01001195a89df27700ffffff4112484b000102030405060708090a0b0c0d0e0f
0020(stream map len) 1b(stream type) e0(stream id) // stream id & stream type can detemine the codec
0x1b && e0 ----> h264
0x24 && e0 ----> H265
001c420e030810ea07800438111f00001c202a0a7fff000007081ffef0874b920c23 節目對映頭
000001e0 002a//長度
8c800a 2734b3ce21(TS) fffffffffc //OPTIONAL PES header
00000001674d00299a6603c0113f2cd404040500000303e80000c35004 // PES 頭
000001e0 000e
8c0003 fffffc // PES OPTIONAL header
0000000168ee3c80 // PES 頭
000001e0 97de
8c0002 fff8
00000001(H264 startcode) 65(NALU type) 8880100015ff006f984997ff0c71232680b211d922115395b10fc3baf38574a402bcc7b5cd2649859b01c669d1800c44c081111e5ed57cac965c829f4ab52bd940b486c3f641c2697e20c6f2a31f520a80a83a99eeed8ff1525ec5e1d32876de5041c2976459022f0a4f31ffd12591a6c4925ecf5284d17466f153ce43fb903bc0e63eb71368b9e19abd34597a62e7d153eda72c46d0e3a8231bce0d2dd580ff4804822a39664039e845fe6bf24276b98a053e29d11afc12a293ddaba75c1e829b4c3f458ed0572aa0e6f830a418f2dbbc0c20d634d51ccc683d134a55f6a38ac5174b324b02eebc6bbfa7ba94bddf524a6c944337ac7cc702726b2bd1f42b6a39108225ce4fc02e161af36ff0468953583870e4205383d94f076a42457f4806894a5ab1f293534e4f853783d9dab0b2376140b93d94cc1b3e872856dfab0547a7c68701ef9a2376ca1af2af68bdbc60ce213f93afe6d1ce67b7e2ec002fc2c03a2507d43bee5c6b467ca47d5a8d32b3974db81d4d365b93a1bd297e97d829f4da1ac006cafb33c2c513b62a6197705e86c44ed9be062cdd85a97e4239a640e70396c50b7506c98ed674594c71ea9f8a3f5634234edacedca6000182f813aa8fe0dd89439fc36d38b6c67bc46e00776713341cc837d029b69c8886a03274ce2675bc8c04d4a682861f169d8caf3dd752bf9377787a662e7ddaf0f5a31bdb5ef74a8aa1a7afc8824cadc9b190250915c15fab8f4bd9f721b9907732b0fbf5cab92048a846b1025c1f543da9edb91c0d5db1e93690e2e9867430658f9a6becf759d52c99e8711ecc366adcd27fe61ac230c2240fa6e2e502ad1feb4f322ebe7ffbc7a0aff2396a6c778edb05f703f1f1e35e89ec652fcc85104990c95888d4745a56008f2d7f1505b707813efcd168a9f5097b256b74c5f6263e8ac8848f6e0accbe0c46f6bcd0258e8d37f3d0254c5f29600dc046eea5ce31c2046d0f34a792045660e432cbe37ab26cd44fae7f7bc1ad639ce489eb8f7403344e3c2263dac1e333f6d36d8b84a42ffb3d41f7b9aa1aba12fec98dafb8066621ea833c3178b2d85b7312e46f50a921f394850dc826a92ee1da3539fd944a6ec69ab2aad230464f7bf752b859b0134980e4d39c1dd7df3bbf5feb1c40d37c6fad02fe9ee97d013299236ae597d2479cc9487b36ef271b382afb66af217d0410596e3bfe48ca3c8633addc9c6414396fe62199536800215b633438e3bfc50761ba6081c8ee465d5bd482a93c036bdb55a17d765cc912e3c2381e63b6947a8fe7fa14aeca8bdb501942be2c6d28bebed06d120c6a1422fc29588633ee11b000531e84e4a0fcbe33ecabcfc4e1d2c68a01426021e3359d24032319d500f1899fe96e735c7bd15f7914c6f51acea443243fb5b517b713bacf572d6d45790168d39179510041f7dc4f6026ce9db7bcb6588b74e95c37f0389cf407d4dc914c6d3c66b60f84e5e1188226eceed6a4462acb102d62403db27662775030195a87c60837f4b6e9d62190a017bfe00510f5fc7ba7687aff4d8118aa2bfbf0d32d388844079a0835d038fdced9c022f266a866ad8ca9d86ce8418d3d5b9d7f4d01bd3397685e5334e30bff63ff7e8a4520b1c2a0e770b3603bd0520c656c02fb02277a8667381626d8e0954e44e9afe597
startcode followed with:
其中0x67的二進位制碼為:
0110 0111
4-8為00111,轉為十進位制7,參考第二幅圖:7對應序列引數集SPS
其中0x68的二進位制碼為:
0110 1000
4-8為01000,轉為十進位制8,參考第二幅圖:8對應影象引數集PPS
其中0x65的二進位制碼為:
0110 0101
4-8為00101,轉為十進位制5,參考第二幅圖:5對應IDR影象中的片(I幀)
其中0x41的二進位制碼為:
0100 0001
4-8為00001,轉為十進位制1,參考第二幅圖:根據上圖可知道這段碼流是【不分割槽、非IDR影象的片】,在baseline的檔次中就是P幀,因為baseline沒有B幀。
所以判斷是否為I幀的演算法為: (NALU型別 & 0001 1111) = 5 即 NALU型別 & 31 = 5
比如0x65 & 31 = 5
PTS DTS標誌欄位 PTS_DTS_flags
2位欄位。當值為'10'時,PTS欄位應出現在PES分組標題中;當值為'11'時,PTS欄位和DTS欄位都應出現在PES分組標題中;當值為'00'時,PTS欄位和DTS欄位都不出現在PES分組標題中。值'01'是不允許的。
中間的某一些幀
000001ba5cd2d4198401028f63fe ffff00575ed0 //PS header
000001e0 0aa2
//1374+
8c80082734b50661fffff800000001619a02026a58af9412669b9edea574537bd2c084d4dbf498cf1543dcd217c43dbcb56adaa220651871c3061a5dc7065f3975e450f4554b99f718990ef5dea8f7aa9a89ec6a58911a6a39bac2d96fd9123699810500c5048d6d26940abc460d5259aed000efcd18bc2161cc6c2ea860030629fce38031df16aa500d89586c59a87873f2ce87d2680cc00ad5b7adaeec9b909a1127f1a93cf13050c3117a2fa39cb66d7d3b6732b68f02bbc92051381a6f322c556bfac2e9ce4ecae153f80e238e773b12552d2ff901e621c9a70d6ea71fae9076e35a455a1a5104443a71e9d1c86efa7932f8f90244b0a1a9e91512092f296b93c2784ece479f247c1f3e66a06371286f3dac2d9e9d64e1b981ffc66be467e06a65d90bebc4c5a2adbf2b44a65cf35190d5d2b298201e9597163c0885c97b976121f24cf581188f84fd32bea9899c95d4e7eb0cebf873eac665bd29bf0812ed819f972170d251372b2e47caf9d4f7873615f23161a1b2d089dad6c8d8928fe47ef06b63d300f5378e1b2317b2243db1495eefd89f9557a9ae18c387d8aa1d78be8713ebfde000d9bf2e07c6f5c11905f3f5d076cf4eae91e3f6d48c06d95b3a1dddda268ed5c78d2d209ec01a188da650af8daadb50693f0bf978139a130669d3f8ab0f366a91c56da46f18adbca973a8aadd03aa99bc46c847b2ce3f5221610aeab7950b8ab775c569128b8bdd7877ad817d3481663e94d9b9174e41efa28589860692b15f213649ad0e7f2ec426b07b927628ef828bda53b7c2639f99896db4840b2f0272c936954376c330b7e43dca7ddc63ec09954e08fc5364e4856547e2afe12e27b66a3b77f29ad10394fd364245b148f00b6899998d14e66303d9ab4084f1285fbb4294cd11d3dd78fc0bbacf3d67ee063e2bb37430793cd29c403d67af9c654af0ffa4c3c1ee84278985a48ed3f93d5ad07c77fe7fe976c238bf5634610ba95015f159c2547d6ba1ded171f77c83dd0ecbe6f7b714326ca0fff0da004bc350deffc4e8b33113b67702939b22a322d28c3b2adfc7a04c7193b5d6941fd9e4456be1a9f09885db9e13cfb005216e245869c77563d65855a64b6c54b9e6f1bdf5af2bf19271784ef451efe0fdf71388229b2a068159fc20418a745b8a95434b4d5aacd9136f8b56090ac6a0b6ed1ec15e3c3072870b0fe9e83b98f90d18aee6aaed3c4e3226b89fb970b30833b558ff583651dd7c473e33e844ea01599abc32f98b0e30e2f6d8b8868261dd133c0bc394b262dd8791db83630e37b3b17087d3cb6058976a6db1116da7c8dc4bdde87ebc96724b2d6b2d4f6d17de9f79b3683412210236859f5b869db41fdc39581546f185980c42bb009040383d1be7b40bec64979998e4ddb1d922a59401a2458e58db3dffb965cac11b41475451b8a67d25d65a91f0e125594733986089f2f958339de1becee46d248064c77570fc63770ff8fbc497a8c2b59bca67fab43e7297229728a0a78492b7a113786829ac8950404fbe2d5553110ba0e13de87dfb59812cf503989fe7616282ac79b69a23712f47aee96814fcb2d02f4f1f6f4ad4e842d326fae632938396f85a6bb1238554e0253c0e167fafda9b51c3b6bba6e692e6b35afc99b497b7a1cc3645217032e9d9a356692907a0e0e92bd3a8653ebcb0c158c09ad426f029f134c064d3e6b75925bc2ef4b14258820a97a5cfa6b05dcd81eb2cdffd241b7d28637b747befb421ac6bb6190072ff1b6d17b6c498c362ece43e460d527f67dfa707b9a902d7c43887c45b151cc03ab6c49e1f55edc174d8b86ce5aadd8fd290c46b451dd2f89a48b96152abcc3aaa4473cc8e3caa40f8b490ff629708336804158acc2f2d3b439e4df1e08a65d25d29e4959b1abb935f262fe93a101a9efd5515419ccc
//1348 +1374 == aa2
ea9d609e63b9ce925297385989c2f1270e66d7d34d586ae73569f319953012d7d6c8a28aebc3a0206883034dc298f1931550593d35d0b665bce1c27c2d485193a3f5894a81182219f2921e9df95f7f8501ba5371cf1f259d9c0b6fc98e37ea01884af42f91025ff12a5404b81ad4661cf4e49eb2cebabfd574047c4ddef68c084f2c5ae31eddd5a599b1508f99c8b38cedc70339989ca457084023e591e68b1c534479efb42d2ffa609fd280a92638ab00b5740699cd05ac8fa6f12092d8f411d62d0b58e3b27683c8fa067739d1ccb120fae3d1730b8af09b45ccfa4ac3a31ba9c50f732ef3d0f711b137bfb859fd8e32cdad74e6016ec19debc9a25998077b2f0329bf3f2bde703b4694be2ebc5c297c9fdbd28b21da45e6f66a652ef94a850b5ed927f4cef2b26d3ff5459bffbdfcac841eed478364ed678586ccd0c1d6cfb9e58593371684fd27b757648c7220d586ec0222c1c8813921ecb3533dc264f63d34f5ee3f817eda0876228a7850e1bbef2dc223bfca02957566d4c749e95debcb0e5b33d9cb24f85bb82d80ae0d8b0a776e8a0c5b93a8fa450fbbe8475c1c0726119ad78b42e0ab9c13113e27a298dcbc4415c4f727141fd723634b212fc88efbcbc6d0fcfbc8b057a4d3cf0860fd0e1f422fa9cd6c2ee0ae68cf1262ca752b8da1a5fdb2cee9070e827e4d96923b69faaf9b2a2f9313053512498937ce0a3d4f91adee9f8ea4854013f916f187c5b3d64a7b29e312391dfe2b5c8ee97f2a68c7f0d6dcb3959c202dbfbc618c1515a0fe998ee20719ec966922f0332d89e2b646c7dec72605fe7e9660bd6a7f604c99ee25bfc72984f3f455795cea4d14c882a893f94aa20bad51fb6df8e23e0d66de3a34ce73a1454939b75f467d1615824f6451b82aa2297ecf2e7bf44a5d40408b8ddce75093a1c33d8ffeabe690fd37e0e4ada695253287d8439c2a7124fb73109c191856df7a01603b7fb6b31c58b2ece9fd39e16fc98502a3bdc2699e8ec86bdd47ce4276f2cea41775c4cbc6a3a14823f57da339e46fe8c067e998e7e30eb95c308f4ae1c43ee45f7ec4970d1c8df8b028ca262f7baeb0272d590b3109641a398b1fd826ce66ad43cf961c7859e67c6f00f8f409304a544390ab91457f289aea167873d7d6ae8e7037ec0865816d447f139a2851e4089c76c6ac53de7902a44fd53a0308832ff678be4d279bc0bee34baaa16e8fc7039062b93bcd1fd515e959e8db8c958789f7aafaed790df3db2d8982ebebf79d029f2fe08fe0d2adea8c933aee24d2f564012d560e22fab7c15796ba41f46cdad1b854af44dfebb9c08d1c68f84b0e7cf926335e08d52ed542a224d13b0f717f6fd6e2a3dc1a6d220a03e7bf400485765fe5dcf9712c118edb6f8b98c84ed36187fe43d7dce8e5c898cc69a2c2f2891fa19dfa4dc849aabecc35c85ffb04f340bbf7d01a44ab50a93cdb8dadc06c6bfef243da7ef8f01073d3d7c068cd0db1f6ad24cd1b922f902b8809a5596cd484f1f6a18436e011a351595d5944005cbc10ab244980ede6f405a0fc5b151815024365a0a015371cc6858efd85271c6ce1e02bec7f05ba356f3d3c1ea51d357e96b1f6253af96767fa584f9562a92183fe41ccd0852162c245499c879852b7a32ec7f16c12c03864de9c894b4e28ebe8d3c855ac4fb88711a933e17b35865b48508f2ccb292fd01ab55ad81382459779b325803a067d620b9630e90a8fcfd50b936d528b40833500b20d9bd6daed361f81a575a346a86032b8c5385d8b012e5cda90b78c34082dd1e58c016b6035b2e80a68319ac2f1ec194215cf60a1a74b5f87a1d4ec2265597a68364a963e694908157bdb3de8213334dba597af90093beed7d1c68a70904e879ca9a9a5faf1baa0