diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 2451056..8ba6dac 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -8,7 +8,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run clang-format style check for C/C++ programs. - uses: jidicula/clang-format-action@v4.4.1 + uses: jidicula/clang-format-action@v4.11.0 with: - clang-format-version: '13' + clang-format-version: '15' check-path: 'IsoLib/libisomediafile' diff --git a/IsoLib/libisomediafile/src/ISOMeta.c b/IsoLib/libisomediafile/src/ISOMeta.c index d331712..6875d18 100644 --- a/IsoLib/libisomediafile/src/ISOMeta.c +++ b/IsoLib/libisomediafile/src/ISOMeta.c @@ -1163,7 +1163,7 @@ ISO_EXTERN(ISOErr) ISOSetItemInfoItemType(ISOMetaItem item, u32 item_type, char if(item_uri_type) { u32 sz = (u32)strlen(item_uri_type); - infe->item_uri_type = (char *)calloc(1, sz); + infe->item_uri_type = (char *)calloc(1, sz + 1); memcpy(infe->item_uri_type, item_uri_type, sz); } else @@ -1176,6 +1176,67 @@ ISO_EXTERN(ISOErr) ISOSetItemInfoItemType(ISOMetaItem item, u32 item_type, char return err; } +ISO_EXTERN(ISOErr) ISOHideItem(ISOMetaItem item) +{ + MP4Err err; + ISOMetaAtomPtr myMeta; + MetaItemLocationPtr myItem; + ISOItemInfoAtomPtr iinf; + ISOPrimaryItemAtomPtr pitm; + ISOItemInfoEntryAtomPtr infe; + + err = MP4NoErr; + myItem = (MetaItemLocationPtr)item; + myMeta = (ISOMetaAtomPtr)myItem->meta; + iinf = (ISOItemInfoAtomPtr)myMeta->iinf; + pitm = (ISOPrimaryItemAtomPtr)myMeta->pitm; + + if(!iinf) BAILWITHERROR(MP4InvalidMediaErr); + + if(pitm->item_ID == myItem->item_ID) BAILWITHERROR(MP4InvalidMediaErr); + + infe = NULL; + err = iinf->getEntry(iinf, myItem->item_ID, &infe); + if(err) goto bail; + + if(infe == NULL) BAILWITHERROR(MP4InvalidMediaErr); + + infe->flags |= 1U; + +bail: + TEST_RETURN(err); + return err; +} + +ISO_EXTERN(ISOErr) ISOIsItemHidden(ISOMetaItem item) +{ + MP4Err err; + ISOMetaAtomPtr myMeta; + MetaItemLocationPtr myItem; + ISOItemInfoAtomPtr iinf; + ISOItemInfoEntryAtomPtr infe; + + err = MP4NoErr; + myItem = (MetaItemLocationPtr)item; + myMeta = (ISOMetaAtomPtr)myItem->meta; + iinf = (ISOItemInfoAtomPtr)myMeta->iinf; + + if(!iinf) BAILWITHERROR(MP4InvalidMediaErr); + + infe = NULL; + err = iinf->getEntry(iinf, myItem->item_ID, &infe); + if(err) goto bail; + + if(infe == NULL) BAILWITHERROR(MP4InvalidMediaErr); + + err = MP4NotFoundErr; + if(infe->flags & 1U) err = MP4NoErr; + +bail: + TEST_RETURN(err); + return err; +} + ISO_EXTERN(ISOErr) ISOGetItemInfoItemType(ISOMetaItem item, u32 *item_type, char **item_uri_type) { MP4Err err; @@ -1201,11 +1262,14 @@ ISO_EXTERN(ISOErr) ISOGetItemInfoItemType(ISOMetaItem item, u32 *item_type, char *item_type = infe->item_type; - if(infe->item_uri_type) + if(item_uri_type) { - u32 sz = (u32)strlen(infe->item_uri_type); - *item_uri_type = (char *)calloc(1, sz); - memcpy(*item_uri_type, infe->item_uri_type, sz); + if(infe->item_uri_type) + { + u32 sz = (u32)strlen(infe->item_uri_type); + *item_uri_type = (char *)calloc(1, sz + 1); + memcpy(*item_uri_type, infe->item_uri_type, sz); + } } bail: TEST_RETURN(err); diff --git a/IsoLib/libisomediafile/src/ISOMovies.h b/IsoLib/libisomediafile/src/ISOMovies.h index f5c369e..54896db 100644 --- a/IsoLib/libisomediafile/src/ISOMovies.h +++ b/IsoLib/libisomediafile/src/ISOMovies.h @@ -715,6 +715,26 @@ extern "C" * @todo rename the function to ISOGetOriginalFormat and parse the cinf and sinf as well */ ISO_EXTERN(ISOErr) ISOGetRESVOriginalFormat(MP4Handle sampleEntryH, u32 *outOrigFmt); + /** + * @brief Get scheme_type and scheme_version from the SchemeTypeBox in resv + * @ingroup SampleDescr + * @param sampleEntryH resv sample entry data + * @param schemeType [out] scheme_type 4CC + * @param schemeVersion [out] scheme_version + * @param schemeURI [out] scheme_uri + */ + ISO_EXTERN(ISOErr) + ISOGetRESVSchemeType(MP4Handle sampleEntryH, u32 *schemeType, u32 *schemeVersion, + char **schemeURI); + /** + * @brief Get the box from the SchemeInformationBox in resv + * @ingroup SampleDescr + * @param sampleEntryH resv sample entry data + * @param atomType type of the atom inside SchemeInformationBox + * @param outAtom [out] data of the found box + */ + ISO_EXTERN(ISOErr) + ISOGetRESVSchemeInfoAtom(MP4Handle sampleEntryH, u32 atomType, MP4Handle outAtom); /** * @brief Create a new HEVC sample entry. * @ingroup SampleDescr @@ -1081,6 +1101,17 @@ extern "C" * @param item_uri_type can be NULL, if the item_type is not ‘uri ‘ */ ISO_EXTERN(ISOErr) ISOSetItemInfoItemType(ISOMetaItem item, u32 item_type, char *item_uri_type); + /** + * @brief Hide item by setting the (flags & 1) = 1 + * @param item Item to hide + */ + ISO_EXTERN(ISOErr) ISOHideItem(ISOMetaItem item); + /** + * @brief Check if item is hiden + * @param item Item to check + * @return MP4NoErr if item is hidden, MP4NotFoundErr if not, MP4InvalidMediaErr otherwise + */ + ISO_EXTERN(ISOErr) ISOIsItemHidden(ISOMetaItem item); /** * @brief Gets an item info item type from an existing item info entry. * @param item_uri_type could be NULL, if the item_type is not ‘uri ‘. diff --git a/IsoLib/libisomediafile/src/ISOSampleDescriptions.c b/IsoLib/libisomediafile/src/ISOSampleDescriptions.c index b562b1a..24f9f1a 100644 --- a/IsoLib/libisomediafile/src/ISOSampleDescriptions.c +++ b/IsoLib/libisomediafile/src/ISOSampleDescriptions.c @@ -403,8 +403,16 @@ ISOGetSampleDescriptionDimensions(MP4Handle sampleEntryH, u16 *width, u16 *heigh err = sampleEntryHToAtomPtr(sampleEntryH, (MP4AtomPtr *)&entry, MP4VisualSampleEntryAtomType); if(err) goto bail; - *width = (u16)entry->width; - *height = (u16)entry->height; + if(entry->type == MP4RestrictedVideoSampleEntryAtomType) + { + *width = (u16)((MP4RestrictedVideoSampleEntryAtomPtr)entry)->width; + *height = (u16)((MP4RestrictedVideoSampleEntryAtomPtr)entry)->height; + } + else + { + *width = (u16)entry->width; + *height = (u16)entry->height; + } bail: if(entry) entry->destroy((MP4AtomPtr)entry); @@ -1381,7 +1389,8 @@ MP4_EXTERN(MP4Err) ISOGetRESVOriginalFormat(MP4Handle sampleEntryH, u32 *outOrig if(entry->type != MP4RestrictedVideoSampleEntryAtomType) BAILWITHERROR(MP4BadParamErr); - rinf = (MP4RestrictedSchemeInfoAtomPtr)entry->MP4RestrictedSchemeInfo; + err = entry->getRinf((MP4AtomPtr)entry, (MP4AtomPtr *)&rinf); + if(err) goto bail; if(!rinf) { BAILWITHERROR(MP4BadParamErr); @@ -1399,6 +1408,50 @@ MP4_EXTERN(MP4Err) ISOGetRESVOriginalFormat(MP4Handle sampleEntryH, u32 *outOrig return err; } +ISO_EXTERN(ISOErr) +ISOGetRESVSchemeType(MP4Handle sampleEntryH, u32 *schemeType, u32 *schemeVersion, char **schemeURI) +{ + MP4Err err; + MP4RestrictedVideoSampleEntryAtomPtr entry = NULL; + + err = sampleEntryHToAtomPtr(sampleEntryH, (MP4AtomPtr *)&entry, MP4VisualSampleEntryAtomType); + if(err) goto bail; + + if(entry->type != MP4RestrictedVideoSampleEntryAtomType) BAILWITHERROR(MP4BadParamErr); + + err = entry->getScheme((MP4AtomPtr)entry, schemeType, schemeVersion, schemeURI); + if(err) goto bail; + +bail: + if(entry) entry->destroy((MP4AtomPtr)entry); + return err; +} + +ISO_EXTERN(ISOErr) +ISOGetRESVSchemeInfoAtom(MP4Handle sampleEntryH, u32 atomType, MP4Handle outAtom) +{ + MP4Err err; + MP4RestrictedVideoSampleEntryAtomPtr entry = NULL; + MP4AtomPtr found; + + if(outAtom == NULL) BAILWITHERROR(MP4BadParamErr); + + err = sampleEntryHToAtomPtr(sampleEntryH, (MP4AtomPtr *)&entry, MP4VisualSampleEntryAtomType); + if(err) goto bail; + + if(entry->type != MP4RestrictedVideoSampleEntryAtomType) BAILWITHERROR(MP4BadParamErr); + + err = entry->getSchemeInfoAtom((MP4AtomPtr)entry, atomType, &found); + if(err) goto bail; + + err = atomPtrToSampleEntryH(outAtom, found); + if(err) goto bail; + +bail: + if(entry) entry->destroy((MP4AtomPtr)entry); + return err; +} + MP4_EXTERN(MP4Err) ISONewHEVCSampleDescription(MP4Track theTrack, MP4Handle sampleDescriptionH, u32 dataReferenceIndex, u32 length_size, MP4Handle first_sps, MP4Handle first_pps, diff --git a/IsoLib/libisomediafile/src/ItemInfoEntryAtom.c b/IsoLib/libisomediafile/src/ItemInfoEntryAtom.c index 1a71ba8..244a251 100644 --- a/IsoLib/libisomediafile/src/ItemInfoEntryAtom.c +++ b/IsoLib/libisomediafile/src/ItemInfoEntryAtom.c @@ -231,7 +231,7 @@ static MP4Err createFromInputStream(MP4AtomPtr s, MP4AtomPtr proto, MP4InputStre char inputstr[4096]; char *str; u32 i; - char msgString[200]; + char msgString[8192]; char typeString[8]; ISOItemInfoEntryAtomPtr self = (ISOItemInfoEntryAtomPtr)s; diff --git a/IsoLib/libisomediafile/src/MP4Atoms.h b/IsoLib/libisomediafile/src/MP4Atoms.h index 7a94d81..818e905 100644 --- a/IsoLib/libisomediafile/src/MP4Atoms.h +++ b/IsoLib/libisomediafile/src/MP4Atoms.h @@ -1224,13 +1224,17 @@ typedef struct MP4SubSampleInformationAtom MP4Err (*addEntry)(struct MP4SubSampleInformationAtom *self, u32 sample_delta, u32 subsample_count, MP4Handle subsample_size_array, MP4Handle subsample_priority_array, MP4Handle subsample_discardable_array); + MP4Err (*addEntry2)(struct MP4SubSampleInformationAtom *self, u32 sample_delta, + u32 subsample_count, MP4Handle subsample_size_array, + MP4Handle subsample_priority_array, MP4Handle subsample_discardable_array, + MP4Handle codec_specific_parameters_array); u32 entry_count; u32 *sample_delta; u32 *subsample_count; u32 **subsample_size; u32 **subsample_priority; u32 **discardable; - u32 **reserved; + u32 **codec_specific_parameters; } MP4SubSampleInformationAtom, *MP4SubSampleInformationAtomPtr; typedef struct MP4SyncSampleAtom @@ -1493,7 +1497,7 @@ enum typedef struct MP4TrackFragmentDecodeTimeAtom { MP4_FULL_ATOM - u32 baseMediaDecodeTime; + u64 baseMediaDecodeTime; } MP4TrackFragmentDecodeTimeAtom, *MP4TrackFragmentDecodeTimeAtomPtr; typedef struct MP4ItemPropertyContainerAtom @@ -1648,11 +1652,11 @@ typedef struct MP4RestrictedVideoSampleEntryAtom MP4_BASE_ATOM COMMON_SAMPLE_ENTRY_FIELDS - MP4AtomPtr MP4RestrictedSchemeInfo; u32 restriction_type; MP4Err (*addSchemeInfoAtom)(struct MP4Atom *self, struct MP4Atom *theAtom); MP4Err (*getSchemeInfoAtom)(struct MP4Atom *self, u32 theType, struct MP4Atom **theAtom); + MP4Err (*getRinf)(struct MP4Atom *self, struct MP4Atom **theAtom); MP4Err (*getScheme)(struct MP4Atom *self, u32 *sch_type, u32 *sch_version, char **sch_url); MP4Err (*transform)(struct MP4Atom *self, u32 sch_type, u32 sch_version, char *sch_url); @@ -1792,6 +1796,8 @@ typedef struct MP4SampleGroupDescriptionAtom u32 default_length; /* we only handle version 1 */ + u32 default_group_description_index; /* only after version 2 */ + u32 groupCount; sampleGroupEntry *groups; diff --git a/IsoLib/libisomediafile/src/MP4FileMappingInputStream.c b/IsoLib/libisomediafile/src/MP4FileMappingInputStream.c index 14f6ea9..53204cb 100644 --- a/IsoLib/libisomediafile/src/MP4FileMappingInputStream.c +++ b/IsoLib/libisomediafile/src/MP4FileMappingInputStream.c @@ -158,6 +158,29 @@ static MP4Err skipData(struct MP4InputStreamRecord *s, u64 bytes, char *msg) return err; } +static MP4Err rewindData(struct MP4InputStreamRecord *s, u64 bytes, char *msg) +{ + MP4Err err; + MP4FileMappingInputStreamPtr self = (MP4FileMappingInputStreamPtr)s; + + if(bytes > self->current_offset) BAILWITHERROR(MP4BadParamErr); + err = MP4NoErr; + + self->available += bytes; + self->current_offset -= bytes; + + if(msg && self->debugging) + { + doIndent(s); + fprintf(stdout, "%s = [%lld bytes of data rewinded]\n", msg, bytes); + } + +bail: + TEST_RETURN(err); + + return err; +} + static MP4Err readData(struct MP4InputStreamRecord *s, u64 bytes, char *outData, char *msg) { MP4Err err; @@ -223,6 +246,7 @@ MP4Err MP4CreateFileMappingInputStream(struct FileMappingObjectRecord *mapping, is->read32 = read32; is->readData = readData; is->skipData = skipData; + is->rewindData = rewindData; is->getStreamOffset = getStreamOffset; is->getFileMappingObject = getFileMappingObject; is->mapping = mapping; diff --git a/IsoLib/libisomediafile/src/MP4Impl.h b/IsoLib/libisomediafile/src/MP4Impl.h index 3af025f..98a7cb0 100644 --- a/IsoLib/libisomediafile/src/MP4Impl.h +++ b/IsoLib/libisomediafile/src/MP4Impl.h @@ -236,6 +236,11 @@ derivative works. Copyright (c) 1999. } \ } +#define REWIND_DATA(length, var) \ + err = inputStream->rewindData(inputStream, length, var); \ + if(err) goto bail; \ + self->bytesRead -= length; + #define PUTBYTES(src, len) \ if((self->bytesWritten + len) > self->size) \ { \ diff --git a/IsoLib/libisomediafile/src/MP4InputStream.h b/IsoLib/libisomediafile/src/MP4InputStream.h index b4e5f77..4a01b28 100644 --- a/IsoLib/libisomediafile/src/MP4InputStream.h +++ b/IsoLib/libisomediafile/src/MP4InputStream.h @@ -41,7 +41,8 @@ derivative works. Copyright (c) 1999. MP4Err (*read32)(struct MP4InputStreamRecord * self, u32 * outVal, char *msg); \ MP4Err (*readData)(struct MP4InputStreamRecord * self, u64 bytes, char *outData, char *msg); \ u64 (*getStreamOffset)(struct MP4InputStreamRecord * self); \ - MP4Err (*skipData)(struct MP4InputStreamRecord * self, u64 bytes, char *msg); + MP4Err (*skipData)(struct MP4InputStreamRecord * self, u64 bytes, char *msg); \ + MP4Err (*rewindData)(struct MP4InputStreamRecord * self, u64 bytes, char *msg); typedef struct MP4InputStreamRecord { diff --git a/IsoLib/libisomediafile/src/MP4LinkedList.c b/IsoLib/libisomediafile/src/MP4LinkedList.c index e795d9e..647762e 100644 --- a/IsoLib/libisomediafile/src/MP4LinkedList.c +++ b/IsoLib/libisomediafile/src/MP4LinkedList.c @@ -37,6 +37,7 @@ MP4Err MP4MakeLinkedList(MP4LinkedList *outList) newList = (MP4LinkedList)calloc(1, sizeof(MP4List)); TESTMALLOC(newList) newList->foundEntryNumber = -1; + newList->entryCount = 0; *outList = newList; bail: return err; diff --git a/IsoLib/libisomediafile/src/MP4MemoryInputStream.c b/IsoLib/libisomediafile/src/MP4MemoryInputStream.c index d345df1..126f4b2 100644 --- a/IsoLib/libisomediafile/src/MP4MemoryInputStream.c +++ b/IsoLib/libisomediafile/src/MP4MemoryInputStream.c @@ -168,6 +168,29 @@ static MP4Err skipData(struct MP4InputStreamRecord *s, u64 bytes, char *msg) return err; } +static MP4Err rewindData(struct MP4InputStreamRecord *s, u64 bytes, char *msg) +{ + MP4Err err; + MP4FileMappingInputStreamPtr self = (MP4FileMappingInputStreamPtr)s; + + if(bytes > self->current_offset) BAILWITHERROR(MP4BadParamErr); + err = MP4NoErr; + + self->available += bytes; + self->current_offset -= bytes; + + if(msg && self->debugging) + { + doIndent(s); + fprintf(stdout, "%s = [%lld bytes of data rewinded]\n", msg, bytes); + } + +bail: + TEST_RETURN(err); + + return err; +} + static MP4Err readData(struct MP4InputStreamRecord *s, u64 bytes, char *outData, char *msg) { MP4Err err; @@ -221,6 +244,7 @@ MP4Err MP4CreateMemoryInputStream(char *base, u32 size, MP4InputStreamPtr *outSt is->read32 = read32; is->readData = readData; is->skipData = skipData; + is->rewindData = rewindData; is->getStreamOffset = getStreamOffset; is->msg = msg; is->getFileMappingObject = getFileMappingObject; diff --git a/IsoLib/libisomediafile/src/MP4Movies.c b/IsoLib/libisomediafile/src/MP4Movies.c index 3821f61..26f00f1 100644 --- a/IsoLib/libisomediafile/src/MP4Movies.c +++ b/IsoLib/libisomediafile/src/MP4Movies.c @@ -395,6 +395,7 @@ MP4_EXTERN(MP4Err) MP4GetMovieTrackCount(MP4Movie theMovie, u32 *outTrackCount) { GETMOVIEATOM(theMovie); + if(movieAtom == NULL) BAILWITHERROR(MP4BadDataErr); *outTrackCount = movieAtom->getTrackCount(movieAtom); bail: TEST_RETURN(err); @@ -790,6 +791,33 @@ MP4GetMovieIndTrack(MP4Movie theMovie, u32 trackIndex, MP4Track *outTrack) return err; } +MP4_EXTERN(MP4Err) +MP4GetMovieIndTrackSampleEntryType(MP4Movie theMovie, u32 idx, u32 *SEType) +{ + MP4Err err; + MP4Track trak; + MP4TrackReader reader; + MP4Handle sampleEntryH; + + MP4NewHandle(0, &sampleEntryH); + + err = MP4GetMovieIndTrack(theMovie, idx, &trak); + if(err) goto bail; + + err = MP4CreateTrackReader(trak, &reader); + if(err) goto bail; + + err = MP4TrackReaderGetCurrentSampleDescription(reader, sampleEntryH); + if(err) goto bail; + + err = ISOGetSampleDescriptionType(sampleEntryH, SEType); + +bail: + TEST_RETURN(err); + MP4DisposeHandle(sampleEntryH); + return err; +} + MP4_EXTERN(MP4Err) MP4GetMovieTrack(MP4Movie theMovie, u32 trackID, MP4Track *outTrack) { diff --git a/IsoLib/libisomediafile/src/MP4Movies.h b/IsoLib/libisomediafile/src/MP4Movies.h index 72ee335..feac52c 100644 --- a/IsoLib/libisomediafile/src/MP4Movies.h +++ b/IsoLib/libisomediafile/src/MP4Movies.h @@ -693,6 +693,25 @@ extern "C" MP4Handle subsample_size_array, MP4Handle subsample_priority_array, MP4Handle subsample_discardable_array); + /** + * @brief Same as MP4AddSubSampleInformationEntry but also allows to add the codec specific + * parameters + * + * @param subsample + * @param sample_delta + * @param subsample_count + * @param subsample_size_array + * @param subsample_priority_array + * @param subsample_discardable_array + * @param codec_specific_parameters_array + * @return MP4Err error code + */ + MP4_EXTERN(MP4Err) + MP4AddSubSampleInformationEntry2(MP4GenericAtom subsample, u32 sample_delta, u32 subsample_count, + MP4Handle subsample_size_array, + MP4Handle subsample_priority_array, + MP4Handle subsample_discardable_array, + MP4Handle codec_specific_parameters_array); /** * @brief Add track to a track group ID. * @@ -726,6 +745,15 @@ extern "C" * @return MP4Err error code */ MP4_EXTERN(MP4Err) MP4GetMovieIndTrack(MP4Movie theMovie, u32 trackIndex, MP4Track *outTrack); + /** + * @brief Get sample entry type of a track. + * + * @note This function only returns the first sample entry type. + * @param theMovie input movie object + * @param idx index of the track ranges between 1 and the number of tracks in theMovie. + * @param SEType [out] sample entry type (4CC) + */ + MP4_EXTERN(MP4Err) MP4GetMovieIndTrackSampleEntryType(MP4Movie theMovie, u32 idx, u32 *SEType); /* MP4_EXTERN ( MP4Err ) diff --git a/IsoLib/libisomediafile/src/MP4TrackReader.h b/IsoLib/libisomediafile/src/MP4TrackReader.h index b8de546..ad7c582 100644 --- a/IsoLib/libisomediafile/src/MP4TrackReader.h +++ b/IsoLib/libisomediafile/src/MP4TrackReader.h @@ -58,7 +58,7 @@ typedef struct MP4TrackReaderStruct { TRACK_READER_ENTRIES u32 isODTrack; -} * MP4TrackReaderPtr; +} *MP4TrackReaderPtr; MP4Err MP4CreateODTrackReader(MP4Movie theMovie, MP4Track theTrack, MP4TrackReaderPtr *outReader); MP4Err MP4CreateOrdinaryTrackReader(MP4Movie theMovie, MP4Track theTrack, diff --git a/IsoLib/libisomediafile/src/MovieFragmentAtom.c b/IsoLib/libisomediafile/src/MovieFragmentAtom.c index 9fa48e1..9154df0 100644 --- a/IsoLib/libisomediafile/src/MovieFragmentAtom.c +++ b/IsoLib/libisomediafile/src/MovieFragmentAtom.c @@ -162,8 +162,10 @@ static MP4Err mergeFragments(struct MP4MovieFragmentAtom *self, MP4MovieAtomPtr if(tfdt->baseMediaDecodeTime < initialMediaDuration) BAILWITHERROR(MP4InvalidMediaErr); if(tfdt->baseMediaDecodeTime > initialMediaDuration) - err = mdia->extendLastSampleDuration(mdia, - tfdt->baseMediaDecodeTime - (u32)initialMediaDuration); + { + u32 duration = (tfdt->baseMediaDecodeTime - initialMediaDuration) & 0xffffffff; + err = mdia->extendLastSampleDuration(mdia, duration); + } if(err) goto bail; } diff --git a/IsoLib/libisomediafile/src/MovieTracks.c b/IsoLib/libisomediafile/src/MovieTracks.c index 91c798c..7b3f2fe 100644 --- a/IsoLib/libisomediafile/src/MovieTracks.c +++ b/IsoLib/libisomediafile/src/MovieTracks.c @@ -323,6 +323,28 @@ MP4AddSubSampleInformationEntry(MP4GenericAtom subsample, u32 sample_delta, u32 return err; } +MP4_EXTERN(MP4Err) +MP4AddSubSampleInformationEntry2(MP4GenericAtom subsample, u32 sample_delta, u32 subsample_count, + MP4Handle subsample_size_array, MP4Handle subsample_priority_array, + MP4Handle subsample_discardable_array, + MP4Handle codec_specific_parameters_array) +{ + MP4Err err; + MP4SubSampleInformationAtomPtr subs; + + err = MP4NoErr; + if(subsample == NULL) BAILWITHERROR(MP4BadParamErr); + subs = (MP4SubSampleInformationAtomPtr)subsample; + + err = subs->addEntry2(subs, sample_delta, subsample_count, subsample_size_array, + subsample_priority_array, subsample_discardable_array, + codec_specific_parameters_array); + +bail: + TEST_RETURN(err); + return err; +} + MP4_EXTERN(MP4Err) MP4AddTrackGroup(MP4Track theTrack, u32 groupID, u32 dependencyType) { MP4Err err; diff --git a/IsoLib/libisomediafile/src/RestrictedVideoSampleEntry.c b/IsoLib/libisomediafile/src/RestrictedVideoSampleEntry.c index 1fa704f..5802586 100644 --- a/IsoLib/libisomediafile/src/RestrictedVideoSampleEntry.c +++ b/IsoLib/libisomediafile/src/RestrictedVideoSampleEntry.c @@ -42,11 +42,6 @@ static void destroy(MP4AtomPtr s) self = (MP4RestrictedVideoSampleEntryAtomPtr)s; if(self == NULL) BAILWITHERROR(MP4BadParamErr) - if(self->MP4RestrictedSchemeInfo) - { - self->MP4RestrictedSchemeInfo->destroy(self->MP4RestrictedSchemeInfo); - self->MP4RestrictedSchemeInfo = NULL; - } DESTROY_ATOM_LIST_F(ExtensionAtomList) if(self->super) self->super->destroy(s); @@ -81,7 +76,6 @@ static MP4Err serialize(struct MP4Atom *s, char *buffer) PUT16(reserved8); PUT16(reserved9); - SERIALIZE_ATOM(MP4RestrictedSchemeInfo); SERIALIZE_ATOM_LIST(ExtensionAtomList); assert(self->bytesWritten == self->size); @@ -102,7 +96,6 @@ static MP4Err calculateSize(struct MP4Atom *s) if(err) goto bail; self->size += (6 + 16 + 31 + (4 * 2) + (1 * 1) + (4 * 4)); /* TODO this probably includes restriction_type */ - ADD_ATOM_SIZE(MP4RestrictedSchemeInfo); ADD_ATOM_LIST_SIZE(ExtensionAtomList); bail: TEST_RETURN(err); @@ -115,12 +108,9 @@ static MP4Err addAtom(MP4RestrictedVideoSampleEntryAtomPtr self, MP4AtomPtr atom MP4Err err; err = MP4NoErr; if(atom == NULL) BAILWITHERROR(MP4BadParamErr); - if(atom->type == MP4RestrictedSchemeInfoAtomType) self->MP4RestrictedSchemeInfo = atom; - else - { - err = MP4AddListEntry(atom, self->ExtensionAtomList); - if(err) goto bail; - } + err = MP4AddListEntry(atom, self->ExtensionAtomList); + if(err) goto bail; + bail: TEST_RETURN(err); @@ -151,7 +141,6 @@ static MP4Err createFromInputStream(MP4AtomPtr s, MP4AtomPtr proto, MP4InputStre GETBYTES(31, name31); GET16(reserved8); GET16(reserved9); - GETATOM(MP4RestrictedSchemeInfo); GETATOM_LIST(ExtensionAtomList); if(self->bytesRead != self->size) BAILWITHERROR(MP4BadDataErr); @@ -228,14 +217,30 @@ static MP4Err transform(struct MP4Atom *s, u32 sch_type, u32 sch_version, char * static MP4Err untransform(struct MP4Atom *s) { MP4Err err; - + u32 atomListSize; + u32 i, index = 0; MP4RestrictedVideoSampleEntryAtomPtr self = (MP4RestrictedVideoSampleEntryAtomPtr)s; MP4OriginalFormatAtomPtr fmt; MP4RestrictedSchemeInfoAtomPtr rinf; - err = MP4NoErr; + err = MP4NoErr; + rinf = NULL; + + err = MP4GetListEntryCount(self->ExtensionAtomList, &atomListSize); + if(err) goto bail; + for(i = 0; i < atomListSize; i++) + { + MP4AtomPtr a; + err = MP4GetListEntry(self->ExtensionAtomList, i, (char **)&a); + if(err) goto bail; + if(a->type == MP4RestrictedSchemeInfoAtomType) + { + index = i; + rinf = (MP4RestrictedSchemeInfoAtomPtr)a; + break; + } + } - rinf = (MP4RestrictedSchemeInfoAtomPtr)self->MP4RestrictedSchemeInfo; if(!rinf) { err = MP4BadParamErr; @@ -249,11 +254,11 @@ static MP4Err untransform(struct MP4Atom *s) goto bail; } - self->type = fmt->original_format; - self->MP4RestrictedSchemeInfo = NULL; - + self->type = fmt->original_format; rinf->destroy((MP4AtomPtr)rinf); + err = MP4DeleteListEntry(self->ExtensionAtomList, index); + bail: TEST_RETURN(err); @@ -268,7 +273,8 @@ static MP4Err addSchemeInfoAtom(struct MP4Atom *s, struct MP4Atom *theAtom) MP4SchemeInfoAtomPtr schi; MP4RestrictedSchemeInfoAtomPtr rinf; - rinf = (MP4RestrictedSchemeInfoAtomPtr)self->MP4RestrictedSchemeInfo; + err = self->getRinf((MP4AtomPtr)self, (MP4AtomPtr *)&rinf); + if(err) goto bail; if(!rinf) { err = MP4BadParamErr; @@ -301,7 +307,8 @@ static MP4Err getSchemeInfoAtom(struct MP4Atom *s, u32 theType, struct MP4Atom * err = MP4NoErr; - rinf = (MP4RestrictedSchemeInfoAtomPtr)self->MP4RestrictedSchemeInfo; + err = self->getRinf((MP4AtomPtr)self, (MP4AtomPtr *)&rinf); + if(err) goto bail; if(!rinf) { err = MP4BadParamErr; @@ -344,6 +351,32 @@ static MP4Err getSchemeInfoAtom(struct MP4Atom *s, u32 theType, struct MP4Atom * return err; } +static MP4Err getRinf(struct MP4Atom *s, struct MP4Atom **theAtom) +{ + MP4Err err; + u32 atomListSize; + u32 i; + MP4RestrictedVideoSampleEntryAtomPtr self = (MP4RestrictedVideoSampleEntryAtomPtr)s; + + err = MP4GetListEntryCount(self->ExtensionAtomList, &atomListSize); + if(err) goto bail; + for(i = 0; i < atomListSize; i++) + { + MP4AtomPtr a; + err = MP4GetListEntry(self->ExtensionAtomList, i, (char **)&a); + if(err) goto bail; + if(a->type == MP4RestrictedSchemeInfoAtomType) + { + *theAtom = a; + return MP4NoErr; + } + } + +bail: + TEST_RETURN(err); + return err; +} + static MP4Err getScheme(struct MP4Atom *s, u32 *sch_type, u32 *sch_version, char **sch_url) { MP4Err err; @@ -355,7 +388,8 @@ static MP4Err getScheme(struct MP4Atom *s, u32 *sch_type, u32 *sch_version, char err = MP4NoErr; - rinf = (MP4RestrictedSchemeInfoAtomPtr)self->MP4RestrictedSchemeInfo; + err = self->getRinf((MP4AtomPtr)self, (MP4AtomPtr *)&rinf); + if(err) goto bail; if(!rinf) { err = MP4BadParamErr; @@ -400,6 +434,7 @@ MP4Err MP4CreateRestrictedVideoSampleEntryAtom(MP4RestrictedVideoSampleEntryAtom self->untransform = untransform; self->addSchemeInfoAtom = addSchemeInfoAtom; self->getSchemeInfoAtom = getSchemeInfoAtom; + self->getRinf = getRinf; self->getScheme = getScheme; self->transform = transform; self->addAtom = addAtom; diff --git a/IsoLib/libisomediafile/src/SampleGroupDescriptionAtom.c b/IsoLib/libisomediafile/src/SampleGroupDescriptionAtom.c index 5c67cdd..9b8ad26 100644 --- a/IsoLib/libisomediafile/src/SampleGroupDescriptionAtom.c +++ b/IsoLib/libisomediafile/src/SampleGroupDescriptionAtom.c @@ -222,14 +222,13 @@ static MP4Err createFromInputStream(MP4AtomPtr s, MP4AtomPtr proto, MP4InputStre sprintf(msgString, " grouping type is '%s'", typeString); inputStream->msg(inputStream, msgString); - if(self->version == 1) + if(self->version >= 1) { GET32(default_length); } - else + if(self->version >= 2) { - err = MP4NotImplementedErr; - goto bail; + GET32(default_group_description_index); } GET32(groupCount); @@ -240,12 +239,22 @@ static MP4Err createFromInputStream(MP4AtomPtr s, MP4AtomPtr proto, MP4InputStre for(i = 0; i < self->groupCount; i++) { u32 count; - if(self->default_length == 0) + if(self->version >= 1) { - GET32_V_MSG(count, NULL); + if(self->default_length == 0) + { + GET32_V_MSG(count, NULL); + } + else + { + count = self->default_length; + } } else - count = self->default_length; + { + assert(self->size > self->bytesRead); + count = self->size - self->bytesRead; + } sprintf(msgString, " entry %d, size %d", i + 1, count); inputStream->msg(inputStream, msgString); @@ -287,6 +296,8 @@ MP4Err MP4CreateSampleGroupDescriptionAtom(MP4SampleGroupDescriptionAtomPtr *out self->groupCount = 0; self->groups = NULL; + self->default_group_description_index = 0; + *outAtom = self; bail: TEST_RETURN(err); diff --git a/IsoLib/libisomediafile/src/SampleTableAtom.c b/IsoLib/libisomediafile/src/SampleTableAtom.c index 3094996..4edb2e7 100644 --- a/IsoLib/libisomediafile/src/SampleTableAtom.c +++ b/IsoLib/libisomediafile/src/SampleTableAtom.c @@ -144,14 +144,14 @@ static MP4Err addAtom(MP4SampleTableAtomPtr self, MP4AtomPtr atom) static MP4Err calculateDuration(struct MP4SampleTableAtom *self, u32 *outDuration) { MP4Err err; - MP4TimeToSampleAtomPtr ctts; + MP4TimeToSampleAtomPtr stts; err = MP4NoErr; if(outDuration == NULL) BAILWITHERROR(MP4BadParamErr) - ctts = (MP4TimeToSampleAtomPtr)self->TimeToSample; - if(ctts == NULL) BAILWITHERROR(MP4InvalidMediaErr) - err = ctts->getTotalDuration(ctts, outDuration); + stts = (MP4TimeToSampleAtomPtr)self->TimeToSample; + if(stts == NULL) BAILWITHERROR(MP4InvalidMediaErr) + err = stts->getTotalDuration(stts, outDuration); if(err) goto bail; bail: @@ -712,7 +712,7 @@ static MP4Err getSampleGroupSampleNumbers(struct MP4SampleTableAtom *self, u32 g { MP4Err err; MP4SampletoGroupAtomPtr theGroup; - u32 i, cur_index, cur_count; + u32 i, cur_index; *outSampleCnt = 0; err = MP4FindGroupAtom(self->sampletoGroupList, groupType, (MP4AtomPtr *)&theGroup); @@ -721,17 +721,14 @@ static MP4Err getSampleGroupSampleNumbers(struct MP4SampleTableAtom *self, u32 g *outSampleNumbers = (u32 *)malloc((theGroup->sampleCount) * sizeof(u32)); TESTMALLOC(*outSampleNumbers); cur_index = (theGroup->group_index)[0]; - cur_count = 1; for(i = 1; i < theGroup->sampleCount; i++) { - if((theGroup->group_index)[i - 1] == (theGroup->group_index)[i]) cur_count++; - else + if((theGroup->group_index)[i - 1] != (theGroup->group_index)[i]) { if(cur_index == groupIndex) { (*outSampleNumbers)[(*outSampleCnt)++] = i; } - cur_count = 1; cur_index = (theGroup->group_index)[i]; } } @@ -743,7 +740,6 @@ static MP4Err getSampleGroupSampleNumbers(struct MP4SampleTableAtom *self, u32 g bail: TEST_RETURN(err); - return err; } diff --git a/IsoLib/libisomediafile/src/SampleToGroupAtom.c b/IsoLib/libisomediafile/src/SampleToGroupAtom.c index d02df47..340ff1d 100644 --- a/IsoLib/libisomediafile/src/SampleToGroupAtom.c +++ b/IsoLib/libisomediafile/src/SampleToGroupAtom.c @@ -676,6 +676,10 @@ static MP4Err serialize(struct MP4Atom *s, char *buffer) (self->compressedGroup.index_msb_indicates_fragment_local_description ? 0x80 : 0) | (self->compressedGroup.grouping_type_parameter_present ? 0x40 : 0); } + else + { + self->flags = 0; + } err = MP4SerializeCommonFullAtomFields((MP4FullAtomPtr)s, buffer); if(err) goto bail; @@ -712,6 +716,7 @@ static MP4Err serialize(struct MP4Atom *s, char *buffer) entryCount++; assert(entryCount == self->entryCount); + (void)entryCount; /* remove the release build warning */ } else { diff --git a/IsoLib/libisomediafile/src/SegmentIndexAtom.c b/IsoLib/libisomediafile/src/SegmentIndexAtom.c index 0e1f5c1..bec787e 100644 --- a/IsoLib/libisomediafile/src/SegmentIndexAtom.c +++ b/IsoLib/libisomediafile/src/SegmentIndexAtom.c @@ -75,7 +75,7 @@ static MP4Err addReference(struct MP4SegmentIndexAtom *self, u8 referenceType, u p->startsWithSAP = startsWithSAP; p->SAPType = SAPType; p->SAPDeltaTime = SAPDeltaTime; - + self->referenceCount++; /* add reference to linked list */ err = MP4AddListEntry(p, self->referencesList); if(err) goto bail; @@ -170,6 +170,7 @@ static MP4Err serialize(struct MP4Atom *s, char *buffer) static MP4Err calculateSize(struct MP4Atom *s) { MP4Err err; + u32 i; MP4SegmentIndexAtomPtr self = (MP4SegmentIndexAtomPtr)s; err = MP4NoErr; @@ -180,6 +181,10 @@ static MP4Err calculateSize(struct MP4Atom *s) self->size += (4 * self->referenceCount); + for(i = 0; i < self->referenceCount; i++) + { + self->size += 12; + } bail: TEST_RETURN(err); diff --git a/IsoLib/libisomediafile/src/SubSampleInformationAtom.c b/IsoLib/libisomediafile/src/SubSampleInformationAtom.c index 9538e14..2e430f0 100644 --- a/IsoLib/libisomediafile/src/SubSampleInformationAtom.c +++ b/IsoLib/libisomediafile/src/SubSampleInformationAtom.c @@ -1,25 +1,17 @@ -/* -This software module was originally developed by Apple Computer, Inc. -in the course of development of MPEG-4. -This software module is an implementation of a part of one or -more MPEG-4 tools as specified by MPEG-4. -ISO/IEC gives users of MPEG-4 free license to this -software module or modifications thereof for use in hardware -or software products claiming conformance to MPEG-4. -Those intending to use this software module in hardware or software -products are advised that its use may infringe existing patents. -The original developer of this software module and his/her company, -the subsequent editors and their companies, and ISO/IEC have no -liability for use of this software module or modifications thereof -in an implementation. -Copyright is not released for non MPEG-4 conforming -products. Apple Computer, Inc. retains full right to use the code for its own -purpose, assign or donate the code to a third party and to -inhibit third parties from using the code for non -MPEG-4 conforming products. -This copyright notice must be included in all copies or -derivative works. Copyright (c) 1999. -*/ +/* This software module was originally developed by Apple Computer, Inc. in the course of + * development of MPEG-4. This software module is an implementation of a part of one or more MPEG-4 + * tools as specified by MPEG-4. ISO/IEC gives users of MPEG-4 free license to this software module + * or modifications thereof for use in hardware or software products claiming conformance to MPEG-4. + * Those intending to use this software module in hardware or software products are advised that its + * use may infringe existing patents. The original developer of this software module and his/her + * company, the subsequent editors and their companies, and ISO/IEC have no liability for use of + * this software module or modifications thereof in an implementation. Copyright is not released for + * non MPEG-4 conforming products. Apple Computer, Inc. retains full right to use the code for its + * own purpose, assign or donate the code to a third party and to inhibit third parties from using + * the code for non MPEG-4 conforming products. This copyright notice must be included in all copies + * or derivative works. Copyright (c) 1999. + */ + /* Created for Nokia FAVS project by Tampere University of Technology */ #include "MP4Atoms.h" @@ -43,8 +35,8 @@ static void destroy(MP4AtomPtr s) self->subsample_priority[i] = NULL; free(self->discardable[i]); self->discardable[i] = NULL; - free(self->reserved[i]); - self->reserved[i] = NULL; + free(self->codec_specific_parameters[i]); + self->codec_specific_parameters[i] = NULL; } } free(self->subsample_size); @@ -53,8 +45,8 @@ static void destroy(MP4AtomPtr s) self->subsample_priority = NULL; free(self->discardable); self->discardable = NULL; - free(self->reserved); - self->reserved = NULL; + free(self->codec_specific_parameters); + self->codec_specific_parameters = NULL; free(self->subsample_count); self->subsample_count = NULL; @@ -91,7 +83,7 @@ static MP4Err serialize(struct MP4Atom *s, char *buffer) } PUT8(subsample_priority[i][j]); PUT8(discardable[i][j]); - PUT32(reserved[i][j]); + PUT32(codec_specific_parameters[i][j]); } } assert(self->bytesWritten == self->size); @@ -159,19 +151,91 @@ static MP4Err addEntry(MP4SubSampleInformationAtom *s, u32 sample_delta, u32 sub self->discardable[current_entry] = (u32 *)calloc(subsample_count, sizeof(u32)); TESTMALLOC(self->discardable[current_entry]); - self->reserved = (u32 **)realloc(self->reserved, (self->entry_count + 1) * sizeof(u32 *)); - TESTMALLOC(self->reserved); - self->reserved[current_entry] = (u32 *)calloc(subsample_count, sizeof(u32)); - TESTMALLOC(self->reserved[current_entry]); + self->codec_specific_parameters = + (u32 **)realloc(self->codec_specific_parameters, (self->entry_count + 1) * sizeof(u32 *)); + TESTMALLOC(self->codec_specific_parameters); + self->codec_specific_parameters[current_entry] = (u32 *)calloc(subsample_count, sizeof(u32)); + TESTMALLOC(self->codec_specific_parameters[current_entry]); self->sample_delta[current_entry] = sample_delta; self->subsample_count[current_entry] = subsample_count; for(i = 0; i < subsample_count; i++) { + if(((u32 *)*subsample_size_array)[i] > 0xFFFF) + { + self->version = 1; + } + self->subsample_size[current_entry][i] = ((u32 *)*subsample_size_array)[i]; + self->subsample_priority[current_entry][i] = ((u32 *)*subsample_priority_array)[i]; + self->discardable[current_entry][i] = ((u32 *)*subsample_discardable_array)[i]; + self->codec_specific_parameters[current_entry][i] = 0; + } + + self->entry_count++; + +bail: + TEST_RETURN(err); + return err; +} + +static MP4Err addEntry2(MP4SubSampleInformationAtom *s, u32 sample_delta, u32 subsample_count, + MP4Handle subsample_size_array, MP4Handle subsample_priority_array, + MP4Handle subsample_discardable_array, + MP4Handle codec_specific_parameters_array) +{ + MP4Err err; + MP4SubSampleInformationAtomPtr self; + u32 i; + u32 current_entry; + + err = MP4NoErr; + if(s == NULL) BAILWITHERROR(MP4BadParamErr); + self = (MP4SubSampleInformationAtomPtr)s; + current_entry = self->entry_count; + + /* re-allocate basic structures */ + self->sample_delta = (u32 *)realloc(self->sample_delta, (self->entry_count + 1) * sizeof(u32)); + TESTMALLOC(self->sample_delta); + self->subsample_count = + (u32 *)realloc(self->subsample_count, (self->entry_count + 1) * sizeof(u32)); + TESTMALLOC(self->subsample_count); + + self->subsample_size = + (u32 **)realloc(self->subsample_size, (self->entry_count + 1) * sizeof(u32 *)); + TESTMALLOC(self->subsample_size); + self->subsample_size[current_entry] = (u32 *)calloc(subsample_count, sizeof(u32)); + TESTMALLOC(self->subsample_size[current_entry]); + + self->subsample_priority = + (u32 **)realloc(self->subsample_priority, (self->entry_count + 1) * sizeof(u32 *)); + TESTMALLOC(self->subsample_priority); + self->subsample_priority[current_entry] = (u32 *)calloc(subsample_count, sizeof(u32)); + TESTMALLOC(self->subsample_priority[current_entry]); + + self->discardable = (u32 **)realloc(self->discardable, (self->entry_count + 1) * sizeof(u32 *)); + TESTMALLOC(self->discardable); + self->discardable[current_entry] = (u32 *)calloc(subsample_count, sizeof(u32)); + TESTMALLOC(self->discardable[current_entry]); + + self->codec_specific_parameters = + (u32 **)realloc(self->codec_specific_parameters, (self->entry_count + 1) * sizeof(u32 *)); + TESTMALLOC(self->codec_specific_parameters); + self->codec_specific_parameters[current_entry] = (u32 *)calloc(subsample_count, sizeof(u32)); + TESTMALLOC(self->codec_specific_parameters[current_entry]); + + self->sample_delta[current_entry] = sample_delta; + self->subsample_count[current_entry] = subsample_count; + for(i = 0; i < subsample_count; i++) + { + if(((u32 *)*subsample_size_array)[i] > 0xFFFF) + { + self->version = 1; + } self->subsample_size[current_entry][i] = ((u32 *)*subsample_size_array)[i]; self->subsample_priority[current_entry][i] = ((u32 *)*subsample_priority_array)[i]; self->discardable[current_entry][i] = ((u32 *)*subsample_discardable_array)[i]; - self->reserved[current_entry][i] = 0; + self->codec_specific_parameters[current_entry][i] = + ((u32 *)*codec_specific_parameters_array)[i]; } self->entry_count++; @@ -205,8 +269,8 @@ static MP4Err createFromInputStream(MP4AtomPtr s, MP4AtomPtr proto, MP4InputStre TESTMALLOC(self->subsample_priority); self->discardable = (u32 **)calloc(self->entry_count, sizeof(u32 *)); TESTMALLOC(self->discardable); - self->reserved = (u32 **)calloc(self->entry_count, sizeof(u32 *)); - TESTMALLOC(self->reserved); + self->codec_specific_parameters = (u32 **)calloc(self->entry_count, sizeof(u32 *)); + TESTMALLOC(self->codec_specific_parameters); for(i = 0; i < self->entry_count; i++) { @@ -218,7 +282,7 @@ static MP4Err createFromInputStream(MP4AtomPtr s, MP4AtomPtr proto, MP4InputStre TESTMALLOC(self->subsample_count[i]); self->discardable[i] = (u32 *)calloc(self->subsample_count[i], sizeof(u32)); TESTMALLOC(self->subsample_count[i]); - self->reserved[i] = (u32 *)calloc(self->subsample_count[i], sizeof(u32)); + self->codec_specific_parameters[i] = (u32 *)calloc(self->subsample_count[i], sizeof(u32)); TESTMALLOC(self->subsample_count[i]); for(j = 0; j < self->subsample_count[i]; j++) { @@ -232,7 +296,7 @@ static MP4Err createFromInputStream(MP4AtomPtr s, MP4AtomPtr proto, MP4InputStre } GET8(subsample_priority[i][j]); GET8(discardable[i][j]); - GET32(reserved[i][j]); + GET32(codec_specific_parameters[i][j]); } } bail: @@ -258,11 +322,11 @@ MP4Err MP4CreateSubSampleInformationAtom(MP4SubSampleInformationAtomPtr *outAtom self->calculateSize = calculateSize; self->serialize = serialize; self->addEntry = addEntry; + self->addEntry2 = addEntry2; *outAtom = self; self->entry_count = 0; bail: TEST_RETURN(err); - return err; } diff --git a/IsoLib/libisomediafile/src/TextMetaSampleEntry.c b/IsoLib/libisomediafile/src/TextMetaSampleEntry.c index e0be906..5fb0208 100644 --- a/IsoLib/libisomediafile/src/TextMetaSampleEntry.c +++ b/IsoLib/libisomediafile/src/TextMetaSampleEntry.c @@ -125,7 +125,7 @@ static MP4Err readstring(char **b, MP4TextMetaSampleEntryAtomPtr self, u32 byte; MP4Err err; char temp[1024]; - char msgString[200]; + char msgString[8192]; char *p; err = MP4NoErr; diff --git a/IsoLib/libisomediafile/src/TrackFragmentDecodeTimeAtom.c b/IsoLib/libisomediafile/src/TrackFragmentDecodeTimeAtom.c index d278e5d..2325409 100644 --- a/IsoLib/libisomediafile/src/TrackFragmentDecodeTimeAtom.c +++ b/IsoLib/libisomediafile/src/TrackFragmentDecodeTimeAtom.c @@ -44,7 +44,17 @@ static MP4Err serialize(struct MP4Atom *s, char *buffer) err = MP4SerializeCommonFullAtomFields((MP4FullAtomPtr)s, buffer); if(err) goto bail; buffer += self->bytesWritten; - PUT32(baseMediaDecodeTime); + + if(self->version == 1) + { + PUT64(baseMediaDecodeTime); + } + else if(self->version == 0) + { + PUT32(baseMediaDecodeTime); + } + else + BAILWITHERROR(MP4NotImplementedErr); assert(self->bytesWritten == self->size); bail: @@ -61,7 +71,17 @@ static MP4Err calculateSize(struct MP4Atom *s) err = MP4CalculateFullAtomFieldSize((MP4FullAtomPtr)s); if(err) goto bail; - self->size += 4; + if(self->version == 1) + { + self->size += 8; + } + else if(self->version == 0) + { + self->size += 4; + } + else + BAILWITHERROR(MP4NotImplementedErr); + bail: TEST_RETURN(err); @@ -77,7 +97,17 @@ static MP4Err createFromInputStream(MP4AtomPtr s, MP4AtomPtr proto, MP4InputStre if(self == NULL) BAILWITHERROR(MP4BadParamErr) err = self->super->createFromInputStream(s, proto, (char *)inputStream); if(err) goto bail; - GET32(baseMediaDecodeTime); + if(self->version == 1) + { + GET64(baseMediaDecodeTime); + } + else if(self->version == 0) + { + GET32(baseMediaDecodeTime); + } + else + BAILWITHERROR(MP4NotImplementedErr); + assert(self->bytesRead == self->size); bail: diff --git a/IsoLib/libisomediafile/src/XMLMetaSampleEntry.c b/IsoLib/libisomediafile/src/XMLMetaSampleEntry.c index 64ffc2a..be90621 100644 --- a/IsoLib/libisomediafile/src/XMLMetaSampleEntry.c +++ b/IsoLib/libisomediafile/src/XMLMetaSampleEntry.c @@ -140,7 +140,7 @@ static MP4Err readstring(char **b, MP4XMLMetaSampleEntryAtomPtr self, MP4InputSt u32 byte; MP4Err err; char temp[1024]; - char msgString[200]; + char msgString[8192]; char *p; err = MP4NoErr; diff --git a/test/test_01_simple.cpp b/test/test_01_simple.cpp index 2f06699..9fe0968 100644 --- a/test/test_01_simple.cpp +++ b/test/test_01_simple.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "testdataPath.h" #include @@ -118,6 +119,30 @@ TEST_CASE("01_simple.mp4") CHECK(err == MP4NoErr); CHECK(uiTrackCnt == 4); + for(uint32_t i=1; i<=uiTrackCnt; i++) + { + uint32_t type = 0; + err = MP4GetMovieIndTrackSampleEntryType(cMovieBox, i, &type); + CHECK(err == MP4NoErr); + switch (i) + { + case 1: + CHECK(type == MP4MPEGSampleEntryAtomType); + break; + case 2: + CHECK(type == MP4MPEGSampleEntryAtomType); + break; + case 3: + CHECK(type == MP4VisualSampleEntryAtomType); + break; + case 4: + CHECK(type == MP4AudioSampleEntryAtomType); + break; + default: + break; + } + } + // ISOGetTrackEnabled u32 outEnabled; ISOGetMovieTrack(cMovieBox, 101, &audioTrack); diff --git a/test/test_metadata.cpp b/test/test_metadata.cpp index 9fc9b8b..69950fa 100644 --- a/test/test_metadata.cpp +++ b/test/test_metadata.cpp @@ -28,7 +28,7 @@ TEST_CASE("metadata") { MP4Err err; - + char test_uri[] = "test_uri"; std::string strTestItem = "test_item.mp4"; std::string strTestEntityGroup = "test_meta_entity.mp4"; @@ -217,6 +217,7 @@ TEST_CASE("metadata") // add 2 items ISOMetaItem item1; ISOMetaItem item2; + ISOMetaItem item3; // URI item MP4Handle itemDataHandle1; MP4Handle itemDataHandle2; @@ -231,7 +232,7 @@ TEST_CASE("metadata") CHECK(err == MP4NoErr); // item 1 - ISOAddMetaItem(meta, &item1, 0, 0); + err = ISOAddMetaItem(meta, &item1, 0, 0); CHECK(err == MP4NoErr); err = ISOAddItemExtentUsingItemData(item1, itemDataHandle1); CHECK(err == MP4NoErr); @@ -247,18 +248,32 @@ TEST_CASE("metadata") err = ISOAddMetaItemProperty(item1, pTestProp, 1); CHECK(err == MP4NoErr); - ISOSetPrimaryItem(meta, item1); + err = ISOSetPrimaryItem(meta, item1); CHECK(err == MP4NoErr); + // it is not allowed to hide a primary item + err = ISOHideItem(item1); + CHECK(err == MP4InvalidMediaErr); + // item 2 ISOAddMetaItem(meta, &item2, 0, 0); - CHECK(err == MP4NoErr); err = ISOAddItemExtentUsingItemData(item2, itemDataHandle2); CHECK(err == MP4NoErr); err = ISOSetItemInfo(item2, 0, (char *)"second item", NULL, NULL); CHECK(err == MP4NoErr); err = ISOSetItemInfoItemType(item2, MP4_FOUR_CHAR_CODE('s', 'c', 'n', 'd'), NULL); CHECK(err == MP4NoErr); + err = ISOHideItem(item2); + CHECK(err == MP4NoErr); + + // item 3 + ISOAddMetaItem(meta, &item3, 0, 0); + err = ISOAddItemExtentUsingItemData(item3, itemDataHandle3); + CHECK(err == MP4NoErr); + err = ISOSetItemInfo(item3, 0, (char *)"third item (URI)", NULL, NULL); + CHECK(err == MP4NoErr); + err = ISOSetItemInfoItemType(item3, MP4_FOUR_CHAR_CODE('u', 'r', 'i', ' '), test_uri); + CHECK(err == MP4NoErr); err = ISOAddMetaItemProperty(item2, pTestProp, 0); CHECK(err == MP4NoErr); @@ -292,7 +307,12 @@ TEST_CASE("metadata") CHECK(cnt == 1); MP4GenericAtom *properties; ISOMetaItem item1 = items[0]; - err = ISOGetProperitesOfMetaItem(item1, &properties, &cnt); + + u32 item_type = 0; + err = ISOGetItemInfoItemType(item1, &item_type, NULL); + CHECK(err == MP4NoErr); + CHECK(item_type == MP4_FOUR_CHAR_CODE('f', 'r', 's', 't')); + err = ISOGetProperitesOfMetaItem(item1, &properties, &cnt); CHECK(err == MP4NoErr); CHECK(cnt == 1); MP4UnknownAtomPtr prop = (MP4UnknownAtomPtr)properties[0]; @@ -302,6 +322,8 @@ TEST_CASE("metadata") memcpy(*propHandle, prop->data, prop->dataSize); err = compareData(propHandle, TestData::DECAFCODEDOC, sizeof(TestData::DECAFCODEDOC)); CHECK(err == MP4NoErr); + err = ISOIsItemHidden(item1); + CHECK(err == MP4NotFoundErr); // check second item err = ISOGetAllItemsWithType(meta, MP4_FOUR_CHAR_CODE('s', 'c', 'n', 'd'), &items, &cnt); @@ -316,6 +338,24 @@ TEST_CASE("metadata") memcpy(*propHandle, prop->data, prop->dataSize); err = compareData(propHandle, TestData::DECAFCODEDOC, sizeof(TestData::DECAFCODEDOC)); CHECK(err == MP4NoErr); + err = ISOIsItemHidden(item2); + CHECK(err == MP4NoErr); + + // check tirhd item + err = ISOGetAllItemsWithType(meta, MP4_FOUR_CHAR_CODE('u', 'r', 'i', ' '), &items, &cnt); + CHECK(err == MP4NoErr); + CHECK(cnt == 1); + item_type = 0; + err = ISOGetItemInfoItemType(items[0], &item_type, NULL); + CHECK(err == MP4NoErr); + CHECK(item_type == MP4_FOUR_CHAR_CODE('u', 'r', 'i', ' ')); + char *item_uri_type; + item_uri_type = NULL; + err = ISOGetItemInfoItemType(items[0], &item_type, &item_uri_type); + CHECK(err == MP4NoErr); + std::string str_test_uri(test_uri); + std::string str_item_uri_type(item_uri_type); + CHECK(str_item_uri_type == str_test_uri); // check references u16 refCnt;