123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- #include "RawMediaReader.h"
- #include "virtualIO.h"
- #include <limits.h>
- bool IsMyExtension(const wchar_t *filename);
- int RawMediaReaderService::CreateRawMediaReader(const wchar_t *filename, ifc_raw_media_reader **out_reader)
- {
- if (IsMyExtension(filename))
- {
- void *unicode_reader = CreateUnicodeReader(filename);
- if (!unicode_reader )
- return NErr_FileNotFound;
- MP4FileHandle mp4 = MP4ReadEx(filename, unicode_reader, &UnicodeIO);
- if (!mp4)
- {
- DestroyUnicodeReader(unicode_reader);
- return NErr_Malformed;
- }
- RawMediaReader *reader = new RawMediaReader(mp4, unicode_reader);
- if (!reader)
- {
- MP4Close(mp4);
- DestroyUnicodeReader(unicode_reader);
- return NErr_OutOfMemory;
- }
- *out_reader = reader;
- return NErr_Success;
- }
- else
- {
- return NErr_False;
- }
- }
- #define CBCLASS RawMediaReaderService
- START_DISPATCH;
- CB(CREATERAWMEDIAREADER, CreateRawMediaReader);
- END_DISPATCH;
- #undef CBCLASS
- RawMediaReader::RawMediaReader(MP4FileHandle file, void *reader) : file(file), reader(reader)
- {
- track_num=0;
- number_of_tracks=MP4GetNumberOfTracks(file);
- current_track = MP4_INVALID_TRACK_ID;
- chunk_position=0;
- chunk_size=0;
- chunk_buffer=0;
- }
- RawMediaReader::~RawMediaReader()
- {
- if (chunk_buffer)
- MP4Free(chunk_buffer);
- MP4Close(file);
- DestroyUnicodeReader(reader);
- }
- int RawMediaReader::ReadNextChunk()
- {
- again:
- /* see if it's time to cycle to the next track */
- if (current_track == MP4_INVALID_TRACK_ID)
- {
- if (track_num == number_of_tracks)
- return NErr_EndOfFile;
- current_track = MP4FindTrackId(file, track_num);
- if (current_track == MP4_INVALID_TRACK_ID)
- return NErr_EndOfFile;
- track_num++;
- const char* trackType = MP4GetTrackType(file, current_track);
- if (!MP4_IS_AUDIO_TRACK_TYPE(trackType) && !MP4_IS_VIDEO_TRACK_TYPE(trackType))
- {
- current_track = MP4_INVALID_TRACK_ID;
- goto again;
- }
- chunk_id = 1;
- number_of_chunks= MP4GetTrackNumberOfChunks(file, current_track);
- }
- /* see if we've read all of our samples */
- if (chunk_id > number_of_chunks)
- {
- current_track = MP4_INVALID_TRACK_ID;
- goto again;
- }
- bool readSuccess = MP4ReadChunk(file, current_track, chunk_id, &chunk_buffer, &chunk_size);
- if (!readSuccess)
- return NErr_Error;
- chunk_position=0;
- chunk_id++;
- return NErr_Success;
- }
- int RawMediaReader::Read(void *buffer, size_t buffer_size, size_t *bytes_read)
- {
- if (buffer_size > INT_MAX)
- return NErr_BadParameter;
- if (chunk_position==chunk_size)
- {
- MP4Free(chunk_buffer);
- chunk_buffer=0;
- }
- if (!chunk_buffer)
- {
- int ret = ReadNextChunk();
- if (ret != NErr_Success)
- return ret;
- }
- size_t to_read = chunk_size-chunk_position;
- if (to_read > buffer_size)
- to_read = buffer_size;
- memcpy(buffer, &chunk_buffer[chunk_position], to_read);
- chunk_position += to_read;
- *bytes_read = to_read;
- return NErr_Success;
- }
- size_t RawMediaReader::Release()
- {
- delete this;
- return 0;
- }
- #define CBCLASS RawMediaReader
- START_DISPATCH;
- CB(RELEASE, Release);
- CB(RAW_READ, Read);
- END_DISPATCH;
- #undef CBCLASS
|