Libav
mpegvideo_xvmc.c
Go to the documentation of this file.
1 /*
2  * XVideo Motion Compensation
3  * Copyright (c) 2003 Ivan Kalvachev
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <limits.h>
23 #include <X11/extensions/XvMC.h>
24 
25 #include "avcodec.h"
26 #include "mpegutils.h"
27 #include "mpegvideo.h"
28 
29 #undef NDEBUG
30 #include <assert.h>
31 
32 #include "xvmc.h"
33 #include "xvmc_internal.h"
34 #include "version.h"
35 
36 #if FF_API_XVMC
37 
46 {
47  struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2];
48  assert(render && render->xvmc_id == AV_XVMC_ID);
49 
50  s->block = (int16_t (*)[64])(render->data_blocks + render->next_free_data_block_num * 64);
51 }
52 
57 void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp)
58 {
59  int i, j = 0;
60  const int mb_block_count = 4 + (1 << s->chroma_format);
61 
62  cbp <<= 12-mb_block_count;
63  for (i = 0; i < mb_block_count; i++) {
64  if (cbp & (1 << 11))
65  s->pblocks[i] = &s->block[j++];
66  else
67  s->pblocks[i] = NULL;
68  cbp += cbp;
69  }
70 }
71 
78 {
79  struct xvmc_pix_fmt *last, *next, *render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2];
80  const int mb_block_count = 4 + (1 << s->chroma_format);
81 
82  assert(avctx);
83  if (!render || render->xvmc_id != AV_XVMC_ID ||
84  !render->data_blocks || !render->mv_blocks ||
85  (unsigned int)render->allocated_mv_blocks > INT_MAX/(64*6) ||
86  (unsigned int)render->allocated_data_blocks > INT_MAX/64 ||
87  !render->p_surface) {
88  av_log(avctx, AV_LOG_ERROR,
89  "Render token doesn't look as expected.\n");
90  return -1; // make sure that this is a render packet
91  }
92 
93  if (render->filled_mv_blocks_num) {
94  av_log(avctx, AV_LOG_ERROR,
95  "Rendering surface contains %i unprocessed blocks.\n",
96  render->filled_mv_blocks_num);
97  return -1;
98  }
99  if (render->allocated_mv_blocks < 1 ||
100  render->allocated_data_blocks < render->allocated_mv_blocks*mb_block_count ||
101  render->start_mv_blocks_num >= render->allocated_mv_blocks ||
102  render->next_free_data_block_num >
103  render->allocated_data_blocks -
104  mb_block_count*(render->allocated_mv_blocks-render->start_mv_blocks_num)) {
105  av_log(avctx, AV_LOG_ERROR,
106  "Rendering surface doesn't provide enough block structures to work with.\n");
107  return -1;
108  }
109 
111  render->flags = s->first_field ? 0 : XVMC_SECOND_FIELD;
112  render->p_future_surface = NULL;
113  render->p_past_surface = NULL;
114 
115  switch(s->pict_type) {
116  case AV_PICTURE_TYPE_I:
117  return 0; // no prediction from other frames
118  case AV_PICTURE_TYPE_B:
119  next = (struct xvmc_pix_fmt*)s->next_picture.f->data[2];
120  if (!next)
121  return -1;
122  if (next->xvmc_id != AV_XVMC_ID)
123  return -1;
124  render->p_future_surface = next->p_surface;
125  // no return here, going to set forward prediction
126  case AV_PICTURE_TYPE_P:
127  last = (struct xvmc_pix_fmt*)s->last_picture.f->data[2];
128  if (!last)
129  last = render; // predict second field from the first
130  if (last->xvmc_id != AV_XVMC_ID)
131  return -1;
132  render->p_past_surface = last->p_surface;
133  return 0;
134  }
135 
136 return -1;
137 }
138 
146 {
147  struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2];
148  assert(render);
149 
150  if (render->filled_mv_blocks_num > 0)
151  ff_mpeg_draw_horiz_band(s, 0, 0);
152 }
153 
159 {
160  XvMCMacroBlock *mv_block;
161  struct xvmc_pix_fmt *render;
162  int i, cbp, blocks_per_mb;
163 
164  const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
165 
166 
167  if (s->encoding) {
168  av_log(s->avctx, AV_LOG_ERROR, "XVMC doesn't support encoding!!!\n");
169  return;
170  }
171 
172  // from ff_mpv_decode_mb(), update DC predictors for P macroblocks
173  if (!s->mb_intra) {
174  s->last_dc[0] =
175  s->last_dc[1] =
176  s->last_dc[2] = 128 << s->intra_dc_precision;
177  }
178 
179  // MC doesn't skip blocks
180  s->mb_skipped = 0;
181 
182 
183  // Do I need to export quant when I could not perform postprocessing?
184  // Anyway, it doesn't hurt.
185  s->current_picture.qscale_table[mb_xy] = s->qscale;
186 
187  // start of XVMC-specific code
188  render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2];
189  assert(render);
190  assert(render->xvmc_id == AV_XVMC_ID);
191  assert(render->mv_blocks);
192 
193  // take the next free macroblock
194  mv_block = &render->mv_blocks[render->start_mv_blocks_num +
195  render->filled_mv_blocks_num];
196 
197  mv_block->x = s->mb_x;
198  mv_block->y = s->mb_y;
199  mv_block->dct_type = s->interlaced_dct; // XVMC_DCT_TYPE_FRAME/FIELD;
200  if (s->mb_intra) {
201  mv_block->macroblock_type = XVMC_MB_TYPE_INTRA; // no MC, all done
202  } else {
203  mv_block->macroblock_type = XVMC_MB_TYPE_PATTERN;
204 
205  if (s->mv_dir & MV_DIR_FORWARD) {
206  mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD;
207  // PMV[n][dir][xy] = mv[dir][n][xy]
208  mv_block->PMV[0][0][0] = s->mv[0][0][0];
209  mv_block->PMV[0][0][1] = s->mv[0][0][1];
210  mv_block->PMV[1][0][0] = s->mv[0][1][0];
211  mv_block->PMV[1][0][1] = s->mv[0][1][1];
212  }
213  if (s->mv_dir & MV_DIR_BACKWARD) {
214  mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD;
215  mv_block->PMV[0][1][0] = s->mv[1][0][0];
216  mv_block->PMV[0][1][1] = s->mv[1][0][1];
217  mv_block->PMV[1][1][0] = s->mv[1][1][0];
218  mv_block->PMV[1][1][1] = s->mv[1][1][1];
219  }
220 
221  switch(s->mv_type) {
222  case MV_TYPE_16X16:
223  mv_block->motion_type = XVMC_PREDICTION_FRAME;
224  break;
225  case MV_TYPE_16X8:
226  mv_block->motion_type = XVMC_PREDICTION_16x8;
227  break;
228  case MV_TYPE_FIELD:
229  mv_block->motion_type = XVMC_PREDICTION_FIELD;
230  if (s->picture_structure == PICT_FRAME) {
231  mv_block->PMV[0][0][1] <<= 1;
232  mv_block->PMV[1][0][1] <<= 1;
233  mv_block->PMV[0][1][1] <<= 1;
234  mv_block->PMV[1][1][1] <<= 1;
235  }
236  break;
237  case MV_TYPE_DMV:
238  mv_block->motion_type = XVMC_PREDICTION_DUAL_PRIME;
239  if (s->picture_structure == PICT_FRAME) {
240 
241  mv_block->PMV[0][0][0] = s->mv[0][0][0]; // top from top
242  mv_block->PMV[0][0][1] = s->mv[0][0][1] << 1;
243 
244  mv_block->PMV[0][1][0] = s->mv[0][0][0]; // bottom from bottom
245  mv_block->PMV[0][1][1] = s->mv[0][0][1] << 1;
246 
247  mv_block->PMV[1][0][0] = s->mv[0][2][0]; // dmv00, top from bottom
248  mv_block->PMV[1][0][1] = s->mv[0][2][1] << 1; // dmv01
249 
250  mv_block->PMV[1][1][0] = s->mv[0][3][0]; // dmv10, bottom from top
251  mv_block->PMV[1][1][1] = s->mv[0][3][1] << 1; // dmv11
252 
253  } else {
254  mv_block->PMV[0][1][0] = s->mv[0][2][0]; // dmv00
255  mv_block->PMV[0][1][1] = s->mv[0][2][1]; // dmv01
256  }
257  break;
258  default:
259  assert(0);
260  }
261 
262  mv_block->motion_vertical_field_select = 0;
263 
264  // set correct field references
265  if (s->mv_type == MV_TYPE_FIELD || s->mv_type == MV_TYPE_16X8) {
266  mv_block->motion_vertical_field_select |= s->field_select[0][0];
267  mv_block->motion_vertical_field_select |= s->field_select[1][0] << 1;
268  mv_block->motion_vertical_field_select |= s->field_select[0][1] << 2;
269  mv_block->motion_vertical_field_select |= s->field_select[1][1] << 3;
270  }
271  } // !intra
272  // time to handle data blocks
273  mv_block->index = render->next_free_data_block_num;
274 
275  blocks_per_mb = 6;
276  if (s->chroma_format >= 2) {
277  blocks_per_mb = 4 + (1 << s->chroma_format);
278  }
279 
280  // calculate cbp
281  cbp = 0;
282  for (i = 0; i < blocks_per_mb; i++) {
283  cbp += cbp;
284  if (s->block_last_index[i] >= 0)
285  cbp++;
286  }
287 
288  if (s->flags & CODEC_FLAG_GRAY) {
289  if (s->mb_intra) { // intra frames are always full chroma blocks
290  for (i = 4; i < blocks_per_mb; i++) {
291  memset(s->pblocks[i], 0, sizeof(*s->pblocks[i])); // so we need to clear them
292  if (!render->unsigned_intra)
293  *s->pblocks[i][0] = 1 << 10;
294  }
295  } else {
296  cbp &= 0xf << (blocks_per_mb - 4);
297  blocks_per_mb = 4; // luminance blocks only
298  }
299  }
300  mv_block->coded_block_pattern = cbp;
301  if (cbp == 0)
302  mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN;
303 
304  for (i = 0; i < blocks_per_mb; i++) {
305  if (s->block_last_index[i] >= 0) {
306  // I do not have unsigned_intra MOCO to test, hope it is OK.
307  if (s->mb_intra && (render->idct || !render->unsigned_intra))
308  *s->pblocks[i][0] -= 1 << 10;
309  if (!render->idct) {
310  s->idsp.idct(*s->pblocks[i]);
311  /* It is unclear if MC hardware requires pixel diff values to be
312  * in the range [-255;255]. TODO: Clipping if such hardware is
313  * ever found. As of now it would only be an unnecessary
314  * slowdown. */
315  }
316  // copy blocks only if the codec doesn't support pblocks reordering
317  if (s->avctx->xvmc_acceleration == 1) {
318  memcpy(&render->data_blocks[render->next_free_data_block_num*64],
319  s->pblocks[i], sizeof(*s->pblocks[i]));
320  }
321  render->next_free_data_block_num++;
322  }
323  }
324  render->filled_mv_blocks_num++;
325 
326  assert(render->filled_mv_blocks_num <= render->allocated_mv_blocks);
327  assert(render->next_free_data_block_num <= render->allocated_data_blocks);
328  /* The above conditions should not be able to fail as long as this function
329  * is used and the following 'if ()' automatically calls a callback to free
330  * blocks. */
331 
332 
333  if (render->filled_mv_blocks_num == render->allocated_mv_blocks)
334  ff_mpeg_draw_horiz_band(s, 0, 0);
335 }
336 
337 #endif /* FF_API_XVMC */
int ff_xvmc_field_start(MpegEncContext *s, AVCodecContext *avctx)
IDCTDSPContext idsp
Definition: mpegvideo.h:354
#define MV_TYPE_FIELD
2 vectors, one per field
Definition: mpegvideo.h:391
int filled_mv_blocks_num
Number of new macroblock descriptions in the mv_blocks array (after start_mv_blocks_num) that are fil...
Definition: xvmc.h:153
int allocated_data_blocks
Number of blocks that can be stored at once in the data_blocks array.
Definition: xvmc.h:85
mpegvideo header.
int allocated_mv_blocks
Number of macroblock descriptions that can be stored in the mv_blocks array.
Definition: xvmc.h:79
int qscale
QP.
Definition: mpegvideo.h:332
int encoding
true if we are encoding (vs decoding)
Definition: mpegvideo.h:237
unsigned int flags
XVMC_SECOND_FIELD - 1st or 2nd field in the sequence.
Definition: xvmc.h:134
int field_select[2][2]
Definition: mpegvideo.h:399
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
Definition: mpegvideo.c:2361
void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp)
int interlaced_dct
Definition: mpegvideo.h:589
Picture current_picture
copy of the current picture structure.
Definition: mpegvideo.h:306
int intra_dc_precision
Definition: mpegvideo.h:572
#define AV_XVMC_ID
special value to ensure that regular pixel routines haven't corrupted the struct the number is 1337 s...
Definition: xvmc.h:45
Libavcodec version macros.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
int last_dc[3]
last DC values for MPEG1
Definition: mpegvideo.h:311
int next_free_data_block_num
Number of the next free data block; one data block consists of 64 short values in the data_blocks arr...
Definition: xvmc.h:166
int mb_skipped
MUST BE SET only during DECODING.
Definition: mpegvideo.h:321
unsigned int picture_structure
top/bottom field or frame
Definition: xvmc.h:128
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:168
int16_t(*[12] pblocks)[64]
Definition: mpegvideo.h:598
int block_last_index[12]
last non zero coefficient in block
Definition: mpegvideo.h:209
int xvmc_id
The field contains the special constant value AV_XVMC_ID.
Definition: xvmc.h:56
void ff_xvmc_init_block(MpegEncContext *s)
if(ac->has_optimized_func)
int first_field
is 1 for the first field of a field picture 0 otherwise
Definition: mpegvideo.h:590
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:388
NULL
Definition: eval.c:55
#define MV_DIR_BACKWARD
Definition: mpegvideo.h:385
Libavcodec external API header.
main external API structure.
Definition: avcodec.h:1050
XvMCMacroBlock * mv_blocks
Pointer to the macroblock description array allocated by XvMCCreateMacroBlocks() and freed by XvMCDes...
Definition: xvmc.h:72
#define MV_TYPE_16X8
2 vectors, one per 16x8 block
Definition: mpegvideo.h:390
Public libavcodec XvMC header.
struct AVFrame * f
Definition: mpegvideo.h:100
#define MV_DIR_FORWARD
Definition: mpegvideo.h:384
int pict_type
AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
Definition: mpegvideo.h:339
int unsigned_intra
In MoCo mode it indicates that intra macroblocks are assumed to be in unsigned format; same as the XV...
Definition: xvmc.h:99
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:141
int mv[2][4][2]
motion vectors for a macroblock first coordinate : 0 = forward 1 = backward second " : depend...
Definition: mpegvideo.h:398
MpegEncContext.
Definition: mpegvideo.h:204
short * data_blocks
Pointer to the block array allocated by XvMCCreateBlocks().
Definition: xvmc.h:65
int8_t * qscale_table
Definition: mpegvideo.h:104
struct AVCodecContext * avctx
Definition: mpegvideo.h:221
XvMCSurface * p_past_surface
Set by the decoder before calling ff_draw_horiz_band(), needed by the XvMCRenderSurface function...
Definition: xvmc.h:116
int start_mv_blocks_num
Number of macroblock descriptions in the mv_blocks array that have already been passed to the hardwar...
Definition: xvmc.h:144
int mb_stride
mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11 ...
Definition: mpegvideo.h:256
#define CODEC_FLAG_GRAY
Only decode/encode grayscale.
Definition: avcodec.h:637
int idct
Indicate that the hardware would interpret data_blocks as IDCT coefficients and perform IDCT on them...
Definition: xvmc.h:92
Picture last_picture
copy of the previous picture structure.
Definition: mpegvideo.h:288
Bi-dir predicted.
Definition: avutil.h:255
#define PICT_FRAME
Definition: mpegutils.h:35
XvMCSurface * p_surface
Pointer to the surface allocated by XvMCCreateSurface().
Definition: xvmc.h:107
int picture_structure
Definition: mpegvideo.h:570
void ff_xvmc_decode_mb(MpegEncContext *s)
#define MV_TYPE_DMV
2 vectors, special mpeg2 Dual Prime Vectors
Definition: mpegvideo.h:392
int16_t(* block)[64]
points to one of the following blocks
Definition: mpegvideo.h:600
Picture next_picture
copy of the next picture structure.
Definition: mpegvideo.h:294
int flags
AVCodecContext.flags (HQ, MV4, ...)
Definition: mpegvideo.h:238
XvMCSurface * p_future_surface
Pointer to the surface used as future reference.
Definition: xvmc.h:122
void ff_xvmc_field_end(MpegEncContext *s)
Predicted.
Definition: avutil.h:254
void(* idct)(int16_t *block)
Definition: idctdsp.h:63