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

📄 av_parsers.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
			avc_get_ue(bs);  /* chroma_sample_location_type_bottom_field */		}		sps->timing_info_present_flag = gf_bs_read_int(bs, 1);		if (sps->timing_info_present_flag) {			sps->num_units_in_tick = gf_bs_read_int(bs, 32);			sps->time_scale = gf_bs_read_int(bs, 32);			sps->fixed_frame_rate_flag = gf_bs_read_int(bs, 1);		}	}    return sps_id;}s32 AVC_ReadPictParamSet(GF_BitStream *bs, AVCState *avc){    s32 pps_id = avc_get_ue(bs);    AVC_PPS *pps= &avc->pps[pps_id];   	if (!pps->status) pps->status = 1;    pps->sps_id= avc_get_ue(bs);    /*pps->cabac = */gf_bs_read_int(bs, 1);    /*pps->pic_order_present= */gf_bs_read_int(bs, 1);    pps->slice_group_count= avc_get_ue(bs) + 1;    if (pps->slice_group_count > 1 ) /*pps->mb_slice_group_map_type = */avc_get_ue(bs);    /*pps->ref_count[0]= */avc_get_ue(bs) /*+ 1*/;    /*pps->ref_count[1]= */avc_get_ue(bs) /*+ 1*/;    /*	if ((pps->ref_count[0] > 32) || (pps->ref_count[1] > 32)) return -1;	*/        /*pps->weighted_pred = */gf_bs_read_int(bs, 1);    /*pps->weighted_bipred_idc = */gf_bs_read_int(bs, 2);    /*pps->init_qp = */avc_get_se(bs) /*+ 26*/;    /*pps->init_qs= */avc_get_se(bs) /*+ 26*/;    /*pps->chroma_qp_index_offset = */avc_get_se(bs);    /*pps->deblocking_filter_parameters_present = */gf_bs_read_int(bs, 1);    /*pps->constrained_intra_pred = */gf_bs_read_int(bs, 1);    pps->redundant_pic_cnt_present = gf_bs_read_int(bs, 1);    return pps_id;}static s32 avc_parse_slice(GF_BitStream *bs, AVCState *avc, AVCSliceInfo *si) {    s32 first_mb_in_slice, pps_id;    /*s->current_picture.reference= h->nal_ref_idc != 0;*/    first_mb_in_slice = avc_get_ue(bs);    si->slice_type = avc_get_ue(bs);    if (si->slice_type > 9) return -1;    pps_id = avc_get_ue(bs);    if (pps_id>255) return -1;    si->pps = &avc->pps[pps_id];    if (!si->pps->slice_group_count) return -2;    si->sps = &avc->sps[si->pps->sps_id];    if (!si->sps->log2_max_frame_num) return -2;    si->frame_num = gf_bs_read_int(bs, si->sps->log2_max_frame_num);	si->field_pic_flag = 0;    if (si->sps->frame_mbs_only_flag) {        /*s->picture_structure= PICT_FRAME;*/    } else {		si->field_pic_flag = gf_bs_read_int(bs, 1);        if (si->field_pic_flag) si->bottom_field_flag = gf_bs_read_int(bs, 1);    }	if (si->nal_unit_type==GF_AVC_NALU_IDR_SLICE)		si->idr_pic_id = avc_get_ue(bs);       if (si->sps->poc_type==0) {		si->poc_lsb = gf_bs_read_int(bs, si->sps->log2_max_poc_lsb);		if (si->pps->pic_order_present && !si->field_pic_flag) {			si->delta_poc_bottom = avc_get_se(bs);		}	} else if ((si->sps->poc_type==1) && !si->sps->delta_pic_order_always_zero_flag) {        si->delta_poc[0] = avc_get_se(bs);        if ((si->pps->pic_order_present==1) && !si->field_pic_flag)            si->delta_poc[1] = avc_get_se(bs);    }    if (si->pps->redundant_pic_cnt_present) {        si->redundant_pic_cnt = avc_get_ue(bs);    }	return 0;}static s32 avc_parse_recovery_point_sei(GF_BitStream *bs, AVCState *avc) {	AVCSeiRecoveryPoint *rp = &avc->sei.recovery_point;	rp->frame_cnt = avc_get_ue(bs);	rp->exact_match_flag = gf_bs_read_int(bs, 1);	rp->broken_link_flag = gf_bs_read_int(bs, 1);	rp->changing_slice_group_idc = gf_bs_read_int(bs, 2);	rp->valid = 1;	return 0;}static void avc_compute_poc(AVCSliceInfo *si){	enum {		AVC_PIC_FRAME,		AVC_PIC_FIELD_TOP,		AVC_PIC_FIELD_BOTTOM,	} pic_type;	s32 field_poc[2] = {0,0};	s32 max_frame_num = 1 << (si->sps->log2_max_frame_num);	/* picture type */	if (si->sps->frame_mbs_only_flag || !si->field_pic_flag) pic_type = AVC_PIC_FRAME;	else if (si->bottom_field_flag) pic_type = AVC_PIC_FIELD_BOTTOM;	else pic_type = AVC_PIC_FIELD_TOP;	/* frame_num_offset */	if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE) {		si->poc_lsb_prev = 0;		si->poc_msb_prev = 0;		si->frame_num_offset = 0;	} else {		if (si->frame_num < si->frame_num_prev)			si->frame_num_offset = si->frame_num_offset_prev + max_frame_num;		else			si->frame_num_offset = si->frame_num_offset_prev;	}		if (si->sps->poc_type==0) {		const u32 max_poc_lsb = 1 << (si->sps->log2_max_poc_lsb);				if ((si->poc_lsb < si->poc_lsb_prev) &&		(si->poc_lsb_prev - si->poc_lsb >= max_poc_lsb / 2) )			si->poc_msb = si->poc_msb_prev + max_poc_lsb;		else if ((si->poc_lsb > si->poc_lsb_prev) &&		(si->poc_lsb - si->poc_lsb_prev > max_poc_lsb / 2))			si->poc_msb = si->poc_msb_prev - max_poc_lsb;		else			si->poc_msb = si->poc_msb_prev;		field_poc[0] = field_poc[1] = si->poc_msb + si->poc_lsb;		if (pic_type == AVC_PIC_FRAME) field_poc[1] += si->delta_poc_bottom;	} else if (si->sps->poc_type==1) {		u32 i;		s32 abs_frame_num, expected_delta_per_poc_cycle, expected_poc;		if (si->sps->poc_cycle_length)			abs_frame_num = si->frame_num_offset + si->frame_num;		else			abs_frame_num = 0;		if (!si->nal_ref_idc && (abs_frame_num > 0)) abs_frame_num--;		expected_delta_per_poc_cycle = 0;		for (i=0; i < si->sps->poc_cycle_length; i++)			expected_delta_per_poc_cycle += si->sps->offset_for_ref_frame[i];		if (abs_frame_num > 0) {			const u32 poc_cycle_cnt = ( abs_frame_num - 1 ) / si->sps->poc_cycle_length;			const u32 frame_num_in_poc_cycle = ( abs_frame_num - 1 ) % si->sps->poc_cycle_length;			expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;			for (i = 0; i<=frame_num_in_poc_cycle; i++)				expected_poc += si->sps->offset_for_ref_frame[i];		} else {			expected_poc = 0;		}		if (!si->nal_ref_idc) expected_poc += si->sps->offset_for_non_ref_pic;		field_poc[0] = expected_poc + si->delta_poc[0];		field_poc[1] = field_poc[0] + si->sps->offset_for_top_to_bottom_field;		if (pic_type == AVC_PIC_FRAME) field_poc[1] += si->delta_poc[1];	} else if (si->sps->poc_type== 2) {		int poc;		if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE) {			poc = 0;		} else {			const int abs_frame_num = si->frame_num_offset + si->frame_num;			poc = 2 * abs_frame_num;			if (!si->nal_ref_idc) poc -= 1;		}		field_poc[0] = poc;		field_poc[1] = poc;	}	if (pic_type == AVC_PIC_FRAME)		si->poc = MIN(field_poc[0], field_poc[1] );	else if (pic_type == AVC_PIC_FIELD_TOP)		si->poc = field_poc[0];	else		si->poc = field_poc[1];}s32 AVC_ParseNALU(GF_BitStream *bs, u32 nal_hdr, AVCState *avc){	u8 temp;	s32 slice, ret;	AVCSliceInfo n_state;	slice = 0;	memcpy(&n_state, &avc->s_info, sizeof(AVCSliceInfo));	temp = n_state.nal_unit_type = nal_hdr & 0x1F;	n_state.nal_ref_idc = (nal_hdr>>5) & 0x3;		ret = 0;	switch (temp) {	case GF_AVC_NALU_ACCESS_UNIT:	case GF_AVC_NALU_END_OF_SEQ:	case GF_AVC_NALU_END_OF_STREAM:		ret = 1;		break;	case GF_AVC_NALU_NON_IDR_SLICE:	case GF_AVC_NALU_DP_A_SLICE:	case GF_AVC_NALU_DP_B_SLICE:	case GF_AVC_NALU_DP_C_SLICE:	case GF_AVC_NALU_IDR_SLICE:		slice = 1;		/* slice buffer - read the info and compare.*/		ret = avc_parse_slice(bs, avc, &n_state);		if (ret<0) return ret;		ret = 0;		if ((avc->s_info.nal_unit_type > GF_AVC_NALU_IDR_SLICE)			|| (avc->s_info.nal_unit_type < GF_AVC_NALU_NON_IDR_SLICE)) {			break;		}		if (avc->s_info.frame_num != n_state.frame_num) { ret = 1; break; }		if (avc->s_info.field_pic_flag != n_state.field_pic_flag) { ret = 1; break; }		if ((avc->s_info.nal_ref_idc != n_state.nal_ref_idc) &&			(!avc->s_info.nal_ref_idc || !n_state.nal_ref_idc)) {			ret = 1;			break;		}		assert(avc->s_info.sps);		if (avc->s_info.sps->poc_type == n_state.sps->poc_type) {			if (!avc->s_info.sps->poc_type) {				if (avc->s_info.poc_lsb != n_state.poc_lsb) { ret = 1; break; }				if (avc->s_info.delta_poc_bottom != n_state.delta_poc_bottom) {					ret = 1;					break;				}			} else if (avc->s_info.sps->poc_type==1) {				if (avc->s_info.delta_poc[0] != n_state.delta_poc[0]) {					ret =1;					break;				}				if (avc->s_info.delta_poc[1] != n_state.delta_poc[1]) {					ret = 1;					break;				}			}		}		if ((avc->s_info.nal_unit_type == GF_AVC_NALU_IDR_SLICE) 		&& (n_state.nal_unit_type == GF_AVC_NALU_IDR_SLICE)) {			if (avc->s_info.idr_pic_id != n_state.idr_pic_id) {				ret = 1;				break;			}		}		break;	default:		if (avc->s_info.nal_unit_type <= GF_AVC_NALU_IDR_SLICE) ret = 1;		else ret = 0;		break;	} 	/* save _prev values */	if (ret && avc->s_info.sps) {		n_state.frame_num_offset_prev = avc->s_info.frame_num_offset;		if ((avc->s_info.sps->poc_type != 2) || (avc->s_info.nal_ref_idc != 0))			n_state.frame_num_prev = avc->s_info.frame_num;		if (avc->s_info.nal_ref_idc) {			n_state.poc_lsb_prev = avc->s_info.poc_lsb;			n_state.poc_msb_prev = avc->s_info.poc_msb;		}	}	if (slice) avc_compute_poc(&n_state);	memcpy(&avc->s_info, &n_state, sizeof(AVCSliceInfo));	return ret;}u32 AVC_ReformatSEI_NALU(char *buffer, u32 nal_size, AVCState *avc){	u32 ptype, psize, hdr, written, start, var, num_zero, size_fix, i;	char *new_buffer;	GF_BitStream *bs;	hdr = buffer[0];	if ((hdr & 0x1F) != GF_AVC_NALU_SEI) return 0;		bs = gf_bs_new(buffer, nal_size, GF_BITSTREAM_READ);	gf_bs_read_int(bs, 8);	new_buffer = (char*)malloc(sizeof(char)*nal_size);	new_buffer[0] = (char) hdr;	written = 1;	/*parse SEI*/	while (gf_bs_available(bs)) {		Bool do_copy;		ptype = 0;		while (gf_bs_peek_bits(bs, 8, 0)==0xFF) {			gf_bs_read_int(bs, 8);			ptype += 255;		}		ptype += gf_bs_read_int(bs, 8);		psize = 0;		while (gf_bs_peek_bits(bs, 8, 0)==0xFF) {			gf_bs_read_int(bs, 8);			psize += 255;		}		psize += gf_bs_read_int(bs, 8);		start = (u32) gf_bs_get_position(bs);		do_copy = 1;		switch (ptype) {		/*remove SEI messages forbidden in MP4*/		case 3: /*filler data*/		case 10: /*sub_seq info*/		case 11: /*sub_seq_layer char*/		case 12: /*sub_seq char*/			do_copy = 0;			break;		case 5: /*user unregistered */		{			u8 prev = buffer[start+2+psize];			buffer[start+2+psize] = 0;			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[avc-h264] SEI user message %s\n", buffer+start+2)); 			buffer[start+2+psize] = prev;		}			break;				case 6: /*recovery point*/			{				GF_BitStream *rp_bs = gf_bs_new(buffer + start, psize, GF_BITSTREAM_READ);				avc_parse_recovery_point_sei(rp_bs, avc);				gf_bs_del(rp_bs);			}			break;		case 0: /*buffering period*/		case 1: /*pic_timing*/		case 2: /*pan scan rect*/		case 4: /*user registered ITU t35*/		case 7: /*def_rec_pic_marking_repetition*/		case 8: /*spare_pic*/		case 9: /*scene info*/		case 13: /*full frame freeze*/		case 14: /*full frame freeze release*/		case 15: /*full frame snapshot*/		case 16: /*progressive refinement segment start*/		case 17: /*progressive refinement segment end*/		case 18: /*motion constrained slice group*/		default:/*reserved*/			break;		}		/*fix payload size due to emulation prevention bytes*/		size_fix = 0;		num_zero = 0;		for (i = 0; i < psize + size_fix; i++)		{			if (!buffer[start + i])				num_zero++;			else			{				if ((num_zero == 2) && (buffer[start + i] == 3))					size_fix++;				num_zero = 0;			}		}		if (do_copy) {			var = ptype;			while (var>=255) { new_buffer[written] = (char) 0xff; written++; var-=255;}			new_buffer[written] = (char) var; written++;			var = psize;			while (var>=255) { new_buffer[written] = (char) 0xff; written++; var-=255;}			new_buffer[written] = (char) var; written++;			memcpy(new_buffer+written, buffer+start, sizeof(char)* (psize + size_fix));			written += psize;		}		gf_bs_skip_bytes(bs, (u64) (psize + size_fix));		gf_bs_align(bs);		if (gf_bs_available(bs)<2) {			if (gf_bs_peek_bits(bs, 8, 0)==0x80) {				new_buffer[written] = (char) 0x80;				written += 1;				break;			}		}	}	gf_bs_del(bs);	assert(written<=nal_size);	if (written) memcpy(buffer, new_buffer, sizeof(char)*written);	free(new_buffer);	/*if only hdr written ignore*/	return (written>1) ? written : 0;}static u8 avc_get_sar_idx(u32 w, u32 h){	u32 i;	for (i=0; i<14; i++) {		if ((avc_sar[i].w==w) && (avc_sar[i].h==h)) return i;	}	return 0xFF;}GF_Err AVC_ChangePAR(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d){	GF_BitStream *orig, *mod;	AVCState avc;	u32 i, bit_offset, flag;	s32 idx;	GF_AVCConfigSlot *slc;	memset(&avc, 0, sizeof(AVCState));	i=0;	while ((slc = (GF_AVCConfigSlot *)gf_list_enum(avcc->sequenceParameterSets, &i))) {		orig = gf_bs_new(slc->data, slc->size, GF_BITSTREAM_READ);		/*skip NALU type*/		gf_bs_read_int(orig, 8);		idx = AVC_ReadSeqInfo(orig, &avc, &bit_offset);		if (idx<0) {			gf_bs_del(orig);			continue;		}		mod = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);		gf_bs_seek(orig, 0);		/*copy over till vui flag*/		while (bit_offset) {			flag = gf_bs_read_int(orig, 1);			gf_bs_write_int(mod, flag, 1);			bit_offset--;		}		/*check VUI*/		flag = gf_bs_read_int(orig, 1);		gf_bs_write_int(mod, 1, 1);		if (flag) {			/*aspect_ratio_info_present_flag*/			if (gf_bs_read_int(orig, 1)) {				s32 aspect_ratio_idc = gf_bs_read_int(orig, 8);				if (aspect_ratio_idc == 255) {					gf_bs_read_int(orig, 16); /*AR num*/					gf_bs_read_int(orig, 16); /*AR den*/				}			}		}		if ((ar_d<0) || (ar_n<0)) {			/*no AR signaled*/			gf_bs_write_int(mod, 0, 1);		} else {			u32 sarx;			gf_bs_write_int(mod, 1, 1);			sarx = avc_get_sar_idx((u32) ar_n, (u32) ar_d);			gf_bs_write_int(mod, sarx, 8);			if (sarx==0xFF) {				gf_bs_write_int(mod, ar_n, 16);				gf_bs_write_int(mod, ar_d, 16);			}		}		/*no VUI in input bitstream, set all vui flags to 0*/		if (!flag) {			gf_bs_write_int(mod, 0, 1);     /*overscan_info_present_flag */			gf_bs_write_int(mod, 0, 1);     /*video_signal_type_present_flag */			gf_bs_write_int(mod, 0, 1);     /*chroma_location_info_present_flag */			gf_bs_write_int(mod, 0, 1);		/*timing_info_present_flag*/			gf_bs_write_int(mod, 0, 1);		/*nal_hrd_parameters_present*/			gf_bs_write_int(mod, 0, 1);		/*vcl_hrd_parameters_present*/			gf_bs_write_int(mod, 0, 1);		/*pic_struct_present*/			gf_bs_write_int(mod, 0, 1);		/*bitstream_restriction*/		}		/*finally copy over remaining*/		while (gf_bs_bits_available(orig)) {			flag = gf_bs_read_int(orig, 1);			gf_bs_write_int(mod, flag, 1);		}		gf_bs_del(orig);		free(slc->data);		slc->data = NULL;		gf_bs_get_content(mod, (char **) &slc->data, &flag);		slc->size = flag;		gf_bs_del(mod);	}	return GF_OK;}GF_EXPORTGF_Err gf_avc_get_sps_info(char *sps_data, u32 sps_size, u32 *width, u32 *height, s32 *par_n, s32 *par_d){	GF_BitStream *bs;	AVCState avc;	s32 idx;	memset(&avc, 0, sizeof(AVCState));	bs = gf_bs_new(sps_data, sps_size, GF_BITSTREAM_READ);	/*skip NALU type*/	gf_bs_read_int(bs, 8);	idx = AVC_ReadSeqInfo(bs, &avc, NULL);	gf_bs_del(bs);

⌨️ 快捷键说明

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