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

📄 isom_store.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
				/*OK write to mdat*/				if (!Emulation) {					char cache_data[4096];					u64 remain = entry->extent_length;					while (remain) {						u32 size_cache = (remain>4096) ? 4096 : (u32) remain;						fread(cache_data, 1, size_cache, src);						gf_bs_write_data(bs, cache_data, size_cache);						remain -= size_cache;					}				}				fclose(src);			} 			else if (gf_list_count(iloc->extent_entries)) {				u32 j;				j=0;				while ((entry = (GF_ItemExtentEntry *)gf_list_enum(iloc->extent_entries, &j))) {					if (j && (maxExtendOffset<it_size) ) maxExtendOffset = it_size;					/*compute new offset*/					entry->extent_offset = baseOffset + it_size;					it_size += entry->extent_length;					if (maxExtendSize<entry->extent_length) maxExtendSize = entry->extent_length;					/*Reading from the input file*/					if (!Emulation) {						char cache_data[4096];						u64 remain = entry->extent_length;						gf_bs_seek(file->movieFileMap->bs, entry->original_extent_offset + iloc->original_base_offset);						while (remain) {							u32 size_cache = (remain>4096) ? 4096 : (u32) remain;							gf_bs_read_data(file->movieFileMap->bs, cache_data, size_cache);							/*Writing to the output file*/							gf_bs_write_data(bs, cache_data, size_cache);							remain -= size_cache;						}					}				}			}			baseOffset += it_size;			*mdatSize += it_size;		} else {			/*we MUST have at least one extent for the dref data*/			if (!gf_list_count(iloc->extent_entries)) {				GF_SAFEALLOC(entry, GF_ItemExtentEntry);				gf_list_add(iloc->extent_entries, entry);			}			entry = (GF_ItemExtentEntry *)gf_list_get(iloc->extent_entries, 0);			entry->extent_offset = 0;			/*0 means full length of referenced file*/			entry->extent_length = 0;		}	}	/*update offset & size length fields*/	if (baseOffset>0xFFFFFFFF) meta->item_locations->base_offset_size = 8;	else if (baseOffset) meta->item_locations->base_offset_size = 4;		if (maxExtendSize>0xFFFFFFFF) meta->item_locations->length_size = 8;	else if (maxExtendSize) meta->item_locations->length_size = 4;	if (maxExtendOffset>0xFFFFFFFF) meta->item_locations->offset_size = 8;	else if (maxExtendOffset) meta->item_locations->offset_size = 4;	return GF_OK;}//this function writes track by track in the order of tracks inside the moov...GF_Err DoWrite(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u64 StartOffset){	u32 i;	GF_Err e;	TrackWriter *writer;	u64 offset, sampOffset, predOffset;	u32 chunkNumber, descIndex, sampSize;	u8 isEdited, force;	u64 size, mdatSize = 0;	GF_ISOFile *movie = mw->movie;	/*write meta content first - WE DON'T support fragmentation of resources in ISOM atm*/	if (movie->openMode != GF_ISOM_OPEN_WRITE) {		if (movie->meta) {			e = DoWriteMeta(movie, movie->meta, bs, Emulation, StartOffset, &size);			if (e) return e;			mdatSize += size;			StartOffset += size;		}		if (movie->moov && movie->moov->meta) {			e = DoWriteMeta(movie, movie->meta, bs, Emulation, StartOffset, &size);			if (e) return e;			mdatSize += size;			StartOffset += size;		}		i=0;		while ((writer = (TrackWriter*)gf_list_enum(writers, &i))) {			if (writer->mdia->mediaTrack->meta) {				e = DoWriteMeta(movie, movie->meta, bs, Emulation, StartOffset, &size);				if (e) return e;				mdatSize += size;				StartOffset += size;			}		}	}	offset = StartOffset;	predOffset = 0;	i=0;	while ((writer = (TrackWriter*)gf_list_enum(writers, &i))) {		while (!writer->isDone) {			//To Check: are empty sample tables allowed ???			if (writer->sampleNumber > writer->mdia->information->sampleTable->SampleSize->sampleCount) {				writer->isDone = 1;				continue;			}			e = stbl_GetSampleInfos(writer->mdia->information->sampleTable, writer->sampleNumber, &sampOffset, &chunkNumber, &descIndex, &isEdited);			if (e) return e;			e = stbl_GetSampleSize(writer->mdia->information->sampleTable->SampleSize, writer->sampleNumber, &sampSize);			if (e) return e;			//update our chunks. 			force = 0;			if (movie->openMode == GF_ISOM_OPEN_WRITE) {				offset = sampOffset;				if (predOffset != offset) 					force = 1;			}			//update our global offset...			if (Media_IsSelfContained(writer->mdia, descIndex) ) {				e = stbl_SetChunkAndOffset(writer->mdia->information->sampleTable, writer->sampleNumber, descIndex, writer->stsc, &writer->stco, offset, force);				if (e) return e;				if (movie->openMode == GF_ISOM_OPEN_WRITE) {					predOffset = sampOffset + sampSize;				} else {					offset += sampSize;					mdatSize += sampSize;				}			} else {				if (predOffset != offset) force = 1;				predOffset = sampOffset + sampSize;				//we have a DataRef, so use the offset idicated in sampleToChunk and ChunkOffset tables...				e = stbl_SetChunkAndOffset(writer->mdia->information->sampleTable, writer->sampleNumber, descIndex, writer->stsc, &writer->stco, sampOffset, force);				if (e) return e;			}			//we write the sample if not emulation			if (!Emulation) {				if (Media_IsSelfContained(writer->mdia, descIndex) ) {					e = WriteSample(mw, sampSize, sampOffset, isEdited, bs);					if (e) return e;				}			}			//ok, the track is done			if (writer->sampleNumber == writer->mdia->information->sampleTable->SampleSize->sampleCount) {				writer->isDone = 1;			} else {				writer->sampleNumber ++;			}		}	}	//set the mdatSize...	movie->mdat->dataSize = mdatSize;	return GF_OK;}//write the file track by track, with moov box before or after the mdatGF_Err WriteFlat(MovieWriter *mw, u8 moovFirst, GF_BitStream *bs){	GF_Err e;	u32 i;	u64 offset, finalOffset, totSize, begin, firstSize, finalSize;	GF_Box *a;	GF_List *writers = gf_list_new();	GF_ISOFile *movie = mw->movie;	begin = totSize = 0;	//first setup the writers	e = SetupWriters(mw, writers, 0);	if (e) goto exit;	if (!moovFirst) {		if (movie->openMode == GF_ISOM_OPEN_WRITE) {			begin = 0;			totSize = gf_isom_datamap_get_offset(movie->editFileMap);			/*start boxes have not been written yet, do it*/			if (!totSize) {				if (movie->is_jp2) {					gf_bs_write_u32(movie->editFileMap->bs, 12);					gf_bs_write_u32(movie->editFileMap->bs, GF_4CC('j','P',' ',' '));					gf_bs_write_u32(movie->editFileMap->bs, 0x0D0A870A);					totSize += 12;					begin += 12;				}				if (movie->brand) {					e = gf_isom_box_size((GF_Box *)movie->brand); if (e) goto exit;					e = gf_isom_box_write((GF_Box *)movie->brand, movie->editFileMap->bs); if (e) goto exit;					totSize += movie->brand->size;					begin += movie->brand->size;				}				if (movie->pdin) {					e = gf_isom_box_size((GF_Box *)movie->pdin); if (e) goto exit;					e = gf_isom_box_write((GF_Box *)movie->pdin, movie->editFileMap->bs); if (e) goto exit;					totSize += movie->pdin->size;					begin += movie->pdin->size;				}			} else {				if (movie->is_jp2) begin += 12;				if (movie->brand) begin += movie->brand->size;				if (movie->pdin) begin += movie->pdin->size;			}			totSize -= begin;		} else {			if (movie->is_jp2) {				gf_bs_write_u32(bs, 12);				gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));				gf_bs_write_u32(bs, 0x0D0A870A);			}			if (movie->brand) {				e = gf_isom_box_size((GF_Box *)movie->brand);				if (e) goto exit;				e = gf_isom_box_write((GF_Box *)movie->brand, bs);				if (e) goto exit;			}			/*then progressive download*/			if (movie->pdin) {				e = gf_isom_box_size((GF_Box *)movie->pdin);				if (e) goto exit;				e = gf_isom_box_write((GF_Box *)movie->pdin, bs);				if (e) goto exit;			}		}		//if the moov is at the end, write directly		i=0;		while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {			switch (a->type) {			/*written by hand*/			case GF_ISOM_BOX_TYPE_MOOV:			case GF_ISOM_BOX_TYPE_META:			case GF_ISOM_BOX_TYPE_FTYP:			case GF_ISOM_BOX_TYPE_PDIN:				break;			case GF_ISOM_BOX_TYPE_MDAT:				//in case we're capturing				if (movie->openMode == GF_ISOM_OPEN_WRITE) {					//emulate a write to recreate our tables (media data already written)					e = DoWrite(mw, writers, bs, 1, begin);					if (e) goto exit;					continue;				}				//to avoid computing the size each time write always 4 + 4 + 8 bytes before				begin = gf_bs_get_position(bs);				gf_bs_write_u64(bs, 0);				gf_bs_write_u64(bs, 0);				e = DoWrite(mw, writers, bs, 0, gf_bs_get_position(bs));				if (e) goto exit;				totSize = gf_bs_get_position(bs) - begin;				break;			default:				e = gf_isom_box_size(a);				if (e) goto exit;				e = gf_isom_box_write(a, bs);				if (e) goto exit;				break;			}		}		//OK, write the movie box.		e = WriteMoovAndMeta(movie, writers, bs);		if (e) goto exit;		/*if data has been written, update mdat size*/		if (totSize) {			offset = gf_bs_get_position(bs);			e = gf_bs_seek(bs, begin);			if (e) goto exit;			if (totSize > 0xFFFFFFFF) {				gf_bs_write_u32(bs, 1);			} else {				gf_bs_write_u32(bs, (u32) totSize);			}			gf_bs_write_u32(bs, GF_ISOM_BOX_TYPE_MDAT);			if (totSize > 0xFFFFFFFF) gf_bs_write_u64(bs, totSize);			e = gf_bs_seek(bs, offset);		}		movie->mdat->size = totSize;		goto exit;	}	//nope, we have to write the moov first. The pb is that 	//1 - we don't know its size till the mdat is written	//2 - we don't know the ofset at which the mdat will start...	//3 - once the mdat is written, the chunkOffset table can have changed...		if (movie->is_jp2) {		gf_bs_write_u32(bs, 12);		gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));		gf_bs_write_u32(bs, 0x0D0A870A);	}	if (movie->brand) {		e = gf_isom_box_size((GF_Box *)movie->brand);		if (e) goto exit;		e = gf_isom_box_write((GF_Box *)movie->brand, bs);		if (e) goto exit;	}	/*then progressive dnload*/	if (movie->pdin) {		e = gf_isom_box_size((GF_Box *)movie->pdin);		if (e) goto exit;		e = gf_isom_box_write((GF_Box *)movie->pdin, bs);		if (e) goto exit;	}	//What we will do is first emulate the write from the begining...	//note: this will set the size of the mdat	e = DoWrite(mw, writers, bs, 1, gf_bs_get_position(bs));	if (e) goto exit;		firstSize = GetMoovAndMetaSize(movie, writers);	//offset = (firstSize > 0xFFFFFFFF ? firstSize + 8 : firstSize) + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);	offset = firstSize + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);	e = ShiftOffset(movie, writers, offset);	if (e) goto exit;	//get the size and see if it has changed (eg, we moved to 64 bit offsets)	finalSize = GetMoovAndMetaSize(movie, writers);	if (firstSize != finalSize) {		//we need to remove our offsets		ResetWriters(writers);		//finalOffset = (finalSize > 0xFFFFFFFF ? finalSize + 8 : finalSize) + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);		finalOffset = finalSize + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);		//OK, now we're sure about the final size.		//we don't need to re-emulate, as the only thing that changed is the offset		//so just shift the offset		e = ShiftOffset(movie, writers, finalOffset - offset);		if (e) goto exit;	}	//now write our stuff	e = WriteMoovAndMeta(movie, writers, bs);	if (e) goto exit;	e = gf_isom_box_size((GF_Box *)movie->mdat);	if (e) goto exit;	e = gf_isom_box_write((GF_Box *)movie->mdat, bs);	if (e) goto exit;	//we don't need the offset as the moov is already written...	ResetWriters(writers);	e = DoWrite(mw, writers, bs, 0, 0);	if (e) goto exit;	//then the rest	i=0;	while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {		switch (a->type) {		case GF_ISOM_BOX_TYPE_MOOV:		case GF_ISOM_BOX_TYPE_META:		case GF_ISOM_BOX_TYPE_FTYP:		case GF_ISOM_BOX_TYPE_PDIN:		case GF_ISOM_BOX_TYPE_MDAT:			break;		default:			e = gf_isom_box_size(a);			if (e) goto exit;			e = gf_isom_box_write(a, bs);			if (e) goto exit;		}	}exit:	CleanWriters(writers);	gf_list_del(writers);	return e;}GF_Err DoFullInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u32 StartOffset){	u32 i, tracksDone;	TrackWriter *tmp, *curWriter, *prevWriter;	GF_Err e;	u64 DTS, DTStmp, TStmp;	s64 res;	u32 descIndex, sampSize, chunkNumber;	u16 curGroupID, curTrackPriority;	u8 forceNewChunk, writeGroup, isEdited;	//this is used to emulate the write ...	u64 offset, totSize, sampOffset;	GF_ISOFile *movie = mw->movie;	e = GF_OK;	totSize = 0;	curGroupID = 1;	prevWriter = NULL;	//we emulate a write from this offset...	offset = StartOffset;	writeGroup = 1;	tracksDone = 0;		//browse each groups	while (1) {		writeGroup = 1;		//proceed a group		while (writeGroup) {			//first get the appropriated sample for the min time in this group			curWriter = NULL;			DTStmp = (u64) -1;			TStmp = 0;			curTrackPriority = (u16) -1;			i=0;			while ((tmp = (TrackWriter*)gf_list_enum(writers, &i))) {				//is it done writing ?				//is it in our group ??				if (tmp->isDone || tmp->mdia->information->sampleTable->groupID != curGroupID) continue;				//OK, get the current sample in this track				stbl_GetSampleDTS(tmp->mdia->information->sampleTable->TimeToSample, tmp->sampleNumber, &DTS);								res = TStmp ? DTStmp * tmp->timeScale - DTS * TStmp : 0;				if (res < 0) continue;				if ((!res) && curTrackPriority <= tmp->mdia->information->sampleTable->trackPriority) continue;				curWriter = tmp;				curTrackPriority = tmp->mdia->information->sampleTable->trackPriority;				DTStmp = DTS;				TStmp = tmp->timeScale;

⌨️ 快捷键说明

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