Mercurial > libavcodec.hg
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 |