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.

911 lines
35KB

  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. /** Do motion compensation over 1 macroblock
  94. * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
  95. */
  96. void ff_vc1_mc_1mv(VC1Context *v, int dir)
  97. {
  98. MpegEncContext *s = &v->s;
  99. H264ChromaContext *h264chroma = &v->h264chroma;
  100. uint8_t *srcY, *srcU, *srcV;
  101. int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
  102. int v_edge_pos = s->v_edge_pos >> v->field_mode;
  103. int i;
  104. uint8_t (*luty)[256], (*lutuv)[256];
  105. int use_ic;
  106. if ((!v->field_mode ||
  107. (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
  108. !v->s.last_picture.f->data[0])
  109. return;
  110. mx = s->mv[dir][0][0];
  111. my = s->mv[dir][0][1];
  112. // store motion vectors for further use in B frames
  113. if (s->pict_type == AV_PICTURE_TYPE_P) {
  114. for (i = 0; i < 4; i++) {
  115. s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
  116. s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
  117. }
  118. }
  119. uvmx = (mx + ((mx & 3) == 3)) >> 1;
  120. uvmy = (my + ((my & 3) == 3)) >> 1;
  121. v->luma_mv[s->mb_x][0] = uvmx;
  122. v->luma_mv[s->mb_x][1] = uvmy;
  123. if (v->field_mode &&
  124. v->cur_field_type != v->ref_field_type[dir]) {
  125. my = my - 2 + 4 * v->cur_field_type;
  126. uvmy = uvmy - 2 + 4 * v->cur_field_type;
  127. }
  128. // fastuvmc shall be ignored for interlaced frame picture
  129. if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
  130. uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
  131. uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
  132. }
  133. if (!dir) {
  134. if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
  135. srcY = s->current_picture.f->data[0];
  136. srcU = s->current_picture.f->data[1];
  137. srcV = s->current_picture.f->data[2];
  138. luty = v->curr_luty;
  139. lutuv = v->curr_lutuv;
  140. use_ic = *v->curr_use_ic;
  141. } else {
  142. srcY = s->last_picture.f->data[0];
  143. srcU = s->last_picture.f->data[1];
  144. srcV = s->last_picture.f->data[2];
  145. luty = v->last_luty;
  146. lutuv = v->last_lutuv;
  147. use_ic = v->last_use_ic;
  148. }
  149. } else {
  150. srcY = s->next_picture.f->data[0];
  151. srcU = s->next_picture.f->data[1];
  152. srcV = s->next_picture.f->data[2];
  153. luty = v->next_luty;
  154. lutuv = v->next_lutuv;
  155. use_ic = v->next_use_ic;
  156. }
  157. if (!srcY || !srcU) {
  158. av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
  159. return;
  160. }
  161. src_x = s->mb_x * 16 + (mx >> 2);
  162. src_y = s->mb_y * 16 + (my >> 2);
  163. uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
  164. uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
  165. if (v->profile != PROFILE_ADVANCED) {
  166. src_x = av_clip( src_x, -16, s->mb_width * 16);
  167. src_y = av_clip( src_y, -16, s->mb_height * 16);
  168. uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
  169. uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
  170. } else {
  171. src_x = av_clip( src_x, -17, s->avctx->coded_width);
  172. src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
  173. uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
  174. uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
  175. }
  176. srcY += src_y * s->linesize + src_x;
  177. srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
  178. srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
  179. if (v->field_mode && v->ref_field_type[dir]) {
  180. srcY += s->current_picture_ptr->f->linesize[0];
  181. srcU += s->current_picture_ptr->f->linesize[1];
  182. srcV += s->current_picture_ptr->f->linesize[2];
  183. }
  184. /* for grayscale we should not try to read from unknown area */
  185. if (s->flags & CODEC_FLAG_GRAY) {
  186. srcU = s->edge_emu_buffer + 18 * s->linesize;
  187. srcV = s->edge_emu_buffer + 18 * s->linesize;
  188. }
  189. if (v->rangeredfrm || use_ic
  190. || s->h_edge_pos < 22 || v_edge_pos < 22
  191. || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
  192. || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 3) {
  193. uint8_t *ubuf = s->edge_emu_buffer + 19 * s->linesize;
  194. uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
  195. const int k = 17 + s->mspel * 2;
  196. srcY -= s->mspel * (1 + s->linesize);
  197. s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
  198. s->linesize, s->linesize,
  199. k, k,
  200. src_x - s->mspel, src_y - s->mspel,
  201. s->h_edge_pos, v_edge_pos);
  202. srcY = s->edge_emu_buffer;
  203. s->vdsp.emulated_edge_mc(ubuf, srcU,
  204. s->uvlinesize, s->uvlinesize,
  205. 8 + 1, 8 + 1,
  206. uvsrc_x, uvsrc_y,
  207. s->h_edge_pos >> 1, v_edge_pos >> 1);
  208. s->vdsp.emulated_edge_mc(vbuf, srcV,
  209. s->uvlinesize, s->uvlinesize,
  210. 8 + 1, 8 + 1,
  211. uvsrc_x, uvsrc_y,
  212. s->h_edge_pos >> 1, v_edge_pos >> 1);
  213. srcU = ubuf;
  214. srcV = vbuf;
  215. /* if we deal with range reduction we need to scale source blocks */
  216. if (v->rangeredfrm) {
  217. vc1_scale_luma(srcY, k, s->linesize);
  218. vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
  219. }
  220. /* if we deal with intensity compensation we need to scale source blocks */
  221. if (use_ic) {
  222. vc1_lut_scale_luma(srcY,
  223. luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)],
  224. luty[v->field_mode ? v->ref_field_type[dir] : ((1 + src_y - s->mspel) & 1)],
  225. k, s->linesize);
  226. vc1_lut_scale_chroma(srcU, srcV,
  227. lutuv[v->field_mode ? v->ref_field_type[dir] : ((0 + uvsrc_y) & 1)],
  228. lutuv[v->field_mode ? v->ref_field_type[dir] : ((1 + uvsrc_y) & 1)],
  229. 9, s->uvlinesize);
  230. }
  231. srcY += s->mspel * (1 + s->linesize);
  232. }
  233. if (s->mspel) {
  234. dxy = ((my & 3) << 2) | (mx & 3);
  235. v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
  236. } else { // hpel mc - always used for luma
  237. dxy = (my & 2) | ((mx & 2) >> 1);
  238. if (!v->rnd)
  239. s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
  240. else
  241. s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
  242. }
  243. if (s->flags & CODEC_FLAG_GRAY) return;
  244. /* Chroma MC always uses qpel bilinear */
  245. uvmx = (uvmx & 3) << 1;
  246. uvmy = (uvmy & 3) << 1;
  247. if (!v->rnd) {
  248. h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  249. h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  250. } else {
  251. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  252. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  253. }
  254. }
  255. /** Do motion compensation for 4-MV macroblock - luminance block
  256. */
  257. void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
  258. {
  259. MpegEncContext *s = &v->s;
  260. uint8_t *srcY;
  261. int dxy, mx, my, src_x, src_y;
  262. int off;
  263. int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
  264. int v_edge_pos = s->v_edge_pos >> v->field_mode;
  265. uint8_t (*luty)[256];
  266. int use_ic;
  267. if ((!v->field_mode ||
  268. (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
  269. !v->s.last_picture.f->data[0])
  270. return;
  271. mx = s->mv[dir][n][0];
  272. my = s->mv[dir][n][1];
  273. if (!dir) {
  274. if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
  275. srcY = s->current_picture.f->data[0];
  276. luty = v->curr_luty;
  277. use_ic = *v->curr_use_ic;
  278. } else {
  279. srcY = s->last_picture.f->data[0];
  280. luty = v->last_luty;
  281. use_ic = v->last_use_ic;
  282. }
  283. } else {
  284. srcY = s->next_picture.f->data[0];
  285. luty = v->next_luty;
  286. use_ic = v->next_use_ic;
  287. }
  288. if (!srcY) {
  289. av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
  290. return;
  291. }
  292. if (v->field_mode) {
  293. if (v->cur_field_type != v->ref_field_type[dir])
  294. my = my - 2 + 4 * v->cur_field_type;
  295. }
  296. if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
  297. int same_count = 0, opp_count = 0, k;
  298. int chosen_mv[2][4][2], f;
  299. int tx, ty;
  300. for (k = 0; k < 4; k++) {
  301. f = v->mv_f[0][s->block_index[k] + v->blocks_off];
  302. chosen_mv[f][f ? opp_count : same_count][0] = s->mv[0][k][0];
  303. chosen_mv[f][f ? opp_count : same_count][1] = s->mv[0][k][1];
  304. opp_count += f;
  305. same_count += 1 - f;
  306. }
  307. f = opp_count > same_count;
  308. switch (f ? opp_count : same_count) {
  309. case 4:
  310. tx = median4(chosen_mv[f][0][0], chosen_mv[f][1][0],
  311. chosen_mv[f][2][0], chosen_mv[f][3][0]);
  312. ty = median4(chosen_mv[f][0][1], chosen_mv[f][1][1],
  313. chosen_mv[f][2][1], chosen_mv[f][3][1]);
  314. break;
  315. case 3:
  316. tx = mid_pred(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0]);
  317. ty = mid_pred(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1]);
  318. break;
  319. case 2:
  320. tx = (chosen_mv[f][0][0] + chosen_mv[f][1][0]) / 2;
  321. ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
  322. break;
  323. default:
  324. av_assert0(0);
  325. }
  326. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
  327. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
  328. for (k = 0; k < 4; k++)
  329. v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
  330. }
  331. if (v->fcm == ILACE_FRAME) { // not sure if needed for other types of picture
  332. int qx, qy;
  333. int width = s->avctx->coded_width;
  334. int height = s->avctx->coded_height >> 1;
  335. if (s->pict_type == AV_PICTURE_TYPE_P) {
  336. s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
  337. s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
  338. }
  339. qx = (s->mb_x * 16) + (mx >> 2);
  340. qy = (s->mb_y * 8) + (my >> 3);
  341. if (qx < -17)
  342. mx -= 4 * (qx + 17);
  343. else if (qx > width)
  344. mx -= 4 * (qx - width);
  345. if (qy < -18)
  346. my -= 8 * (qy + 18);
  347. else if (qy > height + 1)
  348. my -= 8 * (qy - height - 1);
  349. }
  350. if ((v->fcm == ILACE_FRAME) && fieldmv)
  351. off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
  352. else
  353. off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
  354. src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
  355. if (!fieldmv)
  356. src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
  357. else
  358. src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
  359. if (v->profile != PROFILE_ADVANCED) {
  360. src_x = av_clip(src_x, -16, s->mb_width * 16);
  361. src_y = av_clip(src_y, -16, s->mb_height * 16);
  362. } else {
  363. src_x = av_clip(src_x, -17, s->avctx->coded_width);
  364. if (v->fcm == ILACE_FRAME) {
  365. if (src_y & 1)
  366. src_y = av_clip(src_y, -17, s->avctx->coded_height + 1);
  367. else
  368. src_y = av_clip(src_y, -18, s->avctx->coded_height);
  369. } else {
  370. src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
  371. }
  372. }
  373. srcY += src_y * s->linesize + src_x;
  374. if (v->field_mode && v->ref_field_type[dir])
  375. srcY += s->current_picture_ptr->f->linesize[0];
  376. if (fieldmv && !(src_y & 1))
  377. v_edge_pos--;
  378. if (fieldmv && (src_y & 1) && src_y < 4)
  379. src_y--;
  380. if (v->rangeredfrm || use_ic
  381. || s->h_edge_pos < 13 || v_edge_pos < 23
  382. || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
  383. || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
  384. const int k = 9 + s->mspel * 2;
  385. srcY -= s->mspel * (1 + (s->linesize << fieldmv));
  386. /* check emulate edge stride and offset */
  387. s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
  388. s->linesize, s->linesize,
  389. k, k << fieldmv,
  390. src_x - s->mspel, src_y - (s->mspel << fieldmv),
  391. s->h_edge_pos, v_edge_pos);
  392. srcY = s->edge_emu_buffer;
  393. /* if we deal with range reduction we need to scale source blocks */
  394. if (v->rangeredfrm) {
  395. vc1_scale_luma(srcY, k, s->linesize << fieldmv);
  396. }
  397. /* if we deal with intensity compensation we need to scale source blocks */
  398. if (use_ic) {
  399. vc1_lut_scale_luma(srcY,
  400. luty[v->field_mode ? v->ref_field_type[dir] : (((0<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
  401. luty[v->field_mode ? v->ref_field_type[dir] : (((1<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
  402. k, s->linesize << fieldmv);
  403. }
  404. srcY += s->mspel * (1 + (s->linesize << fieldmv));
  405. }
  406. if (s->mspel) {
  407. dxy = ((my & 3) << 2) | (mx & 3);
  408. if (avg)
  409. v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
  410. else
  411. v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
  412. } else { // hpel mc - always used for luma
  413. dxy = (my & 2) | ((mx & 2) >> 1);
  414. if (!v->rnd)
  415. s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
  416. else
  417. s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
  418. }
  419. }
  420. static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag, int *tx, int *ty)
  421. {
  422. int idx, i;
  423. static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
  424. idx = ((a[3] != flag) << 3)
  425. | ((a[2] != flag) << 2)
  426. | ((a[1] != flag) << 1)
  427. | (a[0] != flag);
  428. if (!idx) {
  429. *tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
  430. *ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
  431. return 4;
  432. } else if (count[idx] == 1) {
  433. switch (idx) {
  434. case 0x1:
  435. *tx = mid_pred(mvx[1], mvx[2], mvx[3]);
  436. *ty = mid_pred(mvy[1], mvy[2], mvy[3]);
  437. return 3;
  438. case 0x2:
  439. *tx = mid_pred(mvx[0], mvx[2], mvx[3]);
  440. *ty = mid_pred(mvy[0], mvy[2], mvy[3]);
  441. return 3;
  442. case 0x4:
  443. *tx = mid_pred(mvx[0], mvx[1], mvx[3]);
  444. *ty = mid_pred(mvy[0], mvy[1], mvy[3]);
  445. return 3;
  446. case 0x8:
  447. *tx = mid_pred(mvx[0], mvx[1], mvx[2]);
  448. *ty = mid_pred(mvy[0], mvy[1], mvy[2]);
  449. return 3;
  450. }
  451. } else if (count[idx] == 2) {
  452. int t1 = 0, t2 = 0;
  453. for (i = 0; i < 3; i++)
  454. if (!a[i]) {
  455. t1 = i;
  456. break;
  457. }
  458. for (i = t1 + 1; i < 4; i++)
  459. if (!a[i]) {
  460. t2 = i;
  461. break;
  462. }
  463. *tx = (mvx[t1] + mvx[t2]) / 2;
  464. *ty = (mvy[t1] + mvy[t2]) / 2;
  465. return 2;
  466. } else {
  467. return 0;
  468. }
  469. return -1;
  470. }
  471. /** Do motion compensation for 4-MV macroblock - both chroma blocks
  472. */
  473. void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir)
  474. {
  475. MpegEncContext *s = &v->s;
  476. H264ChromaContext *h264chroma = &v->h264chroma;
  477. uint8_t *srcU, *srcV;
  478. int uvmx, uvmy, uvsrc_x, uvsrc_y;
  479. int k, tx = 0, ty = 0;
  480. int mvx[4], mvy[4], intra[4], mv_f[4];
  481. int valid_count;
  482. int chroma_ref_type = v->cur_field_type;
  483. int v_edge_pos = s->v_edge_pos >> v->field_mode;
  484. uint8_t (*lutuv)[256];
  485. int use_ic;
  486. if (!v->field_mode && !v->s.last_picture.f->data[0])
  487. return;
  488. if (s->flags & CODEC_FLAG_GRAY)
  489. return;
  490. for (k = 0; k < 4; k++) {
  491. mvx[k] = s->mv[dir][k][0];
  492. mvy[k] = s->mv[dir][k][1];
  493. intra[k] = v->mb_type[0][s->block_index[k]];
  494. if (v->field_mode)
  495. mv_f[k] = v->mv_f[dir][s->block_index[k] + v->blocks_off];
  496. }
  497. /* calculate chroma MV vector from four luma MVs */
  498. if (!v->field_mode || (v->field_mode && !v->numref)) {
  499. valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
  500. chroma_ref_type = v->ref_field_type[dir];
  501. if (!valid_count) {
  502. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
  503. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
  504. v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
  505. return; //no need to do MC for intra blocks
  506. }
  507. } else {
  508. int dominant = 0;
  509. if (mv_f[0] + mv_f[1] + mv_f[2] + mv_f[3] > 2)
  510. dominant = 1;
  511. valid_count = get_chroma_mv(mvx, mvy, mv_f, dominant, &tx, &ty);
  512. if (dominant)
  513. chroma_ref_type = !v->cur_field_type;
  514. }
  515. if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f->data[0])
  516. return;
  517. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
  518. s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
  519. uvmx = (tx + ((tx & 3) == 3)) >> 1;
  520. uvmy = (ty + ((ty & 3) == 3)) >> 1;
  521. v->luma_mv[s->mb_x][0] = uvmx;
  522. v->luma_mv[s->mb_x][1] = uvmy;
  523. if (v->fastuvmc) {
  524. uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
  525. uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
  526. }
  527. // Field conversion bias
  528. if (v->cur_field_type != chroma_ref_type)
  529. uvmy += 2 - 4 * chroma_ref_type;
  530. uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
  531. uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
  532. if (v->profile != PROFILE_ADVANCED) {
  533. uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
  534. uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
  535. } else {
  536. uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
  537. uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
  538. }
  539. if (!dir) {
  540. if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
  541. srcU = s->current_picture.f->data[1];
  542. srcV = s->current_picture.f->data[2];
  543. lutuv = v->curr_lutuv;
  544. use_ic = *v->curr_use_ic;
  545. } else {
  546. srcU = s->last_picture.f->data[1];
  547. srcV = s->last_picture.f->data[2];
  548. lutuv = v->last_lutuv;
  549. use_ic = v->last_use_ic;
  550. }
  551. } else {
  552. srcU = s->next_picture.f->data[1];
  553. srcV = s->next_picture.f->data[2];
  554. lutuv = v->next_lutuv;
  555. use_ic = v->next_use_ic;
  556. }
  557. if (!srcU) {
  558. av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
  559. return;
  560. }
  561. srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
  562. srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
  563. if (v->field_mode) {
  564. if (chroma_ref_type) {
  565. srcU += s->current_picture_ptr->f->linesize[1];
  566. srcV += s->current_picture_ptr->f->linesize[2];
  567. }
  568. }
  569. if (v->rangeredfrm || use_ic
  570. || s->h_edge_pos < 18 || v_edge_pos < 18
  571. || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
  572. || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) {
  573. s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
  574. s->uvlinesize, s->uvlinesize,
  575. 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
  576. s->h_edge_pos >> 1, v_edge_pos >> 1);
  577. s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
  578. s->uvlinesize, s->uvlinesize,
  579. 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
  580. s->h_edge_pos >> 1, v_edge_pos >> 1);
  581. srcU = s->edge_emu_buffer;
  582. srcV = s->edge_emu_buffer + 16;
  583. /* if we deal with range reduction we need to scale source blocks */
  584. if (v->rangeredfrm) {
  585. vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
  586. }
  587. /* if we deal with intensity compensation we need to scale source blocks */
  588. if (use_ic) {
  589. vc1_lut_scale_chroma(srcU, srcV,
  590. lutuv[v->field_mode ? chroma_ref_type : ((0 + uvsrc_y) & 1)],
  591. lutuv[v->field_mode ? chroma_ref_type : ((1 + uvsrc_y) & 1)],
  592. 9, s->uvlinesize);
  593. }
  594. }
  595. /* Chroma MC always uses qpel bilinear */
  596. uvmx = (uvmx & 3) << 1;
  597. uvmy = (uvmy & 3) << 1;
  598. if (!v->rnd) {
  599. h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  600. h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  601. } else {
  602. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
  603. v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
  604. }
  605. }
  606. /** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
  607. */
  608. void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
  609. {
  610. MpegEncContext *s = &v->s;
  611. H264ChromaContext *h264chroma = &v->h264chroma;
  612. uint8_t *srcU, *srcV;
  613. int uvsrc_x, uvsrc_y;
  614. int uvmx_field[4], uvmy_field[4];
  615. int i, off, tx, ty;
  616. int fieldmv = v->blk_mv_type[s->block_index[0]];
  617. static const int s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
  618. int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
  619. int v_edge_pos = s->v_edge_pos >> 1;
  620. int use_ic;
  621. uint8_t (*lutuv)[256];
  622. if (s->flags & CODEC_FLAG_GRAY)
  623. return;
  624. for (i = 0; i < 4; i++) {
  625. int d = i < 2 ? dir: dir2;
  626. tx = s->mv[d][i][0];
  627. uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
  628. ty = s->mv[d][i][1];
  629. if (fieldmv)
  630. uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
  631. else
  632. uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
  633. }
  634. for (i = 0; i < 4; i++) {
  635. off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
  636. uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2);
  637. uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
  638. // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
  639. uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
  640. uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
  641. if (i < 2 ? dir : dir2) {
  642. srcU = s->next_picture.f->data[1];
  643. srcV = s->next_picture.f->data[2];
  644. lutuv = v->next_lutuv;
  645. use_ic = v->next_use_ic;
  646. } else {
  647. srcU = s->last_picture.f->data[1];
  648. srcV = s->last_picture.f->data[2];
  649. lutuv = v->last_lutuv;
  650. use_ic = v->last_use_ic;
  651. }
  652. if (!srcU)
  653. return;
  654. srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
  655. srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
  656. uvmx_field[i] = (uvmx_field[i] & 3) << 1;
  657. uvmy_field[i] = (uvmy_field[i] & 3) << 1;
  658. if (fieldmv && !(uvsrc_y & 1))
  659. v_edge_pos = (s->v_edge_pos >> 1) - 1;
  660. if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
  661. uvsrc_y--;
  662. if (use_ic
  663. || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
  664. || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
  665. || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
  666. s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
  667. s->uvlinesize, s->uvlinesize,
  668. 5, (5 << fieldmv), uvsrc_x, uvsrc_y,
  669. s->h_edge_pos >> 1, v_edge_pos);
  670. s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
  671. s->uvlinesize, s->uvlinesize,
  672. 5, (5 << fieldmv), uvsrc_x, uvsrc_y,
  673. s->h_edge_pos >> 1, v_edge_pos);
  674. srcU = s->edge_emu_buffer;
  675. srcV = s->edge_emu_buffer + 16;
  676. /* if we deal with intensity compensation we need to scale source blocks */
  677. if (use_ic) {
  678. vc1_lut_scale_chroma(srcU, srcV,
  679. lutuv[(uvsrc_y + (0 << fieldmv)) & 1],
  680. lutuv[(uvsrc_y + (1 << fieldmv)) & 1],
  681. 5, s->uvlinesize << fieldmv);
  682. }
  683. }
  684. if (avg) {
  685. if (!v->rnd) {
  686. h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  687. h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  688. } else {
  689. 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]);
  690. 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]);
  691. }
  692. } else {
  693. if (!v->rnd) {
  694. h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  695. h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
  696. } else {
  697. 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]);
  698. 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]);
  699. }
  700. }
  701. }
  702. }
  703. /** Motion compensation for direct or interpolated blocks in B-frames
  704. */
  705. void ff_vc1_interp_mc(VC1Context *v)
  706. {
  707. MpegEncContext *s = &v->s;
  708. H264ChromaContext *h264chroma = &v->h264chroma;
  709. uint8_t *srcY, *srcU, *srcV;
  710. int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
  711. int off, off_uv;
  712. int v_edge_pos = s->v_edge_pos >> v->field_mode;
  713. int use_ic = v->next_use_ic;
  714. if (!v->field_mode && !v->s.next_picture.f->data[0])
  715. return;
  716. mx = s->mv[1][0][0];
  717. my = s->mv[1][0][1];
  718. uvmx = (mx + ((mx & 3) == 3)) >> 1;
  719. uvmy = (my + ((my & 3) == 3)) >> 1;
  720. if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) {
  721. my = my - 2 + 4 * v->cur_field_type;
  722. uvmy = uvmy - 2 + 4 * v->cur_field_type;
  723. }
  724. if (v->fastuvmc) {
  725. uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
  726. uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
  727. }
  728. srcY = s->next_picture.f->data[0];
  729. srcU = s->next_picture.f->data[1];
  730. srcV = s->next_picture.f->data[2];
  731. src_x = s->mb_x * 16 + (mx >> 2);
  732. src_y = s->mb_y * 16 + (my >> 2);
  733. uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
  734. uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
  735. if (v->profile != PROFILE_ADVANCED) {
  736. src_x = av_clip( src_x, -16, s->mb_width * 16);
  737. src_y = av_clip( src_y, -16, s->mb_height * 16);
  738. uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
  739. uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
  740. } else {
  741. src_x = av_clip( src_x, -17, s->avctx->coded_width);
  742. src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
  743. uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
  744. uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
  745. }
  746. srcY += src_y * s->linesize + src_x;
  747. srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
  748. srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
  749. if (v->field_mode && v->ref_field_type[1]) {
  750. srcY += s->current_picture_ptr->f->linesize[0];
  751. srcU += s->current_picture_ptr->f->linesize[1];
  752. srcV += s->current_picture_ptr->f->linesize[2];
  753. }
  754. /* for grayscale we should not try to read from unknown area */
  755. if (s->flags & CODEC_FLAG_GRAY) {
  756. srcU = s->edge_emu_buffer + 18 * s->linesize;
  757. srcV = s->edge_emu_buffer + 18 * s->linesize;
  758. }
  759. if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
  760. || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
  761. || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) {
  762. uint8_t *ubuf = s->edge_emu_buffer + 19 * s->linesize;
  763. uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
  764. const int k = 17 + s->mspel * 2;
  765. srcY -= s->mspel * (1 + s->linesize);
  766. s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
  767. s->linesize, s->linesize,
  768. k, k,
  769. src_x - s->mspel, src_y - s->mspel,
  770. s->h_edge_pos, v_edge_pos);
  771. srcY = s->edge_emu_buffer;
  772. s->vdsp.emulated_edge_mc(ubuf, srcU,
  773. s->uvlinesize, s->uvlinesize,
  774. 8 + 1, 8 + 1,
  775. uvsrc_x, uvsrc_y,
  776. s->h_edge_pos >> 1, v_edge_pos >> 1);
  777. s->vdsp.emulated_edge_mc(vbuf, srcV,
  778. s->uvlinesize, s->uvlinesize,
  779. 8 + 1, 8 + 1,
  780. uvsrc_x, uvsrc_y,
  781. s->h_edge_pos >> 1, v_edge_pos >> 1);
  782. srcU = ubuf;
  783. srcV = vbuf;
  784. /* if we deal with range reduction we need to scale source blocks */
  785. if (v->rangeredfrm) {
  786. vc1_scale_luma(srcY, k, s->linesize);
  787. vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
  788. }
  789. if (use_ic) {
  790. uint8_t (*luty )[256] = v->next_luty;
  791. uint8_t (*lutuv)[256] = v->next_lutuv;
  792. vc1_lut_scale_luma(srcY,
  793. luty[v->field_mode ? v->ref_field_type[1] : ((0+src_y - s->mspel) & 1)],
  794. luty[v->field_mode ? v->ref_field_type[1] : ((1+src_y - s->mspel) & 1)],
  795. k, s->linesize);
  796. vc1_lut_scale_chroma(srcU, srcV,
  797. lutuv[v->field_mode ? v->ref_field_type[1] : ((0+uvsrc_y) & 1)],
  798. lutuv[v->field_mode ? v->ref_field_type[1] : ((1+uvsrc_y) & 1)],
  799. 9, s->uvlinesize);
  800. }
  801. srcY += s->mspel * (1 + s->linesize);
  802. }
  803. off = 0;
  804. off_uv = 0;
  805. if (s->mspel) {
  806. dxy = ((my & 3) << 2) | (mx & 3);
  807. v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0] + off , srcY , s->linesize, v->rnd);
  808. } else { // hpel mc
  809. dxy = (my & 2) | ((mx & 2) >> 1);
  810. if (!v->rnd)
  811. s->hdsp.avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
  812. else
  813. s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, 16);
  814. }
  815. if (s->flags & CODEC_FLAG_GRAY) return;
  816. /* Chroma MC always uses qpel blilinear */
  817. uvmx = (uvmx & 3) << 1;
  818. uvmy = (uvmy & 3) << 1;
  819. if (!v->rnd) {
  820. h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
  821. h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
  822. } else {
  823. v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
  824. v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
  825. }
  826. }