Update contrib.
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include <3gplibrary/mp4config.h>
17 #include <3gplibrary/mp4lib.h>
19 #include "mp4memwrap.h"
21 #include "mp4endian.h"
22 #include "mp4compose.h"
23 #include "mp4currenttime.h"
26 #define MP4_INT_MAX KMaxTInt32
27 #define MDAT_HEADER_SIZE 16
39 inline void updateChunkOffset(sampleTable *st, mp4_i32 index, mp4_i64 value)
41 if (value > MP4_INT_MAX)
42 st->stcoNeed64Bits = ETrue;
44 st->stcoChunkOffset[index] = value;
47 /* must be called after determineAudioTrakMetaDataSize and determineVideoTrakMetaDataSize */
48 size_t mvhdAtomSize(MP4HandleImp handle)
50 if (handle->videoDuration > MP4_INT_MAX || handle->audioDuration > MP4_INT_MAX)
62 /* helper functions */
63 mp4_i32 formatMdatHeader(mp4_u8 *buffer, mp4_i64 size);
68 * mp4_i32 updateVideoMetaData(MP4HandleImp handle,
74 * This function updates sample table atom data.
76 * One call of this function will generate one chunk in the MP4 file.
80 * handle MP4 library handle
81 * size Size of video frame to insert
82 * duration Duration of the video frame (in media timescale)
90 mp4_i32 updateVideoMetaData(MP4HandleImp handle, mp4_u32 size, mp4_u32 duration, mp4_bool keyframe)
92 if (handle->flags & MP4_FLAG_LONGCLIP)
94 if (handle->metaDataBlocks == BLOCK_LIMIT)
96 /* Write metadata to temporary files */
98 if (writeMetaDataTmp(handle) < 0)
102 handle->metaDataBlocks++;
105 handle->videoSampleTable->currentChunk++;
107 if (updateDecodingTimeToSample(handle, handle->videoSampleTable, duration) < 0)
110 if (updateSampleSize(handle, handle->videoSampleTable, size) < 0)
113 if (updateSampleToChunk(handle->videoSampleTable) < 0)
116 if (updateChunkOffset(handle, handle->videoSampleTable) < 0)
120 if (updateSyncSample(handle, handle->videoSampleTable) < 0)
130 * mp4_i32 updateAudioMetaData(MP4HandleImp handle,
132 * mp4_u32 numberofframes)
136 * This function updates sample table atom data.
138 * One call of this function will generate one chunk in the MP4 file.
142 * handle MP4 library handle
143 * size Size of video frame to insert
144 * duration Duration of audio frames (in timescale,
145 * see MP4ComposeAddAudioDescription)
153 mp4_i32 updateAudioMetaData(MP4HandleImp handle, mp4_u32 size, mp4_u32 duration)
155 if (handle->flags & MP4_FLAG_LONGCLIP)
157 if (handle->metaDataBlocks == BLOCK_LIMIT)
159 /* Write metadata to temporary files */
161 if (writeMetaDataTmp(handle) < 0)
165 handle->metaDataBlocks++;
168 handle->audioSampleTable->currentChunk++;
170 if (updateDecodingTimeToSample(handle, handle->audioSampleTable, duration) < 0)
173 if (updateSampleSize(handle, handle->audioSampleTable, size) < 0)
176 if (updateSampleToChunk(handle->audioSampleTable) < 0)
179 if (updateChunkOffset(handle, handle->audioSampleTable) < 0)
189 * mp4_i32 writeFTYPAndMDATToFile(MP4HandleImp handle)
193 * This function writes FTYP box to a file. In addition, it writes MDAT box
194 * size and type to a file. The function is used when meta data is put to
199 * handle MP4 library handle
207 mp4_i32 writeFTYPAndMDATToFile(MP4HandleImp handle)
213 if (writeFTYP(handle) < 0)
216 handle->ftypWritten = MP4TRUE;
219 i = formatMdatHeader(buf, (mp4_u32)0);
220 if (writeFile(handle, buf, i) < 0)
230 * mp4_i32 writeDataToFile(MP4HandleImp handle)
234 * This function writes meta and media data to a file.
238 * handle MP4 library handle
246 mp4_i32 writeDataToFile(MP4HandleImp handle)
248 PRINT((_L("e_writedatatofile 1")));
249 mp4_u32 metaDataSize = 0;
250 trakSize *audioTrackSize;
251 trakSize *videoTrackSize;
252 mp4_bool haveAudio = MP4FALSE;
253 mp4_bool haveVideo = MP4FALSE;
254 mp4_u8 ftypdelta = 0;
257 if ((handle->type & MP4_TYPE_AMR_NB) ||
258 (handle->type & MP4_TYPE_AMR_WB) ||
259 (handle->type & MP4_TYPE_QCELP_13K) ||
260 (handle->type & MP4_TYPE_MPEG4_AUDIO))
263 if ((handle->type & MP4_TYPE_H263_PROFILE_0) ||
264 (handle->type & MP4_TYPE_H263_PROFILE_3) ||
265 (handle->type & MP4_TYPE_MPEG4_VIDEO) ||
266 containsAvcVideo( handle->type ) )
269 if ((handle->generate3G2 && !(handle->type & MP4_TYPE_QCELP_13K)) ||
270 (!handle->generate3G2 && !(handle->type & MP4_TYPE_AMR_WB)))
271 ftypdelta = 4; /* one more additional compatible brand */
275 if( containsAvcVideo( handle->type ) )
280 PRINT((_L("e_writedatatofile_alloc_audiotrk 1")));
281 audioTrackSize = (trakSize *)mp4malloc(sizeof(trakSize));
282 if (audioTrackSize == NULL)
284 PRINT((_L("e_writedatatofile_alloc_audiotrk 0")));
286 PRINT((_L("e_writedatatofile_alloc_videotrk 1")));
287 videoTrackSize = (trakSize *)mp4malloc(sizeof(trakSize));
288 if (videoTrackSize == NULL)
290 mp4free(audioTrackSize);
294 PRINT((_L("e_writedatatofile_alloc_videotrk 0")));
298 PRINT((_L("e_writedatatofile_deter_audiotrk_metadatasize 1")));
299 if (determineAudioTrakMetaDataSize(handle, handle->audioSampleTable, audioTrackSize) < 0)
301 mp4free(audioTrackSize);
302 mp4free(videoTrackSize);
305 PRINT((_L("e_writedatatofile_deter_audiotrk_metadatasize 0")));
310 PRINT((_L("e_writedatatofile_deter_videotrk_metadatasize 1")));
311 if (determineVideoTrakMetaDataSize(handle, handle->videoSampleTable, videoTrackSize) < 0)
313 mp4free(audioTrackSize);
314 mp4free(videoTrackSize);
317 PRINT((_L("e_writedatatofile_deter_videotrk_metadatasize 0")));
320 if (handle->flags & MP4_FLAG_METADATALAST)
322 metaDataSize += (FTYP_SIZE + ftypdelta); /* ftyp */
323 handle->metaDataSize = metaDataSize;
327 metaDataSize += (FTYP_SIZE + ftypdelta); /* ftyp */
328 metaDataSize += 8; /* moov atomheader */
329 metaDataSize += mvhdAtomSize(handle); /* mvhd */
330 if (handle->moovUDTA)
332 metaDataSize += 8 + (mp4_u32)handle->moovUDTA->atomcontentsize;
334 metaDataSize += audioTrackSize->trak; /* Audio trak */
335 metaDataSize += videoTrackSize->trak; /* Video trak */
337 handle->metaDataSize = metaDataSize;
341 if (!(handle->flags & MP4_FLAG_LONGCLIP))
343 /* Update metadata pointers only if metadata is in memory */
347 PRINT((_L("e_writedatatofile_reupdata_audiometadata 1")));
348 if (reUpdateAudioMetaData(handle->audioSampleTable, metaDataSize) < 0)
350 mp4free(audioTrackSize);
351 mp4free(videoTrackSize);
355 PRINT((_L("e_writedatatofile_reupdata_audiometadata 0")));
360 PRINT((_L("e_writedatatofile_reupdata_videometadata 1")));
361 if (reUpdateVideoMetaData(handle->videoSampleTable, metaDataSize) < 0)
363 mp4free(audioTrackSize);
364 mp4free(videoTrackSize);
368 PRINT((_L("e_writedatatofile_reupdata_videometadata 0")));
373 /* Write the rest of metadata to temporary files */
374 PRINT((_L("e_writedatatofile_write_metadatablocks 1")));
375 if (handle->metaDataBlocks)
376 if (writeMetaDataTmp(handle) < 0)
378 mp4free(audioTrackSize);
379 mp4free(videoTrackSize);
382 PRINT((_L("e_writedatatofile_write_metadatablocks 0")));
386 if (handle->flags & MP4_FLAG_METADATALAST)
389 mp4_u32 moovSize = 0;
391 moovSize += 8; /* moov atomheader */
392 moovSize += mvhdAtomSize(handle); /* mvhd */
393 moovSize += audioTrackSize->trak; /* Audio trak */
394 moovSize += videoTrackSize->trak; /* Video trak */
395 if (handle->moovUDTA)
397 moovSize += 8 + handle->moovUDTA->atomcontentsize;
400 PRINT((_L("e_writedatatofile_write_moov 1")));
401 if (writeMOOV(handle, moovSize, haveAudio, haveVideo, audioTrackSize, videoTrackSize) < 0)
403 mp4free(audioTrackSize);
404 mp4free(videoTrackSize);
408 PRINT((_L("e_writedatatofile_write_moov 0")));
410 /* Overwrite media data size */
411 PRINT((_L("e_writedatatofile_update_moov_media_size 1")));
412 if(!handle->bufferWrite)
414 if (seekFileAbsWrite(handle, (FTYP_SIZE + ftypdelta)) != 0)
416 mp4free(audioTrackSize);
417 mp4free(videoTrackSize);
422 //make sure the buf is large enough to hold the mdat header
424 i = formatMdatHeader(buf, handle->mediaDataBytes);
425 if (writeFileUnbuffered(handle, buf, i) < 0)
427 mp4free(audioTrackSize);
428 mp4free(videoTrackSize);
431 PRINT((_L("e_writedatatofile_update_moov_media_size 0")));
435 PRINT((_L("e_writedatatofile_write_ftyp 1")));
436 if (writeFTYP(handle) < 0)
438 mp4free(audioTrackSize);
439 mp4free(videoTrackSize);
443 PRINT((_L("e_writedatatofile_write_ftyp 0")));
445 PRINT((_L("e_writedatatofile_write_new_moov 1")));
446 if (writeMOOV(handle, metaDataSize - (FTYP_SIZE + ftypdelta), haveAudio, haveVideo, audioTrackSize, videoTrackSize) < 0)
448 mp4free(audioTrackSize);
449 mp4free(videoTrackSize);
453 PRINT((_L("e_writedatatofile_write_new_moov 0")));
455 PRINT((_L("e_writedatatofile_write_new_mdia 1")));
456 if (writeMediaData(handle) < 0)
458 mp4free(audioTrackSize);
459 mp4free(videoTrackSize);
463 PRINT((_L("e_writedatatofile_write_new_mdia 0")));
466 PRINT((_L("e_writedatatofile_free_audioandvideotrks 1")));
467 mp4free(audioTrackSize);
468 mp4free(videoTrackSize);
469 PRINT((_L("e_writedatatofile_free_audioandvideotrks 0")));
470 PRINT((_L("e_writedatatofile 0")));
478 * mp4_i32 updateDecodingTimeToSample(MP4HandleImp handle,
484 * This function updates stts atom data.
488 * handle MP4 library handle
490 * duration Duration of sample to insert (in media timescale)
498 mp4_i32 updateDecodingTimeToSample(MP4HandleImp handle, sampleTable *st, mp4_u32 duration)
503 if (handle->flags & MP4_FLAG_LONGCLIP)
505 if (st->sttsCurrentEntryCount == 0)
507 st->sttsSampleCount[st->sttsCurrentEntryCount] = 1;
508 st->sttsSampleDelta[st->sttsCurrentEntryCount] = duration;
510 st->sttsCurrentEntryCount++;
511 st->sttsEntryCount++;
516 if (st->sttsCurrentEntryCount == st->sttsMaxEntryCount)
520 p = mp4realloc(st->sttsSampleCount,
521 2 * sizeof(mp4_u32) * st->sttsMaxEntryCount,
522 sizeof(mp4_u32) * st->sttsMaxEntryCount);
526 st->sttsSampleCount = (mp4_u32 *)p;
528 p = mp4realloc(st->sttsSampleDelta,
529 2 * sizeof(mp4_u32) * st->sttsMaxEntryCount,
530 sizeof(mp4_u32) * st->sttsMaxEntryCount);
534 st->sttsSampleDelta = (mp4_u32 *)p;
536 st->sttsMaxEntryCount *= 2;
539 if (st->sttsSampleDelta[st->sttsCurrentEntryCount - 1] == duration)
541 st->sttsSampleCount[st->sttsCurrentEntryCount - 1]++;
545 st->sttsSampleCount[st->sttsCurrentEntryCount] = 1;
546 st->sttsSampleDelta[st->sttsCurrentEntryCount] = duration;
548 st->sttsCurrentEntryCount++;
549 st->sttsEntryCount++;
554 if (st->sttsEntryCount == 0)
556 st->sttsSampleCount[st->sttsEntryCount]++;
557 st->sttsSampleDelta[st->sttsEntryCount] = duration;
559 st->sttsEntryCount++;
564 if (st->sttsEntryCount == st->sttsMaxEntryCount)
568 p = mp4realloc(st->sttsSampleCount,
569 2 * sizeof(mp4_u32) * st->sttsMaxEntryCount,
570 sizeof(mp4_u32) * st->sttsMaxEntryCount);
574 st->sttsSampleCount = (mp4_u32 *)p;
576 p = mp4realloc(st->sttsSampleDelta,
577 2 * sizeof(mp4_u32) * st->sttsMaxEntryCount,
578 sizeof(mp4_u32) * st->sttsMaxEntryCount);
582 st->sttsSampleDelta = (mp4_u32 *)p;
584 st->sttsMaxEntryCount *= 2;
587 if (st->sttsSampleDelta[st->sttsEntryCount - 1] == duration)
589 st->sttsSampleCount[st->sttsEntryCount - 1]++;
593 st->sttsSampleCount[st->sttsEntryCount] = 1;
594 st->sttsSampleDelta[st->sttsEntryCount] = duration;
596 st->sttsEntryCount++;
608 * mp4_i32 updateSampleSize(MP4HandleImp handle,
614 * This function updates stsz atom data.
618 * handle MP4 library handle
620 * size Size of sample in bytes
628 mp4_i32 updateSampleSize(MP4HandleImp handle, sampleTable *st, mp4_u32 size)
636 if (handle->flags & MP4_FLAG_LONGCLIP)
638 if (st->stszCurrentSampleCount == st->stszMaxSampleCount)
642 p = mp4realloc(st->stszEntrySize,
643 2 * sizeof(mp4_u32) * st->stszMaxSampleCount,
644 sizeof(mp4_u32) * st->stszMaxSampleCount);
648 st->stszEntrySize = (mp4_u32 *)p;
650 st->stszMaxSampleCount *= 2;
653 st->stszEntrySize[st->stszCurrentSampleCount] = size;
655 st->stszCurrentSampleCount++;
656 st->stszSampleCount++;
660 if (st->stszSampleCount == st->stszMaxSampleCount)
664 p = mp4realloc(st->stszEntrySize,
665 2 * sizeof(mp4_u32) * st->stszMaxSampleCount,
666 sizeof(mp4_u32) * st->stszMaxSampleCount);
670 st->stszEntrySize = (mp4_u32 *)p;
672 st->stszMaxSampleCount *= 2;
675 st->stszEntrySize[st->stszSampleCount] = size;
677 st->stszSampleCount++;
688 * mp4_i32 updateSampleToChunk(sampleTable *st)
692 * This function updates stsc atom data.
704 mp4_i32 updateSampleToChunk(sampleTable *st)
706 if (st->stscEntryCount != 0)
710 st->stscFirstChunk[st->stscEntryCount] = st->currentChunk;
711 st->stscSamplesPerChunk[st->stscEntryCount] = 1;
712 st->stscSampleDescriptionIndex[st->stscEntryCount] = 1; /* Note: Need to update here for multiple sample entry support */
713 st->stscEntryCount++;
722 * mp4_i32 updateChunkOffset(MP4HandleImp handle,
727 * This function updates stco atom data.
731 * handle MP4 library handle
740 mp4_i32 updateChunkOffset(MP4HandleImp handle, sampleTable *st)
742 if (handle->flags & MP4_FLAG_LONGCLIP)
744 if (st->stcoCurrentEntryCount == st->stcoMaxEntryCount)
748 p = mp4realloc(st->stcoChunkOffset,
749 2 * sizeof(mp4_u64) * st->stcoMaxEntryCount,
750 sizeof(mp4_u64) * st->stcoMaxEntryCount);
754 st->stcoChunkOffset = (mp4_u64*)p;
756 st->stcoMaxEntryCount *= 2;
759 if (handle->flags & MP4_FLAG_METADATALAST)
760 updateChunkOffset(st, st->stcoCurrentEntryCount, handle->mediaDataBytes);
762 updateChunkOffset(st, st->stcoCurrentEntryCount, handle->bytesInTmpFile);
764 st->stcoCurrentEntryCount++;
765 st->stcoEntryCount++;
769 if (st->stcoEntryCount == st->stcoMaxEntryCount)
773 p = mp4realloc(st->stcoChunkOffset,
774 2 * sizeof(mp4_u64) * st->stcoMaxEntryCount,
775 sizeof(mp4_u64) * st->stcoMaxEntryCount);
779 st->stcoChunkOffset = (mp4_u64 *)p;
781 st->stcoMaxEntryCount *= 2;
784 if (handle->flags & MP4_FLAG_METADATALAST)
785 updateChunkOffset(st, st->stcoEntryCount, handle->mediaDataBytes);
787 updateChunkOffset(st, st->stcoEntryCount, handle->bytesInTmpFile);
789 st->stcoEntryCount++;
800 * mp4_i32 updateSyncSample(MP4HandleImp handle,
805 * This function updates stss atom data.
809 * handle MP4 library handle
818 mp4_i32 updateSyncSample(MP4HandleImp handle, sampleTable *st)
820 if (handle->flags & MP4_FLAG_LONGCLIP)
822 if (st->stssCurrentEntryCount == st->stssMaxEntryCount)
826 p = mp4realloc(st->stssSampleNumber,
827 2 * sizeof(mp4_u32) * st->stssMaxEntryCount,
828 sizeof(mp4_u32) * st->stssMaxEntryCount);
832 st->stssSampleNumber = (mp4_u32 *)p;
834 st->stssMaxEntryCount *= 2;
837 st->stssSampleNumber[st->stssCurrentEntryCount] = handle->videoSampleNum;
838 st->stssCurrentEntryCount++;
839 st->stssEntryCount++;
843 if (st->stssEntryCount == st->stssMaxEntryCount)
847 p = mp4realloc(st->stssSampleNumber,
848 2 * sizeof(mp4_u32) * st->stssMaxEntryCount,
849 sizeof(mp4_u32) * st->stssMaxEntryCount);
853 st->stssSampleNumber = (mp4_u32 *)p;
855 st->stssMaxEntryCount *= 2;
858 st->stssSampleNumber[st->stssEntryCount] = handle->videoSampleNum;
859 st->stssEntryCount++;
870 * mp4_i32 determineAudioTrakMetaDataSize(MP4HandleImp handle,
876 * This function calculates the audio track meta data size.
880 * handle MP4 library handle
881 * st Sample table data
882 * ts Atom sizes are returned here
889 mp4_i32 determineAudioTrakMetaDataSize(MP4HandleImp handle, sampleTable *st, trakSize *ts)
891 if (handle->type & MP4_TYPE_AMR_NB) /* AMR-NB */
894 ts->samr = 36 + ts->damr;
895 ts->stsd = 16 + ts->samr;
897 else if (handle->type & MP4_TYPE_AMR_WB) /* AMR-WB */
900 ts->sawb = 36 + ts->damr;
901 ts->stsd = 16 + ts->sawb;
903 else if ((handle->type & MP4_TYPE_QCELP_13K) && (!handle->qcelpStoredAsMPEGAudio)) /* QCELP 13K stored in QCELPSampleEntry */
906 ts->sqcp = 36 + ts->dqcp;
907 ts->stsd = 16 + ts->sqcp;
909 else if ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio)) /* QCELP 13K stored in MP4AudioDescription */
911 calculateES_DescriptorSize(handle, MP4_TYPE_QCELP_13K);
912 ts->esds = 12 + handle->ES_DescriptorSize; /*37 + handle->audioDecSpecificInfoSize;*/
913 ts->mp4a = 36 + ts->esds;
914 ts->stsd = 16 + ts->mp4a;
916 else /* MPEG audio */
918 calculateES_DescriptorSize(handle, MP4_TYPE_MPEG4_AUDIO);
919 ts->esds = 12 + handle->ES_DescriptorSize; /*37 + handle->audioDecSpecificInfoSize;*/
920 ts->mp4a = 36 + ts->esds;
921 ts->stsd = 16 + ts->mp4a;
923 ts->stts = 16 + st->sttsEntryCount * 8;
924 ts->stsc = 16 + st->stscEntryCount * 12;
925 if (st->stszSampleSize != 0)
928 ts->stsz = 20 + st->stszSampleCount * 4;
929 ts->stco = 16 + st->stcoEntryCount * (st->stcoNeed64Bits ? 8 : 4);
930 ts->stbl = 8 + ts->stsd + ts->stts + ts->stsc + ts->stsz + ts->stco;
932 ts->dinf = 8 + ts->dref;
934 ts->minf = 8 + ts->smhd + ts->dinf + ts->stbl;
937 if (handle->audioDuration > MP4_INT_MAX)
948 ts->mdia = 8 + ts->mdhd + ts->hdlr + ts->minf;
949 if ( handle->audioUDTA )
951 ts->udta = 8 + handle->audioUDTA->atomcontentsize;
953 ts->trak = 8 + ts->tkhd + ts->mdia + ts->udta;
962 * mp4_i32 determineVideoTrakMetaDataSize(MP4HandleImp handle,
968 * This function calculates the video track meta data size.
972 * handle MP4 library handle
973 * st Sample table data
974 * ts Atom sizes are returned here
981 mp4_i32 determineVideoTrakMetaDataSize(MP4HandleImp handle, sampleTable *st, trakSize *ts)
983 /* Note: This functions assumes single sample entry per media track.
984 If necessary, modify to support multiple sample entries in the future. */
985 if ((handle->type & MP4_TYPE_H263_PROFILE_0) || (handle->type & MP4_TYPE_H263_PROFILE_3))
988 ts->s263 = 86 + ts->d263;
989 ts->stsd = 16 + ts->s263;
992 if ((handle->type & MP4_TYPE_MPEG4_VIDEO))
994 ts->esds = 37 + handle->videoDecSpecificInfoSize;
995 ts->mp4v = 86 + ts->esds;
996 ts->stsd = 16 + ts->mp4v;
999 if ( containsAvcVideo( handle->type ) )
1001 /* Note: If necessary, add btrt and m4ds boxes here in the future. */
1002 ts->avcc = 8 + handle->videoDecSpecificInfoSize; /*handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfigSize;*/
1003 ts->avc1 = 86 + ts->avcc;
1004 ts->stsd = 16 + ts->avc1;
1010 ts->stts = 16 + st->sttsEntryCount * 8;
1011 ts->stsc = 16 + st->stscEntryCount * 12;
1012 if (st->stszSampleSize != 0)
1015 ts->stsz = 20 + st->stszSampleCount * 4;
1016 ts->stco = 16 + st->stcoEntryCount * (st->stcoNeed64Bits ? 8 : 4);
1017 ts->stss = 16 + st->stssEntryCount * 4;
1018 if( handle->videoSampleTable->sdtpEntryCount )
1019 ts->sdtp = 4 + 4 + 1 + 3 + handle->videoSampleTable->sdtpEntryCount; //size + 'SDTP' + ver + flags + dependencies
1023 ts->stbl = 8 + ts->stsd + ts->stts + ts->stsc + ts->stsz + ts->stco + ts->stss + ts->sdtp;
1025 ts->dinf = 8 + ts->dref;
1027 ts->minf = 8 + ts->vmhd + ts->dinf + ts->stbl;
1030 if (handle->videoDuration > MP4_INT_MAX)
1041 ts->mdia = 8 + ts->mdhd + ts->hdlr + ts->minf;
1042 if ( handle->videoUDTA )
1044 ts->udta = 8 + handle->videoUDTA->atomcontentsize;
1046 ts->trak = 8 + ts->tkhd + ts->mdia + ts->udta;
1055 * mp4_i32 reUpdateAudioMetaData(sampleTable *st,
1056 * mp4_u32 metaDataSize)
1060 * This function updates the chunk offsets in the meta data to point to
1065 * st Sample table data
1066 * metaDataSize Meta data size
1073 mp4_i32 reUpdateAudioMetaData(sampleTable *st, mp4_u32 metaDataSize)
1078 for (i = 0; i < st->stcoEntryCount; i++)
1079 updateChunkOffset(st, i, st->stcoChunkOffset[i] + metaDataSize + MDAT_HEADER_SIZE);
1088 * mp4_i32 reUpdateVideoMetaData(sampleTable *st,
1089 * mp4_u32 metaDataSize)
1093 * This function updates the chunk offsets in the meta data to point to
1098 * st Sample table data
1099 * metaDataSize Meta data size
1106 mp4_i32 reUpdateVideoMetaData(sampleTable *st, mp4_u32 metaDataSize)
1111 for (i = 0; i < st->stcoEntryCount; i++)
1112 updateChunkOffset(st, i, st->stcoChunkOffset[i] + metaDataSize + MDAT_HEADER_SIZE);
1121 * mp4_i32 writeFTYP(MP4HandleImp handle)
1129 * handle MP4 library handle
1137 mp4_i32 writeFTYP(MP4HandleImp handle)
1141 mp4_u8 ftypdelta = 0;
1143 if ((handle->generate3G2 && !(handle->type & MP4_TYPE_QCELP_13K)) ||
1144 (!handle->generate3G2 && !(handle->type & MP4_TYPE_AMR_WB)))
1145 ftypdelta = 4; /* one more additional compatible brand */
1149 if( containsAvcVideo( handle->type ) )
1153 if(handle->bufferWrite)
1154 handle->ftypdelta=ftypdelta;
1156 buf = (mp4_u8 *)mp4malloc(FTYP_SIZE + ftypdelta);
1161 insertu32(buf+i, (mp4_u32)(FTYP_SIZE + ftypdelta));
1165 insertu32(buf+i, (mp4_u32)ATOMTYPE_FTYP);
1168 if ( containsAvcVideo( handle->type ) )
1170 if(handle->generateMP4)
1172 /* MPEG-4 Major brand */
1181 /* AVC is included for 3GPP Release 6 and beyond */
1191 if(handle->generateMP4)
1193 /* MPEG-4 Major brand */
1199 else if(handle->generate3G2)
1201 /* 3GPP2 Major brand */
1209 /* 3GPP Major brand */
1218 if(handle->generateMP4)
1219 { /* MPEG-4 Minor Version */
1220 insertu32(buf+i, (mp4_u32)(0)); /* 0 */
1223 else if(handle->generate3G2)
1224 { /* 3GPP2 Minor Version */
1225 if( containsAvcVideo( handle->type ) )
1227 insertu32(buf+i, (mp4_u32)(2*256*256)); /* VB.0.0 */
1232 insertu32(buf+i, (mp4_u32)(1*256*256)); /* VA.0.0 */
1237 { /* 3GPP Minor Version */
1238 if( containsAvcVideo( handle->type ) )
1240 insertu32(buf+i, (mp4_u32)2*256); /* V6.3.0 */
1245 insertu32(buf+i, (mp4_u32)4*256); /* V4.4.0 */
1250 /* Compatible brands */
1251 if(handle->generateMP4)
1252 {/* MPEG-4 Compatible Brands */
1267 if ( containsAvcVideo( handle->type ) )
1269 /* AVC is included for 3GPP Release 6 and beyond */
1276 else if(handle->generate3G2)
1277 {/* 3GPP2 Compatible Brands */
1278 if( containsAvcVideo( handle->type ) )
1284 if (!(handle->type & MP4_TYPE_QCELP_13K))
1285 { // If 3GPP codecs are used, then put 3GP6 in compatible brands
1298 if (!(handle->type & MP4_TYPE_QCELP_13K))
1299 { // If 3GPP codecs are used, then put 3GP4 in compatible brands
1306 if ( containsAvcVideo( handle->type ) )
1308 /* AVC is included for 3GPP Release 6 and beyond */
1321 {/* 3GPP Compatible Brands */
1322 if ( containsAvcVideo( handle->type ) )
1337 if (!(handle->type & MP4_TYPE_AMR_WB))
1338 { // If 3GPP2 codecs are used, then put 3G2A in compatible brands
1350 if ( containsAvcVideo( handle->type ) )
1352 /* AVC is included for 3GPP Release 6 and beyond */
1360 if (writeFile(handle, buf, (FTYP_SIZE + ftypdelta)) < 0)
1376 * mp4_i32 writeMOOV(MP4HandleImp handle,
1378 * mp4_bool haveAudio,
1379 * mp4_bool haveVideo,
1380 * trakSize *audioTrackSize,
1381 * trakSize *videoTrackSize)
1389 * handle MP4 library handle
1390 * moovSize Size of MOOV atom in bytes
1391 * haveAudio Flag to indicate whether audio exists or not
1392 * haveVideo Flag to indicate whether video exists or not
1393 * audioTrackSize Size of audio track in bytes
1394 * videoTrackSize Size of video track in bytes
1402 mp4_i32 writeMOOV(MP4HandleImp handle, mp4_u32 moovSize, mp4_bool haveAudio, mp4_bool haveVideo, trakSize *audioTrackSize, trakSize *videoTrackSize)
1404 PRINT((_L("e_writemoov 1")));
1410 insertu32(buf+i, moovSize);
1414 insertu32(buf+i, (mp4_u32)ATOMTYPE_MOOV);
1417 PRINT((_L("e_writemoov_header 1")));
1418 if (writeFile(handle, buf, 8) < 0)
1420 PRINT((_L("e_writemoov_header 0")));
1422 PRINT((_L("e_writemoov_mvhd 1")));
1423 if (writeMVHD(handle) < 0)
1425 PRINT((_L("e_writemoov_mvhd 0")));
1427 PRINT((_L("e_writemoov_video 1")));
1429 if (writeVideoTrak(handle, videoTrackSize) < 0)
1431 PRINT((_L("e_writemoov_video 0")));
1433 PRINT((_L("e_writemoov_audio 1")));
1435 if (writeAudioTrak(handle, audioTrackSize) < 0)
1437 PRINT((_L("e_writemoov_audio 0")));
1439 PRINT((_L("e_writemoov_udta 1")));
1440 if (handle->moovUDTA)
1442 if (writeUDTA(handle, handle->moovUDTA) < 0)
1447 PRINT((_L("e_writemoov_udta 0")));
1448 PRINT((_L("e_writemoov 0")));
1456 * mp4_i32 writeMVHD(MP4HandleImp handle)
1464 * handle MP4 library handle
1472 mp4_i32 writeMVHD(MP4HandleImp handle)
1478 size_t mvhdSize = mvhdAtomSize(handle);
1480 buf = (mp4_u8 *)mp4malloc(mvhdSize);
1485 insertu32(buf+i, (mp4_u32)mvhdSize);
1489 insertu32(buf+i, (mp4_u32)ATOMTYPE_MVHD);
1493 if (handle->videoDuration > MP4_INT_MAX || handle->audioDuration > MP4_INT_MAX)
1495 /* Version and flags */
1496 insertu32(buf+i, (mp4_u32)0x01000000); //its going to be a version 1 atom
1500 if (getCurrentTime(&u32) < 0)
1502 insertu64(buf+i, (mp4_u64)u32);
1505 /* Modification time */
1506 if (getCurrentTime(&u32) < 0)
1508 insertu64(buf+i, (mp4_u64)u32);
1512 insertu32(buf+i, (mp4_u32)MVHD_TIMESCALE);
1518 mp4_u64 videoDuration = 0;
1519 mp4_u64 audioDuration = 0;
1522 if (handle->videoTimeScale)
1523 videoDuration = (mp4_u64)((mp4_double)MVHD_TIMESCALE *
1524 (mp4_double)handle->videoDuration /
1525 (mp4_double)handle->videoTimeScale +
1527 if (handle->audioTimeScale)
1528 audioDuration = (mp4_u64)((mp4_double)MVHD_TIMESCALE *
1529 (mp4_double)handle->audioDuration /
1530 (mp4_double)handle->audioTimeScale +
1533 if (audioDuration > videoDuration)
1534 u64 = audioDuration;
1536 u64 = videoDuration;
1538 insertu64(buf+i, u64);
1545 /* Version and flags */
1546 insertu32(buf+i, (mp4_u32)0);
1550 if (getCurrentTime(&u32) < 0)
1552 insertu32(buf+i, (mp4_u32)u32);
1555 /* Modification time */
1556 if (getCurrentTime(&u32) < 0)
1558 insertu32(buf+i, (mp4_u32)u32);
1562 insertu32(buf+i, (mp4_u32)MVHD_TIMESCALE);
1567 mp4_u32 videoDuration = 0;
1568 mp4_u32 audioDuration = 0;
1571 if (handle->videoTimeScale)
1572 videoDuration = (mp4_u32)((mp4_double)MVHD_TIMESCALE *
1573 (mp4_double)handle->videoDuration /
1574 (mp4_double)handle->videoTimeScale +
1576 if (handle->audioTimeScale)
1577 audioDuration = (mp4_u32)((mp4_double)MVHD_TIMESCALE *
1578 (mp4_double)handle->audioDuration /
1579 (mp4_double)handle->audioTimeScale +
1582 if (audioDuration > videoDuration)
1583 u32 = audioDuration;
1585 u32 = videoDuration;
1587 insertu32(buf+i, u32);
1592 insertu32(buf+i, (mp4_u32)0x00010000);
1595 insertu16(buf+i, (mp4_u16)0x0100);
1598 insertu16(buf+i, (mp4_u16)0x0000);
1601 insertu32(buf+i, (mp4_u32)0x00000000);
1604 insertu32(buf+i, (mp4_u32)0x00000000);
1607 insertu32(buf+i, (mp4_u32)0x00010000);
1610 insertu32(buf+i, (mp4_u32)0x00000000);
1613 insertu32(buf+i, (mp4_u32)0x00000000);
1616 insertu32(buf+i, (mp4_u32)0x00000000);
1619 insertu32(buf+i, (mp4_u32)0x00010000);
1622 insertu32(buf+i, (mp4_u32)0x00000000);
1625 insertu32(buf+i, (mp4_u32)0x00000000);
1628 insertu32(buf+i, (mp4_u32)0x00000000);
1631 insertu32(buf+i, (mp4_u32)0x40000000);
1634 insertu32(buf+i, (mp4_u32)0x00000000);
1637 insertu32(buf+i, (mp4_u32)0x00000000);
1640 insertu32(buf+i, (mp4_u32)0x00000000);
1643 insertu32(buf+i, (mp4_u32)0x00000000);
1646 insertu32(buf+i, (mp4_u32)0x00000000);
1649 insertu32(buf+i, (mp4_u32)0x00000000);
1652 insertu32(buf+i, (mp4_u32)0x00010000);
1655 if (writeFile(handle, buf, mvhdSize) < 0)
1671 * mp4_i32 writeVideoTrak(MP4HandleImp handle,
1676 * Write video track atom.
1680 * handle MP4 library handle
1689 mp4_i32 writeVideoTrak(MP4HandleImp handle, trakSize *ts)
1696 insertu32(buf+i, (mp4_u32)ts->trak);
1700 insertu32(buf+i, (mp4_u32)ATOMTYPE_TRAK);
1703 if (writeFile(handle, buf, 8) < 0)
1706 if (writeVideoTKHD(handle, ts) < 0)
1709 if (writeVideoMDIA(handle, ts) < 0)
1712 if (handle->videoUDTA)
1714 if (writeUDTA(handle, handle->videoUDTA) < 0)
1725 * mp4_i32 writeVideoTKHD(MP4HandleImp handle,
1734 * handle MP4 library handle
1743 mp4_i32 writeVideoTKHD(MP4HandleImp handle, trakSize *ts)
1751 buf = (mp4_u8 *)mp4malloc(ts->tkhd);
1756 insertu32(buf+i, (mp4_u32)ts->tkhd);
1760 insertu32(buf+i, (mp4_u32)ATOMTYPE_TKHD);
1764 if (handle->videoDuration > MP4_INT_MAX)
1767 /* Version and flags */
1768 buf[i++] = 1; //make this a version 1 atom
1771 buf[i++] = 7; /* Track enabled, used in movie and preview */
1774 if (getCurrentTime(&u32) < 0)
1776 insertu64(buf+i, (mp4_u64)u32);
1779 /* Modification time */
1780 if (getCurrentTime(&u32) < 0)
1782 insertu64(buf+i, (mp4_u64)u32);
1786 insertu32(buf+i, (mp4_u32)1);
1790 insertu32(buf+i, (mp4_u32)0);
1794 if ( (handle->videoDuration == 0) || (handle->videoTimeScale == 0) )
1800 ud = (mp4_double)MVHD_TIMESCALE * (mp4_double)handle->videoDuration / (mp4_double)handle->videoTimeScale + (mp4_double)0.5;
1804 insertu64(buf+i, u64);
1809 /* Version and flags */
1813 buf[i++] = 7; /* Track enabled, used in movie and preview */
1816 if (getCurrentTime(&u32) < 0)
1818 insertu32(buf+i, (mp4_u32)u32);
1821 /* Modification time */
1822 if (getCurrentTime(&u32) < 0)
1824 insertu32(buf+i, (mp4_u32)u32);
1828 insertu32(buf+i, (mp4_u32)1);
1832 insertu32(buf+i, (mp4_u32)0);
1836 if ( (handle->videoDuration == 0) || (handle->videoTimeScale == 0) )
1842 ud = (mp4_double)MVHD_TIMESCALE * (mp4_double)handle->videoDuration / (mp4_double)handle->videoTimeScale + (mp4_double)0.5;
1846 insertu32(buf+i, u32);
1850 insertu32(buf+i, (mp4_u32)0);
1853 insertu32(buf+i, (mp4_u32)0);
1856 insertu32(buf+i, (mp4_u32)0);
1859 insertu16(buf+i, (mp4_u16)0); /* Visual track */
1862 insertu16(buf+i, (mp4_u16)0);
1865 insertu32(buf+i, (mp4_u32)0x00010000);
1868 insertu32(buf+i, (mp4_u32)0x00000000);
1871 insertu32(buf+i, (mp4_u32)0x00000000);
1874 insertu32(buf+i, (mp4_u32)0x00000000);
1877 insertu32(buf+i, (mp4_u32)0x00010000);
1880 insertu32(buf+i, (mp4_u32)0x00000000);
1883 insertu32(buf+i, (mp4_u32)0x00000000);
1886 insertu32(buf+i, (mp4_u32)0x00000000);
1889 insertu32(buf+i, (mp4_u32)0x40000000);
1892 insertu16(buf+i, (mp4_u16)handle->videoWidth); /* Width */
1895 insertu16(buf+i, (mp4_u16)0);
1898 insertu16(buf+i, (mp4_u16)handle->videoHeight); /* Height */
1901 insertu16(buf+i, (mp4_u16)0);
1904 if (writeFile(handle, buf, ts->tkhd) < 0)
1920 * mp4_i32 writeVideoMDIA(MP4HandleImp handle,
1925 * Write video MDIA atom.
1929 * handle MP4 library handle
1938 mp4_i32 writeVideoMDIA(MP4HandleImp handle, trakSize *ts)
1945 insertu32(buf+i, (mp4_u32)ts->mdia);
1949 insertu32(buf+i, (mp4_u32)ATOMTYPE_MDIA);
1952 if (writeFile(handle, buf, 8) < 0)
1955 if (writeVideoMDHD(handle, ts) < 0)
1958 if (writeVideoHDLR(handle, ts) < 0)
1961 if (writeVideoMINF(handle, ts) < 0)
1971 * mp4_i32 writeVideoMDHD(MP4HandleImp handle,
1976 * Write video MDHD atom.
1980 * handle MP4 library handle
1989 mp4_i32 writeVideoMDHD(MP4HandleImp handle, trakSize *ts)
1996 buf = (mp4_u8 *)mp4malloc(ts->mdhd);
2001 insertu32(buf+i, (mp4_u32)ts->mdhd);
2005 insertu32(buf+i, (mp4_u32)ATOMTYPE_MDHD);
2008 if (handle->videoDuration > MP4_INT_MAX)
2010 /* Version and flags */
2011 insertu32(buf+i, (mp4_u32)0x01000000); //version 1 atom
2015 if (getCurrentTime(&u32) < 0)
2017 insertu64(buf+i, (mp4_u64)u32);
2020 /* Modification time */
2021 if (getCurrentTime(&u32) < 0)
2023 insertu64(buf+i, (mp4_u64)u32);
2027 insertu32(buf+i, (mp4_u32)handle->videoTimeScale);
2031 insertu64(buf+i, handle->videoDuration);
2036 /* Version and flags */
2037 insertu32(buf+i, (mp4_u32)0);
2041 if (getCurrentTime(&u32) < 0)
2043 insertu32(buf+i, (mp4_u32)u32);
2046 /* Modification time */
2047 if (getCurrentTime(&u32) < 0)
2049 insertu32(buf+i, (mp4_u32)u32);
2053 insertu32(buf+i, (mp4_u32)handle->videoTimeScale);
2057 insertu32(buf+i, (mp4_u32)handle->videoDuration);
2062 insertu16(buf+i, (mp4_u16)0x55c4); /* 'und' */
2066 insertu16(buf+i, (mp4_u16)0x0000);
2069 if (writeFile(handle, buf, ts->mdhd) < 0)
2085 * mp4_i32 writeVideoHDLR(MP4HandleImp handle,
2090 * Write video HDLR atom.
2094 * handle MP4 library handle
2103 mp4_i32 writeVideoHDLR(MP4HandleImp handle, trakSize *ts)
2109 buf = (mp4_u8 *)mp4malloc(ts->hdlr);
2114 insertu32(buf+i, (mp4_u32)ts->hdlr);
2118 insertu32(buf+i, (mp4_u32)ATOMTYPE_HDLR);
2121 /* Version and flags */
2122 insertu32(buf+i, (mp4_u32)0);
2126 insertu32(buf+i, (mp4_u32)0);
2136 insertu32(buf+i, (mp4_u32)0);
2140 insertu32(buf+i, (mp4_u32)0);
2144 insertu32(buf+i, (mp4_u32)0);
2150 if (writeFile(handle, buf, ts->hdlr) < 0)
2166 * mp4_i32 writeVideoMINF(MP4HandleImp handle,
2171 * Write video MINF atom.
2175 * handle MP4 library handle
2184 mp4_i32 writeVideoMINF(MP4HandleImp handle, trakSize *ts)
2191 insertu32(buf+i, (mp4_u32)ts->minf);
2195 insertu32(buf+i, (mp4_u32)ATOMTYPE_MINF);
2198 if (writeFile(handle, buf, 8) < 0)
2201 if (writeVMHD(handle, ts) < 0)
2204 if (writeDINF(handle, ts) < 0)
2207 if (writeVideoSTBL(handle, ts) < 0)
2217 * mp4_i32 writeVMHD(MP4HandleImp handle,
2226 * handle MP4 library handle
2235 mp4_i32 writeVMHD(MP4HandleImp handle, trakSize *ts)
2241 buf = (mp4_u8 *)mp4malloc(ts->vmhd);
2246 insertu32(buf+i, (mp4_u32)ts->vmhd);
2250 insertu32(buf+i, (mp4_u32)ATOMTYPE_VMHD);
2253 /* Version and flags */
2254 insertu32(buf+i, (mp4_u32)0x00000001);
2258 insertu32(buf+i, (mp4_u32)0);
2261 insertu32(buf+i, (mp4_u32)0);
2264 if (writeFile(handle, buf, ts->vmhd) < 0)
2280 * mp4_i32 writeDINF(MP4HandleImp handle,
2289 * handle MP4 library handle
2298 mp4_i32 writeDINF(MP4HandleImp handle, trakSize *ts)
2305 insertu32(buf+i, (mp4_u32)ts->dinf);
2309 insertu32(buf+i, (mp4_u32)ATOMTYPE_DINF);
2312 if (writeFile(handle, buf, 8) < 0)
2315 if (writeDREF(handle, ts) < 0)
2325 * mp4_i32 writeDREF(MP4HandleImp handle,
2334 * handle MP4 library handle
2343 mp4_i32 writeDREF(MP4HandleImp handle, trakSize *ts)
2349 buf = (mp4_u8 *)mp4malloc(ts->dref);
2354 insertu32(buf+i, (mp4_u32)ts->dref);
2358 insertu32(buf+i, (mp4_u32)ATOMTYPE_DREF);
2361 /* Version and flags */
2362 insertu32(buf+i, (mp4_u32)0);
2366 insertu32(buf+i, (mp4_u32)1);
2372 insertu32(buf+i, (mp4_u32)12);
2376 insertu32(buf+i, (mp4_u32)ATOMTYPE_URL);
2379 /* Version and flags */
2380 insertu32(buf+i, (mp4_u32)0x00000001);
2383 if (writeFile(handle, buf, ts->dref) < 0)
2399 * mp4_i32 writeVideoSTBL(MP4HandleImp handle,
2404 * Write video STBL atom.
2408 * handle MP4 library handle
2417 mp4_i32 writeVideoSTBL(MP4HandleImp handle, trakSize *ts)
2424 insertu32(buf+i, (mp4_u32)ts->stbl);
2428 insertu32(buf+i, (mp4_u32)ATOMTYPE_STBL);
2431 if (writeFile(handle, buf, 8) < 0)
2434 if (writeVideoSTSD(handle, ts) < 0)
2437 if (handle->flags & MP4_FLAG_LONGCLIP)
2439 if (writeVideoSTTSLongClip(handle, ts) < 0)
2444 if (writeVideoSTTS(handle, ts) < 0)
2448 if (writeVideoSTSC(handle, ts) < 0)
2451 if (handle->flags & MP4_FLAG_LONGCLIP)
2453 if (writeVideoSTSZLongClip(handle, ts) < 0)
2456 if (handle->videoSampleTable->stcoNeed64Bits)
2458 if (writeVideoCO64LongClip(handle, ts) < 0)
2463 if (writeVideoSTCOLongClip(handle, ts) < 0)
2467 if (writeVideoSTSSLongClip(handle, ts) < 0)
2470 if(ts->sdtp && writeVideoSDTPLongClip(handle, ts) < 0)
2475 if (writeVideoSTSZ(handle, ts) < 0)
2478 if (handle->videoSampleTable->stcoNeed64Bits)
2480 if (writeVideoCO64(handle, ts) < 0)
2485 if (writeVideoSTCO(handle, ts) < 0)
2489 if (writeVideoSTSS(handle, ts) < 0)
2492 if(ts->sdtp && writeVideoSDTP(handle, ts) < 0)
2502 * mp4_i32 writeVideoSTSD(MP4HandleImp handle,
2507 * Write video STSD atom.
2511 * handle MP4 library handle
2520 mp4_i32 writeVideoSTSD(MP4HandleImp handle, trakSize *ts)
2527 insertu32(buf+i, (mp4_u32)ts->stsd);
2531 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSD);
2534 /* Version and flags */
2535 insertu32(buf+i, (mp4_u32)0);
2539 insertu32(buf+i, (mp4_u32)1);
2542 if (writeFile(handle, buf, 16) < 0)
2545 if (handle->type & MP4_TYPE_MPEG4_VIDEO)
2547 if (writeMP4V(handle, ts) < 0)
2550 else if ((handle->type & MP4_TYPE_H263_PROFILE_0) ||
2551 (handle->type & MP4_TYPE_H263_PROFILE_3))
2553 if (writeS263(handle, ts) < 0)
2556 else if ( containsAvcVideo( handle->type ) )
2558 if (writeAVC1(handle, ts) < 0)
2572 * mp4_i32 writeMP4V(MP4HandleImp handle,
2581 * handle MP4 library handle
2590 mp4_i32 writeMP4V(MP4HandleImp handle, trakSize *ts)
2596 buf = (mp4_u8 *)mp4malloc(86);
2601 insertu32(buf+i, (mp4_u32)ts->mp4v);
2605 insertu32(buf+i, (mp4_u32)ATOMTYPE_MP4V);
2616 /* Data reference index */
2617 insertu16(buf+i, (mp4_u16)1);
2621 insertu32(buf+i, (mp4_u32)0);
2624 insertu32(buf+i, (mp4_u32)0);
2627 insertu32(buf+i, (mp4_u32)0);
2630 insertu32(buf+i, (mp4_u32)0);
2634 insertu16(buf+i, (mp4_u16)handle->videoWidth);
2638 insertu16(buf+i, (mp4_u16)handle->videoHeight);
2642 insertu32(buf+i, (mp4_u32)0x00480000);
2645 insertu32(buf+i, (mp4_u32)0x00480000);
2648 insertu32(buf+i, (mp4_u32)0);
2651 insertu16(buf+i, (mp4_u16)1);
2654 insertu32(buf+i, (mp4_u32)0);
2657 insertu32(buf+i, (mp4_u32)0);
2660 insertu32(buf+i, (mp4_u32)0);
2663 insertu32(buf+i, (mp4_u32)0);
2666 insertu32(buf+i, (mp4_u32)0);
2669 insertu32(buf+i, (mp4_u32)0);
2672 insertu32(buf+i, (mp4_u32)0);
2675 insertu32(buf+i, (mp4_u32)0);
2678 insertu16(buf+i, (mp4_u16)24);
2681 insertu16(buf+i, (mp4_u16)0xffff);
2684 if (writeFile(handle, buf, 86) < 0)
2691 if (writeVideoESD(handle, ts) < 0)
2707 * mp4_i32 writeVideoESD(MP4HandleImp handle,
2712 * Write video ESD atom.
2716 * handle MP4 library handle
2725 mp4_i32 writeVideoESD(MP4HandleImp handle, trakSize *ts)
2731 buf = (mp4_u8 *)mp4malloc(ts->esds);
2736 insertu32(buf+i, (mp4_u32)ts->esds);
2740 insertu32(buf+i, (mp4_u32)ATOMTYPE_ESD);
2743 /* Version and flags */
2744 insertu32(buf+i, (mp4_u32)0);
2751 buf[i++] = (mp4_u8)(23 + handle->videoDecSpecificInfoSize);
2754 insertu16(buf+i, (mp4_u16)0);
2760 /* DecoderConfigDescrTag */
2764 buf[i++] = (mp4_u8)(15 + handle->videoDecSpecificInfoSize);
2766 /* ObjectTypeIndication */
2778 insertu32(buf+i, (mp4_u32)handle->videoMaxBitrate);
2782 insertu32(buf+i, (mp4_u32)handle->videoAvgBitrate);
2785 /* DecSpecificInfoTag */
2789 buf[i++] = (mp4_u8)handle->videoDecSpecificInfoSize;
2791 /* DecoderSpecificInfo */
2792 mp4memcpy(buf+i, handle->videoDecSpecificInfo, handle->videoDecSpecificInfoSize);
2793 i += handle->videoDecSpecificInfoSize;
2795 /* SLConfigDescrTag */
2804 if (writeFile(handle, buf, ts->esds) < 0)
2820 * mp4_i32 writeS263(MP4HandleImp handle,
2829 * handle MP4 library handle
2838 mp4_i32 writeS263(MP4HandleImp handle, trakSize *ts)
2844 buf = (mp4_u8 *)mp4malloc(86);
2849 insertu32(buf+i, (mp4_u32)ts->s263);
2853 insertu32(buf+i, (mp4_u32)ATOMTYPE_S263);
2864 /* Data reference index */
2865 insertu16(buf+i, (mp4_u16)1);
2869 insertu32(buf+i, (mp4_u32)0);
2872 insertu32(buf+i, (mp4_u32)0);
2875 insertu32(buf+i, (mp4_u32)0);
2878 insertu32(buf+i, (mp4_u32)0);
2882 insertu16(buf+i, (mp4_u16)handle->videoWidth);
2886 insertu16(buf+i, (mp4_u16)handle->videoHeight);
2890 insertu32(buf+i, (mp4_u32)0x00480000);
2893 insertu32(buf+i, (mp4_u32)0x00480000);
2896 insertu32(buf+i, (mp4_u32)0);
2899 insertu16(buf+i, (mp4_u16)1);
2902 insertu32(buf+i, (mp4_u32)0);
2905 insertu32(buf+i, (mp4_u32)0);
2908 insertu32(buf+i, (mp4_u32)0);
2911 insertu32(buf+i, (mp4_u32)0);
2914 insertu32(buf+i, (mp4_u32)0);
2917 insertu32(buf+i, (mp4_u32)0);
2920 insertu32(buf+i, (mp4_u32)0);
2923 insertu32(buf+i, (mp4_u32)0);
2926 insertu16(buf+i, (mp4_u16)24);
2929 insertu16(buf+i, (mp4_u16)0xffff);
2932 if (writeFile(handle, buf, 86) < 0)
2939 if (writeD263(handle, ts) < 0)
2955 * mp4_i32 writeD263(MP4HandleImp handle,
2964 * handle MP4 library handle
2973 mp4_i32 writeD263(MP4HandleImp handle, trakSize *ts)
2980 insertu32(buf+i, (mp4_u32)ts->d263);
2984 insertu32(buf+i, (mp4_u32)ATOMTYPE_D263);
2993 /* Decoder version */
2997 buf[i++] = handle->videoLevel;
3000 if (handle->type & MP4_TYPE_H263_PROFILE_0)
3002 else if (handle->type & MP4_TYPE_H263_PROFILE_3)
3007 if (writeFile(handle, buf, 15) < 0)
3016 * mp4_i32 writeAVC1(MP4HandleImp handle,
3025 * handle MP4 library handle
3034 mp4_i32 writeAVC1(MP4HandleImp handle, trakSize *ts)
3040 buf = (mp4_u8 *)mp4malloc(86);
3045 insertu32(buf+i, (mp4_u32)ts->avc1);
3049 insertu32(buf+i, (mp4_u32)ATOMTYPE_AVC1);
3060 /* Data reference index */
3061 insertu16(buf+i, (mp4_u16)1);
3065 insertu32(buf+i, (mp4_u32)0);
3068 insertu32(buf+i, (mp4_u32)0);
3071 insertu32(buf+i, (mp4_u32)0);
3074 insertu32(buf+i, (mp4_u32)0);
3078 insertu16(buf+i, (mp4_u16)handle->videoWidth);
3082 insertu16(buf+i, (mp4_u16)handle->videoHeight);
3085 /* H-res (default is 72dpi = 0x00480000) */
3086 insertu32(buf+i, (mp4_u32)0x00480000);
3089 /* V-res (default is 72dpi = 0x00480000) */
3090 insertu32(buf+i, (mp4_u32)0x00480000);
3094 insertu32(buf+i, (mp4_u32)0);
3097 /* Frame count (default is 1) */
3098 insertu16(buf+i, (mp4_u16)1);
3101 /* Compressor name (32 byte string) */
3102 // The spec *recommends* inserting "\012AVC Coding" here
3103 // but we just have a string of nulls.
3104 insertu32(buf+i, (mp4_u32)0);
3107 insertu32(buf+i, (mp4_u32)0);
3110 insertu32(buf+i, (mp4_u32)0);
3113 insertu32(buf+i, (mp4_u32)0);
3116 insertu32(buf+i, (mp4_u32)0);
3119 insertu32(buf+i, (mp4_u32)0);
3122 insertu32(buf+i, (mp4_u32)0);
3125 insertu32(buf+i, (mp4_u32)0);
3128 /* Depth (default is 0x0018 which indicates colour images with no alpha) */
3129 insertu16(buf+i, (mp4_u16)24);
3132 /* Pre-defined (-1) */
3133 insertu16(buf+i, (mp4_u16)0xffff);
3136 if (writeFile(handle, buf, 86) < 0)
3143 if (writeAVCC(handle, ts) < 0)
3150 /* Note: If necessary, include writing of btrt and m4ds atoms. */
3160 * mp4_i32 writeAVCC(MP4HandleImp handle,
3169 * handle MP4 library handle
3178 mp4_i32 writeAVCC(MP4HandleImp handle, trakSize *ts)
3184 buf = (mp4_u8 *)mp4malloc(ts->avcc);
3189 insertu32(buf+i, (mp4_u32)ts->avcc);
3193 insertu32(buf+i, (mp4_u32)ATOMTYPE_AVCC);
3196 /*mp4memcpy(buf+i, handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfig,
3197 handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfigSize);*/
3199 mp4memcpy(buf+i, handle->videoDecSpecificInfo, handle->videoDecSpecificInfoSize);
3201 /*i += handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfigSize;*/
3203 i += handle->videoDecSpecificInfoSize;
3205 if (writeFile(handle, buf, ts->avcc) < 0)
3221 * mp4_i32 writeVideoSTTS(MP4HandleImp handle,
3226 * Write video STTS atom.
3230 * handle MP4 library handle
3239 mp4_i32 writeVideoSTTS(MP4HandleImp handle, trakSize *ts)
3246 buf = (mp4_u8 *)mp4malloc(ts->stts);
3251 insertu32(buf+i, (mp4_u32)ts->stts);
3255 insertu32(buf+i, (mp4_u32)ATOMTYPE_STTS);
3258 /* Version and flags */
3259 insertu32(buf+i, (mp4_u32)0);
3263 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->sttsEntryCount);
3266 /* Sample count and sample delta */
3267 for (j = 0; j < handle->videoSampleTable->sttsEntryCount; j++)
3269 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->sttsSampleCount[j]);
3271 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->sttsSampleDelta[j]);
3275 if (writeFile(handle, buf, ts->stts) < 0)
3291 * mp4_i32 writeVideoSTTSLongClip(MP4HandleImp handle,
3296 * Write video STTS atom.
3300 * handle MP4 library handle
3309 mp4_i32 writeVideoSTTSLongClip(MP4HandleImp handle, trakSize *ts)
3316 mp4_u32 bytestoread;
3319 buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
3323 buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE / 2);
3331 insertu32(buf+i, (mp4_u32)ts->stts);
3335 insertu32(buf+i, (mp4_u32)ATOMTYPE_STTS);
3338 /* Version and flags */
3339 insertu32(buf+i, (mp4_u32)0);
3343 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->sttsEntryCount);
3346 if (writeFile(handle, buf, i) < 0)
3354 /* Sample count and delta */
3356 /* Seek to the beginning of temporary files */
3358 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STTS_SAMPLE_COUNT) < 0)
3364 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STTS_SAMPLE_DELTA) < 0)
3371 left = handle->videoSampleTable->sttsEntryCount * 4; /* Bytes left in each file */
3375 if (left > METADATA_COPY_BUFFERSIZE / 2)
3376 bytestoread = METADATA_COPY_BUFFERSIZE / 2;
3380 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STTS_SAMPLE_COUNT) < 0)
3388 for (j = 0; j < bytestoread; j += 4)
3390 insertu32(buf + 2*j, ((mp4_u32 *)buf2)[j / 4]);
3393 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STTS_SAMPLE_DELTA) < 0)
3401 for (j = 0; j < bytestoread; j += 4)
3403 insertu32(buf + 2*j + 4, ((mp4_u32 *)buf2)[j / 4]);
3406 if (writeFile(handle, buf, 2 * bytestoread) < 0)
3414 left -= bytestoread;
3428 * mp4_i32 writeVideoSTSC(MP4HandleImp handle,
3433 * Write video STSC atom.
3437 * handle MP4 library handle
3446 mp4_i32 writeVideoSTSC(MP4HandleImp handle, trakSize *ts)
3453 buf = (mp4_u8 *)mp4malloc(ts->stsc);
3458 insertu32(buf+i, (mp4_u32)ts->stsc);
3462 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSC);
3465 /* Version and flags */
3466 insertu32(buf+i, (mp4_u32)0);
3470 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stscEntryCount);
3473 /* First chunk, samples per chunk and sample description index */
3474 for (j = 0; j < handle->videoSampleTable->stscEntryCount; j++)
3476 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stscFirstChunk[j]);
3478 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stscSamplesPerChunk[j]);
3480 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stscSampleDescriptionIndex[j]);
3484 if (writeFile(handle, buf, ts->stsc) < 0)
3500 * mp4_i32 writeVideoSTSZ(MP4HandleImp handle,
3505 * Write video STSZ atom.
3509 * handle MP4 library handle
3518 mp4_i32 writeVideoSTSZ(MP4HandleImp handle, trakSize *ts)
3525 buf = (mp4_u8 *)mp4malloc(ts->stsz);
3530 insertu32(buf+i, (mp4_u32)ts->stsz);
3534 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSZ);
3537 /* Version and flags */
3538 insertu32(buf+i, (mp4_u32)0);
3542 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszSampleSize);
3546 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszSampleCount);
3550 if (handle->videoSampleTable->stszSampleSize == 0)
3552 for (j = 0; j < handle->videoSampleTable->stszSampleCount; j++)
3554 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszEntrySize[j]);
3559 if (writeFile(handle, buf, ts->stsz) < 0)
3575 * mp4_i32 writeVideoSTSZLongClip(MP4HandleImp handle,
3580 * Write video STSZ atom.
3584 * handle MP4 library handle
3593 mp4_i32 writeVideoSTSZLongClip(MP4HandleImp handle, trakSize *ts)
3600 mp4_u32 bytestoread;
3603 buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
3607 buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
3615 insertu32(buf+i, (mp4_u32)ts->stsz);
3619 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSZ);
3622 /* Version and flags */
3623 insertu32(buf+i, (mp4_u32)0);
3627 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszSampleSize);
3631 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszSampleCount);
3634 if (writeFile(handle, buf, i) < 0)
3644 if (handle->videoSampleTable->stszSampleSize == 0)
3646 /* Seek to the beginning of temporary file */
3648 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STSZ_ENTRY_SIZE) < 0)
3655 left = handle->videoSampleTable->stszSampleCount * 4; /* Bytes left in the file */
3659 if (left > METADATA_COPY_BUFFERSIZE)
3660 bytestoread = METADATA_COPY_BUFFERSIZE;
3664 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STSZ_ENTRY_SIZE) < 0)
3672 for (j = 0; j < bytestoread; j += 4)
3674 insertu32(buf + j, ((mp4_u32 *)buf2)[j / 4]);
3677 if (writeFile(handle, buf, bytestoread) < 0)
3685 left -= bytestoread;
3700 * mp4_i32 writeVideoSTCO(MP4HandleImp handle,
3705 * Write video STCO atom.
3709 * handle MP4 library handle
3718 mp4_i32 writeVideoSTCO(MP4HandleImp handle, trakSize *ts)
3725 buf = (mp4_u8 *)mp4malloc(ts->stco);
3730 insertu32(buf+i, (mp4_u32)ts->stco);
3734 insertu32(buf+i, (mp4_u32)ATOMTYPE_STCO);
3737 /* Version and flags */
3738 insertu32(buf+i, (mp4_u32)0);
3742 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoEntryCount);
3746 for (j = 0; j < handle->videoSampleTable->stcoEntryCount; j++)
3748 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoChunkOffset[j]);
3752 if (writeFile(handle, buf, ts->stco) < 0)
3767 * mp4_i32 writeVideoCO64(MP4HandleImp handle,
3772 * Write video CO64 atom.
3776 * handle MP4 library handle
3785 mp4_i32 writeVideoCO64(MP4HandleImp handle, trakSize *ts)
3792 buf = (mp4_u8 *)mp4malloc(ts->stco);
3797 insertu32(buf+i, (mp4_u32)ts->stco);
3801 insertu32(buf+i, (mp4_u32)ATOMTYPE_CO64);
3804 /* Version and flags */
3805 insertu32(buf+i, (mp4_u32)0);
3809 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoEntryCount);
3813 for (j = 0; j < handle->videoSampleTable->stcoEntryCount; j++)
3815 insertu64(buf+i, (mp4_u64)handle->videoSampleTable->stcoChunkOffset[j]);
3819 if (writeFile(handle, buf, ts->stco) < 0)
3834 * mp4_i32 writeVideoSTCOLongClip(MP4HandleImp handle,
3839 * Write video STCO atom.
3843 * handle MP4 library handle
3852 mp4_i32 writeVideoSTCOLongClip(MP4HandleImp handle, trakSize *ts)
3859 mp4_u32 bytestoread;
3860 mp4_u32 bufferSize = (METADATA_COPY_BUFFERSIZE/sizeof(mp4_u64)) * sizeof(mp4_u64); //must be a multiple of u64
3861 //METADATA_COPY_BUFFERSIZE is only guaranteed to be a multiple of 4
3863 buf = (mp4_u8 *)mp4malloc(bufferSize);
3867 buf2 = (mp4_u8 *)mp4malloc(bufferSize);
3875 insertu32(buf+i, (mp4_u32)ts->stco);
3879 insertu32(buf+i, (mp4_u32)ATOMTYPE_STCO);
3882 /* Version and flags */
3883 insertu32(buf+i, (mp4_u32)0);
3887 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoEntryCount);
3890 if (writeFile(handle, buf, i) < 0)
3900 /* Seek to the beginning of temporary file */
3902 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
3909 left = handle->videoSampleTable->stcoEntryCount * 8; /* Bytes left in the file */
3913 if (left > bufferSize)
3914 bytestoread = bufferSize;
3918 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
3926 for (j = 0; j < bytestoread; j += 8)
3928 ((mp4_u64 *)buf2)[j / 8] += (handle->metaDataSize + MDAT_HEADER_SIZE); /* Update chunk offsets */
3929 insertu32(buf + j/2, ((mp4_u64 *)buf2)[j / 8]);
3932 if (writeFile(handle, buf, bytestoread/2) < 0)
3940 left -= bytestoread;
3953 * mp4_i32 writeVideoCO64LongClip(MP4HandleImp handle,
3958 * Write video CO64 atom.
3962 * handle MP4 library handle
3971 mp4_i32 writeVideoCO64LongClip(MP4HandleImp handle, trakSize *ts)
3978 mp4_u32 bytestoread;
3979 mp4_u32 bufferSize = (METADATA_COPY_BUFFERSIZE/sizeof(mp4_u64)) * sizeof(mp4_u64); //must be a multiple of u64
3980 //METADATA_COPY_BUFFERSIZE is only guaranteed to be a multiple of 4
3982 buf = (mp4_u8 *)mp4malloc(bufferSize);
3986 buf2 = (mp4_u8 *)mp4malloc(bufferSize);
3994 insertu32(buf+i, (mp4_u32)ts->stco);
3998 insertu32(buf+i, (mp4_u32)ATOMTYPE_CO64);
4001 /* Version and flags */
4002 insertu32(buf+i, (mp4_u32)0);
4006 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoEntryCount);
4009 if (writeFile(handle, buf, i) < 0)
4019 /* Seek to the beginning of temporary file */
4021 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
4028 left = handle->videoSampleTable->stcoEntryCount * 8; /* Bytes left in the file */
4032 if (left > bufferSize)
4033 bytestoread = bufferSize;
4037 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
4045 for (j = 0; j < bytestoread; j += 8)
4047 ((mp4_u64 *)buf2)[j / 8] += (handle->metaDataSize + MDAT_HEADER_SIZE); /* Update chunk offsets */
4048 insertu64(buf + j, ((mp4_u64 *)buf2)[j / 8]);
4051 if (writeFile(handle, buf, bytestoread) < 0)
4059 left -= bytestoread;
4072 * mp4_i32 writeVideoSTSS(MP4HandleImp handle,
4077 * Write video STSS atom.
4081 * handle MP4 library handle
4090 mp4_i32 writeVideoSTSS(MP4HandleImp handle, trakSize *ts)
4097 buf = (mp4_u8 *)mp4malloc(ts->stss);
4102 insertu32(buf+i, (mp4_u32)ts->stss);
4106 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSS);
4109 /* Version and flags */
4110 insertu32(buf+i, (mp4_u32)0);
4114 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stssEntryCount);
4117 /* Sample numbers */
4118 for (j = 0; j < handle->videoSampleTable->stssEntryCount; j++)
4120 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stssSampleNumber[j]);
4124 if (writeFile(handle, buf, ts->stss) < 0)
4140 * mp4_i32 writeVideoSTSSLongClip(MP4HandleImp handle,
4145 * Write video STSS atom.
4149 * handle MP4 library handle
4158 mp4_i32 writeVideoSTSSLongClip(MP4HandleImp handle, trakSize *ts)
4165 mp4_u32 bytestoread;
4168 buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
4172 buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
4180 insertu32(buf+i, (mp4_u32)ts->stss);
4184 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSS);
4187 /* Version and flags */
4188 insertu32(buf+i, (mp4_u32)0);
4192 insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stssEntryCount);
4195 if (writeFile(handle, buf, i) < 0)
4203 /* Sample numbers */
4205 /* Seek to the beginning of temporary file */
4207 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STSS_SAMPLE_NUMBER) < 0)
4214 left = handle->videoSampleTable->stssEntryCount * 4; /* Bytes left in the file */
4218 if (left > METADATA_COPY_BUFFERSIZE)
4219 bytestoread = METADATA_COPY_BUFFERSIZE;
4223 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STSS_SAMPLE_NUMBER) < 0)
4231 for (j = 0; j < bytestoread; j += 4)
4233 insertu32(buf + j, ((mp4_u32 *)buf2)[j / 4]);
4236 if (writeFile(handle, buf, bytestoread) < 0)
4244 left -= bytestoread;
4258 * mp4_i32 writeAudioTrak(MP4HandleImp handle,
4263 * Write audio track atom.
4267 * handle MP4 library handle
4276 mp4_i32 writeAudioTrak(MP4HandleImp handle, trakSize *ts)
4283 insertu32(buf+i, (mp4_u32)ts->trak);
4287 insertu32(buf+i, (mp4_u32)ATOMTYPE_TRAK);
4290 if (writeFile(handle, buf, 8) < 0)
4293 if (writeAudioTKHD(handle, ts) < 0)
4296 if (writeAudioMDIA(handle, ts) < 0)
4299 if (handle->audioUDTA)
4301 if (writeUDTA(handle, handle->audioUDTA) < 0)
4312 * mp4_i32 writeAudioTKHD(MP4HandleImp handle,
4317 * Write audio TKHD atom.
4321 * handle MP4 library handle
4330 mp4_i32 writeAudioTKHD(MP4HandleImp handle, trakSize *ts)
4338 buf = (mp4_u8 *)mp4malloc(ts->tkhd);
4343 insertu32(buf+i, (mp4_u32)ts->tkhd);
4347 insertu32(buf+i, (mp4_u32)ATOMTYPE_TKHD);
4351 if (handle->audioDuration > MP4_INT_MAX)
4354 /* Version and flags */
4358 buf[i++] = 7; /* Track enabled, used in movie and preview */
4361 if (getCurrentTime(&u32) < 0)
4363 insertu64(buf+i, (mp4_u64)u32);
4366 /* Modification time */
4367 if (getCurrentTime(&u32) < 0)
4369 insertu64(buf+i, (mp4_u64)u32);
4373 insertu32(buf+i, (mp4_u32)2);
4377 insertu32(buf+i, (mp4_u32)0);
4381 if ( ( handle->audioTimeScale == 0 ) || ( handle->audioDuration == 0 ) )
4387 ud = (mp4_double)MVHD_TIMESCALE * (mp4_double)handle->audioDuration / (mp4_double)handle->audioTimeScale + (mp4_double)0.5;
4390 insertu64(buf+i, u64);
4396 /* Version and flags */
4400 buf[i++] = 7; /* Track enabled, used in movie and preview */
4403 if (getCurrentTime(&u32) < 0)
4405 insertu32(buf+i, (mp4_u32)u32);
4408 /* Modification time */
4409 if (getCurrentTime(&u32) < 0)
4411 insertu32(buf+i, (mp4_u32)u32);
4415 insertu32(buf+i, (mp4_u32)2);
4419 insertu32(buf+i, (mp4_u32)0);
4423 if ( ( handle->audioTimeScale == 0 ) || ( handle->audioDuration == 0 ) )
4429 ud = (mp4_double)MVHD_TIMESCALE * (mp4_double)handle->audioDuration / (mp4_double)handle->audioTimeScale + (mp4_double)0.5;
4432 insertu32(buf+i, u32);
4436 insertu32(buf+i, (mp4_u32)0);
4439 insertu32(buf+i, (mp4_u32)0);
4442 insertu32(buf+i, (mp4_u32)0);
4445 insertu16(buf+i, (mp4_u16)0x0100); /* Audio track */
4448 insertu16(buf+i, (mp4_u16)0);
4451 insertu32(buf+i, (mp4_u32)0x00010000);
4454 insertu32(buf+i, (mp4_u32)0x00000000);
4457 insertu32(buf+i, (mp4_u32)0x00000000);
4460 insertu32(buf+i, (mp4_u32)0x00000000);
4463 insertu32(buf+i, (mp4_u32)0x00010000);
4466 insertu32(buf+i, (mp4_u32)0x00000000);
4469 insertu32(buf+i, (mp4_u32)0x00000000);
4472 insertu32(buf+i, (mp4_u32)0x00000000);
4475 insertu32(buf+i, (mp4_u32)0x40000000);
4478 insertu32(buf+i, (mp4_u32)0); /* Audio track */
4481 insertu32(buf+i, (mp4_u32)0); /* Audio track */
4484 if (writeFile(handle, buf, ts->tkhd) < 0)
4500 * mp4_i32 writeAudioMDIA(MP4HandleImp handle,
4505 * Write audio MDIA atom.
4509 * handle MP4 library handle
4518 mp4_i32 writeAudioMDIA(MP4HandleImp handle, trakSize *ts)
4525 insertu32(buf+i, (mp4_u32)ts->mdia);
4529 insertu32(buf+i, (mp4_u32)ATOMTYPE_MDIA);
4532 if (writeFile(handle, buf, 8) < 0)
4535 if (writeAudioMDHD(handle, ts) < 0)
4538 if (writeAudioHDLR(handle, ts) < 0)
4541 if (writeAudioMINF(handle, ts) < 0)
4551 * mp4_i32 writeAudioMDHD(MP4HandleImp handle,
4556 * Write audio MDHD atom.
4560 * handle MP4 library handle
4569 mp4_i32 writeAudioMDHD(MP4HandleImp handle, trakSize *ts)
4576 buf = (mp4_u8 *)mp4malloc(ts->mdhd);
4581 insertu32(buf+i, (mp4_u32)ts->mdhd);
4585 insertu32(buf+i, (mp4_u32)ATOMTYPE_MDHD);
4588 if (handle->audioDuration > MP4_INT_MAX)
4590 /* Version and flags */
4591 insertu32(buf+i, (mp4_u32)0x1000000); //version 1 atom
4595 if (getCurrentTime(&u32) < 0)
4597 insertu64(buf+i, (mp4_u64)u32);
4600 /* Modification time */
4601 if (getCurrentTime(&u32) < 0)
4603 insertu64(buf+i, (mp4_u64)u32);
4607 insertu32(buf+i, (mp4_u32)handle->audioTimeScale);
4611 insertu64(buf+i, handle->audioDuration);
4617 /* Version and flags */
4618 insertu32(buf+i, (mp4_u32)0);
4622 if (getCurrentTime(&u32) < 0)
4624 insertu32(buf+i, (mp4_u32)u32);
4627 /* Modification time */
4628 if (getCurrentTime(&u32) < 0)
4630 insertu32(buf+i, (mp4_u32)u32);
4634 insertu32(buf+i, (mp4_u32)handle->audioTimeScale);
4638 insertu32(buf+i, (mp4_u32)handle->audioDuration);
4643 insertu16(buf+i, (mp4_u16)0x55c4); /* 'und' */
4647 insertu16(buf+i, (mp4_u16)0x0000);
4650 if (writeFile(handle, buf, ts->mdhd) < 0)
4666 * mp4_i32 writeAudioHDLR(MP4HandleImp handle,
4671 * Write audio HDLR atom.
4675 * handle MP4 library handle
4684 mp4_i32 writeAudioHDLR(MP4HandleImp handle, trakSize *ts)
4690 buf = (mp4_u8 *)mp4malloc(ts->hdlr);
4695 insertu32(buf+i, (mp4_u32)ts->hdlr);
4699 insertu32(buf+i, (mp4_u32)ATOMTYPE_HDLR);
4702 /* Version and flags */
4703 insertu32(buf+i, (mp4_u32)0);
4707 insertu32(buf+i, (mp4_u32)0);
4717 insertu32(buf+i, (mp4_u32)0);
4721 insertu32(buf+i, (mp4_u32)0);
4725 insertu32(buf+i, (mp4_u32)0);
4731 if (writeFile(handle, buf, ts->hdlr) < 0)
4747 * mp4_i32 writeAudioMINF(MP4HandleImp handle,
4752 * Write audio MINF atom.
4756 * handle MP4 library handle
4765 mp4_i32 writeAudioMINF(MP4HandleImp handle, trakSize *ts)
4772 insertu32(buf+i, (mp4_u32)ts->minf);
4776 insertu32(buf+i, (mp4_u32)ATOMTYPE_MINF);
4779 if (writeFile(handle, buf, 8) < 0)
4782 if (writeSMHD(handle, ts) < 0)
4785 if (writeDINF(handle, ts) < 0)
4788 if (writeAudioSTBL(handle, ts) < 0)
4798 * mp4_i32 writeSMHD(MP4HandleImp handle,
4807 * handle MP4 library handle
4816 mp4_i32 writeSMHD(MP4HandleImp handle, trakSize *ts)
4822 buf = (mp4_u8 *)mp4malloc(ts->smhd);
4827 insertu32(buf+i, (mp4_u32)ts->smhd);
4831 insertu32(buf+i, (mp4_u32)ATOMTYPE_SMHD);
4834 /* Version and flags */
4835 insertu32(buf+i, (mp4_u32)0);
4839 insertu32(buf+i, (mp4_u32)0);
4842 if (writeFile(handle, buf, ts->smhd) < 0)
4858 * mp4_i32 writeAudioSTBL(MP4HandleImp handle,
4863 * Write audio STBL atom.
4867 * handle MP4 library handle
4876 mp4_i32 writeAudioSTBL(MP4HandleImp handle, trakSize *ts)
4883 insertu32(buf+i, (mp4_u32)ts->stbl);
4887 insertu32(buf+i, (mp4_u32)ATOMTYPE_STBL);
4890 if (writeFile(handle, buf, 8) < 0)
4893 if (writeAudioSTSD(handle, ts) < 0)
4896 if (handle->flags & MP4_FLAG_LONGCLIP)
4898 if (writeAudioSTTSLongClip(handle, ts) < 0)
4903 if (writeAudioSTTS(handle, ts) < 0)
4907 if (writeAudioSTSC(handle, ts) < 0)
4910 if (handle->flags & MP4_FLAG_LONGCLIP)
4912 if (writeAudioSTSZLongClip(handle, ts) < 0)
4915 if (handle->audioSampleTable->stcoNeed64Bits)
4917 if (writeAudioCO64LongClip(handle, ts) < 0)
4922 if (writeAudioSTCOLongClip(handle, ts) < 0)
4928 if (writeAudioSTSZ(handle, ts) < 0)
4931 if (handle->audioSampleTable->stcoNeed64Bits)
4933 if (writeAudioCO64(handle, ts) < 0)
4938 if (writeAudioSTCO(handle, ts) < 0)
4951 * mp4_i32 writeAudioSTSD(MP4HandleImp handle,
4956 * Write audio STSD atom.
4960 * handle MP4 library handle
4969 mp4_i32 writeAudioSTSD(MP4HandleImp handle, trakSize *ts)
4976 insertu32(buf+i, (mp4_u32)ts->stsd);
4980 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSD);
4983 /* Version and flags */
4984 insertu32(buf+i, (mp4_u32)0);
4988 insertu32(buf+i, (mp4_u32)1);
4991 if (writeFile(handle, buf, 16) < 0)
4994 if (handle->type & MP4_TYPE_MPEG4_AUDIO)
4996 if (writeMP4A(handle, ts) < 0)
4999 else if (handle->type & MP4_TYPE_AMR_NB)
5001 if (writeSAMR(handle, ts) < 0)
5004 else if (handle->type & MP4_TYPE_AMR_WB)
5006 if (writeSAWB(handle, ts) < 0)
5009 else if ((handle->type & MP4_TYPE_QCELP_13K) && (!handle->qcelpStoredAsMPEGAudio))
5011 if (writeSQCP(handle, ts) < 0)
5014 else if ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio))
5016 if (writeMP4A(handle, ts) < 0)
5030 * mp4_i32 writeMP4A(MP4HandleImp handle,
5039 * handle MP4 library handle
5048 mp4_i32 writeMP4A(MP4HandleImp handle, trakSize *ts)
5054 buf = (mp4_u8 *)mp4malloc(36);
5059 insertu32(buf+i, (mp4_u32)ts->mp4a);
5063 insertu32(buf+i, (mp4_u32)ATOMTYPE_MP4A);
5074 /* Data reference index */
5075 insertu16(buf+i, (mp4_u16)1);
5079 insertu32(buf+i, (mp4_u32)0);
5082 insertu32(buf+i, (mp4_u32)0);
5085 insertu16(buf+i, (mp4_u16)2);
5088 insertu16(buf+i, (mp4_u16)16);
5091 insertu32(buf+i, (mp4_u32)0);
5095 insertu16(buf+i, (mp4_u16)handle->audioTimeScale);
5099 insertu16(buf+i, (mp4_u16)0);
5102 if (writeFile(handle, buf, 36) < 0)
5109 if (writeAudioESD(handle, ts) < 0)
5125 * mp4_i32 writeAudioESD(MP4HandleImp handle,
5130 * Write audio ESD atom.
5134 * handle MP4 library handle
5143 mp4_i32 writeAudioESD(MP4HandleImp handle, trakSize *ts)
5147 mp4_u32 bitrate = 0;
5148 mp4_u32 num_of_bytes = 0;
5151 mp4_u32 tempnum = 0;
5153 mp4_u32 size1, size2;
5154 mp4_u32 numofsizebytes1, numofsizebytes2;
5156 buf = (mp4_u8 *)mp4malloc(ts->esds);
5160 /* Calculate the necessary size information */
5161 size1 = handle->audioDecSpecificInfoSize;
5163 numofsizebytes1 = 1;
5166 numofsizebytes1 = 1;
5167 while ( size1 >= 128 )
5174 size2 = 14 + numofsizebytes1 + handle->audioDecSpecificInfoSize;
5176 numofsizebytes2 = 1;
5179 numofsizebytes2 = 1;
5180 while ( size2 >= 128 )
5186 /* End of size calculations */
5189 insertu32(buf+i, (mp4_u32)ts->esds);
5193 insertu32(buf+i, (mp4_u32)ATOMTYPE_ESD);
5196 /* Version and flags */
5197 insertu32(buf+i, (mp4_u32)0);
5204 size = 21 + numofsizebytes1 + numofsizebytes2 + handle->audioDecSpecificInfoSize;
5206 buf[i++] = (mp4_u8)(size);
5210 while ( size >= 128 )
5215 size = 21 + numofsizebytes1 + numofsizebytes2 + handle->audioDecSpecificInfoSize;
5216 for(index = num_of_bytes; index > 0; index--)
5218 tempnum = size >> (7 * index);
5219 buf[i++] = (mp4_u8)(0x80 | (mp4_u8) tempnum);
5220 size -= (tempnum << (7 * index));
5222 buf[i++] = (mp4_u8)size;
5226 insertu16(buf+i, (mp4_u16)0);
5232 /* DecoderConfigDescrTag */
5236 size = 14 + numofsizebytes1 + handle->audioDecSpecificInfoSize;
5238 buf[i++] = (mp4_u8)(size);
5242 while ( size >= 128 )
5247 size = 14 + numofsizebytes1 + handle->audioDecSpecificInfoSize;
5248 for(index = num_of_bytes; index > 0; index--)
5250 tempnum = size >> (7 * index);
5251 buf[i++] = (mp4_u8)(0x80 | (mp4_u8) tempnum);
5252 size -= (tempnum << (7 * index));
5254 buf[i++] = (mp4_u8)size;
5257 /* ObjectTypeIndication */
5258 if (handle->type & MP4_TYPE_MPEG4_AUDIO)
5260 else if ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio))
5270 if (handle->type & MP4_TYPE_MPEG4_AUDIO)
5276 else if ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio))
5277 { /* 4096 for QCELP 13K */
5287 if ((handle->audioDuration != 0) && (handle->audioTimeScale != 0))
5288 bitrate = (mp4_u32)((mp4_double)8 *
5289 (mp4_double)handle->audioMediaDataSize /
5290 ((mp4_double)handle->audioDuration /
5291 (mp4_double)handle->audioTimeScale));
5296 insertu32(buf+i, (mp4_u32)bitrate); /*0x00010000*/
5300 insertu32(buf+i, (mp4_u32)bitrate);/*0x00008000*/
5303 /* DecSpecificInfoTag */
5307 size = handle->audioDecSpecificInfoSize;
5309 buf[i++] = (mp4_u8)(size);
5313 while ( size >= 128 )
5318 size = handle->audioDecSpecificInfoSize;
5319 for(index = num_of_bytes; index > 0; index--)
5321 tempnum = size >> (7 * index);
5322 buf[i++] = (mp4_u8)(0x80 | (mp4_u8) tempnum);
5323 size -= (tempnum << (7 * index));
5325 buf[i++] = (mp4_u8)size;
5328 /* DecoderSpecificInfo */
5329 mp4memcpy(buf+i, handle->audioDecSpecificInfo, handle->audioDecSpecificInfoSize);
5330 i += handle->audioDecSpecificInfoSize;
5332 /* SLConfigDescrTag */
5341 if (writeFile(handle, buf, ts->esds) < 0)
5357 * mp4_i32 writeSAMR(MP4HandleImp handle,
5366 * handle MP4 library handle
5375 mp4_i32 writeSAMR(MP4HandleImp handle, trakSize *ts)
5381 buf = (mp4_u8 *)mp4malloc(36);
5386 insertu32(buf+i, (mp4_u32)ts->samr);
5390 insertu32(buf+i, (mp4_u32)ATOMTYPE_SAMR);
5401 /* Data reference index */
5402 insertu16(buf+i, (mp4_u16)1);
5406 insertu32(buf+i, (mp4_u32)0);
5409 insertu32(buf+i, (mp4_u32)0);
5412 insertu16(buf+i, (mp4_u16)2);
5415 insertu16(buf+i, (mp4_u16)16);
5418 insertu32(buf+i, (mp4_u32)0);
5422 insertu16(buf+i, (mp4_u16)handle->audioTimeScale);
5426 insertu16(buf+i, (mp4_u16)0);
5429 if (writeFile(handle, buf, 36) < 0)
5436 if (writeDAMR(handle, ts) < 0)
5452 * mp4_i32 writeSAWB(MP4HandleImp handle,
5461 * handle MP4 library handle
5470 mp4_i32 writeSAWB(MP4HandleImp handle, trakSize *ts)
5476 buf = (mp4_u8 *)mp4malloc(36);
5481 insertu32(buf+i, (mp4_u32)ts->sawb);
5485 insertu32(buf+i, (mp4_u32)ATOMTYPE_SAWB);
5496 /* Data reference index */
5497 insertu16(buf+i, (mp4_u16)1);
5501 insertu32(buf+i, (mp4_u32)0);
5504 insertu32(buf+i, (mp4_u32)0);
5507 insertu16(buf+i, (mp4_u16)2);
5510 insertu16(buf+i, (mp4_u16)16);
5513 insertu32(buf+i, (mp4_u32)0);
5517 insertu16(buf+i, (mp4_u16)handle->audioTimeScale);
5521 insertu16(buf+i, (mp4_u16)0);
5524 if (writeFile(handle, buf, 36) < 0)
5531 if (writeDAMR(handle, ts) < 0)
5547 * mp4_i32 writeDAMR(MP4HandleImp handle,
5556 * handle MP4 library handle
5565 mp4_i32 writeDAMR(MP4HandleImp handle, trakSize *ts)
5572 insertu32(buf+i, (mp4_u32)ts->damr);
5576 insertu32(buf+i, (mp4_u32)ATOMTYPE_DAMR);
5585 /* Decoder version */
5589 insertu16(buf+i, (mp4_u16)handle->audioModeSet);
5592 /* Mode change period */
5595 /* Frames per sample */
5596 buf[i++] = handle->audioFramesPerSample;
5598 if (writeFile(handle, buf, 17) < 0)
5608 * mp4_i32 writeAudioSTTS(MP4HandleImp handle,
5613 * Write audio STTS atom.
5617 * handle MP4 library handle
5626 mp4_i32 writeAudioSTTS(MP4HandleImp handle, trakSize *ts)
5633 buf = (mp4_u8 *)mp4malloc(ts->stts);
5638 insertu32(buf+i, (mp4_u32)ts->stts);
5642 insertu32(buf+i, (mp4_u32)ATOMTYPE_STTS);
5645 /* Version and flags */
5646 insertu32(buf+i, (mp4_u32)0);
5650 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->sttsEntryCount);
5653 /* Sample count and sample delta */
5654 for (j = 0; j < handle->audioSampleTable->sttsEntryCount; j++)
5656 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->sttsSampleCount[j]);
5658 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->sttsSampleDelta[j]);
5662 if (writeFile(handle, buf, ts->stts) < 0)
5678 * mp4_i32 writeAudioSTTSLongClip(MP4HandleImp handle,
5683 * Write audio STTS atom.
5687 * handle MP4 library handle
5696 mp4_i32 writeAudioSTTSLongClip(MP4HandleImp handle, trakSize *ts)
5703 mp4_u32 bytestoread;
5706 buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
5710 buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE / 2);
5718 insertu32(buf+i, (mp4_u32)ts->stts);
5722 insertu32(buf+i, (mp4_u32)ATOMTYPE_STTS);
5725 /* Version and flags */
5726 insertu32(buf+i, (mp4_u32)0);
5730 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->sttsEntryCount);
5733 if (writeFile(handle, buf, i) < 0)
5741 /* Sample count and delta */
5743 /* Seek to the beginning of temporary files */
5745 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STTS_SAMPLE_COUNT) < 0)
5751 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STTS_SAMPLE_DELTA) < 0)
5758 left = handle->audioSampleTable->sttsEntryCount * 4; /* Bytes left in each file */
5762 if (left > METADATA_COPY_BUFFERSIZE / 2)
5763 bytestoread = METADATA_COPY_BUFFERSIZE / 2;
5767 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STTS_SAMPLE_COUNT) < 0)
5775 for (j = 0; j < bytestoread; j += 4)
5777 insertu32(buf + 2*j, ((mp4_u32 *)buf2)[j / 4]);
5780 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STTS_SAMPLE_DELTA) < 0)
5788 for (j = 0; j < bytestoread; j += 4)
5790 insertu32(buf + 2*j + 4, ((mp4_u32 *)buf2)[j / 4]);
5793 if (writeFile(handle, buf, 2 * bytestoread) < 0)
5801 left -= bytestoread;
5815 * mp4_i32 writeAudioSTSC(MP4HandleImp handle,
5820 * Write audio STSC atom.
5824 * handle MP4 library handle
5833 mp4_i32 writeAudioSTSC(MP4HandleImp handle, trakSize *ts)
5840 buf = (mp4_u8 *)mp4malloc(ts->stsc);
5845 insertu32(buf+i, (mp4_u32)ts->stsc);
5849 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSC);
5852 /* Version and flags */
5853 insertu32(buf+i, (mp4_u32)0);
5857 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stscEntryCount);
5860 /* First chunk, samples per chunk and sample description index */
5861 for (j = 0; j < handle->audioSampleTable->stscEntryCount; j++)
5863 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stscFirstChunk[j]);
5865 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stscSamplesPerChunk[j]);
5867 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stscSampleDescriptionIndex[j]);
5871 if (writeFile(handle, buf, ts->stsc) < 0)
5887 * mp4_i32 writeAudioSTSZ(MP4HandleImp handle,
5892 * Write audio STSZ atom.
5896 * handle MP4 library handle
5905 mp4_i32 writeAudioSTSZ(MP4HandleImp handle, trakSize *ts)
5912 buf = (mp4_u8 *)mp4malloc(ts->stsz);
5917 insertu32(buf+i, (mp4_u32)ts->stsz);
5921 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSZ);
5924 /* Version and flags */
5925 insertu32(buf+i, (mp4_u32)0);
5929 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszSampleSize);
5933 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszSampleCount);
5937 if (handle->audioSampleTable->stszSampleSize == 0)
5939 for (j = 0; j < handle->audioSampleTable->stszSampleCount; j++)
5941 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszEntrySize[j]);
5946 if (writeFile(handle, buf, ts->stsz) < 0)
5962 * mp4_i32 writeAudioSTSZLongClip(MP4HandleImp handle,
5967 * Write audio STSZ atom.
5971 * handle MP4 library handle
5980 mp4_i32 writeAudioSTSZLongClip(MP4HandleImp handle, trakSize *ts)
5987 mp4_u32 bytestoread;
5990 buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
5994 buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
6002 insertu32(buf+i, (mp4_u32)ts->stsz);
6006 insertu32(buf+i, (mp4_u32)ATOMTYPE_STSZ);
6009 /* Version and flags */
6010 insertu32(buf+i, (mp4_u32)0);
6014 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszSampleSize);
6018 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszSampleCount);
6021 if (writeFile(handle, buf, i) < 0)
6031 if (handle->audioSampleTable->stszSampleSize == 0)
6033 /* Seek to the beginning of temporary file */
6035 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STSZ_ENTRY_SIZE) < 0)
6042 left = handle->audioSampleTable->stszSampleCount * 4; /* Bytes left in the file */
6046 if (left > METADATA_COPY_BUFFERSIZE)
6047 bytestoread = METADATA_COPY_BUFFERSIZE;
6051 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STSZ_ENTRY_SIZE) < 0)
6059 for (j = 0; j < bytestoread; j += 4)
6061 insertu32(buf + j, ((mp4_u32 *)buf2)[j / 4]);
6064 if (writeFile(handle, buf, bytestoread) < 0)
6072 left -= bytestoread;
6087 * mp4_i32 writeAudioSTCO(MP4HandleImp handle,
6092 * Write audio STCO atom.
6096 * handle MP4 library handle
6105 mp4_i32 writeAudioSTCO(MP4HandleImp handle, trakSize *ts)
6112 buf = (mp4_u8 *)mp4malloc(ts->stco);
6117 insertu32(buf+i, (mp4_u32)ts->stco);
6121 insertu32(buf+i, (mp4_u32)ATOMTYPE_STCO);
6124 /* Version and flags */
6125 insertu32(buf+i, (mp4_u32)0);
6129 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoEntryCount);
6133 for (j = 0; j < handle->audioSampleTable->stcoEntryCount; j++)
6135 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoChunkOffset[j]);
6139 if (writeFile(handle, buf, ts->stco) < 0)
6154 * mp4_i32 writeAudioCO64(MP4HandleImp handle,
6159 * Write audio CO64 atom.
6163 * handle MP4 library handle
6172 mp4_i32 writeAudioCO64(MP4HandleImp handle, trakSize *ts)
6179 buf = (mp4_u8 *)mp4malloc(ts->stco);
6184 insertu32(buf+i, (mp4_u32)ts->stco);
6188 insertu32(buf+i, (mp4_u32)ATOMTYPE_CO64);
6191 /* Version and flags */
6192 insertu32(buf+i, (mp4_u32)0);
6196 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoEntryCount);
6200 for (j = 0; j < handle->audioSampleTable->stcoEntryCount; j++)
6202 insertu64(buf+j, (mp4_u64)handle->audioSampleTable->stcoChunkOffset[j]);
6205 if (writeFile(handle, buf, ts->stco) < 0)
6220 * mp4_i32 writeAudioSTCOLongClip(MP4HandleImp handle,
6225 * Write audio STCO atom.
6229 * handle MP4 library handle
6238 mp4_i32 writeAudioSTCOLongClip(MP4HandleImp handle, trakSize *ts)
6245 mp4_u32 bytestoread;
6246 mp4_u32 bufferSize = (METADATA_COPY_BUFFERSIZE/sizeof(mp4_u64)) * sizeof(mp4_u64); //must be a multiple of u64
6247 //METADATA_COPY_BUFFERSIZE is only guaranteed to be a multiple of 4
6250 buf = (mp4_u8 *)mp4malloc(bufferSize);
6254 buf2 = (mp4_u8 *)mp4malloc(bufferSize);
6262 insertu32(buf+i, (mp4_u32)ts->stco);
6266 insertu32(buf+i, (mp4_u32)ATOMTYPE_STCO);
6269 /* Version and flags */
6270 insertu32(buf+i, (mp4_u32)0);
6274 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoEntryCount);
6277 if (writeFile(handle, buf, i) < 0)
6287 /* Seek to the beginning of temporary file */
6289 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
6296 left = handle->audioSampleTable->stcoEntryCount * 8; /* Bytes left in the file */
6300 if (left > bufferSize)
6301 bytestoread = bufferSize;
6305 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
6313 for (j = 0; j < bytestoread; j += 8)
6315 ((mp4_u64 *)buf2)[j / 8] += (handle->metaDataSize + MDAT_HEADER_SIZE); /* Update chunk offsets */
6316 insertu32(buf + j/2, ((mp4_u64 *)buf2)[j / 8]);
6319 if (writeFile(handle, buf, bytestoread/2) < 0)
6327 left -= bytestoread;
6340 * mp4_i32 writeAudioCO64LongClip(MP4HandleImp handle,
6345 * Write audio CO64 atom.
6349 * handle MP4 library handle
6358 mp4_i32 writeAudioCO64LongClip(MP4HandleImp handle, trakSize *ts)
6365 mp4_u32 bytestoread;
6366 mp4_u32 bufferSize = (METADATA_COPY_BUFFERSIZE/sizeof(mp4_u64)) * sizeof(mp4_u64); //must be a multiple of u64
6367 //METADATA_COPY_BUFFERSIZE is only guaranteed to be a multiple of 4
6370 buf = (mp4_u8 *)mp4malloc(bufferSize);
6374 buf2 = (mp4_u8 *)mp4malloc(bufferSize);
6382 insertu32(buf+i, (mp4_u32)ts->stco);
6386 insertu32(buf+i, (mp4_u32)ATOMTYPE_CO64);
6389 /* Version and flags */
6390 insertu32(buf+i, (mp4_u32)0);
6394 insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoEntryCount);
6397 if (writeFile(handle, buf, i) < 0)
6407 /* Seek to the beginning of temporary file */
6409 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
6416 left = handle->audioSampleTable->stcoEntryCount * 8; /* Bytes left in the file */
6420 if (left > bufferSize)
6421 bytestoread = bufferSize;
6425 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
6433 for (j = 0; j < bytestoread; j += 8)
6435 ((mp4_u64 *)buf2)[j / 8] += (handle->metaDataSize + MDAT_HEADER_SIZE); /* Update chunk offsets */
6436 insertu64(buf + j, ((mp4_u64 *)buf2)[j / 8]);
6439 if (writeFile(handle, buf, bytestoread) < 0)
6447 left -= bytestoread;
6461 * mp4_i32 writeMediaData(MP4HandleImp handle)
6465 * This function writes media data to the output file.
6467 * Before writing media data to the output file, meta data has
6468 * been written to the file. Media data that is in tmpfile is
6469 * read from there and written to the end of the output file.
6473 * handle MP4 library handle
6481 mp4_i32 writeMediaData(MP4HandleImp handle)
6486 mp4_u32 bytestoread;
6489 buf = (mp4_u8 *)mp4malloc(1024);
6494 i = formatMdatHeader(buf, handle->bytesInTmpFile);
6495 if (writeFile(handle, buf, i) < 0)
6502 /* Seek to the beginning of tmpfile */
6503 if (seekTmpFileAbs(handle, 0) < 0)
6509 left = handle->bytesInTmpFile;
6518 if (readTmpFile(handle, buf, bytestoread) < 0)
6525 if (writeFile(handle, buf, bytestoread) < 0)
6532 left -= bytestoread;
6543 * mp4_i32 insertu64(mp4_u8 *buf,
6548 * This function writes value into buf taking into account the endianism
6549 * of the current computer.
6551 * It is assumed that the caller of the function has allocated enough
6556 * buf Buffer to write to
6557 * value Value to write to buf
6564 mp4_i32 insertu64(mp4_u8 *buf, mp4_u64 value)
6569 u64 = u64endian(value);
6570 mp4memcpy(buf, &u64, sizeof(mp4_u64));
6579 * mp4_i32 insertu32(mp4_u8 *buf,
6584 * This function writes value into buf taking into account the endianism
6585 * of the current computer.
6587 * It is assumed that the caller of the function has allocated enough
6592 * buf Buffer to write to
6593 * value Value to write to buf
6600 mp4_i32 insertu32(mp4_u8 *buf, mp4_u32 value)
6605 u32 = u32endian(value);
6606 mp4memcpy(buf, &u32, 4);
6615 * mp4_i32 insertu16(mp4_u8 *buf,
6620 * This function writes value into buf taking into account the endianism
6621 * of the current computer.
6623 * It is assumed that the caller of the function has allocated enough
6628 * buf Buffer to write to
6629 * value Value to write to buf
6636 mp4_i32 insertu16(mp4_u8 *buf, mp4_u16 value)
6641 u16 = u16endian(value);
6642 mp4memcpy(buf, &u16, 2);
6651 * mp4_i32 writeMetaDataTmp(MP4HandleImp handle)
6655 * This function writes metadata accumulated in memory to the disk.
6659 * handle MP4 library handle
6667 mp4_i32 writeMetaDataTmp(MP4HandleImp handle)
6669 PRINT((_L("e_writemetadatatmp 1")));
6670 if (handle->videoSampleTable)
6672 PRINT((_L("e_writemetadatatmp_writemetadata_video 1")));
6673 if (writeMetaDataFileNum(handle,
6674 (mp4_u8 *)handle->videoSampleTable->sttsSampleCount,
6675 handle->videoSampleTable->sttsCurrentEntryCount * sizeof(mp4_u32),
6676 METADATAFILE_VIDEO_STTS_SAMPLE_COUNT) < 0)
6679 if (writeMetaDataFileNum(handle,
6680 (mp4_u8 *)handle->videoSampleTable->sttsSampleDelta,
6681 handle->videoSampleTable->sttsCurrentEntryCount * sizeof(mp4_u32),
6682 METADATAFILE_VIDEO_STTS_SAMPLE_DELTA) < 0)
6685 if (writeMetaDataFileNum(handle,
6686 (mp4_u8 *)handle->videoSampleTable->stszEntrySize,
6687 handle->videoSampleTable->stszCurrentSampleCount * sizeof(mp4_u32),
6688 METADATAFILE_VIDEO_STSZ_ENTRY_SIZE) < 0)
6691 if (writeMetaDataFileNum(handle,
6692 (mp4_u8 *)handle->videoSampleTable->stcoChunkOffset,
6693 handle->videoSampleTable->stcoCurrentEntryCount * sizeof(mp4_u64),
6694 METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
6697 if (writeMetaDataFileNum(handle,
6698 (mp4_u8 *)handle->videoSampleTable->stssSampleNumber,
6699 handle->videoSampleTable->stssCurrentEntryCount * sizeof(mp4_u32),
6700 METADATAFILE_VIDEO_STSS_SAMPLE_NUMBER) < 0)
6703 if (writeMetaDataFileNum(handle,
6704 (mp4_u8 *)handle->videoSampleTable->sdtpSampleDependency,
6705 handle->videoSampleTable->sdtpCurrentEntryCount * sizeof(mp4_u8),
6706 METADATAFILE_VIDEO_SDTP_SAMPLE_DEPENDENCY) < 0)
6708 PRINT((_L("e_writemetadatatmp_writemetadata_video 0")));
6711 if (handle->audioSampleTable)
6713 PRINT((_L("e_writemetadatatmp_writemetadata_audio 1")));
6714 if (writeMetaDataFileNum(handle,
6715 (mp4_u8 *)handle->audioSampleTable->sttsSampleCount,
6716 handle->audioSampleTable->sttsCurrentEntryCount * sizeof(mp4_u32),
6717 METADATAFILE_AUDIO_STTS_SAMPLE_COUNT) < 0)
6720 if (writeMetaDataFileNum(handle,
6721 (mp4_u8 *)handle->audioSampleTable->sttsSampleDelta,
6722 handle->audioSampleTable->sttsCurrentEntryCount * sizeof(mp4_u32),
6723 METADATAFILE_AUDIO_STTS_SAMPLE_DELTA) < 0)
6726 if (writeMetaDataFileNum(handle,
6727 (mp4_u8 *)handle->audioSampleTable->stszEntrySize,
6728 handle->audioSampleTable->stszCurrentSampleCount * sizeof(mp4_u32),
6729 METADATAFILE_AUDIO_STSZ_ENTRY_SIZE) < 0)
6732 if (writeMetaDataFileNum(handle,
6733 (mp4_u8 *)handle->audioSampleTable->stcoChunkOffset,
6734 handle->audioSampleTable->stcoCurrentEntryCount * sizeof(mp4_u64),
6735 METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
6737 PRINT((_L("e_writemetadatatmp_writemetadata_audio 0")));
6740 if (handle->videoSampleTable)
6742 handle->videoSampleTable->sttsCurrentEntryCount = 0;
6743 handle->videoSampleTable->stszCurrentSampleCount = 0;
6744 handle->videoSampleTable->stcoCurrentEntryCount = 0;
6745 handle->videoSampleTable->stssCurrentEntryCount = 0;
6746 handle->videoSampleTable->sdtpCurrentEntryCount = 0;
6749 if (handle->audioSampleTable)
6751 handle->audioSampleTable->sttsCurrentEntryCount = 0;
6752 handle->audioSampleTable->stszCurrentSampleCount = 0;
6753 handle->audioSampleTable->stcoCurrentEntryCount = 0;
6756 handle->metaDataBlocks = 0;
6757 handle->metaDataOnDisk = MP4TRUE;
6759 PRINT((_L("e_writemetadatatmp 0")));
6766 * mp4_i32 writeSQCP(MP4HandleImp handle,
6775 * handle MP4 library handle
6784 mp4_i32 writeSQCP(MP4HandleImp handle, trakSize *ts)
6790 buf = (mp4_u8 *)mp4malloc(36);
6795 insertu32(buf+i, (mp4_u32)ts->sqcp);
6799 insertu32(buf+i, (mp4_u32)ATOMTYPE_SQCP);
6810 /* Data reference index */
6811 insertu16(buf+i, (mp4_u16)1);
6815 insertu32(buf+i, (mp4_u32)0);
6818 insertu32(buf+i, (mp4_u32)0);
6821 insertu16(buf+i, (mp4_u16)2);
6824 insertu16(buf+i, (mp4_u16)16);
6827 insertu32(buf+i, (mp4_u32)0);
6831 insertu16(buf+i, (mp4_u16)handle->audioTimeScale);
6835 insertu16(buf+i, (mp4_u16)0);
6838 if (writeFile(handle, buf, 36) < 0)
6845 if (writeDQCP(handle, ts) < 0)
6860 * mp4_i32 writeDQCP(MP4HandleImp handle,
6869 * handle MP4 library handle
6878 mp4_i32 writeDQCP(MP4HandleImp handle, trakSize *ts)
6885 insertu32(buf+i, (mp4_u32)ts->dqcp);
6889 insertu32(buf+i, (mp4_u32)ATOMTYPE_DQCP);
6898 /* Decoder version */
6902 // insertu16(buf+i, (mp4_u16)handle->audioModeSet);
6905 /* Mode change period */
6908 /* Frames per sample */
6909 buf[i++] = handle->audioFramesPerSample;
6911 if (writeFile(handle, buf, 14) < 0)
6920 * mp4_i32 calculateES_DescriptorSize(mp4_u32 type)
6924 * Calculated the ES_Descriptor size inside the ESDS box.
6925 * Updates handle->ES_DescriptorSize;
6929 * handle MP4 library handle
6930 * type the media type:
6931 * MP4_TYPE_QCELP_13K
6932 * MP4_TYPE_MPEG_AUDIO
6933 * MP4_TYPE_MPEG4_VIDEO
6940 mp4_i32 calculateES_DescriptorSize(MP4HandleImp handle, mp4_u32 type)
6942 mp4_u32 size1, size2, size3;
6943 mp4_u32 numofsizebytes1, numofsizebytes2, numofsizebytes3;
6944 mp4_u32 decspecinfosize = 0;
6946 if (((type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio)) ||
6947 (type & MP4_TYPE_MPEG4_AUDIO))
6948 decspecinfosize = handle->audioDecSpecificInfoSize;
6949 else /* MPEG video case */
6950 decspecinfosize = handle->videoDecSpecificInfoSize;
6952 size1 = decspecinfosize;
6954 numofsizebytes1 = 1;
6957 numofsizebytes1 = 1;
6958 while ( size1 >= 128 )
6965 size2 = 14 + numofsizebytes1 + decspecinfosize;
6967 numofsizebytes2 = 1;
6970 numofsizebytes2 = 1;
6971 while ( size2 >= 128 )
6978 size3 = 21 + numofsizebytes1 + numofsizebytes2 + decspecinfosize;
6980 numofsizebytes3 = 1;
6983 numofsizebytes3 = 1;
6984 while ( size3 >= 128 )
6991 /* ES_DescriptorSize contains the size of the ES_Descriptor Field, including the 0x03 (ES_ID Tag) */
6992 handle->ES_DescriptorSize = 21 + numofsizebytes1 + numofsizebytes2 + decspecinfosize + numofsizebytes3 + 1;
6999 * mp4_i32 writeUDTA(MP4HandleImp handle,
7000 * userDataAtom *udta)
7008 * handle MP4 library handle
7017 mp4_i32 writeUDTA(MP4HandleImp handle, userDataAtom *udta)
7024 insertu32(buf+i, 8 + (mp4_u32)udta->atomcontentsize);
7028 insertu32(buf+i, (mp4_u32)ATOMTYPE_UDTA);
7031 if (writeFile(handle, buf, 8) < 0)
7034 if (writeFile(handle, udta->contentdata, udta->atomcontentsize) < 0)
7043 * mp4_i32 updateVideoDependencyMetaData(MP4HandleImp handle,
7044 * mp4_u8 aDependsOn,
7045 * mp4_u8 aIsDependentOn,
7046 * mp4_u8 aHasRedundancy)
7050 * Updates SDTP video dependency data
7054 * handle MP4 library handle
7055 * aDependsOn This frame's dependency on other frames
7056 * aIsDependentOn Other frames's dependency on this frame
7057 * aHasRedundancy Whether there is redundant coding in this frame
7065 mp4_i32 updateVideoDependencyMetaData(MP4HandleImp handle, mp4_u8 aDependsOn, mp4_u8 aIsDependentOn, mp4_u8 aHasRedundancy)
7067 if (handle->flags & MP4_FLAG_LONGCLIP)
7069 if (handle->videoSampleTable->sdtpCurrentEntryCount == handle->videoSampleTable->sdtpMaxEntryCount)
7073 p = mp4realloc(handle->videoSampleTable->sdtpSampleDependency,
7074 2 * sizeof(mp4_u8) * handle->videoSampleTable->sdtpMaxEntryCount,
7075 sizeof(mp4_u8) * handle->videoSampleTable->stssMaxEntryCount);
7079 handle->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)p;
7081 handle->videoSampleTable->sdtpMaxEntryCount *= 2;
7084 handle->videoSampleTable->sdtpSampleDependency[handle->videoSampleTable->sdtpCurrentEntryCount] = (aDependsOn << 4) | (aIsDependentOn << 2) | (aHasRedundancy);
7085 handle->videoSampleTable->sdtpCurrentEntryCount++;
7086 handle->videoSampleTable->sdtpEntryCount++;
7090 if (handle->videoSampleTable->sdtpEntryCount == handle->videoSampleTable->sdtpMaxEntryCount)
7094 p = mp4realloc(handle->videoSampleTable->sdtpSampleDependency,
7095 2 * sizeof(mp4_u8) * handle->videoSampleTable->sdtpMaxEntryCount,
7096 sizeof(mp4_u8) * handle->videoSampleTable->sdtpMaxEntryCount);
7100 handle->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)p;
7102 handle->videoSampleTable->sdtpMaxEntryCount *= 2;
7105 handle->videoSampleTable->sdtpSampleDependency[handle->videoSampleTable->sdtpEntryCount] = (aDependsOn << 4) | (aIsDependentOn << 2) | (aHasRedundancy);
7106 handle->videoSampleTable->sdtpEntryCount++;
7115 * mp4_i32 writeVideoSDTP(MP4HandleImp handle,
7120 * Write video SDTP atom.
7124 * handle MP4 library handle
7133 mp4_i32 writeVideoSDTP(MP4HandleImp handle, trakSize *ts)
7139 buf = (mp4_u8 *)mp4malloc(ts->sdtp);
7144 insertu32(buf+i, (mp4_u32)ts->sdtp);
7148 insertu32(buf+i, (mp4_u32)ATOMTYPE_SDTP);
7151 /* Version and flags */
7152 insertu32(buf+i, (mp4_u32)0);
7155 /* Sample dependencies */
7156 for (j = 0; j < handle->videoSampleTable->sdtpEntryCount; j++)
7158 buf[i++] = (mp4_u8)handle->videoSampleTable->sdtpSampleDependency[j];
7161 if (writeFile(handle, buf, ts->sdtp) < 0)
7176 * mp4_i32 writeVideoSDTPLongClip(MP4HandleImp handle,
7181 * Write video SDTP atom.
7185 * handle MP4 library handle
7194 mp4_i32 writeVideoSDTPLongClip(MP4HandleImp handle, trakSize *ts)
7200 mp4_u32 bytestoread;
7203 buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
7207 buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE / 2);
7215 insertu32(buf+i, (mp4_u32)ts->sdtp);
7219 insertu32(buf+i, (mp4_u32)ATOMTYPE_SDTP);
7222 /* Version and flags */
7223 insertu32(buf+i, (mp4_u32)0);
7226 if (writeFile(handle, buf, i) < 0)
7234 /* Sample count and delta */
7236 /* Seek to the beginning of temporary files */
7238 if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_SDTP_SAMPLE_DEPENDENCY) < 0)
7245 left = handle->videoSampleTable->sdtpEntryCount; /* Bytes left in each file */
7249 if (left > METADATA_COPY_BUFFERSIZE / 2)
7250 bytestoread = METADATA_COPY_BUFFERSIZE / 2;
7254 if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_SDTP_SAMPLE_DEPENDENCY) < 0)
7262 if (writeFile(handle, buf2, bytestoread) < 0)
7270 left -= bytestoread;
7283 * mp4_i32 writeAVCP(MP4HandleImp handle,
7292 * handle MP4 library handle
7301 mp4_i32 writeAVCP(MP4HandleImp handle, trakSize *ts)
7307 buf = (mp4_u8 *)mp4malloc(86+7); // 86 = size of VisualSampleEntry, 7 = size of AVCDecoderConfigurationRecord
7308 // with PPS and SPS sizes set to 0
7313 insertu32(buf+i, (mp4_u32)ts->avcp);
7317 insertu32(buf+i, (mp4_u32)ATOMTYPE_AVCP);
7328 /* Data reference index */
7329 insertu16(buf+i, (mp4_u16)1);
7333 insertu32(buf+i, (mp4_u32)0);
7336 insertu32(buf+i, (mp4_u32)0);
7339 insertu32(buf+i, (mp4_u32)0);
7342 insertu32(buf+i, (mp4_u32)0);
7346 insertu16(buf+i, (mp4_u16)handle->videoWidth);
7350 insertu16(buf+i, (mp4_u16)handle->videoHeight);
7354 insertu32(buf+i, (mp4_u32)0x00480000);
7357 insertu32(buf+i, (mp4_u32)0x00480000);
7360 insertu32(buf+i, (mp4_u32)0);
7363 insertu16(buf+i, (mp4_u16)1);
7368 insertu32(buf+i, (mp4_u32)0x41564320); // "AVC "
7370 insertu32(buf+i, (mp4_u32)0x70617261); // "para"
7372 insertu32(buf+i, (mp4_u32)0x6d657465); // "mete"
7374 insertu16(buf+i, (mp4_u16)0x7273); // "rs"
7377 insertu32(buf+i, (mp4_u32)0);
7379 insertu32(buf+i, (mp4_u32)0);
7381 insertu32(buf+i, (mp4_u32)0);
7383 insertu32(buf+i, (mp4_u32)0);
7386 insertu16(buf+i, (mp4_u16)24);
7389 insertu16(buf+i, (mp4_u16)0xffff);
7392 // AVCC without picparams & seqparams
7393 mp4memcpy(buf+i, handle->videoDecSpecificInfo, 5); // 5 = configurationVersion + AVCProfileIndication +
7394 // profile_compatibility + AVCLevelIndication +
7395 // '111111' + lengthSizeMinusOne (2 bits)
7397 buf[i++] = 0xE0 | 0; // '111' + numOfSequenceParameterSets (5 bits)
7398 buf[i++] = 0; // numOfPictureParameterSets
7400 if (writeFile(handle, buf, 86+7) < 0)
7415 * mp4_i32 formatMdatHeader(mp4_u8 *buffer,
7420 * Formats the MDAT header into buffer
7424 * buffer buffer to write the MDAT header into
7425 * size Size of the media data (excluding the MDAT header)
7432 mp4_i32 formatMdatHeader(mp4_u8 *buf, mp4_u64 size)
7435 if (size < MP4_INT_MAX)
7438 insertu32(buf, (mp4_u32)8);
7439 i += sizeof(mp4_u32);
7440 insertu32(buf + i, (mp4_u32)ATOMTYPE_FREE);
7441 i += sizeof(mp4_u32);
7444 insertu32(buf + i, (mp4_u32)size + 8);
7445 i += sizeof(mp4_u32);
7446 insertu32(buf + i, (mp4_u32)ATOMTYPE_MDAT);
7447 i += sizeof(mp4_u32);
7452 insertu32(buf + i, (mp4_u32)1);
7453 i += sizeof(mp4_u32);
7454 insertu32(buf + i, (mp4_u32)ATOMTYPE_MDAT);
7455 i += sizeof(mp4_u32);
7456 insertu64(buf + i, (mp4_u64)size + 16);
7457 i += sizeof(mp4_u64);
7460 ASSERT(MDAT_HEADER_SIZE == i);