www.pudn.com > NETVIDEO.rar > headers.c


#include "../mpeg3private.h" 
#include "../mpeg3protos.h" 
#include "mpeg3video.h" 
 
#include  
#include  
 
int mpeg3video_getseqhdr(mpeg3video_t *video) 
{ 
	int i; 
 
	int aspect_ratio, picture_rate, vbv_buffer_size; 
	int constrained_parameters_flag; 
	int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix; 
 
	video->horizontal_size = mpeg3bits_getbits(video->vstream, 12); 
	video->vertical_size = mpeg3bits_getbits(video->vstream, 12); 
	aspect_ratio = mpeg3bits_getbits(video->vstream, 4); 
	video->framerate_code = mpeg3bits_getbits(video->vstream, 4); 
	video->bitrate = mpeg3bits_getbits(video->vstream, 18); 
	mpeg3bits_getbit_noptr(video->vstream); /* marker bit (=1) */ 
	vbv_buffer_size = mpeg3bits_getbits(video->vstream, 10); 
	constrained_parameters_flag = mpeg3bits_getbit_noptr(video->vstream); 
	video->frame_rate = mpeg3_frame_rate_table[video->framerate_code]; 
 
 	load_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream); 
 	if(load_intra_quantizer_matrix) 
	{ 
    	for(i = 0; i < 64; i++) 
      		video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); 
  	} 
  	else  
	{ 
    	for(i = 0; i < 64; i++) 
      		video->intra_quantizer_matrix[i] = mpeg3_default_intra_quantizer_matrix[i]; 
  	} 
 
	load_non_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream); 
	if(load_non_intra_quantizer_matrix) 
	{ 
    	for(i = 0; i < 64; i++) 
      		video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); 
  	} 
  	else  
	{ 
    	for(i = 0; i < 64; i++) 
      		video->non_intra_quantizer_matrix[i] = 16; 
  	} 
 
/* copy luminance to chrominance matrices */ 
  	for(i = 0; i < 64; i++) 
	{ 
    	video->chroma_intra_quantizer_matrix[i] = video->intra_quantizer_matrix[i]; 
   	 	video->chroma_non_intra_quantizer_matrix[i] = video->non_intra_quantizer_matrix[i]; 
  	} 
 
	return 0; 
} 
 
 
/* decode sequence extension */ 
 
int mpeg3video_sequence_extension(mpeg3video_t *video) 
{ 
	int prof_lev; 
	int horizontal_size_extension, vertical_size_extension; 
	int bit_rate_extension, vbv_buffer_size_extension, low_delay; 
	int frame_rate_extension_n, frame_rate_extension_d; 
	int pos = 0; 
 
	video->mpeg2 = 1; 
	video->scalable_mode = SC_NONE; /* unless overwritten by seq. scal. ext. */ 
	prof_lev = mpeg3bits_getbyte_noptr(video->vstream); 
	video->prog_seq = mpeg3bits_getbit_noptr(video->vstream); 
	video->chroma_format = mpeg3bits_getbits(video->vstream, 2); 
	horizontal_size_extension = mpeg3bits_getbits(video->vstream, 2); 
	vertical_size_extension = mpeg3bits_getbits(video->vstream, 2); 
	bit_rate_extension = mpeg3bits_getbits(video->vstream, 12); 
	mpeg3bits_getbit_noptr(video->vstream); 
	vbv_buffer_size_extension = mpeg3bits_getbyte_noptr(video->vstream); 
	low_delay = mpeg3bits_getbit_noptr(video->vstream); 
	frame_rate_extension_n = mpeg3bits_getbits(video->vstream, 2); 
	frame_rate_extension_d = mpeg3bits_getbits(video->vstream, 5); 
	video->horizontal_size = (horizontal_size_extension << 12) | (video->horizontal_size & 0x0fff); 
	video->vertical_size = (vertical_size_extension << 12) | (video->vertical_size & 0x0fff); 
	return 0; 
} 
 
 
/* decode sequence display extension */ 
 
int mpeg3video_sequence_display_extension(mpeg3video_t *video) 
{ 
	int colour_primaries = 0, transfer_characteristics = 0; 
	int display_horizontal_size, display_vertical_size; 
	int pos = 0; 
	int video_format = mpeg3bits_getbits(video->vstream, 3); 
	int colour_description = mpeg3bits_getbit_noptr(video->vstream); 
 
	if(colour_description) 
	{ 
    	colour_primaries = mpeg3bits_getbyte_noptr(video->vstream); 
    	transfer_characteristics = mpeg3bits_getbyte_noptr(video->vstream); 
    	video->matrix_coefficients = mpeg3bits_getbyte_noptr(video->vstream); 
	} 
 
	display_horizontal_size = mpeg3bits_getbits(video->vstream, 14); 
	mpeg3bits_getbit_noptr(video->vstream); 
	display_vertical_size = mpeg3bits_getbits(video->vstream, 14); 
	return 0; 
} 
 
 
/* decode quant matrix entension */ 
 
int mpeg3video_quant_matrix_extension(mpeg3video_t *video) 
{ 
	int i; 
	int load_intra_quantiser_matrix, load_non_intra_quantiser_matrix; 
	int load_chroma_intra_quantiser_matrix; 
	int load_chroma_non_intra_quantiser_matrix; 
	int pos = 0; 
 
	if((load_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) 
	{ 
      	for(i = 0; i < 64; i++) 
		{ 
    		video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] 
    			= video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] 
    			= mpeg3bits_getbyte_noptr(video->vstream); 
      	} 
	} 
 
	if((load_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) 
	{ 
    	for (i = 0; i < 64; i++) 
		{ 
    		video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] 
    			= video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] 
    			= mpeg3bits_getbyte_noptr(video->vstream); 
    	} 
	} 
 
	if((load_chroma_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) 
	{ 
    	for(i = 0; i < 64; i++) 
    		video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); 
	} 
 
	if((load_chroma_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0) 
	{ 
      	for(i = 0; i < 64; i++) 
    		video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream); 
	} 
	return 0; 
} 
 
 
/* decode sequence scalable extension */ 
 
int mpeg3video_sequence_scalable_extension(mpeg3video_t *video) 
{ 
	int layer_id; 
 
	video->scalable_mode = mpeg3bits_getbits(video->vstream, 2) + 1; /* add 1 to make SC_DP != SC_NONE */ 
	layer_id = mpeg3bits_getbits(video->vstream, 4); 
 
	if(video->scalable_mode == SC_SPAT) 
	{ 
    	video->llw = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_horizontal_size */ 
    	mpeg3bits_getbit_noptr(video->vstream); 
    	video->llh = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_vertical_size */ 
    	video->hm = mpeg3bits_getbits(video->vstream, 5); 
    	video->hn = mpeg3bits_getbits(video->vstream, 5); 
    	video->vm = mpeg3bits_getbits(video->vstream, 5); 
    	video->vn = mpeg3bits_getbits(video->vstream, 5); 
	} 
 
	if(video->scalable_mode == SC_TEMP) 
      	fprintf(stderr, "mpeg3video_sequence_scalable_extension: temporal scalability not implemented\n"); 
	return 0; 
} 
 
 
/* decode picture display extension */ 
 
int mpeg3video_picture_display_extension(mpeg3video_t *video) 
{ 
	int n, i; 
	short frame_centre_horizontal_offset[3]; 
	short frame_centre_vertical_offset[3]; 
 
 
 
	if(video->prog_seq || video->pict_struct != FRAME_PICTURE) 
		n = 1; 
	else  
		n = video->repeatfirst ? 3 : 2; 
 
 
 
 
	for(i = 0; i < n; i++) 
	{ 
    	frame_centre_horizontal_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16); 
    	mpeg3bits_getbit_noptr(video->vstream); 
    	frame_centre_vertical_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16); 
    	mpeg3bits_getbit_noptr(video->vstream); 
	} 
	return 0; 
} 
 
 
/* decode picture coding extension */ 
 
int mpeg3video_picture_coding_extension(mpeg3video_t *video) 
{ 
	int chroma_420_type, composite_display_flag; 
	int v_axis = 0, field_sequence = 0, sub_carrier = 0, burst_amplitude = 0, sub_carrier_phase = 0; 
 
	video->h_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; 
	video->v_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; 
	video->h_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; 
	video->v_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1; 
	video->dc_prec = mpeg3bits_getbits(video->vstream, 2); 
	video->pict_struct = mpeg3bits_getbits(video->vstream, 2); 
	video->topfirst = mpeg3bits_getbit_noptr(video->vstream); 
	video->frame_pred_dct = mpeg3bits_getbit_noptr(video->vstream); 
	video->conceal_mv = mpeg3bits_getbit_noptr(video->vstream); 
	video->qscale_type = mpeg3bits_getbit_noptr(video->vstream); 
	video->intravlc = mpeg3bits_getbit_noptr(video->vstream); 
	video->altscan = mpeg3bits_getbit_noptr(video->vstream); 
 
 
	video->repeatfirst = mpeg3bits_getbit_noptr(video->vstream); 
 
 
	chroma_420_type = mpeg3bits_getbit_noptr(video->vstream); 
	video->prog_frame = mpeg3bits_getbit_noptr(video->vstream); 
 
	if(video->repeat_count > 100) 
		video->repeat_count = 0; 
	video->repeat_count += 100; 
 
	video->current_repeat = 0; 
 
	if(video->prog_seq) 
	{ 
		if(video->repeatfirst) 
		{ 
			if(video->topfirst) 
				video->repeat_count += 200; 
			else 
				video->repeat_count += 100; 
		} 
	} 
	else 
	if(video->prog_frame) 
	{ 
		if(video->repeatfirst) 
		{ 
			video->repeat_count += 50; 
		} 
	} 
 
/*printf("mpeg3video_picture_coding_extension %d\n", video->repeat_count); */ 
	composite_display_flag = mpeg3bits_getbit_noptr(video->vstream); 
 
	if(composite_display_flag) 
	{ 
    	v_axis = mpeg3bits_getbit_noptr(video->vstream); 
    	field_sequence = mpeg3bits_getbits(video->vstream, 3); 
    	sub_carrier = mpeg3bits_getbit_noptr(video->vstream); 
    	burst_amplitude = mpeg3bits_getbits(video->vstream, 7); 
    	sub_carrier_phase = mpeg3bits_getbyte_noptr(video->vstream); 
	} 
	return 0; 
} 
 
 
/* decode picture spatial scalable extension */ 
 
int mpeg3video_picture_spatial_scalable_extension(mpeg3video_t *video) 
{ 
	video->pict_scal = 1; /* use spatial scalability in this picture */ 
 
	video->lltempref = mpeg3bits_getbits(video->vstream, 10); 
	mpeg3bits_getbit_noptr(video->vstream); 
	video->llx0 = mpeg3bits_getbits(video->vstream, 15); 
	if(video->llx0 >= 16384) video->llx0 -= 32768; 
	mpeg3bits_getbit_noptr(video->vstream); 
	video->lly0 = mpeg3bits_getbits(video->vstream, 15); 
	if(video->lly0 >= 16384) video->lly0 -= 32768; 
	video->stwc_table_index = mpeg3bits_getbits(video->vstream, 2); 
	video->llprog_frame = mpeg3bits_getbit_noptr(video->vstream); 
	video->llfieldsel = mpeg3bits_getbit_noptr(video->vstream); 
	return 0; 
} 
 
 
/* decode picture temporal scalable extension 
 * 
 * not implemented 
 * 
 */ 
 
int mpeg3video_picture_temporal_scalable_extension(mpeg3video_t *video) 
{ 
  	fprintf(stderr, "mpeg3video_picture_temporal_scalable_extension: temporal scalability not supported\n"); 
	return 0; 
} 
 
 
/* decode extension and user data */ 
 
int mpeg3video_ext_user_data(mpeg3video_t *video) 
{ 
  	int code = mpeg3bits_next_startcode(video->vstream); 
 
 
  	while((code == MPEG3_EXT_START_CODE || code == MPEG3_USER_START_CODE) && 
		!mpeg3bits_eof(video->vstream)) 
	{ 
    	mpeg3bits_refill(video->vstream); 
		 
    	if(code == MPEG3_EXT_START_CODE) 
		{ 
      		int ext_id = mpeg3bits_getbits(video->vstream, 4); 
      		switch(ext_id) 
			{ 
    			case SEQ_ID: 
					mpeg3video_sequence_extension(video); 
					break; 
    			case DISP_ID: 
					mpeg3video_sequence_display_extension(video); 
					break; 
    			case QUANT_ID: 
					mpeg3video_quant_matrix_extension(video); 
					break; 
    			case SEQSCAL_ID: 
					mpeg3video_sequence_scalable_extension(video); 
					break; 
    			case PANSCAN_ID: 
					mpeg3video_picture_display_extension(video); 
					break; 
    			case CODING_ID: 
					mpeg3video_picture_coding_extension(video); 
					break; 
    			case SPATSCAL_ID: 
					mpeg3video_picture_spatial_scalable_extension(video); 
					break; 
    			case TEMPSCAL_ID: 
					mpeg3video_picture_temporal_scalable_extension(video); 
					break; 
    			default: 
					fprintf(stderr,"mpeg3video_ext_user_data: reserved extension start code ID %d\n", ext_id); 
					break; 
      		} 
   		} 
   		code = mpeg3bits_next_startcode(video->vstream); 
  	} 
	return 0; 
} 
 
 
/* decode group of pictures header */ 
 
int mpeg3video_getgophdr(mpeg3video_t *video) 
{ 
	int drop_flag, closed_gop, broken_link; 
 
//printf("%x\n", mpeg3bits_tell(video->vstream)); 
	video->has_gops = 1; 
	drop_flag = mpeg3bits_getbit_noptr(video->vstream); 
	video->gop_timecode.hour = mpeg3bits_getbits(video->vstream, 5); 
	video->gop_timecode.minute = mpeg3bits_getbits(video->vstream, 6); 
	mpeg3bits_getbit_noptr(video->vstream); 
	video->gop_timecode.second = mpeg3bits_getbits(video->vstream, 6); 
	video->gop_timecode.frame = mpeg3bits_getbits(video->vstream, 6); 
	closed_gop = mpeg3bits_getbit_noptr(video->vstream); 
	broken_link = mpeg3bits_getbit_noptr(video->vstream); 
 
/* 
 * printf("%d:%d:%d:%d %d %d %d\n", video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame,  
 *  	drop_flag, closed_gop, broken_link); 
 */ 
	return mpeg3bits_error(video->vstream); 
} 
 
/* decode picture header */ 
 
int mpeg3video_getpicturehdr(mpeg3video_t *video) 
{ 
	int temp_ref, vbv_delay; 
 
	video->pict_scal = 0; /* unless overwritten by pict. spat. scal. ext. */ 
 
	temp_ref = mpeg3bits_getbits(video->vstream, 10); 
	video->pict_type = mpeg3bits_getbits(video->vstream, 3); 
	vbv_delay = mpeg3bits_getbits(video->vstream, 16); 
 
	if(video->pict_type == P_TYPE || video->pict_type == B_TYPE) 
	{ 
    	video->full_forw = mpeg3bits_getbit_noptr(video->vstream); 
    	video->forw_r_size = mpeg3bits_getbits(video->vstream, 3) - 1; 
	} 
 
	if(video->pict_type == B_TYPE) 
	{ 
    	video->full_back = mpeg3bits_getbit_noptr(video->vstream); 
    	video->back_r_size = mpeg3bits_getbits(video->vstream, 3) - 1; 
	} 
 
/* get extra bit picture */ 
	while(mpeg3bits_getbit_noptr(video->vstream) && 
		!mpeg3bits_eof(video->vstream))  
		mpeg3bits_getbyte_noptr(video->vstream); 
	return 0; 
} 
 
 
int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat) 
{ 
	unsigned int code; 
 
/* a sequence header should be found before returning from `getheader' the */ 
/* first time (this is to set horizontal/vertical size properly) */ 
 
/* Repeat the frame until it's less than 1 count from repeat_count */ 
	if(video->repeat_count - video->current_repeat >= 100 && !dont_repeat) 
	{ 
		return 0; 
	} 
 
	if(dont_repeat) 
	{ 
		video->repeat_count = 0; 
		video->current_repeat = 0; 
	} 
	else 
		video->repeat_count -= video->current_repeat; 
 
//printf("mpeg3video_get_header 1 %d %d\n",  
//	video->vstream->demuxer->titles[0]->fs->current_byte,  
//	video->vstream->demuxer->titles[0]->fs->total_bytes); 
 
	while(1) 
	{ 
//printf("mpeg3video_get_header 1 %llx\n", mpeg3bits_tell(video->vstream)); 
/* look for startcode */ 
    	code = mpeg3bits_next_startcode(video->vstream); 
 
 
//printf("mpeg3video_get_header 2 %x %x %08x\n",  
//	video->vstream->demuxer->titles[0]->fs->current_byte,  
//	video->vstream->demuxer->titles[0]->fs->total_bytes, 
//	code); 
//printf("mpeg3video_get_header 2 %d\n", mpeg3bits_eof(video->vstream)); 
		if(mpeg3bits_eof(video->vstream)) return 1; 
		if(code != MPEG3_SEQUENCE_END_CODE) mpeg3bits_refill(video->vstream); 
  
    	switch(code) 
		{ 
    		case MPEG3_SEQUENCE_START_CODE: 
    			video->found_seqhdr = 1; 
    			mpeg3video_getseqhdr(video);   
    			mpeg3video_ext_user_data(video); 
    			break; 
 
    		case MPEG3_GOP_START_CODE: 
    			mpeg3video_getgophdr(video); 
    			mpeg3video_ext_user_data(video); 
    			break; 
 
    		case MPEG3_PICTURE_START_CODE: 
//printf("%x\n", mpeg3bits_tell(video->vstream)); 
    			mpeg3video_getpicturehdr(video); 
    			mpeg3video_ext_user_data(video); 
    			if(video->found_seqhdr) return 0;       /* Exit here */ 
    			break; 
 
    		case MPEG3_SEQUENCE_END_CODE: 
// Continue until the end 
				mpeg3bits_refill(video->vstream); 
				break; 
 
    		default: 
    			break; 
    	} 
  	} 
 	return 1;      /* Shouldn't be reached. */ 
} 
 
int mpeg3video_ext_bit_info(mpeg3_slice_buffer_t *slice_buffer) 
{ 
	while(mpeg3slice_getbit(slice_buffer)) mpeg3slice_getbyte(slice_buffer); 
	return 0; 
} 
 
/* decode slice header */ 
int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video) 
{ 
	int slice_vertical_position_extension, intra_slice; 
	int qs; 
 
  	slice_vertical_position_extension = (video->mpeg2 && video->vertical_size > 2800) ?  
		mpeg3slice_getbits(slice->slice_buffer, 3) : 0; 
 
  	if(video->scalable_mode == SC_DP) slice->pri_brk = mpeg3slice_getbits(slice->slice_buffer, 7); 
 
  	qs = mpeg3slice_getbits(slice->slice_buffer, 5); 
  	slice->quant_scale = video->mpeg2 ? (video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1)) : qs; 
 
  	if(mpeg3slice_getbit(slice->slice_buffer)) 
	{ 
    	intra_slice = mpeg3slice_getbit(slice->slice_buffer); 
    	mpeg3slice_getbits(slice->slice_buffer, 7); 
    	mpeg3video_ext_bit_info(slice->slice_buffer); 
  	} 
  	else  
		intra_slice = 0; 
 
	return slice_vertical_position_extension; 
}