您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

313 行
11 KiB

  1. using System;
  2. using System.Buffers.Binary;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. namespace JT1078.Flv.MessagePack
  6. {
  7. /// <summary>
  8. /// Exp-Golomb指数哥伦布编码
  9. /// </summary>
  10. public ref struct ExpGolombReader
  11. {
  12. public ReadOnlySpan<byte> SrcBuffer { get; }
  13. public int BytesAvailable { get; private set; }
  14. public int Word { get; private set; }
  15. public int BitsAvailable { get; private set; }
  16. public ExpGolombReader(ReadOnlySpan<byte> srcBuffer)
  17. {
  18. SrcBuffer = srcBuffer;
  19. BytesAvailable = srcBuffer.Length;
  20. Word = 0;
  21. BitsAvailable = 0;
  22. }
  23. public (byte profileIdc,byte levelIdc,uint profileCompat,int width, int height) ReadSPS()
  24. {
  25. int sarScale = 1;
  26. uint frameCropLeftOffset=0;
  27. uint frameCropRightOffset = 0;
  28. uint frameCropTopOffset = 0;
  29. uint frameCropBottomOffset = 0;
  30. ReadByte();
  31. //profile_idc
  32. byte profileIdc = ReadByte();
  33. //constraint_set[0-4]_flag, u(5)
  34. uint profileCompat = ReadBits(5);
  35. //reserved_zero_3bits
  36. SkipBits(3);
  37. //level_idc u(8)
  38. byte levelIdc = ReadByte();
  39. //seq_parameter_set_id
  40. SkipUEG();
  41. if (profileIdc == 100 ||
  42. profileIdc == 110 ||
  43. profileIdc == 122 ||
  44. profileIdc == 244 ||
  45. profileIdc == 44 ||
  46. profileIdc == 83 ||
  47. profileIdc == 86 ||
  48. profileIdc == 118 ||
  49. profileIdc == 128)
  50. {
  51. uint chromaFormatIdc = ReadUEG();
  52. if (chromaFormatIdc == 3)
  53. {
  54. SkipBits(1); // separate_colour_plane_flag
  55. }
  56. SkipUEG(); // bit_depth_luma_minus8
  57. SkipUEG(); // bit_depth_chroma_minus8
  58. SkipBits(1); // qpprime_y_zero_transform_bypass_flag
  59. if (ReadBoolean())
  60. { // seq_scaling_matrix_present_flag
  61. int scalingListCount = (chromaFormatIdc != 3) ? 8 : 12;
  62. for (int i = 0; i < scalingListCount; i++)
  63. {
  64. if (ReadBoolean())
  65. { // seq_scaling_list_present_flag[ i ]
  66. if (i < 6)
  67. {
  68. SkipScalingList(16);
  69. }
  70. else
  71. {
  72. SkipScalingList(64);
  73. }
  74. }
  75. }
  76. }
  77. }
  78. // log2_max_frame_num_minus4
  79. SkipUEG();
  80. var picOrderCntType = ReadUEG();
  81. if (picOrderCntType == 0)
  82. {
  83. ReadUEG(); //log2_max_pic_order_cnt_lsb_minus4
  84. }
  85. else if (picOrderCntType == 1)
  86. {
  87. SkipBits(1); // delta_pic_order_always_zero_flag
  88. SkipEG(); // offset_for_non_ref_pic
  89. SkipEG(); // offset_for_top_to_bottom_field
  90. uint numRefFramesInPicOrderCntCycle = ReadUEG();
  91. for (int i = 0; i < numRefFramesInPicOrderCntCycle; i++)
  92. {
  93. SkipEG(); // offset_for_ref_frame[ i ]
  94. }
  95. }
  96. SkipUEG(); // max_num_ref_frames
  97. SkipBits(1); // gaps_in_frame_num_value_allowed_flag
  98. uint picWidthInMbsMinus1 = ReadUEG();
  99. uint picHeightInMapUnitsMinus1 = ReadUEG();
  100. uint frameMbsOnlyFlag = ReadBits(1);
  101. if (frameMbsOnlyFlag == 0)
  102. {
  103. SkipBits(1); // mb_adaptive_frame_field_flag
  104. }
  105. this.SkipBits(1); // direct_8x8_inference_flag
  106. if (ReadBoolean())
  107. {
  108. // frame_cropping_flag
  109. frameCropLeftOffset = ReadUEG();
  110. frameCropRightOffset = ReadUEG();
  111. frameCropTopOffset = ReadUEG();
  112. frameCropBottomOffset = ReadUEG();
  113. }
  114. if (ReadBoolean())
  115. {
  116. // vui_parameters_present_flag
  117. if (ReadBoolean())
  118. {
  119. // aspect_ratio_info_present_flag
  120. byte[] sarRatio=null;
  121. byte aspectRatioIdc = ReadByte();
  122. switch (aspectRatioIdc)
  123. {
  124. case 1: sarRatio =new byte[2] { 1, 1 }; break;
  125. case 2: sarRatio =new byte[2] { 12, 11}; break;
  126. case 3: sarRatio =new byte[2] { 10, 11}; break;
  127. case 4: sarRatio =new byte[2] { 16, 11}; break;
  128. case 5: sarRatio =new byte[2] { 40, 33}; break;
  129. case 6: sarRatio =new byte[2] { 24, 11}; break;
  130. case 7: sarRatio =new byte[2] { 20, 11}; break;
  131. case 8: sarRatio =new byte[2] { 32, 11 }; break;
  132. case 9: sarRatio = new byte[2] {80, 33 }; break;
  133. case 10: sarRatio = new byte[2]{18, 11 }; break;
  134. case 11: sarRatio = new byte[2]{15, 11 }; break;
  135. case 12: sarRatio = new byte[2]{64, 33 }; break;
  136. case 13: sarRatio = new byte[2]{160, 99 }; break;
  137. case 14: sarRatio = new byte[2]{4, 3 }; break;
  138. case 15: sarRatio = new byte[2]{3, 2 }; break;
  139. case 16: sarRatio = new byte[2]{ 2, 1 }; break;
  140. case 255:
  141. {
  142. sarRatio = new byte[2] { (byte)(ReadByte() << 8 | ReadByte()), (byte)(ReadByte() << 8 | ReadByte()) };
  143. break;
  144. }
  145. }
  146. if (sarRatio != null)
  147. {
  148. sarScale = sarRatio[0] / sarRatio[1];
  149. }
  150. }
  151. }
  152. int width= (int)((((picWidthInMbsMinus1 + 1) * 16) - frameCropLeftOffset * 2 - frameCropRightOffset * 2) * sarScale);
  153. int height = (int)(((2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16) - ((frameMbsOnlyFlag == 1U ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset)));
  154. return (profileIdc, levelIdc, profileCompat,width, height);
  155. }
  156. public void LoadWord()
  157. {
  158. var position = SrcBuffer.Length - BytesAvailable;
  159. int tmpAvailableBytes = BytesAvailable - 4;
  160. int availableBytes = Math.Min(4, BytesAvailable);
  161. //if (availableBytes == 0)
  162. //{
  163. // throw new OverflowException("no bytes available");
  164. //}
  165. ReadOnlySpan<byte> workingBytes=ReadOnlySpan<byte>.Empty;
  166. if (tmpAvailableBytes < 0)
  167. {
  168. var buffer = new byte[4];
  169. Array.Copy(SrcBuffer.Slice(position, BytesAvailable).ToArray(), buffer, BytesAvailable);
  170. workingBytes = buffer;
  171. }
  172. else
  173. {
  174. workingBytes = SrcBuffer.Slice(position, 4);
  175. }
  176. Word = BinaryPrimitives.ReadInt32BigEndian(workingBytes);
  177. // track the amount of this.data that has been processed
  178. BitsAvailable = availableBytes * 8;
  179. BytesAvailable -= availableBytes;
  180. }
  181. public void SkipBits(int count)
  182. {
  183. if (BitsAvailable > count)
  184. {
  185. Word <<= count;
  186. BitsAvailable -= count;
  187. }
  188. else
  189. {
  190. count -= BitsAvailable;
  191. int skipBytes = count >> 3;
  192. count -= (skipBytes >> 3);
  193. LoadWord();
  194. Word <<= count;
  195. BitsAvailable -= count;
  196. }
  197. }
  198. public uint ReadBits(int size)
  199. {
  200. var bits = Math.Min(BitsAvailable, size); // :uint
  201. var valu = (uint)Word >> (32 - bits); // :uint
  202. if (size > 32)
  203. {
  204. throw new OverflowException("Cannot read more than 32 bits at a time");
  205. }
  206. BitsAvailable -= bits;
  207. if (BitsAvailable > 0)
  208. {
  209. Word <<= bits;
  210. }
  211. else if (BytesAvailable > 0)
  212. {
  213. LoadWord();
  214. }
  215. bits = size - bits;
  216. if (bits > 0)
  217. {
  218. return ((valu << bits) | ReadBits(bits));
  219. }
  220. else
  221. {
  222. return valu;
  223. }
  224. }
  225. public int SkipLZ()
  226. {
  227. int leadingZeroCount; // :uint
  228. for (leadingZeroCount = 0; leadingZeroCount < this.BitsAvailable; ++leadingZeroCount)
  229. {
  230. if (0 != (Word & (0x80000000 >> leadingZeroCount)))
  231. {
  232. // the first bit of working word is 1
  233. Word <<= leadingZeroCount;
  234. BitsAvailable -= leadingZeroCount;
  235. return leadingZeroCount;
  236. }
  237. }
  238. // we exhausted word and still have not found a 1
  239. LoadWord();
  240. return (leadingZeroCount + SkipLZ());
  241. }
  242. public void SkipUEG()
  243. {
  244. SkipBits(1 + SkipLZ());
  245. }
  246. public void SkipEG()
  247. {
  248. SkipBits(1 + SkipLZ());
  249. }
  250. public uint ReadUEG()
  251. {
  252. var clz =SkipLZ();
  253. return ReadBits(clz + 1) - 1;
  254. }
  255. public int ReadEG()
  256. {
  257. var valu = (int)ReadUEG(); // :int
  258. if ((0x01 & valu)==1)
  259. {
  260. // the number is odd if the low order bit is set
  261. return (1 + valu) >> 1; // add 1 to make it even, and divide by 2
  262. }
  263. else
  264. {
  265. return -1 * (valu >> 1); // divide by two then make it negative
  266. }
  267. }
  268. public bool ReadBoolean()
  269. {
  270. return 1 == ReadBits(1);
  271. }
  272. public byte ReadByte()
  273. {
  274. return (byte)ReadBits(8);
  275. }
  276. public ushort ReadUShort()
  277. {
  278. return (ushort)ReadBits(16);
  279. }
  280. public uint ReadUInt()
  281. {
  282. return ReadBits(32);
  283. }
  284. /// <summary>
  285. ///Advance the ExpGolomb decoder past a scaling list.The scaling
  286. ///list is optionally transmitted as part of a sequence parameter
  287. ///set and is not relevant to transmuxing.
  288. ///@param count { number}
  289. ///the number of entries in this scaling list
  290. ///@see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
  291. /// </summary>
  292. /// <param name="count"></param>
  293. public void SkipScalingList(int count)
  294. {
  295. int lastScale = 8,
  296. nextScale = 8,
  297. j,
  298. deltaScale;
  299. for (j = 0; j < count; j++)
  300. {
  301. if (nextScale != 0)
  302. {
  303. deltaScale = ReadEG();
  304. nextScale = (lastScale + deltaScale + 256) % 256;
  305. }
  306. lastScale = (nextScale == 0) ? lastScale : nextScale;
  307. }
  308. }
  309. }
  310. }