static GF_Err gf_m4v_parse_config_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi)
{
	s32 o_type;
	u8 go, verid, par;
	s32 clock_rate;

	if (!m4v || !dsi) return GF_BAD_PARAM;

	memset(dsi, 0, sizeof(GF_M4VDecSpecInfo));

	go = 1;
	while (go) {
		o_type = M4V_LoadObject(m4v);
		switch (o_type) {
		/*vosh*/
		case M4V_VOS_START_CODE:
			dsi->VideoPL = (u8) gf_bs_read_u8(m4v->bs);
			break;

		case M4V_VOL_START_CODE:
			verid = 0;
			dsi->RAP_stream = gf_bs_read_int(m4v->bs, 1);
			dsi->objectType = gf_bs_read_int(m4v->bs, 8);
			if (gf_bs_read_int(m4v->bs, 1)) {
				verid = gf_bs_read_int(m4v->bs, 4);
				gf_bs_read_int(m4v->bs, 3);
			}
			par = gf_bs_read_int(m4v->bs, 4);
			if (par == 0xF) {
				dsi->par_num = gf_bs_read_int(m4v->bs, 8);
				dsi->par_den = gf_bs_read_int(m4v->bs, 8);
			} else if (par<6) {
				dsi->par_num = m4v_sar[par].w;
				dsi->par_den = m4v_sar[par].h;
			}
			if (gf_bs_read_int(m4v->bs, 1)) {
				gf_bs_read_int(m4v->bs, 3);
				if (gf_bs_read_int(m4v->bs, 1)) gf_bs_read_int(m4v->bs, 79);
			}
			dsi->has_shape = gf_bs_read_int(m4v->bs, 2);
			if (dsi->has_shape && (verid!=1) ) gf_bs_read_int(m4v->bs, 4);
			gf_bs_read_int(m4v->bs, 1);
			/*clock rate*/
			dsi->clock_rate = gf_bs_read_int(m4v->bs, 16);
			/*marker*/
			gf_bs_read_int(m4v->bs, 1);

			clock_rate = dsi->clock_rate-1;
			if (clock_rate >= 65536) clock_rate = 65535;
			if (clock_rate > 0) {
				for (dsi->NumBitsTimeIncrement = 1; dsi->NumBitsTimeIncrement < 16; dsi->NumBitsTimeIncrement++)	{
					if (clock_rate == 1) break;
					clock_rate = (clock_rate >> 1);
				}
			} else {
				/*fix from vivien for divX*/
				dsi->NumBitsTimeIncrement = 1;
			}
			/*fixed FPS stream*/
			dsi->time_increment = 0;
			if (gf_bs_read_int(m4v->bs, 1)) {
				dsi->time_increment = gf_bs_read_int(m4v->bs, dsi->NumBitsTimeIncrement);
			}
			if (!dsi->has_shape) {
				gf_bs_read_int(m4v->bs, 1);
				dsi->width = gf_bs_read_int(m4v->bs, 13);
				gf_bs_read_int(m4v->bs, 1);
				dsi->height = gf_bs_read_int(m4v->bs, 13);
			} else {
				dsi->width = dsi->height = 0;
			}
			/*shape will be done later*/
			gf_bs_align(m4v->bs);
			break;

		case M4V_VOP_START_CODE:
		case M4V_GOV_START_CODE:
			go = 0;
			break;
		/*EOS*/
		case -1:
			go = 0;
			m4v->current_object_start = gf_bs_get_position(m4v->bs);
			break;
		/*don't interest us*/
		case M4V_UDTA_START_CODE:
		default:
			break;
		}
	}
	return GF_OK;
}
static GF_Err gf_m4v_parse_config_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi)
{
	s32 o_type;
	u8 go, verid, par;
	s32 clock_rate;

	if (!m4v || !dsi) return GF_BAD_PARAM;

	memset(dsi, 0, sizeof(GF_M4VDecSpecInfo));

	go = 1;
	while (go) {
		o_type = M4V_LoadObject(m4v);
		switch (o_type) {
		 
		case M4V_VOS_START_CODE:
			dsi->VideoPL = (u8) gf_bs_read_u8(m4v->bs);
			break;

		case M4V_VOL_START_CODE:
			verid = 0;
			dsi->RAP_stream = gf_bs_read_int(m4v->bs, 1);
			dsi->objectType = gf_bs_read_int(m4v->bs, 8);
			if (gf_bs_read_int(m4v->bs, 1)) {
				verid = gf_bs_read_int(m4v->bs, 4);
				gf_bs_read_int(m4v->bs, 3);
			}
			par = gf_bs_read_int(m4v->bs, 4);
			if (par == 0xF) {
				dsi->par_num = gf_bs_read_int(m4v->bs, 8);
				dsi->par_den = gf_bs_read_int(m4v->bs, 8);
			} else if (par<6) {
				dsi->par_num = m4v_sar[par].w;
				dsi->par_den = m4v_sar[par].h;
			}
			if (gf_bs_read_int(m4v->bs, 1)) {
				gf_bs_read_int(m4v->bs, 3);
				if (gf_bs_read_int(m4v->bs, 1)) gf_bs_read_int(m4v->bs, 79);
			}
			dsi->has_shape = gf_bs_read_int(m4v->bs, 2);
			if (dsi->has_shape && (verid!=1) ) gf_bs_read_int(m4v->bs, 4);
			gf_bs_read_int(m4v->bs, 1);
			 
			dsi->clock_rate = gf_bs_read_int(m4v->bs, 16);
			 
			gf_bs_read_int(m4v->bs, 1);

			clock_rate = dsi->clock_rate-1;
			if (clock_rate >= 65536) clock_rate = 65535;
			if (clock_rate > 0) {
				for (dsi->NumBitsTimeIncrement = 1; dsi->NumBitsTimeIncrement < 16; dsi->NumBitsTimeIncrement++)	{
					if (clock_rate == 1) break;
					clock_rate = (clock_rate >> 1);
				}
			} else {
				 
				dsi->NumBitsTimeIncrement = 1;
			}
			 
			dsi->time_increment = 0;
			if (gf_bs_read_int(m4v->bs, 1)) {
				dsi->time_increment = gf_bs_read_int(m4v->bs, dsi->NumBitsTimeIncrement);
			}
			if (!dsi->has_shape) {
				gf_bs_read_int(m4v->bs, 1);
				dsi->width = gf_bs_read_int(m4v->bs, 13);
				gf_bs_read_int(m4v->bs, 1);
				dsi->height = gf_bs_read_int(m4v->bs, 13);
			} else {
				dsi->width = dsi->height = 0;
			}
			 
			gf_bs_align(m4v->bs);
			break;

		case M4V_VOP_START_CODE:
		case M4V_GOV_START_CODE:
			go = 0;
			break;
		 
		case -1:
			go = 0;
			m4v->current_object_start = gf_bs_get_position(m4v->bs);
			break;
		 
		case M4V_UDTA_START_CODE:
		default:
			break;
		}
	}
	return GF_OK;
}