M4Err Media_AddSample(MediaAtom *mdia, u64 data_offset, M4Sample *sample, u32 StreamDescIndex, u32 syncShadowNumber) { M4Err e; SampleTableAtom *stbl; u32 sampleNumber, i; if (!mdia || !sample) return M4BadParam; stbl = mdia->information->sampleTable; //get a valid sampleNumber for this new guy e = stbl_AddDTS(stbl, sample->DTS, &sampleNumber, mdia->mediaHeader->timeScale); if (e) return e; //add size e = stbl_AddSize(stbl->SampleSize, sampleNumber, sample->dataLength); if (e) return e; //adds CTS offset if (sample->CTS_Offset) { //if we don't have a CTS table, add it... if (!stbl->CompositionOffset) stbl->CompositionOffset = (CompositionOffsetAtom *) CreateAtom(CompositionOffsetAtomType); //then add our CTS (the prev samples with no CTS offset will be automatically added... e = stbl_AddCTS(stbl, sampleNumber, sample->CTS_Offset); if (e) return e; } else if (stbl->CompositionOffset) { e = stbl_AddCTS(stbl, sampleNumber, sample->CTS_Offset); if (e) return e; } //The first non sync sample we see must create a syncTable if (sample->IsRAP) { //insert it only if we have a sync table if (stbl->SyncSample) { e = stbl_AddRAP(stbl->SyncSample, sampleNumber); if (e) return e; } } else { //non-sync sample. Create a SyncSample table if needed if (!stbl->SyncSample) { stbl->SyncSample = (SyncSampleAtom *) CreateAtom(SyncSampleAtomType); //all the prev samples are sync for (i=0; i<stbl->SampleSize->sampleCount; i++) { if (i+1 != sampleNumber) { e = stbl_AddRAP(stbl->SyncSample, i+1); if (e) return e; } } } } //and update the chunks e = stbl_AddChunkOffset(mdia, sampleNumber, StreamDescIndex, data_offset); if (e) return e; if (!syncShadowNumber) return M4OK; if (!stbl->ShadowSync) stbl->ShadowSync = (ShadowSyncAtom *) CreateAtom(ShadowSyncAtomType); return stbl_AddShadow(mdia->information->sampleTable->ShadowSync, sampleNumber, syncShadowNumber); }
M4Err UpdateSample(MediaAtom *mdia, u32 sampleNumber, u32 size, u32 CTS, u64 offset, u8 isRap) { u32 i; SampleTableAtom *stbl = mdia->information->sampleTable; //set size, offset, RAP, CTS ... stbl_SetSampleSize(stbl->SampleSize, sampleNumber, size); stbl_SetChunkOffset(mdia, sampleNumber, offset); //do we have a CTS? if (stbl->CompositionOffset) { stbl_SetSampleCTS(stbl, sampleNumber, CTS); } else { //do we need one ?? if (CTS) { stbl->CompositionOffset = (CompositionOffsetAtom *) CreateAtom(CompositionOffsetAtomType); stbl_AddCTS(stbl, sampleNumber, CTS); } } //do we have a sync ??? if (stbl->SyncSample) { stbl_SetSampleRAP(stbl->SyncSample, sampleNumber, isRap); } else { //do we need one if (! isRap) { stbl->SyncSample = (SyncSampleAtom *) CreateAtom(SyncSampleAtomType); //what a pain: all the sample we had have to be sync ... for (i=0; i<stbl->SampleSize->sampleCount; i++) { if (i+1 != sampleNumber) stbl_AddRAP(stbl->SyncSample, i+1); } } } return M4OK; }
GF_Err UpdateSample(GF_MediaBox *mdia, u32 sampleNumber, u32 size, u32 CTS, u64 offset, u8 isRap) { u32 i; GF_SampleTableBox *stbl = mdia->information->sampleTable; //set size, offset, RAP, CTS ... stbl_SetSampleSize(stbl->SampleSize, sampleNumber, size); stbl_SetChunkOffset(mdia, sampleNumber, offset); //do we have a CTS? if (stbl->CompositionOffset) { stbl_SetSampleCTS(stbl, sampleNumber, CTS); } else { //do we need one ?? if (CTS) { stbl->CompositionOffset = (GF_CompositionOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CTTS); stbl_AddCTS(stbl, sampleNumber, CTS); } } //do we have a sync ??? if (stbl->SyncSample) { stbl_SetSampleRAP(stbl->SyncSample, sampleNumber, isRap); } else { //do we need one if (! isRap) { stbl->SyncSample = (GF_SyncSampleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSS); //what a pain: all the sample we had have to be sync ... for (i=0; i<stbl->SampleSize->sampleCount; i++) { if (i+1 != sampleNumber) stbl_AddRAP(stbl->SyncSample, i+1); } } } if (isRap==2) { stbl_SetRedundant(stbl, sampleNumber); } return GF_OK; }
GF_Err Media_AddSample(GF_MediaBox *mdia, u64 data_offset, GF_ISOSample *sample, u32 StreamDescIndex, u32 syncShadowNumber) { GF_Err e; GF_SampleTableBox *stbl; u32 sampleNumber, i; if (!mdia || !sample) return GF_BAD_PARAM; stbl = mdia->information->sampleTable; //get a valid sampleNumber for this new guy e = stbl_AddDTS(stbl, sample->DTS, &sampleNumber, mdia->mediaHeader->timeScale); if (e) return e; //add size e = stbl_AddSize(stbl->SampleSize, sampleNumber, sample->dataLength); if (e) return e; //adds CTS offset if (sample->CTS_Offset) { //if we don't have a CTS table, add it... if (!stbl->CompositionOffset) stbl->CompositionOffset = (GF_CompositionOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CTTS); //then add our CTS (the prev samples with no CTS offset will be automatically added... e = stbl_AddCTS(stbl, sampleNumber, sample->CTS_Offset); if (e) return e; } else if (stbl->CompositionOffset) { e = stbl_AddCTS(stbl, sampleNumber, sample->CTS_Offset); if (e) return e; } //The first non sync sample we see must create a syncTable if (sample->IsRAP) { //insert it only if we have a sync table if (stbl->SyncSample) { e = stbl_AddRAP(stbl->SyncSample, sampleNumber); if (e) return e; } } else { //non-sync sample. Create a SyncSample table if needed if (!stbl->SyncSample) { stbl->SyncSample = (GF_SyncSampleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSS); //all the prev samples are sync for (i=0; i<stbl->SampleSize->sampleCount; i++) { if (i+1 != sampleNumber) { e = stbl_AddRAP(stbl->SyncSample, i+1); if (e) return e; } } } } if (sample->IsRAP==2) { e = stbl_AddRedundant(stbl, sampleNumber); if (e) return e; } //and update the chunks e = stbl_AddChunkOffset(mdia, sampleNumber, StreamDescIndex, data_offset); if (e) return e; if (!syncShadowNumber) return GF_OK; if (!stbl->ShadowSync) stbl->ShadowSync = (GF_ShadowSyncBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSH); return stbl_AddShadow(mdia->information->sampleTable->ShadowSync, sampleNumber, syncShadowNumber); }