diff options
Diffstat (limited to 'libavcodec/snowenc.c')
-rw-r--r-- | libavcodec/snowenc.c | 255 |
1 files changed, 198 insertions, 57 deletions
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 29f5330..cbdf978 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -22,6 +22,7 @@ #include "libavutil/log.h" #include "libavutil/opt.h" #include "avcodec.h" +#include "internal.h" #include "dsputil.h" #include "dwt.h" #include "snow.h" @@ -217,12 +218,12 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->coded_frame= &s->current_picture; switch(avctx->pix_fmt){ -// case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUV444P: // case AV_PIX_FMT_YUV422P: case AV_PIX_FMT_YUV420P: - case AV_PIX_FMT_GRAY8: +// case AV_PIX_FMT_GRAY8: // case AV_PIX_FMT_YUV411P: -// case AV_PIX_FMT_YUV410P: + case AV_PIX_FMT_YUV410P: s->colorspace_type= 0; break; /* case AV_PIX_FMT_RGB32: @@ -232,9 +233,7 @@ static av_cold int encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n"); return -1; } -// avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); - s->chroma_h_shift= 1; - s->chroma_v_shift= 1; + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp); ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp); @@ -254,12 +253,12 @@ static av_cold int encode_init(AVCodecContext *avctx) } //near copy & paste from dsputil, FIXME -static int pix_sum(uint8_t * pix, int line_size, int w) +static int pix_sum(uint8_t * pix, int line_size, int w, int h) { int s, i, j; s = 0; - for (i = 0; i < w; i++) { + for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { s += pix[0]; pix ++; @@ -325,8 +324,8 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ const int stride= s->current_picture.linesize[0]; const int uvstride= s->current_picture.linesize[1]; 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]; int16_t last_mv[3][2]; int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused @@ -446,15 +445,15 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT; block_s= block_w*block_w; - sum = pix_sum(current_data[0], stride, block_w); + sum = pix_sum(current_data[0], stride, block_w, block_w); l= (sum + block_s/2)/block_s; iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s; - block_s= block_w*block_w>>2; - sum = pix_sum(current_data[1], uvstride, block_w>>1); + block_s= block_w*block_w>>(s->chroma_h_shift + s->chroma_v_shift); + sum = pix_sum(current_data[1], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift); cb= (sum + block_s/2)/block_s; // iscore += pix_norm1(¤t_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s; - sum = pix_sum(current_data[2], uvstride, block_w>>1); + sum = pix_sum(current_data[2], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift); cr= (sum + block_s/2)/block_s; // iscore += pix_norm1(¤t_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s; @@ -576,9 +575,10 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ int i, x2, y2; Plane *p= &s->plane[plane_index]; 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]; 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 @@ -591,6 +591,8 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ int ab=0; int aa=0; + av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc stuff above + b->type|= BLOCK_INTRA; b->color[plane_index]= 0; memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM)); @@ -599,19 +601,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_y2= mb_y + (i>>1) - 1; 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++){ - 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 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(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]; //FIXME precalculate this or simplify it somehow else @@ -668,8 +670,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, uint8_t (*obmc_edged)[MB_SIZE * 2]){ Plane *p= &s->plane[plane_index]; 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]; uint8_t *dst= s->current_picture.data[plane_index]; uint8_t *src= s-> input_picture.data[plane_index]; @@ -684,14 +687,16 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, uin int rate= 0; 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 sy= block_w*mb_y - block_w/2; + int sy= block_h*mb_y - block_h/2; int x0= FFMAX(0,-sx); int y0= FFMAX(0,-sy); 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; - 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++){ const uint8_t *obmc1= obmc_edged[y]; @@ -719,9 +724,9 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, uin else x0 = block_w; if(mb_y == 0) - y1 = block_w; + y1 = block_h; else - y0 = block_w; + y0 = block_h; for(y=y0; y<y1; y++) memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0); } @@ -767,9 +772,10 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ int i, y2; Plane *p= &s->plane[plane_index]; 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]; uint8_t *dst= s->current_picture.data[plane_index]; uint8_t *src= s-> input_picture.data[plane_index]; @@ -783,31 +789,33 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ int rate= 0; 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++){ int mb_x2= mb_x + (i%3) - 1; int mb_y2= mb_y + (i/3) - 1; 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, - 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 for(y2= y; y2<0; y2++) 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); 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); } 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); } 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){ @@ -829,7 +837,7 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ return distortion + rate*penalty_factor; } -static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){ +static int encode_subband_c0run(SnowContext *s, SubBand *b, const IDWTELEM *src, const IDWTELEM *parent, int stride, int orientation){ const int w= b->width; const int h= b->height; int x, y; @@ -949,7 +957,7 @@ static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTE return 0; } -static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){ +static int encode_subband(SnowContext *s, SubBand *b, const IDWTELEM *src, const IDWTELEM *parent, int stride, int orientation){ // encode_subband_qtree(s, b, src, parent, stride, orientation); // encode_subband_z0run(s, b, src, parent, stride, orientation); return encode_subband_c0run(s, b, src, parent, stride, orientation); @@ -1128,22 +1136,23 @@ static void iterative_me(SnowContext *s){ uint8_t *dst= s->current_picture.data[0]; const int stride= s->current_picture.linesize[0]; 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 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 h= s->plane[0].height; int y; for(y=sy; y<0; y++) 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); 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); } 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); } } @@ -1623,21 +1632,19 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, uint8_t rc_header_bak[sizeof(s->header_state)]; uint8_t rc_block_bak[sizeof(s->block_state)]; - if (!pkt->data && - (ret = av_new_packet(pkt, s->b_width*s->b_height*MB_SIZE*MB_SIZE*3 + FF_MIN_BUFFER_SIZE)) < 0) { - av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); + if ((ret = ff_alloc_packet2(avctx, pkt, s->b_width*s->b_height*MB_SIZE*MB_SIZE*3 + FF_MIN_BUFFER_SIZE)) < 0) return ret; - } ff_init_range_encoder(c, pkt->data, pkt->size); ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); 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]], &pict->data[i][y * pict->linesize[i]], - width>>shift); + width>>hshift); } s->new_picture = *pict; @@ -1725,6 +1732,10 @@ redo_frame: else s->spatial_decomposition_count= 5; + while( !(width >>(s->chroma_h_shift + s->spatial_decomposition_count)) + || !(height>>(s->chroma_v_shift + s->spatial_decomposition_count))) + s->spatial_decomposition_count--; + s->m.pict_type = pic->pict_type; s->qbias = pic->pict_type == AV_PICTURE_TYPE_P ? 2 : 0; @@ -1811,6 +1822,7 @@ redo_frame: quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias); if(orientation==0) decorrelate(s, b, b->ibuf, b->stride, pic->pict_type == AV_PICTURE_TYPE_P, 0); + if (!s->no_bitstream) encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation); assert(b->parent==NULL || b->parent->stride == b->stride*2); if(orientation==0) @@ -1915,6 +1927,7 @@ static av_cold int encode_end(AVCodecContext *avctx) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { { "memc_only", "Only do ME/MC (I frames -> ref, P frame -> ME+MC).", OFFSET(memc_only), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "no_bitstream", "Skip final bitstream writeout.", OFFSET(no_bitstream), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, { NULL }, }; @@ -1933,6 +1946,134 @@ AVCodec ff_snow_encoder = { .init = encode_init, .encode2 = encode_frame, .close = encode_end, + .pix_fmts = (const enum AVPixelFormat[]){ + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_NONE + }, .long_name = NULL_IF_CONFIG_SMALL("Snow"), .priv_class = &snowenc_class, }; + + +#ifdef TEST +#undef malloc +#undef free +#undef printf + +#include "libavutil/lfg.h" +#include "libavutil/mathematics.h" + +int main(void){ +#define width 256 +#define height 256 + int buffer[2][width*height]; + SnowContext s; + int i; + AVLFG prng; + s.spatial_decomposition_count=6; + s.spatial_decomposition_type=1; + + s.temp_dwt_buffer = av_mallocz(width * sizeof(DWTELEM)); + s.temp_idwt_buffer = av_mallocz(width * sizeof(IDWTELEM)); + + av_lfg_init(&prng, 1); + + printf("testing 5/3 DWT\n"); + for(i=0; i<width*height; i++) + buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345; + + ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + + for(i=0; i<width*height; i++) + if(buffer[0][i]!= buffer[1][i]) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]); + + printf("testing 9/7 DWT\n"); + s.spatial_decomposition_type=0; + for(i=0; i<width*height; i++) + buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345; + + ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + + for(i=0; i<width*height; i++) + if(FFABS(buffer[0][i] - buffer[1][i])>20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]); + + { + int level, orientation, x, y; + int64_t errors[8][4]; + int64_t g=0; + + memset(errors, 0, sizeof(errors)); + s.spatial_decomposition_count=3; + s.spatial_decomposition_type=0; + for(level=0; level<s.spatial_decomposition_count; level++){ + for(orientation=level ? 1 : 0; orientation<4; orientation++){ + int w= width >> (s.spatial_decomposition_count-level); + int h= height >> (s.spatial_decomposition_count-level); + int stride= width << (s.spatial_decomposition_count-level); + DWTELEM *buf= buffer[0]; + int64_t error=0; + + if(orientation&1) buf+=w; + if(orientation>1) buf+=stride>>1; + + memset(buffer[0], 0, sizeof(int)*width*height); + buf[w/2 + h/2*stride]= 256*256; + ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + for(y=0; y<height; y++){ + for(x=0; x<width; x++){ + int64_t d= buffer[0][x + y*width]; + error += d*d; + if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9 && level==2) printf("%8"PRId64" ", d); + } + if(FFABS(height/2-y)<9 && level==2) printf("\n"); + } + error= (int)(sqrt(error)+0.5); + errors[level][orientation]= error; + if(g) g=av_gcd(g, error); + else g= error; + } + } + printf("static int const visual_weight[][4]={\n"); + for(level=0; level<s.spatial_decomposition_count; level++){ + printf(" {"); + for(orientation=0; orientation<4; orientation++){ + printf("%8"PRId64",", errors[level][orientation]/g); + } + printf("},\n"); + } + printf("};\n"); + { + int level=2; + int w= width >> (s.spatial_decomposition_count-level); + //int h= height >> (s.spatial_decomposition_count-level); + int stride= width << (s.spatial_decomposition_count-level); + DWTELEM *buf= buffer[0]; + int64_t error=0; + + buf+=w; + buf+=stride>>1; + + memset(buffer[0], 0, sizeof(int)*width*height); + for(y=0; y<height; y++){ + for(x=0; x<width; x++){ + int tab[4]={0,2,3,1}; + buffer[0][x+width*y]= 256*256*tab[(x&1) + 2*(y&1)]; + } + } + ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + for(y=0; y<height; y++){ + for(x=0; x<width; x++){ + int64_t d= buffer[0][x + y*width]; + error += d*d; + if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9) printf("%8"PRId64" ", d); + } + if(FFABS(height/2-y)<9) printf("\n"); + } + } + + } + return 0; +} +#endif /* TEST */ |