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 */ |
