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

📄 hint_track.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / ISO Media File Format sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/internal/isomedia_dev.h>Bool IsHintTrack(GF_TrackBox *trak){	if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_HINT) return 0;	//QT doesn't specify any InfoHeader on HintTracks	if (trak->Media->information->InfoHeader 			&& trak->Media->information->InfoHeader->type != GF_ISOM_BOX_TYPE_HMHD) 		return 0;	return 1;}u32 GetHintFormat(GF_TrackBox *trak){	GF_HintMediaHeaderBox *hmhd = (GF_HintMediaHeaderBox *)trak->Media->information->InfoHeader;	if (!hmhd->subType) {		GF_Box *a = (GF_Box *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0);		if (a) hmhd->subType = a->type;	}	return hmhd->subType;}Bool CheckHintFormat(GF_TrackBox *trak, u32 HintType){	if (!IsHintTrack(trak)) return 0;	if (GetHintFormat(trak) != HintType) return 0;	return 1;}#ifndef GPAC_READ_ONLYGF_Err AdjustHintInfo(GF_HintSampleEntryBox *entry, u32 HintSampleNumber){	u32 offset, count, i, size;	GF_HintPacket *pck;	GF_Err e;	offset = gf_isom_hint_sample_size(entry->hint_sample) - entry->hint_sample->dataLength;	count = gf_list_count(entry->hint_sample->packetTable);		for (i=0; i<count; i++) {		pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, i);		if (offset && entry->hint_sample->dataLength) {			//adjust any offset in this packet			e = gf_isom_hint_pck_offset(entry->hint_sample->HintType, pck, offset, HintSampleNumber);			if (e) return e;		}		//adjust the max packet size for this sample entry...		size = gf_isom_hint_pck_length(entry->hint_sample->HintType, pck);		if (entry->MaxPacketSize < size) entry->MaxPacketSize = size;	}	return GF_OK;}GF_Err gf_isom_setup_hint_track(GF_ISOFile *movie, u32 trackNumber, u32 HintType){	GF_Err e;	GF_TrackBox *trak;	GF_TrackReferenceBox *tref;	GF_TrackReferenceTypeBox *dpnd;	GF_HintMediaHeaderBox *hmhd;	//UDTA related ...	GF_UserDataBox *udta;	//what do we support	switch (HintType) {	case GF_ISOM_HINT_RTP:		break;	default:		return GF_NOT_SUPPORTED;	}	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);	if (e) return e;	trak = gf_isom_get_track_from_file(movie, trackNumber);	if (!trak) return gf_isom_last_error(movie);	//check we have a hint ...	if ( !IsHintTrack(trak)) {		return GF_BAD_PARAM;	}	hmhd = (GF_HintMediaHeaderBox *)trak->Media->information->InfoHeader;	//make sure the subtype was not already defined	if (hmhd->subType) return GF_BAD_PARAM;	//store the HintTrack format for later use...	hmhd->subType = HintType;		//hint tracks always have a tref and everything ...	if (!trak->References) {		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;	//do we have a hint reference on this trak ???	e = Track_FindRef(trak, GF_ISOM_BOX_TYPE_HINT, &dpnd);	if (e) return e;	//if yes, return false (existing hint track...)	if (dpnd) return GF_BAD_PARAM;	//create our dep	dpnd = (GF_TrackReferenceTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_HINT);	e = tref_AddBox((GF_Box*)tref, (GF_Box *) dpnd);	if (e) return e;	//for RTP, we need to do some UDTA-related stuff...	if (HintType != GF_ISOM_HINT_RTP) return GF_OK;	if (!trak->udta) {		//create one		udta = (GF_UserDataBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA);		e = trak_AddBox((GF_Box*)trak, (GF_Box *) udta);		if (e) return e;	}	udta = trak->udta;	//HNTI	e = udta_AddBox(udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_HNTI));	if (e) return e;/*	//NAME	e = udta_AddBox(udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_NAME));	if (e) return e;	//HINF	return udta_AddBox(udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_HINF));*/	return GF_OK;}//to use with internally supported protocolsGF_Err gf_isom_new_hint_description(GF_ISOFile *the_file, u32 trackNumber, s32 HintTrackVersion, s32 LastCompatibleVersion, u8 Rely, u32 *HintDescriptionIndex){	GF_Err e;	u32 drefIndex;	GF_TrackBox *trak;	GF_HintSampleEntryBox *hdesc;	GF_RelyHintBox *relyA;	e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);	if (e) return e;	trak = gf_isom_get_track_from_file(the_file, trackNumber);	*HintDescriptionIndex = 0;	if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM;	//OK, create a new HintSampleDesc	hdesc = (GF_HintSampleEntryBox *) gf_isom_box_new(GetHintFormat(trak));	if (HintTrackVersion > 0) hdesc->HintTrackVersion = HintTrackVersion;	if (LastCompatibleVersion > 0) hdesc->LastCompatibleVersion = LastCompatibleVersion;	//create a data reference - WE ONLY DEAL WITH SELF-CONTAINED HINT TRACKS	e = Media_CreateDataRef(trak->Media->information->dataInformation->dref, NULL, NULL, &drefIndex);	if (e) return e;	hdesc->dataReferenceIndex = drefIndex;	//add the entry to our table...	e = stsd_AddBox(trak->Media->information->sampleTable->SampleDescription, (GF_Box *) hdesc);	if (e) return e;	*HintDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList);	//RTP needs a default timeScale... use the media one.	if (CheckHintFormat(trak, GF_ISOM_HINT_RTP)) {		e = gf_isom_rtp_set_timescale(the_file, trackNumber, *HintDescriptionIndex, trak->Media->mediaHeader->timeScale);		if (e) return e;	}	if (!Rely) return GF_OK;	//we need a rely box (common to all protocols)	relyA = (GF_RelyHintBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_RELY);	if (Rely == 1) {		relyA->prefered = 1;	} else {		relyA->required = 1;	}	return gf_list_add(hdesc->HintDataTable, relyA);}/*******************************************************************					RTP WRITING API*******************************************************************///sets the RTP TimeScaleGF_Err gf_isom_rtp_set_timescale(GF_ISOFile *the_file, u32 trackNumber, u32 HintDescriptionIndex, u32 TimeScale){	GF_TrackBox *trak;	GF_HintSampleEntryBox *hdesc;	u32 i, count;	GF_TSHintEntryBox *ent;	trak = gf_isom_get_track_from_file(the_file, trackNumber);	if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM;	//OK, create a new HintSampleDesc	hdesc = (GF_HintSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, HintDescriptionIndex - 1);	count = gf_list_count(hdesc->HintDataTable);	for (i=0; i< count; i++) {		ent = (GF_TSHintEntryBox *)gf_list_get(hdesc->HintDataTable, i);		if (ent->type == GF_ISOM_BOX_TYPE_TIMS) {						ent->timeScale = TimeScale;			return GF_OK;		}	}	//we have to create a new entry...	ent = (GF_TSHintEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TIMS);	ent->timeScale = TimeScale;	return gf_list_add(hdesc->HintDataTable, ent);}//sets the RTP TimeOffset that the server will add to the packets//if not set, the server adds a random offsetGF_Err gf_isom_rtp_set_time_offset(GF_ISOFile *the_file, u32 trackNumber, u32 HintDescriptionIndex, u32 TimeOffset){	GF_TrackBox *trak;	GF_HintSampleEntryBox *hdesc;	u32 i, count;	GF_TimeOffHintEntryBox *ent;	trak = gf_isom_get_track_from_file(the_file, trackNumber);	if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM;	//OK, create a new HintSampleDesc	hdesc = (GF_HintSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, HintDescriptionIndex - 1);	count = gf_list_count(hdesc->HintDataTable);	for (i=0; i< count; i++) {		ent = (GF_TimeOffHintEntryBox *)gf_list_get(hdesc->HintDataTable, i);		if (ent->type == GF_ISOM_BOX_TYPE_TSRO) {						ent->TimeOffset = TimeOffset;			return GF_OK;		}	}	//we have to create a new entry...	ent = (GF_TimeOffHintEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TSRO);	ent->TimeOffset = TimeOffset;	return gf_list_add(hdesc->HintDataTable, ent);}//sets the RTP SequenceNumber Offset that the server will add to the packets//if not set, the server adds a random offsetGF_Err gf_isom_rtp_set_time_sequence_offset(GF_ISOFile *the_file, u32 trackNumber, u32 HintDescriptionIndex, u32 SequenceNumberOffset){	GF_TrackBox *trak;	GF_HintSampleEntryBox *hdesc;	u32 i, count;	GF_SeqOffHintEntryBox *ent;	trak = gf_isom_get_track_from_file(the_file, trackNumber);	if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM;	//OK, create a new HintSampleDesc	hdesc = (GF_HintSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, HintDescriptionIndex - 1);	count = gf_list_count(hdesc->HintDataTable);	for (i=0; i< count; i++) {		ent = (GF_SeqOffHintEntryBox *)gf_list_get(hdesc->HintDataTable, i);		if (ent->type == GF_ISOM_BOX_TYPE_SNRO) {						ent->SeqOffset = SequenceNumberOffset;			return GF_OK;		}	}	//we have to create a new entry...	ent = (GF_SeqOffHintEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_SNRO);	ent->SeqOffset = SequenceNumberOffset;	return gf_list_add(hdesc->HintDataTable, ent);}//Starts a new sample for the hint track. A sample is just a collection of packets//the transmissionTime is indicated in the media timeScale of the hint trackGF_Err gf_isom_begin_hint_sample(GF_ISOFile *the_file, u32 trackNumber, u32 HintDescriptionIndex, u32 TransmissionTime){	GF_TrackBox *trak;	u32 descIndex, dataRefIndex;	GF_HintSample *samp;	GF_HintSampleEntryBox *entry;	GF_Err e;	trak = gf_isom_get_track_from_file(the_file, trackNumber);	if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM;	//assert we're increasing the timing...	if (trak->Media->information->sampleTable->TimeToSample->w_LastDTS > TransmissionTime) return GF_BAD_PARAM;	//store the descIndex for this sample	descIndex = HintDescriptionIndex;	if (!HintDescriptionIndex) {		descIndex = trak->Media->information->sampleTable->currentEntryIndex;	}	e = Media_GetSampleDesc(trak->Media, descIndex, (GF_SampleEntryBox **) &entry, &dataRefIndex);	if (e) return e;	if (!entry || !dataRefIndex) return GF_BAD_PARAM;	//set the current to this one if no packet is used	if (entry->hint_sample) return GF_BAD_PARAM;	trak->Media->information->sampleTable->currentEntryIndex = descIndex;	//create a new sample based on the protocol type of the hint description entry

⌨️ 快捷键说明

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