예제 #1
0
GF_Err schi_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	if (ptr->ikms) {
		e = gf_isom_box_write((GF_Box *) ptr->ikms, bs);
		if (e) return e;
	}
	if (ptr->isfm) {
		e = gf_isom_box_write((GF_Box *) ptr->isfm, bs);
		if (e) return e;
	}
	if (ptr->okms) {
		e = gf_isom_box_write((GF_Box *) ptr->okms, bs);
		if (e) return e;
	}
	if (ptr->tenc) {
		e = gf_isom_box_write((GF_Box *) ptr->tenc, bs);
		if (e) return e;
	}
	if (ptr->piff_tenc) {
		e = gf_isom_box_write((GF_Box *) ptr->piff_tenc, bs);
		if (e) return e;
	}
	return GF_OK;
}
예제 #2
0
//replace the chunk and offset tables...
static GF_Err WriteMoovAndMeta(GF_ISOFile *movie, GF_List *writers, GF_BitStream *bs)
{
	u32 i;
	TrackWriter *writer;
	GF_Err e;
	GF_Box *stco;
	GF_SampleToChunkBox *stsc;

	if (movie->meta) {
		//write the moov box...
		e = gf_isom_box_size((GF_Box *)movie->meta);
		if (e) return e;
		e = gf_isom_box_write((GF_Box *)movie->meta, bs);
		if (e) return e;
	}

	if (movie->moov) {
		//switch all our tables
		i=0;
		while ((writer = (TrackWriter*)gf_list_enum(writers, &i))) {
			//don't delete them !!!
			stsc = writer->mdia->information->sampleTable->SampleToChunk;
			stco = writer->mdia->information->sampleTable->ChunkOffset;
			writer->mdia->information->sampleTable->SampleToChunk = writer->stsc;
			writer->mdia->information->sampleTable->ChunkOffset = writer->stco;
			writer->stco = stco;
			writer->stsc = stsc;
		}
		//write the moov box...
		e = gf_isom_box_size((GF_Box *)movie->moov);
		if (e) return e;
		e = gf_isom_box_write((GF_Box *)movie->moov, bs);
		//and re-switch our table. We have to do it that way because it is 
		//needed when the moov is written first
		i=0;
		while ((writer = (TrackWriter*)gf_list_enum(writers, &i))) {
			//don't delete them !!!
			stsc = writer->stsc;
			stco = writer->stco;
			writer->stsc = writer->mdia->information->sampleTable->SampleToChunk;
			writer->stco = writer->mdia->information->sampleTable->ChunkOffset;
			writer->mdia->information->sampleTable->SampleToChunk = stsc;
			writer->mdia->information->sampleTable->ChunkOffset = stco;
		}
		if (e) return e;
	}
	return GF_OK;
}
예제 #3
0
GF_Err aprm_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	//aeib
	e = gf_isom_box_write((GF_Box *) ptr->enc_info, bs);
	if (e) return e;
	//akey
	e = gf_isom_box_write((GF_Box *) ptr->key_info, bs);
	if (e) return e;

	return GF_OK;
}
예제 #4
0
GF_Err adkm_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	//ahdr
	e = gf_isom_box_write((GF_Box *) ptr->header, bs);
	if (e) return e;
	//adaf
	e = gf_isom_box_write((GF_Box *) ptr->au_format, bs);
	if (e) return e;

	return GF_OK;
}
예제 #5
0
파일: hinting.c 프로젝트: ARSekkat/gpac
GF_Err gf_isom_hint_sample_write(GF_HintSample *ptr, GF_BitStream *bs)
{
	u32 count, i;
	GF_HintPacket *pck;
	GF_Err e;

	if (ptr->hint_subtype==GF_ISOM_BOX_TYPE_FDP_STSD) {
		e = gf_isom_box_size((GF_Box*)ptr);
		if (!e) e = gf_isom_box_write((GF_Box*)ptr, bs);
		return e;
	}

	count = gf_list_count(ptr->packetTable);
	gf_bs_write_u16(bs, count);
	gf_bs_write_u16(bs, ptr->reserved);
	//write the packet table
	for (i=0; i<count; i++) {
		pck = (GF_HintPacket *)gf_list_get(ptr->packetTable, i);
		e = gf_isom_hint_pck_write(pck, bs);
		if (e) return e;
	}
	//write additional data
	if (ptr->AdditionalData) {
		gf_bs_write_data(bs, ptr->AdditionalData, ptr->dataLength);
	}
	return GF_OK;
}
예제 #6
0
GF_Err odkm_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->hdr) {
		e = gf_isom_box_write((GF_Box*)ptr->hdr, bs);
		if (e) return e;
	}
	if (ptr->fmt) {
		e = gf_isom_box_write((GF_Box*)ptr->fmt, bs);
		if (e) return e;
	}
	return GF_OK;
}
예제 #7
0
static GFINLINE GF_Err gpp_write_modifier(GF_BitStream *bs, GF_Box *a)
{
	GF_Err e;
	if (!a) return GF_OK;
	e = gf_isom_box_size(a);
	if (!e) e = gf_isom_box_write(a, bs);
	return e;
}
예제 #8
0
GF_Err sinf_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	//frma
	e = gf_isom_box_write((GF_Box *) ptr->original_format, bs);
	if (e) return e;
	// schm
	e = gf_isom_box_write((GF_Box *) ptr->scheme_type, bs);
	if (e) return e;
	// schi
	e = gf_isom_box_write((GF_Box *) ptr->info, bs);
	if (e) return e;
	return GF_OK;
}
예제 #9
0
파일: webvtt.c 프로젝트: erelh/gpac
GF_Err vtcu_Write(GF_Box *s, GF_BitStream *bs)
{
    GF_Err e;
    GF_VTTCueBox *cuebox = (GF_VTTCueBox *)s;
    e = gf_isom_box_write_header(s, bs);
    if (e) return e;
    if (cuebox->id) {
        e = gf_isom_box_write((GF_Box *)cuebox->id, bs);
        if (e) return e;
    }
    if (cuebox->settings) {
        e = gf_isom_box_write((GF_Box *)cuebox->settings, bs);
        if (e) return e;
    }
    if (cuebox->payload) {
        e = gf_isom_box_write((GF_Box *)cuebox->payload, bs);
    }
    return e;
}
예제 #10
0
GF_Err gppa_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
	return gf_isom_box_write((GF_Box *)ptr->info, bs);
}
예제 #11
0
GF_Err gppv_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_3GPPVisualSampleEntryBox *ptr = (GF_3GPPVisualSampleEntryBox*)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs);
	e = gf_isom_box_write((GF_Box *)ptr->info, bs);
	if (e) return e;
	return GF_OK;
}
예제 #12
0
파일: webvtt.c 프로젝트: dragonlucian/gpac
GF_Err wvtt_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_WebVTTSampleEntryBox *wvtt = (GF_WebVTTSampleEntryBox *)s;
	e = gf_isom_box_write_header(s, bs);
	gf_bs_write_data(bs, wvtt->reserved, 6);
	gf_bs_write_u16(bs, wvtt->dataReferenceIndex);

	if (wvtt->config) gf_isom_box_write((GF_Box *)wvtt->config, bs);
	return e;
}
예제 #13
0
GF_Err ahdr_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	e = gf_isom_box_write((GF_Box *) ptr->std_enc_params, bs);
	if (e) return e;

	return GF_OK;
}
예제 #14
0
GF_Err akey_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	e = gf_isom_box_write((GF_Box *) ptr->params, bs);
	if (e) return e;

	return GF_OK;
}
예제 #15
0
GF_Err meta_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MetaBox *ptr = (GF_MetaBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->handler) {
		e = gf_isom_box_write((GF_Box *) ptr->handler, bs);
		if (e) return e;
	}
	if (ptr->primary_resource) {
		e = gf_isom_box_write((GF_Box *) ptr->primary_resource, bs);
		if (e) return e;
	}
	if (ptr->file_locations) {
		e = gf_isom_box_write((GF_Box *) ptr->file_locations, bs);
		if (e) return e;
	}
	if (ptr->item_locations) {
		e = gf_isom_box_write((GF_Box *) ptr->item_locations, bs);
		if (e) return e;
	}
	if (ptr->protections) {
		e = gf_isom_box_write((GF_Box *) ptr->protections, bs);
		if (e) return e;
	}
	if (ptr->item_infos) {
		e = gf_isom_box_write((GF_Box *) ptr->item_infos, bs);
		if (e) return e;
	}
	if (ptr->IPMP_control) {
		e = gf_isom_box_write((GF_Box *) ptr->IPMP_control, bs);
		if (e) return e;
	}
	if (ptr->item_refs) {
		e = gf_isom_box_write((GF_Box *)ptr->item_refs, bs);
		if (e) return e;
	}
	if (ptr->item_props) {
		e = gf_isom_box_write((GF_Box *) ptr->item_props, bs);
		if (e) return e;
	}
	return GF_OK;
}
예제 #16
0
GF_Err ListItem_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ListItemBox *ptr = (GF_ListItemBox *) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	/*iTune way*/
	if (ptr->data->type) return gf_isom_box_write((GF_Box* )ptr->data, bs);
	/*QT way*/
	gf_bs_write_u16(bs, ptr->data->dataSize);
	gf_bs_write_u16(bs, 0);
	gf_bs_write_data(bs, ptr->data->data, ptr->data->dataSize);
	return GF_OK;
}
예제 #17
0
GF_Err iref_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 count, i;
	GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	count = gf_list_count(ptr->references);
	for (i = 0; i < count; i++) {
		GF_Box *a = (GF_Box *)gf_list_get(ptr->references, i);
		e = gf_isom_box_write(a, bs);
		if (e) return e;
	}
	return e;
}
예제 #18
0
GF_Err ipro_Write(GF_Box *s, GF_BitStream *bs)
{
	u32 count, i;
	GF_Err e;
	GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	count = gf_list_count(ptr->protection_information);
	gf_bs_write_u16(bs, count);
	if (count) {
		for (i = 0; i < count; i++) {
			GF_Box *a = (GF_Box *)gf_list_get(ptr->protection_information, i);
			e = gf_isom_box_write(a, bs);
			if (e) return e;
		}
	}
	return GF_OK;
}
예제 #19
0
파일: webvtt.c 프로젝트: dragonlucian/gpac
GF_ISOSample *gf_isom_webvtt_to_sample(void *s)
{
	GF_Err e = GF_OK;
	GF_ISOSample *res;
	GF_BitStream *bs;
	u32 i;
	GF_WebVTTCue *cue;
	GF_WebVTTSample *samp = (GF_WebVTTSample *)s;
	if (!samp) return NULL;

	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);

	if (gf_list_count(samp->cues)) {
		i=0;
		while ((cue = (GF_WebVTTCue *)gf_list_enum(samp->cues, &i))) {
			e = webvtt_write_cue(bs, cue);
			if (e) break;
		}
		if (e) {
			gf_bs_del(bs);
			return NULL;
		}
	} else {
		GF_Box *cuebox = (GF_Box *)vtte_New();
		e = gf_isom_box_size((GF_Box *)cuebox);
		if (!e) e = gf_isom_box_write((GF_Box *)cuebox, bs);
		gf_isom_box_del((GF_Box *)cuebox);
		if (e) {
			gf_bs_del(bs);
			return NULL;
		}
	}
	res = gf_isom_sample_new();
	if (!res) {
		gf_bs_del(bs);
		return NULL;
	}
	gf_bs_get_content(bs, &res->data, &res->dataLength);
	gf_bs_del(bs);
	res->IsRAP = RAP;
	return res;
}
예제 #20
0
파일: webvtt.c 프로젝트: dragonlucian/gpac
static GF_Err webvtt_write_cue(GF_BitStream *bs, GF_WebVTTCue *cue)
{
	GF_Err e;
	GF_VTTCueBox *cuebox;
	if (!cue) return GF_OK;

	cuebox = (GF_VTTCueBox *)vtcu_New();
	if (cue->id) {
		cuebox->id = (GF_StringBox *)boxstring_new_with_data(GF_ISOM_BOX_TYPE_IDEN, cue->id);
	}
	if (cue->settings) {
		cuebox->settings = (GF_StringBox *)boxstring_new_with_data(GF_ISOM_BOX_TYPE_STTG, cue->settings);
	}
	if (cue->text) {
		cuebox->payload = (GF_StringBox *)boxstring_new_with_data(GF_ISOM_BOX_TYPE_PAYL, cue->text);
	}
	/* TODO: check if a time box should be written */
	e = gf_isom_box_size((GF_Box *)cuebox);
	if (!e) e = gf_isom_box_write((GF_Box *)cuebox, bs);

	gf_isom_box_del((GF_Box *)cuebox);
	return e;
}
예제 #21
0
//write the file track by track, with moov box before or after the mdat
GF_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;
}
예제 #22
0
static GF_Err WriteInterleaved(MovieWriter *mw, GF_BitStream *bs, Bool drift_inter)
{
	GF_Err e;
	u32 i;
	GF_Box *a;
	u64 firstSize, finalSize, offset, finalOffset;
	GF_List *writers = gf_list_new();
	GF_ISOFile *movie = mw->movie;

	//first setup the writers
	e = SetupWriters(mw, writers, 1);
	if (e) goto exit;


	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;
	}
	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;
	}

	e = DoInterleave(mw, writers, bs, 1, gf_bs_get_position(bs), drift_inter);
	if (e) goto exit;

	firstSize = GetMoovAndMetaSize(movie, writers);
	offset = firstSize;
	if (movie->mdat && movie->mdat->dataSize) offset += 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;
		if (movie->mdat->dataSize) finalOffset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
		//OK, now we're sure about the final size -> shift the offsets
		//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;
		firstSize = GetMoovAndMetaSize(movie, writers);
	}
	//now write our stuff
	e = WriteMoovAndMeta(movie, writers, bs);
	if (e) goto exit;

	/*we have 8 extra bytes for large size (not computed in gf_isom_box_size) */
	if (movie->mdat && movie->mdat->dataSize) {
		if (movie->mdat->dataSize > 0xFFFFFFFF) movie->mdat->dataSize += 8;
		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 we are writing...
	ResetWriters(writers);
	e = DoInterleave(mw, writers, bs, 0, 0, drift_inter);
	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;
}
예제 #23
0
static GF_Err WriteInterleaved(MovieWriter *mw, GF_BitStream *bs, Bool drift_inter)
{
	GF_Err e;
	u8 converted;
	u32 i;
	GF_Box *a;
	u64 offset, shift_offset, prev;
	GF_List *writers = gf_list_new();
	GF_ISOFile *movie = mw->movie;

	//first setup the writers
	e = SetupWriters(mw, writers, 1);
	if (e) goto exit;


	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;
	}
	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;
	}

	e = DoInterleave(mw, writers, bs, 1, gf_bs_get_position(bs), drift_inter);
	if (e) goto exit;

	shift_offset = 0;
	prev = 0;
	for (;;) {
		offset = GetMoovAndMetaSize(movie, writers);
		if (offset==prev) break;
		prev = offset;
		if (movie->mdat && movie->mdat->dataSize)
			offset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
		e = ShiftOffset(movie, writers, offset-shift_offset,&converted);
		if (e) goto exit;
		shift_offset = offset;
	}

	//now write our stuff
	e = WriteMoovAndMeta(movie, writers, bs);
	if (e) goto exit;

	/*we have 8 extra bytes for large size (not computed in gf_isom_box_size) */
	if (movie->mdat && movie->mdat->dataSize) {
		if (movie->mdat->dataSize > 0xFFFFFFFF) movie->mdat->dataSize += 8;
		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 we are writing...
	ResetWriters(writers);
	e = DoInterleave(mw, writers, bs, 0, 0, drift_inter);
	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;
}