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.

1131 lines
50KB

  1. /*
  2. * VC-1 and WMV3 decoder
  3. * Copyright (c) 2011 Mashiat Sarker Shakkhar
  4. * Copyright (c) 2006-2007 Konstantin Shishkov
  5. * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
  6. *
  7. * This file is part of FFmpeg.
  8. *
  9. * FFmpeg is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * FFmpeg is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with FFmpeg; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. /**
  24. * @file
  25. * VC-1 and WMV3 block decoding routines
  26. */
  27. #include "avcodec.h"
  28. #include "h264chroma.h"
  29. #include "mathops.h"
  30. #include "mpegvideo.h"
  31. #include "vc1.h"
  32. static av_always_inline void vc1_scale_luma(uint8_t *srcY,
  33. int k, int linesize)
  34. {
  35. int i, j;
  36. for (j = 0; j < k; j++) {
  37. for (i = 0; i < k; i++)
  38. srcY[i] = ((srcY[i] - 128) >> 1) + 128;
  39. srcY += linesize;
  40. }
  41. }
  42. static av_always_inline void vc1_scale_chroma(uint8_t *srcU, uint8_t *srcV,
  43. int k, int uvlinesize)
  44. {
  45. int i, j;
  46. for (j = 0; j < k; j++) {
  47. for (i = 0; i < k; i++) {
  48. srcU[i] = ((srcU[i] - 128) >> 1) + 128;
  49. srcV[i] = ((srcV[i] - 128) >> 1) + 128;
  50. }
  51. srcU += uvlinesize;
  52. srcV += uvlinesize;
  53. }
  54. }
  55. static av_always_inline void vc1_lut_scale_luma(uint8_t *srcY,
  56. uint8_t *lut1, uint8_t *lut2,
  57. int k, int linesize)
  58. {
  59. int i, j;
  60. for (j = 0; j < k; j += 2) {
  61. for (i = 0; i < k; i++)
  62. srcY[i] = lut1[srcY[i]];
  63. srcY += linesize;
  64. if (j + 1 == k)
  65. break;
  66. for (i = 0; i < k; i++)
  67. srcY[i] = lut2[srcY[i]];
  68. srcY += linesize;
  69. }
  70. }
  71. static av_always_inline void vc1_lut_scale_chroma(uint8_t *srcU, uint8_t *srcV,
  72. uint8_t *lut1, uint8_t *lut2,
  73. int k, int uvlinesize)
  74. {
  75. int i, j;
  76. for (j = 0; j < k; j += 2) {
  77. for (i = 0; i < k; i++) {
  78. srcU[i] = lut1[srcU[i]];
  79. srcV[i] = lut1[srcV[i]];
  80. }
  81. srcU += uvlinesize;
  82. srcV += uvlinesize;
  83. if (j + 1 == k)
  84. break;
  85. for (i = 0; i < k; i++) {
  86. srcU[i] = lut2[srcU[i]];
  87. srcV[i] = lut2[srcV[i]];
  88. }
  89. srcU += uvlinesize;
  90. srcV += uvlinesize;
  91. }
  92. }
  93. static const uint8_t popcount4[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
  94. static av_always_inline int get_luma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty)
  95. {
  96. MpegEncContext *s = &v->s;
  97. int idx = v->mv_f[dir][s->block_index[0] + v->blocks_off] |
  98. (v->mv_f[dir][s->block_index[1] + v->blocks_off] << 1) |
  99. (v->mv_f[dir][s->block_index[2] + v->blocks_off] << 2) |
  100. (v->mv_f[dir][s->block_index[3] + v->blocks_off] << 3);
  101. static const uint8_t index2[16] = { 0, 0, 0, 0x23, 0, 0x13, 0x03, 0, 0, 0x12, 0x02, 0, 0x01, 0, 0, 0 };
  102. int opp_count = popcount4[idx];
  103. switch (opp_count) {
  104. case 0:
  105. case 4:
  106. *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
  107. *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
  108. break;
  109. case 1:
  110. *tx = mid_pred(s->mv[dir][idx < 2][0], s->mv[dir][1 + (idx < 4)][0], s->mv[dir][2 + (idx < 8)][0]);
  111. *ty = mid_pred(s->mv[dir][idx < 2][1], s->mv[dir][1 + (idx < 4)][1], s->mv[dir][2 + (idx < 8)][1]);
  112. break;
  113. case 3:
  114. *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
  115. *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
  116. break;
  117. case 2:
  118. *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
  119. *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
  120. break;
  121. }
  122. return opp_count;
  123. }
  124. static av_always_inline int get_chroma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty)
  125. {
  126. MpegEncContext *s = &v->s;
  127. int idx = !v->mb_type[0][s->block_index[0]] |
  128. (!v->mb_type[0][s->block_index[1]] << 1) |
  129. (!v->mb_type[0][s->block_index[2]] << 2) |
  130. (!v->mb_type[0][s->block_index[3]] << 3);
  131. static const uint8_t index2[16] = { 0, 0, 0, 0x01, 0, 0x02, 0x12, 0, 0, 0x03, 0x13, 0, 0x23, 0, 0, 0 };
  132. int valid_count = popcount4[idx];
  133. switch (valid_count) {
  134. case 4:
  135. *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
  136. *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
  137. break;
  138. case 3:
  139. *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
  140. *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
  141. break;
  142. case 2:
  143. *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
  144. *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
  145. break;
  146. default:
  147. return 0;
  148. }
  149. return valid_count;
  150. }
  151. /** Do motion compensation over 1 macroblock
  152. * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
  153. */
  154. void ff_vc1_mc_1mv(VC1Context *v, int dir)
  155. {
  156. MpegEncContext *s = &v->s;
  157. H264ChromaContext *h264chroma = &v->h264chroma;
  158. uint8_t *srcY, *srcU, *srcV;
  159. int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
  160. int v_edge_pos = s->v_edge_pos >> v->field_mode;
  161. int i;
  162. uint8_t (*luty)[256], (*lutuv)[256];
  163. int use_ic;
  164. if ((!v->field_mode ||
  165. (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
  166. !v->s.last_picture.f->data[0])
  167. return;
  168. mx = s->mv[dir][0][0];
  169. my = s->mv[dir][0][1];
  170. // store motion vectors for further use in B-frames
  171. if (s->pict_type == AV_PICTURE_TYPE_P) {
  172. for (i = 0; i < 4; i++) {
  173. s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
  174. s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
  175. }
  176. }
  177. uvmx = (mx + ((mx & 3) == 3)) >> 1;
  178. uvmy = (my + ((my & 3) == 3)) >> 1;
  179. v->luma_mv[s->mb_x][0] = uvmx;
  180. v->luma_mv[s->mb_x][1] = uvmy;
  181. if (v->field_mode &&
  182. v->cur_field_type != v->ref_field_type[dir]) {
  183. my = my - 2 + 4 * v->cur_field_type;
  184. uvmy = uvmy - 2 + 4 * v->cur_field_type;
  185. }
  186. // fastuvmc shall be ignored for interlaced frame picture
  187. if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
  188. uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
  189. uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
  190. }
  191. if (!dir) {
  192. if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
  193. srcY = s->current_picture.f->data[0];
  194. srcU = s->current_picture.f->data[1];
  195. srcV = s->current_picture.f->data[2];
  196. luty = v->curr_luty;
  197. lutuv = v->curr_lutuv;
  198. use_ic = *v->curr_use_ic;
  199. } else {
  200. srcY = s->last_picture.f->data[0];
  201. srcU = s->last_picture.f->data[1];
  202. srcV = s->last_picture.f->data[2];
  203. luty = v->last_luty;
  204. lutuv = v->last_lutuv;
  205. use_ic = v->last_use_ic;
  206. }
  207. } else {
  208. srcY = s->next_picture.f->data[0];
  209. srcU = s->next_picture.f->data[1];
  210. srcV = s->next_picture.f->data[2];
  211. luty = v->next_luty;
  212. lutuv = v->next_lutuv;
  213. use_ic = v->next_use_ic;
  214. }
  215. if (!srcY || !srcU) {
  216. av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
  217. return;
  218. }
  219. src_x = s->mb_x * 16 + (mx >> 2);
  220. src_y = s->mb_y * 16 + (my >> 2);
  221. uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
  222. uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
  223. if (v->profile != PROFILE_ADVANCED) {
  224. src_x = av_clip( src_x, -16, s->mb_width * 16);
  225. src_y = av_clip( src_y, -16, s->mb_height * 16);
  226. uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
  227. uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
  228. } else {
  229. src_x = av_clip( src_x, -17, s->avctx->coded_width);
  230. uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
  231. if (v->fcm == ILACE_FRAME) {
  232. src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
  233. uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
  234. } else {
  235. src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
  236. uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
  237. }
  238. }
  239. srcY += src_y * s->linesize + src_x;
  240. srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
  241. srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
  242. if (v->field_mode && v->ref_field_type[dir]) {
  243. srcY += s->current_picture_ptr->f->linesize[0];
  244. srcU += s->current_picture_ptr->f->linesize[1];
  245. srcV += s->current_picture_ptr->f->linesize[2];
  246. }
  247. /* for grayscale we should not try to read from unknown area */
  248. if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) {
  249. srcU = s->sc.edge_emu_buffer + 18 * s->linesize;
  250. srcV = s->sc.edge_emu_buffer + 18 * s->linesize;
  251. }
  252. if (v->rangeredfrm || use_ic
  253. || s->h_edge_pos < 22 || v_edge_pos < 22
  254. || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
  255. || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 3) {
  256. uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
  257. uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
  258. const int k = 17 + s->mspel * 2;
  259. srcY -= s->mspel * (1 + s->linesize);
  260. if (v->fcm == ILACE_FRAME) {
  261. if (src_y - s->mspel & 1) {
  262. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
  263. srcY,
  264. 2 * s->linesize,
  265. 2 * s->linesize,
  266. k,
  267. k + 1 >> 1,
  268. src_x - s->mspel,
  269. src_y - s->mspel >> 1,
  270. s->h_edge_pos,
  271. v_edge_pos + 1 >> 1);
  272. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize,
  273. srcY + s->linesize,
  274. 2 * s->linesize,
  275. 2 * s->linesize,
  276. k,
  277. k >> 1,
  278. src_x - s->mspel,
  279. src_y - s->mspel + 1 >> 1,
  280. s->h_edge_pos,
  281. v_edge_pos >> 1);
  282. } else {
  283. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
  284. srcY,
  285. 2 * s->linesize,
  286. 2 * s->linesize,
  287. k,
  288. k + 1 >> 1,
  289. src_x - s->mspel,
  290. src_y - s->mspel >> 1,
  291. s->h_edge_pos,
  292. v_edge_pos >> 1);
  293. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize,
  294. srcY + s->linesize,
  295. 2 * s->linesize,
  296. 2 * s->linesize,
  297. k,
  298. k >> 1,
  299. src_x - s->mspel,
  300. src_y - s->mspel + 1 >> 1,
  301. s->h_edge_pos,
  302. v_edge_pos + 1 >> 1);
  303. }
  304. } else
  305. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
  306. s->linesize, s->linesize,
  307. k, k,
  308. src_x - s->mspel, src_y - s->mspel,
  309. s->h_edge_pos, v_edge_pos);
  310. srcY = s->sc.edge_emu_buffer;
  311. if (v->fcm == ILACE_FRAME) {
  312. if (uvsrc_y & 1) {
  313. s->vdsp.emulated_edge_mc(ubuf, srcU,
  314. 2 * s->uvlinesize, 2 * s->uvlinesize,
  315. 8 + 1, 5,
  316. uvsrc_x, uvsrc_y >> 1,
  317. s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
  318. s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize,
  319. 2 * s->uvlinesize, 2 * s->uvlinesize,
  320. 8 + 1, 4,
  321. uvsrc_x, uvsrc_y + 1 >> 1,
  322. s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
  323. s->vdsp.emulated_edge_mc(vbuf, srcV,
  324. 2 * s->uvlinesize, 2 * s->uvlinesize,
  325. 8 + 1, 5,
  326. uvsrc_x, uvsrc_y >> 1,
  327. s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
  328. s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize,
  329. 2 * s->uvlinesize, 2 * s->uvlinesize,
  330. 8 + 1, 4,
  331. uvsrc_x, uvsrc_y + 1 >> 1,
  332. s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
  333. } else {
  334. s->vdsp.emulated_edge_mc(ubuf, srcU,
  335. 2 * s->uvlinesize, 2 * s->uvlinesize,
  336. 8 + 1, 5,
  337. uvsrc_x, uvsrc_y >> 1,
  338. s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
  339. s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize,
  340. 2 * s->uvlinesize, 2 * s->uvlinesize,
  341. 8 + 1, 4,
  342. uvsrc_x, uvsrc_y + 1 >> 1,
  343. s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
  344. s->vdsp.emulated_edge_mc(vbuf, srcV,
  345. 2 * s->uvlinesize, 2 * s->uvlinesize,
  346. 8 + 1, 5,
  347. uvsrc_x, uvsrc_y >> 1,
  348. s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
  349. s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize,
  350. 2 * s->uvlinesize, 2 * s->uvlinesize,
  351. 8 + 1, 4,
  352. uvsrc_x, uvsrc_y + 1 >> 1,
  353. s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
  354. }
  355. } else {
  356. s->vdsp.emulated_edge_mc(ubuf, srcU,
  357. s->uvlinesize, s->uvlinesize,
  358. 8 + 1, 8 + 1,
  359. uvsrc_x, uvsrc_y,
  360. s->h_edge_pos >> 1, v_edge_pos >> 1);
  361. s->vdsp.emulated_edge_mc(vbuf, srcV,
  362. s->uvlinesize, s->uvlinesize,
  363. 8 + 1, 8 + 1,
  364. uvsrc_x, uvsrc_y,
  365. s->h_edge_pos >> 1, v_edge_pos >> 1);
  366. }
  367. srcU = ubuf;
  368. srcV = vbuf;
  369. /* if we deal with range reduction we need to scale source blocks */
  370. if (v->rangeredfrm) {
  371. vc1_scale_luma(srcY, k, s->linesize);
  372. vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
  373. }
  374. /* if we deal with intensity compensation we need to scale source blocks */
  375. if (use_ic) {
  376. vc1_lut_scale_luma(srcY,
  377. luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)],
  378. luty[v->field_mode ? v->ref_field_type[dir] : ((1 + src_y - s->mspel) & 1)],
  379. k, s->linesize);
  380. vc1_lut_scale_chroma(srcU, srcV,
  381. lutuv[v->field_mode ? v->ref_field_type[dir] : ((0 + uvsrc_y) & 1)],
  382. lutuv[v->field_mode ? v->ref_field_type[dir] : ((1 + uvsrc_y) & 1)],
  383. 9, s->uvlinesize);
  384. }
  385. srcY += s->mspel * (1 + s->linesize);
  386. }
  387. if (s->mspel) {
  388. dxy = ((my & 3) << 2) | (mx & 3);
  389. v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
  390. } else { // hpel mc - always used for luma
  391. dxy = (my & 2) | ((mx & 2) >> 1);
  392. if (!v->rnd)
  393. s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
  394. else
  395. s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
  396. }
  397. if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
  398. return;
  399. /* Chroma MC always uses qpel bilinear */
  400. uvmx = (uvmx & 3) << 1;
  401. uvmy = (uvmy & 3) << 1;
  402. if (!v->rnd) {
  403. h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  404. h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  405. } else {
  406. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  407. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  408. }
  409. if (v->field_mode) {
  410. v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir];
  411. v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir];
  412. }
  413. }
  414. /** Do motion compensation for 4-MV macroblock - luminance block
  415. */
  416. void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
  417. {
  418. MpegEncContext *s = &v->s;
  419. uint8_t *srcY;
  420. int dxy, mx, my, src_x, src_y;
  421. int off;
  422. int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
  423. int v_edge_pos = s->v_edge_pos >> v->field_mode;
  424. uint8_t (*luty)[256];
  425. int use_ic;
  426. if ((!v->field_mode ||
  427. (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
  428. !v->s.last_picture.f->data[0])
  429. return;
  430. mx = s->mv[dir][n][0];
  431. my = s->mv[dir][n][1];
  432. if (!dir) {
  433. if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
  434. srcY = s->current_picture.f->data[0];
  435. luty = v->curr_luty;
  436. use_ic = *v->curr_use_ic;
  437. } else {
  438. srcY = s->last_picture.f->data[0];
  439. luty = v->last_luty;
  440. use_ic = v->last_use_ic;
  441. }
  442. } else {
  443. srcY = s->next_picture.f->data[0];
  444. luty = v->next_luty;
  445. use_ic = v->next_use_ic;
  446. }
  447. if (!srcY) {
  448. av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
  449. return;
  450. }
  451. if (v->field_mode) {
  452. if (v->cur_field_type != v->ref_field_type[dir])
  453. my = my - 2 + 4 * v->cur_field_type;
  454. }
  455. if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
  456. int opp_count = get_luma_mv(v, 0,
  457. &s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
  458. &s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1]);
  459. int k, f = opp_count > 2;
  460. for (k = 0; k < 4; k++)
  461. v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
  462. }
  463. if (v->fcm == ILACE_FRAME) { // not sure if needed for other types of picture
  464. int qx, qy;
  465. int width = s->avctx->coded_width;
  466. int height = s->avctx->coded_height >> 1;
  467. if (s->pict_type == AV_PICTURE_TYPE_P) {
  468. s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
  469. s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
  470. }
  471. qx = (s->mb_x * 16) + (mx >> 2);
  472. qy = (s->mb_y * 8) + (my >> 3);
  473. if (qx < -17)
  474. mx -= 4 * (qx + 17);
  475. else if (qx > width)
  476. mx -= 4 * (qx - width);
  477. if (qy < -18)
  478. my -= 8 * (qy + 18);
  479. else if (qy > height + 1)
  480. my -= 8 * (qy - height - 1);
  481. }
  482. if ((v->fcm == ILACE_FRAME) && fieldmv)
  483. off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
  484. else
  485. off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
  486. src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
  487. if (!fieldmv)
  488. src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
  489. else
  490. src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
  491. if (v->profile != PROFILE_ADVANCED) {
  492. src_x = av_clip(src_x, -16, s->mb_width * 16);
  493. src_y = av_clip(src_y, -16, s->mb_height * 16);
  494. } else {
  495. src_x = av_clip(src_x, -17, s->avctx->coded_width);
  496. if (v->fcm == ILACE_FRAME)
  497. src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
  498. else
  499. src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
  500. }
  501. srcY += src_y * s->linesize + src_x;
  502. if (v->field_mode && v->ref_field_type[dir])
  503. srcY += s->current_picture_ptr->f->linesize[0];
  504. if (v->rangeredfrm || use_ic
  505. || s->h_edge_pos < 13 || v_edge_pos < 23
  506. || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
  507. || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
  508. const int k = 9 + s->mspel * 2;
  509. srcY -= s->mspel * (1 + (s->linesize << fieldmv));
  510. /* check emulate edge stride and offset */
  511. if (v->fcm == ILACE_FRAME) {
  512. if (src_y - (s->mspel << fieldmv) & 1) {
  513. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
  514. 2 * s->linesize, 2 * s->linesize,
  515. k, (k << fieldmv) + 1 >> 1,
  516. src_x - s->mspel, src_y - (s->mspel << fieldmv) >> 1,
  517. s->h_edge_pos, v_edge_pos + 1 >> 1);
  518. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, srcY + s->linesize,
  519. 2 * s->linesize, 2 * s->linesize,
  520. k, (k << fieldmv) >> 1,
  521. src_x - s->mspel, src_y - (s->mspel << fieldmv) + 1 >> 1,
  522. s->h_edge_pos, v_edge_pos >> 1);
  523. } else {
  524. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
  525. 2 * s->linesize, 2 * s->linesize,
  526. k, (k << fieldmv) + 1 >> 1,
  527. src_x - s->mspel, src_y - (s->mspel << fieldmv) >> 1,
  528. s->h_edge_pos, v_edge_pos >> 1);
  529. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, srcY + s->linesize,
  530. 2 * s->linesize, 2 * s->linesize,
  531. k, (k << fieldmv) >> 1,
  532. src_x - s->mspel, src_y - (s->mspel << fieldmv) + 1 >> 1,
  533. s->h_edge_pos, v_edge_pos + 1 >> 1);
  534. }
  535. } else
  536. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
  537. s->linesize, s->linesize,
  538. k, k,
  539. src_x - s->mspel, src_y - s->mspel,
  540. s->h_edge_pos, v_edge_pos);
  541. srcY = s->sc.edge_emu_buffer;
  542. /* if we deal with range reduction we need to scale source blocks */
  543. if (v->rangeredfrm) {
  544. vc1_scale_luma(srcY, k, s->linesize << fieldmv);
  545. }
  546. /* if we deal with intensity compensation we need to scale source blocks */
  547. if (use_ic) {
  548. vc1_lut_scale_luma(srcY,
  549. luty[v->field_mode ? v->ref_field_type[dir] : (((0<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
  550. luty[v->field_mode ? v->ref_field_type[dir] : (((1<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
  551. k, s->linesize << fieldmv);
  552. }
  553. srcY += s->mspel * (1 + (s->linesize << fieldmv));
  554. }
  555. if (s->mspel) {
  556. dxy = ((my & 3) << 2) | (mx & 3);
  557. if (avg)
  558. v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
  559. else
  560. v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
  561. } else { // hpel mc - always used for luma
  562. dxy = (my & 2) | ((mx & 2) >> 1);
  563. if (!v->rnd)
  564. s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
  565. else
  566. s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
  567. }
  568. }
  569. /** Do motion compensation for 4-MV macroblock - both chroma blocks
  570. */
  571. void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir)
  572. {
  573. MpegEncContext *s = &v->s;
  574. H264ChromaContext *h264chroma = &v->h264chroma;
  575. uint8_t *srcU, *srcV;
  576. int uvmx, uvmy, uvsrc_x, uvsrc_y;
  577. int16_t tx, ty;
  578. int chroma_ref_type;
  579. int v_edge_pos = s->v_edge_pos >> v->field_mode;
  580. uint8_t (*lutuv)[256];
  581. int use_ic;
  582. if (!v->field_mode && !v->s.last_picture.f->data[0])
  583. return;
  584. if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
  585. return;
  586. /* calculate chroma MV vector from four luma MVs */
  587. if (!v->field_mode || !v->numref) {
  588. int valid_count = get_chroma_mv(v, dir, &tx, &ty);
  589. if (!valid_count) {
  590. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
  591. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
  592. v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
  593. return; //no need to do MC for intra blocks
  594. }
  595. chroma_ref_type = v->ref_field_type[dir];
  596. } else {
  597. int opp_count = get_luma_mv(v, dir, &tx, &ty);
  598. chroma_ref_type = v->cur_field_type ^ (opp_count > 2);
  599. }
  600. if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f->data[0])
  601. return;
  602. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
  603. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
  604. uvmx = (tx + ((tx & 3) == 3)) >> 1;
  605. uvmy = (ty + ((ty & 3) == 3)) >> 1;
  606. v->luma_mv[s->mb_x][0] = uvmx;
  607. v->luma_mv[s->mb_x][1] = uvmy;
  608. if (v->fastuvmc) {
  609. uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
  610. uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
  611. }
  612. // Field conversion bias
  613. if (v->cur_field_type != chroma_ref_type)
  614. uvmy += 2 - 4 * chroma_ref_type;
  615. uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
  616. uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
  617. if (v->profile != PROFILE_ADVANCED) {
  618. uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
  619. uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
  620. } else {
  621. uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
  622. uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
  623. }
  624. if (!dir) {
  625. if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
  626. srcU = s->current_picture.f->data[1];
  627. srcV = s->current_picture.f->data[2];
  628. lutuv = v->curr_lutuv;
  629. use_ic = *v->curr_use_ic;
  630. } else {
  631. srcU = s->last_picture.f->data[1];
  632. srcV = s->last_picture.f->data[2];
  633. lutuv = v->last_lutuv;
  634. use_ic = v->last_use_ic;
  635. }
  636. } else {
  637. srcU = s->next_picture.f->data[1];
  638. srcV = s->next_picture.f->data[2];
  639. lutuv = v->next_lutuv;
  640. use_ic = v->next_use_ic;
  641. }
  642. if (!srcU) {
  643. av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
  644. return;
  645. }
  646. srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
  647. srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
  648. if (v->field_mode) {
  649. if (chroma_ref_type) {
  650. srcU += s->current_picture_ptr->f->linesize[1];
  651. srcV += s->current_picture_ptr->f->linesize[2];
  652. }
  653. }
  654. if (v->rangeredfrm || use_ic
  655. || s->h_edge_pos < 18 || v_edge_pos < 18
  656. || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
  657. || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) {
  658. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
  659. s->uvlinesize, s->uvlinesize,
  660. 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
  661. s->h_edge_pos >> 1, v_edge_pos >> 1);
  662. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
  663. s->uvlinesize, s->uvlinesize,
  664. 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
  665. s->h_edge_pos >> 1, v_edge_pos >> 1);
  666. srcU = s->sc.edge_emu_buffer;
  667. srcV = s->sc.edge_emu_buffer + 16;
  668. /* if we deal with range reduction we need to scale source blocks */
  669. if (v->rangeredfrm) {
  670. vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
  671. }
  672. /* if we deal with intensity compensation we need to scale source blocks */
  673. if (use_ic) {
  674. vc1_lut_scale_chroma(srcU, srcV,
  675. lutuv[v->field_mode ? chroma_ref_type : ((0 + uvsrc_y) & 1)],
  676. lutuv[v->field_mode ? chroma_ref_type : ((1 + uvsrc_y) & 1)],
  677. 9, s->uvlinesize);
  678. }
  679. }
  680. /* Chroma MC always uses qpel bilinear */
  681. uvmx = (uvmx & 3) << 1;
  682. uvmy = (uvmy & 3) << 1;
  683. if (!v->rnd) {
  684. h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  685. h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  686. } else {
  687. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  688. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  689. }
  690. if (v->field_mode) {
  691. v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != chroma_ref_type;
  692. v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != chroma_ref_type;
  693. }
  694. }
  695. /** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
  696. */
  697. void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
  698. {
  699. MpegEncContext *s = &v->s;
  700. H264ChromaContext *h264chroma = &v->h264chroma;
  701. uint8_t *srcU, *srcV;
  702. int uvsrc_x, uvsrc_y;
  703. int uvmx_field[4], uvmy_field[4];
  704. int i, off, tx, ty;
  705. int fieldmv = v->blk_mv_type[s->block_index[0]];
  706. static const uint8_t s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
  707. int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
  708. int v_edge_pos = s->v_edge_pos >> 1;
  709. int use_ic;
  710. uint8_t (*lutuv)[256];
  711. if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
  712. return;
  713. for (i = 0; i < 4; i++) {
  714. int d = i < 2 ? dir: dir2;
  715. tx = s->mv[d][i][0];
  716. uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
  717. ty = s->mv[d][i][1];
  718. if (fieldmv)
  719. uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
  720. else
  721. uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
  722. }
  723. for (i = 0; i < 4; i++) {
  724. off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
  725. uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2);
  726. uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
  727. // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
  728. uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
  729. if (v->fcm == ILACE_FRAME)
  730. uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
  731. else
  732. uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
  733. if (i < 2 ? dir : dir2) {
  734. srcU = s->next_picture.f->data[1];
  735. srcV = s->next_picture.f->data[2];
  736. lutuv = v->next_lutuv;
  737. use_ic = v->next_use_ic;
  738. } else {
  739. srcU = s->last_picture.f->data[1];
  740. srcV = s->last_picture.f->data[2];
  741. lutuv = v->last_lutuv;
  742. use_ic = v->last_use_ic;
  743. }
  744. if (!srcU)
  745. return;
  746. srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
  747. srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
  748. uvmx_field[i] = (uvmx_field[i] & 3) << 1;
  749. uvmy_field[i] = (uvmy_field[i] & 3) << 1;
  750. if (use_ic
  751. || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
  752. || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
  753. || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
  754. if (v->fcm == ILACE_FRAME) {
  755. if (uvsrc_y & 1) {
  756. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
  757. 2 * s->uvlinesize, 2 * s->uvlinesize,
  758. 5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1,
  759. s->h_edge_pos >> 1, v_edge_pos + 1 >> 1);
  760. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->uvlinesize, srcU + s->uvlinesize,
  761. 2 * s->uvlinesize, 2 * s->uvlinesize,
  762. 5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1,
  763. s->h_edge_pos >> 1, v_edge_pos >> 1);
  764. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
  765. 2 * s->uvlinesize, 2 * s->uvlinesize,
  766. 5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1,
  767. s->h_edge_pos >> 1, v_edge_pos + 1 >> 1);
  768. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + s->uvlinesize, srcV + s->uvlinesize,
  769. 2 * s->uvlinesize, 2 * s->uvlinesize,
  770. 5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1,
  771. s->h_edge_pos >> 1, v_edge_pos >> 1);
  772. } else {
  773. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
  774. 2 * s->uvlinesize, 2 * s->uvlinesize,
  775. 5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1,
  776. s->h_edge_pos >> 1, v_edge_pos >> 1);
  777. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->uvlinesize, srcU + s->uvlinesize,
  778. 2 * s->uvlinesize, 2 * s->uvlinesize,
  779. 5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1,
  780. s->h_edge_pos >> 1, v_edge_pos + 1 >> 1);
  781. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
  782. 2 * s->uvlinesize, 2 * s->uvlinesize,
  783. 5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1,
  784. s->h_edge_pos >> 1, v_edge_pos >> 1);
  785. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + s->uvlinesize, srcV + s->uvlinesize,
  786. 2 * s->uvlinesize, 2 * s->uvlinesize,
  787. 5, (5 << fieldmv) + 1, uvsrc_x, uvsrc_y + 1 >> 1,
  788. s->h_edge_pos >> 1, v_edge_pos + 1 >> 1);
  789. }
  790. } else {
  791. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
  792. s->uvlinesize, s->uvlinesize,
  793. 5, 5, uvsrc_x, uvsrc_y,
  794. s->h_edge_pos >> 1, v_edge_pos);
  795. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
  796. s->uvlinesize, s->uvlinesize,
  797. 5, 5, uvsrc_x, uvsrc_y,
  798. s->h_edge_pos >> 1, v_edge_pos);
  799. }
  800. srcU = s->sc.edge_emu_buffer;
  801. srcV = s->sc.edge_emu_buffer + 16;
  802. /* if we deal with intensity compensation we need to scale source blocks */
  803. if (use_ic) {
  804. vc1_lut_scale_chroma(srcU, srcV,
  805. lutuv[(uvsrc_y + (0 << fieldmv)) & 1],
  806. lutuv[(uvsrc_y + (1 << fieldmv)) & 1],
  807. 5, s->uvlinesize << fieldmv);
  808. }
  809. }
  810. if (avg) {
  811. if (!v->rnd) {
  812. h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  813. h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  814. } else {
  815. v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  816. v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  817. }
  818. } else {
  819. if (!v->rnd) {
  820. h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  821. h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  822. } else {
  823. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  824. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  825. }
  826. }
  827. }
  828. }
  829. /** Motion compensation for direct or interpolated blocks in B-frames
  830. */
  831. void ff_vc1_interp_mc(VC1Context *v)
  832. {
  833. MpegEncContext *s = &v->s;
  834. H264ChromaContext *h264chroma = &v->h264chroma;
  835. uint8_t *srcY, *srcU, *srcV;
  836. int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
  837. int v_edge_pos = s->v_edge_pos >> v->field_mode;
  838. int use_ic = v->next_use_ic;
  839. if (!v->field_mode && !v->s.next_picture.f->data[0])
  840. return;
  841. mx = s->mv[1][0][0];
  842. my = s->mv[1][0][1];
  843. uvmx = (mx + ((mx & 3) == 3)) >> 1;
  844. uvmy = (my + ((my & 3) == 3)) >> 1;
  845. if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) {
  846. my = my - 2 + 4 * v->cur_field_type;
  847. uvmy = uvmy - 2 + 4 * v->cur_field_type;
  848. }
  849. if (v->fastuvmc) {
  850. uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
  851. uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
  852. }
  853. srcY = s->next_picture.f->data[0];
  854. srcU = s->next_picture.f->data[1];
  855. srcV = s->next_picture.f->data[2];
  856. src_x = s->mb_x * 16 + (mx >> 2);
  857. src_y = s->mb_y * 16 + (my >> 2);
  858. uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
  859. uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
  860. if (v->profile != PROFILE_ADVANCED) {
  861. src_x = av_clip( src_x, -16, s->mb_width * 16);
  862. src_y = av_clip( src_y, -16, s->mb_height * 16);
  863. uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
  864. uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
  865. } else {
  866. src_x = av_clip( src_x, -17, s->avctx->coded_width);
  867. uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
  868. if (v->fcm == ILACE_FRAME) {
  869. src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
  870. uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
  871. } else {
  872. src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
  873. uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
  874. }
  875. }
  876. srcY += src_y * s->linesize + src_x;
  877. srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
  878. srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
  879. if (v->field_mode && v->ref_field_type[1]) {
  880. srcY += s->current_picture_ptr->f->linesize[0];
  881. srcU += s->current_picture_ptr->f->linesize[1];
  882. srcV += s->current_picture_ptr->f->linesize[2];
  883. }
  884. /* for grayscale we should not try to read from unknown area */
  885. if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) {
  886. srcU = s->sc.edge_emu_buffer + 18 * s->linesize;
  887. srcV = s->sc.edge_emu_buffer + 18 * s->linesize;
  888. }
  889. if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
  890. || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
  891. || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) {
  892. uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
  893. uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
  894. const int k = 17 + s->mspel * 2;
  895. srcY -= s->mspel * (1 + s->linesize);
  896. if (v->fcm == ILACE_FRAME) {
  897. if (src_y - s->mspel & 1) {
  898. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
  899. srcY,
  900. 2 * s->linesize,
  901. 2 * s->linesize,
  902. k,
  903. k + 1 >> 1,
  904. src_x - s->mspel,
  905. src_y - s->mspel >> 1,
  906. s->h_edge_pos,
  907. v_edge_pos + 1 >> 1);
  908. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize,
  909. srcY + s->linesize,
  910. 2 * s->linesize,
  911. 2 * s->linesize,
  912. k,
  913. k >> 1,
  914. src_x - s->mspel,
  915. src_y - s->mspel + 1 >> 1,
  916. s->h_edge_pos,
  917. v_edge_pos >> 1);
  918. } else {
  919. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
  920. srcY,
  921. 2 * s->linesize,
  922. 2 * s->linesize,
  923. k,
  924. k + 1 >> 1,
  925. src_x - s->mspel,
  926. src_y - s->mspel >> 1,
  927. s->h_edge_pos,
  928. v_edge_pos >> 1);
  929. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize,
  930. srcY + s->linesize,
  931. 2 * s->linesize,
  932. 2 * s->linesize,
  933. k,
  934. k >> 1,
  935. src_x - s->mspel,
  936. src_y - s->mspel + 1 >> 1,
  937. s->h_edge_pos,
  938. v_edge_pos + 1 >> 1);
  939. }
  940. } else
  941. s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
  942. s->linesize, s->linesize,
  943. k, k,
  944. src_x - s->mspel, src_y - s->mspel,
  945. s->h_edge_pos, v_edge_pos);
  946. srcY = s->sc.edge_emu_buffer;
  947. if (v->fcm == ILACE_FRAME) {
  948. if (uvsrc_y & 1) {
  949. s->vdsp.emulated_edge_mc(ubuf, srcU,
  950. 2 * s->uvlinesize, 2 * s->uvlinesize,
  951. 8 + 1, 5,
  952. uvsrc_x, uvsrc_y >> 1,
  953. s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
  954. s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize,
  955. 2 * s->uvlinesize, 2 * s->uvlinesize,
  956. 8 + 1, 4,
  957. uvsrc_x, uvsrc_y + 1 >> 1,
  958. s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
  959. s->vdsp.emulated_edge_mc(vbuf, srcV,
  960. 2 * s->uvlinesize, 2 * s->uvlinesize,
  961. 8 + 1, 5,
  962. uvsrc_x, uvsrc_y >> 1,
  963. s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
  964. s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize,
  965. 2 * s->uvlinesize, 2 * s->uvlinesize,
  966. 8 + 1, 4,
  967. uvsrc_x, uvsrc_y + 1 >> 1,
  968. s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
  969. } else {
  970. s->vdsp.emulated_edge_mc(ubuf, srcU,
  971. 2 * s->uvlinesize, 2 * s->uvlinesize,
  972. 8 + 1, 5,
  973. uvsrc_x, uvsrc_y >> 1,
  974. s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
  975. s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize,
  976. 2 * s->uvlinesize, 2 * s->uvlinesize,
  977. 8 + 1, 4,
  978. uvsrc_x, uvsrc_y + 1 >> 1,
  979. s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
  980. s->vdsp.emulated_edge_mc(vbuf, srcV,
  981. 2 * s->uvlinesize, 2 * s->uvlinesize,
  982. 8 + 1, 5,
  983. uvsrc_x, uvsrc_y >> 1,
  984. s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
  985. s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize,
  986. 2 * s->uvlinesize, 2 * s->uvlinesize,
  987. 8 + 1, 4,
  988. uvsrc_x, uvsrc_y + 1 >> 1,
  989. s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
  990. }
  991. } else {
  992. s->vdsp.emulated_edge_mc(ubuf, srcU,
  993. s->uvlinesize, s->uvlinesize,
  994. 8 + 1, 8 + 1,
  995. uvsrc_x, uvsrc_y,
  996. s->h_edge_pos >> 1, v_edge_pos >> 1);
  997. s->vdsp.emulated_edge_mc(vbuf, srcV,
  998. s->uvlinesize, s->uvlinesize,
  999. 8 + 1, 8 + 1,
  1000. uvsrc_x, uvsrc_y,
  1001. s->h_edge_pos >> 1, v_edge_pos >> 1);
  1002. }
  1003. srcU = ubuf;
  1004. srcV = vbuf;
  1005. /* if we deal with range reduction we need to scale source blocks */
  1006. if (v->rangeredfrm) {
  1007. vc1_scale_luma(srcY, k, s->linesize);
  1008. vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
  1009. }
  1010. if (use_ic) {
  1011. uint8_t (*luty )[256] = v->next_luty;
  1012. uint8_t (*lutuv)[256] = v->next_lutuv;
  1013. vc1_lut_scale_luma(srcY,
  1014. luty[v->field_mode ? v->ref_field_type[1] : ((0+src_y - s->mspel) & 1)],
  1015. luty[v->field_mode ? v->ref_field_type[1] : ((1+src_y - s->mspel) & 1)],
  1016. k, s->linesize);
  1017. vc1_lut_scale_chroma(srcU, srcV,
  1018. lutuv[v->field_mode ? v->ref_field_type[1] : ((0+uvsrc_y) & 1)],
  1019. lutuv[v->field_mode ? v->ref_field_type[1] : ((1+uvsrc_y) & 1)],
  1020. 9, s->uvlinesize);
  1021. }
  1022. srcY += s->mspel * (1 + s->linesize);
  1023. }
  1024. if (s->mspel) {
  1025. dxy = ((my & 3) << 2) | (mx & 3);
  1026. v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
  1027. } else { // hpel mc
  1028. dxy = (my & 2) | ((mx & 2) >> 1);
  1029. if (!v->rnd)
  1030. s->hdsp.avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
  1031. else
  1032. s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0], srcY, s->linesize, 16);
  1033. }
  1034. if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
  1035. return;
  1036. /* Chroma MC always uses qpel bilinear */
  1037. uvmx = (uvmx & 3) << 1;
  1038. uvmy = (uvmy & 3) << 1;
  1039. if (!v->rnd) {
  1040. h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  1041. h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  1042. } else {
  1043. v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  1044. v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  1045. }
  1046. }