Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

10 місяці тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "flv-writer.h"
  2. #include "flv-header.h"
  3. #include "flv-proto.h"
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. #include <stdio.h>
  8. #define FLV_HEADER_SIZE 9 // DataOffset included
  9. #define FLV_TAG_HEADER_SIZE 11 // StreamID included
  10. struct flv_writer_t
  11. {
  12. FILE* fp;
  13. flv_writer_onwrite write;
  14. void* param;
  15. };
  16. static int flv_write_header(int audio, int video, struct flv_writer_t* flv)
  17. {
  18. struct flv_vec_t vec[1];
  19. uint8_t header[FLV_HEADER_SIZE + 4];
  20. flv_header_write(audio, video, header, FLV_HEADER_SIZE);
  21. flv_tag_size_write(header + FLV_HEADER_SIZE, 4, 0); // PreviousTagSize0(Always 0)
  22. vec[0].ptr = header;
  23. vec[0].len = sizeof(header);
  24. return flv->write(flv->param, vec, 1);
  25. }
  26. static int flv_write_eos(struct flv_writer_t* flv)
  27. {
  28. int n;
  29. uint8_t header[16];
  30. struct flv_video_tag_header_t video;
  31. memset(&video, 0, sizeof(video));
  32. video.codecid = FLV_VIDEO_H264;
  33. video.keyframe = FLV_VIDEO_KEY_FRAME;
  34. video.avpacket = FLV_END_OF_SEQUENCE;
  35. video.cts = 0;
  36. n = flv_video_tag_header_write(&video, header, sizeof(header));
  37. return n > 0 ? flv_writer_input(flv, FLV_TYPE_VIDEO, header, n, 0) : -1;
  38. }
  39. static int file_write(void* param, const struct flv_vec_t* vec, int n)
  40. {
  41. int i;
  42. for(i = 0; i < n; i++)
  43. {
  44. if (vec[i].len != (int)fwrite(vec[i].ptr, 1, vec[i].len, (FILE*)param))
  45. return ferror((FILE*)param);
  46. }
  47. return 0;
  48. }
  49. void* flv_writer_create(const char* file)
  50. {
  51. FILE* fp;
  52. struct flv_writer_t* flv;
  53. fp = fopen(file, "wb");
  54. if (!fp)
  55. return NULL;
  56. flv = flv_writer_create2(1, 1, file_write, fp);
  57. if (!flv)
  58. {
  59. fclose(fp);
  60. return NULL;
  61. }
  62. flv->fp = fp;
  63. return flv;
  64. }
  65. void* flv_writer_create2(int audio, int video, flv_writer_onwrite write, void* param)
  66. {
  67. struct flv_writer_t* flv;
  68. flv = (struct flv_writer_t*)calloc(1, sizeof(*flv));
  69. if (!flv)
  70. return NULL;
  71. flv->write = write;
  72. flv->param = param;
  73. if (0 != flv_write_header(audio, video, flv))
  74. {
  75. flv_writer_destroy(flv);
  76. return NULL;
  77. }
  78. return flv;
  79. }
  80. void flv_writer_destroy(void* p)
  81. {
  82. struct flv_writer_t* flv;
  83. flv = (struct flv_writer_t*)p;
  84. if (NULL != flv)
  85. {
  86. flv_write_eos(flv);
  87. if (flv->fp)
  88. fclose(flv->fp);
  89. free(flv);
  90. }
  91. }
  92. int flv_writer_input(void* p, int type, const void* data, size_t bytes, uint32_t timestamp)
  93. {
  94. uint8_t buf[FLV_TAG_HEADER_SIZE + 4];
  95. struct flv_vec_t vec[3];
  96. struct flv_writer_t* flv;
  97. struct flv_tag_header_t tag;
  98. flv = (struct flv_writer_t*)p;
  99. memset(&tag, 0, sizeof(tag));
  100. tag.size = (int)bytes;
  101. tag.type = (uint8_t)type;
  102. tag.timestamp = timestamp;
  103. flv_tag_header_write(&tag, buf, FLV_TAG_HEADER_SIZE);
  104. flv_tag_size_write(buf + FLV_TAG_HEADER_SIZE, 4, (uint32_t)bytes + FLV_TAG_HEADER_SIZE);
  105. vec[0].ptr = buf; // FLV Tag Header
  106. vec[0].len = FLV_TAG_HEADER_SIZE;
  107. vec[1].ptr = (void*)data;
  108. vec[1].len = (int)bytes;
  109. vec[2].ptr = buf + FLV_TAG_HEADER_SIZE; // TAG size
  110. vec[2].len = 4;
  111. return flv->write(flv->param, vec, 3);
  112. }
  113. int flv_writer_input_v(void* p, int type, const struct flv_vec_t* v, int n, uint32_t timestamp)
  114. {
  115. int i;
  116. uint8_t buf[FLV_TAG_HEADER_SIZE + 4];
  117. struct flv_vec_t vec[8];
  118. struct flv_writer_t* flv;
  119. struct flv_tag_header_t tag;
  120. flv = (struct flv_writer_t*)p;
  121. memset(&tag, 0, sizeof(tag));
  122. tag.size = 0;
  123. tag.type = (uint8_t)type;
  124. tag.timestamp = timestamp;
  125. assert(n + 2 <= sizeof(vec) / sizeof(vec[0]));
  126. for (i = 0; i < n && i + 2 < sizeof(vec)/sizeof(vec[0]); i++)
  127. {
  128. tag.size += v[i].len;
  129. vec[i+1].ptr = v[i].ptr;
  130. vec[i+1].len = v[i].len;
  131. }
  132. vec[0].ptr = buf; // FLV Tag Header
  133. vec[0].len = FLV_TAG_HEADER_SIZE;
  134. vec[n + 1].ptr = buf + FLV_TAG_HEADER_SIZE; // TAG size
  135. vec[n + 1].len = 4;
  136. flv_tag_header_write(&tag, buf, FLV_TAG_HEADER_SIZE);
  137. flv_tag_size_write(buf + FLV_TAG_HEADER_SIZE, 4, (uint32_t)tag.size + FLV_TAG_HEADER_SIZE);
  138. return flv->write(flv->param, vec, n+2);
  139. }