• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/snow.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
00003  *
00004  * This file is part of FFmpeg.
00005  *
00006  * FFmpeg is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * FFmpeg is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with FFmpeg; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include "libavutil/intmath.h"
00022 #include "avcodec.h"
00023 #include "dsputil.h"
00024 #include "dwt.h"
00025 #include "snow.h"
00026 
00027 #include "rangecoder.h"
00028 #include "mathops.h"
00029 
00030 #include "mpegvideo.h"
00031 #include "h263.h"
00032 
00033 #undef NDEBUG
00034 #include <assert.h>
00035 
00036 static const int8_t quant3[256]={
00037  0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00038  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00039  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00040  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00041  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00042  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00043  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00044  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00045 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00046 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00047 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00048 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00049 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00050 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00051 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00052 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,
00053 };
00054 static const int8_t quant3b[256]={
00055  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00056  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00057  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00058  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00059  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00060  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00061  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00062  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00063 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00064 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00065 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00066 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00067 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00068 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00069 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00070 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00071 };
00072 static const int8_t quant3bA[256]={
00073  0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00074  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00075  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00076  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00077  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00078  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00079  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00080  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00081  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00082  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00083  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00084  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00085  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00086  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00087  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00088  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
00089 };
00090 static const int8_t quant5[256]={
00091  0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00092  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00093  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00094  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00095  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00096  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00097  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00098  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00099 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
00100 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
00101 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
00102 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
00103 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
00104 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
00105 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
00106 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,
00107 };
00108 static const int8_t quant7[256]={
00109  0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00110  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00111  2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
00112  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
00113  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
00114  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
00115  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
00116  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
00117 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
00118 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
00119 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
00120 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
00121 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
00122 -3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,
00123 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
00124 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,
00125 };
00126 static const int8_t quant9[256]={
00127  0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
00128  3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00129  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00130  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00131  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00132  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00133  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00134  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00135 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
00136 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
00137 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
00138 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
00139 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
00140 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
00141 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,
00142 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,
00143 };
00144 static const int8_t quant11[256]={
00145  0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
00146  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00147  4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00148  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00149  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00150  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00151  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00152  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00153 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
00154 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
00155 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
00156 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
00157 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
00158 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4,
00159 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
00160 -4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1,
00161 };
00162 static const int8_t quant13[256]={
00163  0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
00164  4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00165  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00166  5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00167  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00168  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00169  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00170  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00171 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
00172 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
00173 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
00174 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
00175 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5,
00176 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
00177 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
00178 -4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1,
00179 };
00180 
00181 #if 0 //64*cubic
00182 static const uint8_t obmc32[1024]={
00183   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00184   0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,  0,
00185   0,  0,  0,  4,  4,  4,  4,  8,  8, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 12, 12,  8,  8,  4,  4,  4,  4,  0,  0,  0,
00186   0,  0,  4,  4,  8,  8, 12, 16, 16, 20, 24, 24, 28, 28, 32, 32, 32, 32, 28, 28, 24, 24, 20, 16, 16, 12,  8,  8,  4,  4,  0,  0,
00187   0,  0,  4,  8,  8, 12, 16, 24, 28, 32, 36, 40, 44, 48, 48, 48, 48, 48, 48, 44, 40, 36, 32, 28, 24, 16, 12,  8,  8,  4,  0,  0,
00188   0,  4,  4,  8, 12, 20, 24, 32, 40, 44, 52, 56, 60, 64, 68, 72, 72, 68, 64, 60, 56, 52, 44, 40, 32, 24, 20, 12,  8,  4,  4,  0,
00189   0,  4,  4, 12, 16, 24, 32, 40, 52, 60, 68, 76, 80, 88, 88, 92, 92, 88, 88, 80, 76, 68, 60, 52, 40, 32, 24, 16, 12,  4,  4,  0,
00190   0,  4,  8, 16, 24, 32, 40, 52, 64, 76, 84, 92,100,108,112,116,116,112,108,100, 92, 84, 76, 64, 52, 40, 32, 24, 16,  8,  4,  0,
00191   0,  4,  8, 16, 28, 40, 52, 64, 76, 88,100,112,124,132,136,140,140,136,132,124,112,100, 88, 76, 64, 52, 40, 28, 16,  8,  4,  0,
00192   0,  4, 12, 20, 32, 44, 60, 76, 88,104,120,132,144,152,160,164,164,160,152,144,132,120,104, 88, 76, 60, 44, 32, 20, 12,  4,  0,
00193   0,  4, 12, 24, 36, 48, 68, 84,100,120,136,152,164,176,180,184,184,180,176,164,152,136,120,100, 84, 68, 48, 36, 24, 12,  4,  0,
00194   0,  4, 12, 24, 40, 56, 76, 92,112,132,152,168,180,192,204,208,208,204,192,180,168,152,132,112, 92, 76, 56, 40, 24, 12,  4,  0,
00195   0,  4, 16, 28, 44, 60, 80,100,124,144,164,180,196,208,220,224,224,220,208,196,180,164,144,124,100, 80, 60, 44, 28, 16,  4,  0,
00196   0,  8, 16, 28, 48, 64, 88,108,132,152,176,192,208,224,232,240,240,232,224,208,192,176,152,132,108, 88, 64, 48, 28, 16,  8,  0,
00197   0,  4, 16, 32, 48, 68, 88,112,136,160,180,204,220,232,244,248,248,244,232,220,204,180,160,136,112, 88, 68, 48, 32, 16,  4,  0,
00198   1,  8, 16, 32, 48, 72, 92,116,140,164,184,208,224,240,248,255,255,248,240,224,208,184,164,140,116, 92, 72, 48, 32, 16,  8,  1,
00199   1,  8, 16, 32, 48, 72, 92,116,140,164,184,208,224,240,248,255,255,248,240,224,208,184,164,140,116, 92, 72, 48, 32, 16,  8,  1,
00200   0,  4, 16, 32, 48, 68, 88,112,136,160,180,204,220,232,244,248,248,244,232,220,204,180,160,136,112, 88, 68, 48, 32, 16,  4,  0,
00201   0,  8, 16, 28, 48, 64, 88,108,132,152,176,192,208,224,232,240,240,232,224,208,192,176,152,132,108, 88, 64, 48, 28, 16,  8,  0,
00202   0,  4, 16, 28, 44, 60, 80,100,124,144,164,180,196,208,220,224,224,220,208,196,180,164,144,124,100, 80, 60, 44, 28, 16,  4,  0,
00203   0,  4, 12, 24, 40, 56, 76, 92,112,132,152,168,180,192,204,208,208,204,192,180,168,152,132,112, 92, 76, 56, 40, 24, 12,  4,  0,
00204   0,  4, 12, 24, 36, 48, 68, 84,100,120,136,152,164,176,180,184,184,180,176,164,152,136,120,100, 84, 68, 48, 36, 24, 12,  4,  0,
00205   0,  4, 12, 20, 32, 44, 60, 76, 88,104,120,132,144,152,160,164,164,160,152,144,132,120,104, 88, 76, 60, 44, 32, 20, 12,  4,  0,
00206   0,  4,  8, 16, 28, 40, 52, 64, 76, 88,100,112,124,132,136,140,140,136,132,124,112,100, 88, 76, 64, 52, 40, 28, 16,  8,  4,  0,
00207   0,  4,  8, 16, 24, 32, 40, 52, 64, 76, 84, 92,100,108,112,116,116,112,108,100, 92, 84, 76, 64, 52, 40, 32, 24, 16,  8,  4,  0,
00208   0,  4,  4, 12, 16, 24, 32, 40, 52, 60, 68, 76, 80, 88, 88, 92, 92, 88, 88, 80, 76, 68, 60, 52, 40, 32, 24, 16, 12,  4,  4,  0,
00209   0,  4,  4,  8, 12, 20, 24, 32, 40, 44, 52, 56, 60, 64, 68, 72, 72, 68, 64, 60, 56, 52, 44, 40, 32, 24, 20, 12,  8,  4,  4,  0,
00210   0,  0,  4,  8,  8, 12, 16, 24, 28, 32, 36, 40, 44, 48, 48, 48, 48, 48, 48, 44, 40, 36, 32, 28, 24, 16, 12,  8,  8,  4,  0,  0,
00211   0,  0,  4,  4,  8,  8, 12, 16, 16, 20, 24, 24, 28, 28, 32, 32, 32, 32, 28, 28, 24, 24, 20, 16, 16, 12,  8,  8,  4,  4,  0,  0,
00212   0,  0,  0,  4,  4,  4,  4,  8,  8, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 12, 12,  8,  8,  4,  4,  4,  4,  0,  0,  0,
00213   0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,  0,
00214   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00215 //error:0.000022
00216 };
00217 static const uint8_t obmc16[256]={
00218   0,  0,  0,  0,  0,  0,  4,  4,  4,  4,  0,  0,  0,  0,  0,  0,
00219   0,  4,  4,  8, 16, 20, 20, 24, 24, 20, 20, 16,  8,  4,  4,  0,
00220   0,  4, 16, 24, 36, 44, 52, 60, 60, 52, 44, 36, 24, 16,  4,  0,
00221   0,  8, 24, 44, 60, 80, 96,104,104, 96, 80, 60, 44, 24,  8,  0,
00222   0, 16, 36, 60, 92,116,136,152,152,136,116, 92, 60, 36, 16,  0,
00223   0, 20, 44, 80,116,152,180,196,196,180,152,116, 80, 44, 20,  0,
00224   4, 20, 52, 96,136,180,212,228,228,212,180,136, 96, 52, 20,  4,
00225   4, 24, 60,104,152,196,228,248,248,228,196,152,104, 60, 24,  4,
00226   4, 24, 60,104,152,196,228,248,248,228,196,152,104, 60, 24,  4,
00227   4, 20, 52, 96,136,180,212,228,228,212,180,136, 96, 52, 20,  4,
00228   0, 20, 44, 80,116,152,180,196,196,180,152,116, 80, 44, 20,  0,
00229   0, 16, 36, 60, 92,116,136,152,152,136,116, 92, 60, 36, 16,  0,
00230   0,  8, 24, 44, 60, 80, 96,104,104, 96, 80, 60, 44, 24,  8,  0,
00231   0,  4, 16, 24, 36, 44, 52, 60, 60, 52, 44, 36, 24, 16,  4,  0,
00232   0,  4,  4,  8, 16, 20, 20, 24, 24, 20, 20, 16,  8,  4,  4,  0,
00233   0,  0,  0,  0,  0,  0,  4,  4,  4,  4,  0,  0,  0,  0,  0,  0,
00234 //error:0.000033
00235 };
00236 #elif 1 // 64*linear
00237 static const uint8_t obmc32[1024]={
00238   0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8,  8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,
00239   0,  4,  4,  4,  8,  8,  8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12,  8,  8,  8,  4,  4,  4,  0,
00240   0,  4,  8,  8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12,  8,  8,  4,  0,
00241   0,  4,  8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12,  8,  4,  0,
00242   4,  8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12,  8,  4,
00243   4,  8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12,  8,  4,
00244   4,  8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16,  8,  4,
00245   4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12,  4,
00246   4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12,  4,
00247   4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16,  4,
00248   4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16,  4,
00249   4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16,  4,
00250   8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20,  8,
00251   8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20,  8,
00252   8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20,  8,
00253   8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24,  8,
00254   8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24,  8,
00255   8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20,  8,
00256   8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20,  8,
00257   8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20,  8,
00258   4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16,  4,
00259   4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16,  4,
00260   4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16,  4,
00261   4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12,  4,
00262   4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12,  4,
00263   4,  8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16,  8,  4,
00264   4,  8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12,  8,  4,
00265   4,  8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12,  8,  4,
00266   0,  4,  8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12,  8,  4,  0,
00267   0,  4,  8,  8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12,  8,  8,  4,  0,
00268   0,  4,  4,  4,  8,  8,  8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12,  8,  8,  8,  4,  4,  4,  0,
00269   0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8,  8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,
00270  //error:0.000020
00271 };
00272 static const uint8_t obmc16[256]={
00273   0,  4,  4,  8,  8, 12, 12, 16, 16, 12, 12,  8,  8,  4,  4,  0,
00274   4,  8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16,  8,  4,
00275   4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16,  4,
00276   8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20,  8,
00277   8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28,  8,
00278  12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
00279  12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
00280  16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
00281  16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
00282  12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
00283  12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
00284   8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28,  8,
00285   8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20,  8,
00286   4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16,  4,
00287   4,  8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16,  8,  4,
00288   0,  4,  4,  8,  8, 12, 12, 16, 16, 12, 12,  8,  8,  4,  4,  0,
00289 //error:0.000015
00290 };
00291 #else //64*cos
00292 static const uint8_t obmc32[1024]={
00293   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00294   0,  0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  4,  4,  8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,  0,  0,
00295   0,  0,  0,  4,  4,  4,  4,  8,  8, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12,  8,  8,  4,  4,  4,  4,  0,  0,  0,
00296   0,  0,  4,  4,  4,  8,  8, 12, 16, 20, 20, 24, 28, 28, 28, 28, 28, 28, 28, 28, 24, 20, 20, 16, 12,  8,  8,  4,  4,  4,  0,  0,
00297   0,  0,  4,  4,  8, 12, 16, 20, 24, 28, 36, 40, 44, 44, 48, 48, 48, 48, 44, 44, 40, 36, 28, 24, 20, 16, 12,  8,  4,  4,  0,  0,
00298   0,  0,  4,  8, 12, 20, 24, 32, 36, 44, 48, 56, 60, 64, 68, 68, 68, 68, 64, 60, 56, 48, 44, 36, 32, 24, 20, 12,  8,  4,  0,  0,
00299   0,  4,  4,  8, 16, 24, 32, 40, 48, 60, 68, 76, 80, 84, 88, 92, 92, 88, 84, 80, 76, 68, 60, 48, 40, 32, 24, 16,  8,  4,  4,  0,
00300   0,  4,  8, 12, 20, 32, 40, 52, 64, 76, 84, 96,104,108,112,116,116,112,108,104, 96, 84, 76, 64, 52, 40, 32, 20, 12,  8,  4,  0,
00301   0,  4,  8, 16, 24, 36, 48, 64, 76, 92,104,116,124,132,136,140,140,136,132,124,116,104, 92, 76, 64, 48, 36, 24, 16,  8,  4,  0,
00302   0,  4, 12, 20, 28, 44, 60, 76, 92,104,120,136,148,156,160,164,164,160,156,148,136,120,104, 92, 76, 60, 44, 28, 20, 12,  4,  0,
00303   0,  4, 12, 20, 36, 48, 68, 84,104,120,140,152,168,176,184,188,188,184,176,168,152,140,120,104, 84, 68, 48, 36, 20, 12,  4,  0,
00304   0,  4, 12, 24, 36, 56, 76, 96,116,136,152,172,184,196,204,208,208,204,196,184,172,152,136,116, 96, 76, 56, 36, 24, 12,  4,  0,
00305   0,  4, 12, 24, 44, 60, 80,104,124,148,168,184,200,212,224,228,228,224,212,200,184,168,148,124,104, 80, 60, 44, 24, 12,  4,  0,
00306   0,  4, 12, 28, 44, 64, 84,108,132,156,176,196,212,228,236,240,240,236,228,212,196,176,156,132,108, 84, 64, 44, 28, 12,  4,  0,
00307   0,  4, 16, 28, 48, 68, 88,112,136,160,184,204,224,236,244,252,252,244,236,224,204,184,160,136,112, 88, 68, 48, 28, 16,  4,  0,
00308   1,  4, 16, 28, 48, 68, 92,116,140,164,188,208,228,240,252,255,255,252,240,228,208,188,164,140,116, 92, 68, 48, 28, 16,  4,  1,
00309   1,  4, 16, 28, 48, 68, 92,116,140,164,188,208,228,240,252,255,255,252,240,228,208,188,164,140,116, 92, 68, 48, 28, 16,  4,  1,
00310   0,  4, 16, 28, 48, 68, 88,112,136,160,184,204,224,236,244,252,252,244,236,224,204,184,160,136,112, 88, 68, 48, 28, 16,  4,  0,
00311   0,  4, 12, 28, 44, 64, 84,108,132,156,176,196,212,228,236,240,240,236,228,212,196,176,156,132,108, 84, 64, 44, 28, 12,  4,  0,
00312   0,  4, 12, 24, 44, 60, 80,104,124,148,168,184,200,212,224,228,228,224,212,200,184,168,148,124,104, 80, 60, 44, 24, 12,  4,  0,
00313   0,  4, 12, 24, 36, 56, 76, 96,116,136,152,172,184,196,204,208,208,204,196,184,172,152,136,116, 96, 76, 56, 36, 24, 12,  4,  0,
00314   0,  4, 12, 20, 36, 48, 68, 84,104,120,140,152,168,176,184,188,188,184,176,168,152,140,120,104, 84, 68, 48, 36, 20, 12,  4,  0,
00315   0,  4, 12, 20, 28, 44, 60, 76, 92,104,120,136,148,156,160,164,164,160,156,148,136,120,104, 92, 76, 60, 44, 28, 20, 12,  4,  0,
00316   0,  4,  8, 16, 24, 36, 48, 64, 76, 92,104,116,124,132,136,140,140,136,132,124,116,104, 92, 76, 64, 48, 36, 24, 16,  8,  4,  0,
00317   0,  4,  8, 12, 20, 32, 40, 52, 64, 76, 84, 96,104,108,112,116,116,112,108,104, 96, 84, 76, 64, 52, 40, 32, 20, 12,  8,  4,  0,
00318   0,  4,  4,  8, 16, 24, 32, 40, 48, 60, 68, 76, 80, 84, 88, 92, 92, 88, 84, 80, 76, 68, 60, 48, 40, 32, 24, 16,  8,  4,  4,  0,
00319   0,  0,  4,  8, 12, 20, 24, 32, 36, 44, 48, 56, 60, 64, 68, 68, 68, 68, 64, 60, 56, 48, 44, 36, 32, 24, 20, 12,  8,  4,  0,  0,
00320   0,  0,  4,  4,  8, 12, 16, 20, 24, 28, 36, 40, 44, 44, 48, 48, 48, 48, 44, 44, 40, 36, 28, 24, 20, 16, 12,  8,  4,  4,  0,  0,
00321   0,  0,  4,  4,  4,  8,  8, 12, 16, 20, 20, 24, 28, 28, 28, 28, 28, 28, 28, 28, 24, 20, 20, 16, 12,  8,  8,  4,  4,  4,  0,  0,
00322   0,  0,  0,  4,  4,  4,  4,  8,  8, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12,  8,  8,  4,  4,  4,  4,  0,  0,  0,
00323   0,  0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  4,  4,  8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,  0,  0,
00324   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00325 //error:0.000022
00326 };
00327 static const uint8_t obmc16[256]={
00328   0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,  0,
00329   0,  0,  4,  8, 12, 16, 20, 20, 20, 20, 16, 12,  8,  4,  0,  0,
00330   0,  4, 12, 24, 32, 44, 52, 56, 56, 52, 44, 32, 24, 12,  4,  0,
00331   0,  8, 24, 40, 60, 80, 96,104,104, 96, 80, 60, 40, 24,  8,  0,
00332   0, 12, 32, 64, 92,120,140,152,152,140,120, 92, 64, 32, 12,  0,
00333   4, 16, 44, 80,120,156,184,196,196,184,156,120, 80, 44, 16,  4,
00334   4, 20, 52, 96,140,184,216,232,232,216,184,140, 96, 52, 20,  4,
00335   0, 20, 56,104,152,196,232,252,252,232,196,152,104, 56, 20,  0,
00336   0, 20, 56,104,152,196,232,252,252,232,196,152,104, 56, 20,  0,
00337   4, 20, 52, 96,140,184,216,232,232,216,184,140, 96, 52, 20,  4,
00338   4, 16, 44, 80,120,156,184,196,196,184,156,120, 80, 44, 16,  4,
00339   0, 12, 32, 64, 92,120,140,152,152,140,120, 92, 64, 32, 12,  0,
00340   0,  8, 24, 40, 60, 80, 96,104,104, 96, 80, 60, 40, 24,  8,  0,
00341   0,  4, 12, 24, 32, 44, 52, 56, 56, 52, 44, 32, 24, 12,  4,  0,
00342   0,  0,  4,  8, 12, 16, 20, 20, 20, 20, 16, 12,  8,  4,  0,  0,
00343   0,  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,  0,
00344 //error:0.000022
00345 };
00346 #endif /* 0 */
00347 
00348 //linear *64
00349 static const uint8_t obmc8[64]={
00350   4, 12, 20, 28, 28, 20, 12,  4,
00351  12, 36, 60, 84, 84, 60, 36, 12,
00352  20, 60,100,140,140,100, 60, 20,
00353  28, 84,140,196,196,140, 84, 28,
00354  28, 84,140,196,196,140, 84, 28,
00355  20, 60,100,140,140,100, 60, 20,
00356  12, 36, 60, 84, 84, 60, 36, 12,
00357   4, 12, 20, 28, 28, 20, 12,  4,
00358 //error:0.000000
00359 };
00360 
00361 //linear *64
00362 static const uint8_t obmc4[16]={
00363  16, 48, 48, 16,
00364  48,144,144, 48,
00365  48,144,144, 48,
00366  16, 48, 48, 16,
00367 //error:0.000000
00368 };
00369 
00370 static const uint8_t * const obmc_tab[4]={
00371     obmc32, obmc16, obmc8, obmc4
00372 };
00373 
00374 static int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
00375 
00376 typedef struct BlockNode{
00377     int16_t mx;
00378     int16_t my;
00379     uint8_t ref;
00380     uint8_t color[3];
00381     uint8_t type;
00382 //#define TYPE_SPLIT    1
00383 #define BLOCK_INTRA   1
00384 #define BLOCK_OPT     2
00385 //#define TYPE_NOCOLOR  4
00386     uint8_t level; //FIXME merge into type?
00387 }BlockNode;
00388 
00389 static const BlockNode null_block= { //FIXME add border maybe
00390     .color= {128,128,128},
00391     .mx= 0,
00392     .my= 0,
00393     .ref= 0,
00394     .type= 0,
00395     .level= 0,
00396 };
00397 
00398 #define LOG2_MB_SIZE 4
00399 #define MB_SIZE (1<<LOG2_MB_SIZE)
00400 #define ENCODER_EXTRA_BITS 4
00401 #define HTAPS_MAX 8
00402 
00403 typedef struct x_and_coeff{
00404     int16_t x;
00405     uint16_t coeff;
00406 } x_and_coeff;
00407 
00408 typedef struct SubBand{
00409     int level;
00410     int stride;
00411     int width;
00412     int height;
00413     int qlog;        
00414     DWTELEM *buf;
00415     IDWTELEM *ibuf;
00416     int buf_x_offset;
00417     int buf_y_offset;
00418     int stride_line; 
00419     x_and_coeff * x_coeff;
00420     struct SubBand *parent;
00421     uint8_t state[/*7*2*/ 7 + 512][32];
00422 }SubBand;
00423 
00424 typedef struct Plane{
00425     int width;
00426     int height;
00427     SubBand band[MAX_DECOMPOSITIONS][4];
00428 
00429     int htaps;
00430     int8_t hcoeff[HTAPS_MAX/2];
00431     int diag_mc;
00432     int fast_mc;
00433 
00434     int last_htaps;
00435     int8_t last_hcoeff[HTAPS_MAX/2];
00436     int last_diag_mc;
00437 }Plane;
00438 
00439 typedef struct SnowContext{
00440 
00441     AVCodecContext *avctx;
00442     RangeCoder c;
00443     DSPContext dsp;
00444     DWTContext dwt;
00445     AVFrame new_picture;
00446     AVFrame input_picture;              
00447     AVFrame current_picture;
00448     AVFrame last_picture[MAX_REF_FRAMES];
00449     uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4];
00450     AVFrame mconly_picture;
00451 //     uint8_t q_context[16];
00452     uint8_t header_state[32];
00453     uint8_t block_state[128 + 32*128];
00454     int keyframe;
00455     int always_reset;
00456     int version;
00457     int spatial_decomposition_type;
00458     int last_spatial_decomposition_type;
00459     int temporal_decomposition_type;
00460     int spatial_decomposition_count;
00461     int last_spatial_decomposition_count;
00462     int temporal_decomposition_count;
00463     int max_ref_frames;
00464     int ref_frames;
00465     int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
00466     uint32_t *ref_scores[MAX_REF_FRAMES];
00467     DWTELEM *spatial_dwt_buffer;
00468     IDWTELEM *spatial_idwt_buffer;
00469     int colorspace_type;
00470     int chroma_h_shift;
00471     int chroma_v_shift;
00472     int spatial_scalability;
00473     int qlog;
00474     int last_qlog;
00475     int lambda;
00476     int lambda2;
00477     int pass1_rc;
00478     int mv_scale;
00479     int last_mv_scale;
00480     int qbias;
00481     int last_qbias;
00482 #define QBIAS_SHIFT 3
00483     int b_width;
00484     int b_height;
00485     int block_max_depth;
00486     int last_block_max_depth;
00487     Plane plane[MAX_PLANES];
00488     BlockNode *block;
00489 #define ME_CACHE_SIZE 1024
00490     int me_cache[ME_CACHE_SIZE];
00491     int me_cache_generation;
00492     slice_buffer sb;
00493 
00494     MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
00495 
00496     uint8_t *scratchbuf;
00497 }SnowContext;
00498 
00499 #ifdef __sgi
00500 // Avoid a name clash on SGI IRIX
00501 #undef qexp
00502 #endif
00503 #define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
00504 static uint8_t qexp[QROOT];
00505 
00506 static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
00507     int i;
00508 
00509     if(v){
00510         const int a= FFABS(v);
00511         const int e= av_log2(a);
00512 #if 1
00513         const int el= FFMIN(e, 10);
00514         put_rac(c, state+0, 0);
00515 
00516         for(i=0; i<el; i++){
00517             put_rac(c, state+1+i, 1);  //1..10
00518         }
00519         for(; i<e; i++){
00520             put_rac(c, state+1+9, 1);  //1..10
00521         }
00522         put_rac(c, state+1+FFMIN(i,9), 0);
00523 
00524         for(i=e-1; i>=el; i--){
00525             put_rac(c, state+22+9, (a>>i)&1); //22..31
00526         }
00527         for(; i>=0; i--){
00528             put_rac(c, state+22+i, (a>>i)&1); //22..31
00529         }
00530 
00531         if(is_signed)
00532             put_rac(c, state+11 + el, v < 0); //11..21
00533 #else
00534 
00535         put_rac(c, state+0, 0);
00536         if(e<=9){
00537             for(i=0; i<e; i++){
00538                 put_rac(c, state+1+i, 1);  //1..10
00539             }
00540             put_rac(c, state+1+i, 0);
00541 
00542             for(i=e-1; i>=0; i--){
00543                 put_rac(c, state+22+i, (a>>i)&1); //22..31
00544             }
00545 
00546             if(is_signed)
00547                 put_rac(c, state+11 + e, v < 0); //11..21
00548         }else{
00549             for(i=0; i<e; i++){
00550                 put_rac(c, state+1+FFMIN(i,9), 1);  //1..10
00551             }
00552             put_rac(c, state+1+9, 0);
00553 
00554             for(i=e-1; i>=0; i--){
00555                 put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31
00556             }
00557 
00558             if(is_signed)
00559                 put_rac(c, state+11 + 10, v < 0); //11..21
00560         }
00561 #endif /* 1 */
00562     }else{
00563         put_rac(c, state+0, 1);
00564     }
00565 }
00566 
00567 static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
00568     if(get_rac(c, state+0))
00569         return 0;
00570     else{
00571         int i, e, a;
00572         e= 0;
00573         while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
00574             e++;
00575         }
00576 
00577         a= 1;
00578         for(i=e-1; i>=0; i--){
00579             a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
00580         }
00581 
00582         e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21
00583         return (a^e)-e;
00584     }
00585 }
00586 
00587 static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
00588     int i;
00589     int r= log2>=0 ? 1<<log2 : 1;
00590 
00591     assert(v>=0);
00592     assert(log2>=-4);
00593 
00594     while(v >= r){
00595         put_rac(c, state+4+log2, 1);
00596         v -= r;
00597         log2++;
00598         if(log2>0) r+=r;
00599     }
00600     put_rac(c, state+4+log2, 0);
00601 
00602     for(i=log2-1; i>=0; i--){
00603         put_rac(c, state+31-i, (v>>i)&1);
00604     }
00605 }
00606 
00607 static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
00608     int i;
00609     int r= log2>=0 ? 1<<log2 : 1;
00610     int v=0;
00611 
00612     assert(log2>=-4);
00613 
00614     while(get_rac(c, state+4+log2)){
00615         v+= r;
00616         log2++;
00617         if(log2>0) r+=r;
00618     }
00619 
00620     for(i=log2-1; i>=0; i--){
00621         v+= get_rac(c, state+31-i)<<i;
00622     }
00623 
00624     return v;
00625 }
00626 
00627 static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){
00628     const int w= b->width;
00629     const int h= b->height;
00630     int x,y;
00631 
00632     int run, runs;
00633     x_and_coeff *xc= b->x_coeff;
00634     x_and_coeff *prev_xc= NULL;
00635     x_and_coeff *prev2_xc= xc;
00636     x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL;
00637     x_and_coeff *prev_parent_xc= parent_xc;
00638 
00639     runs= get_symbol2(&s->c, b->state[30], 0);
00640     if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
00641     else           run= INT_MAX;
00642 
00643     for(y=0; y<h; y++){
00644         int v=0;
00645         int lt=0, t=0, rt=0;
00646 
00647         if(y && prev_xc->x == 0){
00648             rt= prev_xc->coeff;
00649         }
00650         for(x=0; x<w; x++){
00651             int p=0;
00652             const int l= v;
00653 
00654             lt= t; t= rt;
00655 
00656             if(y){
00657                 if(prev_xc->x <= x)
00658                     prev_xc++;
00659                 if(prev_xc->x == x + 1)
00660                     rt= prev_xc->coeff;
00661                 else
00662                     rt=0;
00663             }
00664             if(parent_xc){
00665                 if(x>>1 > parent_xc->x){
00666                     parent_xc++;
00667                 }
00668                 if(x>>1 == parent_xc->x){
00669                     p= parent_xc->coeff;
00670                 }
00671             }
00672             if(/*ll|*/l|lt|t|rt|p){
00673                 int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1));
00674 
00675                 v=get_rac(&s->c, &b->state[0][context]);
00676                 if(v){
00677                     v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1);
00678                     v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l&0xFF] + 3*quant3bA[t&0xFF]]);
00679 
00680                     xc->x=x;
00681                     (xc++)->coeff= v;
00682                 }
00683             }else{
00684                 if(!run){
00685                     if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
00686                     else           run= INT_MAX;
00687                     v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1);
00688                     v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]);
00689 
00690                     xc->x=x;
00691                     (xc++)->coeff= v;
00692                 }else{
00693                     int max_run;
00694                     run--;
00695                     v=0;
00696 
00697                     if(y) max_run= FFMIN(run, prev_xc->x - x - 2);
00698                     else  max_run= FFMIN(run, w-x-1);
00699                     if(parent_xc)
00700                         max_run= FFMIN(max_run, 2*parent_xc->x - x - 1);
00701                     x+= max_run;
00702                     run-= max_run;
00703                 }
00704             }
00705         }
00706         (xc++)->x= w+1; //end marker
00707         prev_xc= prev2_xc;
00708         prev2_xc= xc;
00709 
00710         if(parent_xc){
00711             if(y&1){
00712                 while(parent_xc->x != parent->width+1)
00713                     parent_xc++;
00714                 parent_xc++;
00715                 prev_parent_xc= parent_xc;
00716             }else{
00717                 parent_xc= prev_parent_xc;
00718             }
00719         }
00720     }
00721 
00722     (xc++)->x= w+1; //end marker
00723 }
00724 
00725 static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){
00726     const int w= b->width;
00727     int y;
00728     const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
00729     int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
00730     int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
00731     int new_index = 0;
00732 
00733     if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){
00734         qadd= 0;
00735         qmul= 1<<QEXPSHIFT;
00736     }
00737 
00738     /* If we are on the second or later slice, restore our index. */
00739     if (start_y != 0)
00740         new_index = save_state[0];
00741 
00742 
00743     for(y=start_y; y<h; y++){
00744         int x = 0;
00745         int v;
00746         IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset;
00747         memset(line, 0, b->width*sizeof(IDWTELEM));
00748         v = b->x_coeff[new_index].coeff;
00749         x = b->x_coeff[new_index++].x;
00750         while(x < w){
00751             register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT;
00752             register int u= -(v&1);
00753             line[x] = (t^u) - u;
00754 
00755             v = b->x_coeff[new_index].coeff;
00756             x = b->x_coeff[new_index++].x;
00757         }
00758     }
00759 
00760     /* Save our variables for the next slice. */
00761     save_state[0] = new_index;
00762 
00763     return;
00764 }
00765 
00766 static void reset_contexts(SnowContext *s){ //FIXME better initial contexts
00767     int plane_index, level, orientation;
00768 
00769     for(plane_index=0; plane_index<3; plane_index++){
00770         for(level=0; level<MAX_DECOMPOSITIONS; level++){
00771             for(orientation=level ? 1:0; orientation<4; orientation++){
00772                 memset(s->plane[plane_index].band[level][orientation].state, MID_STATE, sizeof(s->plane[plane_index].band[level][orientation].state));
00773             }
00774         }
00775     }
00776     memset(s->header_state, MID_STATE, sizeof(s->header_state));
00777     memset(s->block_state, MID_STATE, sizeof(s->block_state));
00778 }
00779 
00780 static int alloc_blocks(SnowContext *s){
00781     int w= -((-s->avctx->width )>>LOG2_MB_SIZE);
00782     int h= -((-s->avctx->height)>>LOG2_MB_SIZE);
00783 
00784     s->b_width = w;
00785     s->b_height= h;
00786 
00787     av_free(s->block);
00788     s->block= av_mallocz(w * h * sizeof(BlockNode) << (s->block_max_depth*2));
00789     return 0;
00790 }
00791 
00792 static inline void copy_rac_state(RangeCoder *d, RangeCoder *s){
00793     uint8_t *bytestream= d->bytestream;
00794     uint8_t *bytestream_start= d->bytestream_start;
00795     *d= *s;
00796     d->bytestream= bytestream;
00797     d->bytestream_start= bytestream_start;
00798 }
00799 
00800 static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
00801     const int w= s->b_width << s->block_max_depth;
00802     const int rem_depth= s->block_max_depth - level;
00803     const int index= (x + y*w) << rem_depth;
00804     const int block_w= 1<<rem_depth;
00805     BlockNode block;
00806     int i,j;
00807 
00808     block.color[0]= l;
00809     block.color[1]= cb;
00810     block.color[2]= cr;
00811     block.mx= mx;
00812     block.my= my;
00813     block.ref= ref;
00814     block.type= type;
00815     block.level= level;
00816 
00817     for(j=0; j<block_w; j++){
00818         for(i=0; i<block_w; i++){
00819             s->block[index + i + j*w]= block;
00820         }
00821     }
00822 }
00823 
00824 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){
00825     const int offset[3]= {
00826           y*c->  stride + x,
00827         ((y*c->uvstride + x)>>1),
00828         ((y*c->uvstride + x)>>1),
00829     };
00830     int i;
00831     for(i=0; i<3; i++){
00832         c->src[0][i]= src [i];
00833         c->ref[0][i]= ref [i] + offset[i];
00834     }
00835     assert(!ref_index);
00836 }
00837 
00838 static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref,
00839                            const BlockNode *left, const BlockNode *top, const BlockNode *tr){
00840     if(s->ref_frames == 1){
00841         *mx = mid_pred(left->mx, top->mx, tr->mx);
00842         *my = mid_pred(left->my, top->my, tr->my);
00843     }else{
00844         const int *scale = scale_mv_ref[ref];
00845         *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8,
00846                        (top ->mx * scale[top ->ref] + 128) >>8,
00847                        (tr  ->mx * scale[tr  ->ref] + 128) >>8);
00848         *my = mid_pred((left->my * scale[left->ref] + 128) >>8,
00849                        (top ->my * scale[top ->ref] + 128) >>8,
00850                        (tr  ->my * scale[tr  ->ref] + 128) >>8);
00851     }
00852 }
00853 
00854 static av_always_inline int same_block(BlockNode *a, BlockNode *b){
00855     if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){
00856         return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2]));
00857     }else{
00858         return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA));
00859     }
00860 }
00861 
00862 static void decode_q_branch(SnowContext *s, int level, int x, int y){
00863     const int w= s->b_width << s->block_max_depth;
00864     const int rem_depth= s->block_max_depth - level;
00865     const int index= (x + y*w) << rem_depth;
00866     int trx= (x+1)<<rem_depth;
00867     const BlockNode *left  = x ? &s->block[index-1] : &null_block;
00868     const BlockNode *top   = y ? &s->block[index-w] : &null_block;
00869     const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
00870     const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
00871     int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
00872 
00873     if(s->keyframe){
00874         set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
00875         return;
00876     }
00877 
00878     if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){
00879         int type, mx, my;
00880         int l = left->color[0];
00881         int cb= left->color[1];
00882         int cr= left->color[2];
00883         int ref = 0;
00884         int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
00885         int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx));
00886         int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my));
00887 
00888         type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
00889 
00890         if(type){
00891             pred_mv(s, &mx, &my, 0, left, top, tr);
00892             l += get_symbol(&s->c, &s->block_state[32], 1);
00893             cb+= get_symbol(&s->c, &s->block_state[64], 1);
00894             cr+= get_symbol(&s->c, &s->block_state[96], 1);
00895         }else{
00896             if(s->ref_frames > 1)
00897                 ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
00898             pred_mv(s, &mx, &my, ref, left, top, tr);
00899             mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
00900             my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);
00901         }
00902         set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
00903     }else{
00904         decode_q_branch(s, level+1, 2*x+0, 2*y+0);
00905         decode_q_branch(s, level+1, 2*x+1, 2*y+0);
00906         decode_q_branch(s, level+1, 2*x+0, 2*y+1);
00907         decode_q_branch(s, level+1, 2*x+1, 2*y+1);
00908     }
00909 }
00910 
00911 static void decode_blocks(SnowContext *s){
00912     int x, y;
00913     int w= s->b_width;
00914     int h= s->b_height;
00915 
00916     for(y=0; y<h; y++){
00917         for(x=0; x<w; x++){
00918             decode_q_branch(s, 0, x, y);
00919         }
00920     }
00921 }
00922 
00923 static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, uint8_t *tmp, int stride, int b_w, int b_h, int dx, int dy){
00924     static const uint8_t weight[64]={
00925     8,7,6,5,4,3,2,1,
00926     7,7,0,0,0,0,0,1,
00927     6,0,6,0,0,0,2,0,
00928     5,0,0,5,0,3,0,0,
00929     4,0,0,0,4,0,0,0,
00930     3,0,0,5,0,3,0,0,
00931     2,0,6,0,0,0,2,0,
00932     1,7,0,0,0,0,0,1,
00933     };
00934 
00935     static const uint8_t brane[256]={
00936     0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x11,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
00937     0x04,0x05,0xcc,0xcc,0xcc,0xcc,0xcc,0x41,0x15,0x16,0xcc,0xcc,0xcc,0xcc,0xcc,0x52,
00938     0x04,0xcc,0x05,0xcc,0xcc,0xcc,0x41,0xcc,0x15,0xcc,0x16,0xcc,0xcc,0xcc,0x52,0xcc,
00939     0x04,0xcc,0xcc,0x05,0xcc,0x41,0xcc,0xcc,0x15,0xcc,0xcc,0x16,0xcc,0x52,0xcc,0xcc,
00940     0x04,0xcc,0xcc,0xcc,0x41,0xcc,0xcc,0xcc,0x15,0xcc,0xcc,0xcc,0x16,0xcc,0xcc,0xcc,
00941     0x04,0xcc,0xcc,0x41,0xcc,0x05,0xcc,0xcc,0x15,0xcc,0xcc,0x52,0xcc,0x16,0xcc,0xcc,
00942     0x04,0xcc,0x41,0xcc,0xcc,0xcc,0x05,0xcc,0x15,0xcc,0x52,0xcc,0xcc,0xcc,0x16,0xcc,
00943     0x04,0x41,0xcc,0xcc,0xcc,0xcc,0xcc,0x05,0x15,0x52,0xcc,0xcc,0xcc,0xcc,0xcc,0x16,
00944     0x44,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x55,0x56,0x56,0x56,0x56,0x56,0x56,0x56,
00945     0x48,0x49,0xcc,0xcc,0xcc,0xcc,0xcc,0x85,0x59,0x5A,0xcc,0xcc,0xcc,0xcc,0xcc,0x96,
00946     0x48,0xcc,0x49,0xcc,0xcc,0xcc,0x85,0xcc,0x59,0xcc,0x5A,0xcc,0xcc,0xcc,0x96,0xcc,
00947     0x48,0xcc,0xcc,0x49,0xcc,0x85,0xcc,0xcc,0x59,0xcc,0xcc,0x5A,0xcc,0x96,0xcc,0xcc,
00948     0x48,0xcc,0xcc,0xcc,0x49,0xcc,0xcc,0xcc,0x59,0xcc,0xcc,0xcc,0x96,0xcc,0xcc,0xcc,
00949     0x48,0xcc,0xcc,0x85,0xcc,0x49,0xcc,0xcc,0x59,0xcc,0xcc,0x96,0xcc,0x5A,0xcc,0xcc,
00950     0x48,0xcc,0x85,0xcc,0xcc,0xcc,0x49,0xcc,0x59,0xcc,0x96,0xcc,0xcc,0xcc,0x5A,0xcc,
00951     0x48,0x85,0xcc,0xcc,0xcc,0xcc,0xcc,0x49,0x59,0x96,0xcc,0xcc,0xcc,0xcc,0xcc,0x5A,
00952     };
00953 
00954     static const uint8_t needs[16]={
00955     0,1,0,0,
00956     2,4,2,0,
00957     0,1,0,0,
00958     15
00959     };
00960 
00961     int x, y, b, r, l;
00962     int16_t tmpIt   [64*(32+HTAPS_MAX)];
00963     uint8_t tmp2t[3][stride*(32+HTAPS_MAX)];
00964     int16_t *tmpI= tmpIt;
00965     uint8_t *tmp2= tmp2t[0];
00966     const uint8_t *hpel[11];
00967     assert(dx<16 && dy<16);
00968     r= brane[dx + 16*dy]&15;
00969     l= brane[dx + 16*dy]>>4;
00970 
00971     b= needs[l] | needs[r];
00972     if(p && !p->diag_mc)
00973         b= 15;
00974 
00975     if(b&5){
00976         for(y=0; y < b_h+HTAPS_MAX-1; y++){
00977             for(x=0; x < b_w; x++){
00978                 int a_1=src[x + HTAPS_MAX/2-4];
00979                 int a0= src[x + HTAPS_MAX/2-3];
00980                 int a1= src[x + HTAPS_MAX/2-2];
00981                 int a2= src[x + HTAPS_MAX/2-1];
00982                 int a3= src[x + HTAPS_MAX/2+0];
00983                 int a4= src[x + HTAPS_MAX/2+1];
00984                 int a5= src[x + HTAPS_MAX/2+2];
00985                 int a6= src[x + HTAPS_MAX/2+3];
00986                 int am=0;
00987                 if(!p || p->fast_mc){
00988                     am= 20*(a2+a3) - 5*(a1+a4) + (a0+a5);
00989                     tmpI[x]= am;
00990                     am= (am+16)>>5;
00991                 }else{
00992                     am= p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6);
00993                     tmpI[x]= am;
00994                     am= (am+32)>>6;
00995                 }
00996 
00997                 if(am&(~255)) am= ~(am>>31);
00998                 tmp2[x]= am;
00999             }
01000             tmpI+= 64;
01001             tmp2+= stride;
01002             src += stride;
01003         }
01004         src -= stride*y;
01005     }
01006     src += HTAPS_MAX/2 - 1;
01007     tmp2= tmp2t[1];
01008 
01009     if(b&2){
01010         for(y=0; y < b_h; y++){
01011             for(x=0; x < b_w+1; x++){
01012                 int a_1=src[x + (HTAPS_MAX/2-4)*stride];
01013                 int a0= src[x + (HTAPS_MAX/2-3)*stride];
01014                 int a1= src[x + (HTAPS_MAX/2-2)*stride];
01015                 int a2= src[x + (HTAPS_MAX/2-1)*stride];
01016                 int a3= src[x + (HTAPS_MAX/2+0)*stride];
01017                 int a4= src[x + (HTAPS_MAX/2+1)*stride];
01018                 int a5= src[x + (HTAPS_MAX/2+2)*stride];
01019                 int a6= src[x + (HTAPS_MAX/2+3)*stride];
01020                 int am=0;
01021                 if(!p || p->fast_mc)
01022                     am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 16)>>5;
01023                 else
01024                     am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 32)>>6;
01025 
01026                 if(am&(~255)) am= ~(am>>31);
01027                 tmp2[x]= am;
01028             }
01029             src += stride;
01030             tmp2+= stride;
01031         }
01032         src -= stride*y;
01033     }
01034     src += stride*(HTAPS_MAX/2 - 1);
01035     tmp2= tmp2t[2];
01036     tmpI= tmpIt;
01037     if(b&4){
01038         for(y=0; y < b_h; y++){
01039             for(x=0; x < b_w; x++){
01040                 int a_1=tmpI[x + (HTAPS_MAX/2-4)*64];
01041                 int a0= tmpI[x + (HTAPS_MAX/2-3)*64];
01042                 int a1= tmpI[x + (HTAPS_MAX/2-2)*64];
01043                 int a2= tmpI[x + (HTAPS_MAX/2-1)*64];
01044                 int a3= tmpI[x + (HTAPS_MAX/2+0)*64];
01045                 int a4= tmpI[x + (HTAPS_MAX/2+1)*64];
01046                 int a5= tmpI[x + (HTAPS_MAX/2+2)*64];
01047                 int a6= tmpI[x + (HTAPS_MAX/2+3)*64];
01048                 int am=0;
01049                 if(!p || p->fast_mc)
01050                     am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 512)>>10;
01051                 else
01052                     am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 2048)>>12;
01053                 if(am&(~255)) am= ~(am>>31);
01054                 tmp2[x]= am;
01055             }
01056             tmpI+= 64;
01057             tmp2+= stride;
01058         }
01059     }
01060 
01061     hpel[ 0]= src;
01062     hpel[ 1]= tmp2t[0] + stride*(HTAPS_MAX/2-1);
01063     hpel[ 2]= src + 1;
01064 
01065     hpel[ 4]= tmp2t[1];
01066     hpel[ 5]= tmp2t[2];
01067     hpel[ 6]= tmp2t[1] + 1;
01068 
01069     hpel[ 8]= src + stride;
01070     hpel[ 9]= hpel[1] + stride;
01071     hpel[10]= hpel[8] + 1;
01072 
01073     if(b==15){
01074         const uint8_t *src1= hpel[dx/8 + dy/8*4  ];
01075         const uint8_t *src2= hpel[dx/8 + dy/8*4+1];
01076         const uint8_t *src3= hpel[dx/8 + dy/8*4+4];
01077         const uint8_t *src4= hpel[dx/8 + dy/8*4+5];
01078         dx&=7;
01079         dy&=7;
01080         for(y=0; y < b_h; y++){
01081             for(x=0; x < b_w; x++){
01082                 dst[x]= ((8-dx)*(8-dy)*src1[x] + dx*(8-dy)*src2[x]+
01083                          (8-dx)*   dy *src3[x] + dx*   dy *src4[x]+32)>>6;
01084             }
01085             src1+=stride;
01086             src2+=stride;
01087             src3+=stride;
01088             src4+=stride;
01089             dst +=stride;
01090         }
01091     }else{
01092         const uint8_t *src1= hpel[l];
01093         const uint8_t *src2= hpel[r];
01094         int a= weight[((dx&7) + (8*(dy&7)))];
01095         int b= 8-a;
01096         for(y=0; y < b_h; y++){
01097             for(x=0; x < b_w; x++){
01098                 dst[x]= (a*src1[x] + b*src2[x] + 4)>>3;
01099             }
01100             src1+=stride;
01101             src2+=stride;
01102             dst +=stride;
01103         }
01104     }
01105 }
01106 
01107 #define mca(dx,dy,b_w)\
01108 static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, int stride, int h){\
01109     uint8_t tmp[stride*(b_w+HTAPS_MAX-1)];\
01110     assert(h==b_w);\
01111     mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, tmp, stride, b_w, b_w, dx, dy);\
01112 }
01113 
01114 mca( 0, 0,16)
01115 mca( 8, 0,16)
01116 mca( 0, 8,16)
01117 mca( 8, 8,16)
01118 mca( 0, 0,8)
01119 mca( 8, 0,8)
01120 mca( 0, 8,8)
01121 mca( 8, 8,8)
01122 
01123 static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){
01124     if(block->type & BLOCK_INTRA){
01125         int x, y;
01126         const int color = block->color[plane_index];
01127         const int color4= color*0x01010101;
01128         if(b_w==32){
01129             for(y=0; y < b_h; y++){
01130                 *(uint32_t*)&dst[0 + y*stride]= color4;
01131                 *(uint32_t*)&dst[4 + y*stride]= color4;
01132                 *(uint32_t*)&dst[8 + y*stride]= color4;
01133                 *(uint32_t*)&dst[12+ y*stride]= color4;
01134                 *(uint32_t*)&dst[16+ y*stride]= color4;
01135                 *(uint32_t*)&dst[20+ y*stride]= color4;
01136                 *(uint32_t*)&dst[24+ y*stride]= color4;
01137                 *(uint32_t*)&dst[28+ y*stride]= color4;
01138             }
01139         }else if(b_w==16){
01140             for(y=0; y < b_h; y++){
01141                 *(uint32_t*)&dst[0 + y*stride]= color4;
01142                 *(uint32_t*)&dst[4 + y*stride]= color4;
01143                 *(uint32_t*)&dst[8 + y*stride]= color4;
01144                 *(uint32_t*)&dst[12+ y*stride]= color4;
01145             }
01146         }else if(b_w==8){
01147             for(y=0; y < b_h; y++){
01148                 *(uint32_t*)&dst[0 + y*stride]= color4;
01149                 *(uint32_t*)&dst[4 + y*stride]= color4;
01150             }
01151         }else if(b_w==4){
01152             for(y=0; y < b_h; y++){
01153                 *(uint32_t*)&dst[0 + y*stride]= color4;
01154             }
01155         }else{
01156             for(y=0; y < b_h; y++){
01157                 for(x=0; x < b_w; x++){
01158                     dst[x + y*stride]= color;
01159                 }
01160             }
01161         }
01162     }else{
01163         uint8_t *src= s->last_picture[block->ref].data[plane_index];
01164         const int scale= plane_index ?  s->mv_scale : 2*s->mv_scale;
01165         int mx= block->mx*scale;
01166         int my= block->my*scale;
01167         const int dx= mx&15;
01168         const int dy= my&15;
01169         const int tab_index= 3 - (b_w>>2) + (b_w>>4);
01170         sx += (mx>>4) - (HTAPS_MAX/2-1);
01171         sy += (my>>4) - (HTAPS_MAX/2-1);
01172         src += sx + sy*stride;
01173         if(   (unsigned)sx >= w - b_w - (HTAPS_MAX-2)
01174            || (unsigned)sy >= h - b_h - (HTAPS_MAX-2)){
01175             ff_emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h);
01176             src= tmp + MB_SIZE;
01177         }
01178 //        assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h);
01179 //        assert(!(b_w&(b_w-1)));
01180         assert(b_w>1 && b_h>1);
01181         assert((tab_index>=0 && tab_index<4) || b_w==32);
01182         if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1)) || !s->plane[plane_index].fast_mc )
01183             mc_block(&s->plane[plane_index], dst, src, tmp, stride, b_w, b_h, dx, dy);
01184         else if(b_w==32){
01185             int y;
01186             for(y=0; y<b_h; y+=16){
01187                 s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride);
01188                 s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride);
01189             }
01190         }else if(b_w==b_h)
01191             s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride);
01192         else if(b_w==2*b_h){
01193             s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst    ,src + 3       + 3*stride,stride);
01194             s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride);
01195         }else{
01196             assert(2*b_w==b_h);
01197             s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst           ,src + 3 + 3*stride           ,stride);
01198             s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride);
01199         }
01200     }
01201 }
01202 
01203 void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h,
01204                               int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){
01205     int y, x;
01206     IDWTELEM * dst;
01207     for(y=0; y<b_h; y++){
01208         //FIXME ugly misuse of obmc_stride
01209         const uint8_t *obmc1= obmc + y*obmc_stride;
01210         const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
01211         const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
01212         const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
01213         dst = slice_buffer_get_line(sb, src_y + y);
01214         for(x=0; x<b_w; x++){
01215             int v=   obmc1[x] * block[3][x + y*src_stride]
01216                     +obmc2[x] * block[2][x + y*src_stride]
01217                     +obmc3[x] * block[1][x + y*src_stride]
01218                     +obmc4[x] * block[0][x + y*src_stride];
01219 
01220             v <<= 8 - LOG2_OBMC_MAX;
01221             if(FRAC_BITS != 8){
01222                 v >>= 8 - FRAC_BITS;
01223             }
01224             if(add){
01225                 v += dst[x + src_x];
01226                 v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
01227                 if(v&(~255)) v= ~(v>>31);
01228                 dst8[x + y*src_stride] = v;
01229             }else{
01230                 dst[x + src_x] -= v;
01231             }
01232         }
01233     }
01234 }
01235 
01236 //FIXME name cleanup (b_w, block_w, b_width stuff)
01237 static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *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){
01238     const int b_width = s->b_width  << s->block_max_depth;
01239     const int b_height= s->b_height << s->block_max_depth;
01240     const int b_stride= b_width;
01241     BlockNode *lt= &s->block[b_x + b_y*b_stride];
01242     BlockNode *rt= lt+1;
01243     BlockNode *lb= lt+b_stride;
01244     BlockNode *rb= lb+1;
01245     uint8_t *block[4];
01246     int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride;
01247     uint8_t *tmp = s->scratchbuf;
01248     uint8_t *ptmp;
01249     int x,y;
01250 
01251     if(b_x<0){
01252         lt= rt;
01253         lb= rb;
01254     }else if(b_x + 1 >= b_width){
01255         rt= lt;
01256         rb= lb;
01257     }
01258     if(b_y<0){
01259         lt= lb;
01260         rt= rb;
01261     }else if(b_y + 1 >= b_height){
01262         lb= lt;
01263         rb= rt;
01264     }
01265 
01266     if(src_x<0){ //FIXME merge with prev & always round internal width up to *16
01267         obmc -= src_x;
01268         b_w += src_x;
01269         if(!sliced && !offset_dst)
01270             dst -= src_x;
01271         src_x=0;
01272     }else if(src_x + b_w > w){
01273         b_w = w - src_x;
01274     }
01275     if(src_y<0){
01276         obmc -= src_y*obmc_stride;
01277         b_h += src_y;
01278         if(!sliced && !offset_dst)
01279             dst -= src_y*dst_stride;
01280         src_y=0;
01281     }else if(src_y + b_h> h){
01282         b_h = h - src_y;
01283     }
01284 
01285     if(b_w<=0 || b_h<=0) return;
01286 
01287     assert(src_stride > 2*MB_SIZE + 5);
01288 
01289     if(!sliced && offset_dst)
01290         dst += src_x + src_y*dst_stride;
01291     dst8+= src_x + src_y*src_stride;
01292 //    src += src_x + src_y*src_stride;
01293 
01294     ptmp= tmp + 3*tmp_step;
01295     block[0]= ptmp;
01296     ptmp+=tmp_step;
01297     pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h);
01298 
01299     if(same_block(lt, rt)){
01300         block[1]= block[0];
01301     }else{
01302         block[1]= ptmp;
01303         ptmp+=tmp_step;
01304         pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h);
01305     }
01306 
01307     if(same_block(lt, lb)){
01308         block[2]= block[0];
01309     }else if(same_block(rt, lb)){
01310         block[2]= block[1];
01311     }else{
01312         block[2]= ptmp;
01313         ptmp+=tmp_step;
01314         pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h);
01315     }
01316 
01317     if(same_block(lt, rb) ){
01318         block[3]= block[0];
01319     }else if(same_block(rt, rb)){
01320         block[3]= block[1];
01321     }else if(same_block(lb, rb)){
01322         block[3]= block[2];
01323     }else{
01324         block[3]= ptmp;
01325         pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h);
01326     }
01327 #if 0
01328     for(y=0; y<b_h; y++){
01329         for(x=0; x<b_w; x++){
01330             int v=   obmc [x + y*obmc_stride] * block[3][x + y*src_stride] * (256/OBMC_MAX);
01331             if(add) dst[x + y*dst_stride] += v;
01332             else    dst[x + y*dst_stride] -= v;
01333         }
01334     }
01335     for(y=0; y<b_h; y++){
01336         uint8_t *obmc2= obmc + (obmc_stride>>1);
01337         for(x=0; x<b_w; x++){
01338             int v=   obmc2[x + y*obmc_stride] * block[2][x + y*src_stride] * (256/OBMC_MAX);
01339             if(add) dst[x + y*dst_stride] += v;
01340             else    dst[x + y*dst_stride] -= v;
01341         }
01342     }
01343     for(y=0; y<b_h; y++){
01344         uint8_t *obmc3= obmc + obmc_stride*(obmc_stride>>1);
01345         for(x=0; x<b_w; x++){
01346             int v=   obmc3[x + y*obmc_stride] * block[1][x + y*src_stride] * (256/OBMC_MAX);
01347             if(add) dst[x + y*dst_stride] += v;
01348             else    dst[x + y*dst_stride] -= v;
01349         }
01350     }
01351     for(y=0; y<b_h; y++){
01352         uint8_t *obmc3= obmc + obmc_stride*(obmc_stride>>1);
01353         uint8_t *obmc4= obmc3+ (obmc_stride>>1);
01354         for(x=0; x<b_w; x++){
01355             int v=   obmc4[x + y*obmc_stride] * block[0][x + y*src_stride] * (256/OBMC_MAX);
01356             if(add) dst[x + y*dst_stride] += v;
01357             else    dst[x + y*dst_stride] -= v;
01358         }
01359     }
01360 #else
01361     if(sliced){
01362         s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
01363     }else{
01364         for(y=0; y<b_h; y++){
01365             //FIXME ugly misuse of obmc_stride
01366             const uint8_t *obmc1= obmc + y*obmc_stride;
01367             const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
01368             const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
01369             const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
01370             for(x=0; x<b_w; x++){
01371                 int v=   obmc1[x] * block[3][x + y*src_stride]
01372                         +obmc2[x] * block[2][x + y*src_stride]
01373                         +obmc3[x] * block[1][x + y*src_stride]
01374                         +obmc4[x] * block[0][x + y*src_stride];
01375 
01376                 v <<= 8 - LOG2_OBMC_MAX;
01377                 if(FRAC_BITS != 8){
01378                     v >>= 8 - FRAC_BITS;
01379                 }
01380                 if(add){
01381                     v += dst[x + y*dst_stride];
01382                     v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
01383                     if(v&(~255)) v= ~(v>>31);
01384                     dst8[x + y*src_stride] = v;
01385                 }else{
01386                     dst[x + y*dst_stride] -= v;
01387                 }
01388             }
01389         }
01390     }
01391 #endif /* 0 */
01392 }
01393 
01394 static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){
01395     Plane *p= &s->plane[plane_index];
01396     const int mb_w= s->b_width  << s->block_max_depth;
01397     const int mb_h= s->b_height << s->block_max_depth;
01398     int x, y, mb_x;
01399     int block_size = MB_SIZE >> s->block_max_depth;
01400     int block_w    = plane_index ? block_size/2 : block_size;
01401     const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
01402     int obmc_stride= plane_index ? block_size : 2*block_size;
01403     int ref_stride= s->current_picture.linesize[plane_index];
01404     uint8_t *dst8= s->current_picture.data[plane_index];
01405     int w= p->width;
01406     int h= p->height;
01407 
01408     if(s->keyframe || (s->avctx->debug&512)){
01409         if(mb_y==mb_h)
01410             return;
01411 
01412         if(add){
01413             for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
01414 //                DWTELEM * line = slice_buffer_get_line(sb, y);
01415                 IDWTELEM * line = sb->line[y];
01416                 for(x=0; x<w; x++){
01417 //                    int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
01418                     int v= line[x] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
01419                     v >>= FRAC_BITS;
01420                     if(v&(~255)) v= ~(v>>31);
01421                     dst8[x + y*ref_stride]= v;
01422                 }
01423             }
01424         }else{
01425             for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
01426 //                DWTELEM * line = slice_buffer_get_line(sb, y);
01427                 IDWTELEM * line = sb->line[y];
01428                 for(x=0; x<w; x++){
01429                     line[x] -= 128 << FRAC_BITS;
01430 //                    buf[x + y*w]-= 128<<FRAC_BITS;
01431                 }
01432             }
01433         }
01434 
01435         return;
01436     }
01437 
01438     for(mb_x=0; mb_x<=mb_w; mb_x++){
01439         add_yblock(s, 1, sb, old_buffer, dst8, obmc,
01440                    block_w*mb_x - block_w/2,
01441                    block_w*mb_y - block_w/2,
01442                    block_w, block_w,
01443                    w, h,
01444                    w, ref_stride, obmc_stride,
01445                    mb_x - 1, mb_y - 1,
01446                    add, 0, plane_index);
01447     }
01448 }
01449 
01450 static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){
01451     Plane *p= &s->plane[plane_index];
01452     const int mb_w= s->b_width  << s->block_max_depth;
01453     const int mb_h= s->b_height << s->block_max_depth;
01454     int x, y, mb_x;
01455     int block_size = MB_SIZE >> s->block_max_depth;
01456     int block_w    = plane_index ? block_size/2 : block_size;
01457     const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
01458     const int obmc_stride= plane_index ? block_size : 2*block_size;
01459     int ref_stride= s->current_picture.linesize[plane_index];
01460     uint8_t *dst8= s->current_picture.data[plane_index];
01461     int w= p->width;
01462     int h= p->height;
01463 
01464     if(s->keyframe || (s->avctx->debug&512)){
01465         if(mb_y==mb_h)
01466             return;
01467 
01468         if(add){
01469             for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
01470                 for(x=0; x<w; x++){
01471                     int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
01472                     v >>= FRAC_BITS;
01473                     if(v&(~255)) v= ~(v>>31);
01474                     dst8[x + y*ref_stride]= v;
01475                 }
01476             }
01477         }else{
01478             for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
01479                 for(x=0; x<w; x++){
01480                     buf[x + y*w]-= 128<<FRAC_BITS;
01481                 }
01482             }
01483         }
01484 
01485         return;
01486     }
01487 
01488     for(mb_x=0; mb_x<=mb_w; mb_x++){
01489         add_yblock(s, 0, NULL, buf, dst8, obmc,
01490                    block_w*mb_x - block_w/2,
01491                    block_w*mb_y - block_w/2,
01492                    block_w, block_w,
01493                    w, h,
01494                    w, ref_stride, obmc_stride,
01495                    mb_x - 1, mb_y - 1,
01496                    add, 1, plane_index);
01497     }
01498 }
01499 
01500 static av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){
01501     const int mb_h= s->b_height << s->block_max_depth;
01502     int mb_y;
01503     for(mb_y=0; mb_y<=mb_h; mb_y++)
01504         predict_slice(s, buf, plane_index, add, mb_y);
01505 }
01506 
01507 static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){
01508     const int w= b->width;
01509     const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
01510     const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
01511     const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
01512     int x,y;
01513 
01514     if(s->qlog == LOSSLESS_QLOG) return;
01515 
01516     for(y=start_y; y<end_y; y++){
01517 //        DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
01518         IDWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
01519         for(x=0; x<w; x++){
01520             int i= line[x];
01521             if(i<0){
01522                 line[x]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
01523             }else if(i>0){
01524                 line[x]=  (( i*qmul + qadd)>>(QEXPSHIFT));
01525             }
01526         }
01527     }
01528 }
01529 
01530 static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){
01531     const int w= b->width;
01532     int x,y;
01533 
01534     IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning
01535     IDWTELEM * prev;
01536 
01537     if (start_y != 0)
01538         line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
01539 
01540     for(y=start_y; y<end_y; y++){
01541         prev = line;
01542 //        line = slice_buffer_get_line_from_address(sb, src + (y * stride));
01543         line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
01544         for(x=0; x<w; x++){
01545             if(x){
01546                 if(use_median){
01547                     if(y && x+1<w) line[x] += mid_pred(line[x - 1], prev[x], prev[x + 1]);
01548                     else  line[x] += line[x - 1];
01549                 }else{
01550                     if(y) line[x] += mid_pred(line[x - 1], prev[x], line[x - 1] + prev[x] - prev[x - 1]);
01551                     else  line[x] += line[x - 1];
01552                 }
01553             }else{
01554                 if(y) line[x] += prev[x];
01555             }
01556         }
01557     }
01558 }
01559 
01560 static void decode_qlogs(SnowContext *s){
01561     int plane_index, level, orientation;
01562 
01563     for(plane_index=0; plane_index<3; plane_index++){
01564         for(level=0; level<s->spatial_decomposition_count; level++){
01565             for(orientation=level ? 1:0; orientation<4; orientation++){
01566                 int q;
01567                 if     (plane_index==2) q= s->plane[1].band[level][orientation].qlog;
01568                 else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog;
01569                 else                    q= get_symbol(&s->c, s->header_state, 1);
01570                 s->plane[plane_index].band[level][orientation].qlog= q;
01571             }
01572         }
01573     }
01574 }
01575 
01576 #define GET_S(dst, check) \
01577     tmp= get_symbol(&s->c, s->header_state, 0);\
01578     if(!(check)){\
01579         av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\
01580         return -1;\
01581     }\
01582     dst= tmp;
01583 
01584 static int decode_header(SnowContext *s){
01585     int plane_index, tmp;
01586     uint8_t kstate[32];
01587 
01588     memset(kstate, MID_STATE, sizeof(kstate));
01589 
01590     s->keyframe= get_rac(&s->c, kstate);
01591     if(s->keyframe || s->always_reset){
01592         reset_contexts(s);
01593         s->spatial_decomposition_type=
01594         s->qlog=
01595         s->qbias=
01596         s->mv_scale=
01597         s->block_max_depth= 0;
01598     }
01599     if(s->keyframe){
01600         GET_S(s->version, tmp <= 0U)
01601         s->always_reset= get_rac(&s->c, s->header_state);
01602         s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0);
01603         s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0);
01604         GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
01605         s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
01606         s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
01607         s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
01608         s->spatial_scalability= get_rac(&s->c, s->header_state);
01609 //        s->rate_scalability= get_rac(&s->c, s->header_state);
01610         GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES)
01611         s->max_ref_frames++;
01612 
01613         decode_qlogs(s);
01614     }
01615 
01616     if(!s->keyframe){
01617         if(get_rac(&s->c, s->header_state)){
01618             for(plane_index=0; plane_index<2; plane_index++){
01619                 int htaps, i, sum=0;
01620                 Plane *p= &s->plane[plane_index];
01621                 p->diag_mc= get_rac(&s->c, s->header_state);
01622                 htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2;
01623                 if((unsigned)htaps > HTAPS_MAX || htaps==0)
01624                     return -1;
01625                 p->htaps= htaps;
01626                 for(i= htaps/2; i; i--){
01627                     p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1));
01628                     sum += p->hcoeff[i];
01629                 }
01630                 p->hcoeff[0]= 32-sum;
01631             }
01632             s->plane[2].diag_mc= s->plane[1].diag_mc;
01633             s->plane[2].htaps  = s->plane[1].htaps;
01634             memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff));
01635         }
01636         if(get_rac(&s->c, s->header_state)){
01637             GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
01638             decode_qlogs(s);
01639         }
01640     }
01641 
01642     s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1);
01643     if(s->spatial_decomposition_type > 1U){
01644         av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported", s->spatial_decomposition_type);
01645         return -1;
01646     }
01647     if(FFMIN(s->avctx-> width>>s->chroma_h_shift,
01648              s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 0){
01649         av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size", s->spatial_decomposition_count);
01650         return -1;
01651     }
01652 
01653     s->qlog           += get_symbol(&s->c, s->header_state, 1);
01654     s->mv_scale       += get_symbol(&s->c, s->header_state, 1);
01655     s->qbias          += get_symbol(&s->c, s->header_state, 1);
01656     s->block_max_depth+= get_symbol(&s->c, s->header_state, 1);
01657     if(s->block_max_depth > 1 || s->block_max_depth < 0){
01658         av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large", s->block_max_depth);
01659         s->block_max_depth= 0;
01660         return -1;
01661     }
01662 
01663     return 0;
01664 }
01665 
01666 static void init_qexp(void){
01667     int i;
01668     double v=128;
01669 
01670     for(i=0; i<QROOT; i++){
01671         qexp[i]= lrintf(v);
01672         v *= pow(2, 1.0 / QROOT);
01673     }
01674 }
01675 
01676 static av_cold int common_init(AVCodecContext *avctx){
01677     SnowContext *s = avctx->priv_data;
01678     int width, height;
01679     int i, j;
01680 
01681     s->avctx= avctx;
01682     s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe
01683 
01684     dsputil_init(&s->dsp, avctx);
01685     ff_dwt_init(&s->dwt);
01686 
01687 #define mcf(dx,dy)\
01688     s->dsp.put_qpel_pixels_tab       [0][dy+dx/4]=\
01689     s->dsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\
01690         s->dsp.put_h264_qpel_pixels_tab[0][dy+dx/4];\
01691     s->dsp.put_qpel_pixels_tab       [1][dy+dx/4]=\
01692     s->dsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\
01693         s->dsp.put_h264_qpel_pixels_tab[1][dy+dx/4];
01694 
01695     mcf( 0, 0)
01696     mcf( 4, 0)
01697     mcf( 8, 0)
01698     mcf(12, 0)
01699     mcf( 0, 4)
01700     mcf( 4, 4)
01701     mcf( 8, 4)
01702     mcf(12, 4)
01703     mcf( 0, 8)
01704     mcf( 4, 8)
01705     mcf( 8, 8)
01706     mcf(12, 8)
01707     mcf( 0,12)
01708     mcf( 4,12)
01709     mcf( 8,12)
01710     mcf(12,12)
01711 
01712 #define mcfh(dx,dy)\
01713     s->dsp.put_pixels_tab       [0][dy/4+dx/8]=\
01714     s->dsp.put_no_rnd_pixels_tab[0][dy/4+dx/8]=\
01715         mc_block_hpel ## dx ## dy ## 16;\
01716     s->dsp.put_pixels_tab       [1][dy/4+dx/8]=\
01717     s->dsp.put_no_rnd_pixels_tab[1][dy/4+dx/8]=\
01718         mc_block_hpel ## dx ## dy ## 8;
01719 
01720     mcfh(0, 0)
01721     mcfh(8, 0)
01722     mcfh(0, 8)
01723     mcfh(8, 8)
01724 
01725     if(!qexp[0])
01726         init_qexp();
01727 
01728 //    dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift);
01729 
01730     width= s->avctx->width;
01731     height= s->avctx->height;
01732 
01733     s->spatial_idwt_buffer= av_mallocz(width*height*sizeof(IDWTELEM));
01734     s->spatial_dwt_buffer= av_mallocz(width*height*sizeof(DWTELEM)); //FIXME this does not belong here
01735 
01736     for(i=0; i<MAX_REF_FRAMES; i++)
01737         for(j=0; j<MAX_REF_FRAMES; j++)
01738             scale_mv_ref[i][j] = 256*(i+1)/(j+1);
01739 
01740     s->avctx->get_buffer(s->avctx, &s->mconly_picture);
01741     s->scratchbuf = av_malloc(s->mconly_picture.linesize[0]*7*MB_SIZE);
01742 
01743     return 0;
01744 }
01745 
01746 static int common_init_after_header(AVCodecContext *avctx){
01747     SnowContext *s = avctx->priv_data;
01748     int plane_index, level, orientation;
01749 
01750     for(plane_index=0; plane_index<3; plane_index++){
01751         int w= s->avctx->width;
01752         int h= s->avctx->height;
01753 
01754         if(plane_index){
01755             w>>= s->chroma_h_shift;
01756             h>>= s->chroma_v_shift;
01757         }
01758         s->plane[plane_index].width = w;
01759         s->plane[plane_index].height= h;
01760 
01761         for(level=s->spatial_decomposition_count-1; level>=0; level--){
01762             for(orientation=level ? 1 : 0; orientation<4; orientation++){
01763                 SubBand *b= &s->plane[plane_index].band[level][orientation];
01764 
01765                 b->buf= s->spatial_dwt_buffer;
01766                 b->level= level;
01767                 b->stride= s->plane[plane_index].width << (s->spatial_decomposition_count - level);
01768                 b->width = (w + !(orientation&1))>>1;
01769                 b->height= (h + !(orientation>1))>>1;
01770 
01771                 b->stride_line = 1 << (s->spatial_decomposition_count - level);
01772                 b->buf_x_offset = 0;
01773                 b->buf_y_offset = 0;
01774 
01775                 if(orientation&1){
01776                     b->buf += (w+1)>>1;
01777                     b->buf_x_offset = (w+1)>>1;
01778                 }
01779                 if(orientation>1){
01780                     b->buf += b->stride>>1;
01781                     b->buf_y_offset = b->stride_line >> 1;
01782                 }
01783                 b->ibuf= s->spatial_idwt_buffer + (b->buf - s->spatial_dwt_buffer);
01784 
01785                 if(level)
01786                     b->parent= &s->plane[plane_index].band[level-1][orientation];
01787                 //FIXME avoid this realloc
01788                 av_freep(&b->x_coeff);
01789                 b->x_coeff=av_mallocz(((b->width+1) * b->height+1)*sizeof(x_and_coeff));
01790             }
01791             w= (w+1)>>1;
01792             h= (h+1)>>1;
01793         }
01794     }
01795 
01796     return 0;
01797 }
01798 
01799 #define QUANTIZE2 0
01800 
01801 #if QUANTIZE2==1
01802 #define Q2_STEP 8
01803 
01804 static void find_sse(SnowContext *s, Plane *p, int *score, int score_stride, IDWTELEM *r0, IDWTELEM *r1, int level, int orientation){
01805     SubBand *b= &p->band[level][orientation];
01806     int x, y;
01807     int xo=0;
01808     int yo=0;
01809     int step= 1 << (s->spatial_decomposition_count - level);
01810 
01811     if(orientation&1)
01812         xo= step>>1;
01813     if(orientation&2)
01814         yo= step>>1;
01815 
01816     //FIXME bias for nonzero ?
01817     //FIXME optimize
01818     memset(score, 0, sizeof(*score)*score_stride*((p->height + Q2_STEP-1)/Q2_STEP));
01819     for(y=0; y<p->height; y++){
01820         for(x=0; x<p->width; x++){
01821             int sx= (x-xo + step/2) / step / Q2_STEP;
01822             int sy= (y-yo + step/2) / step / Q2_STEP;
01823             int v= r0[x + y*p->width] - r1[x + y*p->width];
01824             assert(sx>=0 && sy>=0 && sx < score_stride);
01825             v= ((v+8)>>4)<<4;
01826             score[sx + sy*score_stride] += v*v;
01827             assert(score[sx + sy*score_stride] >= 0);
01828         }
01829     }
01830 }
01831 
01832 static void dequantize_all(SnowContext *s, Plane *p, IDWTELEM *buffer, int width, int height){
01833     int level, orientation;
01834 
01835     for(level=0; level<s->spatial_decomposition_count; level++){
01836         for(orientation=level ? 1 : 0; orientation<4; orientation++){
01837             SubBand *b= &p->band[level][orientation];
01838             IDWTELEM *dst= buffer + (b->ibuf - s->spatial_idwt_buffer);
01839 
01840             dequantize(s, b, dst, b->stride);
01841         }
01842     }
01843 }
01844 
01845 static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, int height, int stride, int type){
01846     int level, orientation, ys, xs, x, y, pass;
01847     IDWTELEM best_dequant[height * stride];
01848     IDWTELEM idwt2_buffer[height * stride];
01849     const int score_stride= (width + 10)/Q2_STEP;
01850     int best_score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size
01851     int score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size
01852     int threshold= (s->m.lambda * s->m.lambda) >> 6;
01853 
01854     //FIXME pass the copy cleanly ?
01855 
01856 //    memcpy(dwt_buffer, buffer, height * stride * sizeof(DWTELEM));
01857     ff_spatial_dwt(buffer, width, height, stride, type, s->spatial_decomposition_count);
01858 
01859     for(level=0; level<s->spatial_decomposition_count; level++){
01860         for(orientation=level ? 1 : 0; orientation<4; orientation++){
01861             SubBand *b= &p->band[level][orientation];
01862             IDWTELEM *dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer);
01863              DWTELEM *src=       buffer + (b-> buf - s->spatial_dwt_buffer);
01864             assert(src == b->buf); // code does not depend on this but it is true currently
01865 
01866             quantize(s, b, dst, src, b->stride, s->qbias);
01867         }
01868     }
01869     for(pass=0; pass<1; pass++){
01870         if(s->qbias == 0) //keyframe
01871             continue;
01872         for(level=0; level<s->spatial_decomposition_count; level++){
01873             for(orientation=level ? 1 : 0; orientation<4; orientation++){
01874                 SubBand *b= &p->band[level][orientation];
01875                 IDWTELEM *dst= idwt2_buffer + (b->ibuf - s->spatial_idwt_buffer);
01876                 IDWTELEM *best_dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer);
01877 
01878                 for(ys= 0; ys<Q2_STEP; ys++){
01879                     for(xs= 0; xs<Q2_STEP; xs++){
01880                         memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
01881                         dequantize_all(s, p, idwt2_buffer, width, height);
01882                         ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count);
01883                         find_sse(s, p, best_score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
01884                         memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
01885                         for(y=ys; y<b->height; y+= Q2_STEP){
01886                             for(x=xs; x<b->width; x+= Q2_STEP){
01887                                 if(dst[x + y*b->stride]<0) dst[x + y*b->stride]++;
01888                                 if(dst[x + y*b->stride]>0) dst[x + y*b->stride]--;
01889                                 //FIXME try more than just --
01890                             }
01891                         }
01892                         dequantize_all(s, p, idwt2_buffer, width, height);
01893                         ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count);
01894                         find_sse(s, p, score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
01895                         for(y=ys; y<b->height; y+= Q2_STEP){
01896                             for(x=xs; x<b->width; x+= Q2_STEP){
01897                                 int score_idx= x/Q2_STEP + (y/Q2_STEP)*score_stride;
01898                                 if(score[score_idx] <= best_score[score_idx] + threshold){
01899                                     best_score[score_idx]= score[score_idx];
01900                                     if(best_dst[x + y*b->stride]<0) best_dst[x + y*b->stride]++;
01901                                     if(best_dst[x + y*b->stride]>0) best_dst[x + y*b->stride]--;
01902                                     //FIXME copy instead
01903                                 }
01904                             }
01905                         }
01906                     }
01907                 }
01908             }
01909         }
01910     }
01911     memcpy(s->spatial_idwt_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); //FIXME work with that directly instead of copy at the end
01912 }
01913 
01914 #endif /* QUANTIZE2==1 */
01915 
01916 #define USE_HALFPEL_PLANE 0
01917 
01918 static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){
01919     int p,x,y;
01920 
01921     assert(!(s->avctx->flags & CODEC_FLAG_EMU_EDGE));
01922 
01923     for(p=0; p<3; p++){
01924         int is_chroma= !!p;
01925         int w= s->avctx->width  >>is_chroma;
01926         int h= s->avctx->height >>is_chroma;
01927         int ls= frame->linesize[p];
01928         uint8_t *src= frame->data[p];
01929 
01930         halfpel[1][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls);
01931         halfpel[2][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls);
01932         halfpel[3][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls);
01933 
01934         halfpel[0][p]= src;
01935         for(y=0; y<h; y++){
01936             for(x=0; x<w; x++){
01937                 int i= y*ls + x;
01938 
01939                 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;
01940             }
01941         }
01942         for(y=0; y<h; y++){
01943             for(x=0; x<w; x++){
01944                 int i= y*ls + x;
01945 
01946                 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;
01947             }
01948         }
01949         src= halfpel[1][p];
01950         for(y=0; y<h; y++){
01951             for(x=0; x<w; x++){
01952                 int i= y*ls + x;
01953 
01954                 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;
01955             }
01956         }
01957 
01958 //FIXME border!
01959     }
01960 }
01961 
01962 static void release_buffer(AVCodecContext *avctx){
01963     SnowContext *s = avctx->priv_data;
01964     int i;
01965 
01966     if(s->last_picture[s->max_ref_frames-1].data[0]){
01967         avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]);
01968         for(i=0; i<9; i++)
01969             if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3])
01970                 av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3]));
01971     }
01972 }
01973 
01974 static int frame_start(SnowContext *s){
01975    AVFrame tmp;
01976    int w= s->avctx->width; //FIXME round up to x16 ?
01977    int h= s->avctx->height;
01978 
01979     if(s->current_picture.data[0]){
01980         s->dsp.draw_edges(s->current_picture.data[0], s->current_picture.linesize[0], w   , h   , EDGE_WIDTH  );
01981         s->dsp.draw_edges(s->current_picture.data[1], s->current_picture.linesize[1], w>>1, h>>1, EDGE_WIDTH/2);
01982         s->dsp.draw_edges(s->current_picture.data[2], s->current_picture.linesize[2], w>>1, h>>1, EDGE_WIDTH/2);
01983     }
01984 
01985     release_buffer(s->avctx);
01986 
01987     tmp= s->last_picture[s->max_ref_frames-1];
01988     memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame));
01989     memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);
01990     if(USE_HALFPEL_PLANE && s->current_picture.data[0])
01991         halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture);
01992     s->last_picture[0]= s->current_picture;
01993     s->current_picture= tmp;
01994 
01995     if(s->keyframe){
01996         s->ref_frames= 0;
01997     }else{
01998         int i;
01999         for(i=0; i<s->max_ref_frames && s->last_picture[i].data[0]; i++)
02000             if(i && s->last_picture[i-1].key_frame)
02001                 break;
02002         s->ref_frames= i;
02003         if(s->ref_frames==0){
02004             av_log(s->avctx,AV_LOG_ERROR, "No reference frames\n");
02005             return -1;
02006         }
02007     }
02008 
02009     s->current_picture.reference= 1;
02010     if(s->avctx->get_buffer(s->avctx, &s->current_picture) < 0){
02011         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
02012         return -1;
02013     }
02014 
02015     s->current_picture.key_frame= s->keyframe;
02016 
02017     return 0;
02018 }
02019 
02020 static av_cold void common_end(SnowContext *s){
02021     int plane_index, level, orientation, i;
02022 
02023     av_freep(&s->spatial_dwt_buffer);
02024     av_freep(&s->spatial_idwt_buffer);
02025 
02026     s->m.me.temp= NULL;
02027     av_freep(&s->m.me.scratchpad);
02028     av_freep(&s->m.me.map);
02029     av_freep(&s->m.me.score_map);
02030     av_freep(&s->m.obmc_scratchpad);
02031 
02032     av_freep(&s->block);
02033     av_freep(&s->scratchbuf);
02034 
02035     for(i=0; i<MAX_REF_FRAMES; i++){
02036         av_freep(&s->ref_mvs[i]);
02037         av_freep(&s->ref_scores[i]);
02038         if(s->last_picture[i].data[0])
02039             s->avctx->release_buffer(s->avctx, &s->last_picture[i]);
02040     }
02041 
02042     for(plane_index=0; plane_index<3; plane_index++){
02043         for(level=s->spatial_decomposition_count-1; level>=0; level--){
02044             for(orientation=level ? 1 : 0; orientation<4; orientation++){
02045                 SubBand *b= &s->plane[plane_index].band[level][orientation];
02046 
02047                 av_freep(&b->x_coeff);
02048             }
02049         }
02050     }
02051     if (s->mconly_picture.data[0])
02052         s->avctx->release_buffer(s->avctx, &s->mconly_picture);
02053     if (s->current_picture.data[0])
02054         s->avctx->release_buffer(s->avctx, &s->current_picture);
02055 }
02056 
02057 static av_cold int decode_init(AVCodecContext *avctx)
02058 {
02059     avctx->pix_fmt= PIX_FMT_YUV420P;
02060 
02061     common_init(avctx);
02062 
02063     return 0;
02064 }
02065 
02066 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){
02067     const uint8_t *buf = avpkt->data;
02068     int buf_size = avpkt->size;
02069     SnowContext *s = avctx->priv_data;
02070     RangeCoder * const c= &s->c;
02071     int bytes_read;
02072     AVFrame *picture = data;
02073     int level, orientation, plane_index;
02074 
02075     ff_init_range_decoder(c, buf, buf_size);
02076     ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
02077 
02078     s->current_picture.pict_type= FF_I_TYPE; //FIXME I vs. P
02079     if(decode_header(s)<0)
02080         return -1;
02081     common_init_after_header(avctx);
02082 
02083     // realloc slice buffer for the case that spatial_decomposition_count changed
02084     ff_slice_buffer_destroy(&s->sb);
02085     ff_slice_buffer_init(&s->sb, s->plane[0].height, (MB_SIZE >> s->block_max_depth) + s->spatial_decomposition_count * 8 + 1, s->plane[0].width, s->spatial_idwt_buffer);
02086 
02087     for(plane_index=0; plane_index<3; plane_index++){
02088         Plane *p= &s->plane[plane_index];
02089         p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40
02090                                               && p->hcoeff[1]==-10
02091                                               && p->hcoeff[2]==2;
02092     }
02093 
02094     alloc_blocks(s);
02095 
02096     if(frame_start(s) < 0)
02097         return -1;
02098     //keyframe flag duplication mess FIXME
02099     if(avctx->debug&FF_DEBUG_PICT_INFO)
02100         av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog);
02101 
02102     decode_blocks(s);
02103 
02104     for(plane_index=0; plane_index<3; plane_index++){
02105         Plane *p= &s->plane[plane_index];
02106         int w= p->width;
02107         int h= p->height;
02108         int x, y;
02109         int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
02110 
02111         if(s->avctx->debug&2048){
02112             memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
02113             predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
02114 
02115             for(y=0; y<h; y++){
02116                 for(x=0; x<w; x++){
02117                     int v= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x];
02118                     s->mconly_picture.data[plane_index][y*s->mconly_picture.linesize[plane_index] + x]= v;
02119                 }
02120             }
02121         }
02122 
02123         {
02124         for(level=0; level<s->spatial_decomposition_count; level++){
02125             for(orientation=level ? 1 : 0; orientation<4; orientation++){
02126                 SubBand *b= &p->band[level][orientation];
02127                 unpack_coeffs(s, b, b->parent, orientation);
02128             }
02129         }
02130         }
02131 
02132         {
02133         const int mb_h= s->b_height << s->block_max_depth;
02134         const int block_size = MB_SIZE >> s->block_max_depth;
02135         const int block_w    = plane_index ? block_size/2 : block_size;
02136         int mb_y;
02137         DWTCompose cs[MAX_DECOMPOSITIONS];
02138         int yd=0, yq=0;
02139         int y;
02140         int end_y;
02141 
02142         ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count);
02143         for(mb_y=0; mb_y<=mb_h; mb_y++){
02144 
02145             int slice_starty = block_w*mb_y;
02146             int slice_h = block_w*(mb_y+1);
02147             if (!(s->keyframe || s->avctx->debug&512)){
02148                 slice_starty = FFMAX(0, slice_starty - (block_w >> 1));
02149                 slice_h -= (block_w >> 1);
02150             }
02151 
02152             for(level=0; level<s->spatial_decomposition_count; level++){
02153                 for(orientation=level ? 1 : 0; orientation<4; orientation++){
02154                     SubBand *b= &p->band[level][orientation];
02155                     int start_y;
02156                     int end_y;
02157                     int our_mb_start = mb_y;
02158                     int our_mb_end = (mb_y + 1);
02159                     const int extra= 3;
02160                     start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
02161                     end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
02162                     if (!(s->keyframe || s->avctx->debug&512)){
02163                         start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level)));
02164                         end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level)));
02165                     }
02166                     start_y = FFMIN(b->height, start_y);
02167                     end_y = FFMIN(b->height, end_y);
02168 
02169                     if (start_y != end_y){
02170                         if (orientation == 0){
02171                             SubBand * correlate_band = &p->band[0][0];
02172                             int correlate_end_y = FFMIN(b->height, end_y + 1);
02173                             int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0));
02174                             decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]);
02175                             correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y);
02176                             dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y);
02177                         }
02178                         else
02179                             decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
02180                     }
02181                 }
02182             }
02183 
02184             for(; yd<slice_h; yd+=4){
02185                 ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
02186             }
02187 
02188             if(s->qlog == LOSSLESS_QLOG){
02189                 for(; yq<slice_h && yq<h; yq++){
02190                     IDWTELEM * line = slice_buffer_get_line(&s->sb, yq);
02191                     for(x=0; x<w; x++){
02192                         line[x] <<= FRAC_BITS;
02193                     }
02194                 }
02195             }
02196 
02197             predict_slice_buffered(s, &s->sb, s->spatial_idwt_buffer, plane_index, 1, mb_y);
02198 
02199             y = FFMIN(p->height, slice_starty);
02200             end_y = FFMIN(p->height, slice_h);
02201             while(y < end_y)
02202                 ff_slice_buffer_release(&s->sb, y++);
02203         }
02204 
02205         ff_slice_buffer_flush(&s->sb);
02206         }
02207 
02208     }
02209 
02210     emms_c();
02211 
02212     release_buffer(avctx);
02213 
02214     if(!(s->avctx->debug&2048))
02215         *picture= s->current_picture;
02216     else
02217         *picture= s->mconly_picture;
02218 
02219     *data_size = sizeof(AVFrame);
02220 
02221     bytes_read= c->bytestream - c->bytestream_start;
02222     if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
02223 
02224     return bytes_read;
02225 }
02226 
02227 static av_cold int decode_end(AVCodecContext *avctx)
02228 {
02229     SnowContext *s = avctx->priv_data;
02230 
02231     ff_slice_buffer_destroy(&s->sb);
02232 
02233     common_end(s);
02234 
02235     return 0;
02236 }
02237 
02238 AVCodec snow_decoder = {
02239     "snow",
02240     AVMEDIA_TYPE_VIDEO,
02241     CODEC_ID_SNOW,
02242     sizeof(SnowContext),
02243     decode_init,
02244     NULL,
02245     decode_end,
02246     decode_frame,
02247     CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
02248     NULL,
02249     .long_name = NULL_IF_CONFIG_SMALL("Snow"),
02250 };
02251 
02252 #if CONFIG_SNOW_ENCODER
02253 static av_cold int encode_init(AVCodecContext *avctx)
02254 {
02255     SnowContext *s = avctx->priv_data;
02256     int plane_index;
02257 
02258     if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
02259         av_log(avctx, AV_LOG_ERROR, "This codec is under development, files encoded with it may not be decodable with future versions!!!\n"
02260                "Use vstrict=-2 / -strict -2 to use it anyway.\n");
02261         return -1;
02262     }
02263 
02264     if(avctx->prediction_method == DWT_97
02265        && (avctx->flags & CODEC_FLAG_QSCALE)
02266        && avctx->global_quality == 0){
02267         av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n");
02268         return -1;
02269     }
02270 
02271     s->spatial_decomposition_type= avctx->prediction_method; //FIXME add decorrelator type r transform_type
02272 
02273     s->mv_scale       = (avctx->flags & CODEC_FLAG_QPEL) ? 2 : 4;
02274     s->block_max_depth= (avctx->flags & CODEC_FLAG_4MV ) ? 1 : 0;
02275 
02276     for(plane_index=0; plane_index<3; plane_index++){
02277         s->plane[plane_index].diag_mc= 1;
02278         s->plane[plane_index].htaps= 6;
02279         s->plane[plane_index].hcoeff[0]=  40;
02280         s->plane[plane_index].hcoeff[1]= -10;
02281         s->plane[plane_index].hcoeff[2]=   2;
02282         s->plane[plane_index].fast_mc= 1;
02283     }
02284 
02285     common_init(avctx);
02286     alloc_blocks(s);
02287 
02288     s->version=0;
02289 
02290     s->m.avctx   = avctx;
02291     s->m.flags   = avctx->flags;
02292     s->m.bit_rate= avctx->bit_rate;
02293 
02294     s->m.me.temp      =
02295     s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t));
02296     s->m.me.map       = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
02297     s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
02298     s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t));
02299     h263_encode_init(&s->m); //mv_penalty
02300 
02301     s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1);
02302 
02303     if(avctx->flags&CODEC_FLAG_PASS1){
02304         if(!avctx->stats_out)
02305             avctx->stats_out = av_mallocz(256);
02306     }
02307     if((avctx->flags&CODEC_FLAG_PASS2) || !(avctx->flags&CODEC_FLAG_QSCALE)){
02308         if(ff_rate_control_init(&s->m) < 0)
02309             return -1;
02310     }
02311     s->pass1_rc= !(avctx->flags & (CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2));
02312 
02313     avctx->coded_frame= &s->current_picture;
02314     switch(avctx->pix_fmt){
02315 //    case PIX_FMT_YUV444P:
02316 //    case PIX_FMT_YUV422P:
02317     case PIX_FMT_YUV420P:
02318     case PIX_FMT_GRAY8:
02319 //    case PIX_FMT_YUV411P:
02320 //    case PIX_FMT_YUV410P:
02321         s->colorspace_type= 0;
02322         break;
02323 /*    case PIX_FMT_RGB32:
02324         s->colorspace= 1;
02325         break;*/
02326     default:
02327         av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n");
02328         return -1;
02329     }
02330 //    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
02331     s->chroma_h_shift= 1;
02332     s->chroma_v_shift= 1;
02333 
02334     ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp);
02335     ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp);
02336 
02337     s->avctx->get_buffer(s->avctx, &s->input_picture);
02338 
02339     if(s->avctx->me_method == ME_ITER){
02340         int i;
02341         int size= s->b_width * s->b_height << 2*s->block_max_depth;
02342         for(i=0; i<s->max_ref_frames; i++){
02343             s->ref_mvs[i]= av_mallocz(size*sizeof(int16_t[2]));
02344             s->ref_scores[i]= av_mallocz(size*sizeof(uint32_t));
02345         }
02346     }
02347 
02348     return 0;
02349 }
02350 
02351 //near copy & paste from dsputil, FIXME
02352 static int pix_sum(uint8_t * pix, int line_size, int w)
02353 {
02354     int s, i, j;
02355 
02356     s = 0;
02357     for (i = 0; i < w; i++) {
02358         for (j = 0; j < w; j++) {
02359             s += pix[0];
02360             pix ++;
02361         }
02362         pix += line_size - w;
02363     }
02364     return s;
02365 }
02366 
02367 //near copy & paste from dsputil, FIXME
02368 static int pix_norm1(uint8_t * pix, int line_size, int w)
02369 {
02370     int s, i, j;
02371     uint32_t *sq = ff_squareTbl + 256;
02372 
02373     s = 0;
02374     for (i = 0; i < w; i++) {
02375         for (j = 0; j < w; j ++) {
02376             s += sq[pix[0]];
02377             pix ++;
02378         }
02379         pix += line_size - w;
02380     }
02381     return s;
02382 }
02383 
02384 //FIXME copy&paste
02385 #define P_LEFT P[1]
02386 #define P_TOP P[2]
02387 #define P_TOPRIGHT P[3]
02388 #define P_MEDIAN P[4]
02389 #define P_MV1 P[9]
02390 #define FLAG_QPEL   1 //must be 1
02391 
02392 static int encode_q_branch(SnowContext *s, int level, int x, int y){
02393     uint8_t p_buffer[1024];
02394     uint8_t i_buffer[1024];
02395     uint8_t p_state[sizeof(s->block_state)];
02396     uint8_t i_state[sizeof(s->block_state)];
02397     RangeCoder pc, ic;
02398     uint8_t *pbbak= s->c.bytestream;
02399     uint8_t *pbbak_start= s->c.bytestream_start;
02400     int score, score2, iscore, i_len, p_len, block_s, sum, base_bits;
02401     const int w= s->b_width  << s->block_max_depth;
02402     const int h= s->b_height << s->block_max_depth;
02403     const int rem_depth= s->block_max_depth - level;
02404     const int index= (x + y*w) << rem_depth;
02405     const int block_w= 1<<(LOG2_MB_SIZE - level);
02406     int trx= (x+1)<<rem_depth;
02407     int try= (y+1)<<rem_depth;
02408     const BlockNode *left  = x ? &s->block[index-1] : &null_block;
02409     const BlockNode *top   = y ? &s->block[index-w] : &null_block;
02410     const BlockNode *right = trx<w ? &s->block[index+1] : &null_block;
02411     const BlockNode *bottom= try<h ? &s->block[index+w] : &null_block;
02412     const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
02413     const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
02414     int pl = left->color[0];
02415     int pcb= left->color[1];
02416     int pcr= left->color[2];
02417     int pmx, pmy;
02418     int mx=0, my=0;
02419     int l,cr,cb;
02420     const int stride= s->current_picture.linesize[0];
02421     const int uvstride= s->current_picture.linesize[1];
02422     uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y*  stride)*block_w,
02423                                 s->input_picture.data[1] + (x + y*uvstride)*block_w/2,
02424                                 s->input_picture.data[2] + (x + y*uvstride)*block_w/2};
02425     int P[10][2];
02426     int16_t last_mv[3][2];
02427     int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused
02428     const int shift= 1+qpel;
02429     MotionEstContext *c= &s->m.me;
02430     int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
02431     int mx_context= av_log2(2*FFABS(left->mx - top->mx));
02432     int my_context= av_log2(2*FFABS(left->my - top->my));
02433     int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
02434     int ref, best_ref, ref_score, ref_mx, ref_my;
02435 
02436     assert(sizeof(s->block_state) >= 256);
02437     if(s->keyframe){
02438         set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
02439         return 0;
02440     }
02441 
02442 //    clip predictors / edge ?
02443 
02444     P_LEFT[0]= left->mx;
02445     P_LEFT[1]= left->my;
02446     P_TOP [0]= top->mx;
02447     P_TOP [1]= top->my;
02448     P_TOPRIGHT[0]= tr->mx;
02449     P_TOPRIGHT[1]= tr->my;
02450 
02451     last_mv[0][0]= s->block[index].mx;
02452     last_mv[0][1]= s->block[index].my;
02453     last_mv[1][0]= right->mx;
02454     last_mv[1][1]= right->my;
02455     last_mv[2][0]= bottom->mx;
02456     last_mv[2][1]= bottom->my;
02457 
02458     s->m.mb_stride=2;
02459     s->m.mb_x=
02460     s->m.mb_y= 0;
02461     c->skip= 0;
02462 
02463     assert(c->  stride ==   stride);
02464     assert(c->uvstride == uvstride);
02465 
02466     c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
02467     c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
02468     c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
02469     c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_MV;
02470 
02471     c->xmin = - x*block_w - 16+3;
02472     c->ymin = - y*block_w - 16+3;
02473     c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
02474     c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
02475 
02476     if(P_LEFT[0]     > (c->xmax<<shift)) P_LEFT[0]    = (c->xmax<<shift);
02477     if(P_LEFT[1]     > (c->ymax<<shift)) P_LEFT[1]    = (c->ymax<<shift);
02478     if(P_TOP[0]      > (c->xmax<<shift)) P_TOP[0]     = (c->xmax<<shift);
02479     if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);
02480     if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
02481     if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift); //due to pmx no clip
02482     if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
02483 
02484     P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
02485     P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
02486 
02487     if (!y) {
02488         c->pred_x= P_LEFT[0];
02489         c->pred_y= P_LEFT[1];
02490     } else {
02491         c->pred_x = P_MEDIAN[0];
02492         c->pred_y = P_MEDIAN[1];
02493     }
02494 
02495     score= INT_MAX;
02496     best_ref= 0;
02497     for(ref=0; ref<s->ref_frames; ref++){
02498         init_ref(c, current_data, s->last_picture[ref].data, NULL, block_w*x, block_w*y, 0);
02499 
02500         ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv,
02501                                          (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w);
02502 
02503         assert(ref_mx >= c->xmin);
02504         assert(ref_mx <= c->xmax);
02505         assert(ref_my >= c->ymin);
02506         assert(ref_my <= c->ymax);
02507 
02508         ref_score= c->sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w);
02509         ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0);
02510         ref_score+= 2*av_log2(2*ref)*c->penalty_factor;
02511         if(s->ref_mvs[ref]){
02512             s->ref_mvs[ref][index][0]= ref_mx;
02513             s->ref_mvs[ref][index][1]= ref_my;
02514             s->ref_scores[ref][index]= ref_score;
02515         }
02516         if(score > ref_score){
02517             score= ref_score;
02518             best_ref= ref;
02519             mx= ref_mx;
02520             my= ref_my;
02521         }
02522     }
02523     //FIXME if mb_cmp != SSE then intra cannot be compared currently and mb_penalty vs. lambda2
02524 
02525   //  subpel search
02526     base_bits= get_rac_count(&s->c) - 8*(s->c.bytestream - s->c.bytestream_start);
02527     pc= s->c;
02528     pc.bytestream_start=
02529     pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo
02530     memcpy(p_state, s->block_state, sizeof(s->block_state));
02531 
02532     if(level!=s->block_max_depth)
02533         put_rac(&pc, &p_state[4 + s_context], 1);
02534     put_rac(&pc, &p_state[1 + left->type + top->type], 0);
02535     if(s->ref_frames > 1)
02536         put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0);
02537     pred_mv(s, &pmx, &pmy, best_ref, left, top, tr);
02538     put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1);
02539     put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1);
02540     p_len= pc.bytestream - pc.bytestream_start;
02541     score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT;
02542 
02543     block_s= block_w*block_w;
02544     sum = pix_sum(current_data[0], stride, block_w);
02545     l= (sum + block_s/2)/block_s;
02546     iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s;
02547 
02548     block_s= block_w*block_w>>2;
02549     sum = pix_sum(current_data[1], uvstride, block_w>>1);
02550     cb= (sum + block_s/2)/block_s;
02551 //    iscore += pix_norm1(&current_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s;
02552     sum = pix_sum(current_data[2], uvstride, block_w>>1);
02553     cr= (sum + block_s/2)/block_s;
02554 //    iscore += pix_norm1(&current_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s;
02555 
02556     ic= s->c;
02557     ic.bytestream_start=
02558     ic.bytestream= i_buffer; //FIXME end/start? and at the other stoo
02559     memcpy(i_state, s->block_state, sizeof(s->block_state));
02560     if(level!=s->block_max_depth)
02561         put_rac(&ic, &i_state[4 + s_context], 1);
02562     put_rac(&ic, &i_state[1 + left->type + top->type], 1);
02563     put_symbol(&ic, &i_state[32],  l-pl , 1);
02564     put_symbol(&ic, &i_state[64], cb-pcb, 1);
02565     put_symbol(&ic, &i_state[96], cr-pcr, 1);
02566     i_len= ic.bytestream - ic.bytestream_start;
02567     iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT;
02568 
02569 //    assert(score==256*256*256*64-1);
02570     assert(iscore < 255*255*256 + s->lambda2*10);
02571     assert(iscore >= 0);
02572     assert(l>=0 && l<=255);
02573     assert(pl>=0 && pl<=255);
02574 
02575     if(level==0){
02576         int varc= iscore >> 8;
02577         int vard= score >> 8;
02578         if (vard <= 64 || vard < varc)
02579             c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
02580         else
02581             c->scene_change_score+= s->m.qscale;
02582     }
02583 
02584     if(level!=s->block_max_depth){
02585         put_rac(&s->c, &s->block_state[4 + s_context], 0);
02586         score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0);
02587         score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0);
02588         score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1);
02589         score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+1);
02590         score2+= s->lambda2>>FF_LAMBDA_SHIFT; //FIXME exact split overhead
02591 
02592         if(score2 < score && score2 < iscore)
02593             return score2;
02594     }
02595 
02596     if(iscore < score){
02597         pred_mv(s, &pmx, &pmy, 0, left, top, tr);
02598         memcpy(pbbak, i_buffer, i_len);
02599         s->c= ic;
02600         s->c.bytestream_start= pbbak_start;
02601         s->c.bytestream= pbbak + i_len;
02602         set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA);
02603         memcpy(s->block_state, i_state, sizeof(s->block_state));
02604         return iscore;
02605     }else{
02606         memcpy(pbbak, p_buffer, p_len);
02607         s->c= pc;
02608         s->c.bytestream_start= pbbak_start;
02609         s->c.bytestream= pbbak + p_len;
02610         set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, best_ref, 0);
02611         memcpy(s->block_state, p_state, sizeof(s->block_state));
02612         return score;
02613     }
02614 }
02615 
02616 static void encode_q_branch2(SnowContext *s, int level, int x, int y){
02617     const int w= s->b_width  << s->block_max_depth;
02618     const int rem_depth= s->block_max_depth - level;
02619     const int index= (x + y*w) << rem_depth;
02620     int trx= (x+1)<<rem_depth;
02621     BlockNode *b= &s->block[index];
02622     const BlockNode *left  = x ? &s->block[index-1] : &null_block;
02623     const BlockNode *top   = y ? &s->block[index-w] : &null_block;
02624     const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
02625     const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
02626     int pl = left->color[0];
02627     int pcb= left->color[1];
02628     int pcr= left->color[2];
02629     int pmx, pmy;
02630     int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
02631     int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 16*!!b->ref;
02632     int my_context= av_log2(2*FFABS(left->my - top->my)) + 16*!!b->ref;
02633     int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
02634 
02635     if(s->keyframe){
02636         set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
02637         return;
02638     }
02639 
02640     if(level!=s->block_max_depth){
02641         if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){
02642             put_rac(&s->c, &s->block_state[4 + s_context], 1);
02643         }else{
02644             put_rac(&s->c, &s->block_state[4 + s_context], 0);
02645             encode_q_branch2(s, level+1, 2*x+0, 2*y+0);
02646             encode_q_branch2(s, level+1, 2*x+1, 2*y+0);
02647             encode_q_branch2(s, level+1, 2*x+0, 2*y+1);
02648             encode_q_branch2(s, level+1, 2*x+1, 2*y+1);
02649             return;
02650         }
02651     }
02652     if(b->type & BLOCK_INTRA){
02653         pred_mv(s, &pmx, &pmy, 0, left, top, tr);
02654         put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1);
02655         put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1);
02656         put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1);
02657         put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1);
02658         set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA);
02659     }else{
02660         pred_mv(s, &pmx, &pmy, b->ref, left, top, tr);
02661         put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0);
02662         if(s->ref_frames > 1)
02663             put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0);
02664         put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1);
02665         put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1);
02666         set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, b->ref, 0);
02667     }
02668 }
02669 
02670 static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){
02671     int i, x2, y2;
02672     Plane *p= &s->plane[plane_index];
02673     const int block_size = MB_SIZE >> s->block_max_depth;
02674     const int block_w    = plane_index ? block_size/2 : block_size;
02675     const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
02676     const int obmc_stride= plane_index ? block_size : 2*block_size;
02677     const int ref_stride= s->current_picture.linesize[plane_index];
02678     uint8_t *src= s-> input_picture.data[plane_index];
02679     IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
02680     const int b_stride = s->b_width << s->block_max_depth;
02681     const int w= p->width;
02682     const int h= p->height;
02683     int index= mb_x + mb_y*b_stride;
02684     BlockNode *b= &s->block[index];
02685     BlockNode backup= *b;
02686     int ab=0;
02687     int aa=0;
02688 
02689     b->type|= BLOCK_INTRA;
02690     b->color[plane_index]= 0;
02691     memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM));
02692 
02693     for(i=0; i<4; i++){
02694         int mb_x2= mb_x + (i &1) - 1;
02695         int mb_y2= mb_y + (i>>1) - 1;
02696         int x= block_w*mb_x2 + block_w/2;
02697         int y= block_w*mb_y2 + block_w/2;
02698 
02699         add_yblock(s, 0, NULL, dst + ((i&1)+(i>>1)*obmc_stride)*block_w, NULL, obmc,
02700                     x, y, block_w, block_w, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index);
02701 
02702         for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_w); y2++){
02703             for(x2= FFMAX(x, 0); x2<FFMIN(w, x+block_w); x2++){
02704                 int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_w*mb_y - block_w/2))*obmc_stride;
02705                 int obmc_v= obmc[index];
02706                 int d;
02707                 if(y<0) obmc_v += obmc[index + block_w*obmc_stride];
02708                 if(x<0) obmc_v += obmc[index + block_w];
02709                 if(y+block_w>h) obmc_v += obmc[index - block_w*obmc_stride];
02710                 if(x+block_w>w) obmc_v += obmc[index - block_w];
02711                 //FIXME precalculate this or simplify it somehow else
02712 
02713                 d = -dst[index] + (1<<(FRAC_BITS-1));
02714                 dst[index] = d;
02715                 ab += (src[x2 + y2*ref_stride] - (d>>FRAC_BITS)) * obmc_v;
02716                 aa += obmc_v * obmc_v; //FIXME precalculate this
02717             }
02718         }
02719     }
02720     *b= backup;
02721 
02722     return av_clip(((ab<<LOG2_OBMC_MAX) + aa/2)/aa, 0, 255); //FIXME we should not need clipping
02723 }
02724 
02725 static inline int get_block_bits(SnowContext *s, int x, int y, int w){
02726     const int b_stride = s->b_width << s->block_max_depth;
02727     const int b_height = s->b_height<< s->block_max_depth;
02728     int index= x + y*b_stride;
02729     const BlockNode *b     = &s->block[index];
02730     const BlockNode *left  = x ? &s->block[index-1] : &null_block;
02731     const BlockNode *top   = y ? &s->block[index-b_stride] : &null_block;
02732     const BlockNode *tl    = y && x ? &s->block[index-b_stride-1] : left;
02733     const BlockNode *tr    = y && x+w<b_stride ? &s->block[index-b_stride+w] : tl;
02734     int dmx, dmy;
02735 //  int mx_context= av_log2(2*FFABS(left->mx - top->mx));
02736 //  int my_context= av_log2(2*FFABS(left->my - top->my));
02737 
02738     if(x<0 || x>=b_stride || y>=b_height)
02739         return 0;
02740 /*
02741 1            0      0
02742 01X          1-2    1
02743 001XX        3-6    2-3
02744 0001XXX      7-14   4-7
02745 00001XXXX   15-30   8-15
02746 */
02747 //FIXME try accurate rate
02748 //FIXME intra and inter predictors if surrounding blocks are not the same type
02749     if(b->type & BLOCK_INTRA){
02750         return 3+2*( av_log2(2*FFABS(left->color[0] - b->color[0]))
02751                    + av_log2(2*FFABS(left->color[1] - b->color[1]))
02752                    + av_log2(2*FFABS(left->color[2] - b->color[2])));
02753     }else{
02754         pred_mv(s, &dmx, &dmy, b->ref, left, top, tr);
02755         dmx-= b->mx;
02756         dmy-= b->my;
02757         return 2*(1 + av_log2(2*FFABS(dmx)) //FIXME kill the 2* can be merged in lambda
02758                     + av_log2(2*FFABS(dmy))
02759                     + av_log2(2*b->ref));
02760     }
02761 }
02762 
02763 static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){
02764     Plane *p= &s->plane[plane_index];
02765     const int block_size = MB_SIZE >> s->block_max_depth;
02766     const int block_w    = plane_index ? block_size/2 : block_size;
02767     const int obmc_stride= plane_index ? block_size : 2*block_size;
02768     const int ref_stride= s->current_picture.linesize[plane_index];
02769     uint8_t *dst= s->current_picture.data[plane_index];
02770     uint8_t *src= s->  input_picture.data[plane_index];
02771     IDWTELEM *pred= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4;
02772     uint8_t *cur = s->scratchbuf;
02773     uint8_t tmp[ref_stride*(2*MB_SIZE+HTAPS_MAX-1)];
02774     const int b_stride = s->b_width << s->block_max_depth;
02775     const int b_height = s->b_height<< s->block_max_depth;
02776     const int w= p->width;
02777     const int h= p->height;
02778     int distortion;
02779     int rate= 0;
02780     const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
02781     int sx= block_w*mb_x - block_w/2;
02782     int sy= block_w*mb_y - block_w/2;
02783     int x0= FFMAX(0,-sx);
02784     int y0= FFMAX(0,-sy);
02785     int x1= FFMIN(block_w*2, w-sx);
02786     int y1= FFMIN(block_w*2, h-sy);
02787     int i,x,y;
02788 
02789     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);
02790 
02791     for(y=y0; y<y1; y++){
02792         const uint8_t *obmc1= obmc_edged + y*obmc_stride;
02793         const IDWTELEM *pred1 = pred + y*obmc_stride;
02794         uint8_t *cur1 = cur + y*ref_stride;
02795         uint8_t *dst1 = dst + sx + (sy+y)*ref_stride;
02796         for(x=x0; x<x1; x++){
02797 #if FRAC_BITS >= LOG2_OBMC_MAX
02798             int v = (cur1[x] * obmc1[x]) << (FRAC_BITS - LOG2_OBMC_MAX);
02799 #else
02800             int v = (cur1[x] * obmc1[x] + (1<<(LOG2_OBMC_MAX - FRAC_BITS-1))) >> (LOG2_OBMC_MAX - FRAC_BITS);
02801 #endif
02802             v = (v + pred1[x]) >> FRAC_BITS;
02803             if(v&(~255)) v= ~(v>>31);
02804             dst1[x] = v;
02805         }
02806     }
02807 
02808     /* copy the regions where obmc[] = (uint8_t)256 */
02809     if(LOG2_OBMC_MAX == 8
02810         && (mb_x == 0 || mb_x == b_stride-1)
02811         && (mb_y == 0 || mb_y == b_height-1)){
02812         if(mb_x == 0)
02813             x1 = block_w;
02814         else
02815             x0 = block_w;
02816         if(mb_y == 0)
02817             y1 = block_w;
02818         else
02819             y0 = block_w;
02820         for(y=y0; y<y1; y++)
02821             memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0);
02822     }
02823 
02824     if(block_w==16){
02825         /* FIXME rearrange dsputil to fit 32x32 cmp functions */
02826         /* FIXME check alignment of the cmp wavelet vs the encoding wavelet */
02827         /* FIXME cmps overlap but do not cover the wavelet's whole support.
02828          * So improving the score of one block is not strictly guaranteed
02829          * to improve the score of the whole frame, thus iterative motion
02830          * estimation does not always converge. */
02831         if(s->avctx->me_cmp == FF_CMP_W97)
02832             distortion = ff_w97_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
02833         else if(s->avctx->me_cmp == FF_CMP_W53)
02834             distortion = ff_w53_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
02835         else{
02836             distortion = 0;
02837             for(i=0; i<4; i++){
02838                 int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride;
02839                 distortion += s->dsp.me_cmp[0](&s->m, src + off, dst + off, ref_stride, 16);
02840             }
02841         }
02842     }else{
02843         assert(block_w==8);
02844         distortion = s->dsp.me_cmp[0](&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
02845     }
02846 
02847     if(plane_index==0){
02848         for(i=0; i<4; i++){
02849 /* ..RRr
02850  * .RXx.
02851  * rxx..
02852  */
02853             rate += get_block_bits(s, mb_x + (i&1) - (i>>1), mb_y + (i>>1), 1);
02854         }
02855         if(mb_x == b_stride-2)
02856             rate += get_block_bits(s, mb_x + 1, mb_y + 1, 1);
02857     }
02858     return distortion + rate*penalty_factor;
02859 }
02860 
02861 static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){
02862     int i, y2;
02863     Plane *p= &s->plane[plane_index];
02864     const int block_size = MB_SIZE >> s->block_max_depth;
02865     const int block_w    = plane_index ? block_size/2 : block_size;
02866     const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
02867     const int obmc_stride= plane_index ? block_size : 2*block_size;
02868     const int ref_stride= s->current_picture.linesize[plane_index];
02869     uint8_t *dst= s->current_picture.data[plane_index];
02870     uint8_t *src= s-> input_picture.data[plane_index];
02871     //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst
02872     // const has only been removed from zero_dst to suppress a warning
02873     static IDWTELEM zero_dst[4096]; //FIXME
02874     const int b_stride = s->b_width << s->block_max_depth;
02875     const int w= p->width;
02876     const int h= p->height;
02877     int distortion= 0;
02878     int rate= 0;
02879     const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
02880 
02881     for(i=0; i<9; i++){
02882         int mb_x2= mb_x + (i%3) - 1;
02883         int mb_y2= mb_y + (i/3) - 1;
02884         int x= block_w*mb_x2 + block_w/2;
02885         int y= block_w*mb_y2 + block_w/2;
02886 
02887         add_yblock(s, 0, NULL, zero_dst, dst, obmc,
02888                    x, y, block_w, block_w, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index);
02889 
02890         //FIXME find a cleaner/simpler way to skip the outside stuff
02891         for(y2= y; y2<0; y2++)
02892             memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
02893         for(y2= h; y2<y+block_w; y2++)
02894             memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
02895         if(x<0){
02896             for(y2= y; y2<y+block_w; y2++)
02897                 memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x);
02898         }
02899         if(x+block_w > w){
02900             for(y2= y; y2<y+block_w; y2++)
02901                 memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w);
02902         }
02903 
02904         assert(block_w== 8 || block_w==16);
02905         distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_w);
02906     }
02907 
02908     if(plane_index==0){
02909         BlockNode *b= &s->block[mb_x+mb_y*b_stride];
02910         int merged= same_block(b,b+1) && same_block(b,b+b_stride) && same_block(b,b+b_stride+1);
02911 
02912 /* ..RRRr
02913  * .RXXx.
02914  * .RXXx.
02915  * rxxx.
02916  */
02917         if(merged)
02918             rate = get_block_bits(s, mb_x, mb_y, 2);
02919         for(i=merged?4:0; i<9; i++){
02920             static const int dxy[9][2] = {{0,0},{1,0},{0,1},{1,1},{2,0},{2,1},{-1,2},{0,2},{1,2}};
02921             rate += get_block_bits(s, mb_x + dxy[i][0], mb_y + dxy[i][1], 1);
02922         }
02923     }
02924     return distortion + rate*penalty_factor;
02925 }
02926 
02927 static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
02928     const int w= b->width;
02929     const int h= b->height;
02930     int x, y;
02931 
02932     if(1){
02933         int run=0;
02934         int runs[w*h];
02935         int run_index=0;
02936         int max_index;
02937 
02938         for(y=0; y<h; y++){
02939             for(x=0; x<w; x++){
02940                 int v, p=0;
02941                 int /*ll=0, */l=0, lt=0, t=0, rt=0;
02942                 v= src[x + y*stride];
02943 
02944                 if(y){
02945                     t= src[x + (y-1)*stride];
02946                     if(x){
02947                         lt= src[x - 1 + (y-1)*stride];
02948                     }
02949                     if(x + 1 < w){
02950                         rt= src[x + 1 + (y-1)*stride];
02951                     }
02952                 }
02953                 if(x){
02954                     l= src[x - 1 + y*stride];
02955                     /*if(x > 1){
02956                         if(orientation==1) ll= src[y + (x-2)*stride];
02957                         else               ll= src[x - 2 + y*stride];
02958                     }*/
02959                 }
02960                 if(parent){
02961                     int px= x>>1;
02962                     int py= y>>1;
02963                     if(px<b->parent->width && py<b->parent->height)
02964                         p= parent[px + py*2*stride];
02965                 }
02966                 if(!(/*ll|*/l|lt|t|rt|p)){
02967                     if(v){
02968                         runs[run_index++]= run;
02969                         run=0;
02970                     }else{
02971                         run++;
02972                     }
02973                 }
02974             }
02975         }
02976         max_index= run_index;
02977         runs[run_index++]= run;
02978         run_index=0;
02979         run= runs[run_index++];
02980 
02981         put_symbol2(&s->c, b->state[30], max_index, 0);
02982         if(run_index <= max_index)
02983             put_symbol2(&s->c, b->state[1], run, 3);
02984 
02985         for(y=0; y<h; y++){
02986             if(s->c.bytestream_end - s->c.bytestream < w*40){
02987                 av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
02988                 return -1;
02989             }
02990             for(x=0; x<w; x++){
02991                 int v, p=0;
02992                 int /*ll=0, */l=0, lt=0, t=0, rt=0;
02993                 v= src[x + y*stride];
02994 
02995                 if(y){
02996                     t= src[x + (y-1)*stride];
02997                     if(x){
02998                         lt= src[x - 1 + (y-1)*stride];
02999                     }
03000                     if(x + 1 < w){
03001                         rt= src[x + 1 + (y-1)*stride];
03002                     }
03003                 }
03004                 if(x){
03005                     l= src[x - 1 + y*stride];
03006                     /*if(x > 1){
03007                         if(orientation==1) ll= src[y + (x-2)*stride];
03008                         else               ll= src[x - 2 + y*stride];
03009                     }*/
03010                 }
03011                 if(parent){
03012                     int px= x>>1;
03013                     int py= y>>1;
03014                     if(px<b->parent->width && py<b->parent->height)
03015                         p= parent[px + py*2*stride];
03016                 }
03017                 if(/*ll|*/l|lt|t|rt|p){
03018                     int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
03019 
03020                     put_rac(&s->c, &b->state[0][context], !!v);
03021                 }else{
03022                     if(!run){
03023                         run= runs[run_index++];
03024 
03025                         if(run_index <= max_index)
03026                             put_symbol2(&s->c, b->state[1], run, 3);
03027                         assert(v);
03028                     }else{
03029                         run--;
03030                         assert(!v);
03031                     }
03032                 }
03033                 if(v){
03034                     int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
03035                     int l2= 2*FFABS(l) + (l<0);
03036                     int t2= 2*FFABS(t) + (t<0);
03037 
03038                     put_symbol2(&s->c, b->state[context + 2], FFABS(v)-1, context-4);
03039                     put_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l2&0xFF] + 3*quant3bA[t2&0xFF]], v<0);
03040                 }
03041             }
03042         }
03043     }
03044     return 0;
03045 }
03046 
03047 static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
03048 //    encode_subband_qtree(s, b, src, parent, stride, orientation);
03049 //    encode_subband_z0run(s, b, src, parent, stride, orientation);
03050     return encode_subband_c0run(s, b, src, parent, stride, orientation);
03051 //    encode_subband_dzr(s, b, src, parent, stride, orientation);
03052 }
03053 
03054 static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, const uint8_t *obmc_edged, int *best_rd){
03055     const int b_stride= s->b_width << s->block_max_depth;
03056     BlockNode *block= &s->block[mb_x + mb_y * b_stride];
03057     BlockNode backup= *block;
03058     int rd, index, value;
03059 
03060     assert(mb_x>=0 && mb_y>=0);
03061     assert(mb_x<b_stride);
03062 
03063     if(intra){
03064         block->color[0] = p[0];
03065         block->color[1] = p[1];
03066         block->color[2] = p[2];
03067         block->type |= BLOCK_INTRA;
03068     }else{
03069         index= (p[0] + 31*p[1]) & (ME_CACHE_SIZE-1);
03070         value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6) + (block->ref<<12);
03071         if(s->me_cache[index] == value)
03072             return 0;
03073         s->me_cache[index]= value;
03074 
03075         block->mx= p[0];
03076         block->my= p[1];
03077         block->type &= ~BLOCK_INTRA;
03078     }
03079 
03080     rd= get_block_rd(s, mb_x, mb_y, 0, obmc_edged);
03081 
03082 //FIXME chroma
03083     if(rd < *best_rd){
03084         *best_rd= rd;
03085         return 1;
03086     }else{
03087         *block= backup;
03088         return 0;
03089     }
03090 }
03091 
03092 /* special case for int[2] args we discard afterwards,
03093  * fixes compilation problem with gcc 2.95 */
03094 static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, const uint8_t *obmc_edged, int *best_rd){
03095     int p[2] = {p0, p1};
03096     return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd);
03097 }
03098 
03099 static av_always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int ref, int *best_rd){
03100     const int b_stride= s->b_width << s->block_max_depth;
03101     BlockNode *block= &s->block[mb_x + mb_y * b_stride];
03102     BlockNode backup[4]= {block[0], block[1], block[b_stride], block[b_stride+1]};
03103     int rd, index, value;
03104 
03105     assert(mb_x>=0 && mb_y>=0);
03106     assert(mb_x<b_stride);
03107     assert(((mb_x|mb_y)&1) == 0);
03108 
03109     index= (p0 + 31*p1) & (ME_CACHE_SIZE-1);
03110     value= s->me_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12);
03111     if(s->me_cache[index] == value)
03112         return 0;
03113     s->me_cache[index]= value;
03114 
03115     block->mx= p0;
03116     block->my= p1;
03117     block->ref= ref;
03118     block->type &= ~BLOCK_INTRA;
03119     block[1]= block[b_stride]= block[b_stride+1]= *block;
03120 
03121     rd= get_4block_rd(s, mb_x, mb_y, 0);
03122 
03123 //FIXME chroma
03124     if(rd < *best_rd){
03125         *best_rd= rd;
03126         return 1;
03127     }else{
03128         block[0]= backup[0];
03129         block[1]= backup[1];
03130         block[b_stride]= backup[2];
03131         block[b_stride+1]= backup[3];
03132         return 0;
03133     }
03134 }
03135 
03136 static void iterative_me(SnowContext *s){
03137     int pass, mb_x, mb_y;
03138     const int b_width = s->b_width  << s->block_max_depth;
03139     const int b_height= s->b_height << s->block_max_depth;
03140     const int b_stride= b_width;
03141     int color[3];
03142 
03143     {
03144         RangeCoder r = s->c;
03145         uint8_t state[sizeof(s->block_state)];
03146         memcpy(state, s->block_state, sizeof(s->block_state));
03147         for(mb_y= 0; mb_y<s->b_height; mb_y++)
03148             for(mb_x= 0; mb_x<s->b_width; mb_x++)
03149                 encode_q_branch(s, 0, mb_x, mb_y);
03150         s->c = r;
03151         memcpy(s->block_state, state, sizeof(s->block_state));
03152     }
03153 
03154     for(pass=0; pass<25; pass++){
03155         int change= 0;
03156 
03157         for(mb_y= 0; mb_y<b_height; mb_y++){
03158             for(mb_x= 0; mb_x<b_width; mb_x++){
03159                 int dia_change, i, j, ref;
03160                 int best_rd= INT_MAX, ref_rd;
03161                 BlockNode backup, ref_b;
03162                 const int index= mb_x + mb_y * b_stride;
03163                 BlockNode *block= &s->block[index];
03164                 BlockNode *tb =                   mb_y            ? &s->block[index-b_stride  ] : NULL;
03165                 BlockNode *lb = mb_x                              ? &s->block[index         -1] : NULL;
03166                 BlockNode *rb = mb_x+1<b_width                    ? &s->block[index         +1] : NULL;
03167                 BlockNode *bb =                   mb_y+1<b_height ? &s->block[index+b_stride  ] : NULL;
03168                 BlockNode *tlb= mb_x           && mb_y            ? &s->block[index-b_stride-1] : NULL;
03169                 BlockNode *trb= mb_x+1<b_width && mb_y            ? &s->block[index-b_stride+1] : NULL;
03170                 BlockNode *blb= mb_x           && mb_y+1<b_height ? &s->block[index+b_stride-1] : NULL;
03171                 BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : NULL;
03172                 const int b_w= (MB_SIZE >> s->block_max_depth);
03173                 uint8_t obmc_edged[b_w*2][b_w*2];
03174 
03175                 if(pass && (block->type & BLOCK_OPT))
03176                     continue;
03177                 block->type |= BLOCK_OPT;
03178 
03179                 backup= *block;
03180 
03181                 if(!s->me_cache_generation)
03182                     memset(s->me_cache, 0, sizeof(s->me_cache));
03183                 s->me_cache_generation += 1<<22;
03184 
03185                 //FIXME precalculate
03186                 {
03187                     int x, y;
03188                     memcpy(obmc_edged, obmc_tab[s->block_max_depth], b_w*b_w*4);
03189                     if(mb_x==0)
03190                         for(y=0; y<b_w*2; y++)
03191                             memset(obmc_edged[y], obmc_edged[y][0] + obmc_edged[y][b_w-1], b_w);
03192                     if(mb_x==b_stride-1)
03193                         for(y=0; y<b_w*2; y++)
03194                             memset(obmc_edged[y]+b_w, obmc_edged[y][b_w] + obmc_edged[y][b_w*2-1], b_w);
03195                     if(mb_y==0){
03196                         for(x=0; x<b_w*2; x++)
03197                             obmc_edged[0][x] += obmc_edged[b_w-1][x];
03198                         for(y=1; y<b_w; y++)
03199                             memcpy(obmc_edged[y], obmc_edged[0], b_w*2);
03200                     }
03201                     if(mb_y==b_height-1){
03202                         for(x=0; x<b_w*2; x++)
03203                             obmc_edged[b_w*2-1][x] += obmc_edged[b_w][x];
03204                         for(y=b_w; y<b_w*2-1; y++)
03205                             memcpy(obmc_edged[y], obmc_edged[b_w*2-1], b_w*2);
03206                     }
03207                 }
03208 
03209                 //skip stuff outside the picture
03210                 if(mb_x==0 || mb_y==0 || mb_x==b_width-1 || mb_y==b_height-1){
03211                     uint8_t *src= s->  input_picture.data[0];
03212                     uint8_t *dst= s->current_picture.data[0];
03213                     const int stride= s->current_picture.linesize[0];
03214                     const int block_w= MB_SIZE >> s->block_max_depth;
03215                     const int sx= block_w*mb_x - block_w/2;
03216                     const int sy= block_w*mb_y - block_w/2;
03217                     const int w= s->plane[0].width;
03218                     const int h= s->plane[0].height;
03219                     int y;
03220 
03221                     for(y=sy; y<0; y++)
03222                         memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
03223                     for(y=h; y<sy+block_w*2; y++)
03224                         memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
03225                     if(sx<0){
03226                         for(y=sy; y<sy+block_w*2; y++)
03227                             memcpy(dst + sx + y*stride, src + sx + y*stride, -sx);
03228                     }
03229                     if(sx+block_w*2 > w){
03230                         for(y=sy; y<sy+block_w*2; y++)
03231                             memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w);
03232                     }
03233                 }
03234 
03235                 // intra(black) = neighbors' contribution to the current block
03236                 for(i=0; i<3; i++)
03237                     color[i]= get_dc(s, mb_x, mb_y, i);
03238 
03239                 // get previous score (cannot be cached due to OBMC)
03240                 if(pass > 0 && (block->type&BLOCK_INTRA)){
03241                     int color0[3]= {block->color[0], block->color[1], block->color[2]};
03242                     check_block(s, mb_x, mb_y, color0, 1, *obmc_edged, &best_rd);
03243                 }else
03244                     check_block_inter(s, mb_x, mb_y, block->mx, block->my, *obmc_edged, &best_rd);
03245 
03246                 ref_b= *block;
03247                 ref_rd= best_rd;
03248                 for(ref=0; ref < s->ref_frames; ref++){
03249                     int16_t (*mvr)[2]= &s->ref_mvs[ref][index];
03250                     if(s->ref_scores[ref][index] > s->ref_scores[ref_b.ref][index]*3/2) //FIXME tune threshold
03251                         continue;
03252                     block->ref= ref;
03253                     best_rd= INT_MAX;
03254 
03255                     check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], *obmc_edged, &best_rd);
03256                     check_block_inter(s, mb_x, mb_y, 0, 0, *obmc_edged, &best_rd);
03257                     if(tb)
03258                         check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], *obmc_edged, &best_rd);
03259                     if(lb)
03260                         check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], *obmc_edged, &best_rd);
03261                     if(rb)
03262                         check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], *obmc_edged, &best_rd);
03263                     if(bb)
03264                         check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], *obmc_edged, &best_rd);
03265 
03266                     /* fullpel ME */
03267                     //FIXME avoid subpel interpolation / round to nearest integer
03268                     do{
03269                         dia_change=0;
03270                         for(i=0; i<FFMAX(s->avctx->dia_size, 1); i++){
03271                             for(j=0; j<i; j++){
03272                                 dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my+(4*j), *obmc_edged, &best_rd);
03273                                 dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), *obmc_edged, &best_rd);
03274                                 dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), *obmc_edged, &best_rd);
03275                                 dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), *obmc_edged, &best_rd);
03276                             }
03277                         }
03278                     }while(dia_change);
03279                     /* subpel ME */
03280                     do{
03281                         static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},};
03282                         dia_change=0;
03283                         for(i=0; i<8; i++)
03284                             dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], *obmc_edged, &best_rd);
03285                     }while(dia_change);
03286                     //FIXME or try the standard 2 pass qpel or similar
03287 
03288                     mvr[0][0]= block->mx;
03289                     mvr[0][1]= block->my;
03290                     if(ref_rd > best_rd){
03291                         ref_rd= best_rd;
03292                         ref_b= *block;
03293                     }
03294                 }
03295                 best_rd= ref_rd;
03296                 *block= ref_b;
03297 #if 1
03298                 check_block(s, mb_x, mb_y, color, 1, *obmc_edged, &best_rd);
03299                 //FIXME RD style color selection
03300 #endif
03301                 if(!same_block(block, &backup)){
03302                     if(tb ) tb ->type &= ~BLOCK_OPT;
03303                     if(lb ) lb ->type &= ~BLOCK_OPT;
03304                     if(rb ) rb ->type &= ~BLOCK_OPT;
03305                     if(bb ) bb ->type &= ~BLOCK_OPT;
03306                     if(tlb) tlb->type &= ~BLOCK_OPT;
03307                     if(trb) trb->type &= ~BLOCK_OPT;
03308                     if(blb) blb->type &= ~BLOCK_OPT;
03309                     if(brb) brb->type &= ~BLOCK_OPT;
03310                     change ++;
03311                 }
03312             }
03313         }
03314         av_log(s->avctx, AV_LOG_ERROR, "pass:%d changed:%d\n", pass, change);
03315         if(!change)
03316             break;
03317     }
03318 
03319     if(s->block_max_depth == 1){
03320         int change= 0;
03321         for(mb_y= 0; mb_y<b_height; mb_y+=2){
03322             for(mb_x= 0; mb_x<b_width; mb_x+=2){
03323                 int i;
03324                 int best_rd, init_rd;
03325                 const int index= mb_x + mb_y * b_stride;
03326                 BlockNode *b[4];
03327 
03328                 b[0]= &s->block[index];
03329                 b[1]= b[0]+1;
03330                 b[2]= b[0]+b_stride;
03331                 b[3]= b[2]+1;
03332                 if(same_block(b[0], b[1]) &&
03333                    same_block(b[0], b[2]) &&
03334                    same_block(b[0], b[3]))
03335                     continue;
03336 
03337                 if(!s->me_cache_generation)
03338                     memset(s->me_cache, 0, sizeof(s->me_cache));
03339                 s->me_cache_generation += 1<<22;
03340 
03341                 init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0);
03342 
03343                 //FIXME more multiref search?
03344                 check_4block_inter(s, mb_x, mb_y,
03345                                    (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2,
03346                                    (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, 0, &best_rd);
03347 
03348                 for(i=0; i<4; i++)
03349                     if(!(b[i]->type&BLOCK_INTRA))
03350                         check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, b[i]->ref, &best_rd);
03351 
03352                 if(init_rd != best_rd)
03353                     change++;
03354             }
03355         }
03356         av_log(s->avctx, AV_LOG_ERROR, "pass:4mv changed:%d\n", change*4);
03357     }
03358 }
03359 
03360 static void encode_blocks(SnowContext *s, int search){
03361     int x, y;
03362     int w= s->b_width;
03363     int h= s->b_height;
03364 
03365     if(s->avctx->me_method == ME_ITER && !s->keyframe && search)
03366         iterative_me(s);
03367 
03368     for(y=0; y<h; y++){
03369         if(s->c.bytestream_end - s->c.bytestream < w*MB_SIZE*MB_SIZE*3){ //FIXME nicer limit
03370             av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
03371             return;
03372         }
03373         for(x=0; x<w; x++){
03374             if(s->avctx->me_method == ME_ITER || !search)
03375                 encode_q_branch2(s, 0, x, y);
03376             else
03377                 encode_q_branch (s, 0, x, y);
03378         }
03379     }
03380 }
03381 
03382 static void quantize(SnowContext *s, SubBand *b, IDWTELEM *dst, DWTELEM *src, int stride, int bias){
03383     const int w= b->width;
03384     const int h= b->height;
03385     const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
03386     const int qmul= qexp[qlog&(QROOT-1)]<<((qlog>>QSHIFT) + ENCODER_EXTRA_BITS);
03387     int x,y, thres1, thres2;
03388 
03389     if(s->qlog == LOSSLESS_QLOG){
03390         for(y=0; y<h; y++)
03391             for(x=0; x<w; x++)
03392                 dst[x + y*stride]= src[x + y*stride];
03393         return;
03394     }
03395 
03396     bias= bias ? 0 : (3*qmul)>>3;
03397     thres1= ((qmul - bias)>>QEXPSHIFT) - 1;
03398     thres2= 2*thres1;
03399 
03400     if(!bias){
03401         for(y=0; y<h; y++){
03402             for(x=0; x<w; x++){
03403                 int i= src[x + y*stride];
03404 
03405                 if((unsigned)(i+thres1) > thres2){
03406                     if(i>=0){
03407                         i<<= QEXPSHIFT;
03408                         i/= qmul; //FIXME optimize
03409                         dst[x + y*stride]=  i;
03410                     }else{
03411                         i= -i;
03412                         i<<= QEXPSHIFT;
03413                         i/= qmul; //FIXME optimize
03414                         dst[x + y*stride]= -i;
03415                     }
03416                 }else
03417                     dst[x + y*stride]= 0;
03418             }
03419         }
03420     }else{
03421         for(y=0; y<h; y++){
03422             for(x=0; x<w; x++){
03423                 int i= src[x + y*stride];
03424 
03425                 if((unsigned)(i+thres1) > thres2){
03426                     if(i>=0){
03427                         i<<= QEXPSHIFT;
03428                         i= (i + bias) / qmul; //FIXME optimize
03429                         dst[x + y*stride]=  i;
03430                     }else{
03431                         i= -i;
03432                         i<<= QEXPSHIFT;
03433                         i= (i + bias) / qmul; //FIXME optimize
03434                         dst[x + y*stride]= -i;
03435                     }
03436                 }else
03437                     dst[x + y*stride]= 0;
03438             }
03439         }
03440     }
03441 }
03442 
03443 static void dequantize(SnowContext *s, SubBand *b, IDWTELEM *src, int stride){
03444     const int w= b->width;
03445     const int h= b->height;
03446     const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
03447     const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
03448     const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
03449     int x,y;
03450 
03451     if(s->qlog == LOSSLESS_QLOG) return;
03452 
03453     for(y=0; y<h; y++){
03454         for(x=0; x<w; x++){
03455             int i= src[x + y*stride];
03456             if(i<0){
03457                 src[x + y*stride]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
03458             }else if(i>0){
03459                 src[x + y*stride]=  (( i*qmul + qadd)>>(QEXPSHIFT));
03460             }
03461         }
03462     }
03463 }
03464 
03465 static void decorrelate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
03466     const int w= b->width;
03467     const int h= b->height;
03468     int x,y;
03469 
03470     for(y=h-1; y>=0; y--){
03471         for(x=w-1; x>=0; x--){
03472             int i= x + y*stride;
03473 
03474             if(x){
03475                 if(use_median){
03476                     if(y && x+1<w) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
03477                     else  src[i] -= src[i - 1];
03478                 }else{
03479                     if(y) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
03480                     else  src[i] -= src[i - 1];
03481                 }
03482             }else{
03483                 if(y) src[i] -= src[i - stride];
03484             }
03485         }
03486     }
03487 }
03488 
03489 static void correlate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
03490     const int w= b->width;
03491     const int h= b->height;
03492     int x,y;
03493 
03494     for(y=0; y<h; y++){
03495         for(x=0; x<w; x++){
03496             int i= x + y*stride;
03497 
03498             if(x){
03499                 if(use_median){
03500                     if(y && x+1<w) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
03501                     else  src[i] += src[i - 1];
03502                 }else{
03503                     if(y) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
03504                     else  src[i] += src[i - 1];
03505                 }
03506             }else{
03507                 if(y) src[i] += src[i - stride];
03508             }
03509         }
03510     }
03511 }
03512 
03513 static void encode_qlogs(SnowContext *s){
03514     int plane_index, level, orientation;
03515 
03516     for(plane_index=0; plane_index<2; plane_index++){
03517         for(level=0; level<s->spatial_decomposition_count; level++){
03518             for(orientation=level ? 1:0; orientation<4; orientation++){
03519                 if(orientation==2) continue;
03520                 put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1);
03521             }
03522         }
03523     }
03524 }
03525 
03526 static void encode_header(SnowContext *s){
03527     int plane_index, i;
03528     uint8_t kstate[32];
03529 
03530     memset(kstate, MID_STATE, sizeof(kstate));
03531 
03532     put_rac(&s->c, kstate, s->keyframe);
03533     if(s->keyframe || s->always_reset){
03534         reset_contexts(s);
03535         s->last_spatial_decomposition_type=
03536         s->last_qlog=
03537         s->last_qbias=
03538         s->last_mv_scale=
03539         s->last_block_max_depth= 0;
03540         for(plane_index=0; plane_index<2; plane_index++){
03541             Plane *p= &s->plane[plane_index];
03542             p->last_htaps=0;
03543             p->last_diag_mc=0;
03544             memset(p->last_hcoeff, 0, sizeof(p->last_hcoeff));
03545         }
03546     }
03547     if(s->keyframe){
03548         put_symbol(&s->c, s->header_state, s->version, 0);
03549         put_rac(&s->c, s->header_state, s->always_reset);
03550         put_symbol(&s->c, s->header_state, s->temporal_decomposition_type, 0);
03551         put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0);
03552         put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
03553         put_symbol(&s->c, s->header_state, s->colorspace_type, 0);
03554         put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0);
03555         put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0);
03556         put_rac(&s->c, s->header_state, s->spatial_scalability);
03557 //        put_rac(&s->c, s->header_state, s->rate_scalability);
03558         put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0);
03559 
03560         encode_qlogs(s);
03561     }
03562 
03563     if(!s->keyframe){
03564         int update_mc=0;
03565         for(plane_index=0; plane_index<2; plane_index++){
03566             Plane *p= &s->plane[plane_index];
03567             update_mc |= p->last_htaps   != p->htaps;
03568             update_mc |= p->last_diag_mc != p->diag_mc;
03569             update_mc |= !!memcmp(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
03570         }
03571         put_rac(&s->c, s->header_state, update_mc);
03572         if(update_mc){
03573             for(plane_index=0; plane_index<2; plane_index++){
03574                 Plane *p= &s->plane[plane_index];
03575                 put_rac(&s->c, s->header_state, p->diag_mc);
03576                 put_symbol(&s->c, s->header_state, p->htaps/2-1, 0);
03577                 for(i= p->htaps/2; i; i--)
03578                     put_symbol(&s->c, s->header_state, FFABS(p->hcoeff[i]), 0);
03579             }
03580         }
03581         if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
03582             put_rac(&s->c, s->header_state, 1);
03583             put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
03584             encode_qlogs(s);
03585         }else
03586             put_rac(&s->c, s->header_state, 0);
03587     }
03588 
03589     put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1);
03590     put_symbol(&s->c, s->header_state, s->qlog            - s->last_qlog    , 1);
03591     put_symbol(&s->c, s->header_state, s->mv_scale        - s->last_mv_scale, 1);
03592     put_symbol(&s->c, s->header_state, s->qbias           - s->last_qbias   , 1);
03593     put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1);
03594 
03595 }
03596 
03597 static void update_last_header_values(SnowContext *s){
03598     int plane_index;
03599 
03600     if(!s->keyframe){
03601         for(plane_index=0; plane_index<2; plane_index++){
03602             Plane *p= &s->plane[plane_index];
03603             p->last_diag_mc= p->diag_mc;
03604             p->last_htaps  = p->htaps;
03605             memcpy(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
03606         }
03607     }
03608 
03609     s->last_spatial_decomposition_type  = s->spatial_decomposition_type;
03610     s->last_qlog                        = s->qlog;
03611     s->last_qbias                       = s->qbias;
03612     s->last_mv_scale                    = s->mv_scale;
03613     s->last_block_max_depth             = s->block_max_depth;
03614     s->last_spatial_decomposition_count = s->spatial_decomposition_count;
03615 }
03616 
03617 static int qscale2qlog(int qscale){
03618     return rint(QROOT*log(qscale / (float)FF_QP2LAMBDA)/log(2))
03619            + 61*QROOT/8; //<64 >60
03620 }
03621 
03622 static int ratecontrol_1pass(SnowContext *s, AVFrame *pict)
03623 {
03624     /* Estimate the frame's complexity as a sum of weighted dwt coefficients.
03625      * FIXME we know exact mv bits at this point,
03626      * but ratecontrol isn't set up to include them. */
03627     uint32_t coef_sum= 0;
03628     int level, orientation, delta_qlog;
03629 
03630     for(level=0; level<s->spatial_decomposition_count; level++){
03631         for(orientation=level ? 1 : 0; orientation<4; orientation++){
03632             SubBand *b= &s->plane[0].band[level][orientation];
03633             IDWTELEM *buf= b->ibuf;
03634             const int w= b->width;
03635             const int h= b->height;
03636             const int stride= b->stride;
03637             const int qlog= av_clip(2*QROOT + b->qlog, 0, QROOT*16);
03638             const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
03639             const int qdiv= (1<<16)/qmul;
03640             int x, y;
03641             //FIXME this is ugly
03642             for(y=0; y<h; y++)
03643                 for(x=0; x<w; x++)
03644                     buf[x+y*stride]= b->buf[x+y*stride];
03645             if(orientation==0)
03646                 decorrelate(s, b, buf, stride, 1, 0);
03647             for(y=0; y<h; y++)
03648                 for(x=0; x<w; x++)
03649                     coef_sum+= abs(buf[x+y*stride]) * qdiv >> 16;
03650         }
03651     }
03652 
03653     /* ugly, ratecontrol just takes a sqrt again */
03654     coef_sum = (uint64_t)coef_sum * coef_sum >> 16;
03655     assert(coef_sum < INT_MAX);
03656 
03657     if(pict->pict_type == FF_I_TYPE){
03658         s->m.current_picture.mb_var_sum= coef_sum;
03659         s->m.current_picture.mc_mb_var_sum= 0;
03660     }else{
03661         s->m.current_picture.mc_mb_var_sum= coef_sum;
03662         s->m.current_picture.mb_var_sum= 0;
03663     }
03664 
03665     pict->quality= ff_rate_estimate_qscale(&s->m, 1);
03666     if (pict->quality < 0)
03667         return INT_MIN;
03668     s->lambda= pict->quality * 3/2;
03669     delta_qlog= qscale2qlog(pict->quality) - s->qlog;
03670     s->qlog+= delta_qlog;
03671     return delta_qlog;
03672 }
03673 
03674 static void calculate_visual_weight(SnowContext *s, Plane *p){
03675     int width = p->width;
03676     int height= p->height;
03677     int level, orientation, x, y;
03678 
03679     for(level=0; level<s->spatial_decomposition_count; level++){
03680         for(orientation=level ? 1 : 0; orientation<4; orientation++){
03681             SubBand *b= &p->band[level][orientation];
03682             IDWTELEM *ibuf= b->ibuf;
03683             int64_t error=0;
03684 
03685             memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height);
03686             ibuf[b->width/2 + b->height/2*b->stride]= 256*16;
03687             ff_spatial_idwt(s->spatial_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count);
03688             for(y=0; y<height; y++){
03689                 for(x=0; x<width; x++){
03690                     int64_t d= s->spatial_idwt_buffer[x + y*width]*16;
03691                     error += d*d;
03692                 }
03693             }
03694 
03695             b->qlog= (int)(log(352256.0/sqrt(error)) / log(pow(2.0, 1.0/QROOT))+0.5);
03696         }
03697     }
03698 }
03699 
03700 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
03701     SnowContext *s = avctx->priv_data;
03702     RangeCoder * const c= &s->c;
03703     AVFrame *pict = data;
03704     const int width= s->avctx->width;
03705     const int height= s->avctx->height;
03706     int level, orientation, plane_index, i, y;
03707     uint8_t rc_header_bak[sizeof(s->header_state)];
03708     uint8_t rc_block_bak[sizeof(s->block_state)];
03709 
03710     ff_init_range_encoder(c, buf, buf_size);
03711     ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
03712 
03713     for(i=0; i<3; i++){
03714         int shift= !!i;
03715         for(y=0; y<(height>>shift); y++)
03716             memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]],
03717                    &pict->data[i][y * pict->linesize[i]],
03718                    width>>shift);
03719     }
03720     s->new_picture = *pict;
03721 
03722     s->m.picture_number= avctx->frame_number;
03723     if(avctx->flags&CODEC_FLAG_PASS2){
03724         s->m.pict_type =
03725         pict->pict_type= s->m.rc_context.entry[avctx->frame_number].new_pict_type;
03726         s->keyframe= pict->pict_type==FF_I_TYPE;
03727         if(!(avctx->flags&CODEC_FLAG_QSCALE)) {
03728             pict->quality= ff_rate_estimate_qscale(&s->m, 0);
03729             if (pict->quality < 0)
03730                 return -1;
03731         }
03732     }else{
03733         s->keyframe= avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0;
03734         s->m.pict_type=
03735         pict->pict_type= s->keyframe ? FF_I_TYPE : FF_P_TYPE;
03736     }
03737 
03738     if(s->pass1_rc && avctx->frame_number == 0)
03739         pict->quality= 2*FF_QP2LAMBDA;
03740     if(pict->quality){
03741         s->qlog= qscale2qlog(pict->quality);
03742         s->lambda = pict->quality * 3/2;
03743     }
03744     if(s->qlog < 0 || (!pict->quality && (avctx->flags & CODEC_FLAG_QSCALE))){
03745         s->qlog= LOSSLESS_QLOG;
03746         s->lambda = 0;
03747     }//else keep previous frame's qlog until after motion estimation
03748 
03749     frame_start(s);
03750 
03751     s->m.current_picture_ptr= &s->m.current_picture;
03752     s->m.last_picture.pts= s->m.current_picture.pts;
03753     s->m.current_picture.pts= pict->pts;
03754     if(pict->pict_type == FF_P_TYPE){
03755         int block_width = (width +15)>>4;
03756         int block_height= (height+15)>>4;
03757         int stride= s->current_picture.linesize[0];
03758 
03759         assert(s->current_picture.data[0]);
03760         assert(s->last_picture[0].data[0]);
03761 
03762         s->m.avctx= s->avctx;
03763         s->m.current_picture.data[0]= s->current_picture.data[0];
03764         s->m.   last_picture.data[0]= s->last_picture[0].data[0];
03765         s->m.    new_picture.data[0]= s->  input_picture.data[0];
03766         s->m.   last_picture_ptr= &s->m.   last_picture;
03767         s->m.linesize=
03768         s->m.   last_picture.linesize[0]=
03769         s->m.    new_picture.linesize[0]=
03770         s->m.current_picture.linesize[0]= stride;
03771         s->m.uvlinesize= s->current_picture.linesize[1];
03772         s->m.width = width;
03773         s->m.height= height;
03774         s->m.mb_width = block_width;
03775         s->m.mb_height= block_height;
03776         s->m.mb_stride=   s->m.mb_width+1;
03777         s->m.b8_stride= 2*s->m.mb_width+1;
03778         s->m.f_code=1;
03779         s->m.pict_type= pict->pict_type;
03780         s->m.me_method= s->avctx->me_method;
03781         s->m.me.scene_change_score=0;
03782         s->m.flags= s->avctx->flags;
03783         s->m.quarter_sample= (s->avctx->flags & CODEC_FLAG_QPEL)!=0;
03784         s->m.out_format= FMT_H263;
03785         s->m.unrestricted_mv= 1;
03786 
03787         s->m.lambda = s->lambda;
03788         s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
03789         s->lambda2= s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
03790 
03791         s->m.dsp= s->dsp; //move
03792         ff_init_me(&s->m);
03793         s->dsp= s->m.dsp;
03794     }
03795 
03796     if(s->pass1_rc){
03797         memcpy(rc_header_bak, s->header_state, sizeof(s->header_state));
03798         memcpy(rc_block_bak, s->block_state, sizeof(s->block_state));
03799     }
03800 
03801 redo_frame:
03802 
03803     if(pict->pict_type == FF_I_TYPE)
03804         s->spatial_decomposition_count= 5;
03805     else
03806         s->spatial_decomposition_count= 5;
03807 
03808     s->m.pict_type = pict->pict_type;
03809     s->qbias= pict->pict_type == FF_P_TYPE ? 2 : 0;
03810 
03811     common_init_after_header(avctx);
03812 
03813     if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
03814         for(plane_index=0; plane_index<3; plane_index++){
03815             calculate_visual_weight(s, &s->plane[plane_index]);
03816         }
03817     }
03818 
03819     encode_header(s);
03820     s->m.misc_bits = 8*(s->c.bytestream - s->c.bytestream_start);
03821     encode_blocks(s, 1);
03822     s->m.mv_bits = 8*(s->c.bytestream - s->c.bytestream_start) - s->m.misc_bits;
03823 
03824     for(plane_index=0; plane_index<3; plane_index++){
03825         Plane *p= &s->plane[plane_index];
03826         int w= p->width;
03827         int h= p->height;
03828         int x, y;
03829 //        int bits= put_bits_count(&s->c.pb);
03830 
03831         if(!(avctx->flags2 & CODEC_FLAG2_MEMC_ONLY)){
03832             //FIXME optimize
03833             if(pict->data[plane_index]) //FIXME gray hack
03834                 for(y=0; y<h; y++){
03835                     for(x=0; x<w; x++){
03836                         s->spatial_idwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<FRAC_BITS;
03837                     }
03838                 }
03839             predict_plane(s, s->spatial_idwt_buffer, plane_index, 0);
03840 
03841             if(   plane_index==0
03842                && pict->pict_type == FF_P_TYPE
03843                && !(avctx->flags&CODEC_FLAG_PASS2)
03844                && s->m.me.scene_change_score > s->avctx->scenechange_threshold){
03845                 ff_init_range_encoder(c, buf, buf_size);
03846                 ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
03847                 pict->pict_type= FF_I_TYPE;
03848                 s->keyframe=1;
03849                 s->current_picture.key_frame=1;
03850                 goto redo_frame;
03851             }
03852 
03853             if(s->qlog == LOSSLESS_QLOG){
03854                 for(y=0; y<h; y++){
03855                     for(x=0; x<w; x++){
03856                         s->spatial_dwt_buffer[y*w + x]= (s->spatial_idwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS;
03857                     }
03858                 }
03859             }else{
03860                 for(y=0; y<h; y++){
03861                     for(x=0; x<w; x++){
03862                         s->spatial_dwt_buffer[y*w + x]=s->spatial_idwt_buffer[y*w + x]<<ENCODER_EXTRA_BITS;
03863                     }
03864                 }
03865             }
03866 
03867             /*  if(QUANTIZE2)
03868                 dwt_quantize(s, p, s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type);
03869             else*/
03870                 ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
03871 
03872             if(s->pass1_rc && plane_index==0){
03873                 int delta_qlog = ratecontrol_1pass(s, pict);
03874                 if (delta_qlog <= INT_MIN)
03875                     return -1;
03876                 if(delta_qlog){
03877                     //reordering qlog in the bitstream would eliminate this reset
03878                     ff_init_range_encoder(c, buf, buf_size);
03879                     memcpy(s->header_state, rc_header_bak, sizeof(s->header_state));
03880                     memcpy(s->block_state, rc_block_bak, sizeof(s->block_state));
03881                     encode_header(s);
03882                     encode_blocks(s, 0);
03883                 }
03884             }
03885 
03886             for(level=0; level<s->spatial_decomposition_count; level++){
03887                 for(orientation=level ? 1 : 0; orientation<4; orientation++){
03888                     SubBand *b= &p->band[level][orientation];
03889 
03890                     if(!QUANTIZE2)
03891                         quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias);
03892                     if(orientation==0)
03893                         decorrelate(s, b, b->ibuf, b->stride, pict->pict_type == FF_P_TYPE, 0);
03894                     encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation);
03895                     assert(b->parent==NULL || b->parent->stride == b->stride*2);
03896                     if(orientation==0)
03897                         correlate(s, b, b->ibuf, b->stride, 1, 0);
03898                 }
03899             }
03900 
03901             for(level=0; level<s->spatial_decomposition_count; level++){
03902                 for(orientation=level ? 1 : 0; orientation<4; orientation++){
03903                     SubBand *b= &p->band[level][orientation];
03904 
03905                     dequantize(s, b, b->ibuf, b->stride);
03906                 }
03907             }
03908 
03909             ff_spatial_idwt(s->spatial_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
03910             if(s->qlog == LOSSLESS_QLOG){
03911                 for(y=0; y<h; y++){
03912                     for(x=0; x<w; x++){
03913                         s->spatial_idwt_buffer[y*w + x]<<=FRAC_BITS;
03914                     }
03915                 }
03916             }
03917             predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
03918         }else{
03919             //ME/MC only
03920             if(pict->pict_type == FF_I_TYPE){
03921                 for(y=0; y<h; y++){
03922                     for(x=0; x<w; x++){
03923                         s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]=
03924                             pict->data[plane_index][y*pict->linesize[plane_index] + x];
03925                     }
03926                 }
03927             }else{
03928                 memset(s->spatial_idwt_buffer, 0, sizeof(IDWTELEM)*w*h);
03929                 predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
03930             }
03931         }
03932         if(s->avctx->flags&CODEC_FLAG_PSNR){
03933             int64_t error= 0;
03934 
03935             if(pict->data[plane_index]) //FIXME gray hack
03936                 for(y=0; y<h; y++){
03937                     for(x=0; x<w; x++){
03938                         int d= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x];
03939                         error += d*d;
03940                     }
03941                 }
03942             s->avctx->error[plane_index] += error;
03943             s->current_picture.error[plane_index] = error;
03944         }
03945 
03946     }
03947 
03948     update_last_header_values(s);
03949 
03950     release_buffer(avctx);
03951 
03952     s->current_picture.coded_picture_number = avctx->frame_number;
03953     s->current_picture.pict_type = pict->pict_type;
03954     s->current_picture.quality = pict->quality;
03955     s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start);
03956     s->m.p_tex_bits = s->m.frame_bits - s->m.misc_bits - s->m.mv_bits;
03957     s->m.current_picture.display_picture_number =
03958     s->m.current_picture.coded_picture_number = avctx->frame_number;
03959     s->m.current_picture.quality = pict->quality;
03960     s->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start);
03961     if(s->pass1_rc)
03962         if (ff_rate_estimate_qscale(&s->m, 0) < 0)
03963             return -1;
03964     if(avctx->flags&CODEC_FLAG_PASS1)
03965         ff_write_pass1_stats(&s->m);
03966     s->m.last_pict_type = s->m.pict_type;
03967     avctx->frame_bits = s->m.frame_bits;
03968     avctx->mv_bits = s->m.mv_bits;
03969     avctx->misc_bits = s->m.misc_bits;
03970     avctx->p_tex_bits = s->m.p_tex_bits;
03971 
03972     emms_c();
03973 
03974     return ff_rac_terminate(c);
03975 }
03976 
03977 static av_cold int encode_end(AVCodecContext *avctx)
03978 {
03979     SnowContext *s = avctx->priv_data;
03980 
03981     common_end(s);
03982     if (s->input_picture.data[0])
03983         avctx->release_buffer(avctx, &s->input_picture);
03984     av_free(avctx->stats_out);
03985 
03986     return 0;
03987 }
03988 
03989 AVCodec snow_encoder = {
03990     "snow",
03991     AVMEDIA_TYPE_VIDEO,
03992     CODEC_ID_SNOW,
03993     sizeof(SnowContext),
03994     encode_init,
03995     encode_frame,
03996     encode_end,
03997     .long_name = NULL_IF_CONFIG_SMALL("Snow"),
03998 };
03999 #endif
04000 
04001 
04002 #ifdef TEST
04003 #undef malloc
04004 #undef free
04005 #undef printf
04006 
04007 #include "libavutil/lfg.h"
04008 
04009 int main(void){
04010     int width=256;
04011     int height=256;
04012     int buffer[2][width*height];
04013     SnowContext s;
04014     int i;
04015     AVLFG prng;
04016     s.spatial_decomposition_count=6;
04017     s.spatial_decomposition_type=1;
04018 
04019     av_lfg_init(&prng, 1);
04020 
04021     printf("testing 5/3 DWT\n");
04022     for(i=0; i<width*height; i++)
04023         buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
04024 
04025     ff_spatial_dwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
04026     ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
04027 
04028     for(i=0; i<width*height; i++)
04029         if(buffer[0][i]!= buffer[1][i]) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
04030 
04031     printf("testing 9/7 DWT\n");
04032     s.spatial_decomposition_type=0;
04033     for(i=0; i<width*height; i++)
04034         buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
04035 
04036     ff_spatial_dwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
04037     ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
04038 
04039     for(i=0; i<width*height; i++)
04040         if(FFABS(buffer[0][i] - buffer[1][i])>20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
04041 
04042 #if 0
04043     printf("testing AC coder\n");
04044     memset(s.header_state, 0, sizeof(s.header_state));
04045     ff_init_range_encoder(&s.c, buffer[0], 256*256);
04046     ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
04047 
04048     for(i=-256; i<256; i++){
04049         put_symbol(&s.c, s.header_state, i*i*i/3*FFABS(i), 1);
04050     }
04051     ff_rac_terminate(&s.c);
04052 
04053     memset(s.header_state, 0, sizeof(s.header_state));
04054     ff_init_range_decoder(&s.c, buffer[0], 256*256);
04055     ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
04056 
04057     for(i=-256; i<256; i++){
04058         int j;
04059         j= get_symbol(&s.c, s.header_state, 1);
04060         if(j!=i*i*i/3*FFABS(i)) printf("fsck: %d != %d\n", i, j);
04061     }
04062 #endif
04063     {
04064     int level, orientation, x, y;
04065     int64_t errors[8][4];
04066     int64_t g=0;
04067 
04068         memset(errors, 0, sizeof(errors));
04069         s.spatial_decomposition_count=3;
04070         s.spatial_decomposition_type=0;
04071         for(level=0; level<s.spatial_decomposition_count; level++){
04072             for(orientation=level ? 1 : 0; orientation<4; orientation++){
04073                 int w= width  >> (s.spatial_decomposition_count-level);
04074                 int h= height >> (s.spatial_decomposition_count-level);
04075                 int stride= width  << (s.spatial_decomposition_count-level);
04076                 DWTELEM *buf= buffer[0];
04077                 int64_t error=0;
04078 
04079                 if(orientation&1) buf+=w;
04080                 if(orientation>1) buf+=stride>>1;
04081 
04082                 memset(buffer[0], 0, sizeof(int)*width*height);
04083                 buf[w/2 + h/2*stride]= 256*256;
04084                 ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
04085                 for(y=0; y<height; y++){
04086                     for(x=0; x<width; x++){
04087                         int64_t d= buffer[0][x + y*width];
04088                         error += d*d;
04089                         if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9 && level==2) printf("%8"PRId64" ", d);
04090                     }
04091                     if(FFABS(height/2-y)<9 && level==2) printf("\n");
04092                 }
04093                 error= (int)(sqrt(error)+0.5);
04094                 errors[level][orientation]= error;
04095                 if(g) g=av_gcd(g, error);
04096                 else g= error;
04097             }
04098         }
04099         printf("static int const visual_weight[][4]={\n");
04100         for(level=0; level<s.spatial_decomposition_count; level++){
04101             printf("  {");
04102             for(orientation=0; orientation<4; orientation++){
04103                 printf("%8"PRId64",", errors[level][orientation]/g);
04104             }
04105             printf("},\n");
04106         }
04107         printf("};\n");
04108         {
04109             int level=2;
04110             int w= width  >> (s.spatial_decomposition_count-level);
04111             //int h= height >> (s.spatial_decomposition_count-level);
04112             int stride= width  << (s.spatial_decomposition_count-level);
04113             DWTELEM *buf= buffer[0];
04114             int64_t error=0;
04115 
04116             buf+=w;
04117             buf+=stride>>1;
04118 
04119             memset(buffer[0], 0, sizeof(int)*width*height);
04120 #if 1
04121             for(y=0; y<height; y++){
04122                 for(x=0; x<width; x++){
04123                     int tab[4]={0,2,3,1};
04124                     buffer[0][x+width*y]= 256*256*tab[(x&1) + 2*(y&1)];
04125                 }
04126             }
04127             ff_spatial_dwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
04128 #else
04129             for(y=0; y<h; y++){
04130                 for(x=0; x<w; x++){
04131                     buf[x + y*stride  ]=169;
04132                     buf[x + y*stride-w]=64;
04133                 }
04134             }
04135             ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
04136 #endif
04137             for(y=0; y<height; y++){
04138                 for(x=0; x<width; x++){
04139                     int64_t d= buffer[0][x + y*width];
04140                     error += d*d;
04141                     if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9) printf("%8"PRId64" ", d);
04142                 }
04143                 if(FFABS(height/2-y)<9) printf("\n");
04144             }
04145         }
04146 
04147     }
04148     return 0;
04149 }
04150 #endif /* TEST */

Generated on Fri Sep 16 2011 17:17:43 for FFmpeg by  doxygen 1.7.1