Ejemplo n.º 1
0
//adds a chunk of data (max 14 bytes) in the packet that is directly copied 
//while streaming
M4Err M4H_AddDirectData(M4File *the_file, u32 trackNumber, char *data, u32 dataLength, u8 AtBegin)
{
	TrackAtom *trak;
	HintSampleEntryAtom *entry;
	u32 count;
	HintPacket *pck;
	ImmediateDTE *dte;
	M4Err e;
	u32 offset = 0;

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak) || (dataLength > 14)) return M4BadParam;

	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (SampleEntryAtom **) &entry, &count);
	if (e) return e;
	if (!entry->w_sample) return M4BadParam;
	count = ChainGetCount(entry->w_sample->packetTable);
	if (!count) return M4BadParam;
	pck = ChainGetEntry(entry->w_sample->packetTable, count - 1);

	dte = (ImmediateDTE *) NewDTE(1);
	memcpy(dte->data, data + offset, dataLength);
	dte->dataLength = dataLength;
	return AddDTE_HintPacket(entry->w_sample->HintType, pck, (GenericDTE *)dte, AtBegin);
}
Ejemplo n.º 2
0
//adds a chunk of data (max 14 bytes) in the packet that is directly copied 
//while streaming
GF_Err gf_isom_hint_direct_data(GF_ISOFile *the_file, u32 trackNumber, char *data, u32 dataLength, u8 AtBegin)
{
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;
	u32 count;
	GF_HintPacket *pck;
	GF_ImmediateDTE *dte;
	GF_Err e;
	u32 offset = 0;

	if (!dataLength) return GF_OK;
	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak) || (dataLength > 14)) return GF_BAD_PARAM;

	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &count);
	if (e) return e;
	if (!entry->hint_sample) return GF_BAD_PARAM;
	count = gf_list_count(entry->hint_sample->packetTable);
	if (!count) return GF_BAD_PARAM;
	pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, count - 1);

	dte = (GF_ImmediateDTE *) NewDTE(1);
	memcpy(dte->data, data + offset, dataLength);
	dte->dataLength = dataLength;
	return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin);
}
Ejemplo n.º 3
0
Bool CheckHintFormat(TrackAtom *trak, u32 HintType)
{
	HintMediaHeaderAtom *hmhd;
	if (!IsHintTrack(trak)) return 0;
	hmhd = (HintMediaHeaderAtom *)trak->Media->information->InfoHeader;
	if (hmhd->subType != HintType) return 0;
	return 1;
}
Ejemplo n.º 4
0
//to use with internally supported protocols
GF_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);
}
Ejemplo n.º 5
0
//stores the hint sample in the file
//set IsRandomAccessPoint if you want to indicate that this is a random access point 
//in the stream
M4Err M4H_EndHintSample(M4File *the_file, u32 trackNumber, u8 IsRandomAccessPoint)
{
	TrackAtom *trak;
	HintSampleEntryAtom *entry;
	u32 dataRefIndex;
	M4Err e;
	BitStream *bs;
	M4Sample *samp;

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return M4BadParam;

	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (SampleEntryAtom **) &entry, &dataRefIndex);
	if (e) return e;
	if (!entry->w_sample) return M4BadParam;

	//first of all, we need to adjust the offset for data referenced IN THIS hint sample
	//and get some PckSize
	e = AdjustHintInfo(entry, trak->Media->information->sampleTable->SampleSize->sampleCount + 1);
	if (e) return e;	
	
	//ok, let's write the sample
	bs = NewBitStream(NULL, 0, BS_WRITE);
	e = Write_HintSample(entry->w_sample, bs);
	if (e) {
		DeleteBitStream(bs);
		return e;
	}
	BS_CutBuffer(bs);

	samp = M4_NewSample();
	samp->CTS_Offset = 0;
	samp->IsRAP = IsRandomAccessPoint;
	samp->DTS = entry->w_sample->TransmissionTime;
	//get the sample
	BS_GetContent(bs, (unsigned char **) &samp->data, &samp->dataLength);
	DeleteBitStream(bs);

	//finally add the sample 
	e = M4_AddSample(the_file, trackNumber, trak->Media->information->sampleTable->currentEntryIndex, samp);
	M4_DeleteSample(&samp);

	//and delete the sample in our entry ...
	Del_HintSample(entry->w_sample);
	entry->w_sample = NULL;
	return e;
}
Ejemplo n.º 6
0
//to use with internally supported protocols
M4Err M4H_NewHintDescription(M4File *the_file, u32 trackNumber, s32 HintTrackVersion, s32 LastCompatibleVersion, u8 Rely, u32 *HintDescriptionIndex)
{
	M4Err e;
	u32 drefIndex;
	TrackAtom *trak;
	HintSampleEntryAtom *hdesc;
	RelyHintEntry *relyA;

	M4Err stsd_AddAtom(SampleDescriptionAtom *ptr, Atom *a);

	trak = GetTrackFromFile(the_file, trackNumber);
	*HintDescriptionIndex = 0;
	if (!trak || !IsHintTrack(trak)) return M4BadParam;

	//OK, create a new HintSampleDesc
	hdesc = (HintSampleEntryAtom *) CreateAtom(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_AddAtom(trak->Media->information->sampleTable->SampleDescription, (Atom *) hdesc);
	if (e) return e;
	*HintDescriptionIndex = ChainGetCount(trak->Media->information->sampleTable->SampleDescription->atomList);

	//RTP needs a default timeScale... use the media one.
	if (CheckHintFormat(trak, M4_Hint_RTP)) {
		e = M4H_RTP_SetTimeScale(the_file, trackNumber, *HintDescriptionIndex, trak->Media->mediaHeader->timeScale);
		if (e) return e;
	}
	if (!Rely) return M4OK;

	//we need a rely atom (common to all protocols)
	relyA = (RelyHintEntry *) CreateAtom(relyHintEntryType);
	if (Rely == 1) {
		relyA->prefered = 1;
	} else {
		relyA->required = 1;
	}
	return ChainAddEntry(hdesc->HintDataTable, relyA);
}
Ejemplo n.º 7
0
//stores the hint sample in the file
//set IsRandomAccessPoint if you want to indicate that this is a random access point 
//in the stream
GF_Err gf_isom_end_hint_sample(GF_ISOFile *the_file, u32 trackNumber, u8 IsRandomAccessPoint)
{
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;
	u32 dataRefIndex;
	GF_Err e;
	GF_BitStream *bs;
	GF_ISOSample *samp;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM;

	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &dataRefIndex);
	if (e) return e;
	if (!entry->hint_sample) return GF_BAD_PARAM;

	//first of all, we need to adjust the offset for data referenced IN THIS hint sample
	//and get some PckSize
	e = AdjustHintInfo(entry, trak->Media->information->sampleTable->SampleSize->sampleCount + 1);
	if (e) return e;	
	
	//ok, let's write the sample
	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
	e = gf_isom_hint_sample_write(entry->hint_sample, bs);
	if (e) {
		gf_bs_del(bs);
		return e;
	}
	samp = gf_isom_sample_new();
	samp->CTS_Offset = 0;
	samp->IsRAP = IsRandomAccessPoint;
	samp->DTS = entry->hint_sample->TransmissionTime;
	//get the sample
	gf_bs_get_content(bs, &samp->data, &samp->dataLength);
	gf_bs_del(bs);

	//finally add the sample 
	e = gf_isom_add_sample(the_file, trackNumber, trak->Media->information->sampleTable->currentEntryIndex, samp);
	gf_isom_sample_del(&samp);

	//and delete the sample in our entry ...
	gf_isom_hint_sample_del(entry->hint_sample);
	entry->hint_sample = NULL;
	return e;
}
Ejemplo n.º 8
0
M4Err M4H_AddStreamDescriptionData(M4File *the_file, u32 trackNumber, u32 SourceTrackID, u32 StreamDescriptionIndex, u16 DataLength, u32 offsetInDescription, u8 AtBegin)
{
	TrackAtom *trak;
	HintSampleEntryAtom *entry;
	u32 count;
	u16 refIndex;
	HintPacket *pck;
	StreamDescDTE *dte;
	M4Err e;
	TrackReferenceTypeAtom *hint;

	M4Err reftype_AddRefTrack(TrackReferenceTypeAtom *ref, u32 trackID, u16 *outRefIndex);

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return M4BadParam;

	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (SampleEntryAtom **) &entry, &count);
	if (e) return e;
	if (!entry->w_sample) return M4BadParam;
	count = ChainGetCount(entry->w_sample->packetTable);
	if (!count) return M4BadParam;
	pck = ChainGetEntry(entry->w_sample->packetTable, count - 1);

	dte = (StreamDescDTE *) NewDTE(3);
	dte->byteOffset = offsetInDescription;
	dte->dataLength = DataLength;
	dte->streamDescIndex = StreamDescriptionIndex;
	if (SourceTrackID == trak->Header->trackID) {
		dte->trackRefIndex = -1;
	} else {
		//get (or set) the track reference index 
		e = Track_FindRef(trak, M4_HintTrack_Ref, &hint);
		if (e) return e;
		e = reftype_AddRefTrack(hint, SourceTrackID, &refIndex);
		if (e) return e;
		//WARNING: IN QT, MUST BE 0-based !!!
		dte->trackRefIndex = (u8) (refIndex - 1);
	}
	return AddDTE_HintPacket(entry->w_sample->HintType, pck, (GenericDTE *)dte, AtBegin);
}
Ejemplo n.º 9
0
//adds a blank chunk of data in the sample that is skipped while streaming
GF_Err gf_isom_hint_blank_data(GF_ISOFile *the_file, u32 trackNumber, u8 AtBegin)
{
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;
	u32 count;
	GF_HintPacket *pck;
	GF_EmptyDTE *dte;
	GF_Err e;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM;

	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &count);
	if (e) return e;
	if (!entry->hint_sample) return GF_BAD_PARAM;
	count = gf_list_count(entry->hint_sample->packetTable);
	if (!count) return GF_BAD_PARAM;
	pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, count - 1);

	dte = (GF_EmptyDTE *) NewDTE(0);
	return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin);
}
Ejemplo n.º 10
0
//adds a blank chunk of data in the sample that is skipped while streaming
M4Err M4H_AddBlankData(M4File *the_file, u32 trackNumber, u8 AtBegin)
{
	TrackAtom *trak;
	HintSampleEntryAtom *entry;
	u32 count;
	HintPacket *pck;
	EmptyDTE *dte;
	M4Err e;

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return M4BadParam;

	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (SampleEntryAtom **) &entry, &count);
	if (e) return e;
	if (!entry->w_sample) return M4BadParam;
	count = ChainGetCount(entry->w_sample->packetTable);
	if (!count) return M4BadParam;
	pck = ChainGetEntry(entry->w_sample->packetTable, count - 1);

	dte = (EmptyDTE *) NewDTE(0);
	return AddDTE_HintPacket(entry->w_sample->HintType, pck, (GenericDTE *)dte, AtBegin);
}
Ejemplo n.º 11
0
GF_Err gf_isom_hint_sample_description_data(GF_ISOFile *the_file, u32 trackNumber, u32 SourceTrackID, u32 StreamDescriptionIndex, u16 DataLength, u32 offsetInDescription, u8 AtBegin)
{
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;
	u32 count;
	u16 refIndex;
	GF_HintPacket *pck;
	GF_StreamDescDTE *dte;
	GF_Err e;
	GF_TrackReferenceTypeBox *hint;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM;

	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &count);
	if (e) return e;
	if (!entry->hint_sample) return GF_BAD_PARAM;
	count = gf_list_count(entry->hint_sample->packetTable);
	if (!count) return GF_BAD_PARAM;
	pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, count - 1);

	dte = (GF_StreamDescDTE *) NewDTE(3);
	dte->byteOffset = offsetInDescription;
	dte->dataLength = DataLength;
	dte->streamDescIndex = StreamDescriptionIndex;
	if (SourceTrackID == trak->Header->trackID) {
		dte->trackRefIndex = (s8) -1;
	} else {
		//get (or set) the track reference index 
		e = Track_FindRef(trak, GF_ISOM_REF_HINT, &hint);
		if (e) return e;
		e = reftype_AddRefTrack(hint, SourceTrackID, &refIndex);
		if (e) return e;
		//WARNING: IN QT, MUST BE 0-based !!!
		dte->trackRefIndex = (u8) (refIndex - 1);
	}
	return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin);
}
Ejemplo n.º 12
0
//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 track
GF_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
	samp = gf_isom_hint_sample_new(entry->type);
	if (!samp) return GF_NOT_SUPPORTED;

	//OK, let's store the time of this sample
	samp->TransmissionTime = TransmissionTime;
	//OK, set our sample in the entry...
	entry->hint_sample = samp;
	return GF_OK;
}
Ejemplo n.º 13
0
//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 track
M4Err M4H_BeginHintSample(M4File *the_file, u32 trackNumber, u32 HintDescriptionIndex, u32 TransmissionTime)
{
	TrackAtom *trak;
	u32 descIndex, dataRefIndex;
	HintSample *samp;
	HintSampleEntryAtom *entry;
	M4Err e;

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return M4BadParam;

	//assert we're increasing the timing...
	if (trak->Media->information->sampleTable->TimeToSample->w_LastDTS > TransmissionTime) return M4BadParam;

	//store the descIndex for this sample
	descIndex = HintDescriptionIndex;
	if (!HintDescriptionIndex) {
		descIndex = trak->Media->information->sampleTable->currentEntryIndex;
	}
	e = Media_GetSampleDesc(trak->Media, descIndex, (SampleEntryAtom **) &entry, &dataRefIndex);
	if (e) return e;
	if (!entry || !dataRefIndex) return M4BadParam;
	//set the current to this one if no packet is used
	if (entry->w_sample) return M4BadParam;
	trak->Media->information->sampleTable->currentEntryIndex = descIndex;

	//create a new sample based on the protocol type of the hint description entry
	samp = New_HintSample(entry->type);
	if (!samp) return M4NotSupported;

	//OK, let's store the time of this sample
	samp->TransmissionTime = TransmissionTime;
	//OK, set our sample in the entry...
	entry->w_sample = samp;
	return M4OK;
}
Ejemplo n.º 14
0
M4Err M4H_AddSampleData(M4File *the_file, u32 trackNumber, u32 SourceTrackID, u32 SampleNumber, u16 DataLength, u32 offsetInSample, char *extra_data, u8 AtBegin)
{
	TrackAtom *trak;
	HintSampleEntryAtom *entry;
	u32 count;
	u16 refIndex;
	HintPacket *pck;
	SampleDTE *dte;
	M4Err e;
	TrackReferenceTypeAtom *hint;

	M4Err reftype_AddRefTrack(TrackReferenceTypeAtom *ref, u32 trackID, u16 *outRefIndex);

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return M4BadParam;


	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (SampleEntryAtom **) &entry, &count);
	if (e) return e;
	if (!entry->w_sample) return M4BadParam;
	count = ChainGetCount(entry->w_sample->packetTable);
	if (!count) return M4BadParam;
	pck = ChainGetEntry(entry->w_sample->packetTable, count - 1);

	dte = (SampleDTE *) NewDTE(2);

	dte->dataLength = DataLength;
	dte->sampleNumber = SampleNumber;
	dte->byteOffset = offsetInSample;

	//we're getting data from another track
	if (SourceTrackID != trak->Header->trackID) {
		//get (or set) the track reference index 
		e = Track_FindRef(trak, M4_HintTrack_Ref, &hint);
		if (e) return e;
		e = reftype_AddRefTrack(hint, SourceTrackID, &refIndex);
		if (e) return e;
		//WARNING: IN QT, MUST BE 0-based !!!
		dte->trackRefIndex = (u8) (refIndex - 1);
	} else {
		//we're in the hint track
		dte->trackRefIndex = -1;
		//basic check...
		if (SampleNumber > trak->Media->information->sampleTable->SampleSize->sampleCount + 1) {
			DelDTE((GenericDTE *)dte);
			return M4BadParam;
		}

		//are we in the current sample ??
		if (!SampleNumber || (SampleNumber == trak->Media->information->sampleTable->SampleSize->sampleCount + 1)) {
			//we adding some stuff in the current sample ...
			dte->byteOffset += entry->w_sample->dataLength;
			if (entry->w_sample->AdditionalData) {
				entry->w_sample->AdditionalData = realloc(entry->w_sample->AdditionalData, sizeof(char) * (entry->w_sample->dataLength + DataLength));
				memcpy(entry->w_sample->AdditionalData + entry->w_sample->dataLength, extra_data, DataLength);
				entry->w_sample->dataLength += DataLength;
			} else {
				entry->w_sample->AdditionalData = malloc(sizeof(char) * DataLength);
				memcpy(entry->w_sample->AdditionalData, extra_data, DataLength);
				entry->w_sample->dataLength = DataLength;
			}
			//and set the sample number ...
			dte->sampleNumber = trak->Media->information->sampleTable->SampleSize->sampleCount + 1;
		}
	}
	//OK, add the entry
	return AddDTE_HintPacket(entry->w_sample->HintType, pck, (GenericDTE *)dte, AtBegin);
}
Ejemplo n.º 15
0
GF_Err gf_isom_hint_sample_data(GF_ISOFile *the_file, u32 trackNumber, u32 SourceTrackID, u32 SampleNumber, u16 DataLength, u32 offsetInSample, char *extra_data, u8 AtBegin)
{
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;
	u32 count;
	u16 refIndex;
	GF_HintPacket *pck;
	GF_SampleDTE *dte;
	GF_Err e;
	GF_TrackReferenceTypeBox *hint;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM;


	e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &count);
	if (e) return e;
	if (!entry->hint_sample) return GF_BAD_PARAM;
	count = gf_list_count(entry->hint_sample->packetTable);
	if (!count) return GF_BAD_PARAM;
	pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, count - 1);

	dte = (GF_SampleDTE *) NewDTE(2);

	dte->dataLength = DataLength;
	dte->sampleNumber = SampleNumber;
	dte->byteOffset = offsetInSample;

	//we're getting data from another track
	if (SourceTrackID != trak->Header->trackID) {
		//get (or set) the track reference index 
		e = Track_FindRef(trak, GF_ISOM_REF_HINT, &hint);
		if (e) return e;
		e = reftype_AddRefTrack(hint, SourceTrackID, &refIndex);
		if (e) return e;
		//WARNING: IN QT, MUST BE 0-based !!!
		dte->trackRefIndex = (u8) (refIndex - 1);
	} else {
		//we're in the hint track
		dte->trackRefIndex = (s8) -1;
		//basic check...
		if (SampleNumber > trak->Media->information->sampleTable->SampleSize->sampleCount + 1) {
			DelDTE((GF_GenericDTE *)dte);
			return GF_BAD_PARAM;
		}

		//are we in the current sample ??
		if (!SampleNumber || (SampleNumber == trak->Media->information->sampleTable->SampleSize->sampleCount + 1)) {
			//we adding some stuff in the current sample ...
			dte->byteOffset += entry->hint_sample->dataLength;
			entry->hint_sample->AdditionalData = (char*)gf_realloc(entry->hint_sample->AdditionalData, sizeof(char) * (entry->hint_sample->dataLength + DataLength));
			if (AtBegin) {
				if (entry->hint_sample->dataLength)
					memmove(entry->hint_sample->AdditionalData + DataLength, entry->hint_sample->AdditionalData, entry->hint_sample->dataLength);
				memcpy(entry->hint_sample->AdditionalData, extra_data, DataLength);
				/*offset existing DTE*/
				gf_isom_hint_pck_offset(entry->hint_sample->HintType, pck, DataLength, SampleNumber);
			} else {
				memcpy(entry->hint_sample->AdditionalData + entry->hint_sample->dataLength, extra_data, DataLength);
			}
			entry->hint_sample->dataLength += DataLength;
			//and set the sample number ...
			dte->sampleNumber = trak->Media->information->sampleTable->SampleSize->sampleCount + 1;
		}
	}
	//OK, add the entry
	return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin);
}
Ejemplo n.º 16
0
Bool CheckHintFormat(GF_TrackBox *trak, u32 HintType)
{
	if (!IsHintTrack(trak)) return 0;
	if (GetHintFormat(trak) != HintType) return 0;
	return 1;
}
Ejemplo n.º 17
0
M4Err M4H_SetupHintTrack(M4File *the_file, u32 trackNumber, u32 HintType)
{
	M4Err e;
	TrackAtom *trak;
	TrackReferenceAtom *tref;
	TrackReferenceTypeAtom *dpnd;
	HintMediaHeaderAtom *hmhd;
	//UDTA related ...
	UserDataAtom *udta;

	M4Err tref_AddAtom(TrackReferenceAtom *ptr, Atom *a);
	M4Err trak_AddAtom(TrackAtom *ptr, Atom *a);
	M4Err moov_AddAtom(MovieAtom *ptr, Atom *a);
	M4Err udta_AddAtom(UserDataAtom *ptr, Atom *a);

	//what do we support
	switch (HintType) {
	case M4_Hint_RTP:
		break;
	default:
		return M4NotSupported;
	}

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak) return M4_GetLastError(the_file);
	if (((M4Movie *)the_file)->openMode != M4_OPEN_EDIT) return M4InvalidMP4Mode;

	//check we have a hint ...
	if ( !IsHintTrack(trak)) {
		return M4BadParam;
	}
	hmhd = (HintMediaHeaderAtom *)trak->Media->information->InfoHeader;
	//make sure the subtype was not already defined
	if (hmhd->subType) return M4HintPresent;
	//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 = (TrackReferenceAtom *) CreateAtom(TrackReferenceAtomType);
			e = trak_AddAtom(trak, (Atom *)tref);
			if (e) return e;
		}
	}
	tref = trak->References;

	//do we have a hint reference on this trak ???
	e = Track_FindRef(trak, HintTrackReferenceAtomType, &dpnd);
	if (e) return e;
	//if yes, return false (existing hint track...)
	if (dpnd) return M4HintPresent;

	//create our dep
	dpnd = (TrackReferenceTypeAtom *) CreateAtom(HintTrackReferenceAtomType);
	e = tref_AddAtom(tref, (Atom *) dpnd);
	if (e) return e;

	//for RTP, we need to do some UDTA-related stuff...
	if (HintType != M4_Hint_RTP) return M4OK;

	if (!trak->udta) {
		//create one
		udta = (UserDataAtom *) CreateAtom(UserDataAtomType);
		e = trak_AddAtom(trak, (Atom *) udta);
		if (e) return e;
	}
	udta = trak->udta;
	//end-of-udta marker for Darwin...
//	if (!udta->voidAtom) {
//		e = udta_AddAtom(udta, CreateAtom(VoidAtomType));
//		if (e) return e;
//	}

	//HNTI
	e = udta_AddAtom(udta, CreateAtom(HintTrackInfoAtomType));
	if (e) return e;

/*
	//NAME
	e = udta_AddAtom(udta, CreateAtom(nameAtomType));
	if (e) return e;
	//HINF
	return udta_AddAtom(udta, CreateAtom(HintInfoAtomType));
*/
	return M4OK;
}
Ejemplo n.º 18
0
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_REFT);
	dpnd->reference_type = 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;
}
Ejemplo n.º 19
0
Bool CheckHintFormat(GF_TrackBox *trak, u32 HintType)
{
	if (!IsHintTrack(trak)) return GF_FALSE;
	if (GetHintFormat(trak) != HintType) return GF_FALSE;
	return GF_TRUE;
}