diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2009-11-30 19:14:00 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2009-11-30 19:14:00 +0000 |
commit | 078cdecf9e469d80c160101f8b4a8bd0dbed519e (patch) | |
tree | 5ef02166e2b55c569687403555f642f014d8a46a | |
parent | 22d4f21331429a05a5c067c5ff358688c7eb3994 (diff) | |
download | ffmpeg-078cdecf9e469d80c160101f8b4a8bd0dbed519e.tar.gz |
Set mb_y in mpeg2 field pictures like h264 does.
This fixes -vismv & -debug 16384 with field pictures.
Originally committed as revision 20670 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/mpeg12.c | 21 | ||||
-rw-r--r-- | libavcodec/mpegvideo.c | 38 | ||||
-rw-r--r-- | libavcodec/mpegvideo_common.h | 30 |
3 files changed, 50 insertions, 39 deletions
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 51bc9f0606..8f4e2169e0 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1673,7 +1673,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, s->resync_mb_x= s->resync_mb_y= -1; - if (mb_y<<field_pic >= s->mb_height){ + if (mb_y >= s->mb_height){ av_log(s->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s->mb_height); return -1; } @@ -1756,11 +1756,9 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, return -1; if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs - const int wrap = field_pic ? 2*s->b8_stride : s->b8_stride; + const int wrap = s->b8_stride; int xy = s->mb_x*2 + s->mb_y*2*wrap; int motion_x, motion_y, dir, i; - if(field_pic && !s->first_field) - xy += wrap/2; for(i=0; i<2; i++){ for(dir=0; dir<2; dir++){ @@ -1795,12 +1793,12 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, if (++s->mb_x >= s->mb_width) { const int mb_size= 16>>s->avctx->lowres; - ff_draw_horiz_band(s, mb_size*s->mb_y, mb_size); + ff_draw_horiz_band(s, mb_size*(s->mb_y>>field_pic), mb_size); s->mb_x = 0; - s->mb_y++; + s->mb_y += 1<<field_pic; - if(s->mb_y<<field_pic >= s->mb_height){ + if(s->mb_y >= s->mb_height){ int left= get_bits_left(&s->gb); int is_d10= s->chroma_format==2 && s->pict_type==FF_I_TYPE && avctx->profile==0 && avctx->level==5 && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0 @@ -1885,8 +1883,9 @@ static int slice_decode_thread(AVCodecContext *c, void *arg){ MpegEncContext *s= *(void**)arg; const uint8_t *buf= s->gb.buffer; int mb_y= s->start_mb_y; + const int field_pic= s->picture_structure != PICT_FRAME; - s->error_count= 3*(s->end_mb_y - s->start_mb_y)*s->mb_width; + s->error_count= (3*(s->end_mb_y - s->start_mb_y)*s->mb_width) >> field_pic; for(;;){ uint32_t start_code; @@ -2384,9 +2383,13 @@ static int decode_chunks(AVCodecContext *avctx, default: if (start_code >= SLICE_MIN_START_CODE && start_code <= SLICE_MAX_START_CODE && last_code!=0) { - int mb_y= start_code - SLICE_MIN_START_CODE; + const int field_pic= s2->picture_structure != PICT_FRAME; + int mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic; last_code= SLICE_MIN_START_CODE; + if(s2->picture_structure == PICT_BOTTOM_FIELD) + mb_y++; + if(s2->last_picture_ptr==NULL){ /* Skip B-frames if we do not have reference frames and gop is not closed */ if(s2->pict_type==FF_B_TYPE){ diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 08ad85073c..e62428db58 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1441,7 +1441,7 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int field_based, int bottom_field, int field_select, uint8_t **ref_picture, h264_chroma_mc_func *pix_op, - int motion_x, int motion_y, int h) + int motion_x, int motion_y, int h, int mb_y) { uint8_t *ptr_y, *ptr_cb, *ptr_cr; int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy, uvsx, uvsy; @@ -1465,7 +1465,7 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, sx= motion_x & s_mask; sy= motion_y & s_mask; src_x = s->mb_x*2*block_s + (motion_x >> (lowres+1)); - src_y =(s->mb_y*2*block_s>>field_based) + (motion_y >> (lowres+1)); + src_y =( mb_y*2*block_s>>field_based) + (motion_y >> (lowres+1)); if (s->out_format == FMT_H263) { uvsx = ((motion_x>>1) & s_mask) | (sx&1); @@ -1478,14 +1478,14 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, uvsx = (2*mx) & s_mask; uvsy = (2*my) & s_mask; uvsrc_x = s->mb_x*block_s + (mx >> lowres); - uvsrc_y = s->mb_y*block_s + (my >> lowres); + uvsrc_y = mb_y*block_s + (my >> lowres); } else { mx = motion_x / 2; my = motion_y / 2; uvsx = mx & s_mask; uvsy = my & s_mask; uvsrc_x = s->mb_x*block_s + (mx >> (lowres+1)); - uvsrc_y =(s->mb_y*block_s>>field_based) + (my >> (lowres+1)); + uvsrc_y =( mb_y*block_s>>field_based) + (my >> (lowres+1)); } ptr_y = ref_picture[0] + src_y * linesize + src_x; @@ -1612,7 +1612,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s, mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, 0, 0, ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s); + s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s, mb_y); break; case MV_TYPE_8X8: mx = 0; @@ -1639,12 +1639,12 @@ static inline void MPV_motion_lowres(MpegEncContext *s, mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, 0, s->field_select[dir][0], ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], block_s); + s->mv[dir][0][0], s->mv[dir][0][1], block_s, mb_y); /* bottom field */ mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, 1, s->field_select[dir][1], ref_picture, pix_op, - s->mv[dir][1][0], s->mv[dir][1][1], block_s); + s->mv[dir][1][0], s->mv[dir][1][1], block_s, mb_y); } else { if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){ ref_picture= s->current_picture_ptr->data; @@ -1653,7 +1653,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s, mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, 0, s->field_select[dir][0], ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s); + s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s, mb_y>>1); } break; case MV_TYPE_16X8: @@ -1669,7 +1669,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s, mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, 0, s->field_select[dir][i], ref2picture, pix_op, - s->mv[dir][i][0], s->mv[dir][i][1] + 2*block_s*i, block_s); + s->mv[dir][i][0], s->mv[dir][i][1] + 2*block_s*i, block_s, mb_y>>1); dest_y += 2*block_s*s->linesize; dest_cb+= (2*block_s>>s->chroma_y_shift)*s->uvlinesize; @@ -1684,7 +1684,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s, mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, j, j^i, ref_picture, pix_op, - s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], block_s); + s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], block_s, mb_y); } pix_op = s->dsp.avg_h264_chroma_pixels_tab; } @@ -1693,7 +1693,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s, mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, 0, s->picture_structure != i+1, ref_picture, pix_op, - s->mv[dir][2*i][0],s->mv[dir][2*i][1],2*block_s); + s->mv[dir][2*i][0],s->mv[dir][2*i][1],2*block_s, mb_y>>1); // after put we make avg of the same block pix_op = s->dsp.avg_h264_chroma_pixels_tab; @@ -2034,16 +2034,17 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ if (s->avctx->draw_horiz_band) { AVFrame *src; + const int field_pic= s->picture_structure != PICT_FRAME; int offset[4]; - if(s->picture_structure != PICT_FRAME){ + h= FFMIN(h, (s->avctx->height>>field_pic) - y); + + if(field_pic && !(s->avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)){ h <<= 1; y <<= 1; - if(s->first_field && !(s->avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)) return; + if(s->first_field) return; } - h= FFMIN(h, s->avctx->height - y); - if(s->pict_type==FF_B_TYPE || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER)) src= (AVFrame*)s->current_picture_ptr; else if(s->last_picture_ptr) @@ -2089,9 +2090,16 @@ void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename if(!(s->pict_type==FF_B_TYPE && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME)) { + if(s->picture_structure==PICT_FRAME){ s->dest[0] += s->mb_y * linesize << mb_size; s->dest[1] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift); s->dest[2] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift); + }else{ + s->dest[0] += (s->mb_y>>1) * linesize << mb_size; + s->dest[1] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift); + s->dest[2] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift); + assert((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD)); + } } } diff --git a/libavcodec/mpegvideo_common.h b/libavcodec/mpegvideo_common.h index 251aa6cd7f..dc817fd600 100644 --- a/libavcodec/mpegvideo_common.h +++ b/libavcodec/mpegvideo_common.h @@ -242,7 +242,7 @@ void mpeg_motion_internal(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int field_based, int bottom_field, int field_select, uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h, int is_mpeg12) + int motion_x, int motion_y, int h, int is_mpeg12, int mb_y) { uint8_t *ptr_y, *ptr_cb, *ptr_cr; int dxy, uvdxy, mx, my, src_x, src_y, @@ -262,7 +262,7 @@ if(s->quarter_sample) dxy = ((motion_y & 1) << 1) | (motion_x & 1); src_x = s->mb_x* 16 + (motion_x >> 1); - src_y =(s->mb_y<<(4-field_based)) + (motion_y >> 1); + src_y =( mb_y<<(4-field_based)) + (motion_y >> 1); if (!is_mpeg12 && s->out_format == FMT_H263) { if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){ @@ -270,7 +270,7 @@ if(s->quarter_sample) my = motion_y >>1; uvdxy = ((my & 1) << 1) | (mx & 1); uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1); + uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1); }else{ uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); uvsrc_x = src_x>>1; @@ -281,14 +281,14 @@ if(s->quarter_sample) my = motion_y / 4; uvdxy = 0; uvsrc_x = s->mb_x*8 + mx; - uvsrc_y = s->mb_y*8 + my; + uvsrc_y = mb_y*8 + my; } else { if(s->chroma_y_shift){ mx = motion_x / 2; my = motion_y / 2; uvdxy = ((my & 1) << 1) | (mx & 1); uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1); + uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1); } else { if(s->chroma_x_shift){ //Chroma422 @@ -370,18 +370,18 @@ void mpeg_motion(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int field_based, int bottom_field, int field_select, uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h) + int motion_x, int motion_y, int h, int mb_y) { #if !CONFIG_SMALL if(s->out_format == FMT_MPEG1) mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based, bottom_field, field_select, ref_picture, pix_op, - motion_x, motion_y, h, 1); + motion_x, motion_y, h, 1, mb_y); else #endif mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based, bottom_field, field_select, ref_picture, pix_op, - motion_x, motion_y, h, 0); + motion_x, motion_y, h, 0, mb_y); } //FIXME move to dsputil, avg variant, 16x16 version @@ -736,7 +736,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 0, 0, ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); + s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y); } break; case MV_TYPE_8X8: @@ -810,12 +810,12 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, mpeg_motion(s, dest_y, dest_cb, dest_cr, 1, 0, s->field_select[dir][0], ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 8); + s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y); /* bottom field */ mpeg_motion(s, dest_y, dest_cb, dest_cr, 1, 1, s->field_select[dir][1], ref_picture, pix_op, - s->mv[dir][1][0], s->mv[dir][1][1], 8); + s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y); } } else { if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){ @@ -825,7 +825,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 0, s->field_select[dir][0], ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); + s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y>>1); } break; case MV_TYPE_16X8: @@ -842,7 +842,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 0, s->field_select[dir][i], ref2picture, pix_op, - s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8); + s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8, mb_y>>1); dest_y += 16*s->linesize; dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize; @@ -857,7 +857,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, mpeg_motion(s, dest_y, dest_cb, dest_cr, 1, j, j^i, ref_picture, pix_op, - s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8); + s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8, mb_y); } pix_op = s->dsp.avg_pixels_tab; } @@ -866,7 +866,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 0, s->picture_structure != i+1, ref_picture, pix_op, - s->mv[dir][2*i][0],s->mv[dir][2*i][1],16); + s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1); // after put we make avg of the same block pix_op=s->dsp.avg_pixels_tab; |