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.

пре 10 месеци
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include "flv-demuxer.h"
  2. #include "flv-reader.h"
  3. #include "flv-proto.h"
  4. #include "mpeg-ps.h"
  5. #include "mpeg-ts.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <assert.h>
  9. #include <map>
  10. static void* ts_alloc(void* /*param*/, size_t bytes)
  11. {
  12. static char s_buffer[188];
  13. assert(bytes <= sizeof(s_buffer));
  14. return s_buffer;
  15. }
  16. static void ts_free(void* /*param*/, void* /*packet*/)
  17. {
  18. return;
  19. }
  20. static int ts_write(void* param, const void* packet, size_t bytes)
  21. {
  22. return 1 == fwrite(packet, bytes, 1, (FILE*)param) ? 0 : ferror((FILE*)param);
  23. }
  24. inline const char* ftimestamp(uint32_t t, char* buf)
  25. {
  26. sprintf(buf, "%u:%02u:%02u.%03u", t / 3600000, (t / 60000) % 60, (t / 1000) % 60, t % 1000);
  27. return buf;
  28. }
  29. static inline char flv_type(int type)
  30. {
  31. switch (type)
  32. {
  33. case FLV_AUDIO_ASC: return 'a';
  34. case FLV_AUDIO_AAC: return 'A';
  35. case FLV_AUDIO_MP3: return 'M';
  36. case FLV_AUDIO_OPUS: return 'O';
  37. case FLV_AUDIO_OPUS_HEAD: return 'o';
  38. case FLV_VIDEO_H264: return 'V';
  39. case FLV_VIDEO_AVCC: return 'v';
  40. case FLV_VIDEO_H265: return 'H';
  41. case FLV_VIDEO_HVCC: return 'h';
  42. default: return '*';
  43. }
  44. }
  45. static inline int flv2ts_codec_id(int type)
  46. {
  47. switch (type)
  48. {
  49. case FLV_AUDIO_ASC:
  50. case FLV_AUDIO_AAC: return PSI_STREAM_AAC;
  51. case FLV_AUDIO_MP3: return PSI_STREAM_MP3;
  52. case FLV_AUDIO_OPUS:
  53. case FLV_AUDIO_OPUS_HEAD: return PSI_STREAM_AUDIO_OPUS;
  54. case FLV_VIDEO_H264:
  55. case FLV_VIDEO_AVCC: return PSI_STREAM_H264;
  56. case FLV_VIDEO_H265:
  57. case FLV_VIDEO_HVCC: return PSI_STREAM_H264;
  58. default: return '*';
  59. }
  60. }
  61. static int ts_stream(void* ts, int codecid, const void* data, size_t bytes)
  62. {
  63. static std::map<int, int> streams;
  64. std::map<int, int>::const_iterator it = streams.find(codecid);
  65. if (streams.end() != it)
  66. return it->second;
  67. int i = mpeg_ts_add_stream(ts, flv2ts_codec_id(codecid), data, bytes);
  68. streams[codecid] = i;
  69. return i;
  70. }
  71. static int onFLV(void* ts, int codec, const void* data, size_t bytes, unsigned int pts, unsigned int dts, int flags)
  72. {
  73. static char s_pts[64], s_dts[64];
  74. static uint32_t v_pts = 0, v_dts = 0;
  75. static uint32_t a_pts = 0, a_dts = 0;
  76. printf("[%c] pts: %s, dts: %s, ", flv_type(codec), ftimestamp(pts, s_pts), ftimestamp(dts, s_dts));
  77. if (FLV_AUDIO_AAC == codec || FLV_AUDIO_MP3 == codec || FLV_AUDIO_OPUS == codec)
  78. {
  79. // assert(0 == a_dts || dts >= a_dts);
  80. pts = (a_pts && pts < a_pts) ? a_pts : pts;
  81. dts = (a_dts && dts < a_dts) ? a_dts : dts;
  82. mpeg_ts_write(ts, ts_stream(ts, codec, NULL, 0), 0, pts * 90, dts * 90, data, bytes);
  83. printf("diff: %03d/%03d", (int)(pts - a_pts), (int)(dts - a_dts));
  84. a_pts = pts;
  85. a_dts = dts;
  86. }
  87. else if (FLV_VIDEO_H264 == codec || FLV_VIDEO_H265 == codec)
  88. {
  89. assert(0 == v_dts || dts >= v_dts);
  90. dts = (a_dts && dts < v_dts) ? v_dts : dts;
  91. mpeg_ts_write(ts, ts_stream(ts, codec, NULL, 0), 0x01 & flags ? 1 : 0, pts * 90, dts * 90, data, bytes);
  92. printf("diff: %03d/%03d%s", (int)(pts - v_pts), (int)(dts - v_dts), flags ? " [I]" : "");
  93. v_pts = pts;
  94. v_dts = dts;
  95. }
  96. else if (FLV_AUDIO_OPUS_HEAD == codec)
  97. {
  98. ts_stream(ts, FLV_AUDIO_OPUS, data, bytes);
  99. }
  100. else
  101. {
  102. // nothing to do
  103. }
  104. printf("\n");
  105. return 0;
  106. }
  107. void flv2ts_test(const char* inputFLV, const char* outputTS)
  108. {
  109. struct mpeg_ts_func_t tshandler;
  110. tshandler.alloc = ts_alloc;
  111. tshandler.write = ts_write;
  112. tshandler.free = ts_free;
  113. FILE* fp = fopen(outputTS, "wb");
  114. void* ts = mpeg_ts_create(&tshandler, fp);
  115. void* reader = flv_reader_create(inputFLV);
  116. flv_demuxer_t* flv = flv_demuxer_create(onFLV, ts);
  117. int type, r;
  118. size_t taglen;
  119. uint32_t timestamp;
  120. static unsigned char s_packet[8 * 1024 * 1024];
  121. while (1 == flv_reader_read(reader, &type, &timestamp, &taglen, s_packet, sizeof(s_packet)))
  122. {
  123. r = flv_demuxer_input(flv, type, s_packet, taglen, timestamp);
  124. if (r < 0)
  125. {
  126. assert(0);
  127. }
  128. }
  129. flv_demuxer_destroy(flv);
  130. flv_reader_destroy(reader);
  131. mpeg_ts_destroy(ts);
  132. fclose(fp);
  133. }