diff --git a/src/add-ons/media/plugins/avcodec/codectbl.cpp b/src/add-ons/media/plugins/avcodec/codectbl.cpp index 7f8322f464..afb0c3f57e 100644 --- a/src/add-ons/media/plugins/avcodec/codectbl.cpp +++ b/src/add-ons/media/plugins/avcodec/codectbl.cpp @@ -32,9 +32,11 @@ const struct codec_table gCodecTable[] = { {CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_AIFF_FORMAT_FAMILY, 'alaw' , "aLaw"}, {CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_AIFF_FORMAT_FAMILY, 'ALAW' , "aLaw"}, {CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, (uint64('au') << 32) | 27, "aLaw"}, -/* + {CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'ulaw', "µLaw"}, -*/ + {CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'alaw', "aLaw"}, + {CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'ALAW', "aLaw"}, + {CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x07, "µLaw"}, {CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_AIFF_FORMAT_FAMILY, 'ulaw', "µLaw"}, {CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_AIFF_FORMAT_FAMILY, 'ULAW', "µLaw"}, @@ -44,7 +46,8 @@ const struct codec_table gCodecTable[] = { {CODEC_ID_ADPCM_MS, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0002, "MS ADPCM"}, {CODEC_ID_ADPCM_IMA_WAV, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730011, "IMA ADPCM"}, {CODEC_ID_ADPCM_MS, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730002, "MS ADPCM"}, - {CODEC_ID_MP3, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730055, "MP3"}, + {CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730050, "MP Layer2"}, + {CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730055, "MP Layer3"}, #ifdef HAS_MACE_AUDIO {CODEC_ID_MACE3, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'MAC3', "MACE 3:1"}, diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp index a66f74008a..79e502c39a 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp @@ -125,7 +125,7 @@ uint32 MOVFileReader::getMovieTimeScale() bigtime_t MOVFileReader::getMovieDuration() { - return ((bigtime_t(getMVHDAtom()->getDuration()) * 1000000) / getMovieTimeScale()); + return ((bigtime_t(getMVHDAtom()->getDuration()) * 1000000L) / getMovieTimeScale()); } uint32 MOVFileReader::getStreamCount() @@ -134,33 +134,27 @@ uint32 MOVFileReader::getStreamCount() return (CountChildAtoms(uint32('trak'))); } -bigtime_t MOVFileReader::getVideoDuration() +bigtime_t MOVFileReader::getVideoDuration(uint32 stream_index) { AtomBase *aAtomBase; -uint32 TimeScale = getMovieTimeScale(); - for (uint32 i=0;i(aAtomBase)->IsVideo())) { - return (dynamic_cast(aAtomBase)->Duration(TimeScale)); - } + if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsVideo())) { + return (dynamic_cast(aAtomBase)->Duration(1)); } return 0; } -bigtime_t MOVFileReader::getAudioDuration() +bigtime_t MOVFileReader::getAudioDuration(uint32 stream_index) { AtomBase *aAtomBase; -uint32 TimeScale = getMovieTimeScale(); - for (uint32 i=0;i(aAtomBase)->IsAudio())) { - return (dynamic_cast(aAtomBase)->Duration(TimeScale)); - } + if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsAudio())) { + return (dynamic_cast(aAtomBase)->Duration(1)); } return 0; @@ -168,39 +162,59 @@ uint32 TimeScale = getMovieTimeScale(); bigtime_t MOVFileReader::getMaxDuration() { - return MAX(getVideoDuration(),getAudioDuration()); +AtomBase *aAtomBase; +int32 video_index,audio_index; + video_index = -1; + audio_index = -1; + + // find the active video and audio tracks + for (uint32 i=0;i(aAtomBase)->IsActive())) { + if (dynamic_cast(aAtomBase)->IsAudio()) { + audio_index = int32(i); + } + if (dynamic_cast(aAtomBase)->IsVideo()) { + video_index = int32(i); + } + } + } + + if ((video_index >= 0) && (audio_index >= 0)) { + return MAX(getVideoDuration(video_index),getAudioDuration(audio_index)); + } + if ((video_index < 0) && (audio_index >= 0)) { + return getAudioDuration(audio_index); + } + if ((video_index >= 0) && (audio_index < 0)) { + return getVideoDuration(video_index); + } + + return 0; } -uint32 MOVFileReader::getVideoFrameCount() +uint32 MOVFileReader::getVideoFrameCount(uint32 stream_index) { AtomBase *aAtomBase; - for (uint32 i=0;i(aAtomBase)->IsVideo())) { + if ((aAtomBase) && (dynamic_cast(aAtomBase)->IsVideo())) { - return dynamic_cast(aAtomBase)->FrameCount(); - } + return dynamic_cast(aAtomBase)->FrameCount(); } return 1; } -uint32 MOVFileReader::getAudioFrameCount() +uint32 MOVFileReader::getAudioFrameCount(uint32 stream_index) { - -AtomBase *aAtomBase; - - for (uint32 i=0;i(aAtomBase)->IsAudio())) { - return uint32(((getAudioDuration() * AudioFormat(i)->SampleRate) / 1000000L) + 0.5); - } + if (IsAudio(stream_index)) { + return uint32(((getAudioDuration(stream_index) * AudioFormat(stream_index)->SampleRate) / 1000000L) + 0.5); } - return 1; + return 0; } bool MOVFileReader::IsVideo(uint32 stream_index) @@ -357,7 +371,7 @@ const mov_main_header *MOVFileReader::MovMainHeader() theMainHeader.initial_frames = 0; while ( videoStream < theMainHeader.streams ) { - if (IsVideo(videoStream)) { + if (IsVideo(videoStream) && IsActive(videoStream)) { break; } videoStream++; @@ -372,7 +386,7 @@ const mov_main_header *MOVFileReader::MovMainHeader() } else { theMainHeader.width = VideoFormat(videoStream)->width; theMainHeader.height = VideoFormat(videoStream)->height; - theMainHeader.total_frames = getVideoFrameCount(); + theMainHeader.total_frames = getVideoFrameCount(videoStream); theMainHeader.suggested_buffer_size = theMainHeader.width * theMainHeader.height * VideoFormat(videoStream)->bit_count / 8; theMainHeader.micro_sec_per_frame = uint32(1000000.0 / VideoFormat(videoStream)->FrameRate); } @@ -454,7 +468,7 @@ const VideoMetaData *MOVFileReader::VideoFormat(uint32 stream_index) if (aAtomBase) { STTSAtom *aSTTSAtom = dynamic_cast(aAtomBase); - theVideo.FrameRate = ((aSTTSAtom->getSUMCounts() * 1000000.0L) / getVideoDuration()); + theVideo.FrameRate = ((aSTTSAtom->getSUMCounts() * 1000000.0L) / aTrakAtom->Duration(1)); return &theVideo; } @@ -469,17 +483,21 @@ const mov_stream_header *MOVFileReader::StreamFormat(uint32 stream_index) { // Fill In a Stream Header theStreamHeader.length = 0; + + if (IsActive(stream_index) == false) { + return NULL; + } if (IsVideo(stream_index)) { - theStreamHeader.rate = uint32(1000000*VideoFormat(stream_index)->FrameRate); - theStreamHeader.scale = 1000000; - theStreamHeader.length = getVideoFrameCount(); + theStreamHeader.rate = uint32(1000000L*VideoFormat(stream_index)->FrameRate); + theStreamHeader.scale = 1000000L; + theStreamHeader.length = getVideoFrameCount(stream_index); } if (IsAudio(stream_index)) { theStreamHeader.rate = uint32(AudioFormat(stream_index)->SampleRate); theStreamHeader.scale = 1; - theStreamHeader.length = getAudioFrameCount(); + theStreamHeader.length = getAudioFrameCount(stream_index); theStreamHeader.sample_size = AudioFormat(stream_index)->SampleSize; theStreamHeader.suggested_buffer_size = theStreamHeader.rate * theStreamHeader.sample_size; } @@ -550,6 +568,17 @@ bool MOVFileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t return ((*start > 0) && (*size > 0) && !(IsEndOfFile(*start))); } +bool MOVFileReader::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 MOVFileReader::IsSupported(BPositionIO *source) { diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.h b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.h index 79fdc6ca48..dcae47c293 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.h @@ -72,20 +72,20 @@ public: // How many tracks in file uint32 getStreamCount(); - // Duration defined + // Duration defined by the movie header bigtime_t getMovieDuration(); - // The first video track duration - bigtime_t getVideoDuration(); - // the first audio track duration - bigtime_t getAudioDuration(); - // the max of the audio or video durations + // The first video track duration indexed by stream_index + bigtime_t getVideoDuration(uint32 stream_index); + // the first audio track duration indexed by stream_index + bigtime_t getAudioDuration(uint32 stream_index); + // the max of all active audio or video durations bigtime_t getMaxDuration(); - // The no of frames in the first video track - uint32 getVideoFrameCount(); - // The no of frames in the first audio track - uint32 getAudioFrameCount(); + // The no of frames in the video track indexed by stream_index + uint32 getVideoFrameCount(uint32 stream_index); + // The no of frames in the audio track indexed by stream_index + uint32 getAudioFrameCount(uint32 stream_index); // Is stream (track) a video track bool IsVideo(uint32 stream_index); @@ -102,6 +102,8 @@ public: status_t ParseFile(); BPositionIO *Source() {return theStream;}; + bool IsActive(uint32 stream_index); + bool GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe); // Return all Audio Meta Data diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp index a92cfc5a6a..924364ccad 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp @@ -267,13 +267,13 @@ void CMOVAtom::OnProcessMetaData() printf("Failed to decompress headers uncompress returned "); switch (result) { case Z_MEM_ERROR: - printf("Lack of Memory Error\n"); + DEBUGGER("Lack of Memory Error\n"); break; case Z_BUF_ERROR: - printf("Lack of Output buffer space Error\n"); + DEBUGGER("Lack of Output buffer space Error\n"); break; case Z_DATA_ERROR: - printf("Input Data is corrupt or not a compressed set Error\n"); + DEBUGGER("Input Data is corrupt or not a compressed set Error\n"); break; } } @@ -387,6 +387,7 @@ void MVHDAtom::OnProcessMetaData() theHeader.SelectionDuration = B_BENDIAN_TO_HOST_INT32(theHeader.SelectionDuration); theHeader.CurrentTime = B_BENDIAN_TO_HOST_INT32(theHeader.CurrentTime); theHeader.NextTrackID = B_BENDIAN_TO_HOST_INT32(theHeader.NextTrackID); + } char *MVHDAtom::OnGetAtomName() @@ -410,6 +411,8 @@ AtomBase *aAtomBase; STTSAtom::STTSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { theHeader.NoEntries = 0; + SUMDurations = 0; + SUMCounts = 0; } STTSAtom::~STTSAtom() @@ -434,6 +437,8 @@ TimeToSample *aTimeToSample; aTimeToSample->Duration = B_BENDIAN_TO_HOST_INT32(aTimeToSample->Duration); theTimeToSampleArray[i] = aTimeToSample; + SUMDurations += (theTimeToSampleArray[i]->Duration * theTimeToSampleArray[i]->Count); + SUMCounts += theTimeToSampleArray[i]->Count; } } @@ -442,39 +447,14 @@ char *STTSAtom::OnGetAtomName() return "Time to Sample Atom"; } -uint64 STTSAtom::getSUMCounts() -{ - uint64 SUMCounts = 0; - uint64 SUMDurations = 0; - - for (uint32 i=0;iDuration * theTimeToSampleArray[i]->Count); - SUMCounts += theTimeToSampleArray[i]->Count; - } - - return SUMCounts; -} - -uint64 STTSAtom::getSUMDurations() -{ -// this Duration is not scaled to timescale - uint64 SUMDurations = 0; - - for (uint32 i=0;iDuration * theTimeToSampleArray[i]->Count); - } - - return SUMDurations; -} - uint32 STTSAtom::getSampleForTime(uint32 pTime) { -// TODO this is too slow. PreCalc SUMCounts when loading this. - uint64 SUMDurations = 0; +// TODO this is too slow. PreCalc when loading this? + uint64 Duration = 0; for (uint32 i=0;iDuration * theTimeToSampleArray[i]->Count); - if (SUMDurations > pTime) { + Duration += (theTimeToSampleArray[i]->Duration * theTimeToSampleArray[i]->Count); + if (Duration > pTime) { return i; } } @@ -528,7 +508,6 @@ SampleToChunk *aSampleToChunk; } theSampleToChunkArray[i] = aSampleToChunk; -// printf("%ld/%ld/%ld\n",aSampleToChunk->FirstChunk,aSampleToChunk->SamplesPerChunk,aSampleToChunk->TotalPrevFrames); } } @@ -727,7 +706,7 @@ ChunkToOffset *aChunkToOffset; theChunkToOffsetArray[i] = aChunkToOffset; } - printf("Chunk to Offset Array has %ld entries\n",theHeader.NoEntries); + PRINT(("Chunk to Offset Array has %ld entries\n",theHeader.NoEntries)); } char *STCOAtom::OnGetAtomName() @@ -742,11 +721,10 @@ uint64 STCOAtom::getOffsetForChunk(uint32 pChunkID) return theChunkToOffsetArray[pChunkID - 1]->Offset; } - printf("Bad Chunk ID %ld / %ld\n",pChunkID,theHeader.NoEntries); + DEBUGGER(("Bad Chunk ID %ld / %ld\n",pChunkID,theHeader.NoEntries)); - // TODO Yes this will seg fault. But I get a very bad lock up if I don't :-( - return theChunkToOffsetArray[pChunkID - 1]->Offset; -// return theChunkToOffsetArray[0]->Offset; + TRESPASS(); + return theChunkToOffsetArray[0]->Offset; } STSDAtom::STSDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) @@ -843,7 +821,7 @@ void STSDAtom::ReadSoundDescription() if (aAtomBase->getAtomSize() > 0) { descBytesLeft = descBytesLeft - aAtomBase->getAtomSize(); } else { - printf("Invalid Atom found when reading Sound Description\n"); + DEBUGGER("Invalid Atom found when reading Sound Description\n"); descBytesLeft = 0; } @@ -855,7 +833,7 @@ void STSDAtom::ReadSoundDescription() theStream->Seek(descBytesLeft,0); - printf("Size:Format=%ld:%ld %ld\n",aSoundDescriptionV1->basefields.Size,aSoundDescriptionV1->basefields.DataFormat,descBytesLeft); + PRINT(("Size:Format=%ld:%ld %ld\n",aSoundDescriptionV1->basefields.Size,aSoundDescriptionV1->basefields.DataFormat,descBytesLeft)); } void STSDAtom::ReadVideoDescription() @@ -896,7 +874,7 @@ void STSDAtom::ReadVideoDescription() // We seem to have read 2 bytes too many??? theStream->Seek(descBytesLeft,0); - printf("Size:Format=%ld:%ld %ld\n",aVideoDescription->basefields.Size,aVideoDescription->basefields.DataFormat,descBytesLeft); + PRINT(("Size:Format=%ld:%ld %ld\n",aVideoDescription->basefields.Size,aVideoDescription->basefields.DataFormat,descBytesLeft)); } void STSDAtom::OnProcessMetaData() @@ -1157,17 +1135,45 @@ TKHDAtom::~TKHDAtom() void TKHDAtom::OnProcessMetaData() { - theStream->Read(&theHeader,sizeof(tkhd)); + theStream->Read(&Version,sizeof(uint8)); + + if (Version == 0) { + tkhdV0 aHeaderV0; + theStream->Read(&aHeaderV0,sizeof(tkhdV0)); + + theHeader.Flags1 = aHeaderV0.Flags1; + theHeader.Flags2 = aHeaderV0.Flags2; + theHeader.Flags3 = aHeaderV0.Flags3; + + for (uint32 i=0;i<36;i++) { + theHeader.MatrixStructure[i] = aHeaderV0.MatrixStructure[i]; + } + + // upconvert to V1 header + theHeader.CreationTime = B_BENDIAN_TO_HOST_INT32(aHeaderV0.CreationTime); + theHeader.ModificationTime = B_BENDIAN_TO_HOST_INT32(aHeaderV0.ModificationTime); + theHeader.TrackID = B_BENDIAN_TO_HOST_INT32(aHeaderV0.TrackID); + theHeader.Duration = B_BENDIAN_TO_HOST_INT32(aHeaderV0.Duration); + theHeader.Layer = B_BENDIAN_TO_HOST_INT16(aHeaderV0.Layer); + theHeader.AlternateGroup = B_BENDIAN_TO_HOST_INT16(aHeaderV0.AlternateGroup); + theHeader.Volume = B_BENDIAN_TO_HOST_INT16(aHeaderV0.Volume); + theHeader.TrackWidth = B_BENDIAN_TO_HOST_INT32(aHeaderV0.TrackWidth); + theHeader.TrackHeight = B_BENDIAN_TO_HOST_INT32(aHeaderV0.TrackHeight); + + } else { + theStream->Read(&theHeader,sizeof(tkhdV1)); + + theHeader.CreationTime = B_BENDIAN_TO_HOST_INT64(theHeader.CreationTime); + theHeader.ModificationTime = B_BENDIAN_TO_HOST_INT64(theHeader.ModificationTime); + theHeader.TrackID = B_BENDIAN_TO_HOST_INT32(theHeader.TrackID); + theHeader.Duration = B_BENDIAN_TO_HOST_INT32(theHeader.Duration); + theHeader.Layer = B_BENDIAN_TO_HOST_INT16(theHeader.Layer); + theHeader.AlternateGroup = B_BENDIAN_TO_HOST_INT16(theHeader.AlternateGroup); + theHeader.Volume = B_BENDIAN_TO_HOST_INT16(theHeader.Volume); + theHeader.TrackWidth = B_BENDIAN_TO_HOST_INT32(theHeader.TrackWidth); + theHeader.TrackHeight = B_BENDIAN_TO_HOST_INT32(theHeader.TrackHeight); + } - theHeader.CreationTime = B_BENDIAN_TO_HOST_INT32(theHeader.CreationTime); - theHeader.ModificationTime = B_BENDIAN_TO_HOST_INT32(theHeader.ModificationTime); - theHeader.TrackID = B_BENDIAN_TO_HOST_INT32(theHeader.TrackID); - theHeader.Duration = B_BENDIAN_TO_HOST_INT32(theHeader.Duration); - theHeader.Layer = B_BENDIAN_TO_HOST_INT16(theHeader.Layer); - theHeader.AlternateGroup = B_BENDIAN_TO_HOST_INT16(theHeader.AlternateGroup); - theHeader.Volume = B_BENDIAN_TO_HOST_INT16(theHeader.Volume); - theHeader.TrackWidth = B_BENDIAN_TO_HOST_INT32(theHeader.TrackWidth); - theHeader.TrackHeight = B_BENDIAN_TO_HOST_INT32(theHeader.TrackHeight); } char *TKHDAtom::OnGetAtomName() @@ -1232,7 +1238,7 @@ char *MDHDAtom::OnGetAtomName() bigtime_t MDHDAtom::getDuration() { - return (bigtime_t(theHeader.Duration) * 1000000) / (theHeader.TimeScale); + return bigtime_t((uint64(theHeader.Duration) * 1000000L) / theHeader.TimeScale); } uint32 MDHDAtom::getTimeScale() diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h index 00d058bcb6..e0101ca063 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h @@ -168,13 +168,15 @@ public: void OnProcessMetaData(); char *OnGetAtomName(); - uint64 getSUMCounts(); - uint64 getSUMDurations(); + uint64 getSUMCounts() {return SUMCounts;}; + uint64 getSUMDurations() {return SUMDurations;}; uint32 getSampleForTime(uint32 pTime); uint32 getSampleForFrame(uint32 pFrame); private: array_header theHeader; TimeToSampleArray theTimeToSampleArray; + uint64 SUMDurations; + uint64 SUMCounts; }; // Atom class for reading the sample to chunk atom @@ -292,9 +294,19 @@ public: char *OnGetAtomName(); uint32 getDuration() {return theHeader.Duration;}; // duration is in the scale of the media - + + // Flags3 should contain the following + // 0x001 Track enabled + // 0x002 Track in Movie + // 0x004 Track in Preview + // 0x008 Track in Poster + // It seems active tracks have all 4 flags set? + + bool IsActive() {return (theHeader.Flags3 == 0x0f);}; + private: - tkhd theHeader; + tkhdV1 theHeader; + uint8 Version; }; @@ -361,6 +373,7 @@ public: uint32 getNoSamplesInChunk(uint32 pChunkID); bool IsSyncSample(uint32 pSampleNo); bool IsSingleSampleSize(); + bool IsActive(); TKHDAtom *getTKHDAtom(); MDHDAtom *getMDHDAtom(); diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVTrakAtom.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVTrakAtom.cpp index b04fb690dd..570d134dc4 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVTrakAtom.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVTrakAtom.cpp @@ -77,7 +77,7 @@ bigtime_t TRAKAtom::Duration(uint32 TimeScale) return getMDHDAtom()->getDuration(); } - return bigtime_t(getTKHDAtom()->getDuration() * 1000000) / TimeScale; + return bigtime_t(getTKHDAtom()->getDuration() * 1000000L) / TimeScale; } void TRAKAtom::OnChildProcessingComplete() @@ -221,5 +221,10 @@ bool TRAKAtom::IsSingleSampleSize() return false; } +bool TRAKAtom::IsActive() +{ + return getTKHDAtom()->IsActive(); +} + // GetAudioMetaData() // If this is a audio track get the audio meta data // GetVideoMetaData() // If this is a video track get the video meta data diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h b/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h index db4da33abb..1a1b03d596 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h @@ -179,8 +179,7 @@ struct mvhd { uint32 NextTrackID; }; -struct tkhd { - uint8 Version; +struct tkhdV0 { uint8 Flags1; uint8 Flags2; uint8 Flags3; @@ -199,6 +198,25 @@ struct tkhd { uint32 TrackHeight; }; +struct tkhdV1 { + uint8 Flags1; + uint8 Flags2; + uint8 Flags3; + uint64 CreationTime; + uint64 ModificationTime; + uint32 TrackID; + uint32 Reserved1; + uint32 Duration; + uint64 Reserved2; + uint16 Layer; + uint16 AlternateGroup; + uint16 Volume; + uint16 Reserved3; + uint8 MatrixStructure[36]; + uint32 TrackWidth; + uint32 TrackHeight; +}; + struct mdhd { uint8 Version; uint8 Flags1; diff --git a/src/add-ons/media/plugins/mov_reader/mov_reader.cpp b/src/add-ons/media/plugins/mov_reader/mov_reader.cpp index 3c3e63e932..50ad382268 100644 --- a/src/add-ons/media/plugins/mov_reader/mov_reader.cpp +++ b/src/add-ons/media/plugins/mov_reader/mov_reader.cpp @@ -146,11 +146,17 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) BMediaFormats formats; media_format *format = &cookie->format; media_format_description description; + + if (theFileReader->IsActive(cookie->stream) == false) { + ERROR("movReader::AllocateCookie: stream %d is not active\n", cookie->stream); + delete cookie; + return B_ERROR; + } const mov_stream_header *stream_header; stream_header = theFileReader->StreamFormat(cookie->stream); if (!stream_header) { - ERROR("movReader::GetStreamInfo: stream %d has no header\n", cookie->stream); + ERROR("movReader::AllocateCookie: stream %d has no header\n", cookie->stream); delete cookie; return B_ERROR; } @@ -160,13 +166,13 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) if (theFileReader->IsAudio(cookie->stream)) { const AudioMetaData *audio_format = theFileReader->AudioFormat(cookie->stream); if (!audio_format) { - ERROR("movReader::GetStreamInfo: audio stream %d has no format\n", cookie->stream); + ERROR("movReader::AllocateCookie: audio stream %d has no format\n", cookie->stream); delete cookie; return B_ERROR; } - cookie->frame_count = theFileReader->getAudioFrameCount(); - cookie->duration = theFileReader->getAudioDuration(); + cookie->frame_count = theFileReader->getAudioFrameCount(cookie->stream); + cookie->duration = theFileReader->getAudioDuration(cookie->stream); cookie->audio = true; cookie->byte_pos = 0; @@ -336,7 +342,7 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) if (theFileReader->IsVideo(cookie->stream)) { const VideoMetaData *video_format = theFileReader->VideoFormat(cookie->stream); if (!video_format) { - ERROR("movReader::GetStreamInfo: video stream %d has no format\n", cookie->stream); + ERROR("movReader::AllocateCookie: video stream %d has no format\n", cookie->stream); delete cookie; return B_ERROR; } @@ -363,6 +369,7 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) TRACE("frame_count %Ld\n", cookie->frame_count); TRACE("duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration); + TRACE("compression %s\n", &video_format->compression); description.family = B_QUICKTIME_FORMAT_FAMILY; if (stream_header->fourcc_handler == 'ekaf' || stream_header->fourcc_handler == 0) // 'fake' or 0 fourcc => used compression id