@@ -1923,6 +1923,147 @@ MP4GetIndMediaSampleWithPad(MP4Media theMedia, u32 sampleNumber, MP4Handle outSa
19231923 return err ;
19241924}
19251925
1926+ MP4_EXTERN (MP4Err )
1927+ MP4UpdateMediaSample (MP4Movie theMovie , MP4Media theMedia , u32 sampleNumber , MP4Handle sampleH ,
1928+ u32 sampleSize )
1929+ {
1930+ MP4Err err ;
1931+ MP4MediaInformationAtomPtr minf ;
1932+ MP4SampleTableAtomPtr stbl ;
1933+ MP4SampleSizeAtomPtr stsz ;
1934+ MP4SampleToChunkAtomPtr stsc ;
1935+ MP4ChunkOffsetAtomPtr stco ;
1936+
1937+ MP4PrivateMovieRecordPtr movie = (MP4PrivateMovieRecordPtr )theMovie ;
1938+ MP4MediaDataAtomPtr mdat ;
1939+
1940+ u32 chunkNumber ;
1941+ u32 sampleDescriptionIndex ;
1942+ u32 firstSampleNumberInChunk ;
1943+ u32 sampleOffsetWithinChunk ;
1944+ u32 oldSize ;
1945+ u64 chunkOffset ;
1946+ u64 computedOffset ;
1947+ s32 deltaSize ;
1948+
1949+ err = MP4NoErr ;
1950+ if ((theMovie == NULL ) || (theMedia == NULL ) || (sampleH == NULL ))
1951+ {
1952+ BAILWITHERROR (MP4BadParamErr );
1953+ }
1954+
1955+ mdat = (MP4MediaDataAtomPtr )movie -> mdat ;
1956+ if ((mdat == NULL ) || (mdat -> data == NULL ))
1957+ {
1958+ BAILWITHERROR (MP4NotImplementedErr );
1959+ }
1960+
1961+ minf = (MP4MediaInformationAtomPtr )((MP4MediaAtomPtr )theMedia )-> information ;
1962+ if (minf == NULL ) BAILWITHERROR (MP4InvalidMediaErr );
1963+
1964+ stbl = (MP4SampleTableAtomPtr )minf -> sampleTable ;
1965+ if (stbl == NULL ) BAILWITHERROR (MP4InvalidMediaErr );
1966+
1967+ stsz = (MP4SampleSizeAtomPtr )stbl -> SampleSize ;
1968+ stsc = (MP4SampleToChunkAtomPtr )stbl -> SampleToChunk ;
1969+ stco = (MP4ChunkOffsetAtomPtr )stbl -> ChunkOffset ;
1970+
1971+ if ((stsz == NULL ) || (stsc == NULL ) || (stco == NULL )) BAILWITHERROR (MP4InvalidMediaErr );
1972+
1973+ /* get chunk and offset within chunk */
1974+ err = stsc -> lookupSample (stbl -> SampleToChunk , sampleNumber , & chunkNumber , & sampleDescriptionIndex ,
1975+ & firstSampleNumberInChunk );
1976+ if (err ) goto bail ;
1977+
1978+ err = stsz -> getSampleSizeAndOffset (stbl -> SampleSize , sampleNumber , & oldSize ,
1979+ firstSampleNumberInChunk , & sampleOffsetWithinChunk );
1980+ if (err ) goto bail ;
1981+
1982+ err = stco -> getChunkOffset (stbl -> ChunkOffset , chunkNumber , & chunkOffset );
1983+ if (err ) goto bail ;
1984+
1985+ computedOffset = chunkOffset + sampleOffsetWithinChunk ;
1986+ deltaSize = sampleSize - oldSize ;
1987+
1988+ if (deltaSize != 0 )
1989+ {
1990+ /* Shift data in mdat */
1991+ u64 mdatOffset = computedOffset ;
1992+ char * newData ;
1993+
1994+ newData = (char * )realloc (mdat -> data , mdat -> dataSize + deltaSize );
1995+ if (newData == NULL ) BAILWITHERROR (MP4NoMemoryErr );
1996+ mdat -> data = newData ;
1997+
1998+ memmove (mdat -> data + mdatOffset + sampleSize , mdat -> data + mdatOffset + oldSize ,
1999+ mdat -> dataSize - (mdatOffset + oldSize ));
2000+
2001+ mdat -> dataSize += deltaSize ;
2002+
2003+ /* Update sample size in stsz */
2004+ if (stsz -> sampleSize != 0 )
2005+ {
2006+ u32 i ;
2007+ stsz -> sizes = (u32 * )calloc (stsz -> sampleCount , sizeof (u32 ));
2008+ if (stsz -> sizes == NULL ) BAILWITHERROR (MP4NoMemoryErr );
2009+ for (i = 0 ; i < stsz -> sampleCount ; i ++ )
2010+ stsz -> sizes [i ] = stsz -> sampleSize ;
2011+ stsz -> sampleSize = 0 ;
2012+ }
2013+ stsz -> sizes [sampleNumber - 1 ] = sampleSize ;
2014+
2015+ /* Update chunk offsets directly for all tracks */
2016+ {
2017+ MP4MovieAtomPtr moov = (MP4MovieAtomPtr )movie -> moovAtomPtr ;
2018+ u32 trackCount ;
2019+ u32 i ;
2020+ err = MP4GetListEntryCount (moov -> trackList , & trackCount );
2021+ if (err ) goto bail ;
2022+
2023+ for (i = 0 ; i < trackCount ; i ++ )
2024+ {
2025+ MP4TrackAtomPtr trak ;
2026+ err = MP4GetListEntry (moov -> trackList , i , (char * * )& trak );
2027+ if (err ) goto bail ;
2028+ if (trak && trak -> trackMedia )
2029+ {
2030+ MP4MediaAtomPtr media = (MP4MediaAtomPtr )trak -> trackMedia ;
2031+ if (media -> information )
2032+ {
2033+ MP4MediaInformationAtomPtr minf_ptr = (MP4MediaInformationAtomPtr )media -> information ;
2034+ if (minf_ptr -> sampleTable )
2035+ {
2036+ MP4SampleTableAtomPtr stbl_ptr = (MP4SampleTableAtomPtr )minf_ptr -> sampleTable ;
2037+ MP4ChunkOffsetAtomPtr stco_ptr = (MP4ChunkOffsetAtomPtr )stbl_ptr -> ChunkOffset ;
2038+
2039+ if (stco_ptr )
2040+ {
2041+ u32 j ;
2042+ for (j = 0 ; j < stco_ptr -> entryCount ; j ++ )
2043+ {
2044+ if (stco_ptr -> offsets [j ] >= computedOffset + oldSize )
2045+ {
2046+ stco_ptr -> offsets [j ] += deltaSize ;
2047+ }
2048+ }
2049+ }
2050+ }
2051+ }
2052+ }
2053+ }
2054+ }
2055+ if (err ) goto bail ;
2056+ }
2057+
2058+ /* Copy new data */
2059+ u64 mdatOffset = computedOffset ;
2060+ memcpy (mdat -> data + mdatOffset , * sampleH , sampleSize );
2061+
2062+ bail :
2063+ TEST_RETURN (err );
2064+ return err ;
2065+ }
2066+
19262067MP4_EXTERN (MP4Err )
19272068MP4GetIndMediaSampleReference (MP4Media theMedia , u32 sampleNumber , u32 * outOffset , u32 * outSize ,
19282069 u32 * outDuration , u32 * outSampleFlags , u32 * outSampleDescIndex ,
0 commit comments