Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

229 rindas
5.4KB

  1. #include "mpeg4-aac.h"
  2. #include "mpeg4-avc.h"
  3. #include "mpeg4-hevc.h"
  4. #include "flv-muxer.h"
  5. #include "flv-writer.h"
  6. #include "http-server.h"
  7. #include "aio-worker.h"
  8. #include "uri-parse.h"
  9. #include "urlcodec.h"
  10. #include "sys/thread.h"
  11. #include "sys/system.h"
  12. #include "sys/path.h"
  13. #include "cstringext.h"
  14. #include <stdio.h>
  15. #include "utf8codec.h"
  16. #include "../deprecated/StdCFile.h"
  17. #include "cpm/shared_ptr.h"
  18. #include <vector>
  19. #define CWD "."
  20. struct http_flv_live_t
  21. {
  22. char path[PATH_MAX];
  23. std::shared_ptr<uint8_t> buf;
  24. size_t cap;
  25. size_t len;
  26. http_session_t* http;
  27. std::shared_ptr<void> writer;
  28. std::shared_ptr<flv_muxer_t> muxer;
  29. uint32_t pts, dts;
  30. std::shared_ptr<void> content;
  31. std::vector<std::pair<const uint8_t*, int> > frames; // h264 frames
  32. std::vector<std::pair<const uint8_t*, int> >::const_iterator it;
  33. const uint8_t* ptr;
  34. int vcl;
  35. };
  36. static int http_flv_live_read(http_flv_live_t* live);
  37. static int http_flv_live_send(http_flv_live_t* live);
  38. static int http_flv_live_destroy(http_flv_live_t* live)
  39. {
  40. // TODO: close http sessoin
  41. delete live;
  42. return 0;
  43. }
  44. static int http_flv_live_onsend(void* param, int code, size_t bytes)
  45. {
  46. http_flv_live_t* live = (http_flv_live_t*)param;
  47. if (0 != code)
  48. {
  49. printf("===============send error: %d===============\r\n", code);
  50. http_flv_live_destroy(live);
  51. return 0;
  52. }
  53. assert(live->len = bytes);
  54. live->len = 0; // clear
  55. system_sleep(40); // next frame
  56. return http_flv_live_send(live);
  57. }
  58. static int http_flv_live_send(http_flv_live_t* live)
  59. {
  60. if (live->it == live->frames.end())
  61. {
  62. printf("===============done===============\r\n");
  63. http_flv_live_destroy(live);
  64. return 0; /*end*/
  65. }
  66. int r = flv_muxer_avc(live->muxer.get(), live->it->first, live->it->second, live->pts, live->dts);
  67. live->pts += 40;
  68. live->dts += 40;
  69. live->it++;
  70. if (0 != r)
  71. {
  72. printf("===============send error===============\r\n");
  73. http_flv_live_destroy(live);
  74. return r;
  75. }
  76. r = http_server_send(live->http, live->buf.get(), live->len, http_flv_live_onsend, live);
  77. return 0 == r ? 1 /*more data*/ : r;
  78. }
  79. static int http_flv_write(void* param, const struct flv_vec_t* v, int n)
  80. {
  81. http_flv_live_t* live = (http_flv_live_t*)param;
  82. assert(n <= 3);
  83. for (int i = 0; i < n; i++)
  84. {
  85. if (live->len + v[i].len > live->cap)
  86. {
  87. // TODO: realloc
  88. assert(0);
  89. return -1;
  90. }
  91. // TODO: avoid memory copy
  92. memcpy(live->buf.get() + live->len, v[i].ptr, v[i].len);
  93. live->len += v[i].len;
  94. }
  95. return 0;
  96. }
  97. static int http_flv_muxer_handler(void* param, int type, const void* data, size_t bytes, uint32_t timestamp)
  98. {
  99. http_flv_live_t* live = (http_flv_live_t*)param;
  100. return flv_writer_input(live->writer.get(), type, data, bytes, timestamp);
  101. }
  102. static int http_flv_live(void* http, http_session_t* session, const char* method, const char* path)
  103. {
  104. char buffer[1024];//[PATH_MAX];
  105. http_flv_live_t* live = new http_flv_live_t();
  106. struct uri_t* uri = uri_parse(path, (int)strlen(path));
  107. url_decode(uri->path, -1, live->path, sizeof(live->path));
  108. uri_free(uri);
  109. int n = 0;
  110. while (live->path[n] == '/') n++; // filter /
  111. UTF8Decode utf8(live->path+n);
  112. path_resolve(buffer, sizeof(buffer), utf8, CWD, strlen(CWD));
  113. // TODO: path resolve to fix /rootpath/../pathtosystem -> /pathtosystem
  114. path_realpath(buffer, live->path);
  115. // read frames
  116. int r = http_flv_live_read(live);
  117. if (0 != r)
  118. {
  119. delete live;
  120. http_server_set_status_code(session, r, NULL);
  121. return http_server_send(session, "", 0, NULL, NULL);
  122. }
  123. live->http = session;
  124. http_server_set_header(session, "Connection", "close"); // server close connection on finish
  125. http_server_set_content_length(session, -1); // don't need content-length
  126. live->pts = 0;
  127. live->dts = 0;
  128. live->it = live->frames.begin();
  129. live->muxer.reset(flv_muxer_create(http_flv_muxer_handler, live), flv_muxer_destroy);
  130. // write flv file header
  131. live->writer.reset(flv_writer_create2(0, 1, http_flv_write, live), flv_writer_destroy);
  132. return http_flv_live_send(live);
  133. }
  134. void http_flv_live_test(const char* ip, int port)
  135. {
  136. aio_worker_init(4);
  137. http_server_t* http = http_server_create(ip, port);
  138. http_server_set_handler(http, http_flv_live, http);
  139. // http process
  140. while ('q' != getchar())
  141. {
  142. }
  143. http_server_destroy(http);
  144. aio_worker_clean(4);
  145. }
  146. static void h264_handler(void* param, const uint8_t* nalu, size_t bytes)
  147. {
  148. http_flv_live_t* ctx = (http_flv_live_t*)param;
  149. assert(ctx->ptr < nalu);
  150. const uint8_t* ptr = nalu - 3;
  151. //const uint8_t* end = (const uint8_t*)nalu + bytes;
  152. uint8_t nalutype = nalu[0] & 0x1f;
  153. if (ctx->vcl > 0 && h264_is_new_access_unit(nalu, bytes))
  154. {
  155. ctx->cap = ptr - ctx->ptr > ctx->cap ? ptr - ctx->ptr : ctx->cap; // max
  156. ctx->frames.push_back(std::make_pair(ctx->ptr, ptr - ctx->ptr));
  157. ctx->ptr = ptr;
  158. ctx->vcl = 0;
  159. }
  160. if (1 <= nalutype && nalutype <= 5)
  161. ++ctx->vcl;
  162. }
  163. static int http_flv_live_read(http_flv_live_t* live)
  164. {
  165. StdCFile fp(live->path, "rb");
  166. if (!fp.IsOpened())
  167. return 404;
  168. long n = fp.GetFileSize();
  169. if (n >= 32 * 1024 * 1024)
  170. return 401;
  171. live->content.reset(fp.Read(), free);
  172. if (!live->content.get())
  173. return 500;
  174. live->vcl = 0;
  175. live->ptr = (const uint8_t*)live->content.get();
  176. live->cap = 0;
  177. live->len = 0;
  178. if (strendswith(live->path, ".h264") || strendswith(live->path, ".264"))
  179. {
  180. mpeg4_h264_annexb_nalu(live->content.get(), n, h264_handler, live);
  181. live->cap += 4 * 1024; // flv avc/aac sequence header
  182. live->buf.reset((uint8_t*)malloc(live->cap), free);
  183. }
  184. else
  185. {
  186. return 500;
  187. }
  188. return 0;
  189. }