Mercurial > libavcodec.hg
annotate libpostproc/postprocess.c @ 787:4914252c963a libavcodec
postprocessing cleanup:
remove opendivx #ifdefs
remove rk1 filter
remove unused / obsolete stuff
add -1,4,2,4,-1 deinterlacing filter (ffmpeg uses that)
threadsafe / no more non-const globals
some optimizations
different strides for Y,U,V possible
remove ebx usage (someone really should fix gcc, this is really lame)
change the dering filter slightly (tell me if its worse for any files)
author | michael |
---|---|
date | Mon, 28 Oct 2002 19:30:58 +0000 |
parents | b71190bacce8 |
children | 4f61ca80b6c1 |
rev | line source |
---|---|
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
1 /* |
183 | 2 Copyright (C) 2001-2002 Michael Niedermayer (michaelni@gmx.at) |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
3 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
4 This program is free software; you can redistribute it and/or modify |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
5 it under the terms of the GNU General Public License as published by |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
6 the Free Software Foundation; either version 2 of the License, or |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
7 (at your option) any later version. |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
8 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
9 This program is distributed in the hope that it will be useful, |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
12 GNU General Public License for more details. |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
13 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
14 You should have received a copy of the GNU General Public License |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
15 along with this program; if not, write to the Free Software |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
17 */ |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
18 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
19 /* |
106
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
20 C MMX MMX2 3DNow |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
21 isVertDC Ec Ec |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
22 isVertMinMaxOk Ec Ec |
106
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
23 doVertLowPass E e e |
163 | 24 doVertDefFilter Ec Ec e e |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
25 isHorizDC Ec Ec |
128
e5266b8e79be
much better horizontal filters (transpose & use the vertical ones) :)
michael
parents:
126
diff
changeset
|
26 isHorizMinMaxOk a E |
e5266b8e79be
much better horizontal filters (transpose & use the vertical ones) :)
michael
parents:
126
diff
changeset
|
27 doHorizLowPass E e e |
163 | 28 doHorizDefFilter Ec Ec e e |
134 | 29 deRing E e e* |
106
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
30 Vertical RKAlgo1 E a a |
129
be35346e27c1
fixed difference with -vo md5 between doVertDefFilter() C and MMX / MMX2 versions
michael
parents:
128
diff
changeset
|
31 Horizontal RKAlgo1 a a |
156 | 32 Vertical X1# a E E |
33 Horizontal X1# a E E | |
111 | 34 LinIpolDeinterlace e E E* |
35 CubicIpolDeinterlace a e e* | |
36 LinBlendDeinterlace e E E* | |
156 | 37 MedianDeinterlace# Ec Ec |
157
bc12fd7e6153
temp denoiser changes: (a-b)^2 instead of |a-b| and MMX2/3DNOW version
michael
parents:
156
diff
changeset
|
38 TempDeNoiser# E e e |
156 | 39 |
40 * i dont have a 3dnow CPU -> its untested, but noone said it doesnt work so it seems to work | |
41 # more or less selfinvented filters so the exactness isnt too meaningfull | |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
42 E = Exact implementation |
111 | 43 e = allmost exact implementation (slightly different rounding,...) |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
44 a = alternative / approximate impl |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
45 c = checked against the other implementations (-vo md5) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
46 */ |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
47 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
48 /* |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
49 TODO: |
182
3ccd74a91074
minor brightness/contrast bugfix / moved some global vars into ppMode
michael
parents:
181
diff
changeset
|
50 remove global/static vars |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
51 reduce the time wasted on the mem transfer |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
52 unroll stuff if instructions depend too much on the prior one |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
53 we use 8x8 blocks for the horizontal filters, opendivx seems to use 8x4? |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
54 move YScale thing to the end instead of fixing QP |
96 | 55 write a faster and higher quality deblocking filter :) |
97
e57b1d38d71f
bugfixes: last 3 lines not brightness/contrast corrected
michael
parents:
96
diff
changeset
|
56 make the mainloop more flexible (variable number of blocks at once |
e57b1d38d71f
bugfixes: last 3 lines not brightness/contrast corrected
michael
parents:
96
diff
changeset
|
57 (the if/else stuff per block is slowing things down) |
99 | 58 compare the quality & speed of all filters |
59 split this huge file | |
140 | 60 optimize c versions |
156 | 61 try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks |
169 | 62 put fastmemcpy back |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
63 ... |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
64 */ |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
65 |
107 | 66 //Changelog: use the CVS log |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
67 |
150 | 68 #include "../config.h" |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
69 #include <inttypes.h> |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
70 #include <stdio.h> |
97
e57b1d38d71f
bugfixes: last 3 lines not brightness/contrast corrected
michael
parents:
96
diff
changeset
|
71 #include <stdlib.h> |
116 | 72 #include <string.h> |
212 | 73 #include <errno.h> |
133 | 74 #ifdef HAVE_MALLOC_H |
75 #include <malloc.h> | |
76 #endif | |
96 | 77 //#undef HAVE_MMX2 |
78 //#define HAVE_3DNOW | |
79 //#undef HAVE_MMX | |
169 | 80 //#undef ARCH_X86 |
163 | 81 //#define DEBUG_BRIGHTNESS |
787 | 82 #include "../libvo/fastmemcpy.h" |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
83 #include "postprocess.h" |
169 | 84 #include "../cpudetect.h" |
210 | 85 #include "../mangle.h" |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
86 |
104 | 87 #define MIN(a,b) ((a) > (b) ? (b) : (a)) |
88 #define MAX(a,b) ((a) < (b) ? (b) : (a)) | |
89 #define ABS(a) ((a) > 0 ? (a) : (-(a))) | |
90 #define SIGN(a) ((a) > 0 ? 1 : -1) | |
91 | |
116 | 92 #define GET_MODE_BUFFER_SIZE 500 |
93 #define OPTIONS_ARRAY_SIZE 10 | |
787 | 94 #define BLOCK_SIZE 8 |
95 #define TEMP_STRIDE 8 | |
96 //#define NUM_BLOCKS_AT_ONCE 16 //not used yet | |
116 | 97 |
169 | 98 #ifdef ARCH_X86 |
148
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
99 static uint64_t __attribute__((aligned(8))) w05= 0x0005000500050005LL; |
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
100 static uint64_t __attribute__((aligned(8))) w20= 0x0020002000200020LL; |
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
101 static uint64_t __attribute__((aligned(8))) b00= 0x0000000000000000LL; |
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
102 static uint64_t __attribute__((aligned(8))) b01= 0x0101010101010101LL; |
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
103 static uint64_t __attribute__((aligned(8))) b02= 0x0202020202020202LL; |
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
104 static uint64_t __attribute__((aligned(8))) b08= 0x0808080808080808LL; |
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
105 static uint64_t __attribute__((aligned(8))) b80= 0x8080808080808080LL; |
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
106 #endif |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
107 |
179 | 108 extern int divx_quality; |
787 | 109 static int firstTime2 = 0; |
179 | 110 |
111 extern int verbose; | |
112 | |
167 | 113 int deringThreshold= 20; |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
114 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
115 //amount of "black" u r willing to loose to get a brightness corrected picture |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
116 double maxClippedThreshold= 0.01; |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
117 |
787 | 118 struct PPFilter{ |
119 char *shortName; | |
120 char *longName; | |
121 int chromDefault; // is chrominance filtering on by default if this filter is manually activated | |
122 int minLumQuality; // minimum quality to turn luminance filtering on | |
123 int minChromQuality; // minimum quality to turn chrominance filtering on | |
124 int mask; // Bitmask to turn this filter on | |
125 }; | |
126 | |
127 typedef struct PPContext{ | |
128 uint8_t *tempBlocks; //used for the horizontal code | |
129 | |
130 /* we need 64bit here otherwise we´ll going to have a problem | |
131 after watching a black picture for 5 hours*/ | |
132 uint64_t *yHistogram; | |
133 | |
134 uint64_t __attribute__((aligned(8))) packedYOffset; | |
135 uint64_t __attribute__((aligned(8))) packedYScale; | |
136 | |
137 /* Temporal noise reducing buffers */ | |
138 uint8_t *tempBlured[3]; | |
139 int32_t *tempBluredPast[3]; | |
140 | |
141 /* Temporary buffers for handling the last row(s) */ | |
142 uint8_t *tempDst; | |
143 uint8_t *tempSrc; | |
144 | |
145 /* Temporary buffers for handling the last block */ | |
146 uint8_t *tempDstBlock; | |
147 uint8_t *tempSrcBlock; | |
148 uint8_t *deintTemp; | |
149 | |
150 uint64_t __attribute__((aligned(8))) pQPb; | |
151 uint64_t __attribute__((aligned(8))) pQPb2; | |
152 | |
153 uint64_t __attribute__((aligned(8))) mmxDcOffset; | |
154 uint64_t __attribute__((aligned(8))) mmxDcThreshold; | |
155 | |
156 int QP; | |
157 int dcOffset; | |
158 int dcThreshold; | |
159 | |
160 int frameNum; | |
161 | |
162 PPMode ppMode; | |
163 } PPContext; | |
164 | |
116 | 165 static struct PPFilter filters[]= |
166 { | |
167 {"hb", "hdeblock", 1, 1, 3, H_DEBLOCK}, | |
168 {"vb", "vdeblock", 1, 2, 4, V_DEBLOCK}, | |
787 | 169 /* {"hr", "rkhdeblock", 1, 1, 3, H_RK1_FILTER}, |
170 {"vr", "rkvdeblock", 1, 2, 4, V_RK1_FILTER},*/ | |
116 | 171 {"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER}, |
172 {"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER}, | |
173 {"dr", "dering", 1, 5, 6, DERING}, | |
174 {"al", "autolevels", 0, 1, 2, LEVEL_FIX}, | |
181 | 175 {"lb", "linblenddeint", 1, 1, 4, LINEAR_BLEND_DEINT_FILTER}, |
176 {"li", "linipoldeint", 1, 1, 4, LINEAR_IPOL_DEINT_FILTER}, | |
177 {"ci", "cubicipoldeint", 1, 1, 4, CUBIC_IPOL_DEINT_FILTER}, | |
178 {"md", "mediandeint", 1, 1, 4, MEDIAN_DEINT_FILTER}, | |
787 | 179 {"fd", "ffmpegdeint", 1, 1, 4, FFMPEG_DEINT_FILTER}, |
156 | 180 {"tn", "tmpnoise", 1, 7, 8, TEMP_NOISE_FILTER}, |
183 | 181 {"fq", "forcequant", 1, 0, 0, FORCE_QUANT}, |
116 | 182 {NULL, NULL,0,0,0,0} //End Marker |
183 }; | |
184 | |
185 static char *replaceTable[]= | |
186 { | |
156 | 187 "default", "hdeblock:a,vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400", |
188 "de", "hdeblock:a,vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400", | |
189 "fast", "x1hdeblock:a,x1vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400", | |
190 "fa", "x1hdeblock:a,x1vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400", | |
116 | 191 NULL //End Marker |
192 }; | |
193 | |
787 | 194 #ifdef ARCH_X86 |
129
be35346e27c1
fixed difference with -vo md5 between doVertDefFilter() C and MMX / MMX2 versions
michael
parents:
128
diff
changeset
|
195 static inline void unusedVariableWarningFixer() |
be35346e27c1
fixed difference with -vo md5 between doVertDefFilter() C and MMX / MMX2 versions
michael
parents:
128
diff
changeset
|
196 { |
787 | 197 if(w05 + w20 + b00 + b01 + b02 + b08 + b80 == 0) b00=0; |
129
be35346e27c1
fixed difference with -vo md5 between doVertDefFilter() C and MMX / MMX2 versions
michael
parents:
128
diff
changeset
|
198 } |
148
1cfc4d567c0a
minor changes (fixed some warnings, added attribute aligned(8) stuff)
michael
parents:
142
diff
changeset
|
199 #endif |
129
be35346e27c1
fixed difference with -vo md5 between doVertDefFilter() C and MMX / MMX2 versions
michael
parents:
128
diff
changeset
|
200 |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
201 static inline long long rdtsc() |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
202 { |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
203 long long l; |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
204 asm volatile( "rdtsc\n\t" |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
205 : "=A" (l) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
206 ); |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
207 // printf("%d\n", int(l/1000)); |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
208 return l; |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
209 } |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
210 |
787 | 211 #ifdef ARCH_X86 |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
212 static inline void prefetchnta(void *p) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
213 { |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
214 asm volatile( "prefetchnta (%0)\n\t" |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
215 : : "r" (p) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
216 ); |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
217 } |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
218 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
219 static inline void prefetcht0(void *p) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
220 { |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
221 asm volatile( "prefetcht0 (%0)\n\t" |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
222 : : "r" (p) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
223 ); |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
224 } |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
225 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
226 static inline void prefetcht1(void *p) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
227 { |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
228 asm volatile( "prefetcht1 (%0)\n\t" |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
229 : : "r" (p) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
230 ); |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
231 } |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
232 |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
233 static inline void prefetcht2(void *p) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
234 { |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
235 asm volatile( "prefetcht2 (%0)\n\t" |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
236 : : "r" (p) |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
237 ); |
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
238 } |
102 | 239 #endif |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
240 |
169 | 241 // The horizontal Functions exist only in C cuz the MMX code is faster with vertical filters and transposing |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
242 |
165 | 243 /** |
244 * Check if the given 8x8 Block is mostly "flat" | |
245 */ | |
787 | 246 static inline int isHorizDC(uint8_t src[], int stride, PPContext *c) |
165 | 247 { |
248 int numEq= 0; | |
249 int y; | |
787 | 250 const int dcOffset= c->dcOffset; |
251 const int dcThreshold= c->dcThreshold; | |
165 | 252 for(y=0; y<BLOCK_SIZE; y++) |
253 { | |
787 | 254 if(((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold) numEq++; |
255 if(((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold) numEq++; | |
256 if(((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold) numEq++; | |
257 if(((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold) numEq++; | |
258 if(((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold) numEq++; | |
259 if(((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold) numEq++; | |
260 if(((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold) numEq++; | |
165 | 261 src+= stride; |
262 } | |
787 | 263 return numEq > c->ppMode.flatnessThreshold; |
264 } | |
265 | |
266 /** | |
267 * Check if the middle 8x8 Block in the given 8x16 block is flat | |
268 */ | |
269 static inline int isVertDC_C(uint8_t src[], int stride, PPContext *c){ | |
270 int numEq= 0; | |
271 int y; | |
272 const int dcOffset= c->dcOffset; | |
273 const int dcThreshold= c->dcThreshold; | |
274 src+= stride*4; // src points to begin of the 8x8 Block | |
275 for(y=0; y<BLOCK_SIZE-1; y++) | |
276 { | |
277 if(((unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold) numEq++; | |
278 if(((unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold) numEq++; | |
279 if(((unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold) numEq++; | |
280 if(((unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold) numEq++; | |
281 if(((unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold) numEq++; | |
282 if(((unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold) numEq++; | |
283 if(((unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold) numEq++; | |
284 if(((unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold) numEq++; | |
285 src+= stride; | |
286 } | |
287 return numEq > c->ppMode.flatnessThreshold; | |
165 | 288 } |
289 | |
290 static inline int isHorizMinMaxOk(uint8_t src[], int stride, int QP) | |
291 { | |
292 if(abs(src[0] - src[7]) > 2*QP) return 0; | |
293 | |
294 return 1; | |
295 } | |
296 | |
297 static inline void doHorizDefFilter(uint8_t dst[], int stride, int QP) | |
298 { | |
299 int y; | |
300 for(y=0; y<BLOCK_SIZE; y++) | |
301 { | |
302 const int middleEnergy= 5*(dst[4] - dst[5]) + 2*(dst[2] - dst[5]); | |
303 | |
304 if(ABS(middleEnergy) < 8*QP) | |
305 { | |
306 const int q=(dst[3] - dst[4])/2; | |
307 const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]); | |
308 const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]); | |
309 | |
310 int d= ABS(middleEnergy) - MIN( ABS(leftEnergy), ABS(rightEnergy) ); | |
311 d= MAX(d, 0); | |
312 | |
313 d= (5*d + 32) >> 6; | |
314 d*= SIGN(-middleEnergy); | |
315 | |
316 if(q>0) | |
317 { | |
318 d= d<0 ? 0 : d; | |
319 d= d>q ? q : d; | |
320 } | |
321 else | |
322 { | |
323 d= d>0 ? 0 : d; | |
324 d= d<q ? q : d; | |
325 } | |
326 | |
327 dst[3]-= d; | |
328 dst[4]+= d; | |
329 } | |
330 dst+= stride; | |
331 } | |
332 } | |
333 | |
334 /** | |
335 * Do a horizontal low pass filter on the 10x8 block (dst points to middle 8x8 Block) | |
336 * using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16 (C version) | |
337 */ | |
338 static inline void doHorizLowPass(uint8_t dst[], int stride, int QP) | |
339 { | |
340 | |
341 int y; | |
342 for(y=0; y<BLOCK_SIZE; y++) | |
343 { | |
344 const int first= ABS(dst[-1] - dst[0]) < QP ? dst[-1] : dst[0]; | |
345 const int last= ABS(dst[8] - dst[7]) < QP ? dst[8] : dst[7]; | |
346 | |
347 int sums[9]; | |
348 sums[0] = first + dst[0]; | |
349 sums[1] = dst[0] + dst[1]; | |
350 sums[2] = dst[1] + dst[2]; | |
351 sums[3] = dst[2] + dst[3]; | |
352 sums[4] = dst[3] + dst[4]; | |
353 sums[5] = dst[4] + dst[5]; | |
354 sums[6] = dst[5] + dst[6]; | |
355 sums[7] = dst[6] + dst[7]; | |
356 sums[8] = dst[7] + last; | |
357 | |
358 dst[0]= ((sums[0]<<2) + ((first + sums[2])<<1) + sums[4] + 8)>>4; | |
359 dst[1]= ((dst[1]<<2) + ((first + sums[0] + sums[3])<<1) + sums[5] + 8)>>4; | |
360 dst[2]= ((dst[2]<<2) + ((first + sums[1] + sums[4])<<1) + sums[6] + 8)>>4; | |
361 dst[3]= ((dst[3]<<2) + ((sums[2] + sums[5])<<1) + sums[0] + sums[7] + 8)>>4; | |
362 dst[4]= ((dst[4]<<2) + ((sums[3] + sums[6])<<1) + sums[1] + sums[8] + 8)>>4; | |
363 dst[5]= ((dst[5]<<2) + ((last + sums[7] + sums[4])<<1) + sums[2] + 8)>>4; | |
364 dst[6]= (((last + dst[6])<<2) + ((dst[7] + sums[5])<<1) + sums[3] + 8)>>4; | |
365 dst[7]= ((sums[8]<<2) + ((last + sums[6])<<1) + sums[4] + 8)>>4; | |
366 | |
367 dst+= stride; | |
368 } | |
369 } | |
370 | |
169 | 371 /** |
372 * Experimental Filter 1 (Horizontal) | |
373 * will not damage linear gradients | |
374 * Flat blocks should look like they where passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter | |
375 * can only smooth blocks at the expected locations (it cant smooth them if they did move) | |
376 * MMX2 version does correct clipping C version doesnt | |
377 * not identical with the vertical one | |
378 */ | |
379 static inline void horizX1Filter(uint8_t *src, int stride, int QP) | |
95
8bce253b537c
new postprocess code by Michael Niedermayer (michaelni@gmx.at)
arpi
parents:
diff
changeset
|
380 { |
169 | 381 int y; |
382 static uint64_t *lut= NULL; | |
383 if(lut==NULL) | |
384 { | |
385 int i; | |
386 lut= (uint64_t*)memalign(8, 256*8); | |
387 for(i=0; i<256; i++) | |
388 { | |
389 int v= i < 128 ? 2*i : 2*(i-256); | |
390 /* | |
391 //Simulate 112242211 9-Tap filter | |
392 uint64_t a= (v/16) & 0xFF; | |
393 uint64_t b= (v/8) & 0xFF; | |
394 uint64_t c= (v/4) & 0xFF; | |
395 uint64_t d= (3*v/8) & 0xFF; | |
396 */ | |
397 //Simulate piecewise linear interpolation | |
398 uint64_t a= (v/16) & 0xFF; | |
399 uint64_t b= (v*3/16) & 0xFF; | |
400 uint64_t c= (v*5/16) & 0xFF; | |
401 uint64_t d= (7*v/16) & 0xFF; | |
402 uint64_t A= (0x100 - a)&0xFF; | |
403 uint64_t B= (0x100 - b)&0xFF; | |
404 uint64_t C= (0x100 - c)&0xFF; | |
405 uint64_t D= (0x100 - c)&0xFF; | |
130 | 406 |
169 | 407 lut[i] = (a<<56) | (b<<48) | (c<<40) | (d<<32) | |
408 (D<<24) | (C<<16) | (B<<8) | (A); | |
409 //lut[i] = (v<<32) | (v<<24); | |
134 | 410 } |
411 } | |
412 | |
169 | 413 for(y=0; y<BLOCK_SIZE; y++) |
134 | 414 { |
169 | 415 int a= src[1] - src[2]; |
416 int b= src[3] - src[4]; | |
417 int c= src[5] - src[6]; | |
134 | 418 |
169 | 419 int d= MAX(ABS(b) - (ABS(a) + ABS(c))/2, 0); |
167 | 420 |
169 | 421 if(d < QP) |
167 | 422 { |
169 | 423 int v = d * SIGN(-b); |
106
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
424 |
169 | 425 src[1] +=v/8; |
426 src[2] +=v/4; | |
427 src[3] +=3*v/8; | |
428 src[4] -=3*v/8; | |
429 src[5] -=v/4; | |
430 src[6] -=v/8; | |
106
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
431 |
169 | 432 } |
433 src+=stride; | |
106
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
434 } |
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
435 } |
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
436 |
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
437 |
171 | 438 //Note: we have C, MMX, MMX2, 3DNOW version there is no 3DNOW+MMX2 one |
169 | 439 //Plain C versions |
171 | 440 #if !defined (HAVE_MMX) || defined (RUNTIME_CPUDETECT) |
441 #define COMPILE_C | |
442 #endif | |
443 | |
787 | 444 #ifdef ARCH_X86 |
171 | 445 |
446 #if (defined (HAVE_MMX) && !defined (HAVE_3DNOW) && !defined (HAVE_MMX2)) || defined (RUNTIME_CPUDETECT) | |
447 #define COMPILE_MMX | |
448 #endif | |
449 | |
450 #if defined (HAVE_MMX2) || defined (RUNTIME_CPUDETECT) | |
451 #define COMPILE_MMX2 | |
452 #endif | |
453 | |
454 #if (defined (HAVE_3DNOW) && !defined (HAVE_MMX2)) || defined (RUNTIME_CPUDETECT) | |
455 #define COMPILE_3DNOW | |
456 #endif | |
787 | 457 #endif //ARCH_X86 |
171 | 458 |
459 #undef HAVE_MMX | |
460 #undef HAVE_MMX2 | |
461 #undef HAVE_3DNOW | |
462 #undef ARCH_X86 | |
463 | |
464 #ifdef COMPILE_C | |
169 | 465 #undef HAVE_MMX |
466 #undef HAVE_MMX2 | |
467 #undef HAVE_3DNOW | |
468 #undef ARCH_X86 | |
469 #define RENAME(a) a ## _C | |
470 #include "postprocess_template.c" | |
171 | 471 #endif |
106
389391a6d0bf
rewrote the horizontal lowpass filter to fix a bug which caused a blocky look
michael
parents:
105
diff
changeset
|
472 |
169 | 473 //MMX versions |
171 | 474 #ifdef COMPILE_MMX |
169 | 475 #undef RENAME |
476 #define HAVE_MMX | |
477 #undef HAVE_MMX2 | |
478 #undef HAVE_3DNOW | |
479 #define ARCH_X86 | |
480 #define RENAME(a) a ## _MMX | |
481 #include "postprocess_template.c" | |
171 | 482 #endif |
128
e5266b8e79be
much better horizontal filters (transpose & use the vertical ones) :)
michael
parents:
126
diff
changeset
|
483 |
169 | 484 //MMX2 versions |
171 | 485 #ifdef COMPILE_MMX2 |
169 | 486 #undef RENAME |
487 #define HAVE_MMX | |
488 #define HAVE_MMX2 | |
489 #undef HAVE_3DNOW | |
490 #define ARCH_X86 | |
491 #define RENAME(a) a ## _MMX2 | |
492 #include "postprocess_template.c" | |
171 | 493 #endif |
128
e5266b8e79be
much better horizontal filters (transpose & use the vertical ones) :)
michael
parents:
126
diff
changeset
|
494 |
169 | 495 //3DNOW versions |
171 | 496 #ifdef COMPILE_3DNOW |
169 | 497 #undef RENAME |
498 #define HAVE_MMX | |
499 #undef HAVE_MMX2 | |
500 #define HAVE_3DNOW | |
501 #define ARCH_X86 | |
502 #define RENAME(a) a ## _3DNow | |
503 #include "postprocess_template.c" | |
171 | 504 #endif |
128
e5266b8e79be
much better horizontal filters (transpose & use the vertical ones) :)
michael
parents:
126
diff
changeset
|
505 |
169 | 506 // minor note: the HAVE_xyz is messed up after that line so dont use it |
128
e5266b8e79be
much better horizontal filters (transpose & use the vertical ones) :)
michael
parents:
126
diff
changeset
|
507 |
169 | 508 static inline void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, |
787 | 509 QP_STORE_T QPs[], int QPStride, int isColor, PPMode *ppMode, void *vc) |
156 | 510 { |
787 | 511 PPContext *c= (PPContext *)vc; |
512 c->ppMode= *ppMode; //FIXME | |
513 | |
169 | 514 // useing ifs here as they are faster than function pointers allthough the |
515 // difference wouldnt be messureable here but its much better because | |
516 // someone might exchange the cpu whithout restarting mplayer ;) | |
171 | 517 #ifdef RUNTIME_CPUDETECT |
787 | 518 #ifdef ARCH_X86 |
169 | 519 // ordered per speed fasterst first |
520 if(gCpuCaps.hasMMX2) | |
787 | 521 postProcess_MMX2(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
169 | 522 else if(gCpuCaps.has3DNow) |
787 | 523 postProcess_3DNow(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
169 | 524 else if(gCpuCaps.hasMMX) |
787 | 525 postProcess_MMX(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
169 | 526 else |
787 | 527 postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
157
bc12fd7e6153
temp denoiser changes: (a-b)^2 instead of |a-b| and MMX2/3DNOW version
michael
parents:
156
diff
changeset
|
528 #else |
787 | 529 postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
157
bc12fd7e6153
temp denoiser changes: (a-b)^2 instead of |a-b| and MMX2/3DNOW version
michael
parents:
156
diff
changeset
|
530 #endif |
171 | 531 #else //RUNTIME_CPUDETECT |
532 #ifdef HAVE_MMX2 | |
787 | 533 postProcess_MMX2(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
171 | 534 #elif defined (HAVE_3DNOW) |
787 | 535 postProcess_3DNow(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
171 | 536 #elif defined (HAVE_MMX) |
787 | 537 postProcess_MMX(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
171 | 538 #else |
787 | 539 postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); |
171 | 540 #endif |
541 #endif //!RUNTIME_CPUDETECT | |
156 | 542 } |
543 | |
169 | 544 //static void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, |
545 // QP_STORE_T QPs[], int QPStride, int isColor, struct PPMode *ppMode); | |
96 | 546 |
116 | 547 /* -pp Command line Help |
548 */ | |
787 | 549 char *postproc_help= |
184 | 550 "-npp <filterName>[:<option>[:<option>...]][,[-]<filterName>[:<option>...]]...\n" |
551 "long form example:\n" | |
552 "-npp vdeblock:autoq,hdeblock:autoq,linblenddeint -npp default,-vdeblock\n" | |
553 "short form example:\n" | |
554 "-npp vb:a,hb:a,lb -npp de,-vb\n" | |
555 "more examples:\n" | |
556 "-npp tn:64:128:256\n" | |
557 "Filters Options\n" | |
558 "short long name short long option Description\n" | |
559 "* * a autoq cpu power dependant enabler\n" | |
560 " c chrom chrominance filtring enabled\n" | |
561 " y nochrom chrominance filtring disabled\n" | |
562 "hb hdeblock (2 Threshold) horizontal deblocking filter\n" | |
563 " 1. Threshold: default=1, higher -> more deblocking\n" | |
564 " 2. Threshold: default=40, lower -> more deblocking\n" | |
565 " the h & v deblocking filters share these\n" | |
566 " so u cant set different thresholds for h / v\n" | |
567 "vb vdeblock (2 Threshold) vertical deblocking filter\n" | |
568 "h1 x1hdeblock Experimental h deblock filter 1\n" | |
569 "v1 x1vdeblock Experimental v deblock filter 1\n" | |
570 "dr dering Deringing filter\n" | |
571 "al autolevels automatic brightness / contrast\n" | |
572 " f fullyrange stretch luminance to (0..255)\n" | |
573 "lb linblenddeint linear blend deinterlacer\n" | |
574 "li linipoldeint linear interpolating deinterlace\n" | |
575 "ci cubicipoldeint cubic interpolating deinterlacer\n" | |
576 "md mediandeint median deinterlacer\n" | |
787 | 577 "fd ffmpegdeint ffmpeg deinterlacer\n" |
184 | 578 "de default hb:a,vb:a,dr:a,al\n" |
579 "fa fast h1:a,v1:a,dr:a,al\n" | |
580 "tn tmpnoise (3 Thresholds) Temporal Noise Reducer\n" | |
581 " 1. <= 2. <= 3. larger -> stronger filtering\n" | |
582 "fq forceQuant <quantizer> Force quantizer\n" | |
583 ; | |
116 | 584 |
585 /** | |
586 * returns a PPMode struct which will have a non 0 error variable if an error occured | |
587 * name is the string after "-pp" on the command line | |
588 * quality is a number from 0 to GET_PP_QUALITY_MAX | |
589 */ | |
590 struct PPMode getPPModeByNameAndQuality(char *name, int quality) | |
591 { | |
592 char temp[GET_MODE_BUFFER_SIZE]; | |
593 char *p= temp; | |
787 | 594 char *filterDelimiters= ",/"; |
116 | 595 char *optionDelimiters= ":"; |
787 | 596 struct PPMode ppMode= {0,0,0,0,0,{150,200,400}}; |
116 | 597 char *filterToken; |
598 | |
787 | 599 ppMode.flatnessThreshold= 56-16; |
600 | |
116 | 601 strncpy(temp, name, GET_MODE_BUFFER_SIZE); |
602 | |
202 | 603 if(verbose>1) printf("pp: %s\n", name); |
156 | 604 |
116 | 605 for(;;){ |
606 char *filterName; | |
156 | 607 int q= 1000000; //GET_PP_QUALITY_MAX; |
116 | 608 int chrom=-1; |
609 char *option; | |
610 char *options[OPTIONS_ARRAY_SIZE]; | |
611 int i; | |
612 int filterNameOk=0; | |
613 int numOfUnknownOptions=0; | |
614 int enable=1; //does the user want us to enabled or disabled the filter | |
615 | |
616 filterToken= strtok(p, filterDelimiters); | |
617 if(filterToken == NULL) break; | |
156 | 618 p+= strlen(filterToken) + 1; // p points to next filterToken |
116 | 619 filterName= strtok(filterToken, optionDelimiters); |
202 | 620 if(verbose>1) printf("pp: %s::%s\n", filterToken, filterName); |
116 | 621 |
622 if(*filterName == '-') | |
623 { | |
624 enable=0; | |
625 filterName++; | |
626 } | |
156 | 627 |
116 | 628 for(;;){ //for all options |
629 option= strtok(NULL, optionDelimiters); | |
630 if(option == NULL) break; | |
631 | |
202 | 632 if(verbose>1) printf("pp: option: %s\n", option); |
116 | 633 if(!strcmp("autoq", option) || !strcmp("a", option)) q= quality; |
634 else if(!strcmp("nochrom", option) || !strcmp("y", option)) chrom=0; | |
635 else if(!strcmp("chrom", option) || !strcmp("c", option)) chrom=1; | |
636 else | |
637 { | |
638 options[numOfUnknownOptions] = option; | |
639 numOfUnknownOptions++; | |
640 } | |
641 if(numOfUnknownOptions >= OPTIONS_ARRAY_SIZE-1) break; | |
642 } | |
156 | 643 options[numOfUnknownOptions] = NULL; |
116 | 644 |
645 /* replace stuff from the replace Table */ | |
646 for(i=0; replaceTable[2*i]!=NULL; i++) | |
647 { | |
648 if(!strcmp(replaceTable[2*i], filterName)) | |
649 { | |
650 int newlen= strlen(replaceTable[2*i + 1]); | |
651 int plen; | |
652 int spaceLeft; | |
653 | |
654 if(p==NULL) p= temp, *p=0; //last filter | |
655 else p--, *p=','; //not last filter | |
656 | |
657 plen= strlen(p); | |
419
b71190bacce8
applied 64bit patch from Ulrich Hecht <uli at suse dot de>
alex
parents:
212
diff
changeset
|
658 spaceLeft= p - temp + plen; |
116 | 659 if(spaceLeft + newlen >= GET_MODE_BUFFER_SIZE) |
660 { | |
661 ppMode.error++; | |
662 break; | |
663 } | |
664 memmove(p + newlen, p, plen+1); | |
665 memcpy(p, replaceTable[2*i + 1], newlen); | |
666 filterNameOk=1; | |
667 } | |
668 } | |
669 | |
670 for(i=0; filters[i].shortName!=NULL; i++) | |
671 { | |
156 | 672 // printf("Compareing %s, %s, %s\n", filters[i].shortName,filters[i].longName, filterName); |
116 | 673 if( !strcmp(filters[i].longName, filterName) |
674 || !strcmp(filters[i].shortName, filterName)) | |
675 { | |
676 ppMode.lumMode &= ~filters[i].mask; | |
677 ppMode.chromMode &= ~filters[i].mask; | |
678 | |
679 filterNameOk=1; | |
680 if(!enable) break; // user wants to disable it | |
681 | |
682 if(q >= filters[i].minLumQuality) | |
683 ppMode.lumMode|= filters[i].mask; | |
684 if(chrom==1 || (chrom==-1 && filters[i].chromDefault)) | |
685 if(q >= filters[i].minChromQuality) | |
686 ppMode.chromMode|= filters[i].mask; | |
687 | |
688 if(filters[i].mask == LEVEL_FIX) | |
689 { | |
690 int o; | |
691 ppMode.minAllowedY= 16; | |
692 ppMode.maxAllowedY= 234; | |
693 for(o=0; options[o]!=NULL; o++) | |
182
3ccd74a91074
minor brightness/contrast bugfix / moved some global vars into ppMode
michael
parents:
181
diff
changeset
|
694 { |
116 | 695 if( !strcmp(options[o],"fullyrange") |
696 ||!strcmp(options[o],"f")) | |
697 { | |
698 ppMode.minAllowedY= 0; | |
699 ppMode.maxAllowedY= 255; | |
700 numOfUnknownOptions--; | |
701 } | |
182
3ccd74a91074
minor brightness/contrast bugfix / moved some global vars into ppMode
michael
parents:
181
diff
changeset
|
702 } |
116 | 703 } |
156 | 704 else if(filters[i].mask == TEMP_NOISE_FILTER) |
705 { | |
706 int o; | |
707 int numOfNoises=0; | |
708 ppMode.maxTmpNoise[0]= 150; | |
709 ppMode.maxTmpNoise[1]= 200; | |
710 ppMode.maxTmpNoise[2]= 400; | |
711 | |
712 for(o=0; options[o]!=NULL; o++) | |
713 { | |
714 char *tail; | |
715 ppMode.maxTmpNoise[numOfNoises]= | |
716 strtol(options[o], &tail, 0); | |
717 if(tail!=options[o]) | |
718 { | |
719 numOfNoises++; | |
720 numOfUnknownOptions--; | |
721 if(numOfNoises >= 3) break; | |
722 } | |
723 } | |
724 } | |
181 | 725 else if(filters[i].mask == V_DEBLOCK || filters[i].mask == H_DEBLOCK) |
726 { | |
727 int o; | |
182
3ccd74a91074
minor brightness/contrast bugfix / moved some global vars into ppMode
michael
parents:
181
diff
changeset
|
728 ppMode.maxDcDiff=1; |
3ccd74a91074
minor brightness/contrast bugfix / moved some global vars into ppMode
michael
parents:
181
diff
changeset
|
729 // hFlatnessThreshold= 40; |
3ccd74a91074
minor brightness/contrast bugfix / moved some global vars into ppMode
michael
parents:
181
diff
changeset
|
730 // vFlatnessThreshold= 40; |
181 | 731 |
732 for(o=0; options[o]!=NULL && o<2; o++) | |
733 { | |
734 char *tail; | |
735 int val= strtol(options[o], &tail, 0); | |
736 if(tail==options[o]) break; | |
737 | |
738 numOfUnknownOptions--; | |
182
3ccd74a91074
minor brightness/contrast bugfix / moved some global vars into ppMode
michael
parents:
181
diff
changeset
|
739 if(o==0) ppMode.maxDcDiff= val; |
787 | 740 else ppMode.flatnessThreshold= val; |
181 | 741 } |
742 } | |
183 | 743 else if(filters[i].mask == FORCE_QUANT) |
744 { | |
745 int o; | |
746 ppMode.forcedQuant= 15; | |
747 | |
748 for(o=0; options[o]!=NULL && o<1; o++) | |
749 { | |
750 char *tail; | |
751 int val= strtol(options[o], &tail, 0); | |
752 if(tail==options[o]) break; | |
753 | |
754 numOfUnknownOptions--; | |
755 ppMode.forcedQuant= val; | |
756 } | |
757 } | |
116 | 758 } |
759 } | |
760 if(!filterNameOk) ppMode.error++; | |
761 ppMode.error += numOfUnknownOptions; | |
762 } | |
763 | |
202 | 764 if(verbose>1) printf("pp: lumMode=%X, chromMode=%X\n", ppMode.lumMode, ppMode.chromMode); |
116 | 765 return ppMode; |
766 } | |
767 | |
787 | 768 void *getPPContext(int width, int height){ |
769 PPContext *c= memalign(32, sizeof(PPContext)); | |
770 int i; | |
771 | |
772 c->tempBlocks= (uint8_t*)memalign(8, 2*16*8); | |
773 c->yHistogram= (uint64_t*)memalign(8, 256*sizeof(uint64_t)); | |
774 for(i=0; i<256; i++) | |
775 c->yHistogram[i]= width*height/64*15/256; | |
776 | |
777 for(i=0; i<3; i++) | |
185 | 778 { |
787 | 779 //Note:the +17*1024 is just there so i dont have to worry about r/w over te end |
780 c->tempBlured[i]= (uint8_t*)memalign(8, ((width+7)&(~7))*2*((height+7)&(~7)) + 17*1024); //FIXME dstStride instead of width | |
781 c->tempBluredPast[i]= (uint32_t*)memalign(8, 256*((height+7)&(~7))/2 + 17*1024); | |
782 | |
783 memset(c->tempBlured[i], 0, ((width+7)&(~7))*2*((height+7)&(~7)) + 17*1024); | |
784 memset(c->tempBluredPast[i], 0, 256*((height+7)&(~7))/2 + 17*1024); | |
185 | 785 } |
786 | |
787 | 787 c->tempDst= (uint8_t*)memalign(8, 1024*24); |
788 c->tempSrc= (uint8_t*)memalign(8, 1024*24); | |
789 c->tempDstBlock= (uint8_t*)memalign(8, 1024*24); | |
790 c->tempSrcBlock= (uint8_t*)memalign(8, 1024*24); | |
791 c->deintTemp= (uint8_t*)memalign(8, width+16); | |
179 | 792 |
787 | 793 c->frameNum=-1; |
179 | 794 |
787 | 795 return c; |
179 | 796 } |
797 | |
787 | 798 void freePPContext(void *vc){ |
799 PPContext *c = (PPContext*)vc; | |
800 int i; | |
801 | |
802 for(i=0; i<3; i++) free(c->tempBlured[i]); | |
803 for(i=0; i<3; i++) free(c->tempBluredPast[i]); | |
804 | |
805 free(c->tempBlocks); | |
806 free(c->yHistogram); | |
807 free(c->tempDst); | |
808 free(c->tempSrc); | |
809 free(c->tempDstBlock); | |
810 free(c->tempSrcBlock); | |
811 free(c->deintTemp); | |
812 | |
813 free(c); | |
814 } | |
815 | |
816 //FIXME move this shit away from here | |
212 | 817 int readPPOpt(void *conf, char *arg) |
818 { | |
819 int val; | |
820 | |
821 if(arg == NULL) | |
822 return -2; // ERR_MISSING_PARAM | |
823 errno = 0; | |
824 val = (int)strtol(arg,NULL,0); | |
825 if(errno != 0) | |
826 return -4; // What about include cfgparser.h and use ERR_* defines */ | |
827 if(val < 0) | |
828 return -3; // ERR_OUT_OF_RANGE | |
829 | |
830 divx_quality = val; | |
787 | 831 firstTime2 = 1; |
212 | 832 |
833 return 1; | |
834 } | |
835 | |
836 void revertPPOpt(void *conf, char* opt) | |
837 { | |
838 divx_quality=0; | |
839 } | |
840 | |
841 | |
787 | 842 void postprocess(uint8_t * src[3], int srcStride[3], |
843 uint8_t * dst[3], int dstStride[3], | |
844 int horizontalSize, int verticalSize, | |
845 QP_STORE_T *QP_store, int QPStride, | |
846 PPMode *mode, void *c) | |
116 | 847 { |
848 | |
183 | 849 QP_STORE_T quantArray[2048/8]; |
787 | 850 |
183 | 851 if(QP_store==NULL || (mode->lumMode & FORCE_QUANT)) |
152 | 852 { |
183 | 853 int i; |
854 QP_store= quantArray; | |
787 | 855 QPStride= 0; |
183 | 856 if(mode->lumMode & FORCE_QUANT) |
857 for(i=0; i<2048/8; i++) quantArray[i]= mode->forcedQuant; | |
858 else | |
859 for(i=0; i<2048/8; i++) quantArray[i]= 1; | |
152 | 860 } |
861 | |
212 | 862 if(firstTime2 && verbose) |
202 | 863 { |
864 printf("using npp filters 0x%X/0x%X\n", mode->lumMode, mode->chromMode); | |
212 | 865 firstTime2=0; |
202 | 866 } |
867 | |
787 | 868 postProcess(src[0], srcStride[0], dst[0], dstStride[0], |
869 horizontalSize, verticalSize, QP_store, QPStride, 0, mode, c); | |
116 | 870 |
787 | 871 horizontalSize = (horizontalSize+1)>> 1; |
872 verticalSize = (verticalSize+1)>>1; | |
116 | 873 |
168
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
874 if(mode->chromMode) |
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
875 { |
787 | 876 postProcess(src[1], srcStride[1], dst[1], dstStride[1], |
877 horizontalSize, verticalSize, QP_store, QPStride, 1, mode, c); | |
878 postProcess(src[2], srcStride[2], dst[2], dstStride[2], | |
879 horizontalSize, verticalSize, QP_store, QPStride, 2, mode, c); | |
168
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
880 } |
787 | 881 else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]) |
168
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
882 { |
787 | 883 memcpy(dst[1], src[1], srcStride[1]*verticalSize); |
884 memcpy(dst[2], src[2], srcStride[2]*verticalSize); | |
168
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
885 } |
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
886 else |
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
887 { |
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
888 int y; |
787 | 889 for(y=0; y<verticalSize; y++) |
168
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
890 { |
787 | 891 memcpy(&(dst[1][y*dstStride[1]]), &(src[1][y*srcStride[1]]), horizontalSize); |
892 memcpy(&(dst[2][y*dstStride[2]]), &(src[2][y*srcStride[2]]), horizontalSize); | |
168
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
893 } |
712c7a115164
use fastmemcpy for chrominance if no chrominance filtering is done
michael
parents:
167
diff
changeset
|
894 } |
116 | 895 } |
896 |