00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <limits.h>
00021
00022
00023 #include "avcodec.h"
00024 #include "dsputil.h"
00025 #include "mpegvideo.h"
00026
00027 #undef NDEBUG
00028 #include <assert.h>
00029
00030 #ifdef USE_FASTMEMCPY
00031 #include "fastmemcpy.h"
00032 #endif
00033
00034 #ifdef HAVE_XVMC
00035
00036
00037
00038
00039
00040 #include "xvmc_render.h"
00041
00042
00043
00044
00045 inline void XVMC_init_block(MpegEncContext *s){
00046 xvmc_render_state_t * render;
00047 render = (xvmc_render_state_t*)s->current_picture.data[2];
00048 assert(render != NULL);
00049 if( (render == NULL) || (render->magic != MP_XVMC_RENDER_MAGIC) ){
00050 assert(0);
00051 return;
00052 }
00053 s->block =(DCTELEM *)(render->data_blocks+(render->next_free_data_block_num)*64);
00054 }
00055
00056 void XVMC_pack_pblocks(MpegEncContext *s, int cbp){
00057 int i,j;
00058 const int mb_block_count = 4+(1<<s->chroma_format);
00059
00060 j=0;
00061 cbp<<= 12-mb_block_count;
00062 for(i=0; i<mb_block_count; i++){
00063 if(cbp & (1<<11)) {
00064 s->pblocks[i] = (short *)(&s->block[(j++)]);
00065 }else{
00066 s->pblocks[i] = NULL;
00067 }
00068 cbp+=cbp;
00069
00070 }
00071 }
00072
00073
00074
00075 int XVMC_field_start(MpegEncContext*s, AVCodecContext *avctx){
00076 xvmc_render_state_t * render,* last, * next;
00077
00078 assert(avctx != NULL);
00079
00080 render = (xvmc_render_state_t*)s->current_picture.data[2];
00081 assert(render != NULL);
00082 if( (render == NULL) || (render->magic != MP_XVMC_RENDER_MAGIC) )
00083 return -1;
00084
00085 render->picture_structure = s->picture_structure;
00086 render->flags = (s->first_field)? 0: XVMC_SECOND_FIELD;
00087
00088
00089 assert(render->filled_mv_blocks_num==0);
00090
00091 render->p_future_surface = NULL;
00092 render->p_past_surface = NULL;
00093
00094 switch(s->pict_type){
00095 case I_TYPE:
00096 return 0;
00097 case B_TYPE:
00098 next = (xvmc_render_state_t*)s->next_picture.data[2];
00099 assert(next!=NULL);
00100 assert(next->state & MP_XVMC_STATE_PREDICTION);
00101 if(next == NULL) return -1;
00102 if(next->magic != MP_XVMC_RENDER_MAGIC) return -1;
00103 render->p_future_surface = next->p_surface;
00104
00105 case P_TYPE:
00106 last = (xvmc_render_state_t*)s->last_picture.data[2];
00107 if(last == NULL)
00108 last = render;
00109 if(last->magic != MP_XVMC_RENDER_MAGIC) return -1;
00110 assert(last->state & MP_XVMC_STATE_PREDICTION);
00111 render->p_past_surface = last->p_surface;
00112 return 0;
00113 }
00114
00115 return -1;
00116 }
00117
00118 void XVMC_field_end(MpegEncContext *s){
00119 xvmc_render_state_t * render;
00120 render = (xvmc_render_state_t*)s->current_picture.data[2];
00121 assert(render != NULL);
00122
00123 if(render->filled_mv_blocks_num > 0){
00124
00125 ff_draw_horiz_band(s,0,0);
00126 }
00127 }
00128
00129 void XVMC_decode_mb(MpegEncContext *s){
00130 XvMCMacroBlock * mv_block;
00131 xvmc_render_state_t * render;
00132 int i,cbp,blocks_per_mb;
00133
00134 const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
00135
00136
00137 if(s->encoding){
00138 av_log(s->avctx, AV_LOG_ERROR, "XVMC doesn't support encoding!!!\n");
00139 return -1;
00140 }
00141
00142
00143
00144 if (!s->mb_intra) {
00145 s->last_dc[0] =
00146 s->last_dc[1] =
00147 s->last_dc[2] = 128 << s->intra_dc_precision;
00148 }
00149
00150
00151 s->mb_skipped = 0;
00152
00153
00154
00155
00156 s->current_picture.qscale_table[mb_xy] = s->qscale;
00157
00158
00159 render = (xvmc_render_state_t*)s->current_picture.data[2];
00160 assert(render!=NULL);
00161 assert(render->magic==MP_XVMC_RENDER_MAGIC);
00162 assert(render->mv_blocks);
00163
00164
00165 mv_block = &render->mv_blocks[render->start_mv_blocks_num +
00166 render->filled_mv_blocks_num ];
00167
00168
00169
00170 mv_block->x = s->mb_x;
00171 mv_block->y = s->mb_y;
00172 mv_block->dct_type = s->interlaced_dct;
00173
00174 if(s->mb_intra){
00175 mv_block->macroblock_type = XVMC_MB_TYPE_INTRA;
00176 }else{
00177 mv_block->macroblock_type = XVMC_MB_TYPE_PATTERN;
00178
00179 if(s->mv_dir & MV_DIR_FORWARD){
00180 mv_block->macroblock_type|= XVMC_MB_TYPE_MOTION_FORWARD;
00181
00182 mv_block->PMV[0][0][0] = s->mv[0][0][0];
00183 mv_block->PMV[0][0][1] = s->mv[0][0][1];
00184 mv_block->PMV[1][0][0] = s->mv[0][1][0];
00185 mv_block->PMV[1][0][1] = s->mv[0][1][1];
00186 }
00187 if(s->mv_dir & MV_DIR_BACKWARD){
00188 mv_block->macroblock_type|=XVMC_MB_TYPE_MOTION_BACKWARD;
00189 mv_block->PMV[0][1][0] = s->mv[1][0][0];
00190 mv_block->PMV[0][1][1] = s->mv[1][0][1];
00191 mv_block->PMV[1][1][0] = s->mv[1][1][0];
00192 mv_block->PMV[1][1][1] = s->mv[1][1][1];
00193 }
00194
00195 switch(s->mv_type){
00196 case MV_TYPE_16X16:
00197 mv_block->motion_type = XVMC_PREDICTION_FRAME;
00198 break;
00199 case MV_TYPE_16X8:
00200 mv_block->motion_type = XVMC_PREDICTION_16x8;
00201 break;
00202 case MV_TYPE_FIELD:
00203 mv_block->motion_type = XVMC_PREDICTION_FIELD;
00204 if(s->picture_structure == PICT_FRAME){
00205 mv_block->PMV[0][0][1]<<=1;
00206 mv_block->PMV[1][0][1]<<=1;
00207 mv_block->PMV[0][1][1]<<=1;
00208 mv_block->PMV[1][1][1]<<=1;
00209 }
00210 break;
00211 case MV_TYPE_DMV:
00212 mv_block->motion_type = XVMC_PREDICTION_DUAL_PRIME;
00213 if(s->picture_structure == PICT_FRAME){
00214
00215 mv_block->PMV[0][0][0] = s->mv[0][0][0];
00216 mv_block->PMV[0][0][1] = s->mv[0][0][1]<<1;
00217
00218 mv_block->PMV[0][1][0] = s->mv[0][0][0];
00219 mv_block->PMV[0][1][1] = s->mv[0][0][1]<<1;
00220
00221 mv_block->PMV[1][0][0] = s->mv[0][2][0];
00222 mv_block->PMV[1][0][1] = s->mv[0][2][1]<<1;
00223
00224 mv_block->PMV[1][1][0] = s->mv[0][3][0];
00225 mv_block->PMV[1][1][1] = s->mv[0][3][1]<<1;
00226
00227 }else{
00228 mv_block->PMV[0][1][0] = s->mv[0][2][0];
00229 mv_block->PMV[0][1][1] = s->mv[0][2][1];
00230 }
00231 break;
00232 default:
00233 assert(0);
00234 }
00235
00236 mv_block->motion_vertical_field_select = 0;
00237
00238
00239 if(s->mv_type == MV_TYPE_FIELD || s->mv_type == MV_TYPE_16X8){
00240 if( s->field_select[0][0] ) mv_block->motion_vertical_field_select|=1;
00241 if( s->field_select[1][0] ) mv_block->motion_vertical_field_select|=2;
00242 if( s->field_select[0][1] ) mv_block->motion_vertical_field_select|=4;
00243 if( s->field_select[1][1] ) mv_block->motion_vertical_field_select|=8;
00244 }
00245 }
00246
00247 mv_block->index = render->next_free_data_block_num;
00248
00249 blocks_per_mb = 6;
00250 if( s->chroma_format >= 2){
00251 blocks_per_mb = 4 + (1 << (s->chroma_format));
00252 }
00253
00254
00255 cbp = 0;
00256 for(i=0; i<blocks_per_mb; i++) {
00257 cbp+= cbp;
00258 if(s->block_last_index[i] >= 0)
00259 cbp++;
00260 }
00261
00262 if(s->flags & CODEC_FLAG_GRAY){
00263 if(s->mb_intra){
00264 for(i=4; i<blocks_per_mb; i++){
00265 memset(s->pblocks[i],0,sizeof(short)*8*8);
00266 if(!render->unsigned_intra)
00267 s->pblocks[i][0] = 1<<10;
00268 }
00269 }else{
00270 cbp&= 0xf << (blocks_per_mb - 4);
00271 blocks_per_mb = 4;
00272 }
00273 }
00274 mv_block->coded_block_pattern = cbp;
00275 if(cbp == 0)
00276 mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN;
00277
00278 for(i=0; i<blocks_per_mb; i++){
00279 if(s->block_last_index[i] >= 0){
00280
00281 if( (s->mb_intra) && ( render->idct || (!render->idct && !render->unsigned_intra)) )
00282 s->pblocks[i][0]-=1<<10;
00283 if(!render->idct){
00284 s->dsp.idct(s->pblocks[i]);
00286 }
00287
00288 if(s->avctx->xvmc_acceleration == 1){
00289 memcpy(&render->data_blocks[(render->next_free_data_block_num)*64],
00290 s->pblocks[i],sizeof(short)*8*8);
00291 }else{
00292
00293
00294
00295
00296
00297
00298 }
00299 render->next_free_data_block_num++;
00300 }
00301 }
00302 render->filled_mv_blocks_num++;
00303
00304 assert(render->filled_mv_blocks_num <= render->total_number_of_mv_blocks);
00305 assert(render->next_free_data_block_num <= render->total_number_of_data_blocks);
00306
00307
00308 if(render->filled_mv_blocks_num >= render->total_number_of_mv_blocks)
00309 ff_draw_horiz_band(s,0,0);
00310
00311
00312
00313
00314 }
00315
00316 #endif