You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 line
4.8KB

  1. #include "mpeg-types.h"
  2. #include "mpeg-util.h"
  3. #include <assert.h>
  4. #include <string.h>
  5. #define H264_NAL_IDR 5
  6. #define H264_NAL_AUD 9
  7. /// e.g.
  8. /// 1. 0x00 00 00 00 00 01 09 EF => return 6(09), leading 4
  9. /// 2. 0x80 00 00 00 00 01 09 EF => return 6(09), leading 4
  10. ///
  11. /// Find h264 nalu start position
  12. /// @param[out] leading leading bytes before nalu position
  13. /// @return -1-not found, other nalu position(after 00 00 01)
  14. int mpeg_h264_find_nalu(const uint8_t* p, size_t bytes, size_t* leading)
  15. {
  16. size_t i, zeros;
  17. for (zeros = i = 0; i + 2 /*naltype + 1-data*/ < bytes; i++)
  18. {
  19. if (0x01 == p[i] && zeros >= 2)
  20. {
  21. assert(i >= zeros);
  22. if (leading)
  23. *leading = (zeros > 2 ? 3 : zeros) + 1; // zeros + 0x01
  24. return (int)(i + 1);
  25. }
  26. zeros = 0x00 != p[i] ? 0 : (zeros + 1);
  27. }
  28. return -1;
  29. }
  30. /// @param[out] leading optional leading zero bytes
  31. /// @return -1-not found, other-AUD position(include start code)
  32. static int mpeg_h264_find_access_unit_delimiter(const uint8_t* p, size_t bytes, size_t* leading)
  33. {
  34. int i;
  35. size_t off;
  36. for (off = 0; off < bytes; off += i + 1)
  37. {
  38. i = mpeg_h264_find_nalu(p + off, bytes - off, leading);
  39. if (-1 == i)
  40. return -1;
  41. if (H264_NAL_AUD == (p[i + off] & 0x1f))
  42. return (int)(i + off);
  43. }
  44. return -1;
  45. }
  46. int mpeg_h264_find_keyframe(const uint8_t* p, size_t bytes)
  47. {
  48. size_t i;
  49. uint8_t type;
  50. for (i = 2; i + 1 < bytes; i++)
  51. {
  52. if (0x01 == p[i] && 0x00 == p[i - 1] && 0x00 == p[i - 2])
  53. {
  54. type = p[i + 1] & 0x1f;
  55. if (H264_NAL_IDR >= type && 1 <= type)
  56. return H264_NAL_IDR == type ? 1 : 0;
  57. }
  58. }
  59. return 0;
  60. }
  61. /// h264_is_new_access_unit H.264 new access unit(frame)
  62. /// @return 1-new access, 0-not a new access
  63. static int mpeg_h264_is_new_access_unit(const uint8_t* nalu, size_t bytes)
  64. {
  65. enum { NAL_NIDR = 1, NAL_PARTITION_A = 2, NAL_IDR = 5, NAL_SEI = 6, NAL_SPS = 7, NAL_PPS = 8, NAL_AUD = 9, };
  66. uint8_t nal_type;
  67. if(bytes < 2)
  68. return 0;
  69. nal_type = nalu[0] & 0x1f;
  70. // 7.4.1.2.3 Order of NAL units and coded pictures and association to access units
  71. if(NAL_AUD == nal_type || NAL_SPS == nal_type || NAL_PPS == nal_type || NAL_SEI == nal_type || (14 <= nal_type && nal_type <= 18))
  72. return 1;
  73. // 7.4.1.2.4 Detection of the first VCL NAL unit of a primary coded picture
  74. if(NAL_NIDR == nal_type || NAL_PARTITION_A == nal_type || NAL_IDR == nal_type)
  75. {
  76. // Live555 H264or5VideoStreamParser::parse
  77. // The high-order bit of the byte after the "nal_unit_header" tells us whether it's
  78. // the start of a new 'access unit' (and thus the current NAL unit ends an 'access unit'):
  79. return (nalu[1] & 0x80) ? 1 : 0; // first_mb_in_slice
  80. }
  81. return 0;
  82. }
  83. int mpeg_h264_find_new_access_unit(const uint8_t* data, size_t bytes, int* vcl)
  84. {
  85. int n;
  86. size_t leading;
  87. uint8_t nal_type;
  88. const uint8_t* p, *end;
  89. end = data + bytes;
  90. for (p = data; p && p < end; p += n)
  91. {
  92. n = mpeg_h264_find_nalu(p, end - p, &leading);
  93. if (n < 0)
  94. return -1;
  95. nal_type = p[n] & 0x1f;
  96. if (*vcl > 0 && mpeg_h264_is_new_access_unit(p + n, end - p - n))
  97. {
  98. return (int)(p - data + n - leading);
  99. }
  100. else if (nal_type > 0 && nal_type < 6)
  101. {
  102. *vcl = H264_NAL_IDR == nal_type ? 1 : 2;
  103. }
  104. else
  105. {
  106. // nothing to do
  107. }
  108. }
  109. return -1;
  110. }
  111. /// @param[out] codec 1-h264, 2-h265
  112. /// @return 0-ok, other-error
  113. int mpeg_h26x_verify(const uint8_t* data, size_t bytes, int* codec)
  114. {
  115. uint32_t h264_flags = 0x01A0U; // sps/pps/idr
  116. uint64_t h265_flags = 0x700000000ULL; // vps/sps/pps
  117. int n, count;
  118. size_t leading;
  119. uint8_t h26x[4][10];
  120. const uint8_t* p, * end;
  121. count = 0;
  122. end = data + bytes;
  123. for (p = data; p && p < end && count < sizeof(h26x[0])/sizeof(h26x[0][0]); p += n)
  124. {
  125. n = mpeg_h264_find_nalu(p, end - p, &leading);
  126. if (n < 0 || p + n + 1 > end)
  127. break;
  128. h26x[0][count] = p[n] & 0x1f;
  129. h26x[1][count] = (p[n] >> 1) & 0x3f;
  130. h26x[2][count] = p[n]; // for mpeg4 vop_start_code
  131. h26x[3][count] = p[n+1]; // for mpeg4 vop_coding_type
  132. ++count;
  133. }
  134. for(n = 0; n < count; n++)
  135. {
  136. h264_flags &= ~(1U << h26x[0][n]);
  137. h265_flags &= ~(1ULL << h26x[1][n]);
  138. }
  139. if (0 == h264_flags && 0 != h265_flags)
  140. {
  141. // match sps/pps/idr
  142. *codec = 1;
  143. return 0;
  144. }
  145. else if (0 == h265_flags && 0 != h264_flags)
  146. {
  147. // match vps/sps/pps
  148. *codec = 2;
  149. return 0;
  150. }
  151. else if (0xB0 == h26x[2][0] && 0 == (0x30 & h26x[3][0]))
  152. {
  153. // match VOP start code
  154. *codec = 3;
  155. return 0;
  156. }
  157. return -1;
  158. }