⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stbl_write.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (sdtp->sampleCount + 1 < sampleNumber) {		u32 missed = sampleNumber-1 - sdtp->sampleCount;		sdtp->sample_info = (u8*) realloc(sdtp->sample_info, sizeof(u8) * (sdtp->sampleCount+missed) );		while (missed) {			u8 isRAP;			if (stbl->SyncSample) stbl_GetSampleRAP(stbl->SyncSample, sdtp->sampleCount+1, &isRAP, NULL, NULL);			else isRAP = 1;			sdtp->sample_info[sdtp->sampleCount] = isRAP ? 0x20 : 0;			sdtp->sampleCount++;			missed--;		}	}	sdtp->sample_info = (u8*) realloc(sdtp->sample_info, sizeof(u8) * (sdtp->sampleCount + 1));	if (!sdtp->sample_info) return GF_OUT_OF_MEM;	if (sdtp->sampleCount < sampleNumber) {		sdtp->sample_info[sdtp->sampleCount] = 0x29;	} else {		u32 snum = sampleNumber-1;		memmove(sdtp->sample_info+snum+1, sdtp->sample_info+snum, sizeof(u8) * (sdtp->sampleCount - snum) );		sdtp->sample_info[snum] = 0x29;	}	//update our list	sdtp->sampleCount ++;	return GF_OK;}//this function is always called in INCREASING order of shadow sample numbersGF_Err stbl_AddShadow(GF_ShadowSyncBox *stsh, u32 sampleNumber, u32 shadowNumber){	GF_StshEntry *ent;	u32 i, count;	count = gf_list_count(stsh->entries);	for (i=0; i<count; i++) {		ent = (GF_StshEntry*)gf_list_get(stsh->entries, i);		if (ent->shadowedSampleNumber == shadowNumber) {			ent->syncSampleNumber = sampleNumber;			return GF_OK;		} else if (ent->shadowedSampleNumber > shadowNumber) break;	}	ent = (GF_StshEntry*)malloc(sizeof(GF_StshEntry));	if (!ent) return GF_OUT_OF_MEM;	ent->shadowedSampleNumber = shadowNumber;	ent->syncSampleNumber = sampleNumber;	if (i == gf_list_count(stsh->entries)) {		return gf_list_add(stsh->entries, ent);	} else {		return gf_list_insert(stsh->entries, ent, i ? i-1 : 0);	}}//used in edit/write, where sampleNumber == chunkNumberGF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIndex, u64 offset){	GF_SampleTableBox *stbl;	GF_ChunkOffsetBox *stco;	GF_ChunkLargeOffsetBox *co64;	GF_StscEntry *ent, *tmp;	u32 count, i, k, *newOff;	u64 *newLarge;	stbl = mdia->information->sampleTable;	count = gf_list_count(mdia->information->sampleTable->SampleToChunk->entryList);	if (count + 1 < sampleNumber ) return GF_BAD_PARAM;	ent = (GF_StscEntry*)malloc(sizeof(GF_StscEntry));	ent->isEdited = 0;	if (Media_IsSelfContained(mdia, StreamDescIndex)) ent->isEdited = 1;	ent->sampleDescriptionIndex = StreamDescIndex;	ent->samplesPerChunk = 1;	//we know 1 chunk == 1 sample, so easy...	ent->firstChunk = sampleNumber;	ent->nextChunk = sampleNumber + 1;	//add the offset to the chunk...	//and we change our offset	if (stbl->ChunkOffset->type == GF_ISOM_BOX_TYPE_STCO) {		stco = (GF_ChunkOffsetBox *)stbl->ChunkOffset;		//if the new offset is a large one, we have to rewrite our table entry by entry (32->64 bit conv)...		if (offset > 0xFFFFFFFF) {			co64 = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64);			co64->entryCount = stco->entryCount + 1;			co64->offsets = (u64*)malloc(sizeof(u64) * co64->entryCount);			k = 0;			for (i=0;i<stco->entryCount; i++) {				if (i + 1 == sampleNumber) {					co64->offsets[i] = offset;					k = 1;				}				co64->offsets[i+k] = (u64) stco->offsets[i];			}			if (!k) co64->offsets[co64->entryCount - 1] = offset;			gf_isom_box_del(stbl->ChunkOffset);			stbl->ChunkOffset = (GF_Box *) co64;		} else {			//no, we can use this one.			if (sampleNumber > stco->entryCount) {				if (!stco->alloc_size) stco->alloc_size = stco->entryCount;				if (stco->entryCount == stco->alloc_size) {					stco->alloc_size += 50;					newOff = (u32*)malloc(sizeof(u32) * stco->alloc_size);					memcpy(newOff, stco->offsets, sizeof(u32) * stco->entryCount);					free(stco->offsets);					stco->offsets = newOff;				}				stco->offsets[stco->entryCount] = (u32) offset;				stco->entryCount += 1;			} else {				//nope. we're inserting				newOff = (u32*)malloc(sizeof(u32) * (stco->entryCount + 1));				k=0;				for (i=0; i<stco->entryCount; i++) {					if (i+1 == sampleNumber) {						newOff[i] = (u32) offset;						k=1;					}					newOff[i+k] = stco->offsets[i];				}				free(stco->offsets);				stco->offsets = newOff;				stco->entryCount ++;				stco->alloc_size = stco->entryCount;			}		}	} else {		//use large offset...		co64 = (GF_ChunkLargeOffsetBox *)stbl->ChunkOffset;		if (sampleNumber > co64->entryCount) {			if (!co64->alloc_size) co64->alloc_size = co64->entryCount;			if (co64->entryCount == co64->alloc_size) {				co64->alloc_size += 50;				newLarge = (u64*)malloc(sizeof(u64) * co64->alloc_size);				memcpy(newLarge, co64->offsets, sizeof(u64) * co64->entryCount);				free(co64->offsets);				co64->offsets = newLarge;			}			co64->offsets[co64->entryCount] = offset;			co64->entryCount += 1;		} else {			//nope. we're inserting			newLarge = (u64*)malloc(sizeof(u64) * (co64->entryCount + 1));			k=0;			for (i=0; i<co64->entryCount; i++) {				if (i+1 == sampleNumber) {					newLarge[i] = offset;					k=1;				}				newLarge[i+k] = co64->offsets[i];			}			free(co64->offsets);			co64->offsets = newLarge;			co64->entryCount++;			co64->alloc_size++;		}	}	//OK, now if we've inserted a chunk, update the sample to chunk info...	if (sampleNumber == count + 1) {		ent->nextChunk = count + 1;		if (stbl->SampleToChunk->currentEntry)			stbl->SampleToChunk->currentEntry->nextChunk = ent->firstChunk;		stbl->SampleToChunk->currentEntry = ent;		stbl->SampleToChunk->currentIndex = count;		stbl->SampleToChunk->firstSampleInCurrentChunk = sampleNumber;		//write - edit mode: sample number = chunk number		stbl->SampleToChunk->currentChunk = sampleNumber;		stbl->SampleToChunk->ghostNumber = 1;		return gf_list_add(stbl->SampleToChunk->entryList, ent);	}	for (i = sampleNumber - 1; i<count; i++) {		tmp = (GF_StscEntry*)gf_list_get(stbl->SampleToChunk->entryList, i);		if (tmp) tmp->firstChunk +=1;	}	return gf_list_insert(stbl->SampleToChunk->entryList, ent, sampleNumber-1);}GF_Err stbl_SetChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u64 offset){	GF_StscEntry *ent;	u32 i;	GF_ChunkLargeOffsetBox *co64;	GF_SampleTableBox *stbl = mdia->information->sampleTable;	if (!sampleNumber || !stbl) return GF_BAD_PARAM;	ent = (GF_StscEntry*)gf_list_get(stbl->SampleToChunk->entryList, sampleNumber - 1);	//we edit our entry if self contained	if (Media_IsSelfContained(mdia, ent->sampleDescriptionIndex))		ent->isEdited = 1;	//and we change our offset	if (stbl->ChunkOffset->type == GF_ISOM_BOX_TYPE_STCO) {		//if the new offset is a large one, we have to rewrite our table...		if (offset > 0xFFFFFFFF) {			co64 = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64);			co64->entryCount = ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->entryCount;			co64->offsets = (u64*)malloc(sizeof(u64)*co64->entryCount);			for (i=0;i<co64->entryCount; i++) {				co64->offsets[i] = (u64) ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets[i];			}			co64->offsets[ent->firstChunk - 1] = offset;			gf_isom_box_del(stbl->ChunkOffset);			stbl->ChunkOffset = (GF_Box *) co64;			return GF_OK;		}		((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets[ent->firstChunk - 1] = (u32) offset;	} else {		((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->offsets[ent->firstChunk - 1] = offset;	}	return GF_OK;}GF_Err stbl_SetSampleCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 offset){	u32 i, j, sampNum, *CTSs;	GF_DttsEntry *ent;	GF_CompositionOffsetBox *ctts = stbl->CompositionOffset;		//if we're setting the CTS of a sample we've skipped...	if (ctts->w_LastSampleNumber < sampleNumber) {		//add some 0 till we get to the sample		while (ctts->w_LastSampleNumber + 1 != sampleNumber) {			AddCompositionOffset(ctts, 0);		}		return AddCompositionOffset(ctts, offset);	}	if (ctts->unpack_mode) {		GF_DttsEntry *dtts = (GF_DttsEntry *)gf_list_get(ctts->entryList, sampleNumber-1);		if (!dtts) return GF_BAD_PARAM;		dtts->decodingOffset = offset;		return GF_OK;	}	//NOPE we are inserting a sample...	CTSs = (u32*)malloc(sizeof(u32) * ctts->w_LastSampleNumber);	sampNum = 0;	i=0;	while ((ent = (GF_DttsEntry *)gf_list_enum(ctts->entryList, &i))) {		for (j = 0; j<ent->sampleCount; j++) {			if (sampNum + 1 == sampleNumber) {				CTSs[sampNum] = offset;			} else {				CTSs[sampNum] = ent->decodingOffset;			}			sampNum ++;		}	}	//delete the entries	while (gf_list_count(ctts->entryList)) {		ent = (GF_DttsEntry*)gf_list_get(ctts->entryList, 0);		free(ent);		gf_list_rem(ctts->entryList, 0);	}	//rewrite the table	ent = (GF_DttsEntry*)malloc(sizeof(GF_DttsEntry));	ent->sampleCount = 1;	ent->decodingOffset = CTSs[0];	i = 1;	//reset the read cache (entry insertion)	ctts->r_currentEntryIndex = 1;	ctts->r_FirstSampleInEntry = 1;	while (1) {		if (i == ctts->w_LastSampleNumber) {			gf_list_add(ctts->entryList, ent);			break;		}		if (CTSs[i] == ent->decodingOffset) {			ent->sampleCount += 1;		} else {			gf_list_add(ctts->entryList, ent);			ent = (GF_DttsEntry*)malloc(sizeof(GF_DttsEntry));			ent->sampleCount = 1;			ent->decodingOffset = CTSs[i];			ctts->r_FirstSampleInEntry = i;		}		if (i==sampleNumber) ctts->r_currentEntryIndex = gf_list_count(ctts->entryList) + 1;		i++;	}	free(CTSs);	return GF_OK;}GF_Err stbl_SetSampleSize(GF_SampleSizeBox *stsz, u32 SampleNumber, u32 size){	u32 i;	if (!SampleNumber || (stsz->sampleCount < SampleNumber)) return GF_BAD_PARAM;	if (stsz->sampleSize) {		if (stsz->sampleSize == size) return GF_OK;		if (stsz->sampleCount == 1) {			stsz->sampleSize = size;			return GF_OK;		}		//nope, we have to rewrite a table		stsz->sizes = (u32*)malloc(sizeof(u32)*stsz->sampleCount);		for (i=0; i<stsz->sampleCount; i++) stsz->sizes[i] = stsz->sampleSize;		stsz->sampleSize = 0;	}	stsz->sizes[SampleNumber - 1] = size;	return GF_OK;}GF_Err stbl_SetSampleRAP(GF_SyncSampleBox *stss, u32 SampleNumber, u8 isRAP){	u32 i, j, k, *newNum, nextSamp;	nextSamp = 0;	//check if we have already a sync sample	for (i = 0; i < stss->entryCount; i++) {		if (stss->sampleNumbers[i] == SampleNumber) {			if (isRAP) return GF_OK;			//remove it...			newNum = (u32*)malloc(sizeof(u32) * (stss->entryCount-1));			k = 0;			for (j=0; j<stss->entryCount; j++) {				if (stss->sampleNumbers[j] == SampleNumber) {					k=1;				} else {					newNum[j-k] = stss->sampleNumbers[j];				}			}			stss->entryCount -=1;			free(stss->sampleNumbers);			stss->sampleNumbers = newNum;			return GF_OK;		}		if (stss->sampleNumbers[i] > SampleNumber) break;	}	//we need to insert a RAP somewhere if RAP ...	if (!isRAP) return GF_OK;	newNum = (u32*)malloc(sizeof(u32) * (stss->entryCount + 1));	k = 0;	for (j = 0 ; j<stss->entryCount; j++) {		if (j == i) {			newNum[j] = SampleNumber;			k = 1;		}		newNum[j+k] = stss->sampleNumbers[j];	}	if (!k) {		newNum[stss->entryCount] = SampleNumber;	}	free(stss->sampleNumbers);	stss->sampleNumbers = newNum;	stss->entryCount ++;	return GF_OK;}GF_Err stbl_SetRedundant(GF_SampleTableBox *stbl, u32 sampleNumber){	if (stbl->SampleDep->sampleCount < sampleNumber) {		return stbl_AddRedundant(stbl, sampleNumber);	} else {		stbl->SampleDep->sample_info[sampleNumber-1] = 0x29;		return GF_OK;	}}GF_Err stbl_SetSyncShadow(GF_ShadowSyncBox *stsh, u32 sampleNumber, u32 syncSample){	u32 i, count;	GF_StshEntry *ent;	count = gf_list_count(stsh->entries);	for (i=0; i<count; i++) {		ent = (GF_StshEntry*)gf_list_get(stsh->entries, i);		if (ent->shadowedSampleNumber == sampleNumber) {			ent->syncSampleNumber = syncSample;			return GF_OK;		}		if (ent->shadowedSampleNumber > sampleNumber) break;	}	//we need a new one...	ent = (GF_StshEntry*)malloc(sizeof(GF_StshEntry));	ent->shadowedSampleNumber = sampleNumber;	ent->syncSampleNumber = syncSample;	//insert or append ?	if (i == gf_list_count(stsh->entries)) {		//don't update the cache ...		return gf_list_add(stsh->entries, ent);	} else {		//update the cache		stsh->r_LastEntryIndex = i;		stsh->r_LastFoundSample = sampleNumber;		return gf_list_insert(stsh->entries, ent, i);	}}//always called before removing the sample from SampleSizeGF_Err stbl_RemoveDTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 LastAUDefDuration){	u64 *DTSs, curDTS;	u32 i, j, k, sampNum;	GF_SttsEntry *ent;	GF_TimeToSampleBox *stts;	stts = stbl->TimeToSample;	//gasp, we're removing the only sample: empty the sample table 	if (stbl->SampleSize->sampleCount == 1) {		if (gf_list_count(stts->entryList)) {			gf_list_rem(stts->entryList, 0);		}		//update the reading cache		stts->r_FirstSampleInEntry = stts->r_currentEntryIndex = 0;		stts->r_CurrentDTS = 0;		return GF_OK;	}	//unpack the DTSs...	DTSs = (u64*)malloc(sizeof(u64) * (stbl->SampleSize->sampleCount - 1));	curDTS = 0;	sampNum = 0;	ent = NULL;	k=0;	i=0;	while ((ent = (GF_SttsEntry *)gf_list_enum(stts->entryList, &i))) {		for (j = 0; j<ent->sampleCount; j++) {			if (sampNum == sampleNumber - 1) {				k=1;			} else {				DTSs[sampNum-k] = curDTS;			}			curDTS += ent->sampleDelta;			sampNum ++;		}	}	//delete the table..	while (gf_list_count(stts->entryList)) {		ent = (GF_SttsEntry*)gf_list_get(stts->entryList, 0);		free(ent);		gf_list_rem(stts->entryList, 0);	}	//rewrite the table	ent = (GF_SttsEntry*)malloc(sizeof(GF_SttsEntry));	ent->sampleCount = 0;	gf_list_add(stts->entryList, ent);	if (stbl->SampleSize->sampleCount == 2) {		ent->sampleDelta = LastAUDefDuration;	} else {		ent->sampleDelta = (u32) DTSs[1];		DTSs[0] = 0;	}	i = 0;	while (1) {		if (i+2 == stbl->SampleSize->sampleCount) {			//and by default, our last sample has the same delta as the prev

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -