comparison mpegvideo.c @ 1842:0d82db458a3c libavcodec

interlaced mpeg4 + edge emu fix (fixes decoding of mermaid.avi) related cleanup
author michael
date Sun, 29 Feb 2004 00:37:36 +0000
parents 8cdbb74c2f4b
children 2b488cb389b6
comparison
equal deleted inserted replaced
1841:05017f3b87d9 1842:0d82db458a3c
2121 2121
2122 #endif //CONFIG_ENCODERS 2122 #endif //CONFIG_ENCODERS
2123 2123
2124 static inline void gmc1_motion(MpegEncContext *s, 2124 static inline void gmc1_motion(MpegEncContext *s,
2125 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, 2125 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
2126 int dest_offset, 2126 uint8_t **ref_picture)
2127 uint8_t **ref_picture, int src_offset)
2128 { 2127 {
2129 uint8_t *ptr; 2128 uint8_t *ptr;
2130 int offset, src_x, src_y, linesize, uvlinesize; 2129 int offset, src_x, src_y, linesize, uvlinesize;
2131 int motion_x, motion_y; 2130 int motion_x, motion_y;
2132 int emu=0; 2131 int emu=0;
2145 motion_y =0; 2144 motion_y =0;
2146 2145
2147 linesize = s->linesize; 2146 linesize = s->linesize;
2148 uvlinesize = s->uvlinesize; 2147 uvlinesize = s->uvlinesize;
2149 2148
2150 ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset; 2149 ptr = ref_picture[0] + (src_y * linesize) + src_x;
2151 2150
2152 dest_y+=dest_offset;
2153 if(s->flags&CODEC_FLAG_EMU_EDGE){ 2151 if(s->flags&CODEC_FLAG_EMU_EDGE){
2154 if( (unsigned)src_x >= s->h_edge_pos - 17 2152 if( (unsigned)src_x >= s->h_edge_pos - 17
2155 || (unsigned)src_y >= s->v_edge_pos - 17){ 2153 || (unsigned)src_y >= s->v_edge_pos - 17){
2156 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos); 2154 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
2157 ptr= s->edge_emu_buffer; 2155 ptr= s->edge_emu_buffer;
2185 motion_x =0; 2183 motion_x =0;
2186 src_y = clip(src_y, -8, s->height>>1); 2184 src_y = clip(src_y, -8, s->height>>1);
2187 if (src_y == s->height>>1) 2185 if (src_y == s->height>>1)
2188 motion_y =0; 2186 motion_y =0;
2189 2187
2190 offset = (src_y * uvlinesize) + src_x + (src_offset>>1); 2188 offset = (src_y * uvlinesize) + src_x;
2191 ptr = ref_picture[1] + offset; 2189 ptr = ref_picture[1] + offset;
2192 if(s->flags&CODEC_FLAG_EMU_EDGE){ 2190 if(s->flags&CODEC_FLAG_EMU_EDGE){
2193 if( (unsigned)src_x >= (s->h_edge_pos>>1) - 9 2191 if( (unsigned)src_x >= (s->h_edge_pos>>1) - 9
2194 || (unsigned)src_y >= (s->v_edge_pos>>1) - 9){ 2192 || (unsigned)src_y >= (s->v_edge_pos>>1) - 9){
2195 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); 2193 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
2196 ptr= s->edge_emu_buffer; 2194 ptr= s->edge_emu_buffer;
2197 emu=1; 2195 emu=1;
2198 } 2196 }
2199 } 2197 }
2200 s->dsp.gmc1(dest_cb + (dest_offset>>1), ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); 2198 s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
2201 2199
2202 ptr = ref_picture[2] + offset; 2200 ptr = ref_picture[2] + offset;
2203 if(emu){ 2201 if(emu){
2204 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); 2202 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
2205 ptr= s->edge_emu_buffer; 2203 ptr= s->edge_emu_buffer;
2206 } 2204 }
2207 s->dsp.gmc1(dest_cr + (dest_offset>>1), ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); 2205 s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
2208 2206
2209 return; 2207 return;
2210 } 2208 }
2211 2209
2212 static inline void gmc_motion(MpegEncContext *s, 2210 static inline void gmc_motion(MpegEncContext *s,
2213 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, 2211 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
2214 int dest_offset, 2212 uint8_t **ref_picture)
2215 uint8_t **ref_picture, int src_offset)
2216 { 2213 {
2217 uint8_t *ptr; 2214 uint8_t *ptr;
2218 int linesize, uvlinesize; 2215 int linesize, uvlinesize;
2219 const int a= s->sprite_warping_accuracy; 2216 const int a= s->sprite_warping_accuracy;
2220 int ox, oy; 2217 int ox, oy;
2221 2218
2222 linesize = s->linesize; 2219 linesize = s->linesize;
2223 uvlinesize = s->uvlinesize; 2220 uvlinesize = s->uvlinesize;
2224 2221
2225 ptr = ref_picture[0] + src_offset; 2222 ptr = ref_picture[0];
2226 2223
2227 dest_y+=dest_offset;
2228
2229 ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16; 2224 ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16;
2230 oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16; 2225 oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16;
2231 2226
2232 s->dsp.gmc(dest_y, ptr, linesize, 16, 2227 s->dsp.gmc(dest_y, ptr, linesize, 16,
2233 ox, 2228 ox,
2244 a+1, (1<<(2*a+1)) - s->no_rounding, 2239 a+1, (1<<(2*a+1)) - s->no_rounding,
2245 s->h_edge_pos, s->v_edge_pos); 2240 s->h_edge_pos, s->v_edge_pos);
2246 2241
2247 if(s->flags&CODEC_FLAG_GRAY) return; 2242 if(s->flags&CODEC_FLAG_GRAY) return;
2248 2243
2249
2250 dest_cb+=dest_offset>>1;
2251 dest_cr+=dest_offset>>1;
2252
2253 ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8; 2244 ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8;
2254 oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8; 2245 oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8;
2255 2246
2256 ptr = ref_picture[1] + (src_offset>>1); 2247 ptr = ref_picture[1];
2257 s->dsp.gmc(dest_cb, ptr, uvlinesize, 8, 2248 s->dsp.gmc(dest_cb, ptr, uvlinesize, 8,
2258 ox, 2249 ox,
2259 oy, 2250 oy,
2260 s->sprite_delta[0][0], s->sprite_delta[0][1], 2251 s->sprite_delta[0][0], s->sprite_delta[0][1],
2261 s->sprite_delta[1][0], s->sprite_delta[1][1], 2252 s->sprite_delta[1][0], s->sprite_delta[1][1],
2262 a+1, (1<<(2*a+1)) - s->no_rounding, 2253 a+1, (1<<(2*a+1)) - s->no_rounding,
2263 s->h_edge_pos>>1, s->v_edge_pos>>1); 2254 s->h_edge_pos>>1, s->v_edge_pos>>1);
2264 2255
2265 ptr = ref_picture[2] + (src_offset>>1); 2256 ptr = ref_picture[2];
2266 s->dsp.gmc(dest_cr, ptr, uvlinesize, 8, 2257 s->dsp.gmc(dest_cr, ptr, uvlinesize, 8,
2267 ox, 2258 ox,
2268 oy, 2259 oy,
2269 s->sprite_delta[0][0], s->sprite_delta[0][1], 2260 s->sprite_delta[0][0], s->sprite_delta[0][1],
2270 s->sprite_delta[1][0], s->sprite_delta[1][1], 2261 s->sprite_delta[1][0], s->sprite_delta[1][1],
2342 } 2333 }
2343 } 2334 }
2344 } 2335 }
2345 2336
2346 static inline int hpel_motion(MpegEncContext *s, 2337 static inline int hpel_motion(MpegEncContext *s,
2347 uint8_t *dest, uint8_t *src, 2338 uint8_t *dest, uint8_t *src,
2339 int field_based, int field_select,
2348 int src_x, int src_y, 2340 int src_x, int src_y,
2349 int width, int height, int stride, 2341 int width, int height, int stride,
2350 int h_edge_pos, int v_edge_pos, 2342 int h_edge_pos, int v_edge_pos,
2351 int w, int h, op_pixels_func *pix_op, 2343 int w, int h, op_pixels_func *pix_op,
2352 int motion_x, int motion_y) 2344 int motion_x, int motion_y)
2368 src += src_y * stride + src_x; 2360 src += src_y * stride + src_x;
2369 2361
2370 if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){ 2362 if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
2371 if( (unsigned)src_x > h_edge_pos - (motion_x&1) - w 2363 if( (unsigned)src_x > h_edge_pos - (motion_x&1) - w
2372 || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){ 2364 || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){
2373 ff_emulated_edge_mc(s->edge_emu_buffer, src, stride, w+1, h+1, 2365 ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based,
2374 src_x, src_y, h_edge_pos, v_edge_pos); 2366 src_x, src_y<<field_based, h_edge_pos, s->v_edge_pos);
2375 src= s->edge_emu_buffer; 2367 src= s->edge_emu_buffer;
2376 emu=1; 2368 emu=1;
2377 } 2369 }
2378 } 2370 }
2371 if(field_select)
2372 src += s->linesize;
2379 pix_op[dxy](dest, src, stride, h); 2373 pix_op[dxy](dest, src, stride, h);
2380 return emu; 2374 return emu;
2381 } 2375 }
2382 2376
2383 /* apply one mpeg motion vector to the three components */ 2377 /* apply one mpeg motion vector to the three components */
2384 static inline void mpeg_motion(MpegEncContext *s, 2378 static inline void mpeg_motion(MpegEncContext *s,
2385 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, 2379 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
2386 int dest_offset, 2380 int field_based, int bottom_field, int field_select,
2387 uint8_t **ref_picture, int src_offset, 2381 uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
2388 int field_based, op_pixels_func (*pix_op)[4],
2389 int motion_x, int motion_y, int h) 2382 int motion_x, int motion_y, int h)
2390 { 2383 {
2391 uint8_t *ptr; 2384 uint8_t *ptr;
2392 int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, uvlinesize; 2385 int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, uvlinesize;
2393 int emu=0; 2386 int emu=0;
2387
2388 if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data
2389 dest_y += s->linesize;
2390 dest_cb+= s->uvlinesize;
2391 dest_cr+= s->uvlinesize;
2392 }
2393
2394 #if 0 2394 #if 0
2395 if(s->quarter_sample) 2395 if(s->quarter_sample)
2396 { 2396 {
2397 motion_x>>=1; 2397 motion_x>>=1;
2398 motion_y>>=1; 2398 motion_y>>=1;
2402 height = s->height >> field_based; 2402 height = s->height >> field_based;
2403 v_edge_pos = s->v_edge_pos >> field_based; 2403 v_edge_pos = s->v_edge_pos >> field_based;
2404 uvlinesize = s->current_picture.linesize[1] << field_based; 2404 uvlinesize = s->current_picture.linesize[1] << field_based;
2405 2405
2406 emu= hpel_motion(s, 2406 emu= hpel_motion(s,
2407 dest_y + dest_offset, ref_picture[0] + src_offset, 2407 dest_y, ref_picture[0], field_based, field_select,
2408 s->mb_x * 16, s->mb_y * (16 >> field_based), 2408 s->mb_x * 16, s->mb_y * (16 >> field_based),
2409 s->width, height, s->current_picture.linesize[0] << field_based, 2409 s->width, height, s->current_picture.linesize[0] << field_based,
2410 s->h_edge_pos, v_edge_pos, 2410 s->h_edge_pos, v_edge_pos,
2411 16, h, pix_op[0], 2411 16, h, pix_op[0],
2412 motion_x, motion_y); 2412 motion_x, motion_y);
2436 if (src_x == (s->width >> 1)) 2436 if (src_x == (s->width >> 1))
2437 dxy &= ~1; 2437 dxy &= ~1;
2438 src_y = clip(src_y, -8, height >> 1); 2438 src_y = clip(src_y, -8, height >> 1);
2439 if (src_y == (height >> 1)) 2439 if (src_y == (height >> 1))
2440 dxy &= ~2; 2440 dxy &= ~2;
2441 offset = (src_y * uvlinesize) + src_x + (src_offset >> 1); 2441 offset = (src_y * uvlinesize) + src_x;
2442 ptr = ref_picture[1] + offset; 2442 ptr = ref_picture[1] + offset;
2443 if(emu){ 2443 if(emu){
2444 ff_emulated_edge_mc(s->edge_emu_buffer, ptr - (src_offset >> 1), s->uvlinesize, 9, 9+field_based, 2444 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9+field_based,
2445 src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); 2445 src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);
2446 ptr= s->edge_emu_buffer + (src_offset >> 1); 2446 ptr= s->edge_emu_buffer;
2447 } 2447 }
2448 pix_op[1][dxy](dest_cb + (dest_offset >> 1), ptr, uvlinesize, h >> 1); 2448 if(field_select)
2449 ptr+= s->uvlinesize;
2450 pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1);
2449 2451
2450 ptr = ref_picture[2] + offset; 2452 ptr = ref_picture[2] + offset;
2451 if(emu){ 2453 if(emu){
2452 ff_emulated_edge_mc(s->edge_emu_buffer, ptr - (src_offset >> 1), s->uvlinesize, 9, 9+field_based, 2454 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9+field_based,
2453 src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); 2455 src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);
2454 ptr= s->edge_emu_buffer + (src_offset >> 1); 2456 ptr= s->edge_emu_buffer;
2455 } 2457 }
2456 pix_op[1][dxy](dest_cr + (dest_offset >> 1), ptr, uvlinesize, h >> 1); 2458 if(field_select)
2459 ptr+= s->uvlinesize;
2460 pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1);
2457 } 2461 }
2458 //FIXME move to dsputil, avg variant, 16x16 version 2462 //FIXME move to dsputil, avg variant, 16x16 version
2459 static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){ 2463 static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){
2460 int x; 2464 int x;
2461 uint8_t * const top = src[1]; 2465 uint8_t * const top = src[1];
2523 for(i=0; i<5; i++){ 2527 for(i=0; i<5; i++){
2524 if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){ 2528 if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){
2525 ptr[i]= ptr[MID]; 2529 ptr[i]= ptr[MID];
2526 }else{ 2530 }else{
2527 ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1); 2531 ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1);
2528 hpel_motion(s, ptr[i], src, 2532 hpel_motion(s, ptr[i], src, 0, 0,
2529 src_x, src_y, 2533 src_x, src_y,
2530 s->width, s->height, s->linesize, 2534 s->width, s->height, s->linesize,
2531 s->h_edge_pos, s->v_edge_pos, 2535 s->h_edge_pos, s->v_edge_pos,
2532 8, 8, pix_op, 2536 8, 8, pix_op,
2533 mv[i][0], mv[i][1]); 2537 mv[i][0], mv[i][1]);
2537 put_obmc(dest, ptr, s->linesize); 2541 put_obmc(dest, ptr, s->linesize);
2538 } 2542 }
2539 2543
2540 static inline void qpel_motion(MpegEncContext *s, 2544 static inline void qpel_motion(MpegEncContext *s,
2541 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, 2545 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
2542 int dest_offset, 2546 int field_based, int bottom_field, int field_select,
2543 uint8_t **ref_picture, int src_offset, 2547 uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
2544 int field_based, op_pixels_func (*pix_op)[4],
2545 qpel_mc_func (*qpix_op)[16], 2548 qpel_mc_func (*qpix_op)[16],
2546 int motion_x, int motion_y, int h) 2549 int motion_x, int motion_y, int h)
2547 { 2550 {
2548 uint8_t *ptr; 2551 uint8_t *ptr;
2549 int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, linesize, uvlinesize; 2552 int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, linesize, uvlinesize;
2550 int emu=0; 2553 int emu=0;
2554
2555 if(bottom_field){
2556 dest_y += s->linesize;
2557 dest_cb+= s->uvlinesize;
2558 dest_cr+= s->uvlinesize;
2559 }
2551 2560
2552 dxy = ((motion_y & 3) << 2) | (motion_x & 3); 2561 dxy = ((motion_y & 3) << 2) | (motion_x & 3);
2553 src_x = s->mb_x * 16 + (motion_x >> 2); 2562 src_x = s->mb_x * 16 + (motion_x >> 2);
2554 src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); 2563 src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
2555 2564
2561 src_y = clip(src_y, -16, height); 2570 src_y = clip(src_y, -16, height);
2562 if (src_y == height) 2571 if (src_y == height)
2563 dxy &= ~12; 2572 dxy &= ~12;
2564 linesize = s->linesize << field_based; 2573 linesize = s->linesize << field_based;
2565 uvlinesize = s->uvlinesize << field_based; 2574 uvlinesize = s->uvlinesize << field_based;
2566 ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset; 2575 ptr = ref_picture[0] + (src_y * linesize) + src_x;
2567 dest_y += dest_offset;
2568 //printf("%d %d %d\n", src_x, src_y, dxy);
2569 2576
2570 if(s->flags&CODEC_FLAG_EMU_EDGE){ 2577 if(s->flags&CODEC_FLAG_EMU_EDGE){
2571 if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16 2578 if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16
2572 || (unsigned)src_y > v_edge_pos - (motion_y&3) - h ){ 2579 || (unsigned)src_y > v_edge_pos - (motion_y&3) - h ){
2573 ff_emulated_edge_mc(s->edge_emu_buffer, ptr - src_offset, s->linesize, 17, 17+field_based, 2580 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize, 17, 17+field_based,
2574 src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos); 2581 src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos);
2575 ptr= s->edge_emu_buffer + src_offset; 2582 ptr= s->edge_emu_buffer;
2576 emu=1; 2583 emu=1;
2577 } 2584 }
2578 } 2585 }
2579 if(!field_based) 2586 if(!field_based)
2580 qpix_op[0][dxy](dest_y, ptr, linesize); 2587 qpix_op[0][dxy](dest_y, ptr, linesize);
2581 else{ 2588 else{
2589 if(field_select)
2590 ptr += s->linesize;
2582 //damn interlaced mode 2591 //damn interlaced mode
2583 //FIXME boundary mirroring is not exactly correct here 2592 //FIXME boundary mirroring is not exactly correct here
2584 qpix_op[1][dxy](dest_y , ptr , linesize); 2593 qpix_op[1][dxy](dest_y , ptr , linesize);
2585 qpix_op[1][dxy](dest_y+8, ptr+8, linesize); 2594 qpix_op[1][dxy](dest_y+8, ptr+8, linesize);
2586 } 2595 }
2615 dxy &= ~1; 2624 dxy &= ~1;
2616 src_y = clip(src_y, -8, height >> 1); 2625 src_y = clip(src_y, -8, height >> 1);
2617 if (src_y == (height >> 1)) 2626 if (src_y == (height >> 1))
2618 dxy &= ~2; 2627 dxy &= ~2;
2619 2628
2620 offset = (src_y * uvlinesize) + src_x + (src_offset >> 1); 2629 offset = (src_y * uvlinesize) + src_x;
2621 ptr = ref_picture[1] + offset; 2630 ptr = ref_picture[1] + offset;
2622 if(emu){ 2631 if(emu){
2623 ff_emulated_edge_mc(s->edge_emu_buffer, ptr - (src_offset >> 1), s->uvlinesize, 9, 9 + field_based, 2632 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9 + field_based,
2624 src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); 2633 src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);
2625 ptr= s->edge_emu_buffer + (src_offset >> 1); 2634 ptr= s->edge_emu_buffer;
2626 } 2635 }
2627 pix_op[1][dxy](dest_cb + (dest_offset >> 1), ptr, uvlinesize, h >> 1); 2636 if(field_select)
2637 ptr += s->uvlinesize;
2638 pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1);
2628 2639
2629 ptr = ref_picture[2] + offset; 2640 ptr = ref_picture[2] + offset;
2630 if(emu){ 2641 if(emu){
2631 ff_emulated_edge_mc(s->edge_emu_buffer, ptr - (src_offset >> 1), s->uvlinesize, 9, 9 + field_based, 2642 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9 + field_based,
2632 src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); 2643 src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);
2633 ptr= s->edge_emu_buffer + (src_offset >> 1); 2644 ptr= s->edge_emu_buffer;
2634 } 2645 }
2635 pix_op[1][dxy](dest_cr + (dest_offset >> 1), ptr, uvlinesize, h >> 1); 2646 if(field_select)
2647 ptr += s->uvlinesize;
2648 pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1);
2636 } 2649 }
2637 2650
2638 inline int ff_h263_round_chroma(int x){ 2651 inline int ff_h263_round_chroma(int x){
2639 if (x >= 0) 2652 if (x >= 0)
2640 return (h263_chroma_roundtab[x & 0xf] + ((x >> 3) & ~1)); 2653 return (h263_chroma_roundtab[x & 0xf] + ((x >> 3) & ~1));
2781 switch(s->mv_type) { 2794 switch(s->mv_type) {
2782 case MV_TYPE_16X16: 2795 case MV_TYPE_16X16:
2783 #ifdef CONFIG_RISKY 2796 #ifdef CONFIG_RISKY
2784 if(s->mcsel){ 2797 if(s->mcsel){
2785 if(s->real_sprite_warping_points==1){ 2798 if(s->real_sprite_warping_points==1){
2786 gmc1_motion(s, dest_y, dest_cb, dest_cr, 0, 2799 gmc1_motion(s, dest_y, dest_cb, dest_cr,
2787 ref_picture, 0); 2800 ref_picture);
2788 }else{ 2801 }else{
2789 gmc_motion(s, dest_y, dest_cb, dest_cr, 0, 2802 gmc_motion(s, dest_y, dest_cb, dest_cr,
2790 ref_picture, 0); 2803 ref_picture);
2791 } 2804 }
2792 }else if(s->quarter_sample){ 2805 }else if(s->quarter_sample){
2793 qpel_motion(s, dest_y, dest_cb, dest_cr, 0, 2806 qpel_motion(s, dest_y, dest_cb, dest_cr,
2794 ref_picture, 0, 2807 0, 0, 0,
2795 0, pix_op, qpix_op, 2808 ref_picture, pix_op, qpix_op,
2796 s->mv[dir][0][0], s->mv[dir][0][1], 16); 2809 s->mv[dir][0][0], s->mv[dir][0][1], 16);
2797 }else if(s->mspel){ 2810 }else if(s->mspel){
2798 ff_mspel_motion(s, dest_y, dest_cb, dest_cr, 2811 ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
2799 ref_picture, pix_op, 2812 ref_picture, pix_op,
2800 s->mv[dir][0][0], s->mv[dir][0][1], 16); 2813 s->mv[dir][0][0], s->mv[dir][0][1], 16);
2801 }else 2814 }else
2802 #endif 2815 #endif
2803 { 2816 {
2804 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 2817 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2805 ref_picture, 0, 2818 0, 0, 0,
2806 0, pix_op, 2819 ref_picture, pix_op,
2807 s->mv[dir][0][0], s->mv[dir][0][1], 16); 2820 s->mv[dir][0][0], s->mv[dir][0][1], 16);
2808 } 2821 }
2809 break; 2822 break;
2810 case MV_TYPE_8X8: 2823 case MV_TYPE_8X8:
2811 mx = 0; 2824 mx = 0;
2842 my += s->mv[dir][i][1]/2; 2855 my += s->mv[dir][i][1]/2;
2843 } 2856 }
2844 }else{ 2857 }else{
2845 for(i=0;i<4;i++) { 2858 for(i=0;i<4;i++) {
2846 hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, 2859 hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
2847 ref_picture[0], 2860 ref_picture[0], 0, 0,
2848 mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, 2861 mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
2849 s->width, s->height, s->linesize, 2862 s->width, s->height, s->linesize,
2850 s->h_edge_pos, s->v_edge_pos, 2863 s->h_edge_pos, s->v_edge_pos,
2851 8, 8, pix_op[1], 2864 8, 8, pix_op[1],
2852 s->mv[dir][i][0], s->mv[dir][i][1]); 2865 s->mv[dir][i][0], s->mv[dir][i][1]);
2861 break; 2874 break;
2862 case MV_TYPE_FIELD: 2875 case MV_TYPE_FIELD:
2863 if (s->picture_structure == PICT_FRAME) { 2876 if (s->picture_structure == PICT_FRAME) {
2864 if(s->quarter_sample){ 2877 if(s->quarter_sample){
2865 /* top field */ 2878 /* top field */
2866 qpel_motion(s, dest_y, dest_cb, dest_cr, 0, 2879 qpel_motion(s, dest_y, dest_cb, dest_cr,
2867 ref_picture, s->field_select[dir][0] ? s->linesize : 0, 2880 1, 0, s->field_select[dir][0],
2868 1, pix_op, qpix_op, 2881 ref_picture, pix_op, qpix_op,
2869 s->mv[dir][0][0], s->mv[dir][0][1], 8); 2882 s->mv[dir][0][0], s->mv[dir][0][1], 8);
2870 /* bottom field */ 2883 /* bottom field */
2871 qpel_motion(s, dest_y, dest_cb, dest_cr, s->linesize, 2884 qpel_motion(s, dest_y, dest_cb, dest_cr,
2872 ref_picture, s->field_select[dir][1] ? s->linesize : 0, 2885 1, 1, s->field_select[dir][1],
2873 1, pix_op, qpix_op, 2886 ref_picture, pix_op, qpix_op,
2874 s->mv[dir][1][0], s->mv[dir][1][1], 8); 2887 s->mv[dir][1][0], s->mv[dir][1][1], 8);
2875 }else{ 2888 }else{
2876 /* top field */ 2889 /* top field */
2877 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 2890 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2878 ref_picture, s->field_select[dir][0] ? s->linesize : 0, 2891 1, 0, s->field_select[dir][0],
2879 1, pix_op, 2892 ref_picture, pix_op,
2880 s->mv[dir][0][0], s->mv[dir][0][1], 8); 2893 s->mv[dir][0][0], s->mv[dir][0][1], 8);
2881 /* bottom field */ 2894 /* bottom field */
2882 mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize, 2895 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2883 ref_picture, s->field_select[dir][1] ? s->linesize : 0, 2896 1, 1, s->field_select[dir][1],
2884 1, pix_op, 2897 ref_picture, pix_op,
2885 s->mv[dir][1][0], s->mv[dir][1][1], 8); 2898 s->mv[dir][1][0], s->mv[dir][1][1], 8);
2886 } 2899 }
2887 } else { 2900 } else {
2888 int offset; 2901 if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != B_TYPE && !s->first_field){
2889 if(s->picture_structure == s->field_select[dir][0] + 1 || s->pict_type == B_TYPE || s->first_field){ 2902 ref_picture= s->current_picture_ptr->data;
2890 offset= s->field_select[dir][0] ? s->linesize : 0;
2891 }else{
2892 ref_picture= s->current_picture.data;
2893 offset= s->field_select[dir][0] ? s->linesize : -s->linesize;
2894 } 2903 }
2895 2904
2896 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 2905 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2897 ref_picture, offset, 2906 0, 0, s->field_select[dir][0],
2898 0, pix_op, 2907 ref_picture, pix_op,
2899 s->mv[dir][0][0], s->mv[dir][0][1], 16); 2908 s->mv[dir][0][0], s->mv[dir][0][1], 16);
2900 } 2909 }
2901 break; 2910 break;
2902 case MV_TYPE_16X8:{ 2911 case MV_TYPE_16X8:{
2903 int offset;
2904 uint8_t ** ref2picture; 2912 uint8_t ** ref2picture;
2905 2913
2906 if(s->picture_structure == s->field_select[dir][0] + 1 || s->pict_type == B_TYPE || s->first_field){ 2914 if(s->picture_structure == s->field_select[dir][0] + 1 || s->pict_type == B_TYPE || s->first_field){
2907 ref2picture= ref_picture; 2915 ref2picture= ref_picture;
2908 offset= s->field_select[dir][0] ? s->linesize : 0;
2909 }else{ 2916 }else{
2910 ref2picture= s->current_picture.data; 2917 ref2picture= s->current_picture_ptr->data;
2911 offset= s->field_select[dir][0] ? s->linesize : -s->linesize;
2912 } 2918 }
2913 2919
2914 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 2920 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2915 ref2picture, offset, 2921 0, 0, s->field_select[dir][0],
2916 0, pix_op, 2922 ref2picture, pix_op,
2917 s->mv[dir][0][0], s->mv[dir][0][1], 8); 2923 s->mv[dir][0][0], s->mv[dir][0][1], 8);
2918 2924
2919 2925
2920 if(s->picture_structure == s->field_select[dir][1] + 1 || s->pict_type == B_TYPE || s->first_field){ 2926 if(s->picture_structure == s->field_select[dir][1] + 1 || s->pict_type == B_TYPE || s->first_field){
2921 ref2picture= ref_picture; 2927 ref2picture= ref_picture;
2922 offset= s->field_select[dir][1] ? s->linesize : 0;
2923 }else{ 2928 }else{
2924 ref2picture= s->current_picture.data; 2929 ref2picture= s->current_picture_ptr->data;
2925 offset= s->field_select[dir][1] ? s->linesize : -s->linesize;
2926 } 2930 }
2927 // I know it is ugly but this is the only way to fool emu_edge without rewrite mpeg_motion 2931 // I know it is ugly but this is the only way to fool emu_edge without rewrite mpeg_motion
2928 mpeg_motion(s, dest_y+16*s->linesize, dest_cb+8*s->uvlinesize, dest_cr+8*s->uvlinesize, 2932 mpeg_motion(s, dest_y+16*s->linesize, dest_cb+8*s->uvlinesize, dest_cr+8*s->uvlinesize,
2929 0, 2933 0, 0, s->field_select[dir][1],
2930 ref2picture, offset, 2934 ref2picture, pix_op,
2931 0, pix_op,
2932 s->mv[dir][1][0], s->mv[dir][1][1]+16, 8); 2935 s->mv[dir][1][0], s->mv[dir][1][1]+16, 8);
2933 } 2936 }
2934 2937
2935 break; 2938 break;
2936 case MV_TYPE_DMV: 2939 case MV_TYPE_DMV:
2937 { 2940 pix_op = s->dsp.put_pixels_tab;
2938 op_pixels_func (*dmv_pix_op)[4];
2939 int offset;
2940
2941 dmv_pix_op = s->dsp.put_pixels_tab;
2942 2941
2943 if(s->picture_structure == PICT_FRAME){ 2942 if(s->picture_structure == PICT_FRAME){
2944 //put top field from top field 2943 //put top field from top field
2945 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 2944 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2946 ref_picture, 0, 2945 1, 0, 0,
2947 1, dmv_pix_op, 2946 ref_picture, pix_op,
2948 s->mv[dir][0][0], s->mv[dir][0][1], 8); 2947 s->mv[dir][0][0], s->mv[dir][0][1], 8);
2949 //put bottom field from bottom field 2948 //put bottom field from bottom field
2950 mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize, 2949 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2951 ref_picture, s->linesize, 2950 1, 1, 1,
2952 1, dmv_pix_op, 2951 ref_picture, pix_op,
2953 s->mv[dir][0][0], s->mv[dir][0][1], 8); 2952 s->mv[dir][0][0], s->mv[dir][0][1], 8);
2954 2953
2955 dmv_pix_op = s->dsp.avg_pixels_tab; 2954 pix_op = s->dsp.avg_pixels_tab;
2956 2955
2957 //avg top field from bottom field 2956 //avg top field from bottom field
2958 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 2957 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2959 ref_picture, s->linesize, 2958 1, 0, 1,
2960 1, dmv_pix_op, 2959 ref_picture, pix_op,
2961 s->mv[dir][2][0], s->mv[dir][2][1], 8); 2960 s->mv[dir][2][0], s->mv[dir][2][1], 8);
2962 //avg bottom field from top field 2961 //avg bottom field from top field
2963 mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize, 2962 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2964 ref_picture, 0, 2963 1, 1, 0,
2965 1, dmv_pix_op, 2964 ref_picture, pix_op,
2966 s->mv[dir][3][0], s->mv[dir][3][1], 8); 2965 s->mv[dir][3][0], s->mv[dir][3][1], 8);
2967 2966
2968 }else{ 2967 }else{
2969 offset=(s->picture_structure == PICT_BOTTOM_FIELD)?
2970 s->linesize : 0;
2971
2972 //put field from the same parity 2968 //put field from the same parity
2973 //same parity is never in the same frame 2969 //same parity is never in the same frame
2974 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 2970 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2975 ref_picture,offset, 2971 0, 0, s->picture_structure == PICT_BOTTOM_FIELD,
2976 0,dmv_pix_op, 2972 ref_picture, pix_op,
2977 s->mv[dir][0][0],s->mv[dir][0][1],16); 2973 s->mv[dir][0][0],s->mv[dir][0][1],16);
2978 2974
2979 // after put we make avg of the same block 2975 // after put we make avg of the same block
2980 dmv_pix_op=s->dsp.avg_pixels_tab; 2976 pix_op=s->dsp.avg_pixels_tab;
2981 2977
2982 //opposite parity is always in the same frame if this is second field 2978 //opposite parity is always in the same frame if this is second field
2983 if(!s->first_field){ 2979 if(!s->first_field){
2984 ref_picture = s->current_picture.data; 2980 ref_picture = s->current_picture_ptr->data;
2985 //top field is one linesize from frame beginig 2981 }
2986 offset=(s->picture_structure == PICT_BOTTOM_FIELD)?
2987 -s->linesize : s->linesize;
2988 }else
2989 offset=(s->picture_structure == PICT_BOTTOM_FIELD)?
2990 0 : s->linesize;
2991 2982
2992 //avg field from the opposite parity 2983 //avg field from the opposite parity
2993 mpeg_motion(s, dest_y, dest_cb, dest_cr,0, 2984 mpeg_motion(s, dest_y, dest_cb, dest_cr,
2994 ref_picture, offset, 2985 0, 0, s->picture_structure != PICT_BOTTOM_FIELD,
2995 0,dmv_pix_op, 2986 ref_picture, pix_op,
2996 s->mv[dir][2][0],s->mv[dir][2][1],16); 2987 s->mv[dir][2][0],s->mv[dir][2][1],16);
2997 } 2988 }
2998 }
2999 break; 2989 break;
3000 default: assert(0); 2990 default: assert(0);
3001 } 2991 }
3002 } 2992 }
3003 2993