From 15318cad33835e4e2dc620d033e43cd930676cdd Mon Sep 17 00:00:00 2001 From: kergoth Date: Fri, 25 Jan 2002 22:14:26 +0000 Subject: Initial revision --- (limited to 'core/multimedia/opieplayer/libmpeg3/video/headers.c') diff --git a/core/multimedia/opieplayer/libmpeg3/video/headers.c b/core/multimedia/opieplayer/libmpeg3/video/headers.c new file mode 100644 index 0000000..5274530 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/headers.c @@ -0,0 +1,492 @@ +#include "../mpeg3demux.h" +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#include "mpeg3video.h" + +#include +#include + +int mpeg3video_getseqhdr(mpeg3video_t *video) +{ + int i; + mpeg3_t *file = video->file; + + 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); +} + + +/* 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); +} + + +/* 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); + } +} + + +/* 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"); +} + + +/* 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); + } +} + + +/* 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); + } +} + + +/* 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); +} + + +/* 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"); +} + + +/* 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); + } +} + + +/* decode group of pictures header */ + +int mpeg3video_getgophdr(mpeg3video_t *video) +{ + int drop_flag, closed_gop, broken_link; + + 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; + + while(1) + { +/* look for startcode */ + code = mpeg3bits_next_startcode(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: + 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; +} -- cgit v0.9.0.2