# HG changeset patch # User michaelni # Date 1046886499 0 # Node ID 5e6e505d8997e7147c6c9ef94717758a865dff01 # Parent c7604e6291c50c0b5489114ebdf6a51593cc0f66 field picture decoding support (16x16 MC blocks only as i dont have any samples which use other modes ...) diff -r c7604e6291c5 -r 5e6e505d8997 mpeg12.c --- a/mpeg12.c Wed Mar 05 16:10:13 2003 +0000 +++ b/mpeg12.c Wed Mar 05 17:48:19 2003 +0000 @@ -1023,8 +1023,8 @@ } break; case MT_FIELD: + s->mv_type = MV_TYPE_FIELD; if (s->picture_structure == PICT_FRAME) { - s->mv_type = MV_TYPE_FIELD; for(j=0;j<2;j++) { s->field_select[i][j] = get_bits1(&s->gb); val = mpeg_decode_motion(s, s->mpeg_f_code[i][0], @@ -1039,7 +1039,6 @@ dprintf("fmy=%d\n", val); } } else { - s->mv_type = MV_TYPE_16X16; s->field_select[i][0] = get_bits1(&s->gb); for(k=0;k<2;k++) { val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], @@ -1701,6 +1700,13 @@ s->chroma_420_type = get_bits1(&s->gb); s->progressive_frame = get_bits1(&s->gb); + if(s->picture_structure == PICT_FRAME) + s->first_field=0; + else{ + s->first_field ^= 1; + memset(s->mbskip_table, 0, s->mb_width*s->mb_height); + } + if(s->alternate_scan){ ff_init_scantable(s, &s->inter_scantable , ff_alternate_vertical_scan); ff_init_scantable(s, &s->intra_scantable , ff_alternate_vertical_scan); @@ -1771,6 +1777,7 @@ Mpeg1Context *s1 = avctx->priv_data; MpegEncContext *s = &s1->mpeg_enc_ctx; int ret; + const int field_pic= s->picture_structure != PICT_FRAME; start_code = (start_code - 1) & 0xff; if (start_code >= s->mb_height){ @@ -1781,9 +1788,9 @@ s->last_dc[1] = s->last_dc[0]; s->last_dc[2] = s->last_dc[0]; memset(s->last_mv, 0, sizeof(s->last_mv)); + /* start frame decoding */ - if (s->first_slice) { - s->first_slice = 0; + if (s->first_slice && (s->first_field || s->picture_structure==PICT_FRAME)) { if(MPV_frame_start(s, avctx) < 0) return DECODE_SLICE_FATAL_ERROR; /* first check if we must repeat the frame */ @@ -1810,6 +1817,7 @@ s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :""); } } + s->first_slice = 0; init_get_bits(&s->gb, buf, buf_size*8); @@ -1844,8 +1852,27 @@ dprintf("ret=%d\n", ret); if (ret < 0) return -1; - +//printf("%d %d\n", s->mb_x, s->mb_y); + //FIXME this isnt the most beautifull way to solve the problem ... + if(s->picture_structure!=PICT_FRAME){ + if(s->picture_structure == PICT_BOTTOM_FIELD){ + s->current_picture.data[0] += s->linesize; + s->current_picture.data[1] += s->uvlinesize; + s->current_picture.data[2] += s->uvlinesize; + } + s->linesize *= 2; + s->uvlinesize *= 2; + } MPV_decode_mb(s, s->block); + if(s->picture_structure!=PICT_FRAME){ + s->linesize /= 2; + s->uvlinesize /= 2; + if(s->picture_structure == PICT_BOTTOM_FIELD){ + s->current_picture.data[0] -= s->linesize; + s->current_picture.data[1] -= s->uvlinesize; + s->current_picture.data[2] -= s->uvlinesize; + } + } if (++s->mb_x >= s->mb_width) { ff_draw_horiz_band(s); @@ -1875,7 +1902,7 @@ } } } - if(s->mb_y >= s->mb_height){ + if(s->mb_y<= s->mb_height){ fprintf(stderr, "slice too long\n"); return DECODE_SLICE_ERROR; } @@ -1883,10 +1910,9 @@ eos: //end of slice emms_c(); - +//intf("%d %d %d %d\n", s->mb_y, s->mb_height, s->pict_type, s->picture_number); /* end of slice reached */ - if (/*s->mb_x == 0 &&*/ - s->mb_y == s->mb_height) { + if (s->mb_y<mb_height && !s->first_field) { /* end of image */ if(s->mpeg2) @@ -2159,6 +2185,7 @@ ret = mpeg_decode_slice(avctx, picture, start_code, s->buffer, input_size); + if (ret == DECODE_SLICE_EOP) { *data_size = sizeof(AVPicture); goto the_end; diff -r c7604e6291c5 -r 5e6e505d8997 mpegvideo.c --- a/mpegvideo.c Wed Mar 05 16:10:13 2003 +0000 +++ b/mpegvideo.c Wed Mar 05 17:48:19 2003 +0000 @@ -212,6 +212,8 @@ ff_init_scantable(s, &s->intra_h_scantable, ff_alternate_horizontal_scan); ff_init_scantable(s, &s->intra_v_scantable, ff_alternate_vertical_scan); + s->picture_structure= PICT_FRAME; + return 0; } @@ -1855,8 +1857,18 @@ s->mv[dir][1][0], s->mv[dir][1][1], 8); } } else { - - + int offset; + if(s->picture_structure == s->field_select[dir][0] + 1 || s->pict_type == B_TYPE || s->first_field){ + offset= s->field_select[dir][0] ? s->linesize/2 : 0; + }else{ + ref_picture= s->current_picture.data; + offset= s->field_select[dir][0] ? s->linesize/2 : -s->linesize/2; + } + + mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, + ref_picture, offset, + 0, pix_op, + s->mv[dir][0][0], s->mv[dir][0][1], 16); } break; } diff -r c7604e6291c5 -r 5e6e505d8997 mpegvideo.h --- a/mpegvideo.h Wed Mar 05 16:10:13 2003 +0000 +++ b/mpegvideo.h Wed Mar 05 17:48:19 2003 +0000 @@ -528,6 +528,7 @@ int full_pel[2]; int interlaced_dct; int first_slice; + int first_field; /* RTP specific */ /* These are explained on avcodec.h */