Commit message: prevent dref memleak on invalid input (#1183)
CVE: CVE-2018-21017
CWE: CWE-400
Vulnerability description: GPAC 0.7.1 has a memory leak in dinf_Read in isomedia/box_code_base.c.

Project: gpac

GF_Box *clap_New()
{
	ISOM_DECL_BOX_ALLOC(GF_CleanApertureBox, GF_ISOM_BOX_TYPE_CLAP);
	return (GF_Box *)tmp;
}

Project: gpac

GF_Err clap_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s;
	ISOM_DECREASE_SIZE(ptr, 32);
	ptr->cleanApertureWidthN = gf_bs_read_u32(bs);
	ptr->cleanApertureWidthD = gf_bs_read_u32(bs);
	ptr->cleanApertureHeightN = gf_bs_read_u32(bs);
	ptr->cleanApertureHeightD = gf_bs_read_u32(bs);
	ptr->horizOffN = gf_bs_read_u32(bs);
	ptr->horizOffD = gf_bs_read_u32(bs);
	ptr->vertOffN = gf_bs_read_u32(bs);
	ptr->vertOffD = gf_bs_read_u32(bs);
	return GF_OK;
}

Project: gpac

GF_Err clap_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_CleanApertureBox *ptr = (GF_CleanApertureBox *)s;
	GF_Err e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->cleanApertureWidthN);
	gf_bs_write_u32(bs, ptr->cleanApertureWidthD);
	gf_bs_write_u32(bs, ptr->cleanApertureHeightN);
	gf_bs_write_u32(bs, ptr->cleanApertureHeightD);
	gf_bs_write_u32(bs, ptr->horizOffN);
	gf_bs_write_u32(bs, ptr->horizOffD);
	gf_bs_write_u32(bs, ptr->vertOffN);
	gf_bs_write_u32(bs, ptr->vertOffD);
	return GF_OK;
}

Project: gpac

void clap_del(GF_Box *s)
{
	GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

Project: gpac

GF_Box *dvcC_New()
{
	GF_DOVIConfigurationBox *tmp = (GF_DOVIConfigurationBox *)gf_malloc(sizeof(GF_DOVIConfigurationBox));
	if (tmp == NULL) return NULL;
	memset(tmp, 0, sizeof(GF_DOVIConfigurationBox));
	tmp->type = GF_ISOM_BOX_TYPE_DVCC;
	return (GF_Box *)tmp;
}

Project: gpac

GF_Err dvcC_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s;

	ptr->DOVIConfig.dv_version_major = gf_bs_read_u8(bs);
	ptr->DOVIConfig.dv_version_minor = gf_bs_read_u8(bs);
	ptr->DOVIConfig.dv_profile = gf_bs_read_int(bs, 7);
	ptr->DOVIConfig.dv_level = gf_bs_read_int(bs, 6);
	ptr->DOVIConfig.rpu_present_flag = gf_bs_read_int(bs, 1);
	ptr->DOVIConfig.el_present_flag = gf_bs_read_int(bs, 1);
	ptr->DOVIConfig.bl_present_flag = gf_bs_read_int(bs, 1);
	{
		int i = 0;
		u32 data[5];
		memset(data, 0, sizeof(data));
		gf_bs_read_data(bs, (char*)data, 20);
		for (i = 0; i < 5; ++i) {
			if (data[i] != 0) {
				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] dvcC reserved bytes are not zero\n"));
			}
		}
	}

	return GF_OK;
}

Project: gpac

GF_Err dvcC_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *) s;
	if (!s) return GF_BAD_PARAM;

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

	gf_bs_write_u8(bs,  ptr->DOVIConfig.dv_version_major);
	gf_bs_write_u8(bs,  ptr->DOVIConfig.dv_version_minor);
	gf_bs_write_int(bs, ptr->DOVIConfig.dv_profile, 7);
	gf_bs_write_int(bs, ptr->DOVIConfig.dv_level, 6);
	gf_bs_write_int(bs, ptr->DOVIConfig.rpu_present_flag, 1);
	gf_bs_write_int(bs, ptr->DOVIConfig.el_present_flag, 1);
	gf_bs_write_int(bs, ptr->DOVIConfig.bl_present_flag, 1);
	gf_bs_write_int(bs, 0, 5*32);

	return GF_OK;
}

Project: gpac

void dvcC_del(GF_Box *s)
{
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox*)s;
	gf_free(ptr);
}

Project: gpac

GF_Err extr_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;

	e = gf_isom_box_parse((GF_Box**) &ptr->feci, bs);
	if (e) return e;
	if (!ptr->feci || ptr->feci->size > ptr->size) return GF_ISOM_INVALID_MEDIA;
	ptr->data_length = (u32) (ptr->size - ptr->feci->size);
	ptr->data = gf_malloc(sizeof(char)*ptr->data_length);
	gf_bs_read_data(bs, ptr->data, ptr->data_length);

	return GF_OK;
}

Project: gpac
File: box_code_base.c

GF_Box *gen_sample_entry_New()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleEntryBox, GF_QT_BOX_TYPE_C608);//type will be overriten
	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
	return (GF_Box *)tmp;
}

Project: gpac
File: box_code_base.c

GF_Err gen_sample_entry_Read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_base_sample_entry_read((GF_SampleEntryBox *)s, bs);
}

Project: gpac
File: box_code_base.c

GF_Err gen_sample_entry_Size(GF_Box *s)
{
	GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
	ptr->size += 8;
	return gf_isom_box_array_size(s, ptr->protections);
}

Project: gpac
File: box_code_base.c

void gen_sample_entry_del(GF_Box *s)
{
	GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
	if (ptr == NULL) return;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
	gf_free(ptr);
}

Project: gpac

static void gf_isom_check_sample_desc(GF_TrackBox *trak)
{
	GF_BitStream *bs;
	GF_UnknownBox *a;
	u32 i;

	if (!trak->Media || !trak->Media->information) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no media box !\n" ));
		return;
	}
	if (!trak->Media->information->sampleTable) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample table !\n" ));
		trak->Media->information->sampleTable = (GF_SampleTableBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STBL);
	}

	if (!trak->Media->information->sampleTable->SampleDescription) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample description box !\n" ));
		trak->Media->information->sampleTable->SampleDescription = (GF_SampleDescriptionBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSD);
		return;
	}

	i=0;
	while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->other_boxes, &i))) {
		switch (a->type) {
		case GF_ISOM_BOX_TYPE_MP4S:
		case GF_ISOM_BOX_TYPE_ENCS:
		case GF_ISOM_BOX_TYPE_MP4A:
		case GF_ISOM_BOX_TYPE_ENCA:
		case GF_ISOM_BOX_TYPE_MP4V:
		case GF_ISOM_BOX_TYPE_ENCV:
		case GF_ISOM_BOX_TYPE_RESV:
		case GF_ISOM_SUBTYPE_3GP_AMR:
		case GF_ISOM_SUBTYPE_3GP_AMR_WB:
		case GF_ISOM_SUBTYPE_3GP_EVRC:
		case GF_ISOM_SUBTYPE_3GP_QCELP:
		case GF_ISOM_SUBTYPE_3GP_SMV:
		case GF_ISOM_SUBTYPE_3GP_H263:
		case GF_ISOM_BOX_TYPE_GHNT:
		case GF_ISOM_BOX_TYPE_RTP_STSD:
		case GF_ISOM_BOX_TYPE_SRTP_STSD:
		case GF_ISOM_BOX_TYPE_FDP_STSD:
		case GF_ISOM_BOX_TYPE_RRTP_STSD:
		case GF_ISOM_BOX_TYPE_RTCP_STSD:
		case GF_ISOM_BOX_TYPE_METX:
		case GF_ISOM_BOX_TYPE_METT:
		case GF_ISOM_BOX_TYPE_STXT:
		case GF_ISOM_BOX_TYPE_AVC1:
		case GF_ISOM_BOX_TYPE_AVC2:
		case GF_ISOM_BOX_TYPE_AVC3:
		case GF_ISOM_BOX_TYPE_AVC4:
		case GF_ISOM_BOX_TYPE_SVC1:
		case GF_ISOM_BOX_TYPE_MVC1:
		case GF_ISOM_BOX_TYPE_HVC1:
		case GF_ISOM_BOX_TYPE_HEV1:
		case GF_ISOM_BOX_TYPE_HVC2:
		case GF_ISOM_BOX_TYPE_HEV2:
		case GF_ISOM_BOX_TYPE_HVT1:
		case GF_ISOM_BOX_TYPE_LHV1:
		case GF_ISOM_BOX_TYPE_LHE1:
		case GF_ISOM_BOX_TYPE_AV01:
		case GF_ISOM_BOX_TYPE_VP08:
		case GF_ISOM_BOX_TYPE_VP09:
		case GF_ISOM_BOX_TYPE_AV1C:
		case GF_ISOM_BOX_TYPE_TX3G:
		case GF_ISOM_BOX_TYPE_TEXT:
		case GF_ISOM_BOX_TYPE_ENCT:
		case GF_ISOM_BOX_TYPE_DIMS:
		case GF_ISOM_BOX_TYPE_AC3:
		case GF_ISOM_BOX_TYPE_EC3:
		case GF_ISOM_BOX_TYPE_LSR1:
		case GF_ISOM_BOX_TYPE_WVTT:
		case GF_ISOM_BOX_TYPE_STPP:
		case GF_ISOM_BOX_TYPE_SBTT:
		case GF_ISOM_BOX_TYPE_MP3:
		case GF_ISOM_BOX_TYPE_JPEG:
		case GF_ISOM_BOX_TYPE_PNG:
		case GF_ISOM_BOX_TYPE_JP2K:
		case GF_ISOM_BOX_TYPE_MHA1:
		case GF_ISOM_BOX_TYPE_MHA2:
		case GF_ISOM_BOX_TYPE_MHM1:
		case GF_ISOM_BOX_TYPE_MHM2:
		case GF_QT_BOX_TYPE_AUDIO_RAW:
		case GF_QT_BOX_TYPE_AUDIO_TWOS:
		case GF_QT_BOX_TYPE_AUDIO_SOWT:
		case GF_QT_BOX_TYPE_AUDIO_FL32:
		case GF_QT_BOX_TYPE_AUDIO_FL64:
		case GF_QT_BOX_TYPE_AUDIO_IN24:
		case GF_QT_BOX_TYPE_AUDIO_IN32:
		case GF_QT_BOX_TYPE_AUDIO_ULAW:
		case GF_QT_BOX_TYPE_AUDIO_ALAW:
		case GF_QT_BOX_TYPE_AUDIO_ADPCM:
		case GF_QT_BOX_TYPE_AUDIO_IMA_ADPCM:
		case GF_QT_BOX_TYPE_AUDIO_DVCA:
		case GF_QT_BOX_TYPE_AUDIO_QDMC:
		case GF_QT_BOX_TYPE_AUDIO_QDMC2:
		case GF_QT_BOX_TYPE_AUDIO_QCELP:
		case GF_QT_BOX_TYPE_AUDIO_kMP3:
			continue;

		case GF_ISOM_BOX_TYPE_UNKNOWN:
			break;
		default:
			if (gf_box_valid_in_parent((GF_Box *) a, "stsd")) {
				continue;
			}
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unexpected box %s in stsd!\n", gf_4cc_to_str(a->type)));
			continue;
		}
		assert(a->type==GF_ISOM_BOX_TYPE_UNKNOWN);

		if (!a->data || (a->dataSize<8) ) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Sample description %s does not have at least 8 bytes!\n", gf_4cc_to_str(a->original_4cc) ));
			continue;
		}
		else if (a->dataSize > a->size) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Sample description %s has wrong data size %d!\n", gf_4cc_to_str(a->original_4cc), a->dataSize));
			continue;
		}

#define STSD_SWITCH_BOX(_box) \
		if (gf_bs_available(bs)) { \
			u64 pos = gf_bs_get_position(bs); \
			u32 count_subb = 0; \
			GF_Err e;\
			gf_bs_set_cookie(bs, 1);\
			e = gf_isom_box_array_read((GF_Box *) _box, bs, gf_isom_box_add_default); \
			count_subb = _box->other_boxes ? gf_list_count(_box->other_boxes) : 0; \
			if (!count_subb || e) { \
				gf_bs_seek(bs, pos); \
				_box->data_size = (u32) gf_bs_available(bs); \
				if (_box->data_size) { \
					_box->data = a->data; \
					a->data = NULL; \
					memmove(_box->data, _box->data + pos, _box->data_size); \
				} \
			} else { \
				_box->data_size = 0; \
			} \
		} \
		gf_bs_del(bs); \
		if (!_box->data_size && _box->data) { \
			gf_free(_box->data); \
			_box->data = NULL; \
		} \
		_box->size = 0; \
		_box->EntryType = a->original_4cc; \
		gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i-1); \
		gf_isom_box_del((GF_Box *)a); \
		gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, _box, i-1); \


		/*only process visual or audio*/
		switch (trak->Media->handler->handlerType) {
        case GF_ISOM_MEDIA_VISUAL:
		case GF_ISOM_MEDIA_AUXV:
		case GF_ISOM_MEDIA_PICT:
		{
			GF_GenericVisualSampleEntryBox *genv = (GF_GenericVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRV);
			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
			genv->size = a->size-8;
			gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *) genv, bs);

			STSD_SWITCH_BOX(genv)

		}
		break;
		case GF_ISOM_MEDIA_AUDIO:
		{
			GF_GenericAudioSampleEntryBox *gena = (GF_GenericAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRA);
			gena->size = a->size-8;
			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
			gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox *) gena, bs);

			STSD_SWITCH_BOX(gena)

		}
		break;

		default:
		{
			GF_Err e;
			GF_GenericSampleEntryBox *genm = (GF_GenericSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRM);
			genm->size = a->size-8;
			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);

			e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)genm, bs);
			if (e) return;

			STSD_SWITCH_BOX(genm)
		}
		break;
		}

	}
}

Project: gpac

GF_Err mhac_Read(GF_Box *s,GF_BitStream *bs)
{
	GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;

	ISOM_DECREASE_SIZE(s, 5)
	ptr->configuration_version = gf_bs_read_u8(bs);
	ptr->mha_pl_indication = gf_bs_read_u8(bs);
	ptr->reference_channel_layout = gf_bs_read_u8(bs);
	ptr->mha_config_size = gf_bs_read_u16(bs);
	if (ptr->mha_config_size) {
		ISOM_DECREASE_SIZE(s, ptr->mha_config_size)
		ptr->mha_config = gf_malloc(sizeof(char)*ptr->mha_config_size);
		gf_bs_read_data(bs, ptr->mha_config, ptr->mha_config_size);
	}
	return GF_OK;
}

Project: gpac

GF_Err mhac_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;

	e = gf_isom_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->configuration_version);
	gf_bs_write_u8(bs, ptr->mha_pl_indication);
	gf_bs_write_u8(bs, ptr->reference_channel_layout);
	gf_bs_write_u16(bs, ptr->mha_config ? ptr->mha_config_size : 0);
	if (ptr->mha_config && ptr->mha_config_size)
		gf_bs_write_data(bs, ptr->mha_config, ptr->mha_config_size);

	return GF_OK;
}

Project: gpac

void mhac_del(GF_Box *s)
{
	GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
	if (ptr->mha_config) gf_free(ptr->mha_config);
	gf_free(s);
}

Project: gpac
File: box_code_base.c

GF_Err moov_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MovieBox *ptr = (GF_MovieBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	if (ptr->mvhd) {
		e = gf_isom_box_write((GF_Box *) ptr->mvhd, bs);
		if (e) return e;
	}
	if (ptr->iods) {
		e = gf_isom_box_write((GF_Box *) ptr->iods, bs);
		if (e) return e;
	}
	if (ptr->meta) {
		e = gf_isom_box_write((GF_Box *) ptr->meta, bs);
		if (e) return e;
	}
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
	if (ptr->mvex && !ptr->mvex_after_traks) {
		e = gf_isom_box_write((GF_Box *) ptr->mvex, bs);
		if (e) return e;
	}
#endif

	e = gf_isom_box_array_write(s, ptr->trackList, bs);
	if (e) return e;

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
	if (ptr->mvex && ptr->mvex_after_traks) {
		e = gf_isom_box_write((GF_Box *) ptr->mvex, bs);
		if (e) return e;
	}
#endif

	if (ptr->udta) {
		e = gf_isom_box_write((GF_Box *) ptr->udta, bs);
		if (e) return e;
	}
	return GF_OK;
}

Project: gpac
File: box_code_base.c

void mvex_del(GF_Box *s)
{
	GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
	if (ptr == NULL) return;
	if (ptr->mehd) gf_isom_box_del((GF_Box*)ptr->mehd);
	gf_isom_box_array_del(ptr->TrackExList);
	gf_isom_box_array_del(ptr->TrackExPropList);
	ptr->mehd = NULL;
	ptr->TrackExList = NULL;
	ptr->TrackExPropList = NULL;
	gf_free(ptr);
}

Project: gpac

GF_Err ssix_Read(GF_Box *s, GF_BitStream *bs)
{
	u32 i,j;
	GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;

	if (ptr->size < 4) return GF_BAD_PARAM;
	ptr->subsegment_count = gf_bs_read_u32(bs);
	ptr->size -= 4;
	ptr->subsegments = gf_malloc(ptr->subsegment_count*sizeof(GF_SubsegmentInfo));
	for (i = 0; i < ptr->subsegment_count; i++) {
		GF_SubsegmentInfo *subseg = &ptr->subsegments[i];
		if (ptr->size < 4) return GF_BAD_PARAM;
		subseg->range_count = gf_bs_read_u32(bs);
		ptr->size -= 4;
		if (ptr->size < subseg->range_count*4) return GF_BAD_PARAM;
		subseg->ranges = (GF_SubsegmentRangeInfo*) gf_malloc(sizeof(GF_SubsegmentRangeInfo) * subseg->range_count);
		for (j = 0; j < subseg->range_count; j++) {
			subseg->ranges[j].level = gf_bs_read_u8(bs);
			subseg->ranges[j].range_size = gf_bs_read_u24(bs);
			ptr->size -= 4;
		}
	}
	return GF_OK;
}

Project: gpac

GF_Err ssix_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i, j;
	GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;

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

	gf_bs_write_u32(bs, ptr->subsegment_count);
	for (i = 0; i<ptr->subsegment_count; i++) {
		gf_bs_write_u32(bs, ptr->subsegments[i].range_count);
		for (j = 0; j < ptr->subsegments[i].range_count; j++) {
			gf_bs_write_u8(bs, ptr->subsegments[i].ranges[j].level);
			gf_bs_write_u24(bs, ptr->subsegments[i].ranges[j].range_size);
		}
	}
	return GF_OK;
}

Project: gpac

void ssix_del(GF_Box *s)
{
	u32 i;
	GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox *)s;
	if (ptr == NULL) return;
	if (ptr->subsegments) {
		for (i = 0; i < ptr->subsegment_count; i++) {
			GF_SubsegmentInfo *subsegment = &ptr->subsegments[i];
			if (subsegment->ranges) gf_free(subsegment->ranges);
		}
		gf_free(ptr->subsegments);
	}
	gf_free(ptr);
}

Project: gpac

GF_Err stbl_AddBox(GF_Box *s, GF_Box *a)
{
	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
	if (!a) return GF_OK;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_STTS:
		if (ptr->TimeToSample) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->TimeToSample = (GF_TimeToSampleBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_CTTS:
		if (ptr->CompositionOffset) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->CompositionOffset = (GF_CompositionOffsetBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_CSLG:
		if (ptr->CompositionToDecode) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->CompositionToDecode = (GF_CompositionToDecodeBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_STSS:
		if (ptr->SyncSample) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->SyncSample = (GF_SyncSampleBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_STSD:
		if (ptr->SampleDescription) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->SampleDescription  =(GF_SampleDescriptionBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_STZ2:
	case GF_ISOM_BOX_TYPE_STSZ:
		if (ptr->SampleSize) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->SampleSize = (GF_SampleSizeBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_STSC:
		if (ptr->SampleToChunk) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->SampleToChunk = (GF_SampleToChunkBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_PADB:
		if (ptr->PaddingBits) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->PaddingBits = (GF_PaddingBitsBox *) a;
		break;

	case GF_ISOM_BOX_TYPE_CO64:
	case GF_ISOM_BOX_TYPE_STCO:
		if (ptr->ChunkOffset) {
			gf_isom_box_del(ptr->ChunkOffset);
		}
		ptr->ChunkOffset = a;
		return GF_OK;
	case GF_ISOM_BOX_TYPE_STSH:
		if (ptr->ShadowSync) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->ShadowSync = (GF_ShadowSyncBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_STDP:
		if (ptr->DegradationPriority) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->DegradationPriority = (GF_DegradationPriorityBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_SDTP:
		if (ptr->SampleDep) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->SampleDep= (GF_SampleDependencyTypeBox *)a;
		break;

	case GF_ISOM_BOX_TYPE_SUBS:
		if (!ptr->sub_samples) ptr->sub_samples = gf_list_new();
		gf_list_add(ptr->sub_samples, a);
		{
			GF_SubSampleInformationBox *subs = (GF_SubSampleInformationBox *)a;
			GF_SubSampleInfoEntry *ent = gf_list_get(subs->Samples, 0);
			if (!ent) {
				gf_list_rem(subs->Samples, 0);
				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable is invalid\n"));
			}
			else if (ent->sample_delta==0) {
				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable has sample_delta of 0, should be one. Fixing\n"));
				ent->sample_delta = 1;
			}
		}
		break;

	case GF_ISOM_BOX_TYPE_SBGP:
		if (!ptr->sampleGroups) ptr->sampleGroups = gf_list_new();
		gf_list_add(ptr->sampleGroups, a);
		break;
	case GF_ISOM_BOX_TYPE_SGPD:
		if (!ptr->sampleGroupsDescription) ptr->sampleGroupsDescription = gf_list_new();
		gf_list_add(ptr->sampleGroupsDescription, a);
		break;

	case GF_ISOM_BOX_TYPE_SAIZ:
		if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new();
		gf_list_add(ptr->sai_sizes, a);
		break;
	case GF_ISOM_BOX_TYPE_SAIO:
		if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new();
		gf_list_add(ptr->sai_offsets, a);
		break;
	default:
		return gf_isom_box_add_default((GF_Box *)ptr, a);
	}
	return GF_OK;
}

Project: gpac

GF_Err stbl_Size(GF_Box *s)
{
	GF_Err e;
	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;

	if (ptr->SampleDescription) {
		e = gf_isom_box_size((GF_Box *) ptr->SampleDescription);
		if (e) return e;
		ptr->size += ptr->SampleDescription->size;
	}
	if (ptr->SampleSize) {
		e = gf_isom_box_size((GF_Box *) ptr->SampleSize);
		if (e) return e;
		ptr->size += ptr->SampleSize->size;
	}
	if (ptr->SampleToChunk) {
		e = gf_isom_box_size((GF_Box *) ptr->SampleToChunk);
		if (e) return e;
		ptr->size += ptr->SampleToChunk->size;
	}
	if (ptr->TimeToSample) {
		e = gf_isom_box_size((GF_Box *) ptr->TimeToSample);
		if (e) return e;
		ptr->size += ptr->TimeToSample->size;
	}
	if (ptr->ChunkOffset) {
		e = gf_isom_box_size(ptr->ChunkOffset);
		if (e) return e;
		ptr->size += ptr->ChunkOffset->size;
	}

	if (ptr->CompositionOffset)	{
		e = gf_isom_box_size((GF_Box *) ptr->CompositionOffset);
		if (e) return e;
		ptr->size += ptr->CompositionOffset->size;
	}
	if (ptr->CompositionToDecode)	{
		e = gf_isom_box_size((GF_Box *) ptr->CompositionToDecode);
		if (e) return e;
		ptr->size += ptr->CompositionToDecode->size;
	}
	if (ptr->DegradationPriority) {
		e = gf_isom_box_size((GF_Box *) ptr->DegradationPriority);
		if (e) return e;
		ptr->size += ptr->DegradationPriority->size;
	}
	if (ptr->ShadowSync) {
		e = gf_isom_box_size((GF_Box *) ptr->ShadowSync);
		if (e) return e;
		ptr->size += ptr->ShadowSync->size;
	}
	if (ptr->SyncSample) {
		e = gf_isom_box_size((GF_Box *) ptr->SyncSample);
		if (e) return e;
		ptr->size += ptr->SyncSample->size;
	}
	if (ptr->SampleDep && ptr->SampleDep->sampleCount) {
		e = gf_isom_box_size((GF_Box *) ptr->SampleDep);
		if (e) return e;
		ptr->size += ptr->SampleDep->size;
	}
	if (ptr->PaddingBits) {
		e = gf_isom_box_size((GF_Box *) ptr->PaddingBits);
		if (e) return e;
		ptr->size += ptr->PaddingBits->size;
	}

	if (ptr->sub_samples) {
		e = gf_isom_box_array_size(s, ptr->sub_samples);
		if (e) return e;
	}
	if (ptr->sampleGroups) {
		e = gf_isom_box_array_size(s, ptr->sampleGroups);
		if (e) return e;
	}
	if (ptr->sampleGroupsDescription) {
		e = gf_isom_box_array_size(s, ptr->sampleGroupsDescription);
		if (e) return e;
	}
	if (ptr->sai_sizes) {
		e = gf_isom_box_array_size(s, ptr->sai_sizes);
		if (e) return e;
	}
	if (ptr->sai_offsets) {
		e = gf_isom_box_array_size(s, ptr->sai_offsets);
		if (e) return e;
	}
	return GF_OK;
}

Project: gpac
File: box_code_base.c

GF_Err stbl_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	if (ptr->SampleDescription) {
		e = gf_isom_box_write((GF_Box *) ptr->SampleDescription, bs);
		if (e) return e;
	}
	if (ptr->TimeToSample) {
		e = gf_isom_box_write((GF_Box *) ptr->TimeToSample, bs);
		if (e) return e;
	}
	if (ptr->CompositionOffset)	{
		e = gf_isom_box_write((GF_Box *) ptr->CompositionOffset, bs);
		if (e) return e;
	}
	if (ptr->CompositionToDecode)	{
		e = gf_isom_box_write((GF_Box *) ptr->CompositionToDecode, bs);
		if (e) return e;
	}
	if (ptr->SyncSample) {
		e = gf_isom_box_write((GF_Box *) ptr->SyncSample, bs);
		if (e) return e;
	}
	if (ptr->ShadowSync) {
		e = gf_isom_box_write((GF_Box *) ptr->ShadowSync, bs);
		if (e) return e;
	}
	if (ptr->SampleToChunk) {
		e = gf_isom_box_write((GF_Box *) ptr->SampleToChunk, bs);
		if (e) return e;
	}
	if (ptr->SampleSize) {
		e = gf_isom_box_write((GF_Box *) ptr->SampleSize, bs);
		if (e) return e;
	}
	if (ptr->ChunkOffset) {
		e = gf_isom_box_write(ptr->ChunkOffset, bs);
		if (e) return e;
	}
	if (ptr->DegradationPriority) {
		e = gf_isom_box_write((GF_Box *) ptr->DegradationPriority, bs);
		if (e) return e;
	}
	if (ptr->SampleDep && ptr->SampleDep->sampleCount) {
		e = gf_isom_box_write((GF_Box *) ptr->SampleDep, bs);
		if (e) return e;
	}
	if (ptr->PaddingBits) {
		e = gf_isom_box_write((GF_Box *) ptr->PaddingBits, bs);
		if (e) return e;
	}
	if (ptr->sub_samples) {
		e = gf_isom_box_array_write(s, ptr->sub_samples, bs);
		if (e) return e;
	}
	if (ptr->sampleGroupsDescription) {
		e = gf_isom_box_array_write(s, ptr->sampleGroupsDescription, bs);
		if (e) return e;
	}
	if (ptr->sampleGroups) {
		e = gf_isom_box_array_write(s, ptr->sampleGroups, bs);
		if (e) return e;
	}
	if (ptr->sai_sizes) {
		e = gf_isom_box_array_write(s, ptr->sai_sizes, bs);
		if (e) return e;
	}
	if (ptr->sai_offsets) {
		e = gf_isom_box_array_write(s, ptr->sai_offsets, bs);
		if (e) return e;
	}
	return GF_OK;
}

Project: gpac
File: box_code_base.c

void stbl_del(GF_Box *s)
{
	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
	if (ptr == NULL) return;

	if (ptr->ChunkOffset) gf_isom_box_del(ptr->ChunkOffset);
	if (ptr->CompositionOffset) gf_isom_box_del((GF_Box *) ptr->CompositionOffset);
	if (ptr->CompositionToDecode) gf_isom_box_del((GF_Box *) ptr->CompositionToDecode);
	if (ptr->DegradationPriority) gf_isom_box_del((GF_Box *) ptr->DegradationPriority);
	if (ptr->SampleDescription) gf_isom_box_del((GF_Box *) ptr->SampleDescription);
	if (ptr->SampleSize) gf_isom_box_del((GF_Box *) ptr->SampleSize);
	if (ptr->SampleToChunk) gf_isom_box_del((GF_Box *) ptr->SampleToChunk);
	if (ptr->ShadowSync) gf_isom_box_del((GF_Box *) ptr->ShadowSync);
	if (ptr->SyncSample) gf_isom_box_del((GF_Box *) ptr->SyncSample);
	if (ptr->TimeToSample) gf_isom_box_del((GF_Box *) ptr->TimeToSample);
	if (ptr->SampleDep) gf_isom_box_del((GF_Box *) ptr->SampleDep);
	if (ptr->PaddingBits) gf_isom_box_del((GF_Box *) ptr->PaddingBits);
	if (ptr->sub_samples) gf_isom_box_array_del(ptr->sub_samples);
	if (ptr->sampleGroups) gf_isom_box_array_del(ptr->sampleGroups);
	if (ptr->sampleGroupsDescription) gf_isom_box_array_del(ptr->sampleGroupsDescription);

	if (ptr->sai_sizes) gf_isom_box_array_del(ptr->sai_sizes);
	if (ptr->sai_offsets) gf_isom_box_array_del(ptr->sai_offsets);
	if (ptr->traf_map) {
		if (ptr->traf_map->sample_num) gf_free(ptr->traf_map->sample_num);
		gf_free(ptr->traf_map);
	}

	gf_free(ptr);
}

Project: gpac

GF_Err stsd_AddBox(GF_Box *s, GF_Box *a)
{
	GF_UnknownBox *def;
	GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
	if (!a) return GF_OK;

	if (gf_box_valid_in_parent(a, "stsd")) {
		return gf_isom_box_add_default((GF_Box*)ptr, a);
	}
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_UNKNOWN:
		def = (GF_UnknownBox *)a;
		/*we need at least 8 bytes for unknown sample entries*/
		if (def->dataSize < 8) {
			gf_isom_box_del(a);
			return GF_OK;
		}
		return gf_isom_box_add_default((GF_Box*)ptr, a);

	default:
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Cannot process box of type %s\n", gf_4cc_to_str(a->type)));
		return GF_ISOM_INVALID_FILE;
	}
}

Project: gpac
File: box_code_base.c

GF_Err tfra_Read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_RandomAccessEntry *p = 0;
	GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;

	if (ptr->size < 12)
		return GF_ISOM_INVALID_FILE;

	ptr->track_id = gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, 4);

	if (gf_bs_read_int(bs, 26) != 0)
		return GF_ISOM_INVALID_FILE;

	ptr->traf_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
	ptr->trun_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
	ptr->sample_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
	ISOM_DECREASE_SIZE(ptr, 4);

	ptr->nb_entries = gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, 4);

	if (ptr->version == 1) {
		if (ptr->nb_entries > ptr->size / (16+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
			return GF_ISOM_INVALID_FILE;
		}
	} else {
		if (ptr->nb_entries > ptr->size / (8+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
			return GF_ISOM_INVALID_FILE;
		}
	}

	if (ptr->nb_entries) {
		p = (GF_RandomAccessEntry *) gf_malloc(sizeof(GF_RandomAccessEntry) * ptr->nb_entries);
		if (!p) return GF_OUT_OF_MEM;
	}

	ptr->entries = p;

	for (i=0; i<ptr->nb_entries; i++) {
		memset(p, 0, sizeof(GF_RandomAccessEntry));

		if (ptr->version == 1) {
			p->time = gf_bs_read_u64(bs);
			p->moof_offset = gf_bs_read_u64(bs);
		} else {
			p->time = gf_bs_read_u32(bs);
			p->moof_offset = gf_bs_read_u32(bs);
		}
		p->traf_number = gf_bs_read_int(bs, ptr->traf_bits);
		p->trun_number = gf_bs_read_int(bs, ptr->trun_bits);
		p->sample_number = gf_bs_read_int(bs, ptr->sample_bits);

		++p;
	}

	return GF_OK;
}

Project: gpac

GF_Err trak_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_TrackBox *ptr = (GF_TrackBox *)s;
	e = gf_isom_box_array_read(s, bs, trak_AddBox);
	if (e) return e;
	gf_isom_check_sample_desc(ptr);

	if (!ptr->Header) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackHeaderBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	if (!ptr->Media) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	if (!ptr->Media->information || !ptr->Media->information->sampleTable) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid MediaBox\n"));
		return GF_ISOM_INVALID_FILE;
	}

	for (i=0; i<gf_list_count(ptr->Media->information->sampleTable->other_boxes); i++) {
		GF_Box *a = gf_list_get(ptr->Media->information->sampleTable->other_boxes, i);
		if ((a->type ==GF_ISOM_BOX_TYPE_UUID) && (((GF_UUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC)) {
			ptr->sample_encryption = (struct __sample_encryption_box *) a;
			break;
		}
		else if (a->type == GF_ISOM_BOX_TYPE_SENC) {
			ptr->sample_encryption = (struct __sample_encryption_box *)a;
			break;
		}
	}
	return e;
}

Project: gpac

GF_Err trex_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;

	ptr->trackID = gf_bs_read_u32(bs);
	ptr->def_sample_desc_index = gf_bs_read_u32(bs);
	ptr->def_sample_duration = gf_bs_read_u32(bs);
	ptr->def_sample_size = gf_bs_read_u32(bs);
	ptr->def_sample_flags = gf_bs_read_u32(bs);
	return GF_OK;
}

Project: gpac

GF_Err trex_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->trackID);
	gf_bs_write_u32(bs, ptr->def_sample_desc_index ? ptr->def_sample_desc_index : 1);
	gf_bs_write_u32(bs, ptr->def_sample_duration);
	gf_bs_write_u32(bs, ptr->def_sample_size);
	gf_bs_write_u32(bs, ptr->def_sample_flags);
	return GF_OK;
}

Project: gpac

GF_Err trun_Size(GF_Box *s)
{
	u32 i, count;
	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;

	ptr->size += 4;
	if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) ptr->size += 4;
	if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) ptr->size += 4;

	if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) {
		return GF_OK;
	}

	count = gf_list_count(ptr->entries);
	for (i=0; i<count; i++) {
		if (ptr->flags & GF_ISOM_TRUN_DURATION) ptr->size += 4;
		if (ptr->flags & GF_ISOM_TRUN_SIZE) ptr->size += 4;
		if (ptr->flags & GF_ISOM_TRUN_FLAGS) ptr->size += 4;
		if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) ptr->size += 4;
	}

	return GF_OK;
}

Project: gpac

GF_Err udta_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e = gf_isom_box_array_read(s, bs, udta_AddBox);
	if (e) return e;
	if (s->size==4) {
		u32 val = gf_bs_read_u32(bs);
		s->size = 0;
		if (val) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] udta has 4 remaining bytes set to %08X but they should be 0\n", val));
		}
	}
	return GF_OK;
}

Project: gpac
File: box_code_base.c

GF_Box *unkn_New()
{
	ISOM_DECL_BOX_ALLOC(GF_UnknownBox, GF_ISOM_BOX_TYPE_UNKNOWN);
	return (GF_Box *) tmp;
}

Project: gpac
File: box_code_base.c

GF_Err unkn_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 type = s->type;
	GF_UnknownBox *ptr = (GF_UnknownBox *)s;
	if (!s) return GF_BAD_PARAM;
	ptr->type = ptr->original_4cc;
	e = gf_isom_box_write_header(s, bs);
	ptr->type = type;
	if (e) return e;

	if (ptr->dataSize && ptr->data) {
		gf_bs_write_data(bs, ptr->data, ptr->dataSize);
	}
	return GF_OK;
}

Project: gpac
File: box_code_base.c

GF_Err video_sample_entry_AddBox(GF_Box *s, GF_Box *a)
{
	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_ESDS:
		if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->esd = (GF_ESDBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_SINF:
		gf_list_add(ptr->protections, a);
		break;
	case GF_ISOM_BOX_TYPE_RINF:
		if (ptr->rinf) ERROR_ON_DUPLICATED_BOX(a, ptr)
		ptr->rinf = (GF_RestrictedSchemeInfoBox *) a;
		break;
	case GF_ISOM_BOX_TYPE_AVCC:
		if (ptr->avc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->avc_config = (GF_AVCConfigurationBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_HVCC:
		if (ptr->hevc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->hevc_config = (GF_HEVCConfigurationBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_SVCC:
		if (ptr->svc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->svc_config = (GF_AVCConfigurationBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_MVCC:
		if (ptr->mvc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->mvc_config = (GF_AVCConfigurationBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_LHVC:
		if (ptr->lhvc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->lhvc_config = (GF_HEVCConfigurationBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_AV1C:
		if (ptr->av1_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->av1_config = (GF_AV1ConfigurationBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_VPCC:
		if (ptr->vp_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->vp_config = (GF_VPConfigurationBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_M4DS:
		if (ptr->descr) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_UUID:
		if (! memcmp(((GF_UnknownUUIDBox*)a)->uuid, GF_ISOM_IPOD_EXT, 16)) {
			if (ptr->ipod_ext) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->ipod_ext = (GF_UnknownUUIDBox *)a;
		} else {
			return gf_isom_box_add_default(s, a);
		}
		break;
	case GF_ISOM_BOX_TYPE_D263:
		ptr->cfg_3gpp = (GF_3GPPConfigBox *)a;
		/*for 3GP config, remember sample entry type in config*/
		ptr->cfg_3gpp->cfg.type = ptr->type;
		break;
		break;

	case GF_ISOM_BOX_TYPE_PASP:
		if (ptr->pasp) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->pasp = (GF_PixelAspectRatioBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_CLAP:
		if (ptr->clap) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->clap = (GF_CleanApertureBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_CCST:
		if (ptr->ccst) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->ccst = (GF_CodingConstraintsBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_AUXI:
		if (ptr->auxi) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->auxi = (GF_AuxiliaryTypeInfoBox *)a;
		break;
	case GF_ISOM_BOX_TYPE_RVCC:
		if (ptr->rvcc) ERROR_ON_DUPLICATED_BOX(a, ptr)
			ptr->rvcc = (GF_RVCConfigurationBox *)a;
		break;
	default:
		return gf_isom_box_add_default(s, a);
	}
	return GF_OK;
}

Project: gpac
File: box_code_base.c

GF_Err video_sample_entry_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_MPEGVisualSampleEntryBox *mp4v = (GF_MPEGVisualSampleEntryBox*)s;
	GF_Err e;
	e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)s, bs);
	if (e) return e;
	e = gf_isom_box_array_read(s, bs, video_sample_entry_AddBox);
	if (e) return e;
	/*this is an AVC sample desc*/
	if (mp4v->avc_config || mp4v->svc_config || mp4v->mvc_config) AVC_RewriteESDescriptor(mp4v);
	/*this is an HEVC sample desc*/
	if (mp4v->hevc_config || mp4v->lhvc_config || (mp4v->type==GF_ISOM_BOX_TYPE_HVT1))
		HEVC_RewriteESDescriptor(mp4v);
	/*this is an AV1 sample desc*/
	if (mp4v->av1_config)
		AV1_RewriteESDescriptor(mp4v);
	return GF_OK;
}

Project: gpac

GF_Err video_sample_entry_Size(GF_Box *s)
{
	GF_Err e;
	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;

	gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);

	if (ptr->esd) {
		e = gf_isom_box_size((GF_Box *)ptr->esd);
		if (e) return e;
		ptr->size += ptr->esd->size;
	} else if (ptr->cfg_3gpp) {
		e = gf_isom_box_size((GF_Box *)ptr->cfg_3gpp);
		if (e) return e;
		ptr->size += ptr->cfg_3gpp->size;
	} else {
		switch (ptr->type) {
		case GF_ISOM_BOX_TYPE_AVC1:
		case GF_ISOM_BOX_TYPE_AVC2:
		case GF_ISOM_BOX_TYPE_AVC3:
		case GF_ISOM_BOX_TYPE_AVC4:
		case GF_ISOM_BOX_TYPE_SVC1:
		case GF_ISOM_BOX_TYPE_SVC2:
		case GF_ISOM_BOX_TYPE_MVC1:
		case GF_ISOM_BOX_TYPE_MVC2:
			if (!ptr->avc_config && !ptr->svc_config  && !ptr->mvc_config)
				return GF_ISOM_INVALID_FILE;
			break;
		case GF_ISOM_BOX_TYPE_VP08:
		case GF_ISOM_BOX_TYPE_VP09:
			if (!ptr->vp_config) {
				return GF_ISOM_INVALID_FILE;
			}
			break;
		case GF_ISOM_BOX_TYPE_AV01:
			if (!ptr->av1_config) {
				return GF_ISOM_INVALID_FILE;
			}
			break;
		case GF_ISOM_BOX_TYPE_HVC1:
		case GF_ISOM_BOX_TYPE_HEV1:
		case GF_ISOM_BOX_TYPE_HVC2:
		case GF_ISOM_BOX_TYPE_HEV2:
		case GF_ISOM_BOX_TYPE_LHV1:
		case GF_ISOM_BOX_TYPE_LHE1:
			if (!ptr->hevc_config && !ptr->lhvc_config) {
				return GF_ISOM_INVALID_FILE;
			}
			break;
		default:
			break;
		}

		if (ptr->hevc_config && ptr->hevc_config->config) {
			e = gf_isom_box_size((GF_Box *)ptr->hevc_config);
			if (e) return e;
			ptr->size += ptr->hevc_config->size;
		}

		if (ptr->avc_config && ptr->avc_config->config) {
			e = gf_isom_box_size((GF_Box *) ptr->avc_config);
			if (e) return e;
			ptr->size += ptr->avc_config->size;
		}

		if (ptr->svc_config && ptr->svc_config->config) {
			e = gf_isom_box_size((GF_Box *) ptr->svc_config);
			if (e) return e;
			ptr->size += ptr->svc_config->size;
		}

		if (ptr->mvc_config && ptr->mvc_config->config) {
			e = gf_isom_box_size((GF_Box *) ptr->mvc_config);
			if (e) return e;
			ptr->size += ptr->mvc_config->size;
		}

		if (ptr->lhvc_config && ptr->lhvc_config->config) {
			e = gf_isom_box_size((GF_Box *) ptr->lhvc_config);
			if (e) return e;
			ptr->size += ptr->lhvc_config->size;
		}

		if (ptr->av1_config && ptr->av1_config->config) {
			e = gf_isom_box_size((GF_Box *)ptr->av1_config);
			if (e) return e;
			ptr->size += ptr->av1_config->size;
		}

		if (ptr->vp_config && ptr->vp_config->config) {
			e = gf_isom_box_size((GF_Box *)ptr->vp_config);
			if (e) return e;
			ptr->size += ptr->vp_config->size;
		}

		if (ptr->ipod_ext) {
			e = gf_isom_box_size((GF_Box *) ptr->ipod_ext);
			if (e) return e;
			ptr->size += ptr->ipod_ext->size;
		}
		if (ptr->descr) {
			e = gf_isom_box_size((GF_Box *) ptr->descr);
			if (e) return e;
			ptr->size += ptr->descr->size;
		}
	}
	if (ptr->pasp) {
		e = gf_isom_box_size((GF_Box *)ptr->pasp);
		if (e) return e;
		ptr->size += ptr->pasp->size;
	}
	if (ptr->clap) {
		e = gf_isom_box_size((GF_Box *)ptr->clap);
		if (e) return e;
		ptr->size += ptr->clap->size;
	}
	if (ptr->ccst) {
		e = gf_isom_box_size((GF_Box *)ptr->ccst);
		if (e) return e;
		ptr->size += ptr->ccst->size;
	}
	if (ptr->auxi) {
		e = gf_isom_box_size((GF_Box *)ptr->auxi);
		if (e) return e;
		ptr->size += ptr->auxi->size;
	}
	if (ptr->rvcc) {
		e = gf_isom_box_size((GF_Box *)ptr->rvcc);
		if (e) return e;
		ptr->size += ptr->rvcc->size;
	}
	if (ptr->rinf) {
		e = gf_isom_box_size((GF_Box *)ptr->rinf);
		if (e) return e;
		ptr->size += ptr->rinf->size;
	}
	return gf_isom_box_array_size(s, ptr->protections);
}

Project: gpac
File: box_code_base.c

GF_Err video_sample_entry_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs);

	/*mp4v*/
	if (ptr->esd) {
		e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
		if (e) return e;
	}
	/*mp4v*/
	else if (ptr->cfg_3gpp) {
		e = gf_isom_box_write((GF_Box *)ptr->cfg_3gpp, bs);
		if (e) return e;
	}
	/*avc or hevc or av1*/
	else {
		if (ptr->avc_config && ptr->avc_config->config) {
			e = gf_isom_box_write((GF_Box *) ptr->avc_config, bs);
			if (e) return e;
		}
		if (ptr->hevc_config && ptr->hevc_config->config) {
			e = gf_isom_box_write((GF_Box *) ptr->hevc_config, bs);
			if (e) return e;
		}
		if (ptr->ipod_ext)	{
			e = gf_isom_box_write((GF_Box *) ptr->ipod_ext, bs);
			if (e) return e;
		}
		if (ptr->descr)	{
			e = gf_isom_box_write((GF_Box *) ptr->descr, bs);
			if (e) return e;
		}
		if (ptr->svc_config && ptr->svc_config->config) {
			e = gf_isom_box_write((GF_Box *) ptr->svc_config, bs);
			if (e) return e;
		}
		if (ptr->mvc_config && ptr->mvc_config->config) {
			e = gf_isom_box_write((GF_Box *) ptr->mvc_config, bs);
			if (e) return e;
		}
		if (ptr->lhvc_config && ptr->lhvc_config->config) {
			e = gf_isom_box_write((GF_Box *) ptr->lhvc_config, bs);
			if (e) return e;
		}
		if (ptr->av1_config && ptr->av1_config->config) {
			e = gf_isom_box_write((GF_Box *)ptr->av1_config, bs);
			if (e) return e;
		}
		if (ptr->vp_config && ptr->vp_config->config) {
			e = gf_isom_box_write((GF_Box *)ptr->vp_config, bs);
			if (e) return e;
		}
	}
	if (ptr->pasp) {
		e = gf_isom_box_write((GF_Box *)ptr->pasp, bs);
		if (e) return e;
	}
	if (ptr->clap) {
		e = gf_isom_box_write((GF_Box *)ptr->clap, bs);
		if (e) return e;
	}
	if (ptr->ccst) {
		e = gf_isom_box_write((GF_Box *)ptr->ccst, bs);
		if (e) return e;
	}
	if (ptr->auxi) {
		e = gf_isom_box_write((GF_Box *)ptr->auxi, bs);
		if (e) return e;
	}
	if (ptr->rvcc) {
		e = gf_isom_box_write((GF_Box *)ptr->rvcc, bs);
		if (e) return e;
	}
	if (ptr->rinf) {
		e = gf_isom_box_write((GF_Box *)ptr->rinf, bs);
		if (e) return e;
	}
	return gf_isom_box_array_write(s, ptr->protections, bs);
}

Project: gpac
File: box_code_base.c

void video_sample_entry_del(GF_Box *s)
{
	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
	if (ptr == NULL) return;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);

	if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
	/*for publishing*/
	if (ptr->emul_esd) gf_odf_desc_del((GF_Descriptor *)ptr->emul_esd);

	if (ptr->avc_config) gf_isom_box_del((GF_Box *) ptr->avc_config);
	if (ptr->svc_config) gf_isom_box_del((GF_Box *) ptr->svc_config);
	if (ptr->mvc_config) gf_isom_box_del((GF_Box *) ptr->mvc_config);
	if (ptr->hevc_config) gf_isom_box_del((GF_Box *) ptr->hevc_config);
	if (ptr->lhvc_config) gf_isom_box_del((GF_Box *) ptr->lhvc_config);
	if (ptr->av1_config) gf_isom_box_del((GF_Box *)ptr->av1_config);
	if (ptr->vp_config) gf_isom_box_del((GF_Box *)ptr->vp_config);
	if (ptr->cfg_3gpp) gf_isom_box_del((GF_Box *)ptr->cfg_3gpp);

	if (ptr->descr) gf_isom_box_del((GF_Box *) ptr->descr);
	if (ptr->ipod_ext) gf_isom_box_del((GF_Box *)ptr->ipod_ext);

	if (ptr->pasp) gf_isom_box_del((GF_Box *)ptr->pasp);
	if (ptr->clap) gf_isom_box_del((GF_Box *)ptr->clap);
	if (ptr->rinf) gf_isom_box_del((GF_Box *)ptr->rinf);
	if (ptr->ccst) gf_isom_box_del((GF_Box *)ptr->ccst);

	if (ptr->rvcc) gf_isom_box_del((GF_Box *)ptr->rvcc);
	if (ptr->auxi) gf_isom_box_del((GF_Box *)ptr->auxi);

	gf_free(ptr);
}