void STSDAtom::ReadDecoderConfig(uint8 **pDecoderConfig, size_t *pDecoderConfigSize, AudioDescription *pAudioDescription, VideoDescription *pVideoDescription) { // Check for a Decoder Config and if it exists copy it back to the caller // MPEG-4 video/audio use the various decoder config structures to pass // additional decoder information to the decoder. The extractor sometimes // needs to decode the data to work out how to properly construct the // decoder // First make sure we have a something if (GetBytesRemaining() > 0) { // Well something is there so read it as an atom AtomBase *aAtomBase = GetAtom(theStream); aAtomBase->ProcessMetaData(); printf("%s [%Ld]\n",aAtomBase->GetAtomName(),aAtomBase->GetAtomSize()); if (dynamic_cast<DecoderConfigAtom *>(aAtomBase)) { // DecoderConfig atom good DecoderConfigAtom *aDecoderConfigAtom = dynamic_cast<DecoderConfigAtom *>(aAtomBase); aDecoderConfigAtom->OverrideAudioDescription(pAudioDescription); aDecoderConfigAtom->OverrideVideoDescription(pVideoDescription); delete aAtomBase; } else { // Unknown atom bad printf("Unknown atom %s\n",aAtomBase->GetAtomName()); delete aAtomBase; } } }
void CMOVAtom::OnProcessMetaData() { BMallocIO *theUncompressedData; uint8 *outBuffer; CMVDAtom *aCMVDAtom = NULL; uint32 compressionID = 0; uint64 descBytesLeft; uint32 Size; descBytesLeft = GetAtomSize(); // Check for Compression Type while (descBytesLeft > 0) { AtomBase *aAtomBase = GetAtom(theStream); aAtomBase->OnProcessMetaData(); if (aAtomBase->GetAtomSize() > 0) { descBytesLeft = descBytesLeft - aAtomBase->GetAtomSize(); } else { printf("Invalid Atom found when reading Compressed Headers\n"); descBytesLeft = 0; } if (dynamic_cast<DCOMAtom *>(aAtomBase)) { // DCOM atom compressionID = dynamic_cast<DCOMAtom *>(aAtomBase)->GetCompressionID(); delete aAtomBase; } else { if (dynamic_cast<CMVDAtom *>(aAtomBase)) { // CMVD atom aCMVDAtom = dynamic_cast<CMVDAtom *>(aAtomBase); descBytesLeft = 0; } } } // Decompress data if (compressionID == 'zlib') { Size = aCMVDAtom->GetUncompressedSize(); outBuffer = (uint8 *)(malloc(Size)); printf("Decompressing %ld bytes to %ld bytes\n",aCMVDAtom->GetBufferSize(),Size); int result = uncompress(outBuffer, &Size, aCMVDAtom->GetCompressedData(), aCMVDAtom->GetBufferSize()); if (result != Z_OK) { printf("Failed to decompress headers uncompress returned "); switch (result) { case Z_MEM_ERROR: DEBUGGER("Lack of Memory Error\n"); break; case Z_BUF_ERROR: DEBUGGER("Lack of Output buffer space Error\n"); break; case Z_DATA_ERROR: DEBUGGER("Input Data is corrupt or not a compressed set Error\n"); break; } } // Copy uncompressed data into BMAllocIO theUncompressedData = new BMallocIO(); theUncompressedData->SetSize(Size); theUncompressedData->WriteAt(0L,outBuffer,Size); free(outBuffer); delete aCMVDAtom; // reset position on BMAllocIO theUncompressedData->Seek(SEEK_SET,0L); // Assign to Stream theUncompressedStream = theUncompressedData; // All subsequent reads should use theUncompressedStream } }
void STSDAtom::ReadVideoDescription() { uint64 descBytesLeft; // read in Video Sample Data VideoDescriptionV0 *aVideoDescription; aVideoDescription = new VideoDescriptionV0; Read(&aVideoDescription->basefields.Size); 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); Read(&aVideoDescription->desc.TemporaralQuality); Read(&aVideoDescription->desc.SpacialQuality); Read(&aVideoDescription->desc.Width); Read(&aVideoDescription->desc.Height); Read(&aVideoDescription->desc.HorizontalResolution); Read(&aVideoDescription->desc.VerticalResolution); Read(&aVideoDescription->desc.DataSize); // FrameCount is actually No of Frames per Sample which is usually 1 Read(&aVideoDescription->desc.FrameCount); Read(aVideoDescription->desc.CompressorName,32); 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<ESDSAtom *>(aAtomBase)) { // ESDS atom good aVideoDescription->VOLSize = aAtomBase->getDataSize(); aVideoDescription->theVOL = (uint8 *)(malloc(aVideoDescription->VOLSize)); memcpy(aVideoDescription->theVOL,dynamic_cast<ESDSAtom *>(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())); }
void STSDAtom::ReadSoundDescription() { uint64 descBytesLeft; SoundDescriptionV1 *aSoundDescriptionV1; aSoundDescriptionV1 = new SoundDescriptionV1; Read(&aSoundDescriptionV1->basefields.Size); Read(&aSoundDescriptionV1->basefields.DataFormat); 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 Read(&aSoundDescriptionV1->desc.Version); Read(&aSoundDescriptionV1->desc.Revision); Read(&aSoundDescriptionV1->desc.Vendor); Read(&aSoundDescriptionV1->desc.NoOfChannels); Read(&aSoundDescriptionV1->desc.SampleSize); Read(&aSoundDescriptionV1->desc.CompressionID); Read(&aSoundDescriptionV1->desc.PacketSize); Read(&aSoundDescriptionV1->desc.SampleRate); if ((aSoundDescriptionV1->desc.Version == 1) && (aSoundDescriptionV1->basefields.DataFormat != AUDIO_IMA4)) { Read(&(aSoundDescriptionV1->samplesPerPacket)); Read(&(aSoundDescriptionV1->bytesPerPacket)); Read(&(aSoundDescriptionV1->bytesPerFrame)); Read(&(aSoundDescriptionV1->bytesPerSample)); } else { // Calculate? if (aSoundDescriptionV1->basefields.DataFormat == AUDIO_IMA4) { aSoundDescriptionV1->samplesPerPacket = 64; aSoundDescriptionV1->bytesPerFrame = aSoundDescriptionV1->desc.NoOfChannels * 34; aSoundDescriptionV1->bytesPerSample = aSoundDescriptionV1->desc.SampleSize / 8; aSoundDescriptionV1->bytesPerPacket = 64 * aSoundDescriptionV1->bytesPerFrame; } else { aSoundDescriptionV1->bytesPerSample = aSoundDescriptionV1->desc.SampleSize / 8; aSoundDescriptionV1->bytesPerFrame = aSoundDescriptionV1->desc.NoOfChannels * aSoundDescriptionV1->bytesPerSample; aSoundDescriptionV1->bytesPerPacket = aSoundDescriptionV1->desc.PacketSize; aSoundDescriptionV1->samplesPerPacket = aSoundDescriptionV1->desc.PacketSize / aSoundDescriptionV1->bytesPerFrame; } } // 0 means we dont have one aSoundDescriptionV1->theWaveFormat.format_tag = 0; descBytesLeft = getBytesRemaining(); while (descBytesLeft > 0) { // More extended atoms AtomBase *aAtomBase = getAtom(theStream); aAtomBase->OnProcessMetaData(); printf("%s\n",aAtomBase->getAtomName()); if (dynamic_cast<WAVEAtom *>(aAtomBase)) { // WAVE atom aSoundDescriptionV1->theWaveFormat = dynamic_cast<WAVEAtom *>(aAtomBase)->getWaveFormat(); } if (dynamic_cast<ESDSAtom *>(aAtomBase)) { // ESDS atom good aSoundDescriptionV1->VOLSize = aAtomBase->getDataSize(); aSoundDescriptionV1->theVOL = (uint8 *)(malloc(aSoundDescriptionV1->VOLSize)); memcpy(aSoundDescriptionV1->theVOL,dynamic_cast<ESDSAtom *>(aAtomBase)->getVOL(),aSoundDescriptionV1->VOLSize); } if ((aAtomBase->getAtomSize() > 0) && (descBytesLeft >= aAtomBase->getAtomSize())) { descBytesLeft = descBytesLeft - aAtomBase->getAtomSize(); } else { DEBUGGER("Invalid Atom found when reading Sound Description\n"); descBytesLeft = 0; } delete aAtomBase; } theAudioDescArray[0] = aSoundDescriptionV1; PRINT(("Size:Format=%ld:%ld %Ld\n",aSoundDescriptionV1->basefields.Size,aSoundDescriptionV1->basefields.DataFormat,descBytesLeft)); }