Commit 5be3a818 authored by Michael Niedermayer's avatar Michael Niedermayer

code to do halfpel interpolation per frame (unfinished and under ifdef but it

should be faster when its finished)

Originally committed as revision 10293 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent f7b8bffe
......@@ -432,6 +432,7 @@ typedef struct SnowContext{
AVFrame input_picture; ///< new_picture with the internal linesizes
AVFrame current_picture;
AVFrame last_picture[MAX_REF_FRAMES];
uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4];
AVFrame mconly_picture;
// uint8_t q_context[16];
uint8_t header_state[32];
......@@ -3815,6 +3816,50 @@ static int encode_init(AVCodecContext *avctx)
return 0;
}
static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){
int p,x,y;
assert(!(s->avctx->flags & CODEC_FLAG_EMU_EDGE));
for(p=0; p<3; p++){
int is_chroma= !!p;
int w= s->avctx->width >>is_chroma;
int h= s->avctx->height >>is_chroma;
int ls= frame->linesize[p];
uint8_t *src= frame->data[p];
halfpel[1][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls);
halfpel[2][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls);
halfpel[3][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls);
halfpel[0][p]= src;
for(y=0; y<h; y++){
for(x=0; x<w; x++){
int i= y*ls + x;
halfpel[1][p][i]= (20*(src[i] + src[i+1]) - 5*(src[i-1] + src[i+2]) + (src[i-2] + src[i+3]) + 16 )>>5;
}
}
for(y=0; y<h; y++){
for(x=0; x<w; x++){
int i= y*ls + x;
halfpel[2][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5;
}
}
src= halfpel[1][p];
for(y=0; y<h; y++){
for(x=0; x<w; x++){
int i= y*ls + x;
halfpel[3][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5;
}
}
//FIXME border!
}
}
static int frame_start(SnowContext *s){
AVFrame tmp;
int w= s->avctx->width; //FIXME round up to x16 ?
......@@ -3828,6 +3873,11 @@ static int frame_start(SnowContext *s){
tmp= s->last_picture[s->max_ref_frames-1];
memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame));
memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);
#ifdef USE_HALFPEL_PLANE
if(s->current_picture.data[0])
halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture);
#endif
s->last_picture[0]= s->current_picture;
s->current_picture= tmp;
......@@ -4083,8 +4133,12 @@ STOP_TIMER("pred-conv")}
}
}
if(s->last_picture[s->max_ref_frames-1].data[0])
if(s->last_picture[s->max_ref_frames-1].data[0]){
avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]);
for(i=0; i<9; i++)
if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3])
av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3]));
}
s->current_picture.coded_picture_number = avctx->frame_number;
s->current_picture.pict_type = pict->pict_type;
......@@ -4172,7 +4226,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
RangeCoder * const c= &s->c;
int bytes_read;
AVFrame *picture = data;
int level, orientation, plane_index;
int level, orientation, plane_index, i;
ff_init_range_decoder(c, buf, buf_size);
ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
......@@ -4304,8 +4358,12 @@ STOP_TIMER("idwt + predict_slices")}
emms_c();
if(s->last_picture[s->max_ref_frames-1].data[0])
if(s->last_picture[s->max_ref_frames-1].data[0]){
avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]);
for(i=0; i<9; i++)
if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3])
av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3]));
}
if(!(s->avctx->debug&2048))
*picture= s->current_picture;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment