00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "avcodec.h"
00029 #include "get_bits.h"
00030 #include "golomb.h"
00031 #include "mathops.h"
00032 #include "cavs.h"
00033
00034 static const uint8_t alpha_tab[64] = {
00035 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3,
00036 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20,
00037 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
00038 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
00039 };
00040
00041 static const uint8_t beta_tab[64] = {
00042 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
00043 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
00044 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14,
00045 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
00046 };
00047
00048 static const uint8_t tc_tab[64] = {
00049 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00050 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
00051 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
00052 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
00053 };
00054
00057 static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
00058
00059 static const int8_t left_modifier_l[8] = { 0, -1, 6, -1, -1, 7, 6, 7 };
00060 static const int8_t top_modifier_l[8] = { -1, 1, 5, -1, -1, 5, 7, 7 };
00061 static const int8_t left_modifier_c[7] = { 5, -1, 2, -1, 6, 5, 6 };
00062 static const int8_t top_modifier_c[7] = { 4, 1, -1, -1, 4, 6, 6 };
00063
00064
00065
00066
00067
00068
00069
00070 static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b) {
00071 if((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA))
00072 return 2;
00073 if( (abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4) )
00074 return 1;
00075 if(b){
00076 mvP += MV_BWD_OFFS;
00077 mvQ += MV_BWD_OFFS;
00078 if( (abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4) )
00079 return 1;
00080 }else{
00081 if(mvP->ref != mvQ->ref)
00082 return 1;
00083 }
00084 return 0;
00085 }
00086
00087 #define SET_PARAMS \
00088 alpha = alpha_tab[av_clip(qp_avg + h->alpha_offset,0,63)]; \
00089 beta = beta_tab[av_clip(qp_avg + h->beta_offset, 0,63)]; \
00090 tc = tc_tab[av_clip(qp_avg + h->alpha_offset,0,63)];
00091
00104 void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type) {
00105 uint8_t bs[8];
00106 int qp_avg, alpha, beta, tc;
00107 int i;
00108
00109
00110 h->topleft_border_y = h->top_border_y[h->mbx*16+15];
00111 h->topleft_border_u = h->top_border_u[h->mbx*10+8];
00112 h->topleft_border_v = h->top_border_v[h->mbx*10+8];
00113 memcpy(&h->top_border_y[h->mbx*16], h->cy + 15* h->l_stride,16);
00114 memcpy(&h->top_border_u[h->mbx*10+1], h->cu + 7* h->c_stride,8);
00115 memcpy(&h->top_border_v[h->mbx*10+1], h->cv + 7* h->c_stride,8);
00116 for(i=0;i<8;i++) {
00117 h->left_border_y[i*2+1] = *(h->cy + 15 + (i*2+0)*h->l_stride);
00118 h->left_border_y[i*2+2] = *(h->cy + 15 + (i*2+1)*h->l_stride);
00119 h->left_border_u[i+1] = *(h->cu + 7 + i*h->c_stride);
00120 h->left_border_v[i+1] = *(h->cv + 7 + i*h->c_stride);
00121 }
00122 if(!h->loop_filter_disable) {
00123
00124 if(mb_type == I_8X8)
00125 memset(bs,2,8);
00126 else{
00127 memset(bs,0,8);
00128 if(ff_cavs_partition_flags[mb_type] & SPLITV){
00129 bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8);
00130 bs[3] = get_bs(&h->mv[MV_FWD_X2], &h->mv[MV_FWD_X3], mb_type > P_8X8);
00131 }
00132 if(ff_cavs_partition_flags[mb_type] & SPLITH){
00133 bs[6] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X2], mb_type > P_8X8);
00134 bs[7] = get_bs(&h->mv[MV_FWD_X1], &h->mv[MV_FWD_X3], mb_type > P_8X8);
00135 }
00136 bs[0] = get_bs(&h->mv[MV_FWD_A1], &h->mv[MV_FWD_X0], mb_type > P_8X8);
00137 bs[1] = get_bs(&h->mv[MV_FWD_A3], &h->mv[MV_FWD_X2], mb_type > P_8X8);
00138 bs[4] = get_bs(&h->mv[MV_FWD_B2], &h->mv[MV_FWD_X0], mb_type > P_8X8);
00139 bs[5] = get_bs(&h->mv[MV_FWD_B3], &h->mv[MV_FWD_X1], mb_type > P_8X8);
00140 }
00141 if(AV_RN64(bs)) {
00142 if(h->flags & A_AVAIL) {
00143 qp_avg = (h->qp + h->left_qp + 1) >> 1;
00144 SET_PARAMS;
00145 h->cdsp.cavs_filter_lv(h->cy,h->l_stride,alpha,beta,tc,bs[0],bs[1]);
00146 h->cdsp.cavs_filter_cv(h->cu,h->c_stride,alpha,beta,tc,bs[0],bs[1]);
00147 h->cdsp.cavs_filter_cv(h->cv,h->c_stride,alpha,beta,tc,bs[0],bs[1]);
00148 }
00149 qp_avg = h->qp;
00150 SET_PARAMS;
00151 h->cdsp.cavs_filter_lv(h->cy + 8,h->l_stride,alpha,beta,tc,bs[2],bs[3]);
00152 h->cdsp.cavs_filter_lh(h->cy + 8*h->l_stride,h->l_stride,alpha,beta,tc,
00153 bs[6],bs[7]);
00154
00155 if(h->flags & B_AVAIL) {
00156 qp_avg = (h->qp + h->top_qp[h->mbx] + 1) >> 1;
00157 SET_PARAMS;
00158 h->cdsp.cavs_filter_lh(h->cy,h->l_stride,alpha,beta,tc,bs[4],bs[5]);
00159 h->cdsp.cavs_filter_ch(h->cu,h->c_stride,alpha,beta,tc,bs[4],bs[5]);
00160 h->cdsp.cavs_filter_ch(h->cv,h->c_stride,alpha,beta,tc,bs[4],bs[5]);
00161 }
00162 }
00163 }
00164 h->left_qp = h->qp;
00165 h->top_qp[h->mbx] = h->qp;
00166 }
00167
00168 #undef SET_PARAMS
00169
00170
00171
00172
00173
00174
00175
00176 void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top,
00177 uint8_t **left, int block) {
00178 int i;
00179
00180 switch(block) {
00181 case 0:
00182 *left = h->left_border_y;
00183 h->left_border_y[0] = h->left_border_y[1];
00184 memset(&h->left_border_y[17],h->left_border_y[16],9);
00185 memcpy(&top[1],&h->top_border_y[h->mbx*16],16);
00186 top[17] = top[16];
00187 top[0] = top[1];
00188 if((h->flags & A_AVAIL) && (h->flags & B_AVAIL))
00189 h->left_border_y[0] = top[0] = h->topleft_border_y;
00190 break;
00191 case 1:
00192 *left = h->intern_border_y;
00193 for(i=0;i<8;i++)
00194 h->intern_border_y[i+1] = *(h->cy + 7 + i*h->l_stride);
00195 memset(&h->intern_border_y[9],h->intern_border_y[8],9);
00196 h->intern_border_y[0] = h->intern_border_y[1];
00197 memcpy(&top[1],&h->top_border_y[h->mbx*16+8],8);
00198 if(h->flags & C_AVAIL)
00199 memcpy(&top[9],&h->top_border_y[(h->mbx + 1)*16],8);
00200 else
00201 memset(&top[9],top[8],9);
00202 top[17] = top[16];
00203 top[0] = top[1];
00204 if(h->flags & B_AVAIL)
00205 h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx*16+7];
00206 break;
00207 case 2:
00208 *left = &h->left_border_y[8];
00209 memcpy(&top[1],h->cy + 7*h->l_stride,16);
00210 top[17] = top[16];
00211 top[0] = top[1];
00212 if(h->flags & A_AVAIL)
00213 top[0] = h->left_border_y[8];
00214 break;
00215 case 3:
00216 *left = &h->intern_border_y[8];
00217 for(i=0;i<8;i++)
00218 h->intern_border_y[i+9] = *(h->cy + 7 + (i+8)*h->l_stride);
00219 memset(&h->intern_border_y[17],h->intern_border_y[16],9);
00220 memcpy(&top[0],h->cy + 7 + 7*h->l_stride,9);
00221 memset(&top[9],top[8],9);
00222 break;
00223 }
00224 }
00225
00226 void ff_cavs_load_intra_pred_chroma(AVSContext *h) {
00227
00228 h->left_border_u[9] = h->left_border_u[8];
00229 h->left_border_v[9] = h->left_border_v[8];
00230 h->top_border_u[h->mbx*10+9] = h->top_border_u[h->mbx*10+8];
00231 h->top_border_v[h->mbx*10+9] = h->top_border_v[h->mbx*10+8];
00232 if(h->mbx && h->mby) {
00233 h->top_border_u[h->mbx*10] = h->left_border_u[0] = h->topleft_border_u;
00234 h->top_border_v[h->mbx*10] = h->left_border_v[0] = h->topleft_border_v;
00235 } else {
00236 h->left_border_u[0] = h->left_border_u[1];
00237 h->left_border_v[0] = h->left_border_v[1];
00238 h->top_border_u[h->mbx*10] = h->top_border_u[h->mbx*10+1];
00239 h->top_border_v[h->mbx*10] = h->top_border_v[h->mbx*10+1];
00240 }
00241 }
00242
00243 static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00244 int y;
00245 uint64_t a = AV_RN64(&top[1]);
00246 for(y=0;y<8;y++) {
00247 *((uint64_t *)(d+y*stride)) = a;
00248 }
00249 }
00250
00251 static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00252 int y;
00253 uint64_t a;
00254 for(y=0;y<8;y++) {
00255 a = left[y+1] * 0x0101010101010101ULL;
00256 *((uint64_t *)(d+y*stride)) = a;
00257 }
00258 }
00259
00260 static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00261 int y;
00262 uint64_t a = 0x8080808080808080ULL;
00263 for(y=0;y<8;y++)
00264 *((uint64_t *)(d+y*stride)) = a;
00265 }
00266
00267 static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00268 int x,y,ia;
00269 int ih = 0;
00270 int iv = 0;
00271 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00272
00273 for(x=0; x<4; x++) {
00274 ih += (x+1)*(top[5+x]-top[3-x]);
00275 iv += (x+1)*(left[5+x]-left[3-x]);
00276 }
00277 ia = (top[8]+left[8])<<4;
00278 ih = (17*ih+16)>>5;
00279 iv = (17*iv+16)>>5;
00280 for(y=0; y<8; y++)
00281 for(x=0; x<8; x++)
00282 d[y*stride+x] = cm[(ia+(x-3)*ih+(y-3)*iv+16)>>5];
00283 }
00284
00285 #define LOWPASS(ARRAY,INDEX) \
00286 (( ARRAY[(INDEX)-1] + 2*ARRAY[(INDEX)] + ARRAY[(INDEX)+1] + 2) >> 2)
00287
00288 static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00289 int x,y;
00290 for(y=0; y<8; y++)
00291 for(x=0; x<8; x++)
00292 d[y*stride+x] = (LOWPASS(top,x+1) + LOWPASS(left,y+1)) >> 1;
00293 }
00294
00295 static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00296 int x,y;
00297 for(y=0; y<8; y++)
00298 for(x=0; x<8; x++)
00299 d[y*stride+x] = (LOWPASS(top,x+y+2) + LOWPASS(left,x+y+2)) >> 1;
00300 }
00301
00302 static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00303 int x,y;
00304 for(y=0; y<8; y++)
00305 for(x=0; x<8; x++)
00306 if(x==y)
00307 d[y*stride+x] = (left[1]+2*top[0]+top[1]+2)>>2;
00308 else if(x>y)
00309 d[y*stride+x] = LOWPASS(top,x-y);
00310 else
00311 d[y*stride+x] = LOWPASS(left,y-x);
00312 }
00313
00314 static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00315 int x,y;
00316 for(y=0; y<8; y++)
00317 for(x=0; x<8; x++)
00318 d[y*stride+x] = LOWPASS(left,y+1);
00319 }
00320
00321 static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride) {
00322 int x,y;
00323 for(y=0; y<8; y++)
00324 for(x=0; x<8; x++)
00325 d[y*stride+x] = LOWPASS(top,x+1);
00326 }
00327
00328 #undef LOWPASS
00329
00330 static inline void modify_pred(const int8_t *mod_table, int *mode)
00331 {
00332 *mode = mod_table[*mode];
00333 if(*mode < 0) {
00334 av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n");
00335 *mode = 0;
00336 }
00337 }
00338
00339 void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv) {
00340
00341 h->pred_mode_Y[3] = h->pred_mode_Y[5];
00342 h->pred_mode_Y[6] = h->pred_mode_Y[8];
00343 h->top_pred_Y[h->mbx*2+0] = h->pred_mode_Y[7];
00344 h->top_pred_Y[h->mbx*2+1] = h->pred_mode_Y[8];
00345
00346
00347 if(!(h->flags & A_AVAIL)) {
00348 modify_pred(left_modifier_l, &h->pred_mode_Y[4]);
00349 modify_pred(left_modifier_l, &h->pred_mode_Y[7]);
00350 modify_pred(left_modifier_c, pred_mode_uv);
00351 }
00352 if(!(h->flags & B_AVAIL)) {
00353 modify_pred(top_modifier_l, &h->pred_mode_Y[4]);
00354 modify_pred(top_modifier_l, &h->pred_mode_Y[5]);
00355 modify_pred(top_modifier_c, pred_mode_uv);
00356 }
00357 }
00358
00359
00360
00361
00362
00363
00364
00365 static inline void mc_dir_part(AVSContext *h,Picture *pic,
00366 int chroma_height,int delta,int list,uint8_t *dest_y,
00367 uint8_t *dest_cb,uint8_t *dest_cr,int src_x_offset,
00368 int src_y_offset,qpel_mc_func *qpix_op,
00369 h264_chroma_mc_func chroma_op,cavs_vector *mv)
00370 {
00371 MpegEncContext * const s = &h->s;
00372 const int mx= mv->x + src_x_offset*8;
00373 const int my= mv->y + src_y_offset*8;
00374 const int luma_xy= (mx&3) + ((my&3)<<2);
00375 uint8_t * src_y = pic->f.data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
00376 uint8_t * src_cb = pic->f.data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
00377 uint8_t * src_cr = pic->f.data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
00378 int extra_width= 0;
00379 int extra_height= extra_width;
00380 int emu=0;
00381 const int full_mx= mx>>2;
00382 const int full_my= my>>2;
00383 const int pic_width = 16*h->mb_width;
00384 const int pic_height = 16*h->mb_height;
00385
00386 if(!pic->f.data[0])
00387 return;
00388 if(mx&7) extra_width -= 3;
00389 if(my&7) extra_height -= 3;
00390
00391 if( full_mx < 0-extra_width
00392 || full_my < 0-extra_height
00393 || full_mx + 16 > pic_width + extra_width
00394 || full_my + 16 > pic_height + extra_height){
00395 s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*h->l_stride, h->l_stride,
00396 16+5, 16+5, full_mx-2, full_my-2, pic_width, pic_height);
00397 src_y= s->edge_emu_buffer + 2 + 2*h->l_stride;
00398 emu=1;
00399 }
00400
00401 qpix_op[luma_xy](dest_y, src_y, h->l_stride);
00402
00403 if(emu){
00404 s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cb, h->c_stride,
00405 9, 9, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
00406 src_cb= s->edge_emu_buffer;
00407 }
00408 chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx&7, my&7);
00409
00410 if(emu){
00411 s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cr, h->c_stride,
00412 9, 9, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
00413 src_cr= s->edge_emu_buffer;
00414 }
00415 chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx&7, my&7);
00416 }
00417
00418 static inline void mc_part_std(AVSContext *h,int chroma_height,int delta,
00419 uint8_t *dest_y,uint8_t *dest_cb,uint8_t *dest_cr,
00420 int x_offset, int y_offset,qpel_mc_func *qpix_put,
00421 h264_chroma_mc_func chroma_put,qpel_mc_func *qpix_avg,
00422 h264_chroma_mc_func chroma_avg, cavs_vector *mv)
00423 {
00424 qpel_mc_func *qpix_op= qpix_put;
00425 h264_chroma_mc_func chroma_op= chroma_put;
00426
00427 dest_y += 2*x_offset + 2*y_offset*h->l_stride;
00428 dest_cb += x_offset + y_offset*h->c_stride;
00429 dest_cr += x_offset + y_offset*h->c_stride;
00430 x_offset += 8*h->mbx;
00431 y_offset += 8*h->mby;
00432
00433 if(mv->ref >= 0){
00434 Picture *ref= &h->DPB[mv->ref];
00435 mc_dir_part(h, ref, chroma_height, delta, 0,
00436 dest_y, dest_cb, dest_cr, x_offset, y_offset,
00437 qpix_op, chroma_op, mv);
00438
00439 qpix_op= qpix_avg;
00440 chroma_op= chroma_avg;
00441 }
00442
00443 if((mv+MV_BWD_OFFS)->ref >= 0){
00444 Picture *ref= &h->DPB[0];
00445 mc_dir_part(h, ref, chroma_height, delta, 1,
00446 dest_y, dest_cb, dest_cr, x_offset, y_offset,
00447 qpix_op, chroma_op, mv+MV_BWD_OFFS);
00448 }
00449 }
00450
00451 void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type) {
00452 if(ff_cavs_partition_flags[mb_type] == 0){
00453 mc_part_std(h, 8, 0, h->cy, h->cu, h->cv, 0, 0,
00454 h->cdsp.put_cavs_qpel_pixels_tab[0],
00455 h->s.dsp.put_h264_chroma_pixels_tab[0],
00456 h->cdsp.avg_cavs_qpel_pixels_tab[0],
00457 h->s.dsp.avg_h264_chroma_pixels_tab[0],&h->mv[MV_FWD_X0]);
00458 }else{
00459 mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 0,
00460 h->cdsp.put_cavs_qpel_pixels_tab[1],
00461 h->s.dsp.put_h264_chroma_pixels_tab[1],
00462 h->cdsp.avg_cavs_qpel_pixels_tab[1],
00463 h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X0]);
00464 mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 0,
00465 h->cdsp.put_cavs_qpel_pixels_tab[1],
00466 h->s.dsp.put_h264_chroma_pixels_tab[1],
00467 h->cdsp.avg_cavs_qpel_pixels_tab[1],
00468 h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X1]);
00469 mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 4,
00470 h->cdsp.put_cavs_qpel_pixels_tab[1],
00471 h->s.dsp.put_h264_chroma_pixels_tab[1],
00472 h->cdsp.avg_cavs_qpel_pixels_tab[1],
00473 h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X2]);
00474 mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 4,
00475 h->cdsp.put_cavs_qpel_pixels_tab[1],
00476 h->s.dsp.put_h264_chroma_pixels_tab[1],
00477 h->cdsp.avg_cavs_qpel_pixels_tab[1],
00478 h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X3]);
00479 }
00480 }
00481
00482
00483
00484
00485
00486
00487
00488 static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, cavs_vector *src, int distp) {
00489 int den = h->scale_den[src->ref];
00490
00491 *d_x = (src->x*distp*den + 256 + (src->x>>31)) >> 9;
00492 *d_y = (src->y*distp*den + 256 + (src->y>>31)) >> 9;
00493 }
00494
00495 static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP,
00496 cavs_vector *mvA, cavs_vector *mvB, cavs_vector *mvC) {
00497 int ax, ay, bx, by, cx, cy;
00498 int len_ab, len_bc, len_ca, len_mid;
00499
00500
00501 scale_mv(h, &ax, &ay, mvA, mvP->dist);
00502 scale_mv(h, &bx, &by, mvB, mvP->dist);
00503 scale_mv(h, &cx, &cy, mvC, mvP->dist);
00504
00505 len_ab = abs(ax - bx) + abs(ay - by);
00506 len_bc = abs(bx - cx) + abs(by - cy);
00507 len_ca = abs(cx - ax) + abs(cy - ay);
00508 len_mid = mid_pred(len_ab, len_bc, len_ca);
00509 if(len_mid == len_ab) {
00510 mvP->x = cx;
00511 mvP->y = cy;
00512 } else if(len_mid == len_bc) {
00513 mvP->x = ax;
00514 mvP->y = ay;
00515 } else {
00516 mvP->x = bx;
00517 mvP->y = by;
00518 }
00519 }
00520
00521 void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC,
00522 enum cavs_mv_pred mode, enum cavs_block size, int ref) {
00523 cavs_vector *mvP = &h->mv[nP];
00524 cavs_vector *mvA = &h->mv[nP-1];
00525 cavs_vector *mvB = &h->mv[nP-4];
00526 cavs_vector *mvC = &h->mv[nC];
00527 const cavs_vector *mvP2 = NULL;
00528
00529 mvP->ref = ref;
00530 mvP->dist = h->dist[mvP->ref];
00531 if(mvC->ref == NOT_AVAIL)
00532 mvC = &h->mv[nP-5];
00533 if((mode == MV_PRED_PSKIP) &&
00534 ((mvA->ref == NOT_AVAIL) || (mvB->ref == NOT_AVAIL) ||
00535 ((mvA->x | mvA->y | mvA->ref) == 0) ||
00536 ((mvB->x | mvB->y | mvB->ref) == 0) )) {
00537 mvP2 = &un_mv;
00538
00539 } else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) {
00540 mvP2= mvA;
00541 } else if((mvA->ref < 0) && (mvB->ref >= 0) && (mvC->ref < 0)) {
00542 mvP2= mvB;
00543 } else if((mvA->ref < 0) && (mvB->ref < 0) && (mvC->ref >= 0)) {
00544 mvP2= mvC;
00545 } else if(mode == MV_PRED_LEFT && mvA->ref == ref){
00546 mvP2= mvA;
00547 } else if(mode == MV_PRED_TOP && mvB->ref == ref){
00548 mvP2= mvB;
00549 } else if(mode == MV_PRED_TOPRIGHT && mvC->ref == ref){
00550 mvP2= mvC;
00551 }
00552 if(mvP2){
00553 mvP->x = mvP2->x;
00554 mvP->y = mvP2->y;
00555 }else
00556 mv_pred_median(h, mvP, mvA, mvB, mvC);
00557
00558 if(mode < MV_PRED_PSKIP) {
00559 mvP->x += get_se_golomb(&h->s.gb);
00560 mvP->y += get_se_golomb(&h->s.gb);
00561 }
00562 set_mvs(mvP,size);
00563 }
00564
00565
00566
00567
00568
00569
00570
00574 void ff_cavs_init_mb(AVSContext *h) {
00575 int i;
00576
00577
00578 for(i=0;i<3;i++) {
00579 h->mv[MV_FWD_B2+i] = h->top_mv[0][h->mbx*2+i];
00580 h->mv[MV_BWD_B2+i] = h->top_mv[1][h->mbx*2+i];
00581 }
00582 h->pred_mode_Y[1] = h->top_pred_Y[h->mbx*2+0];
00583 h->pred_mode_Y[2] = h->top_pred_Y[h->mbx*2+1];
00584
00585 if(!(h->flags & B_AVAIL)) {
00586 h->mv[MV_FWD_B2] = un_mv;
00587 h->mv[MV_FWD_B3] = un_mv;
00588 h->mv[MV_BWD_B2] = un_mv;
00589 h->mv[MV_BWD_B3] = un_mv;
00590 h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL;
00591 h->flags &= ~(C_AVAIL|D_AVAIL);
00592 } else if(h->mbx) {
00593 h->flags |= D_AVAIL;
00594 }
00595 if(h->mbx == h->mb_width-1)
00596 h->flags &= ~C_AVAIL;
00597
00598 if(!(h->flags & C_AVAIL)) {
00599 h->mv[MV_FWD_C2] = un_mv;
00600 h->mv[MV_BWD_C2] = un_mv;
00601 }
00602
00603 if(!(h->flags & D_AVAIL)) {
00604 h->mv[MV_FWD_D3] = un_mv;
00605 h->mv[MV_BWD_D3] = un_mv;
00606 }
00607 }
00608
00614 int ff_cavs_next_mb(AVSContext *h) {
00615 int i;
00616
00617 h->flags |= A_AVAIL;
00618 h->cy += 16;
00619 h->cu += 8;
00620 h->cv += 8;
00621
00622 for(i=0;i<=20;i+=4)
00623 h->mv[i] = h->mv[i+2];
00624
00625 h->top_mv[0][h->mbx*2+0] = h->mv[MV_FWD_X2];
00626 h->top_mv[0][h->mbx*2+1] = h->mv[MV_FWD_X3];
00627 h->top_mv[1][h->mbx*2+0] = h->mv[MV_BWD_X2];
00628 h->top_mv[1][h->mbx*2+1] = h->mv[MV_BWD_X3];
00629
00630 h->mbidx++;
00631 h->mbx++;
00632 if(h->mbx == h->mb_width) {
00633 h->flags = B_AVAIL|C_AVAIL;
00634
00635 h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
00636
00637 for(i=0;i<=20;i+=4)
00638 h->mv[i] = un_mv;
00639 h->mbx = 0;
00640 h->mby++;
00641
00642 h->cy = h->picture.f.data[0] + h->mby * 16 * h->l_stride;
00643 h->cu = h->picture.f.data[1] + h->mby * 8 * h->c_stride;
00644 h->cv = h->picture.f.data[2] + h->mby * 8 * h->c_stride;
00645 if(h->mby == h->mb_height) {
00646 return 0;
00647 }
00648 }
00649 return 1;
00650 }
00651
00652
00653
00654
00655
00656
00657
00658 void ff_cavs_init_pic(AVSContext *h) {
00659 int i;
00660
00661
00662 for(i=0;i<=20;i+=4)
00663 h->mv[i] = un_mv;
00664 h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
00665 set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
00666 h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
00667 set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
00668 h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
00669 h->cy = h->picture.f.data[0];
00670 h->cu = h->picture.f.data[1];
00671 h->cv = h->picture.f.data[2];
00672 h->l_stride = h->picture.f.linesize[0];
00673 h->c_stride = h->picture.f.linesize[1];
00674 h->luma_scan[2] = 8*h->l_stride;
00675 h->luma_scan[3] = 8*h->l_stride+8;
00676 h->mbx = h->mby = h->mbidx = 0;
00677 h->flags = 0;
00678 }
00679
00680
00681
00682
00683
00684
00685
00691 void ff_cavs_init_top_lines(AVSContext *h) {
00692
00693 h->top_qp = av_mallocz( h->mb_width);
00694 h->top_mv[0] = av_mallocz((h->mb_width*2+1)*sizeof(cavs_vector));
00695 h->top_mv[1] = av_mallocz((h->mb_width*2+1)*sizeof(cavs_vector));
00696 h->top_pred_Y = av_mallocz( h->mb_width*2*sizeof(*h->top_pred_Y));
00697 h->top_border_y = av_mallocz((h->mb_width+1)*16);
00698 h->top_border_u = av_mallocz( h->mb_width * 10);
00699 h->top_border_v = av_mallocz( h->mb_width * 10);
00700
00701
00702 h->col_mv = av_mallocz( h->mb_width*h->mb_height*4*sizeof(cavs_vector));
00703 h->col_type_base = av_mallocz(h->mb_width*h->mb_height);
00704 h->block = av_mallocz(64*sizeof(DCTELEM));
00705 }
00706
00707 av_cold int ff_cavs_init(AVCodecContext *avctx) {
00708 AVSContext *h = avctx->priv_data;
00709 MpegEncContext * const s = &h->s;
00710
00711 ff_MPV_decode_defaults(s);
00712 ff_cavsdsp_init(&h->cdsp, avctx);
00713 s->avctx = avctx;
00714
00715 avctx->pix_fmt= PIX_FMT_YUV420P;
00716
00717 h->luma_scan[0] = 0;
00718 h->luma_scan[1] = 8;
00719 h->intra_pred_l[ INTRA_L_VERT] = intra_pred_vert;
00720 h->intra_pred_l[ INTRA_L_HORIZ] = intra_pred_horiz;
00721 h->intra_pred_l[ INTRA_L_LP] = intra_pred_lp;
00722 h->intra_pred_l[ INTRA_L_DOWN_LEFT] = intra_pred_down_left;
00723 h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right;
00724 h->intra_pred_l[ INTRA_L_LP_LEFT] = intra_pred_lp_left;
00725 h->intra_pred_l[ INTRA_L_LP_TOP] = intra_pred_lp_top;
00726 h->intra_pred_l[ INTRA_L_DC_128] = intra_pred_dc_128;
00727 h->intra_pred_c[ INTRA_C_LP] = intra_pred_lp;
00728 h->intra_pred_c[ INTRA_C_HORIZ] = intra_pred_horiz;
00729 h->intra_pred_c[ INTRA_C_VERT] = intra_pred_vert;
00730 h->intra_pred_c[ INTRA_C_PLANE] = intra_pred_plane;
00731 h->intra_pred_c[ INTRA_C_LP_LEFT] = intra_pred_lp_left;
00732 h->intra_pred_c[ INTRA_C_LP_TOP] = intra_pred_lp_top;
00733 h->intra_pred_c[ INTRA_C_DC_128] = intra_pred_dc_128;
00734 h->mv[ 7] = un_mv;
00735 h->mv[19] = un_mv;
00736 return 0;
00737 }
00738
00739 av_cold int ff_cavs_end(AVCodecContext *avctx) {
00740 AVSContext *h = avctx->priv_data;
00741
00742 ff_MPV_common_end(&h->s);
00743
00744 av_free(h->top_qp);
00745 av_free(h->top_mv[0]);
00746 av_free(h->top_mv[1]);
00747 av_free(h->top_pred_Y);
00748 av_free(h->top_border_y);
00749 av_free(h->top_border_u);
00750 av_free(h->top_border_v);
00751 av_free(h->col_mv);
00752 av_free(h->col_type_base);
00753 av_free(h->block);
00754 return 0;
00755 }