changes for aac decoder

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24229 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul 2008-03-04 09:55:49 +00:00
parent 8c5c17cdbc
commit 9f6dbdea6a
6 changed files with 278 additions and 154 deletions

View File

@ -275,14 +275,24 @@ MP4FileReader::getVideoFrameCount(uint32 streamIndex)
uint32
MP4FileReader::getAudioFrameCount(uint32 streamIndex)
{
if (IsAudio(streamIndex)) {
return uint32(((getAudioDuration(streamIndex)
* AudioFormat(streamIndex)->SampleRate) / 1000000L) + 0.5);
}
AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex);
return 0;
if (aAtomBase && dynamic_cast<TRAKAtom *>(aAtomBase)->IsAudio())
return dynamic_cast<TRAKAtom *>(aAtomBase)->FrameCount();
return 1;
}
uint32
MP4FileReader::getAudioChunkCount(uint32 streamIndex)
{
AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex);
if (aAtomBase && dynamic_cast<TRAKAtom *>(aAtomBase)->IsAudio())
return dynamic_cast<TRAKAtom *>(aAtomBase)->getTotalChunks();
return 0;
}
bool
MP4FileReader::IsVideo(uint32 streamIndex)
@ -329,23 +339,18 @@ MP4FileReader::getFirstFrameInChunk(uint32 streamIndex, uint32 pChunkID)
uint32
MP4FileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo)
MP4FileReader::getNoFramesInChunk(uint32 streamIndex, uint32 pFrameNo)
{
// Find Track
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
if (aAtomBase) {
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
uint32 ChunkNo = 1;
if (IsAudio(stream_index))
ChunkNo = pFrameNo;
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
if (IsVideo(stream_index)) {
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
uint32 OffsetInChunk;
ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
}
uint32 OffsetInChunk;
ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
return aTrakAtom->getNoSamplesInChunk(ChunkNo);
}
@ -355,48 +360,38 @@ MP4FileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo)
uint64
MP4FileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo)
MP4FileReader::getOffsetForFrame(uint32 streamIndex, uint32 pFrameNo)
{
// Find Track
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
if (aAtomBase) {
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
if (IsAudio(stream_index)) {
// FrameNo is really chunk No for audio
uint32 ChunkNo = pFrameNo;
if (pFrameNo < aTrakAtom->FrameCount()) {
// Get Sample for Frame
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
// Get Chunk For Sample and the offset for the frame within that chunk
uint32 OffsetInChunk;
uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
// Get Offset For Chunk
return aTrakAtom->getOffsetForChunk(ChunkNo);
}
uint64 OffsetNo = aTrakAtom->getOffsetForChunk(ChunkNo);
if (IsVideo(stream_index)) {
if (pFrameNo < aTrakAtom->FrameCount()) {
// Get Sample for Frame
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
// Get Chunk For Sample and the offset for the frame within that chunk
uint32 OffsetInChunk;
uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
// Get Offset For Chunk
uint64 OffsetNo = aTrakAtom->getOffsetForChunk(ChunkNo);
if (ChunkNo != 0) {
uint32 SizeForSample;
// Adjust the Offset for the Offset in the chunk
if (aTrakAtom->IsSingleSampleSize()) {
SizeForSample = aTrakAtom->getSizeForSample(SampleNo);
OffsetNo = OffsetNo + (OffsetInChunk * SizeForSample);
} else {
// This is bad news performance wise
for (uint32 i=1;i<=OffsetInChunk;i++) {
SizeForSample = aTrakAtom->getSizeForSample(SampleNo-i);
OffsetNo = OffsetNo + SizeForSample;
}
if (ChunkNo != 0) {
uint32 SizeForSample;
// Adjust the Offset for the Offset in the chunk
if (aTrakAtom->IsSingleSampleSize()) {
SizeForSample = aTrakAtom->getSizeForSample(SampleNo);
OffsetNo = OffsetNo + (OffsetInChunk * SizeForSample);
} else {
// This is bad news performance wise
for (uint32 i=1;i<=OffsetInChunk;i++) {
SizeForSample = aTrakAtom->getSizeForSample(SampleNo-i);
OffsetNo = OffsetNo + SizeForSample;
}
}
return OffsetNo;
}
return OffsetNo;
}
}
@ -476,10 +471,10 @@ MP4FileReader::MovMainHeader()
const AudioMetaData *
MP4FileReader::AudioFormat(uint32 stream_index, size_t *size)
MP4FileReader::AudioFormat(uint32 streamIndex, size_t *size)
{
if (IsAudio(stream_index)) {
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
if (IsAudio(streamIndex)) {
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
if (aAtomBase) {
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
@ -496,7 +491,7 @@ MP4FileReader::AudioFormat(uint32 stream_index, size_t *size)
theAudio.NoOfChannels = aAudioDescription.theAudioSampleEntry.ChannelCount;
theAudio.SampleSize = aAudioDescription.theAudioSampleEntry.SampleSize;
theAudio.SampleRate = aAudioDescription.theAudioSampleEntry.SampleRate / 65536; // Convert from fixed point decimal to float
theAudio.PacketSize = uint32((theAudio.SampleRate * theAudio.NoOfChannels * theAudio.SampleSize) / 8);
theAudio.PacketSize = uint32((theAudio.SampleSize * theAudio.NoOfChannels * 1024) / 8);
theAudio.theVOL = aAudioDescription.theVOL;
theAudio.VOLSize = aAudioDescription.VOLSize;
@ -509,12 +504,11 @@ MP4FileReader::AudioFormat(uint32 stream_index, size_t *size)
return NULL;
}
const VideoMetaData*
MP4FileReader::VideoFormat(uint32 stream_index)
MP4FileReader::VideoFormat(uint32 streamIndex)
{
if (IsVideo(stream_index)) {
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
if (IsVideo(streamIndex)) {
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
if (aAtomBase) {
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
@ -556,26 +550,26 @@ MP4FileReader::VideoFormat(uint32 stream_index)
const mp4_stream_header*
MP4FileReader::StreamFormat(uint32 stream_index)
MP4FileReader::StreamFormat(uint32 streamIndex)
{
// Fill In a Stream Header
theStreamHeader.length = 0;
if (IsActive(stream_index) == false) {
if (IsActive(streamIndex) == false) {
return NULL;
}
if (IsVideo(stream_index)) {
theStreamHeader.rate = uint32(1000000L*VideoFormat(stream_index)->FrameRate);
if (IsVideo(streamIndex)) {
theStreamHeader.rate = uint32(1000000L*VideoFormat(streamIndex)->FrameRate);
theStreamHeader.scale = 1000000L;
theStreamHeader.length = getVideoFrameCount(stream_index);
theStreamHeader.length = getVideoFrameCount(streamIndex);
}
if (IsAudio(stream_index)) {
theStreamHeader.rate = uint32(AudioFormat(stream_index)->SampleRate);
if (IsAudio(streamIndex)) {
theStreamHeader.rate = uint32(AudioFormat(streamIndex)->SampleRate);
theStreamHeader.scale = 1;
theStreamHeader.length = getAudioFrameCount(stream_index);
theStreamHeader.sample_size = AudioFormat(stream_index)->SampleSize;
theStreamHeader.length = getAudioFrameCount(streamIndex);
theStreamHeader.sample_size = AudioFormat(streamIndex)->SampleSize;
theStreamHeader.suggested_buffer_size = theStreamHeader.rate * theStreamHeader.sample_size;
}
@ -584,27 +578,15 @@ MP4FileReader::StreamFormat(uint32 stream_index)
uint32
MP4FileReader::getChunkSize(uint32 stream_index, uint32 pFrameNo)
MP4FileReader::getChunkSize(uint32 streamIndex, uint32 pFrameNo)
{
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
if (aAtomBase) {
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(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
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
return aTrakAtom->getSizeForSample(SampleNo);
}
if (pFrameNo < aTrakAtom->FrameCount()) {
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
return aTrakAtom->getSizeForSample(SampleNo);
}
}
@ -613,9 +595,9 @@ MP4FileReader::getChunkSize(uint32 stream_index, uint32 pFrameNo)
bool
MP4FileReader::IsKeyFrame(uint32 stream_index, uint32 pFrameNo)
MP4FileReader::IsKeyFrame(uint32 streamIndex, uint32 pFrameNo)
{
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
if (aAtomBase) {
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
@ -628,14 +610,14 @@ MP4FileReader::IsKeyFrame(uint32 stream_index, uint32 pFrameNo)
bool
MP4FileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo,
MP4FileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo,
off_t *start, uint32 *size, bool *keyframe)
{
*start = getOffsetForFrame(stream_index, pFrameNo);
*size = getChunkSize(stream_index, pFrameNo);
*start = getOffsetForFrame(streamIndex, pFrameNo);
*size = getChunkSize(streamIndex, pFrameNo);
if ((*start > 0) && (*size > 0)) {
*keyframe = IsKeyFrame(stream_index, pFrameNo);
*keyframe = IsKeyFrame(streamIndex, pFrameNo);
}
// TODO need a better method for detecting End of Data Note ChunkSize of 0 seems to be it.
@ -645,9 +627,9 @@ MP4FileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo,
bool
MP4FileReader::IsActive(uint32 stream_index)
MP4FileReader::IsActive(uint32 streamIndex)
{
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
if (aAtomBase) {
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
return aTrakAtom->IsActive();

View File

@ -81,45 +81,47 @@ public:
// Duration defined by the movie header
bigtime_t getMovieDuration();
// 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 first video track duration indexed by streamIndex
bigtime_t getVideoDuration(uint32 streamIndex);
// the first audio track duration indexed by streamIndex
bigtime_t getAudioDuration(uint32 streamIndex);
// the max of all active audio or video durations
bigtime_t getMaxDuration();
// 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);
// The no of frames in the video track indexed by streamIndex
// 1 frame = 1 chunk
uint32 getVideoFrameCount(uint32 streamIndex);
// The no of frames in the audio track indexed by streamIndex
uint32 getAudioFrameCount(uint32 streamIndex);
// The no of chunks in the audio track indexed by streamIndex
uint32 getAudioChunkCount(uint32 streamIndex);
// Is stream (track) a video track
bool IsVideo(uint32 stream_index);
bool IsVideo(uint32 streamIndex);
// Is stream (track) a audio track
bool IsAudio(uint32 stream_index);
bool IsAudio(uint32 streamIndex);
uint32 getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo);
uint32 getFirstFrameInChunk(uint32 stream_index, uint32 pChunkID);
uint32 getNoFramesInChunk(uint32 streamIndex, uint32 pFrameNo);
uint32 getFirstFrameInChunk(uint32 streamIndex, uint32 pChunkID);
uint64 getOffsetForFrame(uint32 stream_index, uint32 pFrameNo);
uint32 getChunkSize(uint32 stream_index, uint32 pFrameNo);
bool IsKeyFrame(uint32 stream_index, uint32 pFrameNo);
uint64 getOffsetForFrame(uint32 streamIndex, uint32 pFrameNo);
uint32 getChunkSize(uint32 streamIndex, uint32 pFrameNo);
bool IsKeyFrame(uint32 streamIndex, uint32 pFrameNo);
status_t ParseFile();
BPositionIO *Source() {return theStream;};
bool IsActive(uint32 stream_index);
bool IsActive(uint32 streamIndex);
bool GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe);
bool GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe);
// Return all Audio Meta Data
const AudioMetaData *AudioFormat(uint32 stream_index, size_t *size = 0);
const AudioMetaData *AudioFormat(uint32 streamIndex, size_t *size = 0);
// Return all Video Meta Data
const VideoMetaData *VideoFormat(uint32 stream_index);
const VideoMetaData *VideoFormat(uint32 streamIndex);
// XXX these need work
const mp4_main_header *MovMainHeader();
const mp4_stream_header *StreamFormat(uint32 stream_index);
const mp4_stream_header *StreamFormat(uint32 streamIndex);
};
#endif

View File

@ -209,7 +209,7 @@ void MOOVAtom::OnProcessMetaData()
char *MOOVAtom::OnGetAtomName()
{
return "Quicktime Movie";
return "MPEG-4 Movie";
}
CMOVAtom::CMOVAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)
@ -322,7 +322,7 @@ void CMOVAtom::OnChildProcessingComplete()
char *CMOVAtom::OnGetAtomName()
{
return "Compressed Quicktime Movie";
return "Compressed MPEG-4 Movie";
}
DCOMAtom::DCOMAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
@ -438,7 +438,7 @@ void MVHDAtom::OnProcessMetaData()
char *MVHDAtom::OnGetAtomName()
{
return "Quicktime Movie Header";
return "MPEG-4 Movie Header";
}
MVHDAtom *MOOVAtom::getMVHDAtom()
@ -908,7 +908,7 @@ uint64 STCOAtom::getOffsetForChunk(uint32 pChunkID)
return 0LL;
}
ESDSAtom::ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
ESDSAtom::ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
{
theVOL = NULL;
}
@ -920,15 +920,116 @@ ESDSAtom::~ESDSAtom()
}
}
void ESDSAtom::OnProcessMetaData()
{
theVOL = (uint8 *)(malloc(getBytesRemaining()));
Read(theVOL,getBytesRemaining());
bool ESDSAtom::SkipTag(uint8 Tag, uint32 *offset) {
uint8 byte;
byte = theVOL[(*offset)++];
if (byte == Tag) {
uint8 numBytes = 0;
unsigned int length = 0;
do {
byte = theVOL[(*offset)++];
numBytes++;
length = (length << 7) | (byte & 0x7F);
} while ((byte & 0x80) && numBytes < 4);
} else {
// go back Tag not found
(*offset)--;
printf("No Tag %d\n",Tag);
return false;
}
return true;
}
uint8 *ESDSAtom::getVOL()
void ESDSAtom::OnProcessMetaData()
{
return theVOL;
FullAtom::OnProcessMetaData();
VOLSize = getBytesRemaining();
uint32 offset = 0;
theVOL = (uint8 *)(malloc(VOLSize));
Read(theVOL,VOLSize);
// Display the VOL
if (VOLSize > 0) {
if (SkipTag(0x03,&offset)) {
offset += 3;
} else {
offset += 2;
}
if (SkipTag(0x04,&offset)) {
printf("type id is %d", theVOL[offset]);
switch (theVOL[offset]) {
case 1: printf("system v1"); break;
case 2: printf("system v2"); break;
case 32: printf("MPEG-4 video"); break;
case 33: printf("MPEG-4 AVC SPS"); break;
case 34: printf("MPEG-4 AVC PPS"); break;
case 64: printf("MPEG-4 audio"); break;
}
offset+=2;
uint32 a,b,c;
uint32 buff;
a = theVOL[offset];
b = theVOL[offset+1];
c = theVOL[offset+2];
buff = (a << 16) | (b << 8) | c;
printf(" buf size %ld ",buff);
printf(" max bit rate %ld",uint32(theVOL[offset+4]));
printf(" avg bit rate %ld\n",uint32(theVOL[offset+8]));
}
} else {
printf("VOL size is 0\n");
}
}
size_t ESDSAtom::getVOLSize(bool forAudio)
{
uint32 offset = 0;
if (forAudio) {
if (SkipTag(0x03,&offset)) {
offset += 3;
} else {
offset += 2;
}
if (SkipTag(0x04,&offset)) {
offset += 13;
}
SkipTag(0x05,&offset);
}
return ( VOLSize - offset);
}
uint8 *ESDSAtom::getVOL(bool forAudio)
{
uint32 offset = 0;
if (forAudio) {
if (SkipTag(0x03,&offset)) {
offset += 3;
} else {
offset += 2;
}
if (SkipTag(0x04,&offset)) {
offset += 13;
}
SkipTag(0x05,&offset);
}
return &theVOL[offset];
}
char *ESDSAtom::OnGetAtomName()
@ -961,7 +1062,7 @@ uint32 STSDAtom::getMediaHandlerType()
return dynamic_cast<STBLAtom *>(getParent())->getMediaHandlerType();
}
void STSDAtom::ReadESDS(uint8 **VOL, size_t *VOLSize)
void STSDAtom::ReadESDS(uint8 **VOL, size_t *VOLSize, bool forAudio)
{
// Check for a esds and if it exists read it into the VOL buffer
// MPEG-4 video/audio use the esds to store the VOL (STUPID COMMITTEE IDEA)
@ -976,9 +1077,9 @@ void STSDAtom::ReadESDS(uint8 **VOL, size_t *VOLSize)
if (dynamic_cast<ESDSAtom *>(aAtomBase)) {
// ESDS atom good
*VOLSize = aAtomBase->getDataSize();
*VOLSize = dynamic_cast<ESDSAtom *>(aAtomBase)->getVOLSize(forAudio);
*VOL = (uint8 *)(malloc(*VOLSize));
memcpy(*VOL,dynamic_cast<ESDSAtom *>(aAtomBase)->getVOL(),*VOLSize);
memcpy(*VOL,dynamic_cast<ESDSAtom *>(aAtomBase)->getVOL(forAudio),*VOLSize);
delete aAtomBase;
} else {
@ -997,8 +1098,8 @@ void STSDAtom::ReadSoundDescription()
Read(&theAudioDescription.theAudioSampleEntry.pre_defined);
Read(&theAudioDescription.theAudioSampleEntry.reserved);
Read(&theAudioDescription.theAudioSampleEntry.SampleRate);
ReadESDS(&theAudioDescription.theVOL,&theAudioDescription.VOLSize);
ReadESDS(&theAudioDescription.theVOL,&theAudioDescription.VOLSize,true);
}
void STSDAtom::ReadVideoDescription()
@ -1028,7 +1129,7 @@ void STSDAtom::ReadVideoDescription()
Read(&theVideoDescription.theVideoSampleEntry.Depth);
Read(&theVideoDescription.theVideoSampleEntry.pre_defined3);
ReadESDS(&theVideoDescription.theVOL,&theVideoDescription.VOLSize);
ReadESDS(&theVideoDescription.theVOL,&theVideoDescription.VOLSize, false);
}
void STSDAtom::OnProcessMetaData()
@ -1253,7 +1354,7 @@ void MINFAtom::OnProcessMetaData()
char *MINFAtom::OnGetAtomName()
{
return "Quicktime Media Information Atom";
return "MPEG-4 Media Information Atom";
}
uint32 MINFAtom::getMediaHandlerType()
@ -1275,7 +1376,7 @@ void STBLAtom::OnProcessMetaData()
char *STBLAtom::OnGetAtomName()
{
return "Quicktime Sample Table Atom";
return "MPEG-4 Sample Table Atom";
}
uint32 STBLAtom::getMediaHandlerType()
@ -1297,7 +1398,7 @@ void DINFAtom::OnProcessMetaData()
char *DINFAtom::OnGetAtomName()
{
return "Quicktime Data Information Atom";
return "MPEG-4 Data Information Atom";
}
TKHDAtom::TKHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
@ -1371,7 +1472,7 @@ void TKHDAtom::OnProcessMetaData()
char *TKHDAtom::OnGetAtomName()
{
return "Quicktime Track Header";
return "MPEG-4 Track Header";
}
MDIAAtom::MDIAAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)
@ -1388,7 +1489,7 @@ void MDIAAtom::OnProcessMetaData()
char *MDIAAtom::OnGetAtomName()
{
return "Quicktime Media Atom";
return "MPEG-4 Media Atom";
}
uint32 MDIAAtom::getMediaHandlerType()
@ -1443,7 +1544,7 @@ void MDHDAtom::OnProcessMetaData()
char *MDHDAtom::OnGetAtomName()
{
return "Quicktime Media Header";
return "MPEG-4 Media Header";
}
bigtime_t MDHDAtom::getDuration()
@ -1486,7 +1587,7 @@ void HDLRAtom::OnProcessMetaData()
char *HDLRAtom::OnGetAtomName()
{
printf("%s %s:",(char *)&(theHeader.handler_type),name);
return "Quicktime Handler Reference Atom ";
return "MPEG-4 Handler Reference Atom ";
}
bool HDLRAtom::IsVideoHandler()
@ -1524,7 +1625,7 @@ void VMHDAtom::OnProcessMetaData()
char *VMHDAtom::OnGetAtomName()
{
return "Quicktime Video Media Header";
return "MPEG-4 Video Media Header";
}
SMHDAtom::SMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
@ -1545,5 +1646,5 @@ void SMHDAtom::OnProcessMetaData()
char *SMHDAtom::OnGetAtomName()
{
return "Quicktime Sound Media Header";
return "MPEG-4 Sound Media Header";
}

View File

@ -300,16 +300,19 @@ public:
off_t getEOF();
};
class ESDSAtom : public AtomBase {
class ESDSAtom : public FullAtom {
public:
ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize);
virtual ~ESDSAtom();
void OnProcessMetaData();
char *OnGetAtomName();
uint8 *getVOL();
uint8 *getVOL(bool forAudio);
size_t getVOLSize(bool forAudio);
private:
bool SkipTag(uint8 Tag, uint32 *offset);
uint8 *theVOL;
size_t VOLSize;
};
// Atom class for reading the sdst atom
@ -326,7 +329,7 @@ public:
private:
uint32 getMediaHandlerType();
void ReadESDS(uint8 **VOL, size_t *VOLSize);
void ReadESDS(uint8 **VOL, size_t *VOLSize, bool forAudio);
void ReadSoundDescription();
void ReadVideoDescription();

View File

@ -42,7 +42,7 @@ void TRAKAtom::OnProcessMetaData()
char *TRAKAtom::OnGetAtomName()
{
return "Quicktime Track Atom";
return "MPEG-4 Track Atom";
}
TKHDAtom *TRAKAtom::getTKHDAtom()

View File

@ -421,31 +421,56 @@ mp4Reader::AllocateCookie(int32 streamNumber, void **_cookie)
format->user_data_type = B_CODEC_TYPE_INFO;
*(uint32 *)format->user_data = description.u.quicktime.codec; format->user_data[4] = 0;
format->u.encoded_video.max_bit_rate = 8 * theFileReader->MovMainHeader()->max_bytes_per_sec;
format->u.encoded_video.avg_bit_rate = format->u.encoded_video.max_bit_rate / 2; // XXX fix this
// format->u.encoded_video.max_bit_rate = 8 * theFileReader->MovMainHeader()->max_bytes_per_sec;
// format->u.encoded_video.avg_bit_rate = format->u.encoded_video.max_bit_rate / 2; // XXX fix this
format->u.encoded_video.output.field_rate = cookie->frames_per_sec_rate / (float)cookie->frames_per_sec_scale;
format->u.encoded_video.output.interlace = 1; // 1: progressive
format->u.encoded_video.output.first_active = 0;
format->u.encoded_video.output.last_active = cookie->line_count - 1;
format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT;
format->u.encoded_video.output.pixel_width_aspect = 1;
format->u.encoded_video.output.pixel_height_aspect = 1;
// format->u.encoded_video.output.display.format = 0;
format->u.encoded_video.output.display.line_width = theFileReader->MovMainHeader()->width;
format->u.encoded_video.output.display.line_count = cookie->line_count;
format->u.encoded_video.output.display.bytes_per_row = 0; // format->u.encoded_video.output.display.line_width * 4;
format->u.encoded_video.avg_bit_rate = 1;
format->u.encoded_video.max_bit_rate = 1;
format->u.encoded_video.frame_size = video_format->width * video_format->height * video_format->planes / 8;
format->u.encoded_video.output.display.bytes_per_row = video_format->planes / 8 * video_format->width;
// align to 2 bytes
format->u.encoded_video.output.display.bytes_per_row += format->u.encoded_video.output.display.bytes_per_row & 1;
switch (video_format->planes) {
case 16:
format->u.encoded_video.output.display.format = B_RGB15_BIG;
break;
case 24:
format->u.encoded_video.output.display.format = B_RGB24_BIG;
break;
case 32:
format->u.encoded_video.output.display.format = B_RGB32_BIG;
break;
default:
format->u.encoded_video.output.display.format = B_NO_COLOR_SPACE;
format->u.encoded_video.frame_size = video_format->width * video_format->height * 8 / 8;
}
format->u.encoded_video.output.display.line_width = video_format->width;
format->u.encoded_video.output.display.line_count = video_format->height;
format->u.encoded_video.output.display.pixel_offset = 0;
format->u.encoded_video.output.display.line_offset = 0;
format->u.encoded_video.output.display.flags = 0;
format->u.encoded_video.output.interlace = 1; // 1: progressive
format->u.encoded_video.output.first_active = 0;
format->u.encoded_video.output.last_active = format->u.encoded_video.output.display.line_count - 1;
format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT;
format->u.encoded_video.output.pixel_width_aspect = 1;
format->u.encoded_video.output.pixel_height_aspect = 1;
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 Found Size is %ld\n",video_format->VOLSize);
size_t size = video_format->VOLSize;
const void *data = video_format->theVOL;
format->SetMetaData(data, size);
if (format->SetMetaData(data, size) != B_OK) {
printf("Failed to set VOL\n %d %d",(16 << 20),32000);
}
#ifdef TRACE_MP4_READER
if (data) {
@ -485,8 +510,17 @@ mp4Reader::GetStreamInfo(void *_cookie, int64 *frameCount, bigtime_t *duration,
*frameCount = cookie->frame_count;
*duration = cookie->duration;
*format = cookie->format;
*infoBuffer = 0;
*infoSize = 0;
// Copy metadata to infoBuffer
if (theFileReader->IsVideo(cookie->stream)) {
const VideoMetaData *video_format = theFileReader->VideoFormat(cookie->stream);
*infoBuffer = video_format->theVOL;
*infoSize = video_format->VOLSize;
} else {
const AudioMetaData *audio_format = theFileReader->AudioFormat(cookie->stream);
*infoBuffer = audio_format->theVOL;
*infoSize = audio_format->VOLSize;
}
return B_OK;
}
@ -578,6 +612,8 @@ mp4Reader::GetNextChunk(void *_cookie, const void **chunkBuffer,
mediaHeader->u.encoded_video.field_flags = keyframe ? B_MEDIA_KEY_FRAME : 0;
mediaHeader->u.encoded_video.first_active_line = 0;
mediaHeader->u.encoded_video.line_count = cookie->line_count;
mediaHeader->u.encoded_video.field_number = 0;
mediaHeader->u.encoded_video.field_sequence = cookie->frame_pos;
cookie->frame_pos++;
}