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.

133 lines
3.0KB

  1. #include "mpeg4-hevc.h"
  2. #include "mpeg4-avc.h"
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <stdint.h>
  6. #include <stddef.h>
  7. #include <errno.h>
  8. #define H265_NAL_VPS 32
  9. #define H265_NAL_SPS 33
  10. #define H265_NAL_PPS 34
  11. #define H265_NAL_AUD 35 // Access unit delimiter
  12. struct h265_mp4toannexb_handle_t
  13. {
  14. const struct mpeg4_hevc_t* hevc;
  15. int vps_sps_pps_flag;
  16. int errcode;
  17. uint8_t* out;
  18. size_t bytes;
  19. size_t capacity;
  20. };
  21. static int h265_vps_sps_pps_size(const struct mpeg4_hevc_t* hevc)
  22. {
  23. int i, n = 0;
  24. for (i = 0; i < hevc->numOfArrays; i++)
  25. n += hevc->nalu[i].bytes + 4;
  26. return n;
  27. }
  28. static void h265_mp4toannexb_handler(void* param, const uint8_t* nalu, size_t bytes)
  29. {
  30. int n;
  31. uint8_t irap, nalu_type;
  32. const uint8_t h265_start_code[] = { 0x00, 0x00, 0x00, 0x01 };
  33. struct h265_mp4toannexb_handle_t* mp4;
  34. mp4 = (struct h265_mp4toannexb_handle_t*)param;
  35. if (bytes < 1)
  36. {
  37. assert(0);
  38. mp4->errcode = -EINVAL;
  39. return;
  40. }
  41. nalu_type = (nalu[0] >> 1) & 0x3F;
  42. #if defined(H2645_FILTER_AUD)
  43. if (H265_NAL_AUD == nalu_type)
  44. continue; // ignore AUD
  45. #endif
  46. if (H265_NAL_VPS == nalu_type || H265_NAL_SPS == nalu_type || H265_NAL_PPS == nalu_type)
  47. mp4->vps_sps_pps_flag = 1;
  48. irap = 16 <= nalu_type && nalu_type <= 23;
  49. if (irap && 0 == mp4->vps_sps_pps_flag)
  50. {
  51. // insert VPS/SPS/PPS before IDR frame
  52. if (mp4->bytes > 0)
  53. {
  54. // write sps/pps at first
  55. n = h265_vps_sps_pps_size(mp4->hevc);
  56. if (n + mp4->bytes > mp4->capacity)
  57. {
  58. mp4->errcode = -E2BIG;
  59. return;
  60. }
  61. memmove(mp4->out + n, mp4->out, mp4->bytes);
  62. }
  63. n = mpeg4_hevc_to_nalu(mp4->hevc, mp4->out, mp4->capacity);
  64. if (n <= 0)
  65. {
  66. mp4->errcode = 0 == n ? -EINVAL : n;
  67. return;
  68. }
  69. mp4->bytes += n;
  70. mp4->vps_sps_pps_flag = 1;
  71. }
  72. if (mp4->bytes + bytes + sizeof(h265_start_code) > mp4->capacity)
  73. {
  74. mp4->errcode = -E2BIG;
  75. return;
  76. }
  77. memcpy(mp4->out + mp4->bytes, h265_start_code, sizeof(h265_start_code));
  78. memcpy(mp4->out + mp4->bytes + sizeof(h265_start_code), nalu, bytes);
  79. mp4->bytes += sizeof(h265_start_code) + bytes;
  80. }
  81. int h265_mp4toannexb(const struct mpeg4_hevc_t* hevc, const void* data, size_t bytes, void* out, size_t size)
  82. {
  83. int i, n;
  84. const uint8_t* src, * end;
  85. struct h265_mp4toannexb_handle_t h;
  86. memset(&h, 0, sizeof(h));
  87. h.hevc = hevc;
  88. h.out = (uint8_t*)out;
  89. h.capacity = size;
  90. end = (uint8_t*)data + bytes;
  91. for(src = (uint8_t*)data; src + hevc->lengthSizeMinusOne + 1 < end; src += n)
  92. {
  93. for (n = i = 0; i < hevc->lengthSizeMinusOne + 1; i++)
  94. n = (n << 8) + ((uint8_t*)src)[i];
  95. // fix 0x00 00 00 01 => flv nalu size
  96. if (0 == hevc->lengthSizeMinusOne || (1 == n && (2 == hevc->lengthSizeMinusOne || 3 == hevc->lengthSizeMinusOne)))
  97. {
  98. //n = (int)(end - src) - avc->nalu;
  99. mpeg4_h264_annexb_nalu(src, end - src, h265_mp4toannexb_handler, &h);
  100. src = end;
  101. break;
  102. }
  103. src += hevc->lengthSizeMinusOne + 1;
  104. if (n < 1 || src + n > end)
  105. {
  106. assert(0);
  107. return -EINVAL;
  108. }
  109. h265_mp4toannexb_handler(&h, src, n);
  110. }
  111. assert(src == end);
  112. return 0 == h.errcode ? (int)h.bytes : 0;
  113. }