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

📄 track.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
				}			}			//add size first			stbl_AppendSize(trak->Media->information->sampleTable, size);			//then TS			stbl_AppendTime(trak->Media->information->sampleTable, duration);			//add chunk on first sample			if (!j) {				data_offset = base_offset;				//aggregated offset				if (!(traf->tfhd->flags & GF_ISOM_TRAF_BASE_OFFSET)) data_offset += chunk_size;				if (trun->flags & GF_ISOM_TRUN_DATA_OFFSET) data_offset += trun->data_offset;				stbl_AppendChunk(trak->Media->information->sampleTable, data_offset);				//then sampleToChunk				stbl_AppendSampleToChunk(trak->Media->information->sampleTable, 					DescIndex, trun->sample_count);			}			chunk_size += size;						//CTS			cts_offset = (trun->flags & GF_ISOM_TRUN_CTS_OFFSET) ? ent->CTS_Offset : 0;			stbl_AppendCTSOffset(trak->Media->information->sampleTable, cts_offset);						//flags			sync = GF_ISOM_GET_FRAG_SYNC(flags);			stbl_AppendRAP(trak->Media->information->sampleTable, sync);			pad = GF_ISOM_GET_FRAG_PAD(flags);			if (pad) stbl_AppendPadding(trak->Media->information->sampleTable, pad);			degr = GF_ISOM_GET_FRAG_DEG(flags);			if (degr) stbl_AppendDegradation(trak->Media->information->sampleTable, degr);		}	}	//end of the fragment, update offset	*moof_offset += chunk_size;	return GF_OK;}#endif#ifndef GPAC_READ_ONLY//used to check if a TrackID is availableu8 RequestTrack(GF_MovieBox *moov, u32 TrackID){	u32 i;	GF_TrackBox *trak;	i=0;	while ((trak = (GF_TrackBox *)gf_list_enum(moov->trackList, &i))) {		if (trak->Header->trackID == TrackID) {			gf_isom_set_last_error(moov->mov, GF_BAD_PARAM);			return 0;		}	}	return 1;}GF_Err Track_RemoveRef(GF_TrackBox *trak, u32 ReferenceType){	GF_TrackReferenceBox *ref;	GF_Box *a;	u32 i;	if (! trak) return GF_BAD_PARAM;	if (! trak->References) return GF_OK;	ref = trak->References;	i=0;	while ((a = (GF_Box *)gf_list_enum(ref->boxList, &i))) {		if (a->type == ReferenceType) {			gf_isom_box_del(a);			gf_list_rem(ref->boxList, i-1);			return GF_OK;		}	}	return GF_OK;	}GF_Err NewMedia(GF_MediaBox **mdia, u32 MediaType, u32 TimeScale){	GF_MediaHeaderBox *mdhd;	GF_Box *mediaInfo;	GF_HandlerBox *hdlr;	GF_MediaInformationBox *minf;	GF_DataInformationBox *dinf;	GF_SampleTableBox *stbl;	GF_SampleDescriptionBox *stsd;	GF_DataReferenceBox *dref;	char *str;	GF_Err e;	if (*mdia || !mdia) return GF_BAD_PARAM;	e = GF_OK;	minf = NULL;	mdhd = NULL;	hdlr = NULL;	dinf = NULL;	stbl = NULL;	stsd = NULL;	dref = NULL;	mediaInfo = NULL;	//first create the media	*mdia = (GF_MediaBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MDIA);	mdhd = (GF_MediaHeaderBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MDHD);	//"handler name" is for debugging purposes. Let's stick our name here ;)	switch (MediaType) {	case GF_ISOM_MEDIA_VISUAL:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_VMHD);		str = "GPAC ISO Video Handler";		break;	case GF_ISOM_MEDIA_AUDIO:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_SMHD);		str = "GPAC ISO Audio Handler";		break;	case GF_ISOM_MEDIA_HINT:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_HMHD);		str = "GPAC ISO Hint Handler";		break;	case GF_ISOM_MEDIA_OD:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC MPEG-4 OD Handler";		break;	case GF_ISOM_MEDIA_OCR:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC MPEG-4 OCR Handler";		break;	case GF_ISOM_MEDIA_SCENE:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC MPEG-4 BIFS Handler";		break;	case GF_ISOM_MEDIA_MPEG7:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC MPEG-4 MPEG-7 Handler";		break;	case GF_ISOM_MEDIA_OCI:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC MPEG-4 OCI Handler";		break;	case GF_ISOM_MEDIA_IPMP:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC MPEG-4 IPMP Handler";		break;	case GF_ISOM_MEDIA_MPEGJ:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC MPEG-4 MPEG-J Handler";		break;	case GF_ISOM_MEDIA_TEXT:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC Streaming Text Handler";		break;	default:		mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD);		str = "GPAC IsoMedia Handler";		break;	}	hdlr = (GF_HandlerBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_HDLR);	minf = (GF_MediaInformationBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MINF);	mdhd->timeScale = TimeScale;	hdlr->handlerType = MediaType;	hdlr->nameUTF8 = strdup(str);	//first set-up the sample table...	stbl = (GF_SampleTableBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STBL);	dinf = (GF_DataInformationBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DINF);	stbl->SampleDescription = (GF_SampleDescriptionBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSD);	stbl->ChunkOffset = gf_isom_box_new(GF_ISOM_BOX_TYPE_STCO);	//by default create a regular table	stbl->SampleSize = (GF_SampleSizeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSZ);	stbl->SampleToChunk = (GF_SampleToChunkBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSC);	stbl->TimeToSample = (GF_TimeToSampleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STTS);	//Create a data reference WITHOUT DATA ENTRY (we don't know anything yet about the media Data)	dref = (GF_DataReferenceBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DREF);	e = dinf_AddBox((GF_Box*)dinf, (GF_Box *)dref); if (e) goto err_exit;	e = minf_AddBox((GF_Box*)minf, (GF_Box *) mediaInfo); if (e) goto err_exit;	e = minf_AddBox((GF_Box*)minf, (GF_Box *) stbl); if (e) goto err_exit;	e = minf_AddBox((GF_Box*)minf, (GF_Box *) dinf); if (e) goto err_exit;	e = mdia_AddBox((GF_Box*)*mdia, (GF_Box *) mdhd); if (e) goto err_exit;	e = mdia_AddBox((GF_Box*)*mdia, (GF_Box *) minf); if (e) goto err_exit;	e = mdia_AddBox((GF_Box*)*mdia, (GF_Box *) hdlr); if (e) goto err_exit;	return GF_OK;err_exit:	if (mdhd) gf_isom_box_del((GF_Box *)mdhd);	if (minf) gf_isom_box_del((GF_Box *)minf);	if (hdlr) {		if (hdlr->nameUTF8) free(hdlr->nameUTF8);		gf_isom_box_del((GF_Box *)hdlr);	}	return e;}GF_Err Track_SetStreamDescriptor(GF_TrackBox *trak, u32 StreamDescriptionIndex, u32 DataReferenceIndex, GF_ESD *esd, u32 *outStreamIndex){	GF_Err e;	GF_MPEGSampleEntryBox *entry;	GF_MPEGVisualSampleEntryBox *entry_v;	GF_MPEGAudioSampleEntryBox *entry_a;	GF_TrackReferenceBox *tref;	GF_TrackReferenceTypeBox *dpnd;	u16 tmpRef;	entry = NULL;	tref = NULL;	if (!trak || !esd || (!outStreamIndex && !DataReferenceIndex) ) return GF_BAD_PARAM;	if (!Track_IsMPEG4Stream(trak->Media->handler->handlerType)) return GF_ISOM_INVALID_MEDIA;		esd->ESID = 0;	//set SL to predefined if no url	if (esd->URLString == NULL) {		if (!esd->slConfig) esd->slConfig = (GF_SLConfig*) gf_odf_desc_new(GF_ODF_SLC_TAG);		esd->slConfig->predefined = SLPredef_MP4;		esd->slConfig->durationFlag = 0;		esd->slConfig->useTimestampsFlag = 1;	}	//get the REF box if needed	if (esd->dependsOnESID  || esd->OCRESID ) {		if (!trak->References) {			tref = (GF_TrackReferenceBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TREF);			e = trak_AddBox((GF_Box*)trak, (GF_Box *)tref);			if (e) return e;		}		tref = trak->References;	}	//Update Stream dependancies	e = Track_FindRef(trak, GF_ISOM_REF_DECODE, &dpnd);	if (e) return e;	if (!dpnd && esd->dependsOnESID) {		dpnd = (GF_TrackReferenceTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DPND);		e = tref_AddBox((GF_Box*)tref, (GF_Box *) dpnd);		if (e) return e;		e = reftype_AddRefTrack(dpnd, esd->dependsOnESID, NULL);		if (e) return e;	} else if (dpnd && !esd->dependsOnESID) {		Track_RemoveRef(trak, GF_ISOM_BOX_TYPE_DPND);	}	esd->dependsOnESID = 0;	//Update GF_Clock dependancies	e = Track_FindRef(trak, GF_ISOM_REF_OCR, &dpnd);	if (e) return e;	if (!dpnd && esd->OCRESID) {		dpnd = (GF_TrackReferenceTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_SYNC);		e = tref_AddBox((GF_Box*)tref, (GF_Box *) dpnd);		if (e) return e;		e = reftype_AddRefTrack(dpnd, esd->OCRESID, NULL);		if (e) return e;	} else if (dpnd && !esd->OCRESID) {		Track_RemoveRef(trak, GF_ISOM_BOX_TYPE_SYNC);	} else if (dpnd && esd->OCRESID) {		if (dpnd->trackIDCount != 1) return GF_ISOM_INVALID_MEDIA;		dpnd->trackIDs[0] = esd->OCRESID;	}	esd->OCRESID = 0;	//brand new case: we have to change the IPI desc	if (esd->ipiPtr) {		e = Track_FindRef(trak, GF_ISOM_REF_IPI, &dpnd);		if (e) return e;		if (!dpnd) {			tmpRef = 0;			dpnd = (GF_TrackReferenceTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_IPIR);			e = tref_AddBox((GF_Box*)tref, (GF_Box *) dpnd);			if (e) return e;			e = reftype_AddRefTrack(dpnd, esd->ipiPtr->IPI_ES_Id, &tmpRef);			if (e) return e;			//and replace the tag and value...			esd->ipiPtr->IPI_ES_Id = tmpRef;			esd->ipiPtr->tag = GF_ODF_ISOM_IPI_PTR_TAG;		} else {			//Watch out! ONLY ONE IPI dependancy is allowed per stream			if (dpnd->trackIDCount != 1) return GF_ISOM_INVALID_MEDIA;			//if an existing one is there, what shall we do ???			//donno, erase it			dpnd->trackIDs[0] = esd->ipiPtr->IPI_ES_Id;			//and replace the tag and value...			esd->ipiPtr->IPI_ES_Id = 1;			esd->ipiPtr->tag = GF_ODF_ISOM_IPI_PTR_TAG;		}	}	/*don't store the lang desc in ESD, use the media header language info*/	if (esd->langDesc) {		trak->Media->mediaHeader->packedLanguage[0] = (esd->langDesc->langCode>>16)&0xFF;		trak->Media->mediaHeader->packedLanguage[1] = (esd->langDesc->langCode>>8)&0xFF;		trak->Media->mediaHeader->packedLanguage[2] = (esd->langDesc->langCode)&0xFF;		gf_odf_desc_del((GF_Descriptor *)esd->langDesc);		esd->langDesc = NULL;	}	//we have a streamDescritpionIndex, use it	if (StreamDescriptionIndex) {		entry = (GF_MPEGSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex - 1);		if (!entry) return GF_ISOM_INVALID_FILE;		switch (entry->type) {		case GF_ISOM_BOX_TYPE_MP4S:			//OK, delete the previous ESD			gf_odf_desc_del((GF_Descriptor *) entry->esd->desc);			entry->esd->desc = esd;			break;		case GF_ISOM_BOX_TYPE_MP4V:			entry_v = (GF_MPEGVisualSampleEntryBox*) entry;			//OK, delete the previous ESD			gf_odf_desc_del((GF_Descriptor *) entry_v->esd->desc);			entry_v->esd->desc = esd;			break;		case GF_ISOM_BOX_TYPE_MP4A:			entry_a = (GF_MPEGAudioSampleEntryBox*) entry;			//OK, delete the previous ESD			gf_odf_desc_del((GF_Descriptor *) entry_a->esd->desc);			entry_a->esd->desc = esd;			break;		case GF_ISOM_BOX_TYPE_AVC1:			e = AVC_UpdateESD((GF_MPEGVisualSampleEntryBox*)entry, esd);			if (e) return e;			break;		default:			gf_odf_desc_del((GF_Descriptor *) esd);			break;		}	} else {		//need to check we're not in URL mode where only ONE description is allowed...		StreamDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);		if (StreamDescriptionIndex) {			entry = (GF_MPEGSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex - 1);			if (!entry) return GF_ISOM_INVALID_FILE;			if (entry->esd->desc->URLString) return GF_BAD_PARAM;		}		//OK, check the handler and create the entry		switch (trak->Media->handler->handlerType) {		case GF_ISOM_MEDIA_VISUAL:			if (esd->decoderConfig->objectTypeIndication==0x21) {				entry_v = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_AVC1);				if (!entry_v) return GF_OUT_OF_MEM;				e = AVC_UpdateESD((GF_MPEGVisualSampleEntryBox*)entry_v, esd);			} else {				entry_v = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MP4V);				if (!entry_v) return GF_OUT_OF_MEM;				entry_v->esd = (GF_ESDBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_ESDS);				entry_v->esd->desc = esd;			}			//type cast possible now			entry = (GF_MPEGSampleEntryBox*) entry_v;			break;		case GF_ISOM_MEDIA_AUDIO:			entry_a = (GF_MPEGAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MP4A);			entry_a->samplerate_hi = trak->Media->mediaHeader->timeScale;			if (!entry_a) return GF_OUT_OF_MEM;			entry_a->esd = (GF_ESDBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_ESDS);			entry_a->esd->desc = esd;			//type cast possible now			entry = (GF_MPEGSampleEntryBox*) entry_a;			break;		default:			entry = (GF_MPEGSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MP4S);			entry->esd = (GF_ESDBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_ESDS);			entry->esd->desc = esd;			break;		}		entry->dataReferenceIndex = DataReferenceIndex;		//and add the entry to our table...		e = stsd_AddBox(trak->Media->information->sampleTable->SampleDescription, (GF_Box *) entry);		if (e) return e;		if(outStreamIndex) *outStreamIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);	}	return GF_OK;}#endif	//GPAC_READ_ONLY

⌨️ 快捷键说明

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