📄 video_mpeg2.c
字号:
= GETBITS(2, "spatial_temporal_weight_code"); } if((mb.modes.macroblock_type & MACROBLOCK_MOTION_FORWARD) || (mb.modes.macroblock_type & MACROBLOCK_MOTION_BACKWARD)) { if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) { if(pic.coding_ext.frame_pred_frame_dct != 0) { /* frame_motion_type omitted from the bitstream */ mb.modes.frame_motion_type = 0x2; } else { mb.modes.frame_motion_type = GETBITS(2, "frame_motion_type"); if(mb.modes.frame_motion_type == 0x0) { fprintf(stderr, "*** invalid frame motion type\n"); return -1; } } } else { mb.modes.field_motion_type = GETBITS(2, "field_motion_type"); if(mb.modes.field_motion_type == 0x0) { fprintf(stderr, "*** invalid field motion type\n"); return -1; } } } /* if(decode_dct_type) */ if((pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) && (pic.coding_ext.frame_pred_frame_dct == 0) && (mb.modes.macroblock_type & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))) { mb.modes.dct_type = GETBITS(1, "dct_type"); } else { /* Table 6-19. Value of dct_type if dct_type is not in the bitstream. pic.coding_ext.frame_pred_frame_dct == 1 then mb.modes.dct_type = 0 else dct_type is unused, either field picture or mb not coded */ mb.modes.dct_type = 0; } return 0;}/* 6.2.4 Slice *//* 6.2.5 Macroblock */void mpeg2_slice(void){ DPRINTFI(3, "slice()\n"); DINDENT(2); reset_dc_dct_pred(); reset_PMV(); slice_data.slice_vertical_position = GETBITS(32, "slice_start_code") & 0xff; // fprintf(stderr, "slice: %d\n", slice_data.slice_vertical_position); seq.mb_row = slice_data.slice_vertical_position - 1;#if 0 if(seq.vertical_size > 2800) { slice_data.slice_vertical_position_extension = GETBITS(3, "slice_vertical_position_extension"); seq.mb_row = (slice_data.slice_vertical_position_extension << 7) + slice_data.slice_vertical_position - 1; }#endif #if 0 //TODO if(0) {//sequence_scalable_extension_present) { if(0) { //scalable_mode == DATA_PARTITIONING) { slice_data.priority_breakpoint = GETBITS(7, "priority_breakpoint"); } }#endif mb.quantiser_scale = q_scale[pic.coding_ext.q_scale_type][GETBITS(5, "quantiser_scale_code")]; if(nextbits(1) == 1) { slice_data.intra_slice_flag = GETBITS(1, "intra_slice_flag"); slice_data.intra_slice = GETBITS(1, "intra_slice"); slice_data.reserved_bits = GETBITS(7, "reserved_bits"); while(nextbits(1) == 1) { slice_data.extra_bit_slice = GETBITS(1, "extra_bit_slice"); slice_data.extra_information_slice = GETBITS(8, "extra_information_slice"); } } slice_data.extra_bit_slice = GETBITS(1, "extra_bit_slice"); DPRINTFI(3, "macroblocks()\n"); DINDENT(2); /* Flag that this is the first macroblock in the slice */ /* seq.mb_column starts at 0 */ seq.mb_column = -1; do { unsigned int tmp; unsigned int macroblock_address_increment = 0; while(nextbits(11) == 0x00f) { GETBITS(11, "macroblock_stuffing"); } while(nextbits(11) == 0x008) { GETBITS(11, "macroblock_escape"); macroblock_address_increment += 33; } // fprintf(stderr, "inc1: %d\n", macroblock_address_increment); // fprintf(stderr, "vlc: %08x\n", nextbits(32)); tmp = get_vlc(table_b1, "macroblock_address_increment"); if(tmp != 0x8000) { macroblock_address_increment += tmp; } else { fprintf(stderr, "*mai error\n"); macroblock_address_increment += 1; } /* macroblock_address_increment += get_vlc(table_b1, "macroblock_address_increment"); */ // fprintf(stderr, "inc2: %d\n", macroblock_address_increment); if(seq.mb_column == -1) { /* a slice never span rows. */ seq.mb_column += macroblock_address_increment; /* The first macroblock is coded. I.e. no skipped blocks, they must have been in another slice with the same startcode (vertical position). */ macroblock_address_increment = 1; } else { /* a slice never span rows. */ seq.mb_column += macroblock_address_increment; } /* Subtract one to get the number of skipped blocks instead. */ macroblock_address_increment -= 1; DPRINTFI(4, " Macroblock: %d, row: %d, col: %d\n", (seq.mb_row * seq.mb_width) + seq.mb_column, seq.mb_row, seq.mb_column); #ifdef DEBUG if(macroblock_address_increment) { DPRINTF(3, "Skipped %d macroblocks\n", macroblock_address_increment + 1); }#endif /* 7.6.6 Skipped Macroblocks */ if(macroblock_address_increment) { /* Skipped blocks never have any DCT coefficients (pattern). */ switch(pic.header.picture_coding_type) { case PIC_CODING_TYPE_P: DPRINTFI(4, "skipped in P-picture\n"); /* In a P-picture when a macroblock is skipped */ reset_PMV(); reset_vectors(); if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) { /* mlib is broken!!! { int x = (seq.mb_column-macroblock_address_increment); int y = seq.mb_row; int offs_y = x * 16 + y * 16 * seq.mb_width * 16; int offs_uv = x * 8 + y * 8 * (seq.mb_width * 16)/2; mlib_VideoCopyRef_U8_U8(&dst_image->y[offs_y], &fwd_ref_image->y[offs_y], macroblock_address_increment*16, 16, (seq.mb_width * 16)); mlib_VideoCopyRef_U8_U8(&dst_image->u[offs_uv], &fwd_ref_image->u[offs_uv], macroblock_address_increment*8, 8, (seq.mb_width * 16)/2); mlib_VideoCopyRef_U8_U8(&dst_image->v[offs_uv], &fwd_ref_image->v[offs_uv], macroblock_address_increment*8, 8, (seq.mb_width * 16)/2); } */#if HAVE_ALTIVEC const int x = seq.mb_column - macroblock_address_increment; const int y = seq.mb_row; const int offs_y = x * 16 + y * 16 * seq.mb_width * 16; const int offs_uv = x * 8 + y * 8 * seq.mb_width * 8; mlib_VideoCopyRef_U8_U8_16x16_multiple(&dst_image->y[offs_y], &fwd_ref_image->y[offs_y], seq.mb_width * 16, macroblock_address_increment); mlib_VideoCopyRef_U8_U8_8x8_multiple(&dst_image->u[offs_uv], &fwd_ref_image->u[offs_uv], seq.mb_width * 8, macroblock_address_increment); mlib_VideoCopyRef_U8_U8_8x8_multiple(&dst_image->v[offs_uv], &fwd_ref_image->v[offs_uv], seq.mb_width * 8, macroblock_address_increment);#else unsigned int x, y; /* 7.6.6.2 P frame picture */ x = (seq.mb_column-macroblock_address_increment)*16; // fprintf(stderr, "x: %d, inc: %d, row: %d\n", // x, macroblock_address_increment, seq.mb_row); for(y = seq.mb_row*16; y < (seq.mb_row+1)*16; y++) { memcpy(&dst_image->y[y*(seq.mb_width*16)+x], &fwd_ref_image->y[y*(seq.mb_width*16)+x], macroblock_address_increment*16); } x = (seq.mb_column-macroblock_address_increment)*8; for(y = seq.mb_row*8; y < (seq.mb_row+1)*8; y++) { memcpy(&dst_image->u[y*(seq.mb_width*16)/2+x], &fwd_ref_image->u[y*(seq.mb_width*16)/2+x], macroblock_address_increment*8); } for(y = seq.mb_row*8; y < (seq.mb_row+1)*8; y++) { memcpy(&dst_image->v[y*(seq.mb_width*16)/2+x], &fwd_ref_image->v[y*(seq.mb_width*16)/2+x], macroblock_address_increment*8); }#endif } else { // Optimize this case too? Maybe move all this to video_motion unsigned int old_col = seq.mb_column; /* 7.6.6.1 P field picture*/ // Are these two needed/wanted? mb.modes.macroblock_type |= MACROBLOCK_MOTION_FORWARD; mb.modes.macroblock_type &= ~MACROBLOCK_MOTION_BACKWARD; mb.prediction_type = PRED_TYPE_FIELD_BASED; mb.motion_vector_count = 1; mb.mv_format = MV_FORMAT_FIELD; mb.motion_vertical_field_select[0][0] = (pic.coding_ext.picture_structure == PIC_STRUCT_TOP_FIELD ? 0 : 1); /* Set mb_column so that motion_comp will use the right adress */ for(seq.mb_column = seq.mb_column-macroblock_address_increment; seq.mb_column < old_col; seq.mb_column++) { motion_comp(); } seq.mb_column = old_col; } break; case PIC_CODING_TYPE_B: DPRINTFI(4, "skipped in B-frame\n"); { unsigned int old_col = seq.mb_column; // The previos macroblocks vectors are used. if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) { /* 7.6.6.4 B frame picture */ mb.prediction_type = PRED_TYPE_FRAME_BASED; mb.motion_vector_count = 1; mb.mv_format = MV_FORMAT_FRAME; } else { /* 7.6.6.3 B field picture */ mb.prediction_type = PRED_TYPE_FIELD_BASED; mb.motion_vector_count = 1; mb.mv_format = MV_FORMAT_FIELD; mb.motion_vertical_field_select[0][0] = pic.coding_ext.picture_structure == PIC_STRUCT_TOP_FIELD ? 0 : 1; mb.motion_vertical_field_select[0][1] = pic.coding_ext.picture_structure == PIC_STRUCT_TOP_FIELD ? 0 : 1; //exit_program(1); // FIXME ??? Are we correct for this case now? } /* Set mb_column so that motion_comp will use the right adress */ for(seq.mb_column = seq.mb_column-macroblock_address_increment; seq.mb_column < old_col; seq.mb_column++) { motion_comp(); } seq.mb_column = old_col; } break; default: fprintf(stderr, "*** skipped blocks in I-picture\n"); //return; ?? break; } reset_dc_dct_pred(); } if(macroblock_modes() == -1) return; if(mb.modes.macroblock_type & MACROBLOCK_QUANT) { mb.quantiser_scale = q_scale[pic.coding_ext.q_scale_type][GETBITS(5, "quantiser_scale_code")]; } if((mb.modes.macroblock_type & MACROBLOCK_MOTION_FORWARD) || ((mb.modes.macroblock_type & MACROBLOCK_INTRA) && pic.coding_ext.concealment_motion_vectors)) { motion_vectors(0); } if(mb.modes.macroblock_type & MACROBLOCK_MOTION_BACKWARD) { motion_vectors(1); } if((mb.modes.macroblock_type & MACROBLOCK_INTRA) && pic.coding_ext.concealment_motion_vectors) { marker_bit(); } /* All motion vectors for the block has been decoded. Update predictors */ if(mb.modes.macroblock_type & MACROBLOCK_INTRA) { /* Whenever an intra macroblock is decoded which has no concealment motion vectors */ if(pic.coding_ext.concealment_motion_vectors == 0) { reset_PMV(); DPRINTF(4, "* 1\n"); } else { pic.PMV[1][0][1] = pic.PMV[0][0][1]; pic.PMV[1][0][0] = pic.PMV[0][0][0]; } } else { DPRINTFI(4, "non_intra macroblock\n"); reset_dc_dct_pred(); switch(mb.prediction_type) { case PRED_TYPE_FIELD_BASED: /* When used in a PIC_STRUCT_FRAME_PICTURE nothing is to be updated. */ if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) break; case PRED_TYPE_FRAME_BASED: /* When used in a PIC_STRUCT_*_FIELD nothing is to be updated. There is no need to test since it can't be used in these pictures.*/ if(mb.modes.macroblock_type & MACROBLOCK_MOTION_FORWARD) { pic.PMV[1][0][1] = pic.PMV[0][0][1]; pic.PMV[1][0][0] = pic.PMV[0][0][0]; } if(mb.modes.macroblock_type & MACROBLOCK_MOTION_BACKWARD) { pic.PMV[1][1][1] = pic.PMV[0][1][1]; pic.PMV[1][1][0] = pic.PMV[0][1][0]; } if(pic.coding_ext.frame_pred_frame_dct != 0) { if(((mb.modes.macroblock_type & MACROBLOCK_MOTION_FORWARD) == 0) && ((mb.modes.macroblock_type & MACROBLOCK_MOTION_BACKWARD) == 0)) { reset_PMV(); DPRINTF(4, "* 2\n"); } } break; case PRED_TYPE_16x8_MC:#ifdef DEBUG if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) { fprintf(stderr, "*** invalid pred_type\n"); return; //exit_program(1); }#endif break; case PRED_TYPE_DUAL_PRIME: if(mb.modes.macroblock_type & MACROBLOCK_MOTION_FORWARD) { pic.PMV[1][0][1] = pic.PMV[0][0][1]; pic.PMV[1][0][0] = pic.PMV[0][0][0]; } break; default: fprintf(stderr, "*** invalid pred_type\n"); return; //exit_program(1); break; } } /*** 7.6.3.5 Prediction in P-pictures ***/ if(pic.header.picture_coding_type == PIC_CODING_TYPE_P) { /* In a P-picture when a non-intra macroblock is decoded in which macroblock_motion_forward is zero */ if((!(mb.modes.macroblock_type & MACROBLOCK_MOTION_FORWARD)) && (!(mb.modes.macroblock_type & MACROBLOCK_INTRA))) { DPRINTF(4, "prediction mode Frame-base, \n" "resetting motion vector predictor and motion vector\n"); /* 7.6.3.4 */ reset_PMV(); if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) { mb.prediction_type = PRED_TYPE_FRAME_BASED; mb.motion_vector_count = 1; mb.mv_format = MV_FORMAT_FRAME; } else { mb.prediction_type = PRED_TYPE_FIELD_BASED; mb.motion_vector_count = 1; mb.mv_format = MV_FORMAT_FIELD; mb.motion_vertical_field_select[0][0] = pic.coding_ext.picture_structure == PIC_STRUCT_TOP_FIELD ? 0 : 1; } mb.modes.macroblock_type |= MACROBLOCK_MOTION_FORWARD; mb.vector[0][0][0] = 0; mb.vector[0][0][1] = 0; mb.vector[1][0][0] = 0; mb.vector[1][0][1] = 0; } } if(mb.modes.macroblock_type & MACROBLOCK_INTRA) { unsigned int block_count = 6; unsigned int i; /* Table 6-20 block_count as a function of chroma_format */#ifdef DEBUG if(seq.ext.chroma_format == 0x01) { block_count = 6; } else if(seq.ext.chroma_format == 0x02) { block_count = 8; } else if(seq.ext.chroma_format == 0x03) { block_count = 12; }#endif /* Intra blocks always have pattern coded for all sub blocks and are writen directly to the output buffers by this code. */ for(i = 0; i < block_count; i++) { DPRINTF(4, "cbpindex: %d assumed\n", i); block_intra(i); /* Shortcut: write the IDCT data directly into the picture buffer */ { const int x = seq.mb_column; const int y = seq.mb_row; const int padded_width = seq.mb_width * 16; int d, stride; uint8_t *dst; if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) { if(mb.modes.dct_type) { d = 1; stride = padded_width * 2; } else { d = 8; stride = padded_width; } if(i < 4) { dst = &dst_image->y[x * 16 + y * 16 * padded_width]; dst = (i & 1) ? dst + 8 : dst; dst = (i >= 2) ? dst + padded_width * d : dst; } else { stride = padded_width / 2; if(i == 4) dst = &dst_image->u[x * 8 + y * 8 * stride]; else // i == 5 dst = &dst_image->v[x * 8 + y * 8 * stride]; } } else { if(i < 4) { stride = padded_width * 2; dst = &dst_image->y[x * 16 + y * 16 * stride]; dst = (i & 1) ? dst + 8 : dst; dst = (i >= 2) ? dst + stride * 8 : dst; } else { stride = padded_width; if(i == 4) dst = &dst_image->u[x * 8 + y * 8 * stride]; else // i == 5 dst = &dst_image->v[x * 8 + y * 8 * stride]; } if(pic.coding_ext.picture_structure == PIC_STRUCT_BOTTOM_FIELD) dst += stride/2; } mlib_VideoIDCT8x8_U8_S16(dst, (int16_t *)mb.QFS, stride); } } } else { /* Non-intra block */ motion_comp(); // Only motion compensate don't add coefficients. if(mb.modes.macroblock_type & MACROBLOCK_PATTERN) { unsigned int i; coded_block_pattern(); for(i = 0; i < 6; i++) { if(mb.cbp & (1<<(5-i))) { DPRINTF(4, "cbpindex: %d set\n", i); block_non_intra(i); //mlib_VideoIDCT8x8_S16_S16((int16_t *)mb.QFS, (int16_t *)mb.QFS); motion_comp_add_coeff(i); // IDCT and add done in here.. } }#if 0 if(seq.ext.chroma_format == 0x02) { for(i = 6; i < 8; i++) { if(mb.coded_block_pattern_1 & (1<<(7-i))) { block_non_intra(i); fprintf(stderr, "ni seq.ext.chroma_format == 0x02\n"); //exit_program(1); } } } if(seq.ext.chroma_format == 0x03) { for(i = 6; i < 12; i++) { if(mb.coded_block_pattern_2 & (1<<(11-i))) { block_non_intra(i); fprintf(stderr, "ni seq.ext.chroma_format == 0x03\n"); //exit_program(1); } } }#endif } } } while(((seq.mb_column + 1) < seq.mb_width) && (nextbits(23) != 0)); DINDENT(-2);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -