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