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.

311 lines
11KB

  1. /*
  2. * XVideo Motion Compensation
  3. * Copyright (c) 2003 Ivan Kalvachev
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <limits.h>
  22. #include "avcodec.h"
  23. #include "dsputil.h"
  24. #include "mpegvideo.h"
  25. #undef NDEBUG
  26. #include <assert.h>
  27. #include "xvmc.h"
  28. #include "xvmc_internal.h"
  29. /**
  30. * Initializes the block field of the MpegEncContext pointer passed as
  31. * parameter after making sure that the data is not corrupted.
  32. */
  33. void ff_xvmc_init_block(MpegEncContext *s)
  34. {
  35. struct xvmc_pixfmt_render *render = (struct xvmc_pixfmt_render*)s->current_picture.data[2];
  36. assert(render && render->unique_id == AV_XVMC_RENDER_MAGIC);
  37. s->block = (DCTELEM *)(render->data_blocks + render->next_free_data_block_num * 64);
  38. }
  39. void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp)
  40. {
  41. int i, j = 0;
  42. const int mb_block_count = 4 + (1 << s->chroma_format);
  43. cbp <<= 12-mb_block_count;
  44. for (i = 0; i < mb_block_count; i++) {
  45. if (cbp & (1 << 11))
  46. s->pblocks[i] = (short *)(&s->block[j++]);
  47. else
  48. s->pblocks[i] = NULL;
  49. cbp+=cbp;
  50. }
  51. }
  52. /**
  53. * This function should be called for every new field and/or frame.
  54. * It should be safe to call the function a few times for the same field.
  55. */
  56. int ff_xvmc_field_start(MpegEncContext*s, AVCodecContext *avctx)
  57. {
  58. struct xvmc_pixfmt_render *last, *next, *render = (struct xvmc_pixfmt_render*)s->current_picture.data[2];
  59. const int mb_block_count = 4 + (1 << s->chroma_format);
  60. assert(avctx);
  61. if (!render || render->unique_id != AV_XVMC_RENDER_MAGIC ||
  62. !render->data_blocks || !render->mv_blocks) {
  63. av_log(avctx, AV_LOG_ERROR,
  64. "Render token doesn't look as expected.\n");
  65. return -1; // make sure that this is a render packet
  66. }
  67. if (render->filled_mv_blocks_num) {
  68. av_log(avctx, AV_LOG_ERROR,
  69. "Rendering surface contains %i unprocessed blocks.\n",
  70. render->filled_mv_blocks_num);
  71. return -1;
  72. }
  73. if (render->total_number_of_mv_blocks < 1 ||
  74. render->total_number_of_data_blocks < mb_block_count) {
  75. av_log(avctx, AV_LOG_ERROR,
  76. "Rendering surface doesn't provide enough block structures to work with.\n");
  77. return -1;
  78. }
  79. render->picture_structure = s->picture_structure;
  80. render->flags = s->first_field ? 0 : XVMC_SECOND_FIELD;
  81. render->p_future_surface = NULL;
  82. render->p_past_surface = NULL;
  83. switch(s->pict_type) {
  84. case FF_I_TYPE:
  85. return 0; // no prediction from other frames
  86. case FF_B_TYPE:
  87. next = (struct xvmc_pixfmt_render*)s->next_picture.data[2];
  88. if (!next)
  89. return -1;
  90. if (next->unique_id != AV_XVMC_RENDER_MAGIC)
  91. return -1;
  92. render->p_future_surface = next->p_surface;
  93. // no return here, going to set forward prediction
  94. case FF_P_TYPE:
  95. last = (struct xvmc_pixfmt_render*)s->last_picture.data[2];
  96. if (!last)
  97. last = render; // predict second field from the first
  98. if (last->unique_id != AV_XVMC_RENDER_MAGIC)
  99. return -1;
  100. render->p_past_surface = last->p_surface;
  101. return 0;
  102. }
  103. return -1;
  104. }
  105. /**
  106. * This function should be called for every new field and/or frame.
  107. * It should be safe to call the function a few times for the same field.
  108. */
  109. void ff_xvmc_field_end(MpegEncContext *s)
  110. {
  111. struct xvmc_pixfmt_render *render = (struct xvmc_pixfmt_render*)s->current_picture.data[2];
  112. assert(render);
  113. if (render->filled_mv_blocks_num > 0)
  114. ff_draw_horiz_band(s, 0, 0);
  115. }
  116. void ff_xvmc_decode_mb(MpegEncContext *s)
  117. {
  118. XvMCMacroBlock *mv_block;
  119. struct xvmc_pixfmt_render *render;
  120. int i, cbp, blocks_per_mb;
  121. const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
  122. if (s->encoding) {
  123. av_log(s->avctx, AV_LOG_ERROR, "XVMC doesn't support encoding!!!\n");
  124. return;
  125. }
  126. // from MPV_decode_mb(), update DC predictors for P macroblocks
  127. if (!s->mb_intra) {
  128. s->last_dc[0] =
  129. s->last_dc[1] =
  130. s->last_dc[2] = 128 << s->intra_dc_precision;
  131. }
  132. // MC doesn't skip blocks
  133. s->mb_skipped = 0;
  134. // Do I need to export quant when I could not perform postprocessing?
  135. // Anyway, it doesn't hurt.
  136. s->current_picture.qscale_table[mb_xy] = s->qscale;
  137. // start of XVMC-specific code
  138. render = (struct xvmc_pixfmt_render*)s->current_picture.data[2];
  139. assert(render);
  140. assert(render->unique_id == AV_XVMC_RENDER_MAGIC);
  141. assert(render->mv_blocks);
  142. // take the next free macroblock
  143. mv_block = &render->mv_blocks[render->start_mv_blocks_num +
  144. render->filled_mv_blocks_num];
  145. mv_block->x = s->mb_x;
  146. mv_block->y = s->mb_y;
  147. mv_block->dct_type = s->interlaced_dct; // XVMC_DCT_TYPE_FRAME/FIELD;
  148. if (s->mb_intra) {
  149. mv_block->macroblock_type = XVMC_MB_TYPE_INTRA; // no MC, all done
  150. } else {
  151. mv_block->macroblock_type = XVMC_MB_TYPE_PATTERN;
  152. if (s->mv_dir & MV_DIR_FORWARD) {
  153. mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD;
  154. // PMV[n][dir][xy] = mv[dir][n][xy]
  155. mv_block->PMV[0][0][0] = s->mv[0][0][0];
  156. mv_block->PMV[0][0][1] = s->mv[0][0][1];
  157. mv_block->PMV[1][0][0] = s->mv[0][1][0];
  158. mv_block->PMV[1][0][1] = s->mv[0][1][1];
  159. }
  160. if (s->mv_dir & MV_DIR_BACKWARD) {
  161. mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD;
  162. mv_block->PMV[0][1][0] = s->mv[1][0][0];
  163. mv_block->PMV[0][1][1] = s->mv[1][0][1];
  164. mv_block->PMV[1][1][0] = s->mv[1][1][0];
  165. mv_block->PMV[1][1][1] = s->mv[1][1][1];
  166. }
  167. switch(s->mv_type) {
  168. case MV_TYPE_16X16:
  169. mv_block->motion_type = XVMC_PREDICTION_FRAME;
  170. break;
  171. case MV_TYPE_16X8:
  172. mv_block->motion_type = XVMC_PREDICTION_16x8;
  173. break;
  174. case MV_TYPE_FIELD:
  175. mv_block->motion_type = XVMC_PREDICTION_FIELD;
  176. if (s->picture_structure == PICT_FRAME) {
  177. mv_block->PMV[0][0][1] <<= 1;
  178. mv_block->PMV[1][0][1] <<= 1;
  179. mv_block->PMV[0][1][1] <<= 1;
  180. mv_block->PMV[1][1][1] <<= 1;
  181. }
  182. break;
  183. case MV_TYPE_DMV:
  184. mv_block->motion_type = XVMC_PREDICTION_DUAL_PRIME;
  185. if (s->picture_structure == PICT_FRAME) {
  186. mv_block->PMV[0][0][0] = s->mv[0][0][0]; // top from top
  187. mv_block->PMV[0][0][1] = s->mv[0][0][1] << 1;
  188. mv_block->PMV[0][1][0] = s->mv[0][0][0]; // bottom from bottom
  189. mv_block->PMV[0][1][1] = s->mv[0][0][1] << 1;
  190. mv_block->PMV[1][0][0] = s->mv[0][2][0]; // dmv00, top from bottom
  191. mv_block->PMV[1][0][1] = s->mv[0][2][1] << 1; // dmv01
  192. mv_block->PMV[1][1][0] = s->mv[0][3][0]; // dmv10, bottom from top
  193. mv_block->PMV[1][1][1] = s->mv[0][3][1] << 1; // dmv11
  194. } else {
  195. mv_block->PMV[0][1][0] = s->mv[0][2][0]; // dmv00
  196. mv_block->PMV[0][1][1] = s->mv[0][2][1]; // dmv01
  197. }
  198. break;
  199. default:
  200. assert(0);
  201. }
  202. mv_block->motion_vertical_field_select = 0;
  203. // set correct field references
  204. if (s->mv_type == MV_TYPE_FIELD || s->mv_type == MV_TYPE_16X8) {
  205. mv_block->motion_vertical_field_select |= s->field_select[0][0];
  206. mv_block->motion_vertical_field_select |= s->field_select[1][0] << 1;
  207. mv_block->motion_vertical_field_select |= s->field_select[0][1] << 2;
  208. mv_block->motion_vertical_field_select |= s->field_select[1][1] << 3;
  209. }
  210. } // !intra
  211. // time to handle data blocks
  212. mv_block->index = render->next_free_data_block_num;
  213. blocks_per_mb = 6;
  214. if (s->chroma_format >= 2) {
  215. blocks_per_mb = 4 + (1 << s->chroma_format);
  216. }
  217. // calculate cbp
  218. cbp = 0;
  219. for (i = 0; i < blocks_per_mb; i++) {
  220. cbp += cbp;
  221. if (s->block_last_index[i] >= 0)
  222. cbp++;
  223. }
  224. if (s->flags & CODEC_FLAG_GRAY) {
  225. if (s->mb_intra) { // intra frames are always full chroma blocks
  226. for (i = 4; i < blocks_per_mb; i++) {
  227. memset(s->pblocks[i], 0, sizeof(short)*64); // so we need to clear them
  228. if (!render->unsigned_intra)
  229. s->pblocks[i][0] = 1 << 10;
  230. }
  231. } else {
  232. cbp &= 0xf << (blocks_per_mb - 4);
  233. blocks_per_mb = 4; // luminance blocks only
  234. }
  235. }
  236. mv_block->coded_block_pattern = cbp;
  237. if (cbp == 0)
  238. mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN;
  239. for (i = 0; i < blocks_per_mb; i++) {
  240. if (s->block_last_index[i] >= 0) {
  241. // I do not have unsigned_intra MOCO to test, hope it is OK.
  242. if (s->mb_intra && (render->idct || (!render->idct && !render->unsigned_intra)))
  243. s->pblocks[i][0] -= 1 << 10;
  244. if (!render->idct) {
  245. s->dsp.idct(s->pblocks[i]);
  246. /* It is unclear if MC hardware requires pixel diff values to be
  247. * in the range [-255;255]. TODO: Clipping if such hardware is
  248. * ever found. As of now it would only be an unnecessary
  249. * slowdown. */
  250. }
  251. // copy blocks only if the codec doesn't support pblocks reordering
  252. if (s->avctx->xvmc_acceleration == 1) {
  253. memcpy(&render->data_blocks[render->next_free_data_block_num*64],
  254. s->pblocks[i], sizeof(short)*64);
  255. }
  256. render->next_free_data_block_num++;
  257. }
  258. }
  259. render->filled_mv_blocks_num++;
  260. assert(render->filled_mv_blocks_num <= render->total_number_of_mv_blocks);
  261. assert(render->next_free_data_block_num <= render->total_number_of_data_blocks);
  262. /* The above conditions should not be able to fail as long as this function
  263. * is used and the following 'if ()' automatically calls a callback to free
  264. * blocks. */
  265. if (render->filled_mv_blocks_num == render->total_number_of_mv_blocks)
  266. ff_draw_horiz_band(s, 0, 0);
  267. }