reader.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/time.h>
  6. static int g_video_size = 0;
  7. static int g_audio_size = 0;
  8. static uint8_t* g_video_buf = NULL;
  9. static uint8_t* g_audio_buf = NULL;
  10. static uint8_t* g_pps_buf = NULL;
  11. static uint8_t* g_sps_buf = NULL;
  12. static const uint32_t nalu_start_4bytecode = 0x01000000;
  13. static const uint32_t nalu_start_3bytecode = 0x010000;
  14. typedef enum H264_NALU_TYPE {
  15. NALU_TYPE_SPS = 7,
  16. NALU_TYPE_PPS = 8,
  17. NALU_TYPE_IDR = 5,
  18. NALU_TYPE_NON_IDR = 1,
  19. } H264_NALU_TYPE;
  20. // 添加循环控制变量
  21. static int g_loop_count = 0;
  22. static int g_max_loops = -1; // -1表示无限循环
  23. static int g_audio_pos = 0; // 音频位置
  24. // 添加读取状态结构
  25. typedef struct {
  26. uint8_t* video_start;
  27. uint8_t* video_current;
  28. uint8_t* video_end;
  29. int audio_pos;
  30. int loop_count;
  31. int sps_size;
  32. int pps_size;
  33. } ReaderState;
  34. static ReaderState g_reader_state = {0};
  35. // 添加函数设置循环次数
  36. void reader_set_loop_count(int max_loops) {
  37. g_max_loops = max_loops;
  38. }
  39. int reader_get_max_loops() {
  40. return g_max_loops;
  41. }
  42. int reader_init(char *video_url) {
  43. FILE* video_fp = NULL;
  44. FILE* audio_fp = NULL;
  45. char audiofile[] = "alaw08m.wav";
  46. printf("open file %s \n", video_url);
  47. video_fp = fopen(video_url, "rb");
  48. if (video_fp == NULL) {
  49. printf("open file %s failed\n", video_url);
  50. return -1;
  51. }
  52. fseek(video_fp, 0, SEEK_END);
  53. g_video_size = ftell(video_fp);
  54. fseek(video_fp, 0, SEEK_SET);
  55. g_video_buf = (uint8_t*)calloc(1, g_video_size);
  56. fread(g_video_buf, 1, g_video_size, video_fp);
  57. fclose(video_fp);
  58. audio_fp = fopen(audiofile, "rb");
  59. if (audio_fp == NULL) {
  60. printf("open file %s failed\n", audiofile);
  61. return -1;
  62. }
  63. fseek(audio_fp, 0, SEEK_END);
  64. g_audio_size = ftell(audio_fp);
  65. fseek(audio_fp, 0, SEEK_SET);
  66. g_audio_buf = (uint8_t*)calloc(1, g_audio_size);
  67. fread(g_audio_buf, 1, g_audio_size, audio_fp);
  68. fclose(audio_fp);
  69. // 初始化读取状态
  70. g_reader_state.video_start = g_video_buf;
  71. g_reader_state.video_current = g_video_buf;
  72. g_reader_state.video_end = g_video_buf + g_video_size;
  73. g_reader_state.audio_pos = 0;
  74. g_reader_state.loop_count = 0;
  75. g_reader_state.sps_size = 0;
  76. g_reader_state.pps_size = 0;
  77. // 重置全局循环计数
  78. g_loop_count = 0;
  79. g_audio_pos = 0;
  80. return 0;
  81. }
  82. uint8_t* reader_h264_find_nalu(uint8_t* buf_start, uint8_t* buf_end) {
  83. uint8_t* p = buf_start;
  84. while ((p + 3) < buf_end) {
  85. if (memcmp(p, &nalu_start_4bytecode, 4) == 0) {
  86. return p;
  87. } else if (memcmp(p, &nalu_start_3bytecode, 3) == 0) {
  88. return p;
  89. }
  90. p++;
  91. }
  92. return buf_end;
  93. }
  94. uint8_t* reader_get_video_frame(int* size) {
  95. uint8_t* buf = NULL;
  96. static int pps_size = 0;
  97. static int sps_size = 0;
  98. uint8_t* buf_end = g_video_buf + g_video_size;
  99. static uint8_t* pstart = NULL;
  100. static uint8_t* pend = NULL;
  101. size_t nalu_size;
  102. if (!pstart)
  103. pstart = g_video_buf;
  104. pend = reader_h264_find_nalu(pstart + 2, buf_end);
  105. if (pend == buf_end) {
  106. pstart = NULL;
  107. return NULL;
  108. }
  109. nalu_size = pend - pstart;
  110. int start_code_offset = memcmp(pstart, &nalu_start_3bytecode, 3) == 0 ? 3 : 4;
  111. H264_NALU_TYPE nalu_type = (H264_NALU_TYPE)(pstart[start_code_offset] & 0x1f);
  112. switch (nalu_type) {
  113. case NALU_TYPE_SPS:
  114. sps_size = nalu_size;
  115. if (g_sps_buf != NULL) {
  116. free(g_sps_buf);
  117. g_sps_buf = NULL;
  118. }
  119. g_sps_buf = (uint8_t*)calloc(1, sps_size);
  120. memcpy(g_sps_buf, pstart, sps_size);
  121. break;
  122. case NALU_TYPE_PPS:
  123. pps_size = nalu_size;
  124. if (g_pps_buf != NULL) {
  125. free(g_pps_buf);
  126. g_pps_buf = NULL;
  127. }
  128. g_pps_buf = (uint8_t*)calloc(1, pps_size);
  129. memcpy(g_pps_buf, pstart, pps_size);
  130. break;
  131. case NALU_TYPE_IDR:
  132. *size = sps_size + pps_size + nalu_size;
  133. buf = (uint8_t*)calloc(1, *size);
  134. memcpy(buf, g_sps_buf, sps_size);
  135. memcpy(buf + sps_size, g_pps_buf, pps_size);
  136. memcpy(buf + sps_size + pps_size, pstart, nalu_size);
  137. break;
  138. case NALU_TYPE_NON_IDR:
  139. default:
  140. *size = nalu_size;
  141. buf = (uint8_t*)calloc(1, *size);
  142. memcpy(buf, pstart, nalu_size);
  143. break;
  144. }
  145. pstart = pend;
  146. return buf;
  147. }
  148. uint8_t* reader_get_audio_frame(int* size) {
  149. // sample-rate=8000 channels=1 format=S16LE duration=20ms alaw-size=160
  150. uint8_t* buf = NULL;
  151. static int pos = 0;
  152. *size = 160;
  153. if ((pos + *size) > g_audio_size) {
  154. pos = 0;
  155. }
  156. buf = g_audio_buf + pos;
  157. pos += *size;
  158. return buf;
  159. }
  160. void reader_deinit() {
  161. if (g_sps_buf != NULL) {
  162. free(g_sps_buf);
  163. g_sps_buf = NULL;
  164. }
  165. if (g_pps_buf != NULL) {
  166. free(g_pps_buf);
  167. g_pps_buf = NULL;
  168. }
  169. if (g_video_buf != NULL) {
  170. free(g_video_buf);
  171. g_video_buf = NULL;
  172. }
  173. if (g_audio_buf != NULL) {
  174. free(g_audio_buf);
  175. g_audio_buf = NULL;
  176. }
  177. // 重置读取状态
  178. memset(&g_reader_state, 0, sizeof(g_reader_state));
  179. g_audio_pos = 0;
  180. g_loop_count = 0;
  181. }
  182. // 添加时间戳计算相关函数
  183. uint32_t reader_get_video_timestamp(int frame_rate) {
  184. static uint32_t base_timestamp = 0;
  185. static uint32_t frame_count = 0;
  186. // 90000 Hz clock rate for video
  187. uint32_t timestamp_increment = 90000 / frame_rate;
  188. uint32_t timestamp = base_timestamp + frame_count * timestamp_increment;
  189. frame_count++;
  190. return timestamp;
  191. }
  192. uint32_t reader_get_audio_timestamp() {
  193. static uint32_t base_timestamp = 0;
  194. static uint32_t sample_count = 0;
  195. // 8000 Hz sample rate for audio
  196. uint32_t timestamp_increment = 160; // 20ms packets at 8000 Hz = 160 samples
  197. uint32_t timestamp = base_timestamp + sample_count;
  198. sample_count += timestamp_increment;
  199. return timestamp;
  200. }