@@ -328,7 +328,7 @@ void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, | |||||
} | } | ||||
}else{ | }else{ | ||||
uint8_t *src= s->last_picture[block->ref].data[plane_index]; | uint8_t *src= s->last_picture[block->ref].data[plane_index]; | ||||
const int scale= plane_index ? s->mv_scale : 2*s->mv_scale; | |||||
const int scale= plane_index ? (2*s->mv_scale)>>s->chroma_h_shift : 2*s->mv_scale; | |||||
int mx= block->mx*scale; | int mx= block->mx*scale; | ||||
int my= block->my*scale; | int my= block->my*scale; | ||||
const int dx= mx&15; | const int dx= mx&15; | ||||
@@ -342,6 +342,9 @@ void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, | |||||
s->dsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h); | s->dsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h); | ||||
src= tmp + MB_SIZE; | src= tmp + MB_SIZE; | ||||
} | } | ||||
av_assert2(s->chroma_h_shift == s->chroma_v_shift); // only one mv_scale | |||||
// assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h); | // assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h); | ||||
// assert(!(b_w&(b_w-1))); | // assert(!(b_w&(b_w-1))); | ||||
assert(b_w>1 && b_h>1); | assert(b_w>1 && b_h>1); | ||||
@@ -513,8 +516,8 @@ static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *fr | |||||
for(p=0; p<3; p++){ | for(p=0; p<3; p++){ | ||||
int is_chroma= !!p; | int is_chroma= !!p; | ||||
int w= s->avctx->width >>is_chroma; | |||||
int h= s->avctx->height >>is_chroma; | |||||
int w= is_chroma ? s->avctx->width >>s->chroma_h_shift : s->avctx->width; | |||||
int h= is_chroma ? s->avctx->height>>s->chroma_v_shift : s->avctx->height; | |||||
int ls= frame->linesize[p]; | int ls= frame->linesize[p]; | ||||
uint8_t *src= frame->data[p]; | uint8_t *src= frame->data[p]; | ||||
@@ -573,11 +576,11 @@ int ff_snow_frame_start(SnowContext *s){ | |||||
s->current_picture.linesize[0], w , h , | s->current_picture.linesize[0], w , h , | ||||
EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); | EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); | ||||
s->dsp.draw_edges(s->current_picture.data[1], | s->dsp.draw_edges(s->current_picture.data[1], | ||||
s->current_picture.linesize[1], w>>1, h>>1, | |||||
EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM); | |||||
s->current_picture.linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift, | |||||
EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM); | |||||
s->dsp.draw_edges(s->current_picture.data[2], | s->dsp.draw_edges(s->current_picture.data[2], | ||||
s->current_picture.linesize[2], w>>1, h>>1, | |||||
EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM); | |||||
s->current_picture.linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift, | |||||
EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM); | |||||
} | } | ||||
ff_snow_release_buffer(s->avctx); | ff_snow_release_buffer(s->avctx); | ||||
@@ -404,20 +404,21 @@ static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int pl | |||||
const int mb_h= s->b_height << s->block_max_depth; | const int mb_h= s->b_height << s->block_max_depth; | ||||
int x, y, mb_x; | int x, y, mb_x; | ||||
int block_size = MB_SIZE >> s->block_max_depth; | int block_size = MB_SIZE >> s->block_max_depth; | ||||
int block_w = plane_index ? block_size/2 : block_size; | |||||
const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth]; | |||||
const int obmc_stride= plane_index ? block_size : 2*block_size; | |||||
int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; | |||||
int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; | |||||
const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; | |||||
const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; | |||||
int ref_stride= s->current_picture.linesize[plane_index]; | int ref_stride= s->current_picture.linesize[plane_index]; | ||||
uint8_t *dst8= s->current_picture.data[plane_index]; | uint8_t *dst8= s->current_picture.data[plane_index]; | ||||
int w= p->width; | int w= p->width; | ||||
int h= p->height; | int h= p->height; | ||||
av_assert2(s->chroma_h_shift == s->chroma_v_shift); // obmc params assume squares | |||||
if(s->keyframe || (s->avctx->debug&512)){ | if(s->keyframe || (s->avctx->debug&512)){ | ||||
if(mb_y==mb_h) | if(mb_y==mb_h) | ||||
return; | return; | ||||
if(add){ | if(add){ | ||||
for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){ | |||||
for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){ | |||||
for(x=0; x<w; x++){ | for(x=0; x<w; x++){ | ||||
int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1)); | int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1)); | ||||
v >>= FRAC_BITS; | v >>= FRAC_BITS; | ||||
@@ -426,7 +427,7 @@ static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int pl | |||||
} | } | ||||
} | } | ||||
}else{ | }else{ | ||||
for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){ | |||||
for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){ | |||||
for(x=0; x<w; x++){ | for(x=0; x<w; x++){ | ||||
buf[x + y*w]-= 128<<FRAC_BITS; | buf[x + y*w]-= 128<<FRAC_BITS; | ||||
} | } | ||||
@@ -439,8 +440,8 @@ static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int pl | |||||
for(mb_x=0; mb_x<=mb_w; mb_x++){ | for(mb_x=0; mb_x<=mb_w; mb_x++){ | ||||
add_yblock(s, 0, NULL, buf, dst8, obmc, | add_yblock(s, 0, NULL, buf, dst8, obmc, | ||||
block_w*mb_x - block_w/2, | block_w*mb_x - block_w/2, | ||||
block_w*mb_y - block_w/2, | |||||
block_w, block_w, | |||||
block_h*mb_y - block_h/2, | |||||
block_w, block_h, | |||||
w, h, | w, h, | ||||
w, ref_stride, obmc_stride, | w, ref_stride, obmc_stride, | ||||
mb_x - 1, mb_y - 1, | mb_x - 1, mb_y - 1, | ||||
@@ -460,6 +461,7 @@ static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, in | |||||
const int rem_depth= s->block_max_depth - level; | const int rem_depth= s->block_max_depth - level; | ||||
const int index= (x + y*w) << rem_depth; | const int index= (x + y*w) << rem_depth; | ||||
const int block_w= 1<<rem_depth; | const int block_w= 1<<rem_depth; | ||||
const int block_h= 1<<rem_depth; //FIXME "w!=h" | |||||
BlockNode block; | BlockNode block; | ||||
int i,j; | int i,j; | ||||
@@ -472,7 +474,7 @@ static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, in | |||||
block.type= type; | block.type= type; | ||||
block.level= level; | block.level= level; | ||||
for(j=0; j<block_w; j++){ | |||||
for(j=0; j<block_h; j++){ | |||||
for(i=0; i<block_w; i++){ | for(i=0; i<block_w; i++){ | ||||
s->block[index + i + j*w]= block; | s->block[index + i + j*w]= block; | ||||
} | } | ||||
@@ -480,10 +482,11 @@ static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, in | |||||
} | } | ||||
static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){ | static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){ | ||||
SnowContext *s = c->avctx->priv_data; | |||||
const int offset[3]= { | const int offset[3]= { | ||||
y*c-> stride + x, | y*c-> stride + x, | ||||
((y*c->uvstride + x)>>1), | |||||
((y*c->uvstride + x)>>1), | |||||
((y*c->uvstride + x)>>s->chroma_h_shift), | |||||
((y*c->uvstride + x)>>s->chroma_h_shift), | |||||
}; | }; | ||||
int i; | int i; | ||||
for(i=0; i<3; i++){ | for(i=0; i<3; i++){ | ||||
@@ -41,9 +41,10 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer | |||||
const int mb_h= s->b_height << s->block_max_depth; | const int mb_h= s->b_height << s->block_max_depth; | ||||
int x, y, mb_x; | int x, y, mb_x; | ||||
int block_size = MB_SIZE >> s->block_max_depth; | int block_size = MB_SIZE >> s->block_max_depth; | ||||
int block_w = plane_index ? block_size/2 : block_size; | |||||
const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth]; | |||||
int obmc_stride= plane_index ? block_size : 2*block_size; | |||||
int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; | |||||
int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; | |||||
const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; | |||||
int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; | |||||
int ref_stride= s->current_picture.linesize[plane_index]; | int ref_stride= s->current_picture.linesize[plane_index]; | ||||
uint8_t *dst8= s->current_picture.data[plane_index]; | uint8_t *dst8= s->current_picture.data[plane_index]; | ||||
int w= p->width; | int w= p->width; | ||||
@@ -54,7 +55,7 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer | |||||
return; | return; | ||||
if(add){ | if(add){ | ||||
for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){ | |||||
for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){ | |||||
// DWTELEM * line = slice_buffer_get_line(sb, y); | // DWTELEM * line = slice_buffer_get_line(sb, y); | ||||
IDWTELEM * line = sb->line[y]; | IDWTELEM * line = sb->line[y]; | ||||
for(x=0; x<w; x++){ | for(x=0; x<w; x++){ | ||||
@@ -66,7 +67,7 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer | |||||
} | } | ||||
} | } | ||||
}else{ | }else{ | ||||
for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){ | |||||
for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){ | |||||
// DWTELEM * line = slice_buffer_get_line(sb, y); | // DWTELEM * line = slice_buffer_get_line(sb, y); | ||||
IDWTELEM * line = sb->line[y]; | IDWTELEM * line = sb->line[y]; | ||||
for(x=0; x<w; x++){ | for(x=0; x<w; x++){ | ||||
@@ -82,8 +83,8 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer | |||||
for(mb_x=0; mb_x<=mb_w; mb_x++){ | for(mb_x=0; mb_x<=mb_w; mb_x++){ | ||||
add_yblock(s, 1, sb, old_buffer, dst8, obmc, | add_yblock(s, 1, sb, old_buffer, dst8, obmc, | ||||
block_w*mb_x - block_w/2, | block_w*mb_x - block_w/2, | ||||
block_w*mb_y - block_w/2, | |||||
block_w, block_w, | |||||
block_h*mb_y - block_h/2, | |||||
block_w, block_h, | |||||
w, h, | w, h, | ||||
w, ref_stride, obmc_stride, | w, ref_stride, obmc_stride, | ||||
mb_x - 1, mb_y - 1, | mb_x - 1, mb_y - 1, | ||||
@@ -289,6 +290,18 @@ static int decode_header(SnowContext *s){ | |||||
s->colorspace_type= get_symbol(&s->c, s->header_state, 0); | s->colorspace_type= get_symbol(&s->c, s->header_state, 0); | ||||
s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0); | s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0); | ||||
s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0); | s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0); | ||||
if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){ | |||||
s->avctx->pix_fmt= PIX_FMT_YUV420P; | |||||
}else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){ | |||||
s->avctx->pix_fmt= PIX_FMT_YUV444P; | |||||
} else { | |||||
av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift); | |||||
s->chroma_h_shift = s->chroma_v_shift = 1; | |||||
s->avctx->pix_fmt= PIX_FMT_YUV420P; | |||||
return AVERROR_INVALIDDATA; | |||||
} | |||||
s->spatial_scalability= get_rac(&s->c, s->header_state); | s->spatial_scalability= get_rac(&s->c, s->header_state); | ||||
// s->rate_scalability= get_rac(&s->c, s->header_state); | // s->rate_scalability= get_rac(&s->c, s->header_state); | ||||
GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES) | GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES) | ||||
@@ -334,10 +347,6 @@ static int decode_header(SnowContext *s){ | |||||
return -1; | return -1; | ||||
} | } | ||||
if (s->chroma_h_shift != 1 || s->chroma_v_shift != 1) { | |||||
av_log(s->avctx, AV_LOG_ERROR, "Invalid chroma shift\n"); | |||||
return AVERROR_PATCHWELCOME; | |||||
} | |||||
s->qlog += get_symbol(&s->c, s->header_state, 1); | s->qlog += get_symbol(&s->c, s->header_state, 1); | ||||
s->mv_scale += get_symbol(&s->c, s->header_state, 1); | s->mv_scale += get_symbol(&s->c, s->header_state, 1); | ||||
@@ -354,8 +363,6 @@ static int decode_header(SnowContext *s){ | |||||
static av_cold int decode_init(AVCodecContext *avctx) | static av_cold int decode_init(AVCodecContext *avctx) | ||||
{ | { | ||||
avctx->pix_fmt= PIX_FMT_YUV420P; | |||||
ff_snow_common_init(avctx); | ff_snow_common_init(avctx); | ||||
return 0; | return 0; | ||||
@@ -452,7 +459,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac | |||||
{ | { | ||||
const int mb_h= s->b_height << s->block_max_depth; | const int mb_h= s->b_height << s->block_max_depth; | ||||
const int block_size = MB_SIZE >> s->block_max_depth; | const int block_size = MB_SIZE >> s->block_max_depth; | ||||
const int block_w = plane_index ? block_size/2 : block_size; | |||||
const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; | |||||
const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; | |||||
int mb_y; | int mb_y; | ||||
DWTCompose cs[MAX_DECOMPOSITIONS]; | DWTCompose cs[MAX_DECOMPOSITIONS]; | ||||
int yd=0, yq=0; | int yd=0, yq=0; | ||||
@@ -462,11 +470,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac | |||||
ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count); | ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count); | ||||
for(mb_y=0; mb_y<=mb_h; mb_y++){ | for(mb_y=0; mb_y<=mb_h; mb_y++){ | ||||
int slice_starty = block_w*mb_y; | |||||
int slice_h = block_w*(mb_y+1); | |||||
int slice_starty = block_h*mb_y; | |||||
int slice_h = block_h*(mb_y+1); | |||||
if (!(s->keyframe || s->avctx->debug&512)){ | if (!(s->keyframe || s->avctx->debug&512)){ | ||||
slice_starty = FFMAX(0, slice_starty - (block_w >> 1)); | |||||
slice_h -= (block_w >> 1); | |||||
slice_starty = FFMAX(0, slice_starty - (block_h >> 1)); | |||||
slice_h -= (block_h >> 1); | |||||
} | } | ||||
for(level=0; level<s->spatial_decomposition_count; level++){ | for(level=0; level<s->spatial_decomposition_count; level++){ | ||||
@@ -477,11 +486,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac | |||||
int our_mb_start = mb_y; | int our_mb_start = mb_y; | ||||
int our_mb_end = (mb_y + 1); | int our_mb_end = (mb_y + 1); | ||||
const int extra= 3; | const int extra= 3; | ||||
start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0); | |||||
end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra); | |||||
start_y = (mb_y ? ((block_h * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0); | |||||
end_y = (((block_h * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra); | |||||
if (!(s->keyframe || s->avctx->debug&512)){ | if (!(s->keyframe || s->avctx->debug&512)){ | ||||
start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level))); | |||||
end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level))); | |||||
start_y = FFMAX(0, start_y - (block_h >> (1+s->spatial_decomposition_count - level))); | |||||
end_y = FFMAX(0, end_y - (block_h >> (1+s->spatial_decomposition_count - level))); | |||||
} | } | ||||
start_y = FFMIN(b->height, start_y); | start_y = FFMIN(b->height, start_y); | ||||
end_y = FFMIN(b->height, end_y); | end_y = FFMIN(b->height, end_y); | ||||
@@ -215,7 +215,7 @@ static av_cold int encode_init(AVCodecContext *avctx) | |||||
avctx->coded_frame= &s->current_picture; | avctx->coded_frame= &s->current_picture; | ||||
switch(avctx->pix_fmt){ | switch(avctx->pix_fmt){ | ||||
// case PIX_FMT_YUV444P: | |||||
case PIX_FMT_YUV444P: | |||||
// case PIX_FMT_YUV422P: | // case PIX_FMT_YUV422P: | ||||
case PIX_FMT_YUV420P: | case PIX_FMT_YUV420P: | ||||
// case PIX_FMT_GRAY8: | // case PIX_FMT_GRAY8: | ||||
@@ -323,8 +323,8 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ | |||||
const int stride= s->current_picture.linesize[0]; | const int stride= s->current_picture.linesize[0]; | ||||
const int uvstride= s->current_picture.linesize[1]; | const int uvstride= s->current_picture.linesize[1]; | ||||
uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y* stride)*block_w, | uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y* stride)*block_w, | ||||
s->input_picture.data[1] + (x + y*uvstride)*block_w/2, | |||||
s->input_picture.data[2] + (x + y*uvstride)*block_w/2}; | |||||
s->input_picture.data[1] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift), | |||||
s->input_picture.data[2] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift)}; | |||||
int P[10][2]; | int P[10][2]; | ||||
int16_t last_mv[3][2]; | int16_t last_mv[3][2]; | ||||
int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused | int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused | ||||
@@ -574,9 +574,10 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ | |||||
int i, x2, y2; | int i, x2, y2; | ||||
Plane *p= &s->plane[plane_index]; | Plane *p= &s->plane[plane_index]; | ||||
const int block_size = MB_SIZE >> s->block_max_depth; | const int block_size = MB_SIZE >> s->block_max_depth; | ||||
const int block_w = plane_index ? block_size/2 : block_size; | |||||
const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth]; | |||||
const int obmc_stride= plane_index ? block_size : 2*block_size; | |||||
const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; | |||||
const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; | |||||
const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; | |||||
const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; | |||||
const int ref_stride= s->current_picture.linesize[plane_index]; | const int ref_stride= s->current_picture.linesize[plane_index]; | ||||
uint8_t *src= s-> input_picture.data[plane_index]; | uint8_t *src= s-> input_picture.data[plane_index]; | ||||
IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned | IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned | ||||
@@ -589,6 +590,8 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ | |||||
int ab=0; | int ab=0; | ||||
int aa=0; | int aa=0; | ||||
av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc stuff above | |||||
b->type|= BLOCK_INTRA; | b->type|= BLOCK_INTRA; | ||||
b->color[plane_index]= 0; | b->color[plane_index]= 0; | ||||
memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM)); | memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM)); | ||||
@@ -597,19 +600,19 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ | |||||
int mb_x2= mb_x + (i &1) - 1; | int mb_x2= mb_x + (i &1) - 1; | ||||
int mb_y2= mb_y + (i>>1) - 1; | int mb_y2= mb_y + (i>>1) - 1; | ||||
int x= block_w*mb_x2 + block_w/2; | int x= block_w*mb_x2 + block_w/2; | ||||
int y= block_w*mb_y2 + block_w/2; | |||||
int y= block_h*mb_y2 + block_h/2; | |||||
add_yblock(s, 0, NULL, dst + ((i&1)+(i>>1)*obmc_stride)*block_w, NULL, obmc, | |||||
x, y, block_w, block_w, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index); | |||||
add_yblock(s, 0, NULL, dst + (i&1)*block_w + (i>>1)*obmc_stride*block_h, NULL, obmc, | |||||
x, y, block_w, block_h, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index); | |||||
for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_w); y2++){ | |||||
for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_h); y2++){ | |||||
for(x2= FFMAX(x, 0); x2<FFMIN(w, x+block_w); x2++){ | for(x2= FFMAX(x, 0); x2<FFMIN(w, x+block_w); x2++){ | ||||
int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_w*mb_y - block_w/2))*obmc_stride; | |||||
int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_h*mb_y - block_h/2))*obmc_stride; | |||||
int obmc_v= obmc[index]; | int obmc_v= obmc[index]; | ||||
int d; | int d; | ||||
if(y<0) obmc_v += obmc[index + block_w*obmc_stride]; | |||||
if(y<0) obmc_v += obmc[index + block_h*obmc_stride]; | |||||
if(x<0) obmc_v += obmc[index + block_w]; | if(x<0) obmc_v += obmc[index + block_w]; | ||||
if(y+block_w>h) obmc_v += obmc[index - block_w*obmc_stride]; | |||||
if(y+block_h>h) obmc_v += obmc[index - block_h*obmc_stride]; | |||||
if(x+block_w>w) obmc_v += obmc[index - block_w]; | if(x+block_w>w) obmc_v += obmc[index - block_w]; | ||||
//FIXME precalculate this or simplify it somehow else | //FIXME precalculate this or simplify it somehow else | ||||
@@ -666,8 +669,9 @@ static inline int get_block_bits(SnowContext *s, int x, int y, int w){ | |||||
static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){ | static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){ | ||||
Plane *p= &s->plane[plane_index]; | Plane *p= &s->plane[plane_index]; | ||||
const int block_size = MB_SIZE >> s->block_max_depth; | const int block_size = MB_SIZE >> s->block_max_depth; | ||||
const int block_w = plane_index ? block_size/2 : block_size; | |||||
const int obmc_stride= plane_index ? block_size : 2*block_size; | |||||
const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; | |||||
const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; | |||||
const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; | |||||
const int ref_stride= s->current_picture.linesize[plane_index]; | const int ref_stride= s->current_picture.linesize[plane_index]; | ||||
uint8_t *dst= s->current_picture.data[plane_index]; | uint8_t *dst= s->current_picture.data[plane_index]; | ||||
uint8_t *src= s-> input_picture.data[plane_index]; | uint8_t *src= s-> input_picture.data[plane_index]; | ||||
@@ -682,14 +686,16 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con | |||||
int rate= 0; | int rate= 0; | ||||
const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp); | const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp); | ||||
int sx= block_w*mb_x - block_w/2; | int sx= block_w*mb_x - block_w/2; | ||||
int sy= block_w*mb_y - block_w/2; | |||||
int sy= block_h*mb_y - block_h/2; | |||||
int x0= FFMAX(0,-sx); | int x0= FFMAX(0,-sx); | ||||
int y0= FFMAX(0,-sy); | int y0= FFMAX(0,-sy); | ||||
int x1= FFMIN(block_w*2, w-sx); | int x1= FFMIN(block_w*2, w-sx); | ||||
int y1= FFMIN(block_w*2, h-sy); | |||||
int y1= FFMIN(block_h*2, h-sy); | |||||
int i,x,y; | int i,x,y; | ||||
ff_snow_pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_w*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h); | |||||
av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc and square assumtions below chckinhg only block_w | |||||
ff_snow_pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_h*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h); | |||||
for(y=y0; y<y1; y++){ | for(y=y0; y<y1; y++){ | ||||
const uint8_t *obmc1= obmc_edged + y*obmc_stride; | const uint8_t *obmc1= obmc_edged + y*obmc_stride; | ||||
@@ -717,9 +723,9 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con | |||||
else | else | ||||
x0 = block_w; | x0 = block_w; | ||||
if(mb_y == 0) | if(mb_y == 0) | ||||
y1 = block_w; | |||||
y1 = block_h; | |||||
else | else | ||||
y0 = block_w; | |||||
y0 = block_h; | |||||
for(y=y0; y<y1; y++) | for(y=y0; y<y1; y++) | ||||
memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0); | memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0); | ||||
} | } | ||||
@@ -765,9 +771,10 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ | |||||
int i, y2; | int i, y2; | ||||
Plane *p= &s->plane[plane_index]; | Plane *p= &s->plane[plane_index]; | ||||
const int block_size = MB_SIZE >> s->block_max_depth; | const int block_size = MB_SIZE >> s->block_max_depth; | ||||
const int block_w = plane_index ? block_size/2 : block_size; | |||||
const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth]; | |||||
const int obmc_stride= plane_index ? block_size : 2*block_size; | |||||
const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; | |||||
const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; | |||||
const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; | |||||
const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; | |||||
const int ref_stride= s->current_picture.linesize[plane_index]; | const int ref_stride= s->current_picture.linesize[plane_index]; | ||||
uint8_t *dst= s->current_picture.data[plane_index]; | uint8_t *dst= s->current_picture.data[plane_index]; | ||||
uint8_t *src= s-> input_picture.data[plane_index]; | uint8_t *src= s-> input_picture.data[plane_index]; | ||||
@@ -781,31 +788,33 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ | |||||
int rate= 0; | int rate= 0; | ||||
const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp); | const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp); | ||||
av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc and square assumtions below | |||||
for(i=0; i<9; i++){ | for(i=0; i<9; i++){ | ||||
int mb_x2= mb_x + (i%3) - 1; | int mb_x2= mb_x + (i%3) - 1; | ||||
int mb_y2= mb_y + (i/3) - 1; | int mb_y2= mb_y + (i/3) - 1; | ||||
int x= block_w*mb_x2 + block_w/2; | int x= block_w*mb_x2 + block_w/2; | ||||
int y= block_w*mb_y2 + block_w/2; | |||||
int y= block_h*mb_y2 + block_h/2; | |||||
add_yblock(s, 0, NULL, zero_dst, dst, obmc, | add_yblock(s, 0, NULL, zero_dst, dst, obmc, | ||||
x, y, block_w, block_w, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index); | |||||
x, y, block_w, block_h, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index); | |||||
//FIXME find a cleaner/simpler way to skip the outside stuff | //FIXME find a cleaner/simpler way to skip the outside stuff | ||||
for(y2= y; y2<0; y2++) | for(y2= y; y2<0; y2++) | ||||
memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w); | memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w); | ||||
for(y2= h; y2<y+block_w; y2++) | |||||
for(y2= h; y2<y+block_h; y2++) | |||||
memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w); | memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w); | ||||
if(x<0){ | if(x<0){ | ||||
for(y2= y; y2<y+block_w; y2++) | |||||
for(y2= y; y2<y+block_h; y2++) | |||||
memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x); | memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x); | ||||
} | } | ||||
if(x+block_w > w){ | if(x+block_w > w){ | ||||
for(y2= y; y2<y+block_w; y2++) | |||||
for(y2= y; y2<y+block_h; y2++) | |||||
memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w); | memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w); | ||||
} | } | ||||
assert(block_w== 8 || block_w==16); | assert(block_w== 8 || block_w==16); | ||||
distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_w); | |||||
distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h); | |||||
} | } | ||||
if(plane_index==0){ | if(plane_index==0){ | ||||
@@ -1116,22 +1125,23 @@ static void iterative_me(SnowContext *s){ | |||||
uint8_t *dst= s->current_picture.data[0]; | uint8_t *dst= s->current_picture.data[0]; | ||||
const int stride= s->current_picture.linesize[0]; | const int stride= s->current_picture.linesize[0]; | ||||
const int block_w= MB_SIZE >> s->block_max_depth; | const int block_w= MB_SIZE >> s->block_max_depth; | ||||
const int block_h= MB_SIZE >> s->block_max_depth; | |||||
const int sx= block_w*mb_x - block_w/2; | const int sx= block_w*mb_x - block_w/2; | ||||
const int sy= block_w*mb_y - block_w/2; | |||||
const int sy= block_h*mb_y - block_h/2; | |||||
const int w= s->plane[0].width; | const int w= s->plane[0].width; | ||||
const int h= s->plane[0].height; | const int h= s->plane[0].height; | ||||
int y; | int y; | ||||
for(y=sy; y<0; y++) | for(y=sy; y<0; y++) | ||||
memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2); | memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2); | ||||
for(y=h; y<sy+block_w*2; y++) | |||||
for(y=h; y<sy+block_h*2; y++) | |||||
memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2); | memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2); | ||||
if(sx<0){ | if(sx<0){ | ||||
for(y=sy; y<sy+block_w*2; y++) | |||||
for(y=sy; y<sy+block_h*2; y++) | |||||
memcpy(dst + sx + y*stride, src + sx + y*stride, -sx); | memcpy(dst + sx + y*stride, src + sx + y*stride, -sx); | ||||
} | } | ||||
if(sx+block_w*2 > w){ | if(sx+block_w*2 > w){ | ||||
for(y=sy; y<sy+block_w*2; y++) | |||||
for(y=sy; y<sy+block_h*2; y++) | |||||
memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w); | memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w); | ||||
} | } | ||||
} | } | ||||
@@ -1618,11 +1628,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |||||
ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); | ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); | ||||
for(i=0; i<3; i++){ | for(i=0; i<3; i++){ | ||||
int shift= !!i; | |||||
for(y=0; y<(height>>shift); y++) | |||||
int hshift= i ? s->chroma_h_shift : 0; | |||||
int vshift= i ? s->chroma_v_shift : 0; | |||||
for(y=0; y<(height>>vshift); y++) | |||||
memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]], | memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]], | ||||
&pict->data[i][y * pict->linesize[i]], | &pict->data[i][y * pict->linesize[i]], | ||||
width>>shift); | |||||
width>>hshift); | |||||
} | } | ||||
s->new_picture = *pict; | s->new_picture = *pict; | ||||