X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Flibzmpeg3%2Fvideo%2Fheaders.C;fp=cinelerra-5.1%2Flibzmpeg3%2Fvideo%2Fheaders.C;h=221a30d695df83f70a3dc31833257f34313eb31d;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/libzmpeg3/video/headers.C b/cinelerra-5.1/libzmpeg3/video/headers.C new file mode 100644 index 00000000..221a30d6 --- /dev/null +++ b/cinelerra-5.1/libzmpeg3/video/headers.C @@ -0,0 +1,488 @@ +#include "../libzmpeg3.h" + +int zvideo_t:: +get_seq_hdr() +{ + int i; + int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix; + +//zmsg("1\n"); + horizontal_size = vstream->get_bits(12); + vertical_size = vstream->get_bits(12); + //int aspect_ratio = + vstream->get_bits(4); + framerate_code = vstream->get_bits(4); + bitrate = vstream->get_bits(18); + vstream->get_bit_noptr(); /* marker bit (=1) */ + //int vbv_buffer_size = + vstream->get_bits(10); + //int constrained_parameters_flag = + vstream->get_bit_noptr(); + frame_rate = frame_rate_table[framerate_code]; + + load_intra_quantizer_matrix = vstream->get_bit_noptr(); + if( load_intra_quantizer_matrix ) { + for( i=0; i<64; ++i ) + intra_quantizer_matrix[zigzag_scan_table[i]] = vstream->get_byte_noptr(); + } + else { + for( i=0; i<64; ++i ) + intra_quantizer_matrix[i] = default_intra_quantizer_matrix[i]; + } + + load_non_intra_quantizer_matrix = vstream->get_bit_noptr(); + if( load_non_intra_quantizer_matrix ) { + for( i=0; i<64; ++i ) + non_intra_quantizer_matrix[zigzag_scan_table[i]] = vstream->get_byte_noptr(); + } + else { + for( i=0; i<64; ++i ) + non_intra_quantizer_matrix[i] = 16; + } + +/* copy luminance to chrominance matrices */ + for( i=0; i<64; ++i ) { + chroma_intra_quantizer_matrix[i] = intra_quantizer_matrix[i]; + chroma_non_intra_quantizer_matrix[i] = non_intra_quantizer_matrix[i]; + } + +//zmsg("100\n"); + return 0; +} + + +/* decode sequence extension */ + +int zvideo_t:: +sequence_extension() +{ + mpeg2 = 1; + scalable_mode = slice_decoder_t::sc_NONE; /* unless overwritten by seq. scal. ext. */ + //int prof_lev = + vstream->get_byte_noptr(); + prog_seq = vstream->get_bit_noptr(); + chroma_format = vstream->get_bits(2); + int horizontal_size_extension = vstream->get_bits(2); + int vertical_size_extension = vstream->get_bits(2); + //int bit_rate_extension = + vstream->get_bits(12); + vstream->get_bit_noptr(); + //int vbv_buffer_size_extension = + vstream->get_byte_noptr(); + //int low_delay = + vstream->get_bit_noptr(); + //int frame_rate_extension_n = + vstream->get_bits(2); + //int frame_rate_extension_d = + vstream->get_bits(5); + horizontal_size = (horizontal_size_extension << 12) | (horizontal_size & 0x0fff); + vertical_size = (vertical_size_extension << 12) | (vertical_size & 0x0fff); + return 0; +} + + +/* decode sequence display extension */ + +int zvideo_t:: +sequence_display_extension() +{ + // int video_format = + vstream->get_bits(3); + int colour_description = vstream->get_bit_noptr(); + + if( colour_description ) { + //int colour_primaries = + vstream->get_byte_noptr(); + //int transfer_characteristics = + vstream->get_byte_noptr(); + matrix_coefficients = vstream->get_byte_noptr(); + } + + //int display_horizontal_size = + vstream->get_bits(14); + vstream->get_bit_noptr(); + //int display_vertical_size = + vstream->get_bits(14); + return 0; +} + + +/* decode quant matrix entension */ + +int zvideo_t:: +quant_matrix_extension() +{ + 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; + + load_intra_quantiser_matrix = vstream->get_bit_noptr(); + if( load_intra_quantiser_matrix != 0 ) { + for( i=0; i<64; ++i ) { + chroma_intra_quantizer_matrix[zigzag_scan_table[i]] + = intra_quantizer_matrix[zigzag_scan_table[i]] + = vstream->get_byte_noptr(); + } + } + + load_non_intra_quantiser_matrix = vstream->get_bit_noptr(); + if( load_non_intra_quantiser_matrix != 0 ) { + for( i=0; i<64; ++i ) { + chroma_non_intra_quantizer_matrix[zigzag_scan_table[i]] + = non_intra_quantizer_matrix[zigzag_scan_table[i]] + = vstream->get_byte_noptr(); + } + } + + load_chroma_intra_quantiser_matrix = vstream->get_bit_noptr(); + if( load_chroma_intra_quantiser_matrix != 0 ) { + for( i=0; i<64; ++i ) + chroma_intra_quantizer_matrix[zigzag_scan_table[i]] = vstream->get_byte_noptr(); + } + + load_chroma_non_intra_quantiser_matrix = vstream->get_bit_noptr(); + if( load_chroma_non_intra_quantiser_matrix != 0 ) { + for( i=0; i<64; ++i ) + chroma_non_intra_quantizer_matrix[zigzag_scan_table[i]] = vstream->get_byte_noptr(); + } + + return 0; +} + + +/* decode sequence scalable extension */ + +int zvideo_t:: +sequence_scalable_extension() +{ + scalable_mode = vstream->get_bits(2) + 1; /* add 1 to make sc_DP != sc_NONE */ + //int layer_id = + vstream->get_bits(4); + + if( scalable_mode == slice_decoder_t::sc_SPAT ) { + llw = vstream->get_bits(14); /* lower_layer_prediction_horizontal_size */ + vstream->get_bit_noptr(); + llh = vstream->get_bits(14); /* lower_layer_prediction_vertical_size */ + hm = vstream->get_bits(5); + hn = vstream->get_bits(5); + vm = vstream->get_bits(5); + vn = vstream->get_bits(5); + } + + if( scalable_mode == slice_decoder_t::sc_TEMP ) + zerr("temporal scalability not implemented\n"); + return 0; +} + + +/* decode picture display extension */ + +int zvideo_t:: +picture_display_extension() +{ +// short frame_centre_horizontal_offset[3]; +// short frame_centre_vertical_offset[3]; +/* per spec */ + int n = prog_seq ? (!repeatfirst ? 1 : (!topfirst ? 2 : 3)) : + pict_struct != pics_FRAME_PICTURE ? 1 : (!repeatfirst ? 2 : 3) ; + + for( int i=0; iget_bits(16); + vstream->get_bit_noptr(); + //frame_centre_vertical_offset[i] = (short) + vstream->get_bits(16); + vstream->get_bit_noptr(); + } + return 0; +} + + +/* decode picture coding extension */ + +int zvideo_t:: +picture_coding_extension() +{ + h_forw_r_size = vstream->get_bits(4) - 1; + v_forw_r_size = vstream->get_bits(4) - 1; + h_back_r_size = vstream->get_bits(4) - 1; + v_back_r_size = vstream->get_bits(4) - 1; + dc_prec = vstream->get_bits(2); + pict_struct = vstream->get_bits(2); + topfirst = vstream->get_bit_noptr(); + frame_pred_dct = vstream->get_bit_noptr(); + conceal_mv = vstream->get_bit_noptr(); + qscale_type = vstream->get_bit_noptr(); + intravlc = vstream->get_bit_noptr(); + altscan = vstream->get_bit_noptr(); + repeatfirst = vstream->get_bit_noptr(); + //int chroma_420_type = + vstream->get_bit_noptr(); + prog_frame = vstream->get_bit_noptr(); + if( repeat_fields > 2 ) repeat_fields = 0; + repeat_fields += 2; + if( repeatfirst ) { + if( prog_seq ) repeat_fields += !topfirst ? 2 : 4; + else if( prog_frame ) ++repeat_fields; + } + current_field = 0; + +//static const char *pstruct[] = { "nil", "top", "bot", "fld" }; +//zmsgs("pstruct %s prog_seq%d prog_frame%d topfirst%d repeatfirst%d repeat_fields%d\n", +// pstruct[pict_struct], prog_seq , prog_frame, topfirst, repeatfirst, repeat_fields); + + int composite_display_flag = vstream->get_bit_noptr(); + if( composite_display_flag ) { + //int v_axis = + vstream->get_bit_noptr(); + field_sequence = vstream->get_bits(3); + //int sub_carrier = + vstream->get_bit_noptr(); + //int burst_amplitude = + vstream->get_bits(7); + //int sub_carrier_phase = + vstream->get_byte_noptr(); + } + return 0; +} + +/* decode picture spatial scalable extension */ + +int zvideo_t:: +picture_spatial_scalable_extension() +{ + pict_scal = 1; /* use spatial scalability in this picture */ + lltempref = vstream->get_bits(10); + vstream->get_bit_noptr(); + llx0 = vstream->get_bits(15); + if(llx0 >= 16384) llx0 -= 32768; + vstream->get_bit_noptr(); + lly0 = vstream->get_bits(15); + if(lly0 >= 16384) lly0 -= 32768; + stwc_table_index = vstream->get_bits(2); + llprog_frame = vstream->get_bit_noptr(); + llfieldsel = vstream->get_bit_noptr(); + return 0; +} + + +/* decode picture temporal scalable extension + * + * not implemented + * + */ + +int zvideo_t:: +picture_temporal_scalable_extension() +{ + zerr("temporal scalability not supported\n"); + return 0; +} + + +/* decode extension and user data */ + +int zvideo_t:: +ext_user_data() +{ + int zcode = vstream->next_start_code(); + if( zcode < 0 ) return 1; + while( zcode == EXT_START_CODE || zcode == USER_START_CODE ) { + vstream->refill(); + if( zcode == EXT_START_CODE ) { + int ext_id = vstream->get_bits(4); + switch(ext_id) { + case ext_id_SEQ: + sequence_extension(); + break; + case ext_id_DISP: + sequence_display_extension(); + break; + case ext_id_QUANT: + quant_matrix_extension(); + break; + case ext_id_SEQSCAL: + sequence_scalable_extension(); + break; + case ext_id_PANSCAN: + picture_display_extension(); + break; + case ext_id_CODING: + picture_coding_extension(); + break; + case ext_id_SPATSCAL: + picture_spatial_scalable_extension(); + break; + case ext_id_TEMPSCAL: + picture_temporal_scalable_extension(); + break; + default: + zerrs("reserved extension start code ID %d\n", ext_id); + break; + } + } + else if( subtitle_track >= 0 ) { + int32_t id = vstream->show_bits(32); + if( id == 0x47413934 ) { /* "GA94" - atsc user data */ + vstream->refill(); + int typ = vstream->get_bits(8); + if( typ == 3 ) /* mpeg cc */ + get_cc()->get_atsc_data(vstream); + } + } + zcode = vstream->next_start_code(); + if( zcode < 0 ) return 1; + } +//zmsgs("prog_seq=%d prog_frame=%d\n", prog_seq,prog_frame); + return 0; +} + + +/* decode group of pictures header */ + +int zvideo_t:: +get_gop_header() +{ +//zmsg("1\n"); + has_gops = 1; + //int drop_flag = + vstream->get_bit_noptr(); + gop_timecode.hour = vstream->get_bits(5); + gop_timecode.minute = vstream->get_bits(6); + vstream->get_bit_noptr(); + gop_timecode.second = vstream->get_bits(6); + gop_timecode.frame = vstream->get_bits(6); + //int closed_gop = + vstream->get_bit_noptr(); + //int broken_link = + vstream->get_bit_noptr(); +//zmsg("100\n"); +//zmsgs("%d:%d:%d:%d %d %d %d\n", +// gop_timecode.hour, gop_timecode.minute, gop_timecode.second, +// gop_timecode.frame, drop_flag, closed_gop, broken_link); + return vstream->error(); +} + +/* decode picture header */ + +int zvideo_t:: +get_picture_hdr() +{ + pict_scal = 0; /* unless overwritten by pict. spat. scal. ext. */ + //int temp_ref = + vstream->get_bits(10); + pict_type = vstream->get_bits(3); + //int vbv_delay = + vstream->get_bits(16); + if( pict_type == pic_type_P || pict_type == pic_type_B ) { + full_forw = vstream->get_bit_noptr(); + forw_r_size = vstream->get_bits(3) - 1; + } + + if( pict_type == pic_type_B ) { + full_back = vstream->get_bit_noptr(); + back_r_size = vstream->get_bits(3) - 1; + } + +/* get extra bit picture */ + while( !vstream->eof() && vstream->get_bit_noptr() ) + vstream->get_bits_noptr(8); + return 0; +} + + +/* move to start of header. */ +/* this updates the demuxer times */ +int zvideo_t:: +find_header() +{ + for( int count=0x1000; --count>=0; ) { + int zcode = vstream->next_start_code(); + if( zcode < 0 ) break; + switch(zcode) { + case SEQUENCE_START_CODE: + case GOP_START_CODE: + case PICTURE_START_CODE: + return 0; + } + vstream->refill(); + } + + return 1; +} + + +int zvideo_t:: +get_header() +{ +// Stop search after this many start codes + for( int count=0x1000; --count>=0; ) { +/* look for startcode */ + int zcode = vstream->next_start_code(); + if( zcode < 0 ) break; + vstream->refill(); + + switch(zcode) { + case SEQUENCE_START_CODE: +/* a sequence header should be found before returning from get_header the */ +/* first time (this is to set horizontal/vertical size properly) */ + found_seqhdr = 1; + get_seq_hdr(); + ext_user_data(); + break; + + case GOP_START_CODE: + get_gop_header(); + ext_user_data(); + break; + + case PICTURE_START_CODE: + get_picture_hdr(); + ext_user_data(); + if( cc ) cc->reorder(); + if( found_seqhdr ) + return 0; /* Exit here */ + break; + } + } + + return 1; +} + +int zslice_buffer_t:: +ext_bit_info() +{ + while( get_bit() ) get_bits(8); + return 0; +} + +/* decode slice header */ +int zslice_decoder_t:: +get_slice_hdr() +{ + int slice_vertical_position_extension; + int qs; + slice_vertical_position_extension = + (video->mpeg2 && video->vertical_size>2800) ? + slice_buffer->get_bits(3) : 0; + + if( video->scalable_mode == sc_DP ) + pri_brk = slice_buffer->get_bits(7); + + qs = slice_buffer->get_bits(5); + quant_scale = video->mpeg2 ? + (video->qscale_type ? non_linear_mquant_table[qs] : (qs << 1)) : + qs; + +//int intra_slice = 0; + if( slice_buffer->get_bit() ) { + //intra_slice = + slice_buffer->get_bit(); + slice_buffer->get_bits(7); + slice_buffer->ext_bit_info(); + } + + return slice_vertical_position_extension; +} +