mpeg3title.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "mpeg3private.h"
  2. #include "mpeg3protos.h"
  3. #include "mpeg3title.h"
  4. #include <stdlib.h>
  5. mpeg3_title_t* mpeg3_new_title(mpeg3_t *file, const char *path)
  6. {
  7. mpeg3_title_t *title = calloc(1, sizeof(mpeg3_title_t));
  8. title->fs = mpeg3_new_fs(path);
  9. title->file = file;
  10. return title;
  11. }
  12. int mpeg3_delete_title(mpeg3_title_t *title)
  13. {
  14. mpeg3_delete_fs(title->fs);
  15. if(title->timecode_table_size)
  16. {
  17. free(title->timecode_table);
  18. }
  19. free(title);
  20. return 0;
  21. }
  22. int mpeg3_copy_title(mpeg3_title_t *dst, mpeg3_title_t *src)
  23. {
  24. int i;
  25. mpeg3_copy_fs(dst->fs, src->fs);
  26. dst->total_bytes = src->total_bytes;
  27. if(src->timecode_table_size)
  28. {
  29. dst->timecode_table_allocation = src->timecode_table_allocation;
  30. dst->timecode_table_size = src->timecode_table_size;
  31. dst->timecode_table = calloc(1, sizeof(mpeg3demux_timecode_t) * dst->timecode_table_allocation);
  32. for(i = 0; i < dst->timecode_table_size; i++)
  33. {
  34. dst->timecode_table[i] = src->timecode_table[i];
  35. }
  36. }
  37. return 0;
  38. }
  39. int mpeg3_dump_title(mpeg3_title_t *title)
  40. {
  41. int i;
  42. printf("mpeg3_dump_title path %s timecode_table_size %dn", title->fs->path, title->timecode_table_size);
  43. for(i = 0; i < title->timecode_table_size; i++)
  44. {
  45. printf("%.02f: %x - %x %.02f %.02f %xn", 
  46. title->timecode_table[i].absolute_start_time, 
  47. title->timecode_table[i].start_byte, 
  48. title->timecode_table[i].end_byte, 
  49. title->timecode_table[i].start_time, 
  50. title->timecode_table[i].end_time, 
  51. title->timecode_table[i].program);
  52. }
  53. return 0;
  54. }
  55. // Realloc doesn't work for some reason.
  56. static void extend_timecode_table(mpeg3_title_t *title)
  57. {
  58. if(!title->timecode_table || 
  59. title->timecode_table_allocation <= title->timecode_table_size)
  60. {
  61. long new_allocation;
  62. mpeg3demux_timecode_t *new_table;
  63. int i;
  64. //printf("extend_timecode_table 1n");
  65. new_allocation = title->timecode_table_allocation ? 
  66. title->timecode_table_size * 2 : 
  67. 64;
  68. new_table = calloc(1, sizeof(mpeg3demux_timecode_t) * new_allocation);
  69. //printf("extend_timecode_table 1n");
  70. memcpy(new_table, 
  71. title->timecode_table, 
  72. sizeof(mpeg3demux_timecode_t) * title->timecode_table_allocation);
  73. //printf("extend_timecode_table 1 %p %d %dn", title->timecode_table, title->timecode_table_allocation,
  74. // (new_allocation - title->timecode_table_allocation));
  75. free(title->timecode_table);
  76. title->timecode_table = new_table;
  77. //printf("extend_timecode_table 2n");
  78. title->timecode_table_allocation = new_allocation;
  79. //printf("extend_timecode_table 2n");
  80. }
  81. }
  82. void mpeg3_new_timecode(mpeg3_title_t *title, 
  83. long start_byte, 
  84. double start_time,
  85. long end_byte,
  86. double end_time,
  87. int program)
  88. {
  89. mpeg3demux_timecode_t *new_timecode;
  90. extend_timecode_table(title);
  91. new_timecode = &title->timecode_table[title->timecode_table_size];
  92. new_timecode->start_byte = start_byte;
  93. new_timecode->start_time = start_time;
  94. new_timecode->end_byte = end_byte;
  95. new_timecode->end_time = end_time;
  96. new_timecode->absolute_start_time = 0;
  97. new_timecode->program = program;
  98. title->timecode_table_size++;
  99. }
  100. mpeg3demux_timecode_t* mpeg3_append_timecode(mpeg3_demuxer_t *demuxer, 
  101. mpeg3_title_t *title, 
  102. long prev_byte, 
  103. double prev_time, 
  104. long start_byte, 
  105. double start_time,
  106. int dont_store,
  107. int program)
  108. {
  109. mpeg3demux_timecode_t *new_timecode, *old_timecode;
  110. long i;
  111. extend_timecode_table(title);
  112. /*
  113.  * printf("mpeg3_append_timecode 1 %d %f %d %f %d %dn", prev_byte, 
  114.  *  prev_time, 
  115.  *  start_byte, 
  116.  *  start_time,
  117.  *  dont_store,
  118.  *  program);
  119.  */
  120. new_timecode = &title->timecode_table[title->timecode_table_size];
  121. if(!dont_store)
  122. {
  123. new_timecode->start_byte = start_byte;
  124. new_timecode->start_time = start_time;
  125. new_timecode->absolute_start_time = 0;
  126. if(title->timecode_table_size > 0)
  127. {
  128. old_timecode = &title->timecode_table[title->timecode_table_size - 1];
  129. old_timecode->end_byte = prev_byte;
  130. old_timecode->end_time = prev_time;
  131. new_timecode->absolute_start_time = 
  132. prev_time - 
  133. old_timecode->start_time + 
  134. old_timecode->absolute_start_time;
  135. new_timecode->absolute_end_time = start_time;
  136. }
  137. }
  138. title->timecode_table_size++;
  139. return new_timecode;
  140. }
  141. /* Create a title. */
  142. /* Build a table of timecodes contained in the program stream. */
  143. /* If toc is 0 just read the first and last timecode. */
  144. int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, 
  145. int timecode_search, 
  146. FILE *toc)
  147. {
  148. int result = 0, done = 0, counter_start, counter;
  149. mpeg3_t *file = demuxer->file;
  150. long next_byte, prev_byte;
  151. double next_time, prev_time, absolute_time;
  152. long i;
  153. mpeg3_title_t *title;
  154. u_int32_t test_header = 0;
  155. mpeg3demux_timecode_t *timecode = 0;
  156. demuxer->error_flag = 0;
  157. demuxer->read_all = 1;
  158. /* Create a single title */
  159. if(!demuxer->total_titles)
  160. {
  161. demuxer->titles[0] = mpeg3_new_title(file, file->fs->path);
  162. demuxer->total_titles = 1;
  163. mpeg3demux_open_title(demuxer, 0);
  164. }
  165. title = demuxer->titles[0];
  166. title->total_bytes = mpeg3io_total_bytes(title->fs);
  167. /* Get timecodes for the title */
  168. if(file->is_transport_stream || file->is_program_stream)
  169. {
  170. mpeg3io_seek(title->fs, 0);
  171. //fprintf(stderr, "mpeg3demux_create_title: 0 %f %d %dn", demuxer->time, result, mpeg3io_eof(title->fs));
  172. while(!done && !result && !mpeg3io_eof(title->fs))
  173. {
  174. next_byte = mpeg3io_tell(title->fs);
  175. result = mpeg3_read_next_packet(demuxer);
  176. //printf("mpeg3demux_create_title: 1 %f %dn", demuxer->time, result);
  177. if(!result)
  178. {
  179. next_time = demuxer->time;
  180. //printf("timecode: %f %f %fn", (double)next_time, (double)prev_time, (double)demuxer->time);
  181. if(next_time < prev_time || 
  182. next_time - prev_time > MPEG3_CONTIGUOUS_THRESHOLD ||
  183. !title->timecode_table_size)
  184. {
  185. /* Discontinuous */
  186. timecode = mpeg3_append_timecode(demuxer, 
  187. title, 
  188. prev_byte, 
  189. prev_time, 
  190. next_byte, 
  191. next_time,
  192. 0,
  193. 0);
  194. /*
  195.  * printf("timecode: %ld %ld %f %fn",
  196.  *  timecode->start_byte,
  197.  *  timecode->end_byte,
  198.  *  timecode->start_time,
  199.  *  timecode->end_time);
  200.  */
  201. counter_start = next_time;
  202. }
  203. // Breaks transport stream decoding
  204. // Kai Strieder
  205. // if (prev_time == next_time)
  206. // {
  207. // done = 1;
  208. // }
  209. prev_time = next_time;
  210. prev_byte = next_byte;
  211. counter = next_time;
  212. }
  213. /* Just get the first bytes if not building a toc to get the stream ID's. */
  214. if(next_byte > 0x100000 && 
  215. (!timecode_search || !toc)) done = 1;
  216. //printf("mpeg3demux_create_title 2 next_byte=%d next_time=%f done=%d result=%d %dn", 
  217. // next_byte, next_time, done, result, mpeg3io_eof(title->fs));
  218. }
  219. /* Get the last timecode */
  220. if(!toc || !timecode_search)
  221. {
  222. demuxer->read_all = 0;
  223. result = mpeg3io_seek(title->fs, title->total_bytes);
  224. // result = mpeg3io_seek(title->fs, title->total_bytes - 
  225. // (title->total_bytes % demuxer->packet_size));
  226. //printf("mpeg3demux_create_title 3 %dn", result);
  227. if(!result) result = mpeg3_read_prev_packet(demuxer);
  228. }
  229. //fprintf(stderr, "mpeg3demux_create_title 4 %d %fn", result, demuxer->time);
  230. if(title->timecode_table && timecode)
  231. {
  232. timecode->end_byte = title->total_bytes;
  233. // timecode->end_byte = mpeg3io_tell(title->fs)/*  + demuxer->packet_size */;
  234. timecode->end_time = demuxer->time;
  235. timecode->absolute_end_time = timecode->end_time - timecode->start_time;
  236. }
  237. }
  238. //fprintf(stderr, "mpeg3demux_create_title 5 %dn", result);
  239. mpeg3io_seek(title->fs, 0);
  240. demuxer->read_all = 0;
  241. return 0;
  242. }
  243. int mpeg3demux_print_timecodes(mpeg3_title_t *title, FILE *output)
  244. {
  245. mpeg3demux_timecode_t *timecode;
  246. mpeg3_t *file = title->file;
  247. int i;
  248. if(title->timecode_table)
  249. {
  250. for(i = 0; i < title->timecode_table_size; i++)
  251. {
  252. timecode = &title->timecode_table[i];
  253. fprintf(output, "REGION: %ld %ld %f %f %dn",
  254. timecode->start_byte,
  255. timecode->end_byte,
  256. timecode->start_time,
  257. timecode->end_time,
  258. timecode->program);
  259. }
  260. }
  261. return 0;
  262. }
  263. int mpeg3demux_print_streams(mpeg3_demuxer_t *demuxer, FILE *toc)
  264. {
  265. int i;
  266. /* Print the stream information */
  267. for(i = 0; i < MPEG3_MAX_STREAMS; i++)
  268. {
  269. if(demuxer->astream_table[i])
  270. fprintf(toc, "ASTREAM: %d %dn", i, demuxer->astream_table[i]);
  271. if(demuxer->vstream_table[i])
  272. fprintf(toc, "VSTREAM: %d %dn", i, demuxer->vstream_table[i]);
  273. }
  274. return 0;
  275. }