📄 quicktimefilesink.cpp
字号:
size += addWord(duration); // Duration size += addWord(0x00000000); // Language+QualityaddAtomEnd;addAtom(hdlr); size += addWord(0x00000000); // Version + Flags size += add4ByteString("mhlr"); // Component type size += addWord(fCurrentIOState->fQTcomponentSubtype); // Component subtype size += add4ByteString("appl"); // Component manufacturer size += addWord(0x00000000); // Component flags size += addWord(0x00000000); // Component flags mask size += addArbitraryString(fCurrentIOState->fQTcomponentName); // Component nameaddAtomEnd;addAtom(minf); SubsessionIOState::atomCreationFunc mediaInformationAtomCreator = fCurrentIOState->fQTMediaInformationAtomCreator; size += (this->*mediaInformationAtomCreator)(); size += addAtom_hdlr2(); size += addAtom_dinf(); size += addAtom_stbl();addAtomEnd;addAtom(smhd); size += addZeroWords(2); // Version+Flags+Balance+ReservedaddAtomEnd;addAtom(vmhd); size += addWord(0x00000001); // Version + Flags size += addWord(0x00408000); // Graphics mode + Opcolor[red] size += addWord(0x80008000); // Opcolor[green} + Opcolor[blue]addAtomEnd;addAtom(gmhd); size += addAtom_gmin();addAtomEnd;addAtom(gmin); size += addWord(0x00000000); // Version + Flags // The following fields probably aren't used for hint tracks, so just // use values that I've seen in other files: size += addWord(0x00408000); // Graphics mode + Opcolor (1st 2 bytes) size += addWord(0x80008000); // Opcolor (last 4 bytes) size += addWord(0x00000000); // Balance + ReservedaddAtomEnd;unsigned QuickTimeFileSink::addAtom_hdlr2() { unsigned initFilePosn = ftell(fOutFid); unsigned size = addAtomHeader("hdlr"); size += addWord(0x00000000); // Version + Flags size += add4ByteString("dhlr"); // Component type size += add4ByteString("alis"); // Component subtype size += add4ByteString("appl"); // Component manufacturer size += addZeroWords(2); // Component flags+Component flags mask size += addArbitraryString("Apple Alias Data Handler"); // Component nameaddAtomEnd;addAtom(dinf); size += addAtom_dref();addAtomEnd;addAtom(dref); size += addWord(0x00000000); // Version + Flags size += addWord(0x00000001); // Number of entries size += addAtom_alis();addAtomEnd;addAtom(alis); size += addWord(0x00000001); // Version + FlagsaddAtomEnd;addAtom(stbl); size += addAtom_stsd(); size += addAtom_stts(); size += addAtom_stsc(); size += addAtom_stsz(); size += addAtom_stco();addAtomEnd;addAtom(stsd); size += addWord(0x00000000); // Version+Flags size += addWord(0x00000001); // Number of entries SubsessionIOState::atomCreationFunc mediaDataAtomCreator = fCurrentIOState->fQTMediaDataAtomCreator; size += (this->*mediaDataAtomCreator)();addAtomEnd;unsigned QuickTimeFileSink::addAtom_genericMedia() { unsigned initFilePosn = ftell(fOutFid); // Our source is assumed to be a "QuickTimeGenericRTPSource" // Use its "sdAtom" state for our contents: QuickTimeGenericRTPSource* rtpSource = (QuickTimeGenericRTPSource*) fCurrentIOState->fOurSubsession.rtpSource(); QuickTimeGenericRTPSource::QTState& qtState = rtpSource->qtState; char const* from = qtState.sdAtom; unsigned size = qtState.sdAtomSize; for (unsigned i = 0; i < size; ++i) addByte(from[i]);addAtomEnd;unsigned QuickTimeFileSink::addAtom_soundMediaGeneral() { unsigned initFilePosn = ftell(fOutFid); unsigned size = addAtomHeader(fCurrentIOState->fQTAudioDataType);// General sample description fields: size += addWord(0x00000000); // Reserved size += addWord(0x00000001); // Reserved+Data reference index// Sound sample description fields: unsigned short const version = fCurrentIOState->fQTSoundSampleVersion; size += addWord(version<<16); // Version+Revision level size += addWord(0x00000000); // Vendor unsigned short numChannels = (unsigned short)(fCurrentIOState->fOurSubsession.numChannels()); size += addHalfWord(numChannels); // Number of channels size += addHalfWord(0x0010); // Sample size // size += addWord(0x00000000); // Compression ID+Packet size size += addWord(0xfffe0000); // Compression ID+Packet size ##### unsigned const sampleRateFixedPoint = fCurrentIOState->fQTTimeScale << 16; size += addWord(sampleRateFixedPoint); // Sample rateaddAtomEnd;unsigned QuickTimeFileSink::addAtom_Qclp() { // The beginning of this atom looks just like a general Sound Media atom, // except with a version field of 1: unsigned initFilePosn = ftell(fOutFid); fCurrentIOState->fQTAudioDataType = "Qclp"; fCurrentIOState->fQTSoundSampleVersion = 1; unsigned size = addAtom_soundMediaGeneral(); // Next, add the four fields that are particular to version 1: // (Later, parameterize these #####) size += addWord(0x000000a0); // samples per packet size += addWord(0x00000000); // ??? size += addWord(0x00000000); // ??? size += addWord(0x00000002); // bytes per sample (uncompressed) // Other special fields are in a 'wave' atom that follows: size += addAtom_wave();addAtomEnd;addAtom(wave); size += addAtom_frma(); if (strcmp(fCurrentIOState->fQTAudioDataType, "Qclp") == 0) { size += addWord(0x00000014); // ??? size += add4ByteString("Qclp"); // ??? if (fCurrentIOState->fQTBytesPerFrame == 35) { size += addAtom_Fclp(); // full-rate QCELP } else { size += addAtom_Hclp(); // half-rate QCELP } // what about other QCELP 'rates'??? ##### size += addWord(0x00000008); // ??? size += addWord(0x00000000); // ??? size += addWord(0x00000000); // ??? size += addWord(0x00000008); // ??? } else if (strcmp(fCurrentIOState->fQTAudioDataType, "mp4a") == 0) { size += addWord(0x0000000c); // ??? size += add4ByteString("mp4a"); // ??? size += addWord(0x00000000); // ??? size += addAtom_esds(); // ESDescriptor size += addWord(0x00000008); // ??? size += addWord(0x00000000); // ??? }addAtomEnd;addAtom(frma); size += add4ByteString(fCurrentIOState->fQTAudioDataType); // ???addAtomEnd;addAtom(Fclp); size += addWord(0x00000000); // ???addAtomEnd;addAtom(Hclp); size += addWord(0x00000000); // ???addAtomEnd;unsigned QuickTimeFileSink::addAtom_mp4a() { // The beginning of this atom looks just like a general Sound Media atom, // except with a version field of 1: unsigned initFilePosn = ftell(fOutFid); fCurrentIOState->fQTAudioDataType = "mp4a"; fCurrentIOState->fQTSoundSampleVersion = 1; unsigned size = addAtom_soundMediaGeneral(); if (fGenerateMP4Format) { size += addAtom_esds(); } else { // Next, add the four fields that are particular to version 1: // (Later, parameterize these #####) size += addWord(fCurrentIOState->fQTTimeUnitsPerSample); size += addWord(0x00000001); // ??? size += addWord(0x00000001); // ??? size += addWord(0x00000002); // bytes per sample (uncompressed) // Other special fields are in a 'wave' atom that follows: size += addAtom_wave(); }addAtomEnd;addAtom(esds); //##### MediaSubsession& subsession = fCurrentIOState->fOurSubsession; if (strcmp(subsession.mediumName(), "audio") == 0) { // MPEG-4 audio size += addWord(0x00000000); // ??? size += addWord(0x03808080); // ??? size += addWord(0x2a000000); // ??? size += addWord(0x04808080); // ??? size += addWord(0x1c401500); // ??? size += addWord(0x18000000); // ??? size += addWord(0x6d600000); // ??? size += addWord(0x6d600580); // ??? size += addByte(0x80); size += addByte(0x80); // ??? } else if (strcmp(subsession.mediumName(), "video") == 0) { // MPEG-4 video size += addWord(0x00000000); // ??? size += addWord(0x03370000); // ??? size += addWord(0x1f042f20); // ??? size += addWord(0x1104fd46); // ??? size += addWord(0x000d4e10); // ??? size += addWord(0x000d4e10); // ??? size += addByte(0x05); // ??? } // Add the source's 'config' information: unsigned configSize; unsigned char* config = parseGeneralConfigStr(subsession.fmtp_config(), configSize); if (configSize > 0) --configSize; // remove trailing '\0'; size += addByte(configSize); for (unsigned i = 0; i < configSize; ++i) { size += addByte(config[i]); } if (strcmp(subsession.mediumName(), "audio") == 0) { // MPEG-4 audio size += addWord(0x06808080); // ??? size += addByte(0x01); // ??? } else { // MPEG-4 video size += addHalfWord(0x0601); // ??? size += addByte(0x02); // ??? } //#####addAtomEnd;addAtom(srcq); //##### size += addWord(0x00000040); // ??? //#####addAtomEnd;addAtom(h263);// General sample description fields: size += addWord(0x00000000); // Reserved size += addWord(0x00000001); // Reserved+Data reference index// Video sample description fields: size += addWord(0x00020001); // Version+Revision level size += add4ByteString("appl"); // Vendor size += addWord(0x00000000); // Temporal quality size += addWord(0x000002fc); // Spatial quality unsigned const widthAndHeight = (fMovieWidth<<16)|fMovieHeight; size += addWord(widthAndHeight); // Width+height size += addWord(0x00480000); // Horizontal resolution size += addWord(0x00480000); // Vertical resolution size += addWord(0x00000000); // Data size size += addWord(0x00010548); // Frame count+Compressor name (start) // "H.263" size += addWord(0x2e323633); // Compressor name (continued) size += addZeroWords(6); // Compressor name (continued - zero) size += addWord(0x00000018); // Compressor name (final)+Depth size += addHalfWord(0xffff); // Color table idaddAtomEnd;addAtom(mp4v);// General sample description fields: size += addWord(0x00000000); // Reserved size += addWord(0x00000001); // Reserved+Data reference index// Video sample description fields: size += addWord(0x00020001); // Version+Revision level size += add4ByteString("appl"); // Vendor size += addWord(0x00000200); // Temporal quality size += addWord(0x00000400); // Spatial quality unsigned const widthAndHeight = (fMovieWidth<<16)|fMovieHeight; size += addWord(widthAndHeight); // Width+height size += addWord(0x00480000); // Horizontal resolution size += addWord(0x00480000); // Vertical resolution size += addWord(0x00000000); // Data size size += addWord(0x00010c4d); // Frame count+Compressor name (start) // "MPEG-4 Video" size += addWord(0x5045472d); // Compressor name (continued) size += addWord(0x34205669); // Compressor name (continued) size += addWord(0x64656f00); // Compressor name (continued) size += addZeroWords(4); // Compressor name (continued - zero) size += addWord(0x00000018); // Compressor name (final)+Depth size += addHalfWord(0xffff); // Color table id size += addAtom_esds(); // ESDescriptor size += addWord(0x00000000); // ???addAtomEnd;unsigned QuickTimeFileSink::addAtom_rtp() { unsigned initFilePosn = ftell(fOutFid); unsigned size = addAtomHeader("rtp "); size += addWord(0x00000000); // Reserved (1st 4 bytes) size += addWord(0x00000001); // Reserved (last 2 bytes) + Data ref index size += addWord(0x00010001); // Hint track version + Last compat htv size += addWord(1450); // Max packet size size += addAtom_tims();addAtomEnd;addAtom(tims); size += addWord(fCurrentIOState->fOurSubsession.rtpTimestampFrequency());addAtomEnd;addAtom(stts); // Time-to-Sample size += addWord(0x00000000); // Version+flags // First, add a dummy "Number of entries" field // (and remember its position). We'll fill this field in later: unsigned numEntriesPosition = ftell(fOutFid); size += addWord(0); // dummy for "Number of entries" // Then, run through the chunk descriptors, and enter the entries // in this (compressed) Time-to-Sample table: unsigned numEntries = 0, numSamplesSoFar = 0; unsigned prevSampleDuration = 0; unsigned const samplesPerFrame = fCurrentIOState->fQTSamplesPerFrame; ChunkDescriptor* chunk = fCurrentIOState->fHeadChunk; while (chunk != NULL) { unsigned const sampleDuration = chunk->fFrameDuration/samplesPerFrame; if (sampleDuration != prevSampleDuration) { // This chunk will start a new table entry, // so write out the old one (if any): if (chunk != fCurrentIOState->fHeadChunk) { ++numEntries; size += addWord(numSamplesSoFar); // Sample count size += addWord(prevSampleDuration); // Sample duration numSamplesSoFar = 0; } } unsigned const numSamples = chunk->fNumFrames*samplesPerFrame; numSamplesSoFar += numSamples; prevSampleDuration = sampleDuration; chunk = chunk->fNextChunk; } // Then, write out the last entry: ++numEntries; size += addWord(numSamplesSoFar); // Sample count size += addWord(prevSampleDuration); // Sample duration // Now go back and fill in the "Number of entries" field: setWord(numEntriesPosition, numEntries);addAtomEnd;addAtom(stsc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -