obmc32, obmc16, obmc8, obmc4
};
+static int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
+
typedef struct BlockNode{
int16_t mx;
int16_t my;
for(level=0; level<decomposition_count; level++){
switch(type){
- case 0: spatial_decompose97i(buffer, width>>level, height>>level, stride<<level); break;
- case 1: spatial_decompose53i(buffer, width>>level, height>>level, stride<<level); break;
- case 2: spatial_decomposeX (buffer, width>>level, height>>level, stride<<level); break;
+ case DWT_97: spatial_decompose97i(buffer, width>>level, height>>level, stride<<level); break;
+ case DWT_53: spatial_decompose53i(buffer, width>>level, height>>level, stride<<level); break;
+ case DWT_X: spatial_decomposeX (buffer, width>>level, height>>level, stride<<level); break;
}
}
}
int level;
for(level=decomposition_count-1; level>=0; level--){
switch(type){
- case 0: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
- case 1: spatial_compose53i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
+ case DWT_97: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
+ case DWT_53: spatial_compose53i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
/* not slicified yet */
- case 2: /*spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;*/
+ case DWT_X: /*spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;*/
av_log(NULL, AV_LOG_ERROR, "spatial_composeX neither buffered nor slicified yet.\n"); break;
}
}
int level;
for(level=decomposition_count-1; level>=0; level--){
switch(type){
- case 0: spatial_compose97i_init(cs+level, buffer, height>>level, stride<<level); break;
- case 1: spatial_compose53i_init(cs+level, buffer, height>>level, stride<<level); break;
+ case DWT_97: spatial_compose97i_init(cs+level, buffer, height>>level, stride<<level); break;
+ case DWT_53: spatial_compose53i_init(cs+level, buffer, height>>level, stride<<level); break;
/* not slicified yet */
- case 2: spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;
+ case DWT_X: spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;
}
}
}
for(level=decomposition_count-1; level>=0; level--){
while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
switch(type){
- case 0: spatial_compose97i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
+ case DWT_97: spatial_compose97i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
break;
- case 1: spatial_compose53i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
+ case DWT_53: spatial_compose53i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
break;
- case 2: break;
+ case DWT_X: break;
}
}
}
for(level=decomposition_count-1; level>=0; level--){
while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
switch(type){
- case 0: spatial_compose97i_dy_buffered(dsp, cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
+ case DWT_97: spatial_compose97i_dy_buffered(dsp, cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
break;
- case 1: spatial_compose53i_dy_buffered(cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
+ case DWT_53: spatial_compose53i_dy_buffered(cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
break;
- case 2: break;
+ case DWT_X: break;
}
}
}
assert(!ref_index);
}
+static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref,
+ BlockNode *left, BlockNode *top, BlockNode *tr){
+ if(s->ref_frames == 1){
+ *mx = mid_pred(left->mx, top->mx, tr->mx);
+ *my = mid_pred(left->my, top->my, tr->my);
+ }else{
+ const int *scale = scale_mv_ref[ref];
+ *mx = mid_pred(left->mx * scale[left->ref] + 128 >>8,
+ top ->mx * scale[top ->ref] + 128 >>8,
+ tr ->mx * scale[tr ->ref] + 128 >>8);
+ *my = mid_pred(left->my * scale[left->ref] + 128 >>8,
+ top ->my * scale[top ->ref] + 128 >>8,
+ tr ->my * scale[tr ->ref] + 128 >>8);
+ }
+}
+
//FIXME copy&paste
#define P_LEFT P[1]
#define P_TOP P[2]
int pl = left->color[0];
int pcb= left->color[1];
int pcr= left->color[2];
- int pmx= mid_pred(left->mx, top->mx, tr->mx);
- int pmy= mid_pred(left->my, top->my, tr->my);
+ int pmx, pmy;
int mx=0, my=0;
int l,cr,cb;
const int stride= s->current_picture.linesize[0];
assert(sizeof(s->block_state) >= 256);
if(s->keyframe){
- set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, 0, BLOCK_INTRA);
+ set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
return 0;
}
put_rac(&pc, &p_state[1 + left->type + top->type], 0);
if(s->ref_frames > 1)
put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0);
+ pred_mv(s, &pmx, &pmy, best_ref, left, top, tr);
put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1);
put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1);
p_len= pc.bytestream - pc.bytestream_start;
}
if(iscore < score){
+ pred_mv(s, &pmx, &pmy, 0, left, top, tr);
memcpy(pbbak, i_buffer, i_len);
s->c= ic;
s->c.bytestream_start= pbbak_start;
int pl = left->color[0];
int pcb= left->color[1];
int pcr= left->color[2];
- int pmx= mid_pred(left->mx, top->mx, tr->mx);
- int pmy= mid_pred(left->my, top->my, tr->my);
+ int pmx, pmy;
int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
int mx_context= av_log2(2*ABS(left->mx - top->mx)) + 16*!!b->ref;
int my_context= av_log2(2*ABS(left->my - top->my)) + 16*!!b->ref;
int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
if(s->keyframe){
- set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, 0, BLOCK_INTRA);
+ set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
return;
}
}
}
if(b->type & BLOCK_INTRA){
+ pred_mv(s, &pmx, &pmy, 0, left, top, tr);
put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1);
put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1);
put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1);
put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1);
set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA);
}else{
+ pred_mv(s, &pmx, &pmy, b->ref, left, top, tr);
put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0);
if(s->ref_frames > 1)
put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0);
type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
if(type){
+ pred_mv(s, &mx, &my, 0, left, top, tr);
l += get_symbol(&s->c, &s->block_state[32], 1);
cb+= get_symbol(&s->c, &s->block_state[64], 1);
cr+= get_symbol(&s->c, &s->block_state[96], 1);
}else{
if(s->ref_frames > 1)
ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
+ pred_mv(s, &mx, &my, ref, left, top, tr);
mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);
}
}
//FIXME name clenup (b_w, block_w, b_width stuff)
-static always_inline void add_yblock(SnowContext *s, DWTELEM *dst, uint8_t *dst8, uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){
+static always_inline void add_yblock(SnowContext *s, DWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){
const int b_width = s->b_width << s->block_max_depth;
const int b_height= s->b_height << s->block_max_depth;
const int b_stride= b_width;
if(x<0 || x>=b_stride || y>=b_height)
return 0;
- dmx= b->mx - mid_pred(left->mx, top->mx, tr->mx);
- dmy= b->my - mid_pred(left->my, top->my, tr->my);
/*
1 0 0
01X 1-2 1
return 3+2*( av_log2(2*ABS(left->color[0] - b->color[0]))
+ av_log2(2*ABS(left->color[1] - b->color[1]))
+ av_log2(2*ABS(left->color[2] - b->color[2])));
- }else
+ }else{
+ pred_mv(s, &dmx, &dmy, b->ref, left, top, tr);
+ dmx-= b->mx;
+ dmy-= b->my;
return 2*(1 + av_log2(2*ABS(dmx)) //FIXME kill the 2* can be merged in lambda
+ av_log2(2*ABS(dmy))
+ av_log2(2*b->ref));
+ }
}
static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){
BlockNode backup, ref_b;
const int index= mb_x + mb_y * b_stride;
BlockNode *block= &s->block[index];
- BlockNode *tb = mb_y ? &s->block[index-b_stride ] : &null_block;
- BlockNode *lb = mb_x ? &s->block[index -1] : &null_block;
- BlockNode *rb = mb_x+1<b_width ? &s->block[index +1] : &null_block;
- BlockNode *bb = mb_y+1<b_height ? &s->block[index+b_stride ] : &null_block;
- BlockNode *tlb= mb_x && mb_y ? &s->block[index-b_stride-1] : &null_block;
- BlockNode *trb= mb_x+1<b_width && mb_y ? &s->block[index-b_stride+1] : &null_block;
- BlockNode *blb= mb_x && mb_y+1<b_height ? &s->block[index+b_stride-1] : &null_block;
- BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : &null_block;
+ BlockNode *tb = mb_y ? &s->block[index-b_stride ] : NULL;
+ BlockNode *lb = mb_x ? &s->block[index -1] : NULL;
+ BlockNode *rb = mb_x+1<b_width ? &s->block[index +1] : NULL;
+ BlockNode *bb = mb_y+1<b_height ? &s->block[index+b_stride ] : NULL;
+ BlockNode *tlb= mb_x && mb_y ? &s->block[index-b_stride-1] : NULL;
+ BlockNode *trb= mb_x+1<b_width && mb_y ? &s->block[index-b_stride+1] : NULL;
+ BlockNode *blb= mb_x && mb_y+1<b_height ? &s->block[index+b_stride-1] : NULL;
+ BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : NULL;
const int b_w= (MB_SIZE >> s->block_max_depth);
uint8_t obmc_edged[b_w*2][b_w*2];
check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], *obmc_edged, &best_rd);
check_block_inter(s, mb_x, mb_y, 0, 0, *obmc_edged, &best_rd);
- if(tb!=&null_block)
+ if(tb)
check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], *obmc_edged, &best_rd);
- if(lb!=&null_block)
+ if(lb)
check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], *obmc_edged, &best_rd);
- if(rb!=&null_block)
+ if(rb)
check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], *obmc_edged, &best_rd);
- if(bb!=&null_block)
+ if(bb)
check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], *obmc_edged, &best_rd);
/* fullpel ME */
//FIXME RD style color selection
#endif
if(!same_block(block, &backup)){
- if(tb != &null_block) tb ->type &= ~BLOCK_OPT;
- if(lb != &null_block) lb ->type &= ~BLOCK_OPT;
- if(rb != &null_block) rb ->type &= ~BLOCK_OPT;
- if(bb != &null_block) bb ->type &= ~BLOCK_OPT;
- if(tlb!= &null_block) tlb->type &= ~BLOCK_OPT;
- if(trb!= &null_block) trb->type &= ~BLOCK_OPT;
- if(blb!= &null_block) blb->type &= ~BLOCK_OPT;
- if(brb!= &null_block) brb->type &= ~BLOCK_OPT;
+ if(tb ) tb ->type &= ~BLOCK_OPT;
+ if(lb ) lb ->type &= ~BLOCK_OPT;
+ if(rb ) rb ->type &= ~BLOCK_OPT;
+ if(bb ) bb ->type &= ~BLOCK_OPT;
+ if(tlb) tlb->type &= ~BLOCK_OPT;
+ if(trb) trb->type &= ~BLOCK_OPT;
+ if(blb) blb->type &= ~BLOCK_OPT;
+ if(brb) brb->type &= ~BLOCK_OPT;
change ++;
}
}
int change= 0;
for(mb_y= 0; mb_y<b_height; mb_y+=2){
for(mb_x= 0; mb_x<b_width; mb_x+=2){
- int dia_change, i, j;
+ int i;
int best_rd, init_rd;
const int index= mb_x + mb_y * b_stride;
BlockNode *b[4];
SnowContext *s = avctx->priv_data;
int width, height;
int level, orientation, plane_index, dec;
+ int i, j;
s->avctx= avctx;
}
}
+ for(i=0; i<MAX_REF_FRAMES; i++)
+ for(j=0; j<MAX_REF_FRAMES; j++)
+ scale_mv_ref[i][j] = 256*(i+1)/(j+1);
+
reset_contexts(s);
/*
width= s->width= avctx->width;
return -1;
}
+ if(avctx->prediction_method == DWT_97
+ && (avctx->flags & CODEC_FLAG_QSCALE)
+ && avctx->global_quality == 0){
+ av_log(avctx, AV_LOG_ERROR, "the 9/7 wavelet is incompatible with lossless mode\n");
+ return -1;
+ }
+
common_init(avctx);
alloc_blocks(s);
int x, y;
// int bits= put_bits_count(&s->c.pb);
+ if(!(avctx->flags2 & CODEC_FLAG2_MEMC_ONLY)){
//FIXME optimize
if(pict->data[plane_index]) //FIXME gray hack
for(y=0; y<h; y++){
{START_TIMER
predict_plane(s, s->spatial_dwt_buffer, plane_index, 1);
STOP_TIMER("pred-conv")}
+ }else{
+ //ME/MC only
+ if(pict->pict_type == I_TYPE){
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]=
+ pict->data[plane_index][y*pict->linesize[plane_index] + x];
+ }
+ }
+ }else{
+ memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
+ predict_plane(s, s->spatial_dwt_buffer, plane_index, 1);
+ }
+ }
if(s->avctx->flags&CODEC_FLAG_PSNR){
int64_t error= 0;