Mercurial > libavcodec.hg
comparison libpostproc/postprocess_template.c @ 116:1895a8fa81ea libavcodec
auto brightness/ contrast bugfix
getPPModeByNameAndQuality
author | michael |
---|---|
date | Mon, 22 Oct 2001 23:36:35 +0000 |
parents | 4514b8e7f0f1 |
children | a02f3088b0cf |
comparison
equal
deleted
inserted
replaced
115:4514b8e7f0f1 | 116:1895a8fa81ea |
---|---|
69 //Changelog: use the CVS log | 69 //Changelog: use the CVS log |
70 | 70 |
71 #include <inttypes.h> | 71 #include <inttypes.h> |
72 #include <stdio.h> | 72 #include <stdio.h> |
73 #include <stdlib.h> | 73 #include <stdlib.h> |
74 #include <string.h> | |
74 #include "../config.h" | 75 #include "../config.h" |
75 //#undef HAVE_MMX2 | 76 //#undef HAVE_MMX2 |
76 //#define HAVE_3DNOW | 77 //#define HAVE_3DNOW |
77 //#undef HAVE_MMX | 78 //#undef HAVE_MMX |
78 #include "postprocess.h" | 79 #include "postprocess.h" |
85 #ifdef HAVE_MMX2 | 86 #ifdef HAVE_MMX2 |
86 #define PAVGB(a,b) "pavgb " #a ", " #b " \n\t" | 87 #define PAVGB(a,b) "pavgb " #a ", " #b " \n\t" |
87 #elif defined (HAVE_3DNOW) | 88 #elif defined (HAVE_3DNOW) |
88 #define PAVGB(a,b) "pavgusb " #a ", " #b " \n\t" | 89 #define PAVGB(a,b) "pavgusb " #a ", " #b " \n\t" |
89 #endif | 90 #endif |
91 | |
92 #define GET_MODE_BUFFER_SIZE 500 | |
93 #define OPTIONS_ARRAY_SIZE 10 | |
94 | |
90 | 95 |
91 static uint64_t packedYOffset= 0x0000000000000000LL; | 96 static uint64_t packedYOffset= 0x0000000000000000LL; |
92 static uint64_t packedYScale= 0x0100010001000100LL; | 97 static uint64_t packedYScale= 0x0100010001000100LL; |
93 static uint64_t w05= 0x0005000500050005LL; | 98 static uint64_t w05= 0x0005000500050005LL; |
94 static uint64_t w20= 0x0020002000200020LL; | 99 static uint64_t w20= 0x0020002000200020LL; |
128 int vFlatnessThreshold= 56 - 16; | 133 int vFlatnessThreshold= 56 - 16; |
129 | 134 |
130 //amount of "black" u r willing to loose to get a brightness corrected picture | 135 //amount of "black" u r willing to loose to get a brightness corrected picture |
131 double maxClippedThreshold= 0.01; | 136 double maxClippedThreshold= 0.01; |
132 | 137 |
133 int maxAllowedY=255; | 138 int maxAllowedY=234; |
134 //FIXME can never make a movie´s black brighter (anyone needs that?) | 139 //FIXME can never make a movie´s black brighter (anyone needs that?) |
135 int minAllowedY=16; | 140 int minAllowedY=16; |
141 | |
142 static struct PPFilter filters[]= | |
143 { | |
144 {"hb", "hdeblock", 1, 1, 3, H_DEBLOCK}, | |
145 {"vb", "vdeblock", 1, 2, 4, V_DEBLOCK}, | |
146 {"vr", "rkvdeblock", 1, 2, 4, H_RK1_FILTER}, | |
147 {"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER}, | |
148 {"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER}, | |
149 {"dr", "dering", 1, 5, 6, DERING}, | |
150 {"al", "autolevels", 0, 1, 2, LEVEL_FIX}, | |
151 {"lb", "linblenddeint", 0, 1, 6, LINEAR_BLEND_DEINT_FILTER}, | |
152 {"li", "linipoldeint", 0, 1, 6, LINEAR_IPOL_DEINT_FILTER}, | |
153 {"ci", "cubicipoldeint", 0, 1, 6, CUBIC_IPOL_DEINT_FILTER}, | |
154 {"md", "mediandeint", 0, 1, 6, MEDIAN_DEINT_FILTER}, | |
155 {NULL, NULL,0,0,0,0} //End Marker | |
156 }; | |
157 | |
158 static char *replaceTable[]= | |
159 { | |
160 "default", "hdeblock:a,vdeblock:a,dering:a,autolevels", | |
161 "de", "hdeblock:a,vdeblock:a,dering:a,autolevels", | |
162 "fast", "x1hdeblock:a,x1vdeblock:a,dering:a,autolevels", | |
163 "fa", "x1hdeblock:a,x1vdeblock:a,dering:a,autolevels", | |
164 NULL //End Marker | |
165 }; | |
136 | 166 |
137 #ifdef TIMING | 167 #ifdef TIMING |
138 static inline long long rdtsc() | 168 static inline long long rdtsc() |
139 { | 169 { |
140 long long l; | 170 long long l; |
2161 #endif | 2191 #endif |
2162 | 2192 |
2163 static void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, | 2193 static void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, |
2164 QP_STORE_T QPs[], int QPStride, int isColor, int mode); | 2194 QP_STORE_T QPs[], int QPStride, int isColor, int mode); |
2165 | 2195 |
2196 /* -pp Command line Help | |
2197 NOTE/FIXME: put this at an appropriate place (--help, html docs, man mplayer)? | |
2198 | |
2199 -pp <filterName>[:<option>[:<option>...]][,[-]<filterName>[:<option>...]]... | |
2200 | |
2201 long form example: | |
2202 -pp vdeblock:autoq,hdeblock:autoq,linblenddeint -pp default,-vdeblock | |
2203 short form example: | |
2204 -pp vb:a,hb:a,lb -pp de,-vb | |
2205 | |
2206 Filters Options | |
2207 short long name short long option Description | |
2208 * * a autoq cpu power dependant enabler | |
2209 c chrom chrominance filtring enabled | |
2210 y nochrom chrominance filtring disabled | |
2211 hb hdeblock horizontal deblocking filter | |
2212 vb vdeblock vertical deblocking filter | |
2213 vr rkvdeblock | |
2214 h1 x1hdeblock Experimental horizontal deblock filter 1 | |
2215 v1 x1vdeblock Experimental vertical deblock filter 1 | |
2216 dr dering not implemented yet | |
2217 al autolevels automatic brightness / contrast fixer | |
2218 f fullyrange stretch luminance range to (0..255) | |
2219 lb linblenddeint linear blend deinterlacer | |
2220 li linipoldeint linear interpolating deinterlacer | |
2221 ci cubicipoldeint cubic interpolating deinterlacer | |
2222 md mediandeint median deinterlacer | |
2223 de default hdeblock:a,vdeblock:a,dering:a,autolevels | |
2224 fa fast x1hdeblock:a,x1vdeblock:a,dering:a,autolevels | |
2225 */ | |
2226 | |
2227 /** | |
2228 * returns a PPMode struct which will have a non 0 error variable if an error occured | |
2229 * name is the string after "-pp" on the command line | |
2230 * quality is a number from 0 to GET_PP_QUALITY_MAX | |
2231 */ | |
2232 struct PPMode getPPModeByNameAndQuality(char *name, int quality) | |
2233 { | |
2234 char temp[GET_MODE_BUFFER_SIZE]; | |
2235 char *p= temp; | |
2236 char *filterDelimiters= ","; | |
2237 char *optionDelimiters= ":"; | |
2238 struct PPMode ppMode= {0,0,0,0,0,0}; | |
2239 char *filterToken; | |
2240 | |
2241 strncpy(temp, name, GET_MODE_BUFFER_SIZE); | |
2242 | |
2243 for(;;){ | |
2244 char *p2; | |
2245 char *filterName; | |
2246 int q= GET_PP_QUALITY_MAX; | |
2247 int chrom=-1; | |
2248 char *option; | |
2249 char *options[OPTIONS_ARRAY_SIZE]; | |
2250 int i; | |
2251 int filterNameOk=0; | |
2252 int numOfUnknownOptions=0; | |
2253 int enable=1; //does the user want us to enabled or disabled the filter | |
2254 | |
2255 filterToken= strtok(p, filterDelimiters); | |
2256 if(filterToken == NULL) break; | |
2257 p+= strlen(filterToken) + 1; | |
2258 filterName= strtok(filterToken, optionDelimiters); | |
2259 printf("%s::%s\n", filterToken, filterName); | |
2260 | |
2261 if(*filterName == '-') | |
2262 { | |
2263 enable=0; | |
2264 filterName++; | |
2265 } | |
2266 for(;;){ //for all options | |
2267 option= strtok(NULL, optionDelimiters); | |
2268 if(option == NULL) break; | |
2269 | |
2270 printf("%s\n", option); | |
2271 if(!strcmp("autoq", option) || !strcmp("a", option)) q= quality; | |
2272 else if(!strcmp("nochrom", option) || !strcmp("y", option)) chrom=0; | |
2273 else if(!strcmp("chrom", option) || !strcmp("c", option)) chrom=1; | |
2274 else | |
2275 { | |
2276 options[numOfUnknownOptions] = option; | |
2277 numOfUnknownOptions++; | |
2278 options[numOfUnknownOptions] = NULL; | |
2279 } | |
2280 if(numOfUnknownOptions >= OPTIONS_ARRAY_SIZE-1) break; | |
2281 } | |
2282 | |
2283 /* replace stuff from the replace Table */ | |
2284 for(i=0; replaceTable[2*i]!=NULL; i++) | |
2285 { | |
2286 if(!strcmp(replaceTable[2*i], filterName)) | |
2287 { | |
2288 int newlen= strlen(replaceTable[2*i + 1]); | |
2289 int plen; | |
2290 int spaceLeft; | |
2291 | |
2292 if(p==NULL) p= temp, *p=0; //last filter | |
2293 else p--, *p=','; //not last filter | |
2294 | |
2295 plen= strlen(p); | |
2296 spaceLeft= (int)p - (int)temp + plen; | |
2297 if(spaceLeft + newlen >= GET_MODE_BUFFER_SIZE) | |
2298 { | |
2299 ppMode.error++; | |
2300 break; | |
2301 } | |
2302 memmove(p + newlen, p, plen+1); | |
2303 memcpy(p, replaceTable[2*i + 1], newlen); | |
2304 filterNameOk=1; | |
2305 } | |
2306 } | |
2307 | |
2308 for(i=0; filters[i].shortName!=NULL; i++) | |
2309 { | |
2310 if( !strcmp(filters[i].longName, filterName) | |
2311 || !strcmp(filters[i].shortName, filterName)) | |
2312 { | |
2313 ppMode.lumMode &= ~filters[i].mask; | |
2314 ppMode.chromMode &= ~filters[i].mask; | |
2315 | |
2316 filterNameOk=1; | |
2317 if(!enable) break; // user wants to disable it | |
2318 | |
2319 if(q >= filters[i].minLumQuality) | |
2320 ppMode.lumMode|= filters[i].mask; | |
2321 if(chrom==1 || (chrom==-1 && filters[i].chromDefault)) | |
2322 if(q >= filters[i].minChromQuality) | |
2323 ppMode.chromMode|= filters[i].mask; | |
2324 | |
2325 if(filters[i].mask == LEVEL_FIX) | |
2326 { | |
2327 int o; | |
2328 ppMode.minAllowedY= 16; | |
2329 ppMode.maxAllowedY= 234; | |
2330 for(o=0; options[o]!=NULL; o++) | |
2331 if( !strcmp(options[o],"fullyrange") | |
2332 ||!strcmp(options[o],"f")) | |
2333 { | |
2334 ppMode.minAllowedY= 0; | |
2335 ppMode.maxAllowedY= 255; | |
2336 numOfUnknownOptions--; | |
2337 } | |
2338 } | |
2339 } | |
2340 } | |
2341 if(!filterNameOk) ppMode.error++; | |
2342 ppMode.error += numOfUnknownOptions; | |
2343 } | |
2344 | |
2345 if(ppMode.lumMode & H_DEBLOCK) ppMode.oldMode |= PP_DEBLOCK_Y_H; | |
2346 if(ppMode.lumMode & V_DEBLOCK) ppMode.oldMode |= PP_DEBLOCK_Y_V; | |
2347 if(ppMode.chromMode & H_DEBLOCK) ppMode.oldMode |= PP_DEBLOCK_C_H; | |
2348 if(ppMode.chromMode & V_DEBLOCK) ppMode.oldMode |= PP_DEBLOCK_C_V; | |
2349 if(ppMode.lumMode & DERING) ppMode.oldMode |= PP_DERING_Y; | |
2350 if(ppMode.chromMode & DERING) ppMode.oldMode |= PP_DERING_C; | |
2351 | |
2352 return ppMode; | |
2353 } | |
2354 | |
2166 /** | 2355 /** |
2167 * ... | 2356 * ... |
2168 */ | 2357 */ |
2169 void postprocess(unsigned char * src[], int src_stride, | 2358 void postprocess(unsigned char * src[], int src_stride, |
2170 unsigned char * dst[], int dst_stride, | 2359 unsigned char * dst[], int dst_stride, |
2171 int horizontal_size, int vertical_size, | 2360 int horizontal_size, int vertical_size, |
2172 QP_STORE_T *QP_store, int QP_stride, | 2361 QP_STORE_T *QP_store, int QP_stride, |
2173 int mode) | 2362 int mode) |
2174 { | 2363 { |
2364 /* | |
2365 static int qual=0; | |
2366 | |
2367 struct PPMode ppMode= getPPModeByNameAndQuality("fast,default,-hdeblock,-vdeblock", qual); | |
2368 qual++; | |
2369 qual%=7; | |
2370 printf("\n%d %d %d %d\n", ppMode.lumMode, ppMode.chromMode, ppMode.oldMode, ppMode.error); | |
2371 postprocess2(src, src_stride, dst, dst_stride, | |
2372 horizontal_size, vertical_size, QP_store, QP_stride, &ppMode); | |
2373 | |
2374 return; | |
2375 */ | |
2175 | 2376 |
2176 #ifdef HAVE_ODIVX_POSTPROCESS | 2377 #ifdef HAVE_ODIVX_POSTPROCESS |
2177 // Note: I could make this shit outside of this file, but it would mean one | 2378 // Note: I could make this shit outside of this file, but it would mean one |
2178 // more function call... | 2379 // more function call... |
2179 if(use_old_pp){ | 2380 if(use_old_pp){ |
2180 odivx_postprocess(src,src_stride,dst,dst_stride,horizontal_size,vertical_size,QP_store,QP_stride,mode); | 2381 odivx_postprocess(src,src_stride,dst,dst_stride,horizontal_size,vertical_size,QP_store,QP_stride,mode); |
2181 return; | 2382 return; |
2182 } | 2383 } |
2183 #endif | 2384 #endif |
2184 | 2385 |
2185 /* | |
2186 long long T= rdtsc(); | |
2187 for(int y=vertical_size-1; y>=0 ; y--) | |
2188 memcpy(dst[0] + y*src_stride, src[0] + y*src_stride,src_stride); | |
2189 // memcpy(dst[0], src[0],src_stride*vertical_size); | |
2190 printf("%4dk\r", (rdtsc()-T)/1000); | |
2191 | |
2192 return; | |
2193 */ | |
2194 /* | |
2195 long long T= rdtsc(); | |
2196 while( (rdtsc() - T)/1000 < 4000); | |
2197 | |
2198 return; | |
2199 */ | |
2200 postProcess(src[0], src_stride, dst[0], dst_stride, | 2386 postProcess(src[0], src_stride, dst[0], dst_stride, |
2201 horizontal_size, vertical_size, QP_store, QP_stride, 0, mode); | 2387 horizontal_size, vertical_size, QP_store, QP_stride, 0, mode); |
2202 | 2388 |
2203 horizontal_size >>= 1; | 2389 horizontal_size >>= 1; |
2204 vertical_size >>= 1; | 2390 vertical_size >>= 1; |
2209 if(1) | 2395 if(1) |
2210 { | 2396 { |
2211 postProcess(src[1], src_stride, dst[1], dst_stride, | 2397 postProcess(src[1], src_stride, dst[1], dst_stride, |
2212 horizontal_size, vertical_size, QP_store, QP_stride, 1, mode); | 2398 horizontal_size, vertical_size, QP_store, QP_stride, 1, mode); |
2213 postProcess(src[2], src_stride, dst[2], dst_stride, | 2399 postProcess(src[2], src_stride, dst[2], dst_stride, |
2214 horizontal_size, vertical_size, QP_store, QP_stride, 1, mode); | 2400 horizontal_size, vertical_size, QP_store, QP_stride, 2, mode); |
2215 } | 2401 } |
2216 else | 2402 else |
2217 { | 2403 { |
2218 memcpy(dst[1], src[1], src_stride*horizontal_size); | 2404 memcpy(dst[1], src[1], src_stride*horizontal_size); |
2219 memcpy(dst[2], src[2], src_stride*horizontal_size); | 2405 memcpy(dst[2], src[2], src_stride*horizontal_size); |
2220 } | 2406 } |
2221 } | 2407 } |
2408 | |
2409 void postprocess2(unsigned char * src[], int src_stride, | |
2410 unsigned char * dst[], int dst_stride, | |
2411 int horizontal_size, int vertical_size, | |
2412 QP_STORE_T *QP_store, int QP_stride, | |
2413 struct PPMode *mode) | |
2414 { | |
2415 | |
2416 #ifdef HAVE_ODIVX_POSTPROCESS | |
2417 // Note: I could make this shit outside of this file, but it would mean one | |
2418 // more function call... | |
2419 if(use_old_pp){ | |
2420 odivx_postprocess(src,src_stride,dst,dst_stride,horizontal_size,vertical_size,QP_store,QP_stride, | |
2421 mode->oldMode); | |
2422 return; | |
2423 } | |
2424 #endif | |
2425 | |
2426 postProcess(src[0], src_stride, dst[0], dst_stride, | |
2427 horizontal_size, vertical_size, QP_store, QP_stride, 0, mode->lumMode); | |
2428 | |
2429 horizontal_size >>= 1; | |
2430 vertical_size >>= 1; | |
2431 src_stride >>= 1; | |
2432 dst_stride >>= 1; | |
2433 | |
2434 postProcess(src[1], src_stride, dst[1], dst_stride, | |
2435 horizontal_size, vertical_size, QP_store, QP_stride, 1, mode->chromMode); | |
2436 postProcess(src[2], src_stride, dst[2], dst_stride, | |
2437 horizontal_size, vertical_size, QP_store, QP_stride, 2, mode->chromMode); | |
2438 } | |
2439 | |
2222 | 2440 |
2223 /** | 2441 /** |
2224 * gets the mode flags for a given quality (larger values mean slower but better postprocessing) | 2442 * gets the mode flags for a given quality (larger values mean slower but better postprocessing) |
2225 * 0 <= quality <= 6 | 2443 * 0 <= quality <= 6 |
2226 */ | 2444 */ |