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