Hi! I recognized that there was a recent release I missed. My patch was for release 2009-07-09.
Since 2010-03-08 release added code for stss atom the first patch will not work on the current release. Find the new patch for 2010-03-08 release attached on this mail. Regards, Wolfgang -- Wolfgang Breyha <wbre...@gmx.net> | http://www.blafasel.at/ Vienna University Computer Center | Austria
diff -urN live.orig/liveMedia/include/QuickTimeFileSink.hh live/liveMedia/include/QuickTimeFileSink.hh --- live.orig/liveMedia/include/QuickTimeFileSink.hh 2010-03-08 10:52:12.000000000 +0100 +++ live/liveMedia/include/QuickTimeFileSink.hh 2010-03-12 14:50:16.000000000 +0100 @@ -85,6 +85,7 @@ private: ///// Definitions specific to the QuickTime file format: + unsigned addWord64(u_int64_t word); unsigned addWord(unsigned word); unsigned addHalfWord(unsigned short halfWord); unsigned addByte(unsigned char byte) { @@ -96,8 +97,10 @@ unsigned addArbitraryString(char const* str, Boolean oneByteLength = True); unsigned addAtomHeader(char const* atomName); + unsigned addAtomHeader64(char const* atomName); // strlen(atomName) must be 4 - void setWord(unsigned filePosn, unsigned size); + void setWord(int64_t filePosn, unsigned size); + void setWord64(int64_t filePosn, u_int64_t size); unsigned movieTimeScale() const {return fLargestRTPtimestampFrequency;} @@ -151,7 +154,7 @@ _atom(stss); _atom(stsc); _atom(stsz); - _atom(stco); + _atom(co64); _atom(udta); _atom(name); _atom(hnti); @@ -176,8 +179,8 @@ private: unsigned short fMovieWidth, fMovieHeight; unsigned fMovieFPS; - unsigned fMDATposition; - unsigned fMVHD_durationPosn; + int64_t fMDATposition; + int64_t fMVHD_durationPosn; unsigned fMaxTrackDurationM; // in movie time units class SubsessionIOState* fCurrentIOState; }; diff -urN live.orig/liveMedia/QuickTimeFileSink.cpp live/liveMedia/QuickTimeFileSink.cpp --- live.orig/liveMedia/QuickTimeFileSink.cpp 2010-03-08 10:52:12.000000000 +0100 +++ live/liveMedia/QuickTimeFileSink.cpp 2010-03-12 14:54:10.000000000 +0100 @@ -21,6 +21,7 @@ #include "QuickTimeFileSink.hh" #include "QuickTimeGenericRTPSource.hh" #include "GroupsockHelper.hh" +#include "InputFile.hh" #include "OutputFile.hh" #include "H263plusVideoRTPSource.hh" // for the special header #include "MPEG4GenericRTPSource.hh" //for "samplingFrequencyFromAudioSpecificConfig()" @@ -36,19 +37,19 @@ class ChunkDescriptor { public: - ChunkDescriptor(unsigned offsetInFile, unsigned size, + ChunkDescriptor(int64_t offsetInFile, unsigned size, unsigned frameSize, unsigned frameDuration, struct timeval presentationTime); virtual ~ChunkDescriptor(); - ChunkDescriptor* extendChunk(unsigned newOffsetInFile, unsigned newSize, + ChunkDescriptor* extendChunk(int64_t newOffsetInFile, unsigned newSize, unsigned newFrameSize, unsigned newFrameDuration, struct timeval newPresentationTime); // this may end up allocating a new chunk instead public: ChunkDescriptor* fNextChunk; - unsigned fOffsetInFile; + int64_t fOffsetInFile; unsigned fNumFrames; unsigned fFrameSize; unsigned fFrameDuration; @@ -148,7 +149,7 @@ unsigned fQTTotNumSamples; unsigned fQTDurationM; // in media time units unsigned fQTDurationT; // in track time units - unsigned fTKHD_durationPosn; + int64_t fTKHD_durationPosn; // position of the duration in the output 'tkhd' atom unsigned fQTInitialOffsetDuration; // if there's a pause at the beginning @@ -179,7 +180,7 @@ // used by the above two routines: unsigned useFrame1(unsigned sourceDataSize, struct timeval presentationTime, - unsigned frameDuration, unsigned destFileOffset); + unsigned frameDuration, int64_t destFileOffset); // returns the number of samples in this data private: @@ -187,7 +188,7 @@ struct { unsigned frameSize; struct timeval presentationTime; - unsigned destFileOffset; // used for non-hint tracks only + int64_t destFileOffset; // used for non-hint tracks only // The remaining fields are used for hint tracks only: unsigned startSampleNumber; @@ -292,8 +293,10 @@ // Begin by writing a "mdat" atom at the start of the file. // (Later, when we've finished copying data to the file, we'll come // back and fill in its size.) - fMDATposition = ftell(fOutFid); - addAtomHeader("mdat"); + fMDATposition = TellFile64(fOutFid); + addAtomHeader64("mdat"); + // add 64Bit offset + fMDATposition += 8; } QuickTimeFileSink::~QuickTimeFileSink() { @@ -455,8 +458,8 @@ // Begin by filling in the initial "mdat" atom with the current // file size: - unsigned curFileSize = ftell(fOutFid); - setWord(fMDATposition, curFileSize); + int64_t curFileSize = TellFile64(fOutFid); + setWord64(fMDATposition, (u_int64_t)curFileSize); // Then, note the time of the first received data: MediaSubsessionIterator iter(fInputSession); @@ -750,7 +753,7 @@ unsigned char* const frameSource = buffer.dataStart(); unsigned const frameSize = buffer.bytesInUse(); struct timeval const& presentationTime = buffer.presentationTime(); - unsigned const destFileOffset = ftell(fOurSink.fOutFid); + int64_t const destFileOffset = TellFile64(fOurSink.fOutFid); unsigned sampleNumberOfFrameStart = fQTTotNumSamples + 1; Boolean avcHack = fQTMediaDataAtomCreator == &QuickTimeFileSink::addAtom_avc1; @@ -854,7 +857,7 @@ } } - unsigned const hintSampleDestFileOffset = ftell(fOurSink.fOutFid); + int64_t const hintSampleDestFileOffset = TellFile64(fOurSink.fOutFid); unsigned const maxPacketSize = 1450; unsigned short numPTEntries @@ -1009,7 +1012,7 @@ unsigned SubsessionIOState::useFrame1(unsigned sourceDataSize, struct timeval presentationTime, unsigned frameDuration, - unsigned destFileOffset) { + int64_t destFileOffset) { // Figure out the actual frame size for this data: unsigned frameSize = fQTBytesPerFrame; if (frameSize == 0) { @@ -1088,7 +1091,7 @@ } ChunkDescriptor -::ChunkDescriptor(unsigned offsetInFile, unsigned size, +::ChunkDescriptor(int64_t offsetInFile, unsigned size, unsigned frameSize, unsigned frameDuration, struct timeval presentationTime) : fNextChunk(NULL), fOffsetInFile(offsetInFile), @@ -1102,7 +1105,7 @@ } ChunkDescriptor* ChunkDescriptor -::extendChunk(unsigned newOffsetInFile, unsigned newSize, +::extendChunk(int64_t newOffsetInFile, unsigned newSize, unsigned newFrameSize, unsigned newFrameDuration, struct timeval newPresentationTime) { // First, check whether the new space is just at the end of this @@ -1130,6 +1133,15 @@ ////////// QuickTime-specific implementation ////////// +unsigned QuickTimeFileSink::addWord64(u_int64_t word) { + addByte(word>>56); addByte(word>>48); + addByte(word>>40); addByte(word>>32); + addByte(word>>24); addByte(word>>16); + addByte(word>>8); addByte(word); + + return 8; +} + unsigned QuickTimeFileSink::addWord(unsigned word) { addByte(word>>24); addByte(word>>16); addByte(word>>8); addByte(word); @@ -1188,11 +1200,37 @@ return 8; } -void QuickTimeFileSink::setWord(unsigned filePosn, unsigned size) { +unsigned QuickTimeFileSink::addAtomHeader64(char const* atomName) { + // Output 64Bit size marker + addWord(1); + + // Output the 4-byte atom name: + add4ByteString(atomName); + + addWord64(0); + + return 16; +} + +void QuickTimeFileSink::setWord(int64_t filePosn, unsigned size) { do { - if (fseek(fOutFid, filePosn, SEEK_SET) < 0) break; + if (SeekFile64(fOutFid, filePosn, SEEK_SET) < 0) break; addWord(size); - if (fseek(fOutFid, 0, SEEK_END) < 0) break; // go back to where we were + if (SeekFile64(fOutFid, 0, SEEK_END) < 0) break; // go back to where we were + + return; + } while (0); + + // One of the fseek()s failed, probable because we're not a seekable file + envir() << "QuickTimeFileSink::setWord(): fseek failed (err " + << envir().getErrno() << ")\n"; +} + +void QuickTimeFileSink::setWord64(int64_t filePosn, u_int64_t size) { + do { + if (SeekFile64(fOutFid, filePosn, SEEK_SET) < 0) break; + addWord64(size); + if (SeekFile64(fOutFid, 0, SEEK_END) < 0) break; // go back to where we were return; } while (0); @@ -1206,7 +1244,7 @@ #define addAtom(name) \ unsigned QuickTimeFileSink::addAtom_##name() { \ - unsigned initFilePosn = ftell(fOutFid); \ + int64_t initFilePosn = TellFile64(fOutFid); \ unsigned size = addAtomHeader("" #name "") #define addAtomEnd \ @@ -1273,7 +1311,7 @@ size += addWord(movieTimeScale()); // Time scale unsigned const duration = fMaxTrackDurationM; - fMVHD_durationPosn = ftell(fOutFid); + fMVHD_durationPosn = TellFile64(fOutFid); size += addWord(duration); // Duration size += addWord(0x00010000); // Preferred rate @@ -1327,7 +1365,7 @@ size += addWord(0x00000000); // Reserved unsigned const duration = fCurrentIOState->fQTDurationM; // movie units - fCurrentIOState->fTKHD_durationPosn = ftell(fOutFid); + fCurrentIOState->fTKHD_durationPosn = TellFile64(fOutFid); size += addWord(duration); // Duration size += addZeroWords(3); // Reserved+Layer+Alternate grp size += addWord(0x01000000); // Volume + Reserved @@ -1366,7 +1404,7 @@ // Add a dummy "Number of entries" field // (and remember its position). We'll fill this field in later: - unsigned numEntriesPosition = ftell(fOutFid); + int64_t numEntriesPosition = TellFile64(fOutFid); size += addWord(0); // dummy for "Number of entries" unsigned numEdits = 0; unsigned totalDurationOfEdits = 0; // in movie time units @@ -1525,7 +1563,7 @@ addAtomEnd; unsigned QuickTimeFileSink::addAtom_hdlr2() { - unsigned initFilePosn = ftell(fOutFid); + int64_t initFilePosn = TellFile64(fOutFid); unsigned size = addAtomHeader("hdlr"); size += addWord(0x00000000); // Version + Flags size += add4ByteString("dhlr"); // Component type @@ -1557,7 +1595,7 @@ } size += addAtom_stsc(); size += addAtom_stsz(); - size += addAtom_stco(); + size += addAtom_co64(); addAtomEnd; addAtom(stsd); @@ -1569,7 +1607,7 @@ addAtomEnd; unsigned QuickTimeFileSink::addAtom_genericMedia() { - unsigned initFilePosn = ftell(fOutFid); + int64_t initFilePosn = TellFile64(fOutFid); // Our source is assumed to be a "QuickTimeGenericRTPSource" // Use its "sdAtom" state for our contents: @@ -1582,7 +1620,7 @@ addAtomEnd; unsigned QuickTimeFileSink::addAtom_soundMediaGeneral() { - unsigned initFilePosn = ftell(fOutFid); + int64_t initFilePosn = TellFile64(fOutFid); unsigned size = addAtomHeader(fCurrentIOState->fQTAudioDataType); // General sample description fields: @@ -1606,7 +1644,7 @@ 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); + int64_t initFilePosn = TellFile64(fOutFid); fCurrentIOState->fQTAudioDataType = "Qclp"; fCurrentIOState->fQTSoundSampleVersion = 1; unsigned size = addAtom_soundMediaGeneral(); @@ -1659,16 +1697,20 @@ addAtomEnd; unsigned QuickTimeFileSink::addAtom_mp4a() { + unsigned size = 0; // The beginning of this atom looks just like a general Sound Media atom, // except with a version field of 1: - unsigned initFilePosn = ftell(fOutFid); + int64_t initFilePosn = TellFile64(fOutFid); fCurrentIOState->fQTAudioDataType = "mp4a"; - fCurrentIOState->fQTSoundSampleVersion = 1; - unsigned size = addAtom_soundMediaGeneral(); if (fGenerateMP4Format) { + fCurrentIOState->fQTSoundSampleVersion = 0; + size = addAtom_soundMediaGeneral(); size += addAtom_esds(); } else { + fCurrentIOState->fQTSoundSampleVersion = 1; + size = addAtom_soundMediaGeneral(); + // Next, add the four fields that are particular to version 1: // (Later, parameterize these #####) size += addWord(fCurrentIOState->fQTTimeUnitsPerSample); @@ -1720,7 +1762,7 @@ if (strcmp(subsession.mediumName(), "audio") == 0) { // MPEG-4 audio size += addWord(0x06808080); // ??? - size += addByte(0x01); // ??? + size += addHalfWord(0x0102); // ??? } else { // MPEG-4 video size += addHalfWord(0x0601); // ??? @@ -1847,7 +1889,7 @@ addAtomEnd; unsigned QuickTimeFileSink::addAtom_rtp() { - unsigned initFilePosn = ftell(fOutFid); + int64_t initFilePosn = TellFile64(fOutFid); unsigned size = addAtomHeader("rtp "); size += addWord(0x00000000); // Reserved (1st 4 bytes) @@ -1867,7 +1909,7 @@ // First, add a dummy "Number of entries" field // (and remember its position). We'll fill this field in later: - unsigned numEntriesPosition = ftell(fOutFid); + int64_t numEntriesPosition = TellFile64(fOutFid); size += addWord(0); // dummy for "Number of entries" // Then, run through the chunk descriptors, and enter the entries @@ -1909,7 +1951,7 @@ // First, add a dummy "Number of entries" field // (and remember its position). We'll fill this field in later: - unsigned numEntriesPosition = ftell(fOutFid); + int64_t numEntriesPosition = TellFile64(fOutFid); size += addWord(0); // dummy for "Number of entries" // Then, run through the chunk descriptors, counting up the total nuber of samples: @@ -1946,7 +1988,7 @@ // First, add a dummy "Number of entries" field // (and remember its position). We'll fill this field in later: - unsigned numEntriesPosition = ftell(fOutFid); + int64_t numEntriesPosition = TellFile64(fOutFid); size += addWord(0); // dummy for "Number of entries" // Then, run through the chunk descriptors, and enter the entries @@ -2037,14 +2079,14 @@ } addAtomEnd; -addAtom(stco); // Chunk Offset +addAtom(co64); // Chunk Offset size += addWord(0x00000000); // Version+flags size += addWord(fCurrentIOState->fNumChunks); // Number of entries // Run through the chunk descriptors, entering the file offsets: ChunkDescriptor* chunk = fCurrentIOState->fHeadChunk; while (chunk != NULL) { - size += addWord(chunk->fOffsetInFile); + size += addWord64(chunk->fOffsetInFile); chunk = chunk->fNextChunk; } @@ -2068,7 +2110,7 @@ addAtomEnd; unsigned QuickTimeFileSink::addAtom_sdp() { - unsigned initFilePosn = ftell(fOutFid); + int64_t initFilePosn = TellFile64(fOutFid); unsigned size = addAtomHeader("sdp "); // Add this subsession's SDP lines: @@ -2208,6 +2250,6 @@ // A dummy atom (with name "????"): unsigned QuickTimeFileSink::addAtom_dummy() { - unsigned initFilePosn = ftell(fOutFid); + int64_t initFilePosn = TellFile64(fOutFid); unsigned size = addAtomHeader("????"); addAtomEnd;
_______________________________________________ live-devel mailing list live-devel@lists.live555.com http://lists.live555.com/mailman/listinfo/live-devel