Пример #1
0
M4Err M4H_RTP_NewPacket(M4File *the_file, u32 trackNumber, 
						   s32 relativeTime, 
						   u8 PackingBit, 
						   u8 eXtensionBit, 
						   u8 MarkerBit, 
						   u8 PayloadType, 
						   u8 B_frame, 
						   u8 IsRepeatedPacket, 
						   u16 SequenceNumber)
{
	TrackAtom *trak;
	HintSampleEntryAtom *entry;
	RTPPacket *pck;
	u32 dataRefIndex;
	M4Err e;

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !CheckHintFormat(trak, M4_Hint_RTP)) 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;

	pck = (RTPPacket *) New_HintPacket(entry->w_sample->HintType);

	pck->P_bit = PackingBit ? 1 : 0;
	pck->X_bit = eXtensionBit ? 1 : 0;
	pck->M_bit = MarkerBit ? 1 : 0;
	pck->payloadType = PayloadType;
	pck->SequenceNumber = SequenceNumber;
	pck->B_bit = B_frame ? 1 : 0;
	pck->R_bit = IsRepeatedPacket ? 1 : 0;
	pck->relativeTransTime = relativeTime;
	return ChainAddEntry(entry->w_sample->packetTable, pck);
}
Пример #2
0
//set the time offset of this packet. This enables packets to be placed in the hint track 
//in decoding order, but have their presentation time-stamp in the transmitted 
//packet be in a different order. Typically used for MPEG video with B-frames
GF_Err gf_isom_rtp_packet_set_offset(GF_ISOFile *the_file, u32 trackNumber, s32 timeOffset)
{
	GF_RTPOBox *rtpo;
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;
	GF_RTPPacket *pck;
	u32 dataRefIndex, i;
	GF_Err e;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) 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;

	pck = (GF_RTPPacket *)gf_list_get(entry->hint_sample->packetTable, gf_list_count(entry->hint_sample->packetTable) - 1);
	if (!pck) return GF_BAD_PARAM;

	//look in the TLV
	i=0;
	while ((rtpo = (GF_RTPOBox *)gf_list_enum(pck->TLV, &i))) {
		if (rtpo->type == GF_ISOM_BOX_TYPE_RTPO) {
			rtpo->timeOffset = timeOffset;
			return GF_OK;
		}
	}
	//not found, add it
	rtpo = (GF_RTPOBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_RTPO);
	rtpo->timeOffset = timeOffset;

	return gf_list_add(pck->TLV, rtpo);
}
Пример #3
0
//set the time offset of this packet. This enables packets to be placed in the hint track 
//in decoding order, but have their presentation time-stamp in the transmitted 
//packet be in a different order. Typically used for MPEG video with B-frames
M4Err M4H_RTP_SetPacketTimeOffset(M4File *the_file, u32 trackNumber, s32 timeOffset)
{
	RtpoAtom *rtpo;
	TrackAtom *trak;
	HintSampleEntryAtom *entry;
	RTPPacket *pck;
	u32 dataRefIndex, i;
	M4Err e;

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !CheckHintFormat(trak, M4_Hint_RTP)) 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;

	pck = ChainGetEntry(entry->w_sample->packetTable, ChainGetCount(entry->w_sample->packetTable) - 1);
	if (!pck) return M4BadParam;

	//look in the TLV
	for (i=0; i<ChainGetCount(pck->TLV); i++) {
		rtpo = ChainGetEntry(pck->TLV, i);
		if (rtpo->type == rtpoAtomType) {
			rtpo->timeOffset = timeOffset;
			return M4OK;
		}
	}
	//not found, add it
	rtpo = (RtpoAtom *) CreateAtom(rtpoAtomType);
	rtpo->timeOffset = timeOffset;

	return ChainAddEntry(pck->TLV, rtpo);
}
Пример #4
0
M4Err M4H_RTP_SetPacketFlags(M4File *the_file, u32 trackNumber,
						   u8 PackingBit, 
						   u8 eXtensionBit, 
						   u8 MarkerBit, 
						   u8 B_frame, 
						   u8 IsRepeatedPacket)
{
	TrackAtom *trak;
	HintSampleEntryAtom *entry;
	RTPPacket *pck;
	u32 dataRefIndex, ind;
	M4Err e;

	trak = GetTrackFromFile(the_file, trackNumber);
	if (!trak || !CheckHintFormat(trak, M4_Hint_RTP)) 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;

	ind = ChainGetCount(entry->w_sample->packetTable);
	if (!ind) return M4BadParam;
	pck = ChainGetEntry(entry->w_sample->packetTable, ind-1);

	pck->P_bit = PackingBit ? 1 : 0;
	pck->X_bit = eXtensionBit ? 1 : 0;
	pck->M_bit = MarkerBit ? 1 : 0;
	pck->B_bit = B_frame ? 1 : 0;
	pck->R_bit = IsRepeatedPacket ? 1 : 0;
	return M4OK;
}
Пример #5
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);
}
Пример #6
0
M4Err Media_UpdateSampleReference(MediaAtom *mdia, u32 sampleNumber, M4Sample *sample, u64 data_offset)
{
	M4Err e;
	u32 drefIndex, DTS, chunkNum, descIndex;
	u64 off;
	u8 isEdited;
	DataEntryURLAtom *Dentry;
	SampleTableAtom *stbl;
	M4Err stbl_AddAtom(SampleTableAtom *ptr, Atom *a);

	if (!mdia) return M4BadParam;
	stbl = mdia->information->sampleTable;

	//check we have the sampe dts
	e = stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);
	if (e) return e;
	if (DTS != sample->DTS) return M4BadParam;

	//get our infos
	stbl_GetSampleInfos(stbl, sampleNumber, &off, &chunkNum, &descIndex, &isEdited);

	//then check the data ref
	e = Media_GetSampleDesc(mdia, descIndex, NULL, &drefIndex);
	if (e) return e;
	Dentry = (DataEntryURLAtom*)ChainGetEntry(mdia->information->dataInformation->dref->atomList, drefIndex - 1);
	if (!Dentry) return M4InvalidMP4File;

	//we only modify self-contained data
	if (Dentry->flags == 1) return M4InvalidMP4Mode;

	//and we don't modify the media data
	return UpdateSample(mdia, sampleNumber, sample->dataLength, sample->CTS_Offset, data_offset, sample->IsRAP);
}
Пример #7
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);
}
Пример #8
0
GF_Err Media_UpdateSampleReference(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSample *sample, u64 data_offset)
{
	GF_Err e;
	u32 drefIndex, chunkNum, descIndex;
	u64 off, DTS;
	u8 isEdited;
	GF_DataEntryURLBox *Dentry;
	GF_SampleTableBox *stbl;

	if (!mdia) return GF_BAD_PARAM;
	stbl = mdia->information->sampleTable;

	//check we have the sampe dts
	e = stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);
	if (e) return e;
	if (DTS != sample->DTS) return GF_BAD_PARAM;

	//get our infos
	stbl_GetSampleInfos(stbl, sampleNumber, &off, &chunkNum, &descIndex, &isEdited);

	//then check the data ref
	e = Media_GetSampleDesc(mdia, descIndex, NULL, &drefIndex);
	if (e) return e;
	Dentry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->other_boxes, drefIndex - 1);
	if (!Dentry) return GF_ISOM_INVALID_FILE;

	//we only modify self-contained data
	if (Dentry->flags == 1) return GF_ISOM_INVALID_MODE;

	//and we don't modify the media data
	return UpdateSample(mdia, sampleNumber, sample->dataLength, sample->CTS_Offset, data_offset, sample->IsRAP);
}
Пример #9
0
GF_Err gf_isom_change_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, char *scheme_uri, char *kms_uri)
{
	GF_TrackBox *trak;
	GF_Err e;
	GF_SampleEntryBox *sea;

	e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
	if (e) return e;
	
	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !trak->Media || !StreamDescriptionIndex) return GF_BAD_PARAM;

	Media_GetSampleDesc(trak->Media, StreamDescriptionIndex, &sea, NULL);
	/*non-encrypted or non-ISMA*/
	if (!sea || !sea->protection_info) return GF_BAD_PARAM;
	if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM;

	if (scheme_uri) {
		free(sea->protection_info->scheme_type->URI);
		sea->protection_info->scheme_type->URI = strdup(scheme_uri);
	}
	if (kms_uri) {
		free(sea->protection_info->info->ikms->URI);
		sea->protection_info->info->ikms->URI = strdup(kms_uri);
	}
	return GF_OK;
}
Пример #10
0
GF_Err gf_isom_rtp_packet_set_flags(GF_ISOFile *the_file, u32 trackNumber,
						   u8 PackingBit, 
						   u8 eXtensionBit, 
						   u8 MarkerBit, 
						   u8 disposable_packet, 
						   u8 IsRepeatedPacket)
{
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;
	GF_RTPPacket *pck;
	u32 dataRefIndex, ind;
	GF_Err e;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) 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;

	ind = gf_list_count(entry->hint_sample->packetTable);
	if (!ind) return GF_BAD_PARAM;
	pck = (GF_RTPPacket *)gf_list_get(entry->hint_sample->packetTable, ind-1);

	pck->P_bit = PackingBit ? 1 : 0;
	pck->X_bit = eXtensionBit ? 1 : 0;
	pck->M_bit = MarkerBit ? 1 : 0;
	pck->B_bit = disposable_packet ? 1 : 0;
	pck->R_bit = IsRepeatedPacket ? 1 : 0;
	return GF_OK;
}
Пример #11
0
GF_Err gf_isom_rtp_packet_begin(GF_ISOFile *the_file, u32 trackNumber, 
						   s32 relativeTime, 
						   u8 PackingBit, 
						   u8 eXtensionBit, 
						   u8 MarkerBit, 
						   u8 PayloadType, 
						   u8 B_frame, 
						   u8 IsRepeatedPacket, 
						   u16 SequenceNumber)
{
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;
	GF_RTPPacket *pck;
	u32 dataRefIndex;
	GF_Err e;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) 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;

	pck = (GF_RTPPacket *) gf_isom_hint_pck_new(entry->hint_sample->HintType);

	pck->P_bit = PackingBit ? 1 : 0;
	pck->X_bit = eXtensionBit ? 1 : 0;
	pck->M_bit = MarkerBit ? 1 : 0;
	pck->payloadType = PayloadType;
	pck->SequenceNumber = SequenceNumber;
	pck->B_bit = B_frame ? 1 : 0;
	pck->R_bit = IsRepeatedPacket ? 1 : 0;
	pck->relativeTransTime = relativeTime;
	return gf_list_add(entry->hint_sample->packetTable, pck);
}
Пример #12
0
GF_EXPORT
GF_Err gf_isom_reset_hint_reader(GF_ISOFile *the_file, u32 trackNumber, u32 sample_start, u32 ts_offset, u32 sn_offset, u32 ssrc)
{
	GF_Err e;
	GF_TrackBox *trak;
	GF_HintSampleEntryBox *entry;

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

	if (!sample_start) return GF_BAD_PARAM;
	if (sample_start>=trak->Media->information->sampleTable->SampleSize->sampleCount) return GF_BAD_PARAM;

	e = Media_GetSampleDesc(trak->Media, 1, (GF_SampleEntryBox **) &entry, NULL);
	if (e) return e;
	switch (entry->type) {
	case GF_ISOM_BOX_TYPE_RTP_STSD:
		break;
	default:
		return GF_NOT_SUPPORTED;
	}

	entry->hint_ref = NULL;
	e = Track_FindRef(trak, GF_ISOM_REF_HINT, &entry->hint_ref);
	if (e) return e;

	entry->cur_sample = sample_start;
	entry->pck_sn = 1 + sn_offset;
	entry->ssrc = ssrc;
	entry->ts_offset = ts_offset;
	if (entry->hint_sample) gf_isom_hint_sample_del(entry->hint_sample);
	entry->hint_sample = NULL;
	return GF_OK;
}
Пример #13
0
GF_EXPORT
u32 gf_isom_is_media_encrypted(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
{
	GF_TrackBox *trak;
	GF_SampleEntryBox *sea;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak) return 0;

	Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
	/*non-encrypted or non-ISMA*/
	if (!sea || !sea->protection_info || !sea->protection_info->scheme_type) return 0;
	return sea->protection_info->scheme_type->scheme_type;
}
Пример #14
0
Bool Media_IsSelfContained(MediaAtom *mdia, u32 StreamDescIndex)
{
	u32 drefIndex;
	FullAtom *a;
	SampleEntryAtom *se = NULL;

	Media_GetSampleDesc(mdia, StreamDescIndex, &se, &drefIndex);
	if (!drefIndex) return 0;
	a = (FullAtom*)ChainGetEntry(mdia->information->dataInformation->dref->atomList, drefIndex - 1);
	if (a->flags & 1) return 1;
	/*QT specific*/
	if (a->type == FOUR_CHAR_INT('a', 'l', 'i', 's')) return 1;
	return 0;
}
Пример #15
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;
}
Пример #16
0
GF_Err Media_UpdateSample(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSample *sample, Bool data_only)
{
	GF_Err e;
	u32 drefIndex, chunkNum, descIndex;
	u64 newOffset, DTS;
	u8 isEdited;
	GF_DataEntryURLBox *Dentry;
	GF_SampleTableBox *stbl;

	if (!mdia || !sample || !sampleNumber || !mdia->mediaTrack->moov->mov->editFileMap)
		return GF_BAD_PARAM;
	
	stbl = mdia->information->sampleTable;

	if (!data_only) {
		//check we have the sampe dts
		e = stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);
		if (e) return e;
		if (DTS != sample->DTS) return GF_BAD_PARAM;
	}

	//get our infos
	stbl_GetSampleInfos(stbl, sampleNumber, &newOffset, &chunkNum, &descIndex, &isEdited);

	//then check the data ref
	e = Media_GetSampleDesc(mdia, descIndex, NULL, &drefIndex);
	if (e) return e;
	Dentry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->other_boxes, drefIndex - 1);
	if (!Dentry) return GF_ISOM_INVALID_FILE;

	if (Dentry->flags != 1) return GF_BAD_PARAM;

	//MEDIA DATA EDIT: write this new sample to the edit temp file
	newOffset = gf_isom_datamap_get_offset(mdia->mediaTrack->moov->mov->editFileMap);
	if (sample->dataLength) {
		e = gf_isom_datamap_add_data(mdia->mediaTrack->moov->mov->editFileMap, sample->data, sample->dataLength);
		if (e) return e;
	}

	if (data_only) {
		stbl_SetSampleSize(stbl->SampleSize, sampleNumber, sample->dataLength);
		return stbl_SetChunkOffset(mdia, sampleNumber, newOffset);
	}
	return UpdateSample(mdia, sampleNumber, sample->dataLength, sample->CTS_Offset, newOffset, sample->IsRAP);
}
Пример #17
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;
}
Пример #18
0
Bool Media_IsSelfContained(GF_MediaBox *mdia, u32 StreamDescIndex)
{
	u32 drefIndex=0;
	GF_FullBox *a;
	GF_SampleEntryBox *se = NULL;

	Media_GetSampleDesc(mdia, StreamDescIndex, &se, &drefIndex);
	if (!drefIndex) return 0;
	a = (GF_FullBox*)gf_list_get(mdia->information->dataInformation->dref->other_boxes, drefIndex - 1);
	if (!a) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] broken file: Data reference index set to %d but no data reference entry found\n", drefIndex));
		return 0;
	}
	if (a->flags & 1) return 1;
	/*QT specific*/
	if (a->type == GF_4CC('a', 'l', 'i', 's')) return 1;
	return 0;
}
Пример #19
0
/*retrieves ISMACryp info for the given track & SDI*/
GF_EXPORT
GF_Err gf_isom_get_omadrm_info(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex, u32 *outOriginalFormat,
							   u32 *outSchemeType, u32 *outSchemeVersion,
							   const char **outContentID, const char **outRightsIssuerURL, const char **outTextualHeaders, u32 *outTextualHeadersLen, u64 *outPlaintextLength, u32 *outEncryptionType, Bool *outSelectiveEncryption, u32 *outIVLength, u32 *outKeyIndicationLength)
{
	GF_TrackBox *trak;
	GF_SampleEntryBox *sea;
	
	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak) return GF_BAD_PARAM;

	Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
	/*non-encrypted or non-ISMA*/
	if (!sea || !sea->protection_info) return GF_BAD_PARAM;
	if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM;
	if (!sea->protection_info->info || !sea->protection_info->info->okms || !sea->protection_info->info->okms->hdr) return GF_NON_COMPLIANT_BITSTREAM;

	if (outOriginalFormat) {
		*outOriginalFormat = sea->protection_info->original_format->data_format;
		if (IsMP4Description(sea->protection_info->original_format->data_format)) *outOriginalFormat = GF_ISOM_SUBTYPE_MPEG4;
	}
	if (outSchemeType) *outSchemeType = sea->protection_info->scheme_type->scheme_type;
	if (outSchemeVersion) *outSchemeVersion = sea->protection_info->scheme_type->scheme_version;
	if (outContentID) *outContentID = sea->protection_info->info->okms->hdr->ContentID;
	if (outRightsIssuerURL) *outRightsIssuerURL = sea->protection_info->info->okms->hdr->RightsIssuerURL;
	if (outTextualHeaders) {
		*outTextualHeaders = sea->protection_info->info->okms->hdr->TextualHeaders;
		if (outTextualHeadersLen) *outTextualHeadersLen = sea->protection_info->info->okms->hdr->TextualHeadersLen;
	}
	if (outPlaintextLength) *outPlaintextLength = sea->protection_info->info->okms->hdr->PlaintextLength;
	if (outEncryptionType) *outEncryptionType = sea->protection_info->info->okms->hdr->EncryptionMethod;

	if (sea->protection_info->info && sea->protection_info->info->okms  && sea->protection_info->info->okms->fmt) {
		if (outSelectiveEncryption) *outSelectiveEncryption = sea->protection_info->info->okms->fmt->selective_encryption;
		if (outIVLength) *outIVLength = sea->protection_info->info->okms->fmt->IV_length;
		if (outKeyIndicationLength) *outKeyIndicationLength = sea->protection_info->info->okms->fmt->key_indicator_length;
	} else {
		if (outSelectiveEncryption) *outSelectiveEncryption = 0;
		if (outIVLength) *outIVLength = 0;
		if (outKeyIndicationLength) *outKeyIndicationLength = 0;
	}
	return GF_OK;
}
Пример #20
0
GF_EXPORT
GF_Err gf_isom_get_original_format_type(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex, u32 *outOriginalFormat)
{
	GF_TrackBox *trak;
	GF_SampleEntryBox *sea;
	GF_ProtectionInfoBox *sinf;

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

	Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
	if (!sea) return GF_BAD_PARAM;

	sinf = (GF_ProtectionInfoBox*)gf_list_get(sea->protections, 0);
	if (outOriginalFormat && sinf->original_format) {
		*outOriginalFormat = sinf->original_format->data_format;
	}
	return GF_OK;
}
Пример #21
0
static GF_ProtectionInfoBox *gf_isom_get_sinf_entry(GF_TrackBox *trak, u32 sampleDescriptionIndex, u32 scheme_type, GF_SampleEntryBox **out_sea)
{
	u32 i=0;
	GF_SampleEntryBox *sea=NULL;
	GF_ProtectionInfoBox *sinf;

	Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
	if (!sea) return NULL;

	i = 0;
	while ((sinf = (GF_ProtectionInfoBox*)gf_list_enum(sea->protections, &i))) {
		if (sinf->original_format && sinf->scheme_type && sinf->info) {
			if (!scheme_type || (sinf->scheme_type->scheme_type == scheme_type)) {
				if (out_sea)
					*out_sea = sea;
				return sinf;
			}
		}
	}
	return NULL;
}
Пример #22
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);
}
Пример #23
0
M4Err M4_SetExtractionSLConfig(M4File *the_file, u32 trackNumber, u32 StreamDescriptionIndex, SLConfigDescriptor *slConfig)
{
	TrackAtom *trak;
	SampleEntryAtom *entry;
	M4Err e;
	SLConfigDescriptor **slc;

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

	e = Media_GetSampleDesc(trak->Media, StreamDescriptionIndex, &entry, NULL);
	if (e) return e;

	//we must be sure we are not using a remote ESD
	switch (entry->type) {
	case MPEGSampleEntryAtomType:
		if (((MPEGSampleEntryAtom *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return M4BadParam;
		slc = & ((MPEGSampleEntryAtom *)entry)->slc;
		break;
	case MPEGAudioSampleEntryAtomType:
		if (((MPEGAudioSampleEntryAtom *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return M4BadParam;
		slc = & ((MPEGAudioSampleEntryAtom *)entry)->slc;
		break;
	case MPEGVisualSampleEntryAtomType:
		if (((MPEGVisualSampleEntryAtom *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return M4BadParam;
		slc = & ((MPEGVisualSampleEntryAtom *)entry)->slc;
		break;
	default:
		return M4BadParam;
	}

	if (*slc) {
		OD_DeleteDescriptor((Descriptor **)slc);
		*slc = NULL;
	}
	if (!slConfig) return M4OK;
	//finally duplicate the SL
	return OD_DuplicateDescriptor((Descriptor *) slConfig, (Descriptor **) slc);
}
Пример #24
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);
}
Пример #25
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);
}
Пример #26
0
M4Err Media_UpdateSample(MediaAtom *mdia, u32 sampleNumber, M4Sample *sample)
{
	M4Err e;
	u32 drefIndex, chunkNum, descIndex, DTS;
	u64 newOffset;
	u8 isEdited;
	DataEntryURLAtom *Dentry;
	SampleTableAtom *stbl;

	M4Err stbl_AddAtom(SampleTableAtom *ptr, Atom *a);

	if (!mdia || !sample || !sampleNumber || !mdia->mediaTrack->moov->mov->editFileMap)
		return M4BadParam;
	
	stbl = mdia->information->sampleTable;

	//check we have the sampe dts
	e = stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);
	if (e) return e;
	if (DTS != sample->DTS) return M4BadParam;

	//get our infos
	stbl_GetSampleInfos(stbl, sampleNumber, &newOffset, &chunkNum, &descIndex, &isEdited);

	//then check the data ref
	e = Media_GetSampleDesc(mdia, descIndex, NULL, &drefIndex);
	if (e) return e;
	Dentry = (DataEntryURLAtom*)ChainGetEntry(mdia->information->dataInformation->dref->atomList, drefIndex - 1);
	if (!Dentry) return M4InvalidMP4File;

	if (Dentry->flags != 1) return M4BadParam;

	//MEDIA DATA EDIT: write this new sample to the edit temp file
	newOffset = DataMap_GetTotalOffset(mdia->mediaTrack->moov->mov->editFileMap);
	e = DataMap_AddData(mdia->mediaTrack->moov->mov->editFileMap, sample->data, sample->dataLength);
	if (e) return e;

	return UpdateSample(mdia, sampleNumber, sample->dataLength, sample->CTS_Offset, newOffset, sample->IsRAP);
}
Пример #27
0
/*retrieves ISMACryp info for the given track & SDI*/
GF_EXPORT
GF_Err gf_isom_get_ismacryp_info(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex, u32 *outOriginalFormat, u32 *outSchemeType, u32 *outSchemeVersion, const char **outSchemeURI, const char **outKMS_URI, Bool *outSelectiveEncryption, u32 *outIVLength, u32 *outKeyIndicationLength)
{
	GF_TrackBox *trak;
	GF_SampleEntryBox *sea;
	
	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak) return GF_BAD_PARAM;

	Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
	/*non-encrypted or non-ISMA*/
	if (!sea || !sea->protection_info) return GF_BAD_PARAM;
	if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM;

	if (outOriginalFormat) {
		*outOriginalFormat = sea->protection_info->original_format->data_format;
		if (IsMP4Description(sea->protection_info->original_format->data_format)) *outOriginalFormat = GF_ISOM_SUBTYPE_MPEG4;
	}
	if (outSchemeType) *outSchemeType = sea->protection_info->scheme_type->scheme_type;
	if (outSchemeVersion) *outSchemeVersion = sea->protection_info->scheme_type->scheme_version;
	if (outSchemeURI) *outSchemeURI = sea->protection_info->scheme_type->URI;

	if (sea->protection_info->info && sea->protection_info->info->ikms) {
		if (outKMS_URI) *outKMS_URI = sea->protection_info->info->ikms->URI;
	} else {
		if (outKMS_URI) *outKMS_URI = NULL;
	}
	if (sea->protection_info->info && sea->protection_info->info->isfm) {
		if (outSelectiveEncryption) *outSelectiveEncryption = sea->protection_info->info->isfm->selective_encryption;
		if (outIVLength) *outIVLength = sea->protection_info->info->isfm->IV_length;
		if (outKeyIndicationLength) *outKeyIndicationLength = sea->protection_info->info->isfm->key_indicator_length;
	} else {
		if (outSelectiveEncryption) *outSelectiveEncryption = 0;
		if (outIVLength) *outIVLength = 0;
		if (outKeyIndicationLength) *outKeyIndicationLength = 0;
	}
	return GF_OK;
}
Пример #28
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);
}
Пример #29
0
GF_EXPORT
Bool gf_isom_is_omadrm_media(GF_ISOFile *the_file, u32 trackNumber, u32 sampleDescriptionIndex)
{
	GF_TrackBox *trak;
	GF_SampleEntryBox *sea;

	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak) return 0;

	Media_GetSampleDesc(trak->Media, sampleDescriptionIndex, &sea, NULL);
	/*non-encrypted or non-ISMA*/
	if (!sea 
		|| !sea->protection_info 
		|| !sea->protection_info->scheme_type 
		|| (sea->protection_info->scheme_type->scheme_type != GF_4CC('o','d','k','m') )
		|| !sea->protection_info->info
		|| !sea->protection_info->info->okms
		|| !sea->protection_info->info->okms->hdr
		) 
		return 0;

	return 1;
}
Пример #30
0
GF_Err gf_isom_remove_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex)
{
	GF_TrackBox *trak;
	GF_Err e;
	GF_SampleEntryBox *sea;

	e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
	if (e) return e;
	
	trak = gf_isom_get_track_from_file(the_file, trackNumber);
	if (!trak || !trak->Media || !StreamDescriptionIndex) return GF_BAD_PARAM;

	Media_GetSampleDesc(trak->Media, StreamDescriptionIndex, &sea, NULL);
	/*non-encrypted or non-ISMA*/
	if (!sea || !sea->protection_info) return GF_BAD_PARAM;
	if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM;

	sea->type = sea->protection_info->original_format->data_format;
	gf_isom_box_del((GF_Box *)sea->protection_info);
	sea->protection_info = NULL;
	if (sea->type == GF_4CC('2','6','4','b')) sea->type = GF_ISOM_BOX_TYPE_AVC1;
	return GF_OK;
}