25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
4.3KB

  1. #include "hls-media.h"
  2. #include "hls-param.h"
  3. #include "mpeg-ts.h"
  4. #include "mpeg-ps.h"
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. #define N_TS_PACKET 188
  9. #define N_TS_FILESIZE (100 * 1024 * 1024) // 100M
  10. #define VMAX(a, b) ((a) > (b) ? (a) : (b))
  11. struct hls_media_t
  12. {
  13. void* ts;
  14. uint8_t* ptr;
  15. size_t bytes;
  16. size_t capacity;
  17. size_t maxsize; // max bytes per ts file
  18. int64_t duration; // user setting segment duration
  19. int64_t dts_last; // last packet dts
  20. int64_t dts; // segment first dts
  21. int64_t pts; // segment first pts
  22. int audio; // audio stream id
  23. int video; // video stream id
  24. int audio_only_flag;// don't have video stream in segment
  25. hls_media_handler handler;
  26. void* param;
  27. };
  28. static void* hls_ts_alloc(void* param, size_t bytes)
  29. {
  30. struct hls_media_t* hls;
  31. hls = (struct hls_media_t*)param;
  32. assert(188 == bytes);
  33. assert(hls->capacity >= hls->bytes);
  34. if (hls->capacity - hls->bytes < bytes)
  35. {
  36. void* p = realloc(hls->ptr, hls->capacity + bytes + N_TS_PACKET * 10 * 1024);
  37. if (NULL == p)
  38. return NULL;
  39. hls->ptr = p;
  40. hls->capacity += bytes + N_TS_PACKET * 10 * 1024;
  41. }
  42. return hls->ptr + hls->bytes;
  43. }
  44. static void hls_ts_free(void* param, void* packet)
  45. {
  46. struct hls_media_t* hls;
  47. hls = (struct hls_media_t*)param;
  48. assert(packet == hls->ptr + hls->bytes - 188);
  49. assert(hls->ptr <= (uint8_t*)packet && hls->ptr + hls->capacity > (uint8_t*)packet);
  50. }
  51. static int hls_ts_write(void* param, const void* packet, size_t bytes)
  52. {
  53. struct hls_media_t* hls;
  54. hls = (struct hls_media_t*)param;
  55. assert(188 == bytes);
  56. assert(hls->ptr <= (uint8_t*)packet && hls->ptr + hls->capacity > (uint8_t*)packet);
  57. hls->bytes += bytes; // update packet length
  58. return 0;
  59. }
  60. static void* hls_ts_create(struct hls_media_t* hls)
  61. {
  62. struct mpeg_ts_func_t handler;
  63. handler.alloc = hls_ts_alloc;
  64. handler.write = hls_ts_write;
  65. handler.free = hls_ts_free;
  66. return mpeg_ts_create(&handler, hls);
  67. }
  68. struct hls_media_t* hls_media_create(int64_t duration, hls_media_handler handler, void* param)
  69. {
  70. struct hls_media_t* hls;
  71. hls = (struct hls_media_t*)malloc(sizeof(*hls));
  72. if (NULL == hls)
  73. return NULL;
  74. memset(hls, 0, sizeof(struct hls_media_t));
  75. hls->ts = hls_ts_create(hls);
  76. if (NULL == hls->ts)
  77. {
  78. free(hls);
  79. return NULL;
  80. }
  81. hls->audio = mpeg_ts_add_stream(hls->ts, PSI_STREAM_AAC, NULL, 0);
  82. hls->video = mpeg_ts_add_stream(hls->ts, PSI_STREAM_H264, NULL, 0);
  83. hls->maxsize = N_TS_FILESIZE;
  84. hls->dts = hls->pts = PTS_NO_VALUE;
  85. hls->dts_last = PTS_NO_VALUE;
  86. hls->duration = duration;
  87. hls->handler = handler;
  88. hls->param = param;
  89. return hls;
  90. }
  91. void hls_media_destroy(struct hls_media_t* hls)
  92. {
  93. if (hls->ts)
  94. mpeg_ts_destroy(hls->ts);
  95. if (hls->ptr)
  96. {
  97. assert(hls->capacity > 0);
  98. free(hls->ptr);
  99. }
  100. free(hls);
  101. }
  102. int hls_media_input(struct hls_media_t* hls, int avtype, const void* data, size_t bytes, int64_t pts, int64_t dts, int flags)
  103. {
  104. int r;
  105. int segment;
  106. int force_new_segment;
  107. int64_t duration;
  108. assert(dts < hls->dts_last + hls->duration || PTS_NO_VALUE == hls->dts_last);
  109. // PTS/DTS rewind
  110. force_new_segment = 0;
  111. if (dts + hls->duration < hls->dts_last || NULL == data || 0 == bytes)
  112. force_new_segment = 1;
  113. // IDR frame
  114. // 1. check segment duration
  115. // 2. new segment per keyframe
  116. // 3. check segment file size
  117. if ((dts - hls->dts >= hls->duration || 0 == hls->duration)
  118. && (HLS_FLAGS_KEYFRAME & flags || hls->bytes >= hls->maxsize) )
  119. {
  120. segment = 1;
  121. }
  122. else if (hls->audio_only_flag && dts - hls->dts >= hls->duration)
  123. {
  124. // audio only file
  125. segment = 1;
  126. }
  127. else
  128. {
  129. segment = 0;
  130. }
  131. if (0 == hls->bytes || segment || force_new_segment)
  132. {
  133. if (hls->bytes > 0)
  134. {
  135. duration = ((force_new_segment || dts > hls->dts_last + 100) ? hls->dts_last : dts) - hls->dts;
  136. r = hls->handler(hls->param, hls->ptr, hls->bytes, hls->pts, hls->dts, duration);
  137. if (0 != r) return r;
  138. // reset mpeg ts generator
  139. mpeg_ts_reset(hls->ts);
  140. }
  141. // new segment
  142. hls->pts = pts;
  143. hls->dts = dts;
  144. hls->bytes = 0;
  145. hls->audio_only_flag = 1;
  146. }
  147. assert(PSI_STREAM_H264 == avtype || PSI_STREAM_AAC == avtype);
  148. if (hls->audio_only_flag && PSI_STREAM_H264 == avtype)
  149. hls->audio_only_flag = 0; // clear audio only flag
  150. hls->dts_last = dts;
  151. return mpeg_ts_write(hls->ts, PSI_STREAM_H264 == avtype ? hls->video : hls->audio, HLS_FLAGS_KEYFRAME & flags ? 1 : 0, pts * 90, dts * 90, data, bytes);
  152. }