diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.cpp index f4d70137ab..2d859aa4d3 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.cpp @@ -86,7 +86,7 @@ bool AtomBase::MoveToEnd() off_t NewPosition = streamOffset + atomSize; if (getStream()->Position() != NewPosition) { - return (getStream()->Seek(NewPosition,0) > 0); + return (getStream()->Seek(NewPosition,SEEK_SET) > 0); } return true; } diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.h b/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.h index bcf445b127..4faecb4abe 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVAtom.h @@ -104,6 +104,8 @@ public: off_t getAtomOffset() {return atomOffset;}; off_t getStreamOffset() {return streamOffset;}; + uint64 getDataSize() {return atomSize - 8;}; + uint64 getBytesRemaining(); bool IsType(uint32 patomType) {return patomType == atomType;}; 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 70c872cee9..b8241de963 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp @@ -459,6 +459,9 @@ const AudioMetaData *MOVFileReader::AudioFormat(uint32 stream_index, size_t * theAudio.SampleSize = aSoundDescription.desc.SampleSize; theAudio.SampleRate = aSoundDescription.desc.SampleRate / 65536; // Convert from fixed point decimal to float theAudio.PacketSize = uint32((theAudio.SampleRate * theAudio.NoOfChannels * theAudio.SampleSize) / 8); + + theAudio.theVOL = aSoundDescription.theVOL; + theAudio.VOLSize = aSoundDescription.VOLSize; // // Do we have a wave structure // if ((aSoundDescription.samplesPerPacket == 0) && (aSoundDescription.theWaveFormat.format_tag != 0)) { @@ -502,6 +505,9 @@ const VideoMetaData *MOVFileReader::VideoFormat(uint32 stream_index) theVideo.HorizontalResolution = aVideoDescriptionV0.desc.HorizontalResolution; theVideo.VerticalResolution = aVideoDescriptionV0.desc.VerticalResolution; + theVideo.theVOL = aVideoDescriptionV0.theVOL; + theVideo.VOLSize = aVideoDescriptionV0.VOLSize; + aAtomBase = aTrakAtom->GetChildAtom(uint32('stts'),0); if (aAtomBase) { STTSAtom *aSTTSAtom = dynamic_cast(aAtomBase); 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 6fab837ba6..e8ad3b50f8 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp @@ -173,6 +173,10 @@ AtomBase *getAtom(BPositionIO *pStream) return new CMVDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); } + if (aAtomType == uint32('esds')) { + return new ESDSAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); + } + return new AtomBase(pStream, aStreamOffset, aAtomType, aRealAtomSize); } @@ -718,6 +722,34 @@ uint64 STCOAtom::getOffsetForChunk(uint32 pChunkID) return 0LL; } +ESDSAtom::ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) +{ + theVOL = NULL; +} + +ESDSAtom::~ESDSAtom() +{ + if (theVOL) { + free(theVOL); + } +} + +void ESDSAtom::OnProcessMetaData() +{ + theVOL = (uint8 *)(malloc(getBytesRemaining())); + Read(theVOL,getBytesRemaining()); +} + +uint8 *ESDSAtom::getVOL() +{ + return theVOL; +} + +char *ESDSAtom::OnGetAtomName() +{ + return "Extended Sample Description Atom"; +} + STSDAtom::STSDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) { theHeader.NoEntries = 0; @@ -727,11 +759,21 @@ STSDAtom::~STSDAtom() { if (getMediaComponentSubType() == 'soun') { for (uint32 i=0;itheVOL) { + free(theAudioDescArray[i]->theVOL); + theAudioDescArray[i]->theVOL = NULL; + } + delete theAudioDescArray[i]; theAudioDescArray[i] = NULL; } } else if (getMediaComponentSubType() == 'vide') { for (uint32 i=0;itheVOL) { + free(theVideoDescArray[i]->theVOL); + theVideoDescArray[i]->theVOL = NULL; + } + delete theVideoDescArray[i]; theVideoDescArray[i] = NULL; } @@ -755,6 +797,9 @@ void STSDAtom::ReadSoundDescription() Read(aSoundDescriptionV1->basefields.Reserved,6); Read(&aSoundDescriptionV1->basefields.DataReference); + aSoundDescriptionV1->VOLSize = 0; + aSoundDescriptionV1->theVOL = NULL; + // Read in Audio Sample Data // We place into a V1 description even though it might be a V0 or earlier @@ -802,7 +847,14 @@ void STSDAtom::ReadSoundDescription() // WAVE atom aSoundDescriptionV1->theWaveFormat = dynamic_cast(aAtomBase)->getWaveFormat(); } - + + if (dynamic_cast(aAtomBase)) { + // ESDS atom good + aSoundDescriptionV1->VOLSize = aAtomBase->getDataSize(); + aSoundDescriptionV1->theVOL = (uint8 *)(malloc(aSoundDescriptionV1->VOLSize)); + memcpy(aSoundDescriptionV1->theVOL,dynamic_cast(aAtomBase)->getVOL(),aSoundDescriptionV1->VOLSize); + } + if (aAtomBase->getAtomSize() > 0) { descBytesLeft = descBytesLeft - aAtomBase->getAtomSize(); } else { @@ -811,7 +863,6 @@ void STSDAtom::ReadSoundDescription() } delete aAtomBase; - } theAudioDescArray[0] = aSoundDescriptionV1; @@ -821,6 +872,8 @@ void STSDAtom::ReadSoundDescription() void STSDAtom::ReadVideoDescription() { + uint64 descBytesLeft; + // read in Video Sample Data VideoDescriptionV0 *aVideoDescription; @@ -830,7 +883,7 @@ void STSDAtom::ReadVideoDescription() Read(&aVideoDescription->basefields.DataFormat); Read(aVideoDescription->basefields.Reserved,6); Read(&aVideoDescription->basefields.DataReference); - + Read(&aVideoDescription->desc.Version); Read(&aVideoDescription->desc.Revision); Read(&aVideoDescription->desc.Vendor); @@ -847,8 +900,38 @@ void STSDAtom::ReadVideoDescription() Read(&aVideoDescription->desc.Depth); Read(&aVideoDescription->desc.ColourTableID); + aVideoDescription->VOLSize = 0; + aVideoDescription->theVOL = NULL; + theVideoDescArray[0] = aVideoDescription; + descBytesLeft = getBytesRemaining(); + + // May be a VOL + // If not then seek back to where we are as it may be a complete new video description + + if (descBytesLeft > 0) { + + off_t pos = theStream->Position(); + // More extended atoms + AtomBase *aAtomBase = getAtom(theStream); + + aAtomBase->OnProcessMetaData(); + printf("%s\n",aAtomBase->getAtomName()); + + if (dynamic_cast(aAtomBase)) { + // ESDS atom good + aVideoDescription->VOLSize = aAtomBase->getDataSize(); + aVideoDescription->theVOL = (uint8 *)(malloc(aVideoDescription->VOLSize)); + memcpy(aVideoDescription->theVOL,dynamic_cast(aAtomBase)->getVOL(),aVideoDescription->VOLSize); + } else { + // Seek Back + theStream->Seek(pos,SEEK_SET); + } + + delete aAtomBase; + } + PRINT(("Size:Format=%ld:%ld %Ld\n",aVideoDescription->basefields.Size,aVideoDescription->basefields.DataFormat,getBytesRemaining())); } @@ -872,8 +955,10 @@ void STSDAtom::OnProcessMetaData() Read(&aSampleDescBase.DataFormat); Read(aSampleDescBase.Reserved,6); Read(&aSampleDescBase.DataReference); + + printf("%c%c%c%c\n",char(aSampleDescBase.DataFormat>>24),char(aSampleDescBase.DataFormat>>16),char(aSampleDescBase.DataFormat>>8),char(aSampleDescBase.DataFormat)); - theStream->Seek(aSampleDescBase.Size - SampleDescBaseSize, 0); + theStream->Seek(aSampleDescBase.Size - SampleDescBaseSize, SEEK_CUR); break; } } 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 44ae524aea..de14d7fb48 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.h @@ -254,6 +254,18 @@ public: off_t getEOF(); }; +class ESDSAtom : public AtomBase { +public: + ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); + virtual ~ESDSAtom(); + void OnProcessMetaData(); + char *OnGetAtomName(); + + uint8 *getVOL(); +private: + uint8 *theVOL; +}; + // Atom class for reading the sdst atom class STSDAtom : public AtomBase { public: @@ -293,7 +305,7 @@ public: // 0x008 Track in Poster // It seems active tracks have all 4 flags set? - bool IsActive() {return (theHeader.Flags3 == 0x0f);}; + bool IsActive() {return ((theHeader.Flags3 == 0x0f) || (theHeader.Flags3 == 0x03));}; private: tkhdV1 theHeader; 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 74766550f6..4298d48b1e 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h @@ -92,6 +92,8 @@ struct VideoMetaData uint32 HorizontalResolution; uint32 VerticalResolution; float FrameRate; + uint8 *theVOL; + size_t VOLSize; }; struct AudioMetaData @@ -101,6 +103,8 @@ struct AudioMetaData uint16 SampleSize; // bits per sample float SampleRate; // Samples per second (OR Frames per second) uint32 PacketSize; // (Sample Rate * NoOfchannels * SampleSize)/8 = bytes per second + uint8 *theVOL; + size_t VOLSize; }; struct wave_format_ex @@ -306,6 +310,8 @@ struct SoundDescriptionV1 { uint32 bytesPerSample; // These are optional data from atoms that follow wave_format_ex theWaveFormat; // wave atom is a copy of wave_format_ex + uint8 *theVOL; + size_t VOLSize; }; struct VideoDescription { @@ -331,4 +337,6 @@ struct VideoDescription { struct VideoDescriptionV0 { SampleDescBase basefields; VideoDescription desc; + uint8 *theVOL; + size_t VOLSize; }; 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 b51f0c9999..9446bba741 100644 --- a/src/add-ons/media/plugins/mov_reader/mov_reader.cpp +++ b/src/add-ons/media/plugins/mov_reader/mov_reader.cpp @@ -402,6 +402,14 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) TRACE("max_bit_rate %.3f\n", format->u.encoded_video.max_bit_rate); TRACE("field_rate %.3f\n", format->u.encoded_video.output.field_rate); + // Set the VOL + if (video_format->VOLSize > 0) { + TRACE("VOL SIZE %ld\n", video_format->VOLSize); + size_t size = video_format->VOLSize; + const void *data = video_format->theVOL; + format->SetMetaData(data, size); + } + return B_OK; } diff --git a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Parser.cpp b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Parser.cpp index 843fbd3aba..2c895bf876 100644 --- a/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Parser.cpp +++ b/src/add-ons/media/plugins/mp4_reader/libMP4/MP4Parser.cpp @@ -899,7 +899,10 @@ uint64 STCOAtom::getOffsetForChunk(uint32 pChunkID) return theChunkToOffsetArray[pChunkID - 1]->Offset; } - DEBUGGER(("Bad Chunk ID %ld / %ld\n",pChunkID,theHeader.NoEntries)); + #if DEBUG + char msg[100]; sprintf(msg, "Bad Chunk ID %ld / %ld\n", pChunkID, theHeader.NoEntries); + DEBUGGER(msg); + #endif TRESPASS(); return 0LL; 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 d899f855f7..1259fd1b01 100644 --- a/src/add-ons/media/plugins/mp4_reader/mp4_reader.cpp +++ b/src/add-ons/media/plugins/mp4_reader/mp4_reader.cpp @@ -427,17 +427,19 @@ mp4Reader::AllocateCookie(int32 streamNumber, void **_cookie) TRACE("field_rate %.3f\n", format->u.encoded_video.output.field_rate); // Set the VOL - size_t size = video_format->VOLSize; - const void *data = video_format->theVOL; - format->SetMetaData(data, size); + if (video_format->VOLSize > 0) { + size_t size = video_format->VOLSize; + const void *data = video_format->theVOL; + format->SetMetaData(data, size); #ifdef TRACE_MP4_READER - if (data) { - uint8 *p = (uint8 *)data; - TRACE("extra_data: %ld: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - size, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]); - } + if (data) { + uint8 *p = (uint8 *)data; + TRACE("extra_data: %ld: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + size, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]); + } #endif + } return B_OK; }