RawMediaReader.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include "RawMediaReader.h"
  2. #include "virtualIO.h"
  3. #include <limits.h>
  4. bool IsMyExtension(const wchar_t *filename);
  5. int RawMediaReaderService::CreateRawMediaReader(const wchar_t *filename, ifc_raw_media_reader **out_reader)
  6. {
  7. if (IsMyExtension(filename))
  8. {
  9. void *unicode_reader = CreateUnicodeReader(filename);
  10. if (!unicode_reader )
  11. return NErr_FileNotFound;
  12. MP4FileHandle mp4 = MP4ReadEx(filename, unicode_reader, &UnicodeIO);
  13. if (!mp4)
  14. {
  15. DestroyUnicodeReader(unicode_reader);
  16. return NErr_Malformed;
  17. }
  18. RawMediaReader *reader = new RawMediaReader(mp4, unicode_reader);
  19. if (!reader)
  20. {
  21. MP4Close(mp4);
  22. DestroyUnicodeReader(unicode_reader);
  23. return NErr_OutOfMemory;
  24. }
  25. *out_reader = reader;
  26. return NErr_Success;
  27. }
  28. else
  29. {
  30. return NErr_False;
  31. }
  32. }
  33. #define CBCLASS RawMediaReaderService
  34. START_DISPATCH;
  35. CB(CREATERAWMEDIAREADER, CreateRawMediaReader);
  36. END_DISPATCH;
  37. #undef CBCLASS
  38. RawMediaReader::RawMediaReader(MP4FileHandle file, void *reader) : file(file), reader(reader)
  39. {
  40. track_num=0;
  41. number_of_tracks=MP4GetNumberOfTracks(file);
  42. current_track = MP4_INVALID_TRACK_ID;
  43. chunk_position=0;
  44. chunk_size=0;
  45. chunk_buffer=0;
  46. }
  47. RawMediaReader::~RawMediaReader()
  48. {
  49. if (chunk_buffer)
  50. MP4Free(chunk_buffer);
  51. MP4Close(file);
  52. DestroyUnicodeReader(reader);
  53. }
  54. int RawMediaReader::ReadNextChunk()
  55. {
  56. again:
  57. /* see if it's time to cycle to the next track */
  58. if (current_track == MP4_INVALID_TRACK_ID)
  59. {
  60. if (track_num == number_of_tracks)
  61. return NErr_EndOfFile;
  62. current_track = MP4FindTrackId(file, track_num);
  63. if (current_track == MP4_INVALID_TRACK_ID)
  64. return NErr_EndOfFile;
  65. track_num++;
  66. const char* trackType = MP4GetTrackType(file, current_track);
  67. if (!MP4_IS_AUDIO_TRACK_TYPE(trackType) && !MP4_IS_VIDEO_TRACK_TYPE(trackType))
  68. {
  69. current_track = MP4_INVALID_TRACK_ID;
  70. goto again;
  71. }
  72. chunk_id = 1;
  73. number_of_chunks= MP4GetTrackNumberOfChunks(file, current_track);
  74. }
  75. /* see if we've read all of our samples */
  76. if (chunk_id > number_of_chunks)
  77. {
  78. current_track = MP4_INVALID_TRACK_ID;
  79. goto again;
  80. }
  81. bool readSuccess = MP4ReadChunk(file, current_track, chunk_id, &chunk_buffer, &chunk_size);
  82. if (!readSuccess)
  83. return NErr_Error;
  84. chunk_position=0;
  85. chunk_id++;
  86. return NErr_Success;
  87. }
  88. int RawMediaReader::Read(void *buffer, size_t buffer_size, size_t *bytes_read)
  89. {
  90. if (buffer_size > INT_MAX)
  91. return NErr_BadParameter;
  92. if (chunk_position==chunk_size)
  93. {
  94. MP4Free(chunk_buffer);
  95. chunk_buffer=0;
  96. }
  97. if (!chunk_buffer)
  98. {
  99. int ret = ReadNextChunk();
  100. if (ret != NErr_Success)
  101. return ret;
  102. }
  103. size_t to_read = chunk_size-chunk_position;
  104. if (to_read > buffer_size)
  105. to_read = buffer_size;
  106. memcpy(buffer, &chunk_buffer[chunk_position], to_read);
  107. chunk_position += to_read;
  108. *bytes_read = to_read;
  109. return NErr_Success;
  110. }
  111. size_t RawMediaReader::Release()
  112. {
  113. delete this;
  114. return 0;
  115. }
  116. #define CBCLASS RawMediaReader
  117. START_DISPATCH;
  118. CB(RELEASE, Release);
  119. CB(RAW_READ, Read);
  120. END_DISPATCH;
  121. #undef CBCLASS