You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

901 lines
34KB

  1. /*
  2. * The simplest mpeg encoder (well, it was the simplest!)
  3. * Copyright (c) 2000,2001 Fabrice Bellard.
  4. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  5. *
  6. * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
  7. *
  8. * This file is part of FFmpeg.
  9. *
  10. * FFmpeg is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation; either
  13. * version 2.1 of the License, or (at your option) any later version.
  14. *
  15. * FFmpeg is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with FFmpeg; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. */
  24. /**
  25. * @file mpegvideo_common.h
  26. * The simplest mpeg encoder (well, it was the simplest!).
  27. */
  28. #ifndef AVCODEC_MPEGVIDEO_COMMON_H
  29. #define AVCODEC_MPEGVIDEO_COMMON_H
  30. #include "avcodec.h"
  31. #include "dsputil.h"
  32. #include "mpegvideo.h"
  33. #include "mjpegenc.h"
  34. #include "msmpeg4.h"
  35. #include "faandct.h"
  36. #include <limits.h>
  37. int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
  38. int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
  39. void denoise_dct_c(MpegEncContext *s, DCTELEM *block);
  40. /**
  41. * allocates a Picture
  42. * The pixels are allocated/set by calling get_buffer() if shared=0
  43. */
  44. int alloc_picture(MpegEncContext *s, Picture *pic, int shared);
  45. /**
  46. * sets the given MpegEncContext to common defaults (same for encoding and decoding).
  47. * the changed fields will not depend upon the prior state of the MpegEncContext.
  48. */
  49. void MPV_common_defaults(MpegEncContext *s);
  50. static inline void gmc1_motion(MpegEncContext *s,
  51. uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
  52. uint8_t **ref_picture)
  53. {
  54. uint8_t *ptr;
  55. int offset, src_x, src_y, linesize, uvlinesize;
  56. int motion_x, motion_y;
  57. int emu=0;
  58. motion_x= s->sprite_offset[0][0];
  59. motion_y= s->sprite_offset[0][1];
  60. src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1));
  61. src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1));
  62. motion_x<<=(3-s->sprite_warping_accuracy);
  63. motion_y<<=(3-s->sprite_warping_accuracy);
  64. src_x = av_clip(src_x, -16, s->width);
  65. if (src_x == s->width)
  66. motion_x =0;
  67. src_y = av_clip(src_y, -16, s->height);
  68. if (src_y == s->height)
  69. motion_y =0;
  70. linesize = s->linesize;
  71. uvlinesize = s->uvlinesize;
  72. ptr = ref_picture[0] + (src_y * linesize) + src_x;
  73. if(s->flags&CODEC_FLAG_EMU_EDGE){
  74. if( (unsigned)src_x >= s->h_edge_pos - 17
  75. || (unsigned)src_y >= s->v_edge_pos - 17){
  76. ff_emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
  77. ptr= s->edge_emu_buffer;
  78. }
  79. }
  80. if((motion_x|motion_y)&7){
  81. s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
  82. s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
  83. }else{
  84. int dxy;
  85. dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2);
  86. if (s->no_rounding){
  87. s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
  88. }else{
  89. s->dsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16);
  90. }
  91. }
  92. if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return;
  93. motion_x= s->sprite_offset[1][0];
  94. motion_y= s->sprite_offset[1][1];
  95. src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1));
  96. src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1));
  97. motion_x<<=(3-s->sprite_warping_accuracy);
  98. motion_y<<=(3-s->sprite_warping_accuracy);
  99. src_x = av_clip(src_x, -8, s->width>>1);
  100. if (src_x == s->width>>1)
  101. motion_x =0;
  102. src_y = av_clip(src_y, -8, s->height>>1);
  103. if (src_y == s->height>>1)
  104. motion_y =0;
  105. offset = (src_y * uvlinesize) + src_x;
  106. ptr = ref_picture[1] + offset;
  107. if(s->flags&CODEC_FLAG_EMU_EDGE){
  108. if( (unsigned)src_x >= (s->h_edge_pos>>1) - 9
  109. || (unsigned)src_y >= (s->v_edge_pos>>1) - 9){
  110. 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);
  111. ptr= s->edge_emu_buffer;
  112. emu=1;
  113. }
  114. }
  115. s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
  116. ptr = ref_picture[2] + offset;
  117. if(emu){
  118. 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);
  119. ptr= s->edge_emu_buffer;
  120. }
  121. s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
  122. return;
  123. }
  124. static inline void gmc_motion(MpegEncContext *s,
  125. uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
  126. uint8_t **ref_picture)
  127. {
  128. uint8_t *ptr;
  129. int linesize, uvlinesize;
  130. const int a= s->sprite_warping_accuracy;
  131. int ox, oy;
  132. linesize = s->linesize;
  133. uvlinesize = s->uvlinesize;
  134. ptr = ref_picture[0];
  135. ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16;
  136. oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16;
  137. s->dsp.gmc(dest_y, ptr, linesize, 16,
  138. ox,
  139. oy,
  140. s->sprite_delta[0][0], s->sprite_delta[0][1],
  141. s->sprite_delta[1][0], s->sprite_delta[1][1],
  142. a+1, (1<<(2*a+1)) - s->no_rounding,
  143. s->h_edge_pos, s->v_edge_pos);
  144. s->dsp.gmc(dest_y+8, ptr, linesize, 16,
  145. ox + s->sprite_delta[0][0]*8,
  146. oy + s->sprite_delta[1][0]*8,
  147. s->sprite_delta[0][0], s->sprite_delta[0][1],
  148. s->sprite_delta[1][0], s->sprite_delta[1][1],
  149. a+1, (1<<(2*a+1)) - s->no_rounding,
  150. s->h_edge_pos, s->v_edge_pos);
  151. if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return;
  152. ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8;
  153. oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8;
  154. ptr = ref_picture[1];
  155. s->dsp.gmc(dest_cb, ptr, uvlinesize, 8,
  156. ox,
  157. oy,
  158. s->sprite_delta[0][0], s->sprite_delta[0][1],
  159. s->sprite_delta[1][0], s->sprite_delta[1][1],
  160. a+1, (1<<(2*a+1)) - s->no_rounding,
  161. s->h_edge_pos>>1, s->v_edge_pos>>1);
  162. ptr = ref_picture[2];
  163. s->dsp.gmc(dest_cr, ptr, uvlinesize, 8,
  164. ox,
  165. oy,
  166. s->sprite_delta[0][0], s->sprite_delta[0][1],
  167. s->sprite_delta[1][0], s->sprite_delta[1][1],
  168. a+1, (1<<(2*a+1)) - s->no_rounding,
  169. s->h_edge_pos>>1, s->v_edge_pos>>1);
  170. }
  171. static inline int hpel_motion(MpegEncContext *s,
  172. uint8_t *dest, uint8_t *src,
  173. int field_based, int field_select,
  174. int src_x, int src_y,
  175. int width, int height, int stride,
  176. int h_edge_pos, int v_edge_pos,
  177. int w, int h, op_pixels_func *pix_op,
  178. int motion_x, int motion_y)
  179. {
  180. int dxy;
  181. int emu=0;
  182. dxy = ((motion_y & 1) << 1) | (motion_x & 1);
  183. src_x += motion_x >> 1;
  184. src_y += motion_y >> 1;
  185. /* WARNING: do no forget half pels */
  186. src_x = av_clip(src_x, -16, width); //FIXME unneeded for emu?
  187. if (src_x == width)
  188. dxy &= ~1;
  189. src_y = av_clip(src_y, -16, height);
  190. if (src_y == height)
  191. dxy &= ~2;
  192. src += src_y * stride + src_x;
  193. if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
  194. if( (unsigned)src_x > h_edge_pos - (motion_x&1) - w
  195. || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){
  196. ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based,
  197. src_x, src_y<<field_based, h_edge_pos, s->v_edge_pos);
  198. src= s->edge_emu_buffer;
  199. emu=1;
  200. }
  201. }
  202. if(field_select)
  203. src += s->linesize;
  204. pix_op[dxy](dest, src, stride, h);
  205. return emu;
  206. }
  207. static av_always_inline
  208. void mpeg_motion_internal(MpegEncContext *s,
  209. uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
  210. int field_based, int bottom_field, int field_select,
  211. uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
  212. int motion_x, int motion_y, int h, int is_mpeg12)
  213. {
  214. uint8_t *ptr_y, *ptr_cb, *ptr_cr;
  215. int dxy, uvdxy, mx, my, src_x, src_y,
  216. uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize;
  217. #if 0
  218. if(s->quarter_sample)
  219. {
  220. motion_x>>=1;
  221. motion_y>>=1;
  222. }
  223. #endif
  224. v_edge_pos = s->v_edge_pos >> field_based;
  225. linesize = s->current_picture.linesize[0] << field_based;
  226. uvlinesize = s->current_picture.linesize[1] << field_based;
  227. dxy = ((motion_y & 1) << 1) | (motion_x & 1);
  228. src_x = s->mb_x* 16 + (motion_x >> 1);
  229. src_y =(s->mb_y<<(4-field_based)) + (motion_y >> 1);
  230. if (!is_mpeg12 && s->out_format == FMT_H263) {
  231. if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){
  232. mx = (motion_x>>1)|(motion_x&1);
  233. my = motion_y >>1;
  234. uvdxy = ((my & 1) << 1) | (mx & 1);
  235. uvsrc_x = s->mb_x* 8 + (mx >> 1);
  236. uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1);
  237. }else{
  238. uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
  239. uvsrc_x = src_x>>1;
  240. uvsrc_y = src_y>>1;
  241. }
  242. }else if(!is_mpeg12 && s->out_format == FMT_H261){//even chroma mv's are full pel in H261
  243. mx = motion_x / 4;
  244. my = motion_y / 4;
  245. uvdxy = 0;
  246. uvsrc_x = s->mb_x*8 + mx;
  247. uvsrc_y = s->mb_y*8 + my;
  248. } else {
  249. if(s->chroma_y_shift){
  250. mx = motion_x / 2;
  251. my = motion_y / 2;
  252. uvdxy = ((my & 1) << 1) | (mx & 1);
  253. uvsrc_x = s->mb_x* 8 + (mx >> 1);
  254. uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1);
  255. } else {
  256. if(s->chroma_x_shift){
  257. //Chroma422
  258. mx = motion_x / 2;
  259. uvdxy = ((motion_y & 1) << 1) | (mx & 1);
  260. uvsrc_x = s->mb_x* 8 + (mx >> 1);
  261. uvsrc_y = src_y;
  262. } else {
  263. //Chroma444
  264. uvdxy = dxy;
  265. uvsrc_x = src_x;
  266. uvsrc_y = src_y;
  267. }
  268. }
  269. }
  270. ptr_y = ref_picture[0] + src_y * linesize + src_x;
  271. ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
  272. ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
  273. if( (unsigned)src_x > s->h_edge_pos - (motion_x&1) - 16
  274. || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){
  275. if(is_mpeg12 || s->codec_id == CODEC_ID_MPEG2VIDEO ||
  276. s->codec_id == CODEC_ID_MPEG1VIDEO){
  277. av_log(s->avctx,AV_LOG_DEBUG,
  278. "MPEG motion vector out of boundary\n");
  279. return ;
  280. }
  281. ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
  282. 17, 17+field_based,
  283. src_x, src_y<<field_based,
  284. s->h_edge_pos, s->v_edge_pos);
  285. ptr_y = s->edge_emu_buffer;
  286. if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
  287. uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
  288. ff_emulated_edge_mc(uvbuf ,
  289. ptr_cb, s->uvlinesize,
  290. 9, 9+field_based,
  291. uvsrc_x, uvsrc_y<<field_based,
  292. s->h_edge_pos>>1, s->v_edge_pos>>1);
  293. ff_emulated_edge_mc(uvbuf+16,
  294. ptr_cr, s->uvlinesize,
  295. 9, 9+field_based,
  296. uvsrc_x, uvsrc_y<<field_based,
  297. s->h_edge_pos>>1, s->v_edge_pos>>1);
  298. ptr_cb= uvbuf;
  299. ptr_cr= uvbuf+16;
  300. }
  301. }
  302. if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data
  303. dest_y += s->linesize;
  304. dest_cb+= s->uvlinesize;
  305. dest_cr+= s->uvlinesize;
  306. }
  307. if(field_select){
  308. ptr_y += s->linesize;
  309. ptr_cb+= s->uvlinesize;
  310. ptr_cr+= s->uvlinesize;
  311. }
  312. pix_op[0][dxy](dest_y, ptr_y, linesize, h);
  313. if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
  314. pix_op[s->chroma_x_shift][uvdxy]
  315. (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
  316. pix_op[s->chroma_x_shift][uvdxy]
  317. (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
  318. }
  319. if(!is_mpeg12 && (ENABLE_H261_ENCODER || ENABLE_H261_DECODER) &&
  320. s->out_format == FMT_H261){
  321. ff_h261_loop_filter(s);
  322. }
  323. }
  324. /* apply one mpeg motion vector to the three components */
  325. static av_always_inline
  326. void mpeg_motion(MpegEncContext *s,
  327. uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
  328. int field_based, int bottom_field, int field_select,
  329. uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
  330. int motion_x, int motion_y, int h)
  331. {
  332. #ifndef CONFIG_SMALL
  333. if(s->out_format == FMT_MPEG1)
  334. mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based,
  335. bottom_field, field_select, ref_picture, pix_op,
  336. motion_x, motion_y, h, 1);
  337. else
  338. #endif
  339. mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based,
  340. bottom_field, field_select, ref_picture, pix_op,
  341. motion_x, motion_y, h, 0);
  342. }
  343. //FIXME move to dsputil, avg variant, 16x16 version
  344. static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){
  345. int x;
  346. uint8_t * const top = src[1];
  347. uint8_t * const left = src[2];
  348. uint8_t * const mid = src[0];
  349. uint8_t * const right = src[3];
  350. uint8_t * const bottom= src[4];
  351. #define OBMC_FILTER(x, t, l, m, r, b)\
  352. dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3
  353. #define OBMC_FILTER4(x, t, l, m, r, b)\
  354. OBMC_FILTER(x , t, l, m, r, b);\
  355. OBMC_FILTER(x+1 , t, l, m, r, b);\
  356. OBMC_FILTER(x +stride, t, l, m, r, b);\
  357. OBMC_FILTER(x+1+stride, t, l, m, r, b);
  358. x=0;
  359. OBMC_FILTER (x , 2, 2, 4, 0, 0);
  360. OBMC_FILTER (x+1, 2, 1, 5, 0, 0);
  361. OBMC_FILTER4(x+2, 2, 1, 5, 0, 0);
  362. OBMC_FILTER4(x+4, 2, 0, 5, 1, 0);
  363. OBMC_FILTER (x+6, 2, 0, 5, 1, 0);
  364. OBMC_FILTER (x+7, 2, 0, 4, 2, 0);
  365. x+= stride;
  366. OBMC_FILTER (x , 1, 2, 5, 0, 0);
  367. OBMC_FILTER (x+1, 1, 2, 5, 0, 0);
  368. OBMC_FILTER (x+6, 1, 0, 5, 2, 0);
  369. OBMC_FILTER (x+7, 1, 0, 5, 2, 0);
  370. x+= stride;
  371. OBMC_FILTER4(x , 1, 2, 5, 0, 0);
  372. OBMC_FILTER4(x+2, 1, 1, 6, 0, 0);
  373. OBMC_FILTER4(x+4, 1, 0, 6, 1, 0);
  374. OBMC_FILTER4(x+6, 1, 0, 5, 2, 0);
  375. x+= 2*stride;
  376. OBMC_FILTER4(x , 0, 2, 5, 0, 1);
  377. OBMC_FILTER4(x+2, 0, 1, 6, 0, 1);
  378. OBMC_FILTER4(x+4, 0, 0, 6, 1, 1);
  379. OBMC_FILTER4(x+6, 0, 0, 5, 2, 1);
  380. x+= 2*stride;
  381. OBMC_FILTER (x , 0, 2, 5, 0, 1);
  382. OBMC_FILTER (x+1, 0, 2, 5, 0, 1);
  383. OBMC_FILTER4(x+2, 0, 1, 5, 0, 2);
  384. OBMC_FILTER4(x+4, 0, 0, 5, 1, 2);
  385. OBMC_FILTER (x+6, 0, 0, 5, 2, 1);
  386. OBMC_FILTER (x+7, 0, 0, 5, 2, 1);
  387. x+= stride;
  388. OBMC_FILTER (x , 0, 2, 4, 0, 2);
  389. OBMC_FILTER (x+1, 0, 1, 5, 0, 2);
  390. OBMC_FILTER (x+6, 0, 0, 5, 1, 2);
  391. OBMC_FILTER (x+7, 0, 0, 4, 2, 2);
  392. }
  393. /* obmc for 1 8x8 luma block */
  394. static inline void obmc_motion(MpegEncContext *s,
  395. uint8_t *dest, uint8_t *src,
  396. int src_x, int src_y,
  397. op_pixels_func *pix_op,
  398. int16_t mv[5][2]/* mid top left right bottom*/)
  399. #define MID 0
  400. {
  401. int i;
  402. uint8_t *ptr[5];
  403. assert(s->quarter_sample==0);
  404. for(i=0; i<5; i++){
  405. if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){
  406. ptr[i]= ptr[MID];
  407. }else{
  408. ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1);
  409. hpel_motion(s, ptr[i], src, 0, 0,
  410. src_x, src_y,
  411. s->width, s->height, s->linesize,
  412. s->h_edge_pos, s->v_edge_pos,
  413. 8, 8, pix_op,
  414. mv[i][0], mv[i][1]);
  415. }
  416. }
  417. put_obmc(dest, ptr, s->linesize);
  418. }
  419. static inline void qpel_motion(MpegEncContext *s,
  420. uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
  421. int field_based, int bottom_field, int field_select,
  422. uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
  423. qpel_mc_func (*qpix_op)[16],
  424. int motion_x, int motion_y, int h)
  425. {
  426. uint8_t *ptr_y, *ptr_cb, *ptr_cr;
  427. int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize;
  428. dxy = ((motion_y & 3) << 2) | (motion_x & 3);
  429. src_x = s->mb_x * 16 + (motion_x >> 2);
  430. src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
  431. v_edge_pos = s->v_edge_pos >> field_based;
  432. linesize = s->linesize << field_based;
  433. uvlinesize = s->uvlinesize << field_based;
  434. if(field_based){
  435. mx= motion_x/2;
  436. my= motion_y>>1;
  437. }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){
  438. static const int rtab[8]= {0,0,1,1,0,0,0,1};
  439. mx= (motion_x>>1) + rtab[motion_x&7];
  440. my= (motion_y>>1) + rtab[motion_y&7];
  441. }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){
  442. mx= (motion_x>>1)|(motion_x&1);
  443. my= (motion_y>>1)|(motion_y&1);
  444. }else{
  445. mx= motion_x/2;
  446. my= motion_y/2;
  447. }
  448. mx= (mx>>1)|(mx&1);
  449. my= (my>>1)|(my&1);
  450. uvdxy= (mx&1) | ((my&1)<<1);
  451. mx>>=1;
  452. my>>=1;
  453. uvsrc_x = s->mb_x * 8 + mx;
  454. uvsrc_y = s->mb_y * (8 >> field_based) + my;
  455. ptr_y = ref_picture[0] + src_y * linesize + src_x;
  456. ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
  457. ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
  458. if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16
  459. || (unsigned)src_y > v_edge_pos - (motion_y&3) - h ){
  460. ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
  461. 17, 17+field_based, src_x, src_y<<field_based,
  462. s->h_edge_pos, s->v_edge_pos);
  463. ptr_y= s->edge_emu_buffer;
  464. if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
  465. uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
  466. ff_emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
  467. 9, 9 + field_based,
  468. uvsrc_x, uvsrc_y<<field_based,
  469. s->h_edge_pos>>1, s->v_edge_pos>>1);
  470. ff_emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
  471. 9, 9 + field_based,
  472. uvsrc_x, uvsrc_y<<field_based,
  473. s->h_edge_pos>>1, s->v_edge_pos>>1);
  474. ptr_cb= uvbuf;
  475. ptr_cr= uvbuf + 16;
  476. }
  477. }
  478. if(!field_based)
  479. qpix_op[0][dxy](dest_y, ptr_y, linesize);
  480. else{
  481. if(bottom_field){
  482. dest_y += s->linesize;
  483. dest_cb+= s->uvlinesize;
  484. dest_cr+= s->uvlinesize;
  485. }
  486. if(field_select){
  487. ptr_y += s->linesize;
  488. ptr_cb += s->uvlinesize;
  489. ptr_cr += s->uvlinesize;
  490. }
  491. //damn interlaced mode
  492. //FIXME boundary mirroring is not exactly correct here
  493. qpix_op[1][dxy](dest_y , ptr_y , linesize);
  494. qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize);
  495. }
  496. if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
  497. pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1);
  498. pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1);
  499. }
  500. }
  501. /**
  502. * h263 chroma 4mv motion compensation.
  503. */
  504. static inline void chroma_4mv_motion(MpegEncContext *s,
  505. uint8_t *dest_cb, uint8_t *dest_cr,
  506. uint8_t **ref_picture,
  507. op_pixels_func *pix_op,
  508. int mx, int my){
  509. int dxy, emu=0, src_x, src_y, offset;
  510. uint8_t *ptr;
  511. /* In case of 8X8, we construct a single chroma motion vector
  512. with a special rounding */
  513. mx= ff_h263_round_chroma(mx);
  514. my= ff_h263_round_chroma(my);
  515. dxy = ((my & 1) << 1) | (mx & 1);
  516. mx >>= 1;
  517. my >>= 1;
  518. src_x = s->mb_x * 8 + mx;
  519. src_y = s->mb_y * 8 + my;
  520. src_x = av_clip(src_x, -8, s->width/2);
  521. if (src_x == s->width/2)
  522. dxy &= ~1;
  523. src_y = av_clip(src_y, -8, s->height/2);
  524. if (src_y == s->height/2)
  525. dxy &= ~2;
  526. offset = (src_y * (s->uvlinesize)) + src_x;
  527. ptr = ref_picture[1] + offset;
  528. if(s->flags&CODEC_FLAG_EMU_EDGE){
  529. if( (unsigned)src_x > (s->h_edge_pos>>1) - (dxy &1) - 8
  530. || (unsigned)src_y > (s->v_edge_pos>>1) - (dxy>>1) - 8){
  531. ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
  532. 9, 9, src_x, src_y,
  533. s->h_edge_pos>>1, s->v_edge_pos>>1);
  534. ptr= s->edge_emu_buffer;
  535. emu=1;
  536. }
  537. }
  538. pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
  539. ptr = ref_picture[2] + offset;
  540. if(emu){
  541. ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
  542. 9, 9, src_x, src_y,
  543. s->h_edge_pos>>1, s->v_edge_pos>>1);
  544. ptr= s->edge_emu_buffer;
  545. }
  546. pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
  547. }
  548. static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){
  549. /* fetch pixels for estimated mv 4 macroblocks ahead
  550. * optimized for 64byte cache lines */
  551. const int shift = s->quarter_sample ? 2 : 1;
  552. const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8;
  553. const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y;
  554. int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64;
  555. s->dsp.prefetch(pix[0]+off, s->linesize, 4);
  556. off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64;
  557. s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
  558. }
  559. /**
  560. * motion compensation of a single macroblock
  561. * @param s context
  562. * @param dest_y luma destination pointer
  563. * @param dest_cb chroma cb/u destination pointer
  564. * @param dest_cr chroma cr/v destination pointer
  565. * @param dir direction (0->forward, 1->backward)
  566. * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
  567. * @param pic_op halfpel motion compensation function (average or put normally)
  568. * @param pic_op qpel motion compensation function (average or put normally)
  569. * the motion vectors are taken from s->mv and the MV type from s->mv_type
  570. */
  571. static av_always_inline void MPV_motion_internal(MpegEncContext *s,
  572. uint8_t *dest_y, uint8_t *dest_cb,
  573. uint8_t *dest_cr, int dir,
  574. uint8_t **ref_picture,
  575. op_pixels_func (*pix_op)[4],
  576. qpel_mc_func (*qpix_op)[16], int is_mpeg12)
  577. {
  578. int dxy, mx, my, src_x, src_y, motion_x, motion_y;
  579. int mb_x, mb_y, i;
  580. uint8_t *ptr, *dest;
  581. mb_x = s->mb_x;
  582. mb_y = s->mb_y;
  583. prefetch_motion(s, ref_picture, dir);
  584. if(!is_mpeg12 && s->obmc && s->pict_type != FF_B_TYPE){
  585. int16_t mv_cache[4][4][2];
  586. const int xy= s->mb_x + s->mb_y*s->mb_stride;
  587. const int mot_stride= s->b8_stride;
  588. const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
  589. assert(!s->mb_skipped);
  590. memcpy(mv_cache[1][1], s->current_picture.motion_val[0][mot_xy ], sizeof(int16_t)*4);
  591. memcpy(mv_cache[2][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4);
  592. memcpy(mv_cache[3][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4);
  593. if(mb_y==0 || IS_INTRA(s->current_picture.mb_type[xy-s->mb_stride])){
  594. memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4);
  595. }else{
  596. memcpy(mv_cache[0][1], s->current_picture.motion_val[0][mot_xy-mot_stride], sizeof(int16_t)*4);
  597. }
  598. if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){
  599. *(int32_t*)mv_cache[1][0]= *(int32_t*)mv_cache[1][1];
  600. *(int32_t*)mv_cache[2][0]= *(int32_t*)mv_cache[2][1];
  601. }else{
  602. *(int32_t*)mv_cache[1][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1];
  603. *(int32_t*)mv_cache[2][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1+mot_stride];
  604. }
  605. if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){
  606. *(int32_t*)mv_cache[1][3]= *(int32_t*)mv_cache[1][2];
  607. *(int32_t*)mv_cache[2][3]= *(int32_t*)mv_cache[2][2];
  608. }else{
  609. *(int32_t*)mv_cache[1][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2];
  610. *(int32_t*)mv_cache[2][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2+mot_stride];
  611. }
  612. mx = 0;
  613. my = 0;
  614. for(i=0;i<4;i++) {
  615. const int x= (i&1)+1;
  616. const int y= (i>>1)+1;
  617. int16_t mv[5][2]= {
  618. {mv_cache[y][x ][0], mv_cache[y][x ][1]},
  619. {mv_cache[y-1][x][0], mv_cache[y-1][x][1]},
  620. {mv_cache[y][x-1][0], mv_cache[y][x-1][1]},
  621. {mv_cache[y][x+1][0], mv_cache[y][x+1][1]},
  622. {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}};
  623. //FIXME cleanup
  624. obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
  625. ref_picture[0],
  626. mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
  627. pix_op[1],
  628. mv);
  629. mx += mv[0][0];
  630. my += mv[0][1];
  631. }
  632. if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY))
  633. chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
  634. return;
  635. }
  636. switch(s->mv_type) {
  637. case MV_TYPE_16X16:
  638. if(s->mcsel){
  639. if(s->real_sprite_warping_points==1){
  640. gmc1_motion(s, dest_y, dest_cb, dest_cr,
  641. ref_picture);
  642. }else{
  643. gmc_motion(s, dest_y, dest_cb, dest_cr,
  644. ref_picture);
  645. }
  646. }else if(!is_mpeg12 && s->quarter_sample){
  647. qpel_motion(s, dest_y, dest_cb, dest_cr,
  648. 0, 0, 0,
  649. ref_picture, pix_op, qpix_op,
  650. s->mv[dir][0][0], s->mv[dir][0][1], 16);
  651. }else if(!is_mpeg12 && ENABLE_WMV2 && s->mspel){
  652. ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
  653. ref_picture, pix_op,
  654. s->mv[dir][0][0], s->mv[dir][0][1], 16);
  655. }else
  656. {
  657. mpeg_motion(s, dest_y, dest_cb, dest_cr,
  658. 0, 0, 0,
  659. ref_picture, pix_op,
  660. s->mv[dir][0][0], s->mv[dir][0][1], 16);
  661. }
  662. break;
  663. case MV_TYPE_8X8:
  664. if (!is_mpeg12) {
  665. mx = 0;
  666. my = 0;
  667. if(s->quarter_sample){
  668. for(i=0;i<4;i++) {
  669. motion_x = s->mv[dir][i][0];
  670. motion_y = s->mv[dir][i][1];
  671. dxy = ((motion_y & 3) << 2) | (motion_x & 3);
  672. src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
  673. src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8;
  674. /* WARNING: do no forget half pels */
  675. src_x = av_clip(src_x, -16, s->width);
  676. if (src_x == s->width)
  677. dxy &= ~3;
  678. src_y = av_clip(src_y, -16, s->height);
  679. if (src_y == s->height)
  680. dxy &= ~12;
  681. ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
  682. if(s->flags&CODEC_FLAG_EMU_EDGE){
  683. if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 8
  684. || (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 8 ){
  685. ff_emulated_edge_mc(s->edge_emu_buffer, ptr,
  686. s->linesize, 9, 9,
  687. src_x, src_y,
  688. s->h_edge_pos, s->v_edge_pos);
  689. ptr= s->edge_emu_buffer;
  690. }
  691. }
  692. dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
  693. qpix_op[1][dxy](dest, ptr, s->linesize);
  694. mx += s->mv[dir][i][0]/2;
  695. my += s->mv[dir][i][1]/2;
  696. }
  697. }else{
  698. for(i=0;i<4;i++) {
  699. hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
  700. ref_picture[0], 0, 0,
  701. mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
  702. s->width, s->height, s->linesize,
  703. s->h_edge_pos, s->v_edge_pos,
  704. 8, 8, pix_op[1],
  705. s->mv[dir][i][0], s->mv[dir][i][1]);
  706. mx += s->mv[dir][i][0];
  707. my += s->mv[dir][i][1];
  708. }
  709. }
  710. if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY))
  711. chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
  712. }
  713. break;
  714. case MV_TYPE_FIELD:
  715. if (s->picture_structure == PICT_FRAME) {
  716. if(!is_mpeg12 && s->quarter_sample){
  717. for(i=0; i<2; i++){
  718. qpel_motion(s, dest_y, dest_cb, dest_cr,
  719. 1, i, s->field_select[dir][i],
  720. ref_picture, pix_op, qpix_op,
  721. s->mv[dir][i][0], s->mv[dir][i][1], 8);
  722. }
  723. }else{
  724. /* top field */
  725. mpeg_motion(s, dest_y, dest_cb, dest_cr,
  726. 1, 0, s->field_select[dir][0],
  727. ref_picture, pix_op,
  728. s->mv[dir][0][0], s->mv[dir][0][1], 8);
  729. /* bottom field */
  730. mpeg_motion(s, dest_y, dest_cb, dest_cr,
  731. 1, 1, s->field_select[dir][1],
  732. ref_picture, pix_op,
  733. s->mv[dir][1][0], s->mv[dir][1][1], 8);
  734. }
  735. } else {
  736. if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){
  737. ref_picture= s->current_picture_ptr->data;
  738. }
  739. mpeg_motion(s, dest_y, dest_cb, dest_cr,
  740. 0, 0, s->field_select[dir][0],
  741. ref_picture, pix_op,
  742. s->mv[dir][0][0], s->mv[dir][0][1], 16);
  743. }
  744. break;
  745. case MV_TYPE_16X8:
  746. for(i=0; i<2; i++){
  747. uint8_t ** ref2picture;
  748. if(s->picture_structure == s->field_select[dir][i] + 1
  749. || s->pict_type == FF_B_TYPE || s->first_field){
  750. ref2picture= ref_picture;
  751. }else{
  752. ref2picture= s->current_picture_ptr->data;
  753. }
  754. mpeg_motion(s, dest_y, dest_cb, dest_cr,
  755. 0, 0, s->field_select[dir][i],
  756. ref2picture, pix_op,
  757. s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8);
  758. dest_y += 16*s->linesize;
  759. dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize;
  760. dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize;
  761. }
  762. break;
  763. case MV_TYPE_DMV:
  764. if(s->picture_structure == PICT_FRAME){
  765. for(i=0; i<2; i++){
  766. int j;
  767. for(j=0; j<2; j++){
  768. mpeg_motion(s, dest_y, dest_cb, dest_cr,
  769. 1, j, j^i,
  770. ref_picture, pix_op,
  771. s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8);
  772. }
  773. pix_op = s->dsp.avg_pixels_tab;
  774. }
  775. }else{
  776. for(i=0; i<2; i++){
  777. mpeg_motion(s, dest_y, dest_cb, dest_cr,
  778. 0, 0, s->picture_structure != i+1,
  779. ref_picture, pix_op,
  780. s->mv[dir][2*i][0],s->mv[dir][2*i][1],16);
  781. // after put we make avg of the same block
  782. pix_op=s->dsp.avg_pixels_tab;
  783. //opposite parity is always in the same frame if this is second field
  784. if(!s->first_field){
  785. ref_picture = s->current_picture_ptr->data;
  786. }
  787. }
  788. }
  789. break;
  790. default: assert(0);
  791. }
  792. }
  793. static inline void MPV_motion(MpegEncContext *s,
  794. uint8_t *dest_y, uint8_t *dest_cb,
  795. uint8_t *dest_cr, int dir,
  796. uint8_t **ref_picture,
  797. op_pixels_func (*pix_op)[4],
  798. qpel_mc_func (*qpix_op)[16])
  799. {
  800. #ifndef CONFIG_SMALL
  801. if(s->out_format == FMT_MPEG1)
  802. MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
  803. ref_picture, pix_op, qpix_op, 1);
  804. else
  805. #endif
  806. MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
  807. ref_picture, pix_op, qpix_op, 0);
  808. }
  809. #endif /* AVCODEC_MPEGVIDEO_COMMON_H */