Improvements to mov_reader still alpha

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13080 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul 2005-06-13 07:09:45 +00:00
parent 509db2a318
commit 011badde6b
10 changed files with 460 additions and 231 deletions

View File

@ -57,6 +57,8 @@ const struct codec_table gCodecTable[] = {
{CODEC_ID_WMAV2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x161, "MS WMA v2"}, {CODEC_ID_WMAV2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x161, "MS WMA v2"},
{CODEC_ID_CINEPAK, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('cvid'), "Cinepak Video"}, {CODEC_ID_CINEPAK, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('cvid'), "Cinepak Video"},
{CODEC_ID_CINEPAK, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, FOURCC('divc'), "Cinepak Video"},
{CODEC_ID_CINEPAK, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, FOURCC('cvid'), "Cinepak Video"},
{CODEC_ID_MSRLE, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('RLE '), "MS RLE"}, // ??? {CODEC_ID_MSRLE, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('RLE '), "MS RLE"}, // ???
{CODEC_ID_MSRLE, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('mrle'), "MS RLE"}, // ??? {CODEC_ID_MSRLE, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('mrle'), "MS RLE"}, // ???

View File

@ -1,3 +1,27 @@
/*
* Copyright (c) 2005, David McPaul
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h> #include <stdio.h>
#include "MOVAtom.h" #include "MOVAtom.h"
@ -8,11 +32,13 @@ AtomBase::AtomBase(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType,
streamOffset = pstreamOffset; streamOffset = pstreamOffset;
atomType = patomType; atomType = patomType;
atomSize = patomSize; atomSize = patomSize;
parentAtom = NULL;
} }
AtomBase::~AtomBase() AtomBase::~AtomBase()
{ {
theStream = NULL; theStream = NULL;
parentAtom = NULL;
} }
char *AtomBase::getAtomName() char *AtomBase::getAtomName()
@ -137,6 +163,7 @@ void AtomContainer::ProcessMetaData()
bool AtomContainer::AddChild(AtomBase *pChildAtom) bool AtomContainer::AddChild(AtomBase *pChildAtom)
{ {
if (pChildAtom) { if (pChildAtom) {
pChildAtom->setParent(this);
atomChildren[TotalChildren++] = pChildAtom; atomChildren[TotalChildren++] = pChildAtom;
return true; return true;
} }

View File

@ -1,3 +1,27 @@
/*
* Copyright (c) 2005, David McPaul
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MOV_ATOM_H #ifndef _MOV_ATOM_H
#define _MOV_ATOM_H #define _MOV_ATOM_H
@ -52,6 +76,7 @@ private:
uint32 atomType; uint32 atomType;
uint64 atomSize; uint64 atomSize;
char fourcc[5]; // make this an alias to atomType char fourcc[5]; // make this an alias to atomType
AtomBase *parentAtom;
protected: protected:
BPositionIO *theStream; BPositionIO *theStream;
@ -96,6 +121,9 @@ public:
// Many atoms use an array header // Many atoms use an array header
void ReadArrayHeader(array_header *pHeader); void ReadArrayHeader(array_header *pHeader);
void setParent(AtomBase *pParent) {parentAtom = pParent;};
AtomBase *getParent() { return parentAtom;};
}; };
class AtomContainer : public AtomBase { class AtomContainer : public AtomBase {

View File

@ -1,3 +1,27 @@
/*
* Copyright (c) 2005, David McPaul
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <iostream.h> #include <iostream.h>
#include <DataIO.h> #include <DataIO.h>
@ -261,12 +285,17 @@ uint64 MOVFileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo)
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo); uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
// Get Chunk For Sample and the offset for the frame within that chunk // Get Chunk For Sample and the offset for the frame within that chunk
uint32 OffsetInChunk; uint32 OffsetInChunk;
if (stream_index == 0) {
OffsetInChunk = 99;
}
uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk); uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
// Get Offset For Chunk // Get Offset For Chunk
// printf("Stream: %ld Frame %ld %ld <%ld/%ld> (",stream_index, pFrameNo, SampleNo, ChunkNo, OffsetInChunk);
uint64 OffsetNo = aTrakAtom->getOffsetForChunk(ChunkNo); uint64 OffsetNo = aTrakAtom->getOffsetForChunk(ChunkNo);
// printf("Frame %ld {%lld} <%ld/%ld> (",pFrameNo, OffsetNo, ChunkNo, OffsetInChunk); // printf("Frame %ld {%lld} <%ld/%ld> (",pFrameNo, OffsetNo, ChunkNo, OffsetInChunk);
if (ChunkNo != 0) {
uint32 SampleSize; uint32 SampleSize;
// Adjust the Offset for the Offset in the chunk // Adjust the Offset for the Offset in the chunk
for (uint32 i=1;i<=OffsetInChunk;i++) { for (uint32 i=1;i<=OffsetInChunk;i++) {
@ -275,8 +304,9 @@ uint64 MOVFileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo)
OffsetNo = OffsetNo + SampleSize; OffsetNo = OffsetNo + SampleSize;
} }
// printf(") %lld\n",OffsetNo); // printf(") %lld\n",OffsetNo);
}
// printf("%ld:%ld:%ld:%lld\n",pFrameNo, SampleNo, ChunkNo, OffsetNo); // printf("%ld:%ld:%ld:%lld\n",pFrameNo, SampleNo, ChunkNo, OffsetNo);
// printf("\n");
return OffsetNo; return OffsetNo;
} }

View File

@ -1,3 +1,27 @@
/*
* Copyright (c) 2005, David McPaul
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MOV_FILE_READER_H #ifndef _MOV_FILE_READER_H
#define _MOV_FILE_READER_H #define _MOV_FILE_READER_H

View File

@ -1,3 +1,27 @@
/*
* Copyright (c) 2005, David McPaul
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h> #include <stdio.h>
#include <DataIO.h> #include <DataIO.h>
@ -6,45 +30,6 @@
#include "MOVParser.h" #include "MOVParser.h"
struct mov_codec_table
{
int id;
media_type type;
uint32 fourcc;
};
static const uint32 num_codecs = 27;
static const mov_codec_table theCodecTable[num_codecs] =
{
{1,B_MEDIA_ENCODED_VIDEO,'3IV1'},
{2,B_MEDIA_ENCODED_VIDEO,'3IV2'},
{3,B_MEDIA_ENCODED_VIDEO,'MP4V'},
{4,B_MEDIA_ENCODED_VIDEO,'mp4v'},
{5,B_MEDIA_ENCODED_VIDEO,'RMP4'},
{6,B_MEDIA_ENCODED_VIDEO,'dm4v'},
{7,B_MEDIA_ENCODED_VIDEO,'UMP4'},
{8,B_MEDIA_ENCODED_VIDEO,'MP4S'},
{9,B_MEDIA_ENCODED_AUDIO,AUDIO_NONE},
{10,B_MEDIA_ENCODED_AUDIO,AUDIO_RAW},
{11,B_MEDIA_ENCODED_AUDIO,AUDIO_TWOS1},
{12,B_MEDIA_ENCODED_AUDIO,AUDIO_TWOS2},
{13,B_MEDIA_ENCODED_AUDIO,'.mp3'},
{14,B_MEDIA_ENCODED_AUDIO,AUDIO_IMA4},
{15,B_MEDIA_ENCODED_AUDIO,'fl32'},
{16,B_MEDIA_ENCODED_AUDIO,'fl64'},
{17,B_MEDIA_ENCODED_AUDIO,'in24'},
{18,B_MEDIA_ENCODED_AUDIO,'in32'},
{19,B_MEDIA_ENCODED_AUDIO,'ulaw'},
{20,B_MEDIA_ENCODED_AUDIO,'alaw'},
{21,B_MEDIA_ENCODED_AUDIO,'dvca'},
{22,B_MEDIA_ENCODED_AUDIO,'QDMC'},
{23,B_MEDIA_ENCODED_AUDIO,AUDIO_MS_PCM02},
{24,B_MEDIA_ENCODED_AUDIO,AUDIO_INTEL_PCM17},
{25,B_MEDIA_ENCODED_AUDIO,'mp4a'},
{26,B_MEDIA_ENCODED_AUDIO,AUDIO_MPEG3_CBR},
{27,B_MEDIA_ENCODED_VIDEO,'avc1'},
};
//static //static
AtomBase *getAtom(BPositionIO *pStream) AtomBase *getAtom(BPositionIO *pStream)
{ {
@ -356,16 +341,32 @@ SampleToChunk *aSampleToChunk;
ReadArrayHeader(&theHeader); ReadArrayHeader(&theHeader);
uint32 TotalPrevFrames = 0;
for (uint32 i=0;i<theHeader.NoEntries;i++) { for (uint32 i=0;i<theHeader.NoEntries;i++) {
aSampleToChunk = new SampleToChunk; aSampleToChunk = new SampleToChunk;
theStream->Read(aSampleToChunk,sizeof(SampleToChunk)); theStream->Read(&aSampleToChunk->FirstChunk,sizeof(uint32));
theStream->Read(&aSampleToChunk->SamplesPerChunk,sizeof(uint32));
theStream->Read(&aSampleToChunk->SampleDescriptionID,sizeof(uint32));
aSampleToChunk->FirstChunk = B_BENDIAN_TO_HOST_INT32(aSampleToChunk->FirstChunk); aSampleToChunk->FirstChunk = B_BENDIAN_TO_HOST_INT32(aSampleToChunk->FirstChunk);
aSampleToChunk->SamplesPerChunk = B_BENDIAN_TO_HOST_INT32(aSampleToChunk->SamplesPerChunk); aSampleToChunk->SamplesPerChunk = B_BENDIAN_TO_HOST_INT32(aSampleToChunk->SamplesPerChunk);
aSampleToChunk->SampleDescriptionID = B_BENDIAN_TO_HOST_INT32(aSampleToChunk->SampleDescriptionID); aSampleToChunk->SampleDescriptionID = B_BENDIAN_TO_HOST_INT32(aSampleToChunk->SampleDescriptionID);
if (i > 0) {
TotalPrevFrames = TotalPrevFrames + (aSampleToChunk->FirstChunk - theSampleToChunkArray[i-1]->FirstChunk) * theSampleToChunkArray[i-1]->SamplesPerChunk;
aSampleToChunk->TotalPrevFrames = TotalPrevFrames;
} else {
aSampleToChunk->TotalPrevFrames = 0;
}
// printf("First Chunk/Samples Per Chunk/ID %ld/%ld/%ld (%ld)\n",aSampleToChunk->FirstChunk,aSampleToChunk->SamplesPerChunk,aSampleToChunk->SampleDescriptionID,aSampleToChunk->TotalPrevFrames);
theSampleToChunkArray[i] = aSampleToChunk; theSampleToChunkArray[i] = aSampleToChunk;
} }
// printf("Sample To Chunk Array contains %ld Entries\n",theHeader.NoEntries);
} }
char *STSCAtom::OnGetAtomName() char *STSCAtom::OnGetAtomName()
@ -375,18 +376,28 @@ char *STSCAtom::OnGetAtomName()
uint32 STSCAtom::getChunkForSample(uint32 pSample, uint32 *pOffsetInChunk) uint32 STSCAtom::getChunkForSample(uint32 pSample, uint32 *pOffsetInChunk)
{ {
uint32 SampleNo = 0; uint32 ChunkID = 0;
uint32 OffsetInChunk = 0;
for (uint32 i=0;i<theHeader.NoEntries;i++) { for (int32 i=theHeader.NoEntries-1;i>=0;i--) {
SampleNo += theSampleToChunkArray[i]->SamplesPerChunk; if (pSample >= theSampleToChunkArray[i]->TotalPrevFrames) {
if (SampleNo > pSample) { // Found chunk now calculate offset
// printf("*%ld %ld %ld %ld\n",SampleNo, pSample, theSampleToChunkArray[i]->SamplesPerChunk, theSampleToChunkArray[i]->FirstChunk); ChunkID = (pSample - theSampleToChunkArray[i]->TotalPrevFrames) / theSampleToChunkArray[i]->SamplesPerChunk;
*pOffsetInChunk = theSampleToChunkArray[i]->SamplesPerChunk - (SampleNo - pSample); ChunkID += theSampleToChunkArray[i]->FirstChunk;
return theSampleToChunkArray[i]->FirstChunk;
OffsetInChunk = (pSample - theSampleToChunkArray[i]->TotalPrevFrames) % theSampleToChunkArray[i]->SamplesPerChunk;
if (*pOffsetInChunk == 99) {
// printf("%ld (%ld/%ld)\n",pSample, ChunkID, OffsetInChunk);
}
*pOffsetInChunk = OffsetInChunk;
return ChunkID;
} }
} }
return 0; *pOffsetInChunk = 0;
return theSampleToChunkArray[theHeader.NoEntries-1]->FirstChunk;
} }
STSSAtom::STSSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) STSSAtom::STSSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
@ -529,6 +540,8 @@ ChunkToOffset *aChunkToOffset;
theChunkToOffsetArray[i] = aChunkToOffset; theChunkToOffsetArray[i] = aChunkToOffset;
} }
printf("Chunk to Offset Array has %ld entries\n",theHeader.NoEntries);
} }
char *STCOAtom::OnGetAtomName() char *STCOAtom::OnGetAtomName()
@ -538,6 +551,8 @@ char *STCOAtom::OnGetAtomName()
uint64 STCOAtom::getOffsetForChunk(uint32 pChunkID) uint64 STCOAtom::getOffsetForChunk(uint32 pChunkID)
{ {
// printf("?Chunk ID %ld / %ld\n",pChunkID,theHeader.NoEntries);
// First chunk is first array entry // First chunk is first array entry
if ((pChunkID > 0) && (pChunkID <= theHeader.NoEntries)) { if ((pChunkID > 0) && (pChunkID <= theHeader.NoEntries)) {
return theChunkToOffsetArray[pChunkID - 1]->Offset; return theChunkToOffsetArray[pChunkID - 1]->Offset;
@ -546,6 +561,7 @@ uint64 STCOAtom::getOffsetForChunk(uint32 pChunkID)
printf("Bad Chunk ID %ld / %ld\n",pChunkID,theHeader.NoEntries); printf("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 :-( // 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[pChunkID - 1]->Offset;
// return theChunkToOffsetArray[0]->Offset;
} }
STSDAtom::STSDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) STSDAtom::STSDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
@ -555,12 +571,12 @@ STSDAtom::STSDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType,
STSDAtom::~STSDAtom() STSDAtom::~STSDAtom()
{ {
if (IsAudioSampleDesc(DataFormat)) { if (getMediaComponentSubType() == 'soun') {
for (uint32 i=0;i<theHeader.NoEntries;i++) { for (uint32 i=0;i<theHeader.NoEntries;i++) {
delete theAudioDescArray[i]; delete theAudioDescArray[i];
theAudioDescArray[i] = NULL; theAudioDescArray[i] = NULL;
} }
} else { } else if (getMediaComponentSubType() == 'vide') {
for (uint32 i=0;i<theHeader.NoEntries;i++) { for (uint32 i=0;i<theHeader.NoEntries;i++) {
delete theVideoDescArray[i]; delete theVideoDescArray[i];
theVideoDescArray[i] = NULL; theVideoDescArray[i] = NULL;
@ -568,82 +584,31 @@ STSDAtom::~STSDAtom()
} }
} }
bool STSDAtom::IsAudioSampleDesc(uint32 pDataFormat) uint32 STSDAtom::getMediaComponentSubType()
{ {
char dcc[5]; return dynamic_cast<STBLAtom *>(getParent())->getMediaComponentSubType();
dcc[0] = (char)((pDataFormat >> 24) & 0xff);
dcc[1] = (char)((pDataFormat >> 16) & 0xff);
dcc[2] = (char)((pDataFormat >> 8) & 0xff);
dcc[3] = (char)((pDataFormat >> 0) & 0xff);
dcc[4] = '\0';
printf("%s\n",dcc);
for (uint32 i=0;i<num_codecs;i++) {
if (theCodecTable[i].fourcc == pDataFormat) {
if (theCodecTable[i].type == B_MEDIA_ENCODED_AUDIO) {
return true;
}
}
} }
return false; void STSDAtom::ReadSoundDescription()
}
bool STSDAtom::IsVideoSampleDesc(uint32 pDataFormat)
{
char dcc[5];
dcc[0] = (char)((pDataFormat >> 24) & 0xff);
dcc[1] = (char)((pDataFormat >> 16) & 0xff);
dcc[2] = (char)((pDataFormat >> 8) & 0xff);
dcc[3] = (char)((pDataFormat >> 0) & 0xff);
dcc[4] = '\0';
printf("%s\n",dcc);
for (uint32 i=0;i<num_codecs;i++) {
if (theCodecTable[i].fourcc == pDataFormat) {
if (theCodecTable[i].type == B_MEDIA_ENCODED_VIDEO) {
return true;
}
}
}
return false;
}
void STSDAtom::OnProcessMetaData()
{ {
uint32 descBytesLeft; uint32 descBytesLeft;
ReadArrayHeader(&theHeader);
SampleDescBase aSampleDesc;
printf("Entries=%ld\n",theHeader.NoEntries);
for (uint32 i=0;i<theHeader.NoEntries;i++) {
theStream->Read(&aSampleDesc,sizeof(SampleDescBase));
aSampleDesc.Size = B_BENDIAN_TO_HOST_INT32(aSampleDesc.Size);
aSampleDesc.DataFormat = B_BENDIAN_TO_HOST_INT32(aSampleDesc.DataFormat);
aSampleDesc.DataReference = B_BENDIAN_TO_HOST_INT16(aSampleDesc.DataReference);
descBytesLeft = aSampleDesc.Size - sizeof(SampleDescBase);
// Hmm this should be ok if each stsd describes only a single type
DataFormat = aSampleDesc.DataFormat;
if (IsAudioSampleDesc(aSampleDesc.DataFormat)) {
// Read in Audio Sample Data
// We place into a V1 description even though it might be a V0 or earlier
SoundDescriptionV1 *aSoundDescriptionV1; SoundDescriptionV1 *aSoundDescriptionV1;
aSoundDescriptionV1 = new SoundDescriptionV1; aSoundDescriptionV1 = new SoundDescriptionV1;
aSoundDescriptionV1->basefields.Size = aSampleDesc.Size; theStream->Read(&aSoundDescriptionV1->basefields,sizeof(SampleDescBase));
aSoundDescriptionV1->basefields.DataFormat = aSampleDesc.DataFormat;
aSoundDescriptionV1->basefields.DataReference = aSampleDesc.DataReference; aSoundDescriptionV1->basefields.Size = B_BENDIAN_TO_HOST_INT32(aSoundDescriptionV1->basefields.Size);
aSoundDescriptionV1->basefields.DataFormat = B_BENDIAN_TO_HOST_INT32(aSoundDescriptionV1->basefields.DataFormat);
aSoundDescriptionV1->basefields.DataReference = B_BENDIAN_TO_HOST_INT16(aSoundDescriptionV1->basefields.DataReference);
descBytesLeft = aSoundDescriptionV1->basefields.Size - sizeof(SampleDescBase);
// Hmm this should be ok if each stsd describes only a single type
DataFormat = aSoundDescriptionV1->basefields.DataFormat;
// Read in Audio Sample Data
// We place into a V1 description even though it might be a V0 or earlier
theStream->Read(&aSoundDescriptionV1->desc,sizeof(SoundDescription)); theStream->Read(&aSoundDescriptionV1->desc,sizeof(SoundDescription));
descBytesLeft = descBytesLeft - sizeof(SoundDescription); descBytesLeft = descBytesLeft - sizeof(SoundDescription);
@ -704,20 +669,27 @@ void STSDAtom::OnProcessMetaData()
} }
theAudioDescArray[i] = aSoundDescriptionV1; theAudioDescArray[0] = aSoundDescriptionV1;
theStream->Seek(descBytesLeft,0); theStream->Seek(descBytesLeft,0);
} else { printf("Size:Format=%ld:%ld %ld\n",aSoundDescriptionV1->basefields.Size,aSoundDescriptionV1->basefields.DataFormat,descBytesLeft);
if (IsVideoSampleDesc(aSampleDesc.DataFormat)) { }
void STSDAtom::ReadVideoDescription()
{
// read in Video Sample Data // read in Video Sample Data
uint32 descBytesLeft;
VideoDescriptionV0 *aVideoDescription; VideoDescriptionV0 *aVideoDescription;
aVideoDescription = new VideoDescriptionV0; aVideoDescription = new VideoDescriptionV0;
aVideoDescription->basefields.Size = aSampleDesc.Size; theStream->Read(&aVideoDescription->basefields,sizeof(SampleDescBase));
aVideoDescription->basefields.DataFormat = aSampleDesc.DataFormat; aVideoDescription->basefields.Size = B_BENDIAN_TO_HOST_INT32(aVideoDescription->basefields.Size);
aVideoDescription->basefields.DataReference = aSampleDesc.DataReference; aVideoDescription->basefields.DataFormat = B_BENDIAN_TO_HOST_INT32(aVideoDescription->basefields.DataFormat);
aVideoDescription->basefields.DataReference = B_BENDIAN_TO_HOST_INT16(aVideoDescription->basefields.DataReference);
descBytesLeft = aVideoDescription->basefields.Size - sizeof(SampleDescBase);
theStream->Read(&(aVideoDescription->desc),sizeof(VideoDescription)); theStream->Read(&(aVideoDescription->desc),sizeof(VideoDescription));
@ -737,21 +709,41 @@ void STSDAtom::OnProcessMetaData()
descBytesLeft = descBytesLeft - sizeof(VideoDescription); descBytesLeft = descBytesLeft - sizeof(VideoDescription);
theVideoDescArray[i] = aVideoDescription; theVideoDescArray[0] = aVideoDescription;
// We seem to have read 2 bytes too many??? // We seem to have read 2 bytes too many???
theStream->Seek(descBytesLeft,0); theStream->Seek(descBytesLeft,0);
}
printf("Size:Format=%ld:%ld %ld\n",aVideoDescription->basefields.Size,aVideoDescription->basefields.DataFormat,descBytesLeft);
} }
printf("Size:Format=%ld:%ld %ld\n",aSampleDesc.Size,aSampleDesc.DataFormat,descBytesLeft); void STSDAtom::OnProcessMetaData()
{
ReadArrayHeader(&theHeader);
for (uint32 i=0;i<theHeader.NoEntries;i++) {
switch (getMediaComponentSubType()) {
case 'soun':
ReadSoundDescription();
break;
case 'vide':
ReadVideoDescription();
break;
default:
// Skip
SampleDescBase aSampleDescBase;
theStream->Read(&aSampleDescBase,sizeof(SampleDescBase));
aSampleDescBase.Size = B_BENDIAN_TO_HOST_INT32(aSampleDescBase.Size);
theStream->Seek(aSampleDescBase.Size - sizeof(SampleDescBase),0);
break;
}
} }
} }
VideoDescriptionV0 STSDAtom::getAsVideo() VideoDescriptionV0 STSDAtom::getAsVideo()
{ {
// Assert IsVideo - how will we handle multiples // Assert IsVideo - how will we handle multiples
return *theVideoDescArray[0]; return *theVideoDescArray[0];
} }
@ -929,6 +921,11 @@ char *MINFAtom::OnGetAtomName()
return "Quicktime Media Information Atom"; return "Quicktime Media Information Atom";
} }
uint32 MINFAtom::getMediaComponentSubType()
{
return dynamic_cast<MDIAAtom *>(getParent())->getMediaComponentSubType();
}
STBLAtom::STBLAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize) STBLAtom::STBLAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)
{ {
} }
@ -946,6 +943,11 @@ char *STBLAtom::OnGetAtomName()
return "Quicktime Sample Table Atom"; return "Quicktime Sample Table Atom";
} }
uint32 STBLAtom::getMediaComponentSubType()
{
return dynamic_cast<MINFAtom *>(getParent())->getMediaComponentSubType();
}
DINFAtom::DINFAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize) DINFAtom::DINFAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)
{ {
} }
@ -1008,6 +1010,19 @@ char *MDIAAtom::OnGetAtomName()
return "Quicktime Media Atom"; return "Quicktime Media Atom";
} }
uint32 MDIAAtom::getMediaComponentSubType()
{
// get child atom hdlr
HDLRAtom *aHDLRAtom;
aHDLRAtom = dynamic_cast<HDLRAtom *>(GetChildAtom(uint32('hdlr')));
if (aHDLRAtom) {
return aHDLRAtom->getMediaComponentSubType();
}
return 0;
}
MDHDAtom::MDHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) MDHDAtom::MDHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
{ {
} }
@ -1053,8 +1068,13 @@ HDLRAtom::~HDLRAtom()
void HDLRAtom::OnProcessMetaData() void HDLRAtom::OnProcessMetaData()
{ {
hdlr aHeader; theStream->Read(&theHeader,sizeof(hdlr));
theStream->Read(&aHeader,sizeof(hdlr)); theHeader.ComponentType = B_BENDIAN_TO_HOST_INT32(theHeader.ComponentType);
theHeader.ComponentSubType = B_BENDIAN_TO_HOST_INT32(theHeader.ComponentSubType);
theHeader.ComponentManufacturer = B_BENDIAN_TO_HOST_INT32(theHeader.ComponentManufacturer);
theHeader.ComponentFlags = B_BENDIAN_TO_HOST_INT32(theHeader.ComponentFlags);
theHeader.ComponentFlagsMask = B_BENDIAN_TO_HOST_INT32(theHeader.ComponentFlagsMask);
// Read Array of Strings? // Read Array of Strings?
} }
@ -1063,6 +1083,21 @@ char *HDLRAtom::OnGetAtomName()
return "Quicktime Handler Reference Atom "; return "Quicktime Handler Reference Atom ";
} }
bool HDLRAtom::IsVideoHandler()
{
return (theHeader.ComponentSubType == 'vide');
}
bool HDLRAtom::IsAudioHandler()
{
return (theHeader.ComponentSubType == 'soun');
}
uint32 HDLRAtom::getMediaComponentSubType()
{
return theHeader.ComponentSubType;
}
VMHDAtom::VMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) VMHDAtom::VMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
{ {
} }

View File

@ -1,3 +1,27 @@
/*
* Copyright (c) 2005, David McPaul
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MOV_PARSER_H #ifndef _MOV_PARSER_H
#define _MOV_PARSER_H #define _MOV_PARSER_H
@ -206,8 +230,10 @@ public:
SoundDescriptionV1 getAsAudio(); SoundDescriptionV1 getAsAudio();
private: private:
bool IsAudioSampleDesc(uint32 pDataFormat); uint32 getMediaComponentSubType();
bool IsVideoSampleDesc(uint32 pDataFormat);
void ReadSoundDescription();
void ReadVideoDescription();
array_header theHeader; array_header theHeader;
SoundDescArray theAudioDescArray; SoundDescArray theAudioDescArray;
@ -304,6 +330,7 @@ public:
void OnProcessMetaData(); void OnProcessMetaData();
char *OnGetAtomName(); char *OnGetAtomName();
uint32 getMediaComponentSubType();
}; };
// Atom class for reading the media information atom // Atom class for reading the media information atom
@ -314,6 +341,7 @@ public:
void OnProcessMetaData(); void OnProcessMetaData();
char *OnGetAtomName(); char *OnGetAtomName();
uint32 getMediaComponentSubType();
}; };
// Atom class for reading the stbl atom // Atom class for reading the stbl atom
@ -324,6 +352,7 @@ public:
void OnProcessMetaData(); void OnProcessMetaData();
char *OnGetAtomName(); char *OnGetAtomName();
uint32 getMediaComponentSubType();
}; };
// Atom class for reading the dinf atom // Atom class for reading the dinf atom
@ -333,7 +362,6 @@ public:
virtual ~DINFAtom(); virtual ~DINFAtom();
void OnProcessMetaData(); void OnProcessMetaData();
char *OnGetAtomName(); char *OnGetAtomName();
}; };
// Atom class for reading the tmcd atom // Atom class for reading the tmcd atom
@ -358,7 +386,7 @@ private:
wave_format_ex theWaveFormat; wave_format_ex theWaveFormat;
}; };
// Atom class for reading the hdlr atom // Atom class for reading the Media Handler atom
class HDLRAtom : public AtomBase { class HDLRAtom : public AtomBase {
public: public:
HDLRAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize); HDLRAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize);
@ -366,6 +394,12 @@ public:
void OnProcessMetaData(); void OnProcessMetaData();
char *OnGetAtomName(); char *OnGetAtomName();
bool IsVideoHandler();
bool IsAudioHandler();
uint32 getMediaComponentSubType();
private:
hdlr theHeader;
}; };
#endif #endif

View File

@ -1,3 +1,27 @@
/*
* Copyright (c) 2005, David McPaul
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "MOVParser.h" #include "MOVParser.h"
TRAKAtom::TRAKAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize) TRAKAtom::TRAKAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)

View File

@ -1,3 +1,27 @@
/*
* Copyright (c) 2005, David McPaul
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
struct xxxx { struct xxxx {
uint8 Version; uint8 Version;
uint8 Flags1; uint8 Flags1;
@ -107,6 +131,7 @@ struct SampleToChunk {
uint32 FirstChunk; uint32 FirstChunk;
uint32 SamplesPerChunk; uint32 SamplesPerChunk;
uint32 SampleDescriptionID; uint32 SampleDescriptionID;
uint32 TotalPrevFrames;
}; };
// Note standard is 32bits offsets but later is 64 // Note standard is 32bits offsets but later is 64

View File

@ -121,7 +121,7 @@ movReader::GetFileFormatInfo(media_file_format *mff)
| media_file_format::B_KNOWS_ENCODED_VIDEO | media_file_format::B_KNOWS_ENCODED_VIDEO
| media_file_format::B_KNOWS_ENCODED_AUDIO | media_file_format::B_KNOWS_ENCODED_AUDIO
| media_file_format::B_IMPERFECTLY_SEEKABLE; | media_file_format::B_IMPERFECTLY_SEEKABLE;
mff->family = B_MISC_FORMAT_FAMILY; mff->family = B_QUICKTIME_FORMAT_FAMILY;
mff->version = 100; mff->version = 100;
strcpy(mff->mime_type, "audio/x-mov"); strcpy(mff->mime_type, "audio/x-mov");
strcpy(mff->file_extension, "mov"); strcpy(mff->file_extension, "mov");