diff options
Diffstat (limited to 'libmpeg2')
-rw-r--r-- | libmpeg2/header.c | 16 | ||||
-rw-r--r-- | libmpeg2/mpeg2_internal.h | 3 | ||||
-rw-r--r-- | libmpeg2/slice.c | 215 |
3 files changed, 119 insertions, 115 deletions
diff --git a/libmpeg2/header.c b/libmpeg2/header.c index 852ff541bd..dd29cb035e 100644 --- a/libmpeg2/header.c +++ b/libmpeg2/header.c @@ -177,10 +177,10 @@ static int header_process_quant_matrix_extension (picture_t * picture, static int header_process_picture_coding_extension (picture_t * picture, uint8_t * buffer) { /* pre subtract 1 for use later in compute_motion_vector */ - picture->f_code[0][0] = (buffer[0] & 15) - 1; - picture->f_code[0][1] = (buffer[1] >> 4) - 1; - picture->f_code[1][0] = (buffer[1] & 15) - 1; - picture->f_code[1][1] = (buffer[2] >> 4) - 1; + picture->f_motion.f_code[0] = (buffer[0] & 15) - 1; + picture->f_motion.f_code[1] = (buffer[1] >> 4) - 1; + picture->b_motion.f_code[0] = (buffer[1] & 15) - 1; + picture->b_motion.f_code[1] = (buffer[2] >> 4) - 1; picture->intra_dc_precision = (buffer[2] >> 2) & 3; picture->picture_structure = buffer[2] & 3; @@ -237,11 +237,11 @@ int header_process_picture_header (picture_t *picture, uint8_t * buffer) picture->picture_coding_type = (buffer [1] >> 3) & 7; /* forward_f_code and backward_f_code - used in mpeg1 only */ - picture->f_code[0][1] = (buffer[3] >> 2) & 1; - picture->f_code[0][0] = + picture->f_motion.f_code[1] = (buffer[3] >> 2) & 1; + picture->f_motion.f_code[0] = (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1; - picture->f_code[1][1] = (buffer[4] >> 6) & 1; - picture->f_code[1][0] = ((buffer[4] >> 3) & 7) - 1; + picture->b_motion.f_code[1] = (buffer[4] >> 6) & 1; + picture->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1; /* move in header_process_picture_header */ picture->second_field = diff --git a/libmpeg2/mpeg2_internal.h b/libmpeg2/mpeg2_internal.h index ed278cc786..8eb3e924da 100644 --- a/libmpeg2/mpeg2_internal.h +++ b/libmpeg2/mpeg2_internal.h @@ -84,6 +84,7 @@ typedef struct picture_s { int quantizer_scale; /* remove */ int current_field; /* remove */ + int v_offset; /* remove */ /* now non-slice-specific information */ @@ -103,8 +104,6 @@ typedef struct picture_s { /* picture coding extension stuff */ - /* quantization factor for motion vectors */ - int f_code[2][2]; /* quantization factor for intra dc coefficients */ int intra_dc_precision; /* top/bottom/both fields */ diff --git a/libmpeg2/slice.c b/libmpeg2/slice.c index 04728cda36..1d85cc5cdc 100644 --- a/libmpeg2/slice.c +++ b/libmpeg2/slice.c @@ -975,6 +975,7 @@ static inline int get_macroblock_address_increment (picture_t * picture) NEEDBITS (bit_buf, bits, bit_ptr); break; default: /* end of slice, or error */ +// printf("MB error: %d \n",(UBITS (bit_buf, 11))); // FIXME! return 0; } } @@ -1024,42 +1025,55 @@ static inline void slice_non_intra_DCT (picture_t * picture, uint8_t * dest, idct_block_add (picture->DCTblock, dest, stride); } +#define MOTION_Y(table,offset_x,offset_y,motion_x,motion_y, \ + dest,src,offset_dest,offset_src,stride,height) \ +do { \ + int xy_half; \ + int total_offset; \ + \ + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ + total_offset = ((offset_y + (motion_y >> 1)) * stride + \ + offset_x + (motion_x >> 1) + (offset_src)); \ + table[xy_half] (dest[0] + offset_x + (offset_dest), \ + src[0] + total_offset, stride, height); \ +} while (0) + +#define MOTION_UV(table,offset_x,offset_y,motion_x,motion_y, \ + dest,src,offset_dest,offset_src,stride,height) \ +do { \ + int xy_half; \ + int total_offset; \ + \ + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ + total_offset = (((offset_y + motion_y) >> 1) * (stride) + \ + ((offset_x + motion_x) >> 1) + (offset_src)); \ + table[4+xy_half] (dest[1] + (offset_x >> 1) + (offset_dest), \ + src[1] + total_offset, stride, height); \ + table[4+xy_half] (dest[2] + (offset_x >> 1) + (offset_dest), \ + src[2] + total_offset, stride, height); \ +} while (0) + static inline void motion_block (void (** table) (uint8_t *, uint8_t *, - int32_t, int32_t), + int32_t, int32_t), + int x_offset, int y_offset, int mb_y_8_offset, + int src_field, int dest_field, int x_pred, int y_pred, - uint8_t * dest[3], int dest_offset, - uint8_t * src[3], int src_offset, - int stride, int height, int second_half) + uint8_t * dest[3], uint8_t * src[3], + int stride, int height) { - int xy_half; - uint8_t * src1; - uint8_t * src2; - - xy_half = ((y_pred & 1) << 1) | (x_pred & 1); - - src1 = src[0] + src_offset + (x_pred >> 1) + (y_pred >> 1) * stride + - second_half * (stride << 3); - - table[xy_half] (dest[0] + dest_offset + second_half * (stride << 3), - src1, stride, height); + MOTION_Y (table, x_offset, y_offset, x_pred, y_pred, dest, src, + dest_field + mb_y_8_offset*8*stride, src_field, stride, height); x_pred /= 2; y_pred /= 2; - - xy_half = ((y_pred & 1) << 1) | (x_pred & 1); stride >>= 1; height >>= 1; - src_offset >>= 1; src_offset += second_half * (stride << 2); - dest_offset >>= 1; dest_offset += second_half * (stride << 2); - - src1 = src[1] + src_offset + (x_pred >> 1) + (y_pred >> 1) * stride; - src2 = src[2] + src_offset + (x_pred >> 1) + (y_pred >> 1) * stride; - table[4+xy_half] (dest[1] + dest_offset, src1, stride, height); - table[4+xy_half] (dest[2] + dest_offset, src2, stride, height); + MOTION_UV (table, x_offset, y_offset, x_pred, y_pred, dest, src, + (dest_field >> 1) + mb_y_8_offset*4*stride, src_field >> 1, + stride, height); } - static void motion_mp1 (picture_t * picture, motion_t * motion, uint8_t * dest[3], int offset, int stride, void (** table) (uint8_t *, uint8_t *, int, int)) @@ -1086,8 +1100,8 @@ static void motion_mp1 (picture_t * picture, motion_t * motion, motion_y <<= 1; } - motion_block (table, motion_x, motion_y, dest, offset, - motion->ref[0], offset, stride, 16, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, + motion_x, motion_y, dest, motion->ref[0], stride, 16); #undef bit_buf #undef bits #undef bit_ptr @@ -1107,8 +1121,8 @@ static void motion_mp1_reuse (picture_t * picture, motion_t * motion, motion_y <<= 1; } - motion_block (table, motion_x, motion_y, dest, offset, - motion->ref[0], offset, stride, 16, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, + motion_x, motion_y, dest, motion->ref[0], stride, 16); } static void motion_fr_frame (picture_t * picture, motion_t * motion, @@ -1132,8 +1146,8 @@ static void motion_fr_frame (picture_t * picture, motion_t * motion, motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion->pmv[0][1] = motion_y; - motion_block (table, motion_x, motion_y, dest, offset, - motion->ref[0], offset, stride, 16, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, + motion_x, motion_y, dest, motion->ref[0], stride, 16); #undef bit_buf #undef bits #undef bit_ptr @@ -1164,9 +1178,9 @@ static void motion_fr_field (picture_t * picture, motion_t * motion, /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ motion->pmv[0][1] = motion_y << 1; - motion_block (table, motion_x, motion_y, dest, offset, - motion->ref[0], offset + (field_select & stride), - stride * 2, 8, 0); + motion_block (table, offset, picture->v_offset >> 1, + 0, (field_select & stride), 0, + motion_x, motion_y, dest, motion->ref[0], stride * 2, 8); NEEDBITS (bit_buf, bits, bit_ptr); field_select = SBITS (bit_buf, 1); @@ -1183,9 +1197,9 @@ static void motion_fr_field (picture_t * picture, motion_t * motion, /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ motion->pmv[1][1] = motion_y << 1; - motion_block (table, motion_x, motion_y, dest, offset + stride, - motion->ref[0], offset + (field_select & stride), - stride * 2, 8, 0); + motion_block (table, offset, picture->v_offset >> 1, + 0, (field_select & stride), stride, + motion_x, motion_y, dest, motion->ref[0], stride * 2, 8); #undef bit_buf #undef bits #undef bit_ptr @@ -1221,23 +1235,24 @@ static void motion_fr_dmv (picture_t * picture, motion_t * motion, NEEDBITS (bit_buf, bits, bit_ptr); dmv_y = get_dmv (picture); - motion_block (mc_functions.put, motion_x, motion_y, dest, offset, - motion->ref[0], offset, stride * 2, 8, 0); + motion_block (mc_functions.put, offset, picture->v_offset >> 1, 0, 0, 0, + motion_x, motion_y, dest, motion->ref[0], stride * 2, 8); m = picture->top_field_first ? 1 : 3; other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1; - motion_block (mc_functions.avg, other_x, other_y, dest, offset, - motion->ref[0], offset + stride, stride * 2, 8, 0); + motion_block (mc_functions.avg, offset, picture->v_offset >> 1, 0, stride, 0, + other_x, other_y, dest, motion->ref[0], stride * 2, 8); - motion_block (mc_functions.put, motion_x, motion_y, dest, offset + stride, - motion->ref[0], offset + stride, stride * 2, 8, 0); + motion_block (mc_functions.put, offset, picture->v_offset >> 1, + 0, stride, stride, + motion_x, motion_y, dest, motion->ref[0], stride * 2, 8); m = picture->top_field_first ? 3 : 1; other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1; - motion_block (mc_functions.avg, other_x, other_y, dest, offset + stride, - motion->ref[0], offset, stride * 2, 8, 0); + motion_block (mc_functions.avg, offset, picture->v_offset >> 1, 0, 0, stride, + other_x, other_y, dest, motion->ref[0], stride * 2, 8); #undef bit_buf #undef bits #undef bit_ptr @@ -1248,8 +1263,9 @@ static void motion_fr_reuse (picture_t * picture, motion_t * motion, uint8_t * dest[3], int offset, int stride, void (** table) (uint8_t *, uint8_t *, int, int)) { - motion_block (table, motion->pmv[0][0], motion->pmv[0][1], dest, offset, - motion->ref[0], offset, stride, 16, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, + motion->pmv[0][0], motion->pmv[0][1], + dest, motion->ref[0], stride, 16); } /* like motion_frame, but use null motion vectors */ @@ -1257,8 +1273,8 @@ static void motion_fr_zero (picture_t * picture, motion_t * motion, uint8_t * dest[3], int offset, int stride, void (** table) (uint8_t *, uint8_t *, int, int)) { - motion_block (table, 0, 0, dest, offset, - motion->ref[0], offset, stride, 16, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, 0, 0, + dest, motion->ref[0], stride, 16); } /* like motion_frame, but parsing without actual motion compensation */ @@ -1313,8 +1329,9 @@ static void motion_fi_field (picture_t * picture, motion_t * motion, motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion->pmv[0][1] = motion_y; - motion_block (table, motion_x, motion_y, dest, offset, - motion->ref[field_select], offset, stride, 16, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, + motion_x, motion_y, + dest, motion->ref[field_select], stride, 16); #undef bit_buf #undef bits #undef bit_ptr @@ -1346,8 +1363,9 @@ static void motion_fi_16x8 (picture_t * picture, motion_t * motion, motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[0][1] = motion_y; - motion_block (table, motion_x, motion_y, dest, offset, - motion->ref[field_select], offset, stride, 8, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, + motion_x, motion_y, + dest, motion->ref[field_select], stride, 8); NEEDBITS (bit_buf, bits, bit_ptr); field_select = UBITS (bit_buf, 1); @@ -1365,8 +1383,9 @@ static void motion_fi_16x8 (picture_t * picture, motion_t * motion, motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion_y; - motion_block (table, motion_x, motion_y, dest, offset, - motion->ref[field_select], offset, stride, 8, 1); + motion_block (table, offset, picture->v_offset+8, 1, 0, 0, + motion_x, motion_y, + dest, motion->ref[field_select], stride, 8); #undef bit_buf #undef bits #undef bit_ptr @@ -1400,14 +1419,16 @@ static void motion_fi_dmv (picture_t * picture, motion_t * motion, NEEDBITS (bit_buf, bits, bit_ptr); dmv_y = get_dmv (picture); - motion_block (mc_functions.put, motion_x, motion_y, dest, offset, - motion->ref[picture->current_field], offset, stride, 16, 0); + motion_block (mc_functions.put, offset, picture->v_offset, 0, 0, 0, + motion_x, motion_y, + dest, motion->ref[picture->current_field], stride, 16); motion_x = ((motion_x + (motion_x > 0)) >> 1) + dmv_x; motion_y = ((motion_y + (motion_y > 0)) >> 1) + dmv_y + 2 * picture->current_field - 1; - motion_block (mc_functions.avg, motion_x, motion_y, dest, offset, - motion->ref[!picture->current_field], offset, stride, 16, 0); + motion_block (mc_functions.avg, offset, picture->v_offset, 0, 0, 0, + motion_x, motion_y, + dest, motion->ref[!picture->current_field], stride, 16); #undef bit_buf #undef bits #undef bit_ptr @@ -1417,16 +1438,17 @@ static void motion_fi_reuse (picture_t * picture, motion_t * motion, uint8_t * dest[3], int offset, int stride, void (** table) (uint8_t *, uint8_t *, int, int)) { - motion_block (table, motion->pmv[0][0], motion->pmv[0][1], dest, offset, - motion->ref[picture->current_field], offset, stride, 16, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, + motion->pmv[0][0], motion->pmv[0][1], + dest, motion->ref[picture->current_field], stride, 16); } static void motion_fi_zero (picture_t * picture, motion_t * motion, uint8_t * dest[3], int offset, int stride, void (** table) (uint8_t *, uint8_t *, int, int)) { - motion_block (table, 0, 0, dest, offset, - motion->ref[picture->current_field], offset, stride, 16, 0); + motion_block (table, offset, picture->v_offset, 0, 0, 0, 0, 0, + dest, motion->ref[picture->current_field], stride, 16); } static void motion_fi_conceal (picture_t * picture) @@ -1471,12 +1493,6 @@ do { \ #define CHECK_DISPLAY \ do { \ if (offset == picture->coded_picture_width) { \ - picture->f_motion.ref[0][0] += 16 * stride; \ - picture->f_motion.ref[0][1] += 4 * stride; \ - picture->f_motion.ref[0][2] += 4 * stride; \ - picture->b_motion.ref[0][0] += 16 * stride; \ - picture->b_motion.ref[0][1] += 4 * stride; \ - picture->b_motion.ref[0][2] += 4 * stride; \ do { /* just so we can use the break statement */ \ if (picture->current_frame->copy) { \ picture->current_frame->copy (picture->current_frame, \ @@ -1488,6 +1504,11 @@ do { \ dest[1] += 4 * stride; \ dest[2] += 4 * stride; \ } while (0); \ + if (! (picture->mpeg1)) \ + return 0; \ + picture->v_offset += 16; \ + if (picture->v_offset >= picture->coded_picture_height) \ + return 0; \ offset = 0; ++code; \ } \ } while (0) @@ -1505,46 +1526,41 @@ int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer) stride = picture->coded_picture_width; offset = (code - 1) * stride * 4; + picture->v_offset = (code - 1) * 16; forward_ref[0] = picture->forward_reference_frame->base; if (picture->picture_structure != FRAME_PICTURE) { - offset <<= 1; forward_ref[1] = picture->forward_reference_frame->base; + offset <<= 1; picture->current_field = (picture->picture_structure == BOTTOM_FIELD); if ((picture->second_field) && (picture->picture_coding_type != B_TYPE)) forward_ref[picture->picture_structure == TOP_FIELD] = picture->current_frame->base; - picture->f_motion.ref[1][0] = forward_ref[1][0] + offset * 4 + stride; - picture->f_motion.ref[1][1] = - forward_ref[1][1] + offset + (stride >> 1); - picture->f_motion.ref[1][2] = - forward_ref[1][2] + offset + (stride >> 1); - picture->b_motion.ref[1][0] = - picture->backward_reference_frame->base[0] + offset * 4 + stride; + + picture->f_motion.ref[1][0] = forward_ref[1][0] + stride; + picture->f_motion.ref[1][1] = forward_ref[1][1] + (stride >> 1); + picture->f_motion.ref[1][2] = forward_ref[1][2] + (stride >> 1); + + picture->b_motion.ref[1][0] = + picture->backward_reference_frame->base[0] + stride; picture->b_motion.ref[1][1] = - (picture->backward_reference_frame->base[1] + - offset + (stride >> 1)); + picture->backward_reference_frame->base[1] + (stride >> 1); picture->b_motion.ref[1][2] = - (picture->backward_reference_frame->base[2] + - offset + (stride >> 1)); + picture->backward_reference_frame->base[2] + (stride >> 1); } - picture->f_motion.ref[0][0] = forward_ref[0][0] + offset * 4; - picture->f_motion.ref[0][1] = forward_ref[0][1] + offset; - picture->f_motion.ref[0][2] = forward_ref[0][2] + offset; - picture->f_motion.f_code[0] = picture->f_code[0][0]; - picture->f_motion.f_code[1] = picture->f_code[0][1]; + picture->f_motion.ref[0][0] = forward_ref[0][0]; + picture->f_motion.ref[0][1] = forward_ref[0][1]; + picture->f_motion.ref[0][2] = forward_ref[0][2]; + picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; - picture->b_motion.ref[0][0] = - picture->backward_reference_frame->base[0] + offset * 4; - picture->b_motion.ref[0][1] = - picture->backward_reference_frame->base[1] + offset; - picture->b_motion.ref[0][2] = - picture->backward_reference_frame->base[2] + offset; - picture->b_motion.f_code[0] = picture->f_code[1][0]; - picture->b_motion.f_code[1] = picture->f_code[1][1]; + + picture->b_motion.ref[0][0] = picture->backward_reference_frame->base[0]; + picture->b_motion.ref[0][1] = picture->backward_reference_frame->base[1]; + picture->b_motion.ref[0][2] = picture->backward_reference_frame->base[2]; + picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; @@ -1566,7 +1582,6 @@ int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer) stride <<= 1; } - /* reset intra dc predictor */ picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision + 7); @@ -1617,7 +1632,6 @@ int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer) DCT_stride = stride; } - /* Decode lum blocks */ slice_intra_DCT (picture, 0, dest[0] + offset, DCT_stride); slice_intra_DCT (picture, 0, dest[0] + offset + 8, DCT_stride); slice_intra_DCT (picture, 0, dest[0] + offset + DCT_offset, @@ -1625,7 +1639,6 @@ int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer) slice_intra_DCT (picture, 0, dest[0] + offset + DCT_offset + 8, DCT_stride); - /* Decode chroma blocks */ slice_intra_DCT (picture, 1, dest[1] + (offset >> 1), stride >> 1); slice_intra_DCT (picture, 2, dest[2] + (offset >> 1), stride >> 1); @@ -1693,7 +1706,6 @@ int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer) break; } - /* 6.3.17.4 Coded block pattern */ if (macroblock_modes & MACROBLOCK_PATTERN) { int coded_block_pattern; int DCT_offset, DCT_stride; @@ -1708,8 +1720,6 @@ int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer) coded_block_pattern = get_coded_block_pattern (picture); - /* Decode lum blocks */ - if (coded_block_pattern & 0x20) slice_non_intra_DCT (picture, dest[0] + offset, DCT_stride); @@ -1725,8 +1735,6 @@ int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer) dest[0] + offset + DCT_offset + 8, DCT_stride); - /* Decode chroma blocks */ - if (coded_block_pattern & 0x2) slice_non_intra_DCT (picture, dest[1] + (offset >> 1), stride >> 1); @@ -1756,12 +1764,9 @@ int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer) if (!mba_inc) break; - /* reset intra dc predictor on skipped block */ picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision+7); - /* handling of skipped mb's differs between P_TYPE and B_TYPE */ - /* pictures */ if (picture->picture_coding_type == P_TYPE) { picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; |