diff --git a/src/add-ons/media/plugins/mp4_reader/libMP4/ChunkSuperIndex.h b/src/add-ons/media/plugins/mp4_reader/libMP4/ChunkSuperIndex.h index bf5ba955b0..a0caee5ea6 100644 --- a/src/add-ons/media/plugins/mp4_reader/libMP4/ChunkSuperIndex.h +++ b/src/add-ons/media/plugins/mp4_reader/libMP4/ChunkSuperIndex.h @@ -27,8 +27,8 @@ #include -// Std Headers -#include +#include + struct ChunkIndex { uint32 stream; diff --git a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Atom.h b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Atom.h index f8ed7f4387..607ec4d1bd 100644 --- a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Atom.h +++ b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Atom.h @@ -25,15 +25,15 @@ #ifndef _MP4_ATOM_H #define _MP4_ATOM_H +#include "MP4Structs.h" + #include #include #include #include -// Std Headers -#include +#include -#include "MP4Structs.h" /* AtomBase diff --git a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4FileReader.cpp b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4FileReader.cpp index d33bfcb8a0..99f9366a0e 100644 --- a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4FileReader.cpp +++ b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4FileReader.cpp @@ -22,38 +22,45 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include #include "MP4Parser.h" #include "MP4FileReader.h" +#include +#include + +#include + + extern AtomBase *getAtom(BPositionIO *pStream); + MP4FileReader::MP4FileReader(BPositionIO *pStream) { theStream = pStream; - + // Find Size of Stream, need to rethink this for non seekable streams theStream->Seek(0,SEEK_END); StreamSize = theStream->Position(); theStream->Seek(0,SEEK_SET); TotalChildren = 0; - + theMVHDAtom = NULL; } + MP4FileReader::~MP4FileReader() { theStream = NULL; theMVHDAtom = NULL; } -bool MP4FileReader::IsEndOfData(off_t pPosition) + +bool +MP4FileReader::IsEndOfData(off_t pPosition) { -AtomBase *aAtomBase; + AtomBase* aAtomBase; for (uint32 index=0;index= aMdatAtom->getEOF(); } } - + return true; } -bool MP4FileReader::IsEndOfFile(off_t pPosition) + +bool +MP4FileReader::IsEndOfFile(off_t position) { - return (pPosition >= StreamSize); + return (position >= StreamSize); } -bool MP4FileReader::IsEndOfFile() + +bool +MP4FileReader::IsEndOfFile() { - return (theStream->Position() >= StreamSize); + return theStream->Position() >= StreamSize; } -bool MP4FileReader::AddChild(AtomBase *pChildAtom) + +bool +MP4FileReader::AddChild(AtomBase *childAtom) { - if (pChildAtom) { - atomChildren[TotalChildren++] = pChildAtom; + if (childAtom) { + atomChildren[TotalChildren++] = childAtom; return true; } return false; } -AtomBase *MP4FileReader::GetChildAtom(uint32 patomType, uint32 offset) + +AtomBase * +MP4FileReader::GetChildAtom(uint32 patomType, uint32 offset) { - for (uint32 i=0;iIsType(patomType)) { // found match, skip if offset non zero. if (offset == 0) { @@ -110,7 +125,9 @@ AtomBase *MP4FileReader::GetChildAtom(uint32 patomType, uint32 offset) return NULL; } -uint32 MP4FileReader::CountChildAtoms(uint32 patomType) + +uint32 +MP4FileReader::CountChildAtoms(uint32 patomType) { uint32 count = 0; @@ -120,9 +137,11 @@ uint32 MP4FileReader::CountChildAtoms(uint32 patomType) return count; } -MVHDAtom *MP4FileReader::getMVHDAtom() + +MVHDAtom* +MP4FileReader::getMVHDAtom() { -AtomBase *aAtomBase; + AtomBase *aAtomBase; if (theMVHDAtom == NULL) { aAtomBase = GetChildAtom(uint32('mvhd')); @@ -133,9 +152,11 @@ AtomBase *aAtomBase; return theMVHDAtom; } -void MP4FileReader::BuildSuperIndex() + +void +MP4FileReader::BuildSuperIndex() { -AtomBase *aAtomBase; + AtomBase *aAtomBase; for (uint32 stream=0;streamgetTimeScale(); } -bigtime_t MP4FileReader::getMovieDuration() + +bigtime_t +MP4FileReader::getMovieDuration() { - return ((bigtime_t(getMVHDAtom()->getDuration()) * 1000000L) / getMovieTimeScale()); + return (bigtime_t(getMVHDAtom()->getDuration()) * 1000000L) + / getMovieTimeScale(); } -uint32 MP4FileReader::getStreamCount() + +uint32 +MP4FileReader::getStreamCount() { // count the number of tracks in the file - return (CountChildAtoms(uint32('trak'))); + return CountChildAtoms(uint32('trak')); } -bigtime_t MP4FileReader::getVideoDuration(uint32 stream_index) -{ -AtomBase *aAtomBase; - aAtomBase = GetChildAtom(uint32('trak'),stream_index); - - if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsVideo())) { - return (dynamic_cast(aAtomBase)->Duration(1)); - } - +bigtime_t +MP4FileReader::getVideoDuration(uint32 streamIndex) +{ + AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); + + if (aAtomBase && dynamic_cast(aAtomBase)->IsVideo()) + return dynamic_cast(aAtomBase)->Duration(1); + return 0; } -bigtime_t MP4FileReader::getAudioDuration(uint32 stream_index) -{ -AtomBase *aAtomBase; - aAtomBase = GetChildAtom(uint32('trak'),stream_index); - - if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsAudio())) { - return (dynamic_cast(aAtomBase)->Duration(1)); - } - +bigtime_t +MP4FileReader::getAudioDuration(uint32 streamIndex) +{ + AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); + + if (aAtomBase && dynamic_cast(aAtomBase)->IsAudio()) + return dynamic_cast(aAtomBase)->Duration(1); + return 0; } -bigtime_t MP4FileReader::getMaxDuration() + +bigtime_t +MP4FileReader::getMaxDuration() { -AtomBase *aAtomBase; -int32 video_index,audio_index; - video_index = -1; - audio_index = -1; + AtomBase *aAtomBase; + int32 videoIndex = -1; + int32 audioIndex = -1; // find the active video and audio tracks - for (uint32 i=0;i(aAtomBase)->IsActive())) { if (dynamic_cast(aAtomBase)->IsAudio()) { - audio_index = int32(i); + audioIndex = int32(i); } if (dynamic_cast(aAtomBase)->IsVideo()) { - video_index = int32(i); + videoIndex = int32(i); } } } - if ((video_index >= 0) && (audio_index >= 0)) { - return MAX(getVideoDuration(video_index),getAudioDuration(audio_index)); + if (videoIndex >= 0 && audioIndex >= 0) { + return max_c(getVideoDuration(videoIndex), + getAudioDuration(audioIndex)); } - if ((video_index < 0) && (audio_index >= 0)) { - return getAudioDuration(audio_index); + if (videoIndex < 0 && audioIndex >= 0) { + return getAudioDuration(audioIndex); } - if ((video_index >= 0) && (audio_index < 0)) { - return getVideoDuration(video_index); + if (videoIndex >= 0 && audioIndex < 0) { + return getVideoDuration(videoIndex); } - + return 0; } -uint32 MP4FileReader::getVideoFrameCount(uint32 stream_index) + +uint32 +MP4FileReader::getVideoFrameCount(uint32 streamIndex) { -AtomBase *aAtomBase; - - aAtomBase = GetChildAtom(uint32('trak'),stream_index); - - if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsVideo())) { + AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); + if (aAtomBase && dynamic_cast(aAtomBase)->IsVideo()) return dynamic_cast(aAtomBase)->FrameCount(); - } - + return 1; } -uint32 MP4FileReader::getAudioFrameCount(uint32 stream_index) + +uint32 +MP4FileReader::getAudioFrameCount(uint32 streamIndex) { - if (IsAudio(stream_index)) { - return uint32(((getAudioDuration(stream_index) * AudioFormat(stream_index)->SampleRate) / 1000000L) + 0.5); + if (IsAudio(streamIndex)) { + return uint32(((getAudioDuration(streamIndex) + * AudioFormat(streamIndex)->SampleRate) / 1000000L) + 0.5); } - + return 0; } -bool MP4FileReader::IsVideo(uint32 stream_index) -{ - // Look for a trak with a vmhd atom - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); - - if (aAtomBase) { - return (dynamic_cast(aAtomBase)->IsVideo()); - } - - // No trak +bool +MP4FileReader::IsVideo(uint32 streamIndex) +{ + // Look for a 'trak' with a vmhd atom + + AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); + if (aAtomBase) + return dynamic_cast(aAtomBase)->IsVideo(); + + // No track return false; } -bool MP4FileReader::IsAudio(uint32 stream_index) -{ - // Look for a trak with a smhd atom - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); - - if (aAtomBase) { - return (dynamic_cast(aAtomBase)->IsAudio()); - } - - // No trak +bool +MP4FileReader::IsAudio(uint32 streamIndex) +{ + // Look for a 'trak' with a smhd atom + + AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); + + if (aAtomBase) + return dynamic_cast(aAtomBase)->IsAudio(); + + // No track return false; } -uint32 MP4FileReader::getFirstFrameInChunk(uint32 stream_index, uint32 pChunkID) + +uint32 +MP4FileReader::getFirstFrameInChunk(uint32 streamIndex, uint32 pChunkID) { // Find Track - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); + AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); - + return aTrakAtom->getFirstSampleInChunk(pChunkID); } - + return 0; } -uint32 MP4FileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo) + +uint32 +MP4FileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo) { // Find Track AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); @@ -303,10 +337,9 @@ uint32 MP4FileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo) TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); uint32 ChunkNo = 1; - if (IsAudio(stream_index)) { - ChunkNo = pFrameNo; - } - + if (IsAudio(stream_index)) + ChunkNo = pFrameNo; + if (IsVideo(stream_index)) { uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo); @@ -320,7 +353,9 @@ uint32 MP4FileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo) return 0; } -uint64 MP4FileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo) + +uint64 +MP4FileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo) { // Find Track AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); @@ -336,7 +371,6 @@ uint64 MP4FileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo) } if (IsVideo(stream_index)) { - if (pFrameNo < aTrakAtom->FrameCount()) { // Get Sample for Frame uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo); @@ -365,11 +399,13 @@ uint64 MP4FileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo) } } } - + return 0; } -status_t MP4FileReader::ParseFile() + +status_t +MP4FileReader::ParseFile() { AtomBase *aChild; while (IsEndOfFile() == false) { @@ -389,7 +425,9 @@ status_t MP4FileReader::ParseFile() return B_OK; } -const mp4_main_header *MP4FileReader::MovMainHeader() + +const mp4_main_header* +MP4FileReader::MovMainHeader() { // Fill In theMainHeader // uint32 micro_sec_per_frame; @@ -409,10 +447,10 @@ const mp4_main_header *MP4FileReader::MovMainHeader() theMainHeader.flags = 0; theMainHeader.initial_frames = 0; - while ( videoStream < theMainHeader.streams ) { - if (IsVideo(videoStream) && IsActive(videoStream)) { + while (videoStream < theMainHeader.streams) { + if (IsVideo(videoStream) && IsActive(videoStream)) break; - } + videoStream++; } @@ -429,17 +467,18 @@ const mp4_main_header *MP4FileReader::MovMainHeader() theMainHeader.suggested_buffer_size = theMainHeader.width * theMainHeader.height * VideoFormat(videoStream)->bit_count / 8; theMainHeader.micro_sec_per_frame = uint32(1000000.0 / VideoFormat(videoStream)->FrameRate); } - + theMainHeader.padding_granularity = 0; theMainHeader.max_bytes_per_sec = 0; return &theMainHeader; } -const AudioMetaData *MP4FileReader::AudioFormat(uint32 stream_index, size_t *size = 0) + +const AudioMetaData * +MP4FileReader::AudioFormat(uint32 stream_index, size_t *size) { if (IsAudio(stream_index)) { - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { @@ -470,22 +509,21 @@ const AudioMetaData *MP4FileReader::AudioFormat(uint32 stream_index, size_t * return NULL; } -const VideoMetaData *MP4FileReader::VideoFormat(uint32 stream_index) + +const VideoMetaData* +MP4FileReader::VideoFormat(uint32 stream_index) { if (IsVideo(stream_index)) { - AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); - + aAtomBase = aTrakAtom->GetChildAtom(uint32('stsd'),0); - if (aAtomBase) { STSDAtom *aSTSDAtom = dynamic_cast(aAtomBase); - VideoDescription aVideoDescription = aSTSDAtom->getAsVideo(); - + theVideo.compression = aVideoDescription.codecid; theVideo.width = aVideoDescription.theVideoSampleEntry.Width; @@ -506,17 +544,19 @@ const VideoMetaData *MP4FileReader::VideoFormat(uint32 stream_index) STTSAtom *aSTTSAtom = dynamic_cast(aAtomBase); theVideo.FrameRate = ((aSTTSAtom->getSUMCounts() * 1000000.0L) / aTrakAtom->Duration(1)); - + return &theVideo; } } } } - + return NULL; } -const mp4_stream_header *MP4FileReader::StreamFormat(uint32 stream_index) + +const mp4_stream_header* +MP4FileReader::StreamFormat(uint32 stream_index) { // Fill In a Stream Header theStreamHeader.length = 0; @@ -530,7 +570,7 @@ const mp4_stream_header *MP4FileReader::StreamFormat(uint32 stream_index) theStreamHeader.scale = 1000000L; theStreamHeader.length = getVideoFrameCount(stream_index); } - + if (IsAudio(stream_index)) { theStreamHeader.rate = uint32(AudioFormat(stream_index)->SampleRate); theStreamHeader.scale = 1; @@ -538,26 +578,27 @@ const mp4_stream_header *MP4FileReader::StreamFormat(uint32 stream_index) theStreamHeader.sample_size = AudioFormat(stream_index)->SampleSize; theStreamHeader.suggested_buffer_size = theStreamHeader.rate * theStreamHeader.sample_size; } - + return &theStreamHeader; } -uint32 MP4FileReader::getChunkSize(uint32 stream_index, uint32 pFrameNo) + +uint32 +MP4FileReader::getChunkSize(uint32 stream_index, uint32 pFrameNo) { AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); if (IsAudio(stream_index)) { - // We read audio in chunk by chunk so chunk size is chunk size uint32 ChunkNo = pFrameNo; off_t Chunk_Start = aTrakAtom->getOffsetForChunk(ChunkNo); uint32 ChunkSize = theChunkSuperIndex.getChunkSize(stream_index,ChunkNo,Chunk_Start); - + return ChunkSize; } - + if (IsVideo(stream_index)) { if (pFrameNo < aTrakAtom->FrameCount()) { // We read video in Sample by Sample so we use get Sample Size @@ -565,18 +606,19 @@ uint32 MP4FileReader::getChunkSize(uint32 stream_index, uint32 pFrameNo) return aTrakAtom->getSizeForSample(SampleNo); } } - } return 0; } -bool MP4FileReader::IsKeyFrame(uint32 stream_index, uint32 pFrameNo) + +bool +MP4FileReader::IsKeyFrame(uint32 stream_index, uint32 pFrameNo) { AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); - + uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo); return aTrakAtom->IsSyncSample(SampleNo); } @@ -584,38 +626,44 @@ bool MP4FileReader::IsKeyFrame(uint32 stream_index, uint32 pFrameNo) return false; } -bool MP4FileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe) + +bool +MP4FileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, + off_t *start, uint32 *size, bool *keyframe) { *start = getOffsetForFrame(stream_index, pFrameNo); *size = getChunkSize(stream_index, pFrameNo); - + if ((*start > 0) && (*size > 0)) { *keyframe = IsKeyFrame(stream_index, pFrameNo); } // TODO need a better method for detecting End of Data Note ChunkSize of 0 seems to be it. - return ((*start > 0) && (*size > 0) && !(IsEndOfFile(*start + *size)) && !(IsEndOfData(*start + *size))); + return *start > 0 && *size > 0 && !IsEndOfFile(*start + *size) + && !IsEndOfData(*start + *size); } -bool MP4FileReader::IsActive(uint32 stream_index) + +bool +MP4FileReader::IsActive(uint32 stream_index) { AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index); if (aAtomBase) { TRAKAtom *aTrakAtom = dynamic_cast(aAtomBase); return aTrakAtom->IsActive(); } - + return false; } + /* static */ -bool MP4FileReader::IsSupported(BPositionIO *source) +bool +MP4FileReader::IsSupported(BPositionIO *source) { - AtomBase *aAtom; - - aAtom = getAtom(source); - if (aAtom) { - return (aAtom->IsKnown()); - } + AtomBase *aAtom = getAtom(source); + if (aAtom) + return aAtom->IsKnown(); + return false; } diff --git a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Parser.h b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Parser.h index 90a3ea011b..6fd4535e66 100644 --- a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Parser.h +++ b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Parser.h @@ -31,7 +31,7 @@ #include // Std Headers -#include +#include #include "MP4Atom.h" diff --git a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Structs.h b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Structs.h index ca571e64f8..18e42d7ce2 100644 --- a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Structs.h +++ b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Structs.h @@ -22,6 +22,12 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef MP4_STRUCTS_H +#define MP4_STRUCTS_H + + +#include + #define AUDIO_NONE 'NONE' #define AUDIO_RAW 'raw ' @@ -33,8 +39,7 @@ #define AUDIO_MPEG3_CBR 0x6D730055 // this is all from the avi reader. we rework it for mp4 -struct mp4_main_header -{ +struct mp4_main_header { uint32 micro_sec_per_frame; uint32 max_bytes_per_sec; uint32 padding_granularity; @@ -273,3 +278,5 @@ struct VideoDescription { uint8 *theVOL; size_t VOLSize; }; + +#endif // MP4_STRUCTS_H diff --git a/src/add-ons/media/plugins/mp4_reader/mp4_reader.cpp b/src/add-ons/media/plugins/mp4_reader/mp4_reader.cpp index 1259fd1b01..df7ecea8b1 100644 --- a/src/add-ons/media/plugins/mp4_reader/mp4_reader.cpp +++ b/src/add-ons/media/plugins/mp4_reader/mp4_reader.cpp @@ -22,29 +22,33 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "RawFormats.h" + #include "mp4_reader.h" +#include "RawFormats.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + #define TRACE_MP4_READER #ifdef TRACE_MP4_READER - #define TRACE printf +# define TRACE printf #else - #define TRACE(a...) +# define TRACE(a...) #endif #define ERROR(a...) fprintf(stderr, a) -struct mp4_cookie -{ + +struct mp4_cookie { unsigned stream; char * buffer; unsigned buffer_size; @@ -77,17 +81,20 @@ mp4Reader::mp4Reader() TRACE("mp4Reader::mp4Reader\n"); } + mp4Reader::~mp4Reader() { delete theFileReader; } + const char * mp4Reader::Copyright() { return "MPEG4 & libMP4, " B_UTF8_COPYRIGHT " by David McPaul"; } + status_t mp4Reader::Sniff(int32 *streamCount) { @@ -118,13 +125,14 @@ mp4Reader::Sniff(int32 *streamCount) return B_OK; } + void mp4Reader::GetFileFormatInfo(media_file_format *mff) { - mff->capabilities = media_file_format::B_READABLE - | media_file_format::B_KNOWS_ENCODED_VIDEO - | media_file_format::B_KNOWS_ENCODED_AUDIO - | media_file_format::B_IMPERFECTLY_SEEKABLE; + mff->capabilities = media_file_format::B_READABLE + | media_file_format::B_KNOWS_ENCODED_VIDEO + | media_file_format::B_KNOWS_ENCODED_AUDIO + | media_file_format::B_IMPERFECTLY_SEEKABLE; mff->family = B_QUICKTIME_FORMAT_FAMILY; mff->version = 100; strcpy(mff->mime_type, "video/quicktime"); @@ -133,6 +141,7 @@ mp4Reader::GetFileFormatInfo(media_file_format *mff) strcpy(mff->pretty_name, "MPEG-4 (MP4) file format"); } + status_t mp4Reader::AllocateCookie(int32 streamNumber, void **_cookie) { @@ -180,40 +189,46 @@ mp4Reader::AllocateCookie(int32 streamNumber, void **_cookie) cookie->chunk_pos = 1; if (stream_header->scale && stream_header->rate) { - cookie->bytes_per_sec_rate = stream_header->rate * audio_format->SampleSize * audio_format->NoOfChannels / 8; + cookie->bytes_per_sec_rate = stream_header->rate * + audio_format->SampleSize * audio_format->NoOfChannels / 8; cookie->bytes_per_sec_scale = stream_header->scale; cookie->frames_per_sec_rate = stream_header->rate; cookie->frames_per_sec_scale = stream_header->scale; - TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using both)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); + TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using both)\n", + cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); } else if (stream_header->rate) { - cookie->bytes_per_sec_rate = stream_header->rate * audio_format->SampleSize * audio_format->NoOfChannels / 8; + cookie->bytes_per_sec_rate = stream_header->rate * audio_format->SampleSize + * audio_format->NoOfChannels / 8; cookie->bytes_per_sec_scale = 1; cookie->frames_per_sec_rate = stream_header->rate; cookie->frames_per_sec_scale = 1; - TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); + TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", + cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); } else if (audio_format->PacketSize) { cookie->bytes_per_sec_rate = audio_format->PacketSize; cookie->bytes_per_sec_scale = 1; - cookie->frames_per_sec_rate = audio_format->PacketSize * 8 / audio_format->SampleSize / audio_format->NoOfChannels; + cookie->frames_per_sec_rate = audio_format->PacketSize * 8 + / audio_format->SampleSize / audio_format->NoOfChannels; cookie->frames_per_sec_scale = 1; - TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using PacketSize)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); + TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using PacketSize)\n", + cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); } else { cookie->bytes_per_sec_rate = 128000; cookie->bytes_per_sec_scale = 8; cookie->frames_per_sec_rate = 16000; cookie->frames_per_sec_scale = 1; - TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using fallback)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); + TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using fallback)\n", + cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); } - if ((audio_format->compression == AUDIO_NONE) || - (audio_format->compression == AUDIO_RAW) || - (audio_format->compression == AUDIO_TWOS1) || - (audio_format->compression == AUDIO_TWOS2)) { + if (audio_format->compression == AUDIO_NONE + || audio_format->compression == AUDIO_RAW + || audio_format->compression == AUDIO_TWOS1 + || audio_format->compression == AUDIO_TWOS2) { description.family = B_BEOS_FORMAT_FAMILY; description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO; - if (B_OK != formats.GetFormatFor(description, format)) { + if (B_OK != formats.GetFormatFor(description, format)) format->type = B_MEDIA_RAW_AUDIO; - } format->u.raw_audio.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale; format->u.raw_audio.channel_count = audio_format->NoOfChannels; @@ -463,7 +478,7 @@ mp4Reader::FreeCookie(void *_cookie) status_t mp4Reader::GetStreamInfo(void *_cookie, int64 *frameCount, bigtime_t *duration, - media_format *format, const void **infoBuffer, size_t *infoSize) + media_format *format, const void **infoBuffer, size_t *infoSize) { mp4_cookie *cookie = (mp4_cookie *)_cookie; @@ -477,9 +492,7 @@ mp4Reader::GetStreamInfo(void *_cookie, int64 *frameCount, bigtime_t *duration, status_t -mp4Reader::Seek(void *cookie, - uint32 seekTo, - int64 *frame, bigtime_t *time) +mp4Reader::Seek(void *cookie, uint32 seekTo, int64 *frame, bigtime_t *time) { // We should seek to nearest keyframe requested @@ -515,21 +528,23 @@ mp4Reader::Seek(void *cookie, status_t -mp4Reader::GetNextChunk(void *_cookie, - const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) +mp4Reader::GetNextChunk(void *_cookie, const void **chunkBuffer, + size_t *chunkSize, media_header *mediaHeader) { mp4_cookie *cookie = (mp4_cookie *)_cookie; - - int64 start; uint32 size; bool keyframe; + int64 start; + uint32 size; + bool keyframe; if (cookie->audio) { // use chunk position - if (!theFileReader->GetNextChunkInfo(cookie->stream, cookie->chunk_pos, &start, &size, &keyframe)) + if (!theFileReader->GetNextChunkInfo(cookie->stream, cookie->chunk_pos, + &start, &size, &keyframe)) return B_LAST_BUFFER_ERROR; } else { // use frame position - if (!theFileReader->GetNextChunkInfo(cookie->stream, cookie->frame_pos, &start, &size, &keyframe)) + if (!theFileReader->GetNextChunkInfo(cookie->stream, cookie->frame_pos, + &start, &size, &keyframe)) return B_LAST_BUFFER_ERROR; } @@ -571,7 +586,15 @@ mp4Reader::GetNextChunk(void *_cookie, *chunkBuffer = cookie->buffer; *chunkSize = size; - return (int)size == theFileReader->Source()->ReadAt(start, cookie->buffer, size) ? B_OK : B_LAST_BUFFER_ERROR; + + ssize_t bytesRead = theFileReader->Source()->ReadAt(start, cookie->buffer, size); + if (bytesRead < B_OK) + return bytesRead; + + if (bytesRead < (ssize_t)size) + return B_LAST_BUFFER_ERROR; + + return B_OK; }