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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "libmpeg3.h"
  2. #include "mpeg3protos.h"
  3. #include <fcntl.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #ifndef MAX
  7. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  8. #endif
  9. mpeg3_t* mpeg3_new(const char *path)
  10. {
  11. int i;
  12. mpeg3_t *file = calloc(1, sizeof(mpeg3_t));
  13. file->cpus = 1;
  14. file->fs = mpeg3_new_fs(path);
  15. file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
  16. file->seekable = 1;
  17. return file;
  18. }
  19. int mpeg3_delete(mpeg3_t *file)
  20. {
  21. int i;
  22. for(i = 0; i < file->total_vstreams; i++)
  23. mpeg3_delete_vtrack(file, file->vtrack[i]);
  24. for(i = 0; i < file->total_astreams; i++)
  25. mpeg3_delete_atrack(file, file->atrack[i]);
  26. mpeg3_delete_fs(file->fs);
  27. mpeg3_delete_demuxer(file->demuxer);
  28. if(file->frame_offsets)
  29. {
  30. for(i = 0; i < file->total_vstreams; i++)
  31. {
  32. free(file->frame_offsets[i]);
  33. free(file->keyframe_numbers[i]);
  34. }
  35. free(file->frame_offsets);
  36. free(file->keyframe_numbers);
  37. free(file->total_frame_offsets);
  38. free(file->total_keyframe_numbers);
  39. }
  40. if(file->sample_offsets)
  41. {
  42. for(i = 0; i < file->total_astreams; i++)
  43. free(file->sample_offsets[i]);
  44. free(file->sample_offsets);
  45. free(file->total_sample_offsets);
  46. }
  47. free(file);
  48. return 0;
  49. }
  50. int mpeg3_check_sig(const char *path)
  51. {
  52. mpeg3_fs_t *fs;
  53. u_int32_t bits;
  54. char *ext;
  55. int result = 0;
  56. fs = mpeg3_new_fs(path);
  57. if(mpeg3io_open_file(fs))
  58. {
  59. /* File not found */
  60. return 0;
  61. }
  62. bits = mpeg3io_read_int32(fs);
  63. /* Test header */
  64. if(bits == MPEG3_TOC_PREFIX)
  65. {
  66. result = 1;
  67. }
  68. else
  69. if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) ||
  70. (bits == MPEG3_PACK_START_CODE) ||
  71. ((bits & 0xfff00000) == 0xfff00000) ||
  72. ((bits & 0xffff0000) == 0xffe30000) ||
  73. (bits == MPEG3_SEQUENCE_START_CODE) ||
  74. (bits == MPEG3_PICTURE_START_CODE) ||
  75. (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) ||
  76. ((bits >> 8) == MPEG3_ID3_PREFIX) ||
  77. (bits == MPEG3_RIFF_CODE) ||
  78.         (bits == MPEG3_IFO_PREFIX))
  79. {
  80. result = 1;
  81. ext = strrchr(path, '.');
  82. if(ext)
  83. {
  84. /* Test file extension. */
  85. if(strncasecmp(ext, ".ifo", 4) && 
  86.              strncasecmp(ext, ".mp2", 4) && 
  87. strncasecmp(ext, ".mp3", 4) &&
  88. strncasecmp(ext, ".m1v", 4) &&
  89. strncasecmp(ext, ".m2v", 4) &&
  90. strncasecmp(ext, ".m2s", 4) &&
  91. strncasecmp(ext, ".mpg", 4) &&
  92. strncasecmp(ext, ".vob", 4) &&
  93. strncasecmp(ext, ".mpeg", 4) &&
  94. strncasecmp(ext, ".ac3", 4))
  95. result = 0;
  96. }
  97. }
  98. mpeg3io_close_file(fs);
  99. mpeg3_delete_fs(fs);
  100. return result;
  101. }
  102. static uint32_t read_int32(unsigned char *buffer, int *position)
  103. {
  104. uint32_t temp;
  105. if(MPEG3_LITTLE_ENDIAN)
  106. {
  107. ((unsigned char*)&temp)[3] = buffer[(*position)++];
  108. ((unsigned char*)&temp)[2] = buffer[(*position)++];
  109. ((unsigned char*)&temp)[1] = buffer[(*position)++];
  110. ((unsigned char*)&temp)[0] = buffer[(*position)++];
  111. }
  112. else
  113. {
  114. ((unsigned char*)&temp)[0] = buffer[(*position)++];
  115. ((unsigned char*)&temp)[1] = buffer[(*position)++];
  116. ((unsigned char*)&temp)[2] = buffer[(*position)++];
  117. ((unsigned char*)&temp)[3] = buffer[(*position)++];
  118. }
  119. return temp;
  120. }
  121. static uint64_t read_int64(unsigned char *buffer, int *position)
  122. {
  123. uint64_t temp;
  124. if(MPEG3_LITTLE_ENDIAN)
  125. {
  126. ((unsigned char*)&temp)[7] = buffer[(*position)++];
  127. ((unsigned char*)&temp)[6] = buffer[(*position)++];
  128. ((unsigned char*)&temp)[5] = buffer[(*position)++];
  129. ((unsigned char*)&temp)[4] = buffer[(*position)++];
  130. ((unsigned char*)&temp)[3] = buffer[(*position)++];
  131. ((unsigned char*)&temp)[2] = buffer[(*position)++];
  132. ((unsigned char*)&temp)[1] = buffer[(*position)++];
  133. ((unsigned char*)&temp)[0] = buffer[(*position)++];
  134. }
  135. else
  136. {
  137. ((unsigned char*)&temp)[0] = buffer[(*position)++];
  138. ((unsigned char*)&temp)[1] = buffer[(*position)++];
  139. ((unsigned char*)&temp)[2] = buffer[(*position)++];
  140. ((unsigned char*)&temp)[3] = buffer[(*position)++];
  141. ((unsigned char*)&temp)[4] = buffer[(*position)++];
  142. ((unsigned char*)&temp)[5] = buffer[(*position)++];
  143. ((unsigned char*)&temp)[6] = buffer[(*position)++];
  144. ((unsigned char*)&temp)[7] = buffer[(*position)++];
  145. }
  146. return temp;
  147. }
  148. static int read_toc(mpeg3_t *file)
  149. {
  150. unsigned char *buffer;
  151. int file_type;
  152. int position = 4;
  153. int stream_type;
  154. int atracks;
  155. int vtracks;
  156. int i, j;
  157. buffer = malloc(mpeg3io_total_bytes(file->fs));
  158. mpeg3io_seek(file->fs, 0);
  159. mpeg3io_read_data(buffer, mpeg3io_total_bytes(file->fs), file->fs);
  160. //printf("read_toc %lldn", mpeg3io_total_bytes(file->fs));
  161. // File type
  162. file_type = buffer[position++];
  163. switch(file_type)
  164. {
  165. case FILE_TYPE_PROGRAM:
  166. file->is_program_stream = 1;
  167. break;
  168. case FILE_TYPE_TRANSPORT:
  169. file->is_transport_stream = 1;
  170. break;
  171. case FILE_TYPE_AUDIO:
  172. file->is_audio_stream = 1;
  173. break;
  174. case FILE_TYPE_VIDEO:
  175. file->is_video_stream = 1;
  176. break;
  177. }
  178. // Stream ID's
  179. while((stream_type = buffer[position]) != TITLE_PATH)
  180. {
  181. int offset;
  182. int stream_id;
  183. //printf("read_toc %d %xn", position, buffer[position]);
  184. position++;
  185. offset = read_int32(buffer, &position);
  186. stream_id = read_int32(buffer, &position);
  187. if(stream_type == STREAM_AUDIO)
  188. {
  189. file->demuxer->astream_table[offset] = stream_id;
  190. }
  191. if(stream_type == STREAM_VIDEO)
  192. {
  193. file->demuxer->vstream_table[offset] = stream_id;
  194. }
  195. }
  196. // Titles
  197. while(buffer[position] == TITLE_PATH)
  198. {
  199. char string[MPEG3_STRLEN];
  200. int string_len = 0;
  201. mpeg3_title_t *title;
  202. position++;
  203. while(buffer[position] != 0) string[string_len++] = buffer[position++];
  204. string[string_len++] = 0;
  205. position++;
  206. title = 
  207. file->demuxer->titles[file->demuxer->total_titles++] = 
  208. mpeg3_new_title(file, string);
  209. title->total_bytes = read_int64(buffer, &position);
  210. // Cells
  211. title->timecode_table_size = 
  212. title->timecode_table_allocation = 
  213. read_int32(buffer, &position);
  214. title->timecode_table = calloc(title->timecode_table_size, sizeof(mpeg3demux_timecode_t));
  215. for(i = 0; i < title->timecode_table_size; i++)
  216. {
  217. title->timecode_table[i].start_byte = read_int64(buffer, &position);
  218. title->timecode_table[i].end_byte = read_int64(buffer, &position);
  219. title->timecode_table[i].program = read_int32(buffer, &position);
  220. }
  221. }
  222. // Audio streams
  223. // Skip ATRACK_COUNT
  224. position++;
  225. atracks = read_int32(buffer, &position);
  226. // Skip VTRACK_COUNT
  227. position++;
  228. vtracks = read_int32(buffer, &position);
  229. if(atracks)
  230. {
  231. file->sample_offsets = malloc(sizeof(int64_t*) * atracks);
  232. file->total_sample_offsets = malloc(sizeof(int*) * atracks);
  233. for(i = 0; i < atracks; i++)
  234. {
  235. file->total_sample_offsets[i] = read_int32(buffer, &position);
  236. file->sample_offsets[i] = malloc(file->total_sample_offsets[i] * sizeof(int64_t));
  237. for(j = 0; j < file->total_sample_offsets[i]; j++)
  238. {
  239. file->sample_offsets[i][j] = read_int64(buffer, &position);
  240. //printf("samples %llxn", file->sample_offsets[i][j]);
  241. }
  242. }
  243. }
  244. if(vtracks)
  245. {
  246. file->frame_offsets = malloc(sizeof(int64_t*) * vtracks);
  247. file->total_frame_offsets = malloc(sizeof(int*) * vtracks);
  248. file->keyframe_numbers = malloc(sizeof(int64_t*) * vtracks);
  249. file->total_keyframe_numbers = malloc(sizeof(int*) * vtracks);
  250. for(i = 0; i < vtracks; i++)
  251. {
  252. file->total_frame_offsets[i] = read_int32(buffer, &position);
  253. file->frame_offsets[i] = malloc(file->total_frame_offsets[i] * sizeof(int64_t));
  254. for(j = 0; j < file->total_frame_offsets[i]; j++)
  255. {
  256. file->frame_offsets[i][j] = read_int64(buffer, &position);
  257. //printf("frame %llxn", file->frame_offsets[i][j]);
  258. }
  259. file->total_keyframe_numbers[i] = read_int32(buffer, &position);
  260. file->keyframe_numbers[i] = malloc(file->total_keyframe_numbers[i] * sizeof(int64_t));
  261. for(j = 0; j < file->total_keyframe_numbers[i]; j++)
  262. {
  263. file->keyframe_numbers[i][j] = read_int64(buffer, &position);
  264. }
  265. }
  266. }
  267. free(buffer);
  268. //printf("read_toc 1n");
  269. mpeg3demux_open_title(file->demuxer, 0);
  270. //printf("read_toc 2 %llxn", mpeg3demux_tell(file->demuxer));
  271. return 0;
  272. }
  273. mpeg3_t* mpeg3_open_copy(const char *path, mpeg3_t *old_file)
  274. {
  275. mpeg3_t *file = 0;
  276. unsigned int bits;
  277. int i, done;
  278. /* Initialize the file structure */
  279. file = mpeg3_new(path);
  280. //printf("mpeg3_open_copy %sn", path);
  281. /* Need to perform authentication before reading a single byte. */
  282. if(mpeg3io_open_file(file->fs))
  283. {
  284. mpeg3_delete(file);
  285. return 0;
  286. }
  287. /* =============================== Create the title objects ========================= */
  288. bits = mpeg3io_read_int32(file->fs);
  289. //printf("mpeg3_open 1 %p %d %d %d %dn", old_file, file->is_transport_stream, file->is_program_stream, file->is_video_stream, file->is_audio_stream);
  290. if(bits == MPEG3_TOC_PREFIX)   /* TOC  */
  291. {
  292. /* Table of contents for another title set */
  293. if(!old_file)
  294. {
  295. //printf("libmpeg3 1n");
  296. if(read_toc(file))
  297. {
  298. //printf("libmpeg3 1n");
  299. mpeg3io_close_file(file->fs);
  300. mpeg3_delete(file);
  301. return 0;
  302. }
  303. //printf("libmpeg3 1n");
  304. }
  305. mpeg3io_close_file(file->fs);
  306. }
  307. else
  308. // IFO file
  309. #ifndef _WIN32
  310.     if(bits == MPEG3_IFO_PREFIX)
  311.     {
  312. //printf("libmpeg3 1n");
  313.      if(!old_file)
  314. {
  315. //printf("libmpeg3 2n");
  316. if(mpeg3_read_ifo(file, 0))
  317.          {
  318. mpeg3_delete(file);
  319. mpeg3io_close_file(file->fs);
  320. return 0;
  321.          }
  322. //printf("libmpeg3 3n");
  323. }
  324. file->is_ifo_file = 1;
  325. mpeg3io_close_file(file->fs);
  326.     }
  327.     else
  328. #endif
  329. if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE)
  330. {
  331. /* Transport stream */
  332. //printf("libmpeg3 2n");
  333. file->is_transport_stream = 1;
  334. }
  335. else
  336. if(bits == MPEG3_PACK_START_CODE)
  337. {
  338. /* Program stream */
  339. /* Determine packet size empirically */
  340. //printf("libmpeg3 3n");
  341. file->is_program_stream = 1;
  342. }
  343. else
  344. if((bits & 0xfff00000) == 0xfff00000 ||
  345. (bits & 0xffff0000) == 0xffe30000 ||
  346. ((bits >> 8) == MPEG3_ID3_PREFIX) ||
  347. (bits == MPEG3_RIFF_CODE))
  348. {
  349. /* MPEG Audio only */
  350. //printf("libmpeg3 4n");
  351. file->is_audio_stream = 1;
  352. }
  353. else
  354. if(bits == MPEG3_SEQUENCE_START_CODE ||
  355. bits == MPEG3_PICTURE_START_CODE)
  356. {
  357. /* Video only */
  358. //printf("libmpeg3 5n");
  359. file->is_video_stream = 1;
  360. }
  361. else
  362. if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
  363. {
  364. /* AC3 Audio only */
  365. //printf("libmpeg3 6n");
  366. file->is_audio_stream = 1;
  367. }
  368. else
  369. {
  370. //printf("libmpeg3 7n");
  371. mpeg3_delete(file);
  372. fprintf(stderr, "mpeg3_open: not an MPEG 2 streamn");
  373. return 0;
  374. }
  375. //printf("mpeg3_open 2 %p %d %d %d %dn", 
  376. // old_file, file->is_transport_stream, file->is_program_stream, file->is_video_stream, file->is_audio_stream);
  377. // Configure packet size
  378. if(file->is_transport_stream)
  379. file->packet_size = MPEG3_TS_PACKET_SIZE;
  380. else
  381. if(file->is_program_stream)
  382. file->packet_size = 0;
  383. else
  384. if(file->is_audio_stream)
  385. file->packet_size = MPEG3_DVD_PACKET_SIZE;
  386. else
  387. if(file->is_video_stream)
  388. file->packet_size = MPEG3_DVD_PACKET_SIZE;
  389. //printf("mpeg3_open 1n");
  390. /* Create titles */
  391. /* Copy timecodes from an old demuxer */
  392. if(old_file && mpeg3_get_demuxer(old_file))
  393. {
  394. mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file));
  395. file->is_transport_stream = old_file->is_transport_stream;
  396. file->is_program_stream = old_file->is_program_stream;
  397. }
  398. else
  399. /* Start from scratch */
  400. if(!file->demuxer->total_titles)
  401. {
  402. mpeg3demux_create_title(file->demuxer, 0, 0);
  403. }
  404. //printf("mpeg3_open 2n");
  405. /* Generate tracks */
  406. if(file->is_transport_stream || file->is_program_stream)
  407. {
  408. /* Create video tracks */
  409. /* Video must be created before audio because audio uses the video timecode */
  410. /* to get its length. */
  411. for(i = 0; i < MPEG3_MAX_STREAMS; i++)
  412. {
  413. if(file->demuxer->vstream_table[i])
  414. {
  415. file->vtrack[file->total_vstreams] = 
  416. mpeg3_new_vtrack(file, 
  417. i, 
  418. file->demuxer, 
  419. file->total_vstreams);
  420. if(file->vtrack[file->total_vstreams]) 
  421. file->total_vstreams++;
  422. //printf("libmpeg3 %d %d %p %dn", i, file->demuxer->vstream_table[i], file->vtrack[file->total_vstreams], file->total_vstreams);
  423. }
  424. }
  425. /* Create audio tracks */
  426. for(i = 0; i < MPEG3_MAX_STREAMS; i++)
  427. {
  428. if(file->demuxer->astream_table[i])
  429. {
  430. file->atrack[file->total_astreams] = mpeg3_new_atrack(file, 
  431. i, 
  432. file->demuxer->astream_table[i], 
  433. file->demuxer,
  434. file->total_astreams);
  435. if(file->atrack[file->total_astreams]) file->total_astreams++;
  436. }
  437. }
  438. }
  439. else
  440. if(file->is_video_stream)
  441. {
  442. /* Create video tracks */
  443. //printf("mpeg3_open 3n");
  444. file->vtrack[0] = mpeg3_new_vtrack(file, 
  445. -1, 
  446. file->demuxer, 
  447. 0);
  448. //printf("mpeg3_open 4n");
  449. if(file->vtrack[0]) file->total_vstreams++;
  450. }
  451. else
  452. if(file->is_audio_stream)
  453. {
  454. /* Create audio tracks */
  455. //printf("mpeg3_open 3n");
  456. file->atrack[0] = mpeg3_new_atrack(file, 
  457. -1, 
  458. AUDIO_UNKNOWN, 
  459. file->demuxer,
  460. 0);
  461. //printf("mpeg3_open 3n");
  462. if(file->atrack[0]) file->total_astreams++;
  463. }
  464. //printf("mpeg3_open 5n");
  465. mpeg3io_close_file(file->fs);
  466. return file;
  467. }
  468. mpeg3_t* mpeg3_open(const char *path)
  469. {
  470. return mpeg3_open_copy(path, 0);
  471. }
  472. int mpeg3_close(mpeg3_t *file)
  473. {
  474. /* File is closed in the same procedure it is opened in. */
  475. mpeg3_delete(file);
  476. return 0;
  477. }
  478. int mpeg3_has_audio(mpeg3_t *file)
  479. {
  480. return file->total_astreams > 0;
  481. }
  482. int mpeg3_total_astreams(mpeg3_t *file)
  483. {
  484. return file->total_astreams;
  485. }
  486. int mpeg3_audio_channels(mpeg3_t *file,
  487. int stream)
  488. {
  489. if(file->total_astreams)
  490. return file->atrack[stream]->channels;
  491. return -1;
  492. }
  493. int mpeg3_sample_rate(mpeg3_t *file,
  494. int stream)
  495. {
  496. if(file->total_astreams)
  497. return file->atrack[stream]->sample_rate;
  498. return -1;
  499. }
  500. int mpeg3_audio_samples_per_frame(mpeg3_t *file,
  501. int stream)
  502. {
  503. if(file->total_astreams)
  504. return file->atrack[stream]->samples_per_frame;
  505. return -1;
  506. }
  507. uint32_t mpeg3_audio_get_number_of_frames (mpeg3_t *file, 
  508.    int stream)
  509. {
  510.   if (file->total_astreams) 
  511.     return file->atrack[stream]->total_frames;
  512.   return -1;
  513. }
  514. char* mpeg3_audio_format(mpeg3_t *file, int stream)
  515. {
  516. if(stream < file->total_astreams)
  517. {
  518. switch(file->atrack[stream]->format)
  519. {
  520. case AUDIO_UNKNOWN: return "Unknown"; break;
  521. case AUDIO_MPEG:    return "MPEG"; break;
  522. case AUDIO_AC3:     return "AC3"; break;
  523. case AUDIO_PCM:     return "PCM"; break;
  524. case AUDIO_AAC:     return "AAC"; break;
  525. case AUDIO_JESUS:   return "Vorbis"; break;
  526. }
  527. }
  528. return "";
  529. }
  530. int mpeg3_has_video(mpeg3_t *file)
  531. {
  532. return file->total_vstreams > 0;
  533. }
  534. int mpeg3_total_vstreams(mpeg3_t *file)
  535. {
  536. return file->total_vstreams;
  537. }
  538. int mpeg3_video_width(mpeg3_t *file,
  539. int stream)
  540. {
  541. if(file->total_vstreams)
  542. return file->vtrack[stream]->width;
  543. return -1;
  544. }
  545. int mpeg3_video_height(mpeg3_t *file,
  546. int stream)
  547. {
  548. if(file->total_vstreams)
  549. return file->vtrack[stream]->height;
  550. return -1;
  551. }
  552. float mpeg3_aspect_ratio(mpeg3_t *file, int stream)
  553. {
  554. if(file->total_vstreams)
  555. return file->vtrack[stream]->aspect_ratio;
  556. return 0;
  557. }
  558. float mpeg3_frame_rate(mpeg3_t *file,
  559. int stream)
  560. {
  561. if(file->total_vstreams)
  562. return file->vtrack[stream]->frame_rate;
  563. return -1;
  564. }
  565. long mpeg3_video_frames(mpeg3_t *file,
  566. int stream)
  567. {
  568. if(file->total_vstreams)
  569. return file->vtrack[stream]->total_frames;
  570. return -1;
  571. }
  572. long mpeg3_get_frame(mpeg3_t *file,
  573. int stream)
  574. {
  575. if(file->total_vstreams)
  576. return file->vtrack[stream]->current_position;
  577. return -1;
  578. }
  579. int mpeg3_set_frame(mpeg3_t *file, 
  580. long frame,
  581. int stream)
  582. {
  583. if(file->total_vstreams)
  584. {
  585.   file->vtrack[stream]->current_position = frame;
  586. mpeg3vtrack_seek_frame(file->vtrack[stream], frame);
  587. return 0;
  588. }
  589. return -1;
  590. }
  591. int mpeg3_seek_percentage(mpeg3_t *file, double percentage)
  592. {
  593. int i;
  594. for(i = 0; i < file->total_vstreams; i++)
  595. {
  596. mpeg3vtrack_seek_percentage(file->vtrack[i], percentage);
  597. }
  598. for(i = 0; i < file->total_astreams; i++)
  599. {
  600.   mpeg3atrack_seek_percentage(file->atrack[i], percentage);
  601. }
  602. return 0;
  603. }
  604. int mpeg3_seek_audio_percentage(mpeg3_t *file, int stream, double percentage)
  605. {
  606.   mpeg3atrack_seek_percentage(file->atrack[stream], percentage);
  607.   return 0;
  608. }
  609. int mpeg3_seek_video_percentage(mpeg3_t *file, int stream, double percentage)
  610. {
  611.   mpeg3vtrack_seek_percentage(file->vtrack[stream], percentage);
  612.   return 0;
  613. }
  614. #if 0
  615. int mpeg3_previous_frame(mpeg3_t *file, int stream)
  616. {
  617. file->last_type_read = 2;
  618. file->last_stream_read = stream;
  619. if(file->total_vstreams)
  620. return mpeg3video_previous_frame(file->vtrack[stream]->video);
  621. return 0;
  622. }
  623. #endif
  624. double mpeg3_tell_percentage(mpeg3_t *file)
  625. {
  626. double percent = 0;
  627. if(file->last_type_read == 1)
  628. {
  629. percent = mpeg3demux_tell_percentage(file->atrack[file->last_stream_read]->demuxer);
  630. }
  631. if(file->last_type_read == 2)
  632. {
  633. percent = mpeg3demux_tell_percentage(file->vtrack[file->last_stream_read]->demuxer);
  634. }
  635. return percent;
  636. }
  637. int mpeg3_end_of_audio(mpeg3_t *file, int stream)
  638. {
  639. int result = 0;
  640. result = mpeg3demux_eof(file->atrack[stream]->demuxer);
  641. return result;
  642. }
  643. int mpeg3_end_of_video(mpeg3_t *file, int stream)
  644. {
  645. int result = 0;
  646. result = mpeg3demux_eof(file->vtrack[stream]->demuxer);
  647. return result;
  648. }
  649. int mpeg3_read_audio_frame (mpeg3_t *file,
  650.     unsigned char **output,
  651.     uint32_t *size,
  652.     uint32_t *max_size,
  653.     int stream)
  654. {
  655.   int result = -1;
  656.   if (file->total_astreams) {
  657.     result = mpeg3_atrack_read_frame(file->atrack[stream],
  658.      output, 
  659.      size,
  660.      max_size);
  661.     file->last_type_read = 1;
  662.     file->last_stream_read = stream;
  663.   }
  664.   return result;
  665. }
  666.  
  667. int mpeg3_get_audio_format (mpeg3_t *file, int stream)
  668. {
  669.   if (file->total_astreams) {
  670.     return (file->atrack[stream]->format);
  671.   }
  672.   return AUDIO_UNKNOWN;
  673. }
  674. int mpeg3_read_video_chunk(mpeg3_t *file, 
  675. unsigned char *output, 
  676. long *size, 
  677. long max_size,
  678. int stream)
  679. {
  680. int result = 0;
  681. if(file->total_vstreams)
  682. {
  683. result = mpeg3vtrack_read_raw(file->vtrack[stream], output, size, max_size);
  684. file->last_type_read = 2;
  685. file->last_stream_read = stream;
  686. }
  687. return result;
  688. }
  689. int mpeg3_read_video_chunk_resize (mpeg3_t *file,
  690.    unsigned char **output,
  691.    long *size,
  692.    int stream)
  693. {
  694. int result = 0;
  695. if(file->total_vstreams)
  696. {
  697. result = mpeg3vtrack_read_raw_resize(file->vtrack[stream], 
  698.      output, 
  699.      size);
  700. file->last_type_read = 2;
  701. file->last_stream_read = stream;
  702. }
  703. return result;
  704. }
  705. void mpeg3_read_video_chunk_cleanup (mpeg3_t *file,
  706.      int stream)
  707. {
  708. int result = 0;
  709. if(file->total_vstreams)
  710. {
  711.   mpeg3vtrack_cleanup_frame(file->vtrack[stream]);
  712. }
  713. }