[svn] / branches / unlabeled-1.9.1 / vfw / src / codec.c Repository:
ViewVC logotype

Annotation of /branches/unlabeled-1.9.1/vfw/src/codec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 61 - (view) (download)
Original Path: trunk/vfw/src/codec.c

1 : Isibaar 3 /**************************************************************************
2 :     *
3 :     * XVID VFW FRONTEND
4 :     * codec
5 :     *
6 :     * This program is free software; you can redistribute it and/or modify
7 :     * it under the terms of the GNU General Public License as published by
8 :     * the Free Software Foundation; either version 2 of the License, or
9 :     * (at your option) any later version.
10 :     *
11 :     * This program is distributed in the hope that it will be useful,
12 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 :     * GNU General Public License for more details.
15 :     *
16 :     * You should have received a copy of the GNU General Public License
17 :     * along with this program; if not, write to the Free Software
18 :     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 :     *
20 :     *************************************************************************/
21 :    
22 :     /**************************************************************************
23 :     *
24 :     * History:
25 :     *
26 : h 61 * 23.03.2002 daniel smith <danielsmith@astroboymail.com>
27 :     * changed inter4v to only be in modes 5 or 6
28 :     * fixed null mode crash ?
29 :     * merged foxer's alternative 2-pass code
30 :     * added DEBUGERR output on errors instead of returning
31 : h 30 * 16.03.2002 daniel smith <danielsmith@astroboymail.com>
32 :     * changed BITMAPV4HEADER to BITMAPINFOHEADER
33 :     * - prevents memcpy crash in compress_get_format()
34 :     * credits are processed in external 2pass mode
35 :     * motion search precision = 0 now effective in 2-pass
36 :     * modulated quantization
37 :     * added DX50 fourcc
38 : Isibaar 3 * 01.12.2001 inital version; (c)2001 peter ross <suxen_drol@hotmail.com>
39 :     *
40 :     *************************************************************************/
41 :    
42 :     #include <windows.h>
43 :     #include <vfw.h>
44 :    
45 :     #include "codec.h"
46 :     #include <math.h> // fabs()
47 :    
48 :     int pmvfast_presets[7] = {
49 :     0, PMV_QUICKSTOP16, PMV_EARLYSTOP16, PMV_EARLYSTOP16 | PMV_EARLYSTOP8,
50 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8,
51 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8,
52 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 |
53 :     PMV_EARLYSTOP8 | PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8
54 :     };
55 :    
56 :     /* return xvid compatbile colorspace,
57 :     or XVID_CSP_NULL if failure
58 :     */
59 :    
60 : h 30 int get_colorspace(BITMAPINFOHEADER * hdr)
61 : Isibaar 3 {
62 : h 30 if (hdr->biHeight < 0)
63 : Isibaar 3 {
64 : h 61 DEBUGERR("colorspace: inverted input format not supported");
65 : Isibaar 3 return XVID_CSP_NULL;
66 :     }
67 :    
68 : h 30 switch(hdr->biCompression)
69 : Isibaar 3 {
70 :     case BI_RGB :
71 : h 30 if (hdr->biBitCount == 16)
72 : Isibaar 3 {
73 :     DEBUG("RGB16 (RGB555)");
74 :     return XVID_CSP_VFLIP | XVID_CSP_RGB555;
75 :     }
76 : h 30 if (hdr->biBitCount == 24)
77 : Isibaar 3 {
78 :     DEBUG("RGB24");
79 :     return XVID_CSP_VFLIP | XVID_CSP_RGB24;
80 :     }
81 : h 30 if (hdr->biBitCount == 32)
82 : Isibaar 3 {
83 :     DEBUG("RGB32");
84 :     return XVID_CSP_VFLIP | XVID_CSP_RGB32;
85 :     }
86 :    
87 : h 30 DEBUG1("BI_RGB unsupported", hdr->biBitCount);
88 : Isibaar 3 return XVID_CSP_NULL;
89 :    
90 : h 30 // how do these work in BITMAPINFOHEADER ???
91 :     /* case BI_BITFIELDS :
92 :     if (hdr->biBitCount == 16
93 :     if(hdr->biBitCount == 16 &&
94 : Isibaar 3 hdr->bV4RedMask == 0x7c00 &&
95 :     hdr->bV4GreenMask == 0x3e0 &&
96 :     hdr->bV4BlueMask == 0x1f)
97 :     {
98 :     DEBUG("RGB555");
99 :     return XVID_CSP_VFLIP | XVID_CSP_RGB555;
100 :     }
101 :     if(hdr->bV4BitCount == 16 &&
102 :     hdr->bV4RedMask == 0xf800 &&
103 :     hdr->bV4GreenMask == 0x7e0 &&
104 :     hdr->bV4BlueMask == 0x1f)
105 :     {
106 :     DEBUG("RGB565");
107 :     return XVID_CSP_VFLIP | XVID_CSP_RGB565;
108 :     }
109 :    
110 :     DEBUG1("BI_FIELDS unsupported", hdr->bV4BitCount);
111 :     return XVID_CSP_NULL;
112 : h 30 */
113 : Isibaar 3 case FOURCC_I420:
114 :     case FOURCC_IYUV:
115 :     DEBUG("IYUY");
116 :     return XVID_CSP_I420;
117 :    
118 :     case FOURCC_YV12 :
119 :     DEBUG("YV12");
120 :     return XVID_CSP_YV12;
121 :    
122 :     case FOURCC_YUYV :
123 :     case FOURCC_YUY2 :
124 :     case FOURCC_V422 :
125 :     DEBUG("YUY2");
126 :     return XVID_CSP_YUY2;
127 :    
128 :     case FOURCC_YVYU:
129 :     DEBUG("YVYU");
130 :     return XVID_CSP_YVYU;
131 :    
132 :     case FOURCC_UYVY:
133 :     DEBUG("UYVY");
134 :     return XVID_CSP_UYVY;
135 :    
136 :     }
137 : h 30 DEBUGFOURCC("colorspace: unknown", hdr->biCompression);
138 : Isibaar 3 return XVID_CSP_NULL;
139 :     }
140 :    
141 :    
142 :     /* compressor */
143 :    
144 :    
145 :     /* test the output format */
146 :    
147 :     LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
148 :     {
149 : h 30 BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
150 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
151 : Isibaar 3
152 :     if (get_colorspace(inhdr) == XVID_CSP_NULL)
153 :     {
154 :     return ICERR_BADFORMAT;
155 :     }
156 :    
157 :     if (lpbiOutput == NULL)
158 :     {
159 :     return ICERR_OK;
160 :     }
161 : h 30
162 :     if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight ||
163 :     (outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX))
164 : Isibaar 3 {
165 :     return ICERR_BADFORMAT;
166 :     }
167 :    
168 :     return ICERR_OK;
169 :     }
170 :    
171 :    
172 :     LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
173 :     {
174 : h 30 BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
175 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
176 : Isibaar 3
177 : h 30 if (get_colorspace(inhdr) == XVID_CSP_NULL)
178 : Isibaar 3 {
179 : h 30 return ICERR_BADFORMAT;
180 : Isibaar 3 }
181 :    
182 :     if (lpbiOutput == NULL)
183 :     {
184 :     return sizeof(BITMAPV4HEADER);
185 :     }
186 :    
187 : h 30 memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
188 :     outhdr->biSize = sizeof(BITMAPINFOHEADER);
189 :     outhdr->biBitCount = 24; // or 16
190 :     outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput);
191 :     outhdr->biXPelsPerMeter = 0;
192 :     outhdr->biYPelsPerMeter = 0;
193 :     outhdr->biClrUsed = 0;
194 :     outhdr->biClrImportant = 0;
195 : Isibaar 3
196 :     if (codec->config.fourcc_used == 0)
197 :     {
198 : h 30 outhdr->biCompression = FOURCC_XVID;
199 : Isibaar 3 }
200 : h 30 else if (codec->config.fourcc_used == 1)
201 :     {
202 :     outhdr->biCompression = FOURCC_DIVX;
203 :     }
204 : Isibaar 3 else
205 :     {
206 : h 30 outhdr->biCompression = FOURCC_DX50;
207 : Isibaar 3 }
208 :    
209 :     return ICERR_OK;
210 :     }
211 :    
212 :    
213 :     LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
214 :     {
215 : h 30 return lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3;
216 : Isibaar 3 }
217 :    
218 :    
219 :     LRESULT compress_frames_info(CODEC * codec, ICCOMPRESSFRAMES * icf)
220 :     {
221 :     // DEBUG2("frate fscale", codec->frate, codec->fscale);
222 :     codec->fincr = icf->dwScale;
223 :     codec->fbase = icf->dwRate;
224 :     return ICERR_OK;
225 :     }
226 :    
227 :    
228 :     LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
229 :     {
230 :     XVID_ENC_PARAM param;
231 :     XVID_INIT_PARAM init_param;
232 :    
233 :     switch (codec->config.mode)
234 :     {
235 :     case DLG_MODE_CBR :
236 :     param.bitrate = codec->config.bitrate;
237 :     param.rc_buffersize = codec->config.rc_buffersize;
238 :     break;
239 :    
240 :     case DLG_MODE_VBR_QUAL :
241 :     codec->config.fquant = 0;
242 :     param.bitrate = 0;
243 :     break;
244 :    
245 :     case DLG_MODE_VBR_QUANT :
246 :     codec->config.fquant = (float) codec->config.quant;
247 :     param.bitrate = 0;
248 :     break;
249 :    
250 : h 61 case DLG_MODE_2PASS_1 :
251 :     case DLG_MODE_2PASS_2_INT :
252 :     case DLG_MODE_2PASS_2_EXT :
253 : Isibaar 3 param.bitrate = 0;
254 :     break;
255 :    
256 : h 61 case DLG_MODE_NULL :
257 :     return ICERR_OK;
258 :    
259 : Isibaar 3 default :
260 :     break;
261 :     }
262 :    
263 :     if(codec->ehandle)
264 :     {
265 :     xvid_encore(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
266 :     codec->ehandle = NULL;
267 :     }
268 :    
269 :     init_param.cpu_flags = codec->config.cpu;
270 :     xvid_init(0, 0, &init_param, NULL);
271 :     if((codec->config.cpu & XVID_CPU_FORCE) <= 0)
272 :     codec->config.cpu = init_param.cpu_flags;
273 :    
274 : h 30 param.width = lpbiInput->bmiHeader.biWidth;
275 :     param.height = lpbiInput->bmiHeader.biHeight;
276 : Isibaar 3 param.fincr = codec->fincr;
277 :     param.fbase = codec->fbase;
278 :    
279 :     param.rc_buffersize = codec->config.rc_buffersize;
280 :    
281 : h 30 param.min_quantizer = codec->config.min_pquant;
282 :     param.max_quantizer = codec->config.max_pquant;
283 : Isibaar 3 param.max_key_interval = codec->config.max_key_interval;
284 :    
285 :     switch(xvid_encore(0, XVID_ENC_CREATE, &param, NULL))
286 :     {
287 :     case XVID_ERR_FAIL :
288 :     return ICERR_ERROR;
289 :    
290 :     case XVID_ERR_MEMORY :
291 :     return ICERR_MEMORY;
292 :    
293 :     case XVID_ERR_FORMAT :
294 :     return ICERR_BADFORMAT;
295 :     }
296 :    
297 :     codec->ehandle = param.handle;
298 :     codec->framenum = 0;
299 :     codec->keyspacing = 0;
300 :    
301 :     codec->twopass.stats1 = codec->twopass.stats2 = INVALID_HANDLE_VALUE;
302 :    
303 :     return ICERR_OK;
304 :     }
305 :    
306 :    
307 :     LRESULT compress_end(CODEC * codec)
308 :     {
309 :     if (codec->ehandle != NULL)
310 :     {
311 :     xvid_encore(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
312 :     if (codec->twopass.stats1 != INVALID_HANDLE_VALUE)
313 :     {
314 :     CloseHandle(codec->twopass.stats1);
315 :     }
316 :     if (codec->twopass.stats2 != INVALID_HANDLE_VALUE)
317 :     {
318 :     CloseHandle(codec->twopass.stats2);
319 :     }
320 :     codec->ehandle = NULL;
321 :     }
322 :    
323 :     return ICERR_OK;
324 :     }
325 :    
326 :    
327 :     LRESULT compress(CODEC * codec, ICCOMPRESS * icc)
328 :     {
329 : h 30 BITMAPINFOHEADER * inhdr = icc->lpbiInput;
330 :     BITMAPINFOHEADER * outhdr = icc->lpbiOutput;
331 : Isibaar 3 XVID_ENC_FRAME frame;
332 :     XVID_ENC_STATS stats;
333 :    
334 :     // mpeg2avi yuv bug workaround (2 instances of CODEC)
335 :     if (codec->twopass.stats1 == INVALID_HANDLE_VALUE)
336 :     {
337 :     if (codec_2pass_init(codec) == ICERR_ERROR)
338 :     {
339 :     return ICERR_ERROR;
340 :     }
341 :     }
342 :    
343 :     frame.general = 0;
344 :     frame.motion = 0;
345 : h 30 frame.intra = -1;
346 : Isibaar 3
347 :     frame.general |= XVID_HALFPEL;
348 :    
349 : h 61 if(codec->config.motion_search > 4)
350 : Isibaar 3 frame.general |= XVID_INTER4V;
351 :    
352 :     if(((codec->config.mode == DLG_MODE_2PASS_1) ? 0 : codec->config.lum_masking) == 1)
353 :     frame.general |= XVID_LUMIMASKING;
354 :    
355 :     frame.motion = pmvfast_presets[codec->config.motion_search];
356 : h 30
357 : Isibaar 3 frame.image = icc->lpInput;
358 :    
359 : h 30 if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL)
360 : Isibaar 3 return ICERR_BADFORMAT;
361 :    
362 :     frame.bitstream = icc->lpOutput;
363 :     frame.length = icc->lpbiOutput->biSizeImage;
364 :    
365 :     switch (codec->config.mode)
366 :     {
367 :     case DLG_MODE_CBR :
368 :     frame.quant = 0;
369 :     break;
370 :    
371 :     case DLG_MODE_VBR_QUAL :
372 :     case DLG_MODE_VBR_QUANT :
373 :     case DLG_MODE_2PASS_1 :
374 :     if (codec_get_quant(codec, &frame) == ICERR_ERROR)
375 :     {
376 :     return ICERR_ERROR;
377 :     }
378 :     break;
379 :    
380 :     case DLG_MODE_2PASS_2_EXT :
381 :     case DLG_MODE_2PASS_2_INT :
382 :     if (codec_2pass_get_quant(codec, &frame) == ICERR_ERROR)
383 :     {
384 :     return ICERR_ERROR;
385 :     }
386 :     if (codec->config.dummy2pass)
387 :     {
388 : h 30 outhdr->biSizeImage = codec->twopass.bytes2;
389 : Isibaar 3 *icc->lpdwFlags = (codec->twopass.nns1.quant & NNSTATS_KEYFRAME) ? AVIIF_KEYFRAME : 0;
390 :     return ICERR_OK;
391 :     }
392 :     break;
393 :    
394 :     case DLG_MODE_NULL :
395 : h 30 outhdr->biSizeImage = 0;
396 : Isibaar 3 *icc->lpdwFlags = AVIIF_KEYFRAME;
397 :     return ICERR_OK;
398 :    
399 :     default :
400 : h 61 DEBUGERR("Invalid encoding mode");
401 : Isibaar 3 return ICERR_ERROR;
402 :     }
403 :    
404 : h 30 if (codec->config.quant_type == QUANT_MODE_H263)
405 : Isibaar 3 {
406 : h 30 frame.general |= XVID_H263QUANT;
407 :     }
408 :     else
409 :     {
410 :     frame.general |= XVID_MPEGQUANT;
411 :    
412 :     // we actually need "default/custom" selectbox for both inter/intra
413 :     // this will do for now
414 :     if (codec->config.quant_type == QUANT_MODE_CUSTOM)
415 :     {
416 :     frame.general |= XVID_CUSTOM_QMATRIX;
417 :     frame.quant_intra_matrix = codec->config.qmatrix_intra;
418 :     frame.quant_inter_matrix = codec->config.qmatrix_inter;
419 :     }
420 :     else
421 :     {
422 :     frame.quant_intra_matrix = NULL;
423 :     frame.quant_inter_matrix = NULL;
424 :     }
425 :     }
426 :    
427 :     // force keyframe spacing in 2-pass 1st pass
428 :     if (codec->config.motion_search == 0)
429 :     {
430 :     frame.intra = 1;
431 :     }
432 :     else if ((codec->keyspacing < codec->config.min_key_interval && codec->framenum) &&
433 :     (codec->config.mode == DLG_MODE_2PASS_1))
434 :     {
435 : Isibaar 3 DEBUG("current frame forced to p-frame");
436 :     frame.intra = 0;
437 :     }
438 :    
439 :     switch (xvid_encore(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats))
440 :     {
441 :     case XVID_ERR_FAIL :
442 :     return ICERR_ERROR;
443 :    
444 :     case XVID_ERR_MEMORY :
445 :     return ICERR_MEMORY;
446 :    
447 :     case XVID_ERR_FORMAT :
448 :     return ICERR_BADFORMAT;
449 :     }
450 :    
451 :     if (frame.intra)
452 :     {
453 :     codec->keyspacing = 0;
454 :     *icc->lpdwFlags = AVIIF_KEYFRAME;
455 :     }
456 :     else
457 :     {
458 :     *icc->lpdwFlags = 0;
459 :     }
460 :    
461 : h 30 outhdr->biSizeImage = frame.length;
462 : Isibaar 3
463 : h 30 if (codec->config.mode == DLG_MODE_2PASS_1 && codec->config.discard1pass)
464 : Isibaar 3 {
465 : h 30 outhdr->biSizeImage = 0;
466 : Isibaar 3 }
467 :    
468 :     codec_2pass_update(codec, &frame, &stats);
469 :    
470 :     ++codec->framenum;
471 :     ++codec->keyspacing;
472 :    
473 :     return ICERR_OK;
474 :     }
475 :    
476 :    
477 :     /* decompressor */
478 :    
479 :    
480 :     LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput)
481 :     {
482 : h 30 BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
483 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
484 : Isibaar 3
485 :     if (lpbiInput == NULL)
486 :     {
487 :     return ICERR_ERROR;
488 :     }
489 :    
490 : h 30 if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX)
491 : Isibaar 3 {
492 :     return ICERR_BADFORMAT;
493 :     }
494 :    
495 :     if (lpbiOutput == NULL)
496 :     {
497 :     return ICERR_OK;
498 :     }
499 :    
500 : h 30 if (inhdr->biWidth != outhdr->biWidth ||
501 :     inhdr->biHeight != outhdr->biHeight ||
502 : Isibaar 3 get_colorspace(outhdr) == XVID_CSP_NULL)
503 :     {
504 :     return ICERR_BADFORMAT;
505 :     }
506 :    
507 :     return ICERR_OK;
508 :     }
509 :    
510 :    
511 :     LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
512 :     {
513 : h 30 BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
514 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
515 : Isibaar 3 LRESULT result;
516 :    
517 :     if (lpbiOutput == NULL)
518 :     {
519 : h 30 return sizeof(BITMAPINFOHEADER);
520 : Isibaar 3 }
521 :    
522 :     result = decompress_query(codec, lpbiInput, lpbiOutput);
523 :     if (result != ICERR_OK)
524 :     {
525 :     return result;
526 :     }
527 :    
528 : h 30 memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
529 :     outhdr->biSize = sizeof(BITMAPINFOHEADER);
530 :     outhdr->biCompression = FOURCC_YUY2;
531 :     outhdr->biSizeImage = outhdr->biWidth * outhdr->biHeight * outhdr->biBitCount;
532 :     outhdr->biXPelsPerMeter = 0;
533 :     outhdr->biYPelsPerMeter = 0;
534 :     outhdr->biClrUsed = 0;
535 :     outhdr->biClrImportant = 0;
536 : Isibaar 3
537 :     return ICERR_OK;
538 :     }
539 :    
540 :    
541 :     LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
542 :     {
543 :     XVID_DEC_PARAM param;
544 :     XVID_INIT_PARAM init_param;
545 :    
546 :     init_param.cpu_flags = codec->config.cpu;
547 :     xvid_init(0, 0, &init_param, NULL);
548 :     if((codec->config.cpu & XVID_CPU_FORCE) <= 0)
549 :     {
550 :     codec->config.cpu = init_param.cpu_flags;
551 :     }
552 :    
553 : h 30 param.width = lpbiInput->bmiHeader.biWidth;
554 :     param.height = lpbiInput->bmiHeader.biHeight;
555 : Isibaar 3
556 :     switch(xvid_decore(0, XVID_DEC_CREATE, &param, NULL))
557 :     {
558 :     case XVID_ERR_FAIL :
559 :     return ICERR_ERROR;
560 :    
561 :     case XVID_ERR_MEMORY :
562 :     return ICERR_MEMORY;
563 :    
564 :     case XVID_ERR_FORMAT :
565 :     return ICERR_BADFORMAT;
566 :     }
567 :    
568 :     codec->dhandle = param.handle;
569 :    
570 :     return ICERR_OK;
571 :     }
572 :    
573 :    
574 :     LRESULT decompress_end(CODEC * codec)
575 :     {
576 :     if (codec->dhandle != NULL)
577 :     {
578 :     xvid_decore(codec->dhandle, XVID_DEC_DESTROY, NULL, NULL);
579 :     codec->dhandle = NULL;
580 :     }
581 :     return ICERR_OK;
582 :     }
583 :    
584 :    
585 :     LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd)
586 :     {
587 :     XVID_DEC_FRAME frame;
588 :    
589 :     frame.bitstream = icd->lpInput;
590 :     frame.length = icd->lpbiInput->biSizeImage;
591 :    
592 :     frame.image = icd->lpOutput;
593 :     frame.stride = icd->lpbiOutput->biWidth;
594 :    
595 :     if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE)))
596 :     {
597 : h 30 if ((frame.colorspace = get_colorspace(icd->lpbiOutput)) == XVID_CSP_NULL)
598 : Isibaar 3 {
599 :     return ICERR_BADFORMAT;
600 :     }
601 :     }
602 :     else
603 :     {
604 :     frame.colorspace = XVID_CSP_NULL;
605 :     }
606 :    
607 :     switch (xvid_decore(codec->dhandle, XVID_DEC_DECODE, &frame, NULL))
608 :     {
609 :     case XVID_ERR_FAIL :
610 :     return ICERR_ERROR;
611 :    
612 :     case XVID_ERR_MEMORY :
613 :     return ICERR_MEMORY;
614 :    
615 :     case XVID_ERR_FORMAT :
616 :     return ICERR_BADFORMAT;
617 :     }
618 :    
619 :     return ICERR_OK;
620 :     }
621 :    
622 :     int codec_2pass_init(CODEC* codec)
623 :     {
624 :     TWOPASS *twopass = &codec->twopass;
625 :     DWORD version = -20;
626 :     DWORD read, wrote;
627 :    
628 :     int frames = 0, credits_frames = 0, i_frames = 0;
629 :     __int64 total = 0, i_total = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0;
630 :     __int64 desired = codec->config.desired_size * 1024;
631 :    
632 :     double total1 = 0.0;
633 :     double total2 = 0.0;
634 :    
635 :     switch (codec->config.mode)
636 :     {
637 :     case DLG_MODE_2PASS_1 :
638 :     twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
639 :     if (twopass->stats1 == INVALID_HANDLE_VALUE)
640 :     {
641 : h 61 DEBUGERR("2pass init error - couldn't create stats1");
642 : Isibaar 3 return ICERR_ERROR;
643 :     }
644 :     if (WriteFile(twopass->stats1, &version, sizeof(DWORD), &wrote, 0) == 0 || wrote != sizeof(DWORD))
645 :     {
646 :     CloseHandle(twopass->stats1);
647 :     twopass->stats1 = INVALID_HANDLE_VALUE;
648 : h 61 DEBUGERR("2pass init error - couldn't write to stats1");
649 : Isibaar 3 return ICERR_ERROR;
650 :     }
651 :     break;
652 :    
653 :     case DLG_MODE_2PASS_2_INT :
654 :     case DLG_MODE_2PASS_2_EXT :
655 :     twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
656 :     if (twopass->stats1 == INVALID_HANDLE_VALUE)
657 :     {
658 : h 61 DEBUGERR("2pass init error - couldn't open stats1");
659 : Isibaar 3 return ICERR_ERROR;
660 :     }
661 :     if (ReadFile(twopass->stats1, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))
662 :     {
663 :     CloseHandle(twopass->stats1);
664 :     twopass->stats1 = INVALID_HANDLE_VALUE;
665 : h 61 DEBUGERR("2pass init error - couldn't read from stats1");
666 : Isibaar 3 return ICERR_ERROR;
667 :     }
668 :     if (version != -20)
669 :     {
670 :     CloseHandle(twopass->stats1);
671 :     twopass->stats1 = INVALID_HANDLE_VALUE;
672 : h 61 DEBUGERR("2pass init error - wrong .stats version");
673 : Isibaar 3 return ICERR_ERROR;
674 :     }
675 :    
676 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
677 :     {
678 :     if (twopass->stats2 != INVALID_HANDLE_VALUE)
679 :     {
680 :     CloseHandle(twopass->stats2);
681 :     }
682 :    
683 :     twopass->stats2 = CreateFile(codec->config.stats2, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
684 :    
685 :     if (twopass->stats2 == INVALID_HANDLE_VALUE)
686 :     {
687 :     CloseHandle(twopass->stats1);
688 :     twopass->stats1 = INVALID_HANDLE_VALUE;
689 : h 61 DEBUGERR("2pass init error - couldn't open stats2");
690 : Isibaar 3 return ICERR_ERROR;
691 :     }
692 :     if (ReadFile(twopass->stats2, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))
693 :     {
694 :     CloseHandle(twopass->stats1);
695 :     twopass->stats1 = INVALID_HANDLE_VALUE;
696 :     CloseHandle(twopass->stats2);
697 :     twopass->stats2 = INVALID_HANDLE_VALUE;
698 : h 61 DEBUGERR("2pass init error - couldn't read from stats2");
699 : Isibaar 3 return ICERR_ERROR;
700 :     }
701 :     if (version != -20)
702 :     {
703 :     CloseHandle(twopass->stats1);
704 :     twopass->stats1 = INVALID_HANDLE_VALUE;
705 :     CloseHandle(twopass->stats2);
706 :     twopass->stats2 = INVALID_HANDLE_VALUE;
707 : h 61 DEBUGERR("2pass init error - wrong .stats version");
708 : Isibaar 3 return ICERR_ERROR;
709 :     }
710 :    
711 :     while (1)
712 :     {
713 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||
714 :     !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
715 :     {
716 :     DWORD err = GetLastError();
717 :    
718 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
719 :     {
720 :     break;
721 :     }
722 :     else
723 :     {
724 :     CloseHandle(twopass->stats1);
725 :     CloseHandle(twopass->stats2);
726 :     twopass->stats1 = INVALID_HANDLE_VALUE;
727 :     twopass->stats2 = INVALID_HANDLE_VALUE;
728 : h 61 DEBUGERR("2pass init error - incomplete stats1/stats2 record?");
729 : Isibaar 3 return ICERR_ERROR;
730 :     }
731 :     }
732 :    
733 :     if (!codec_is_in_credits(&codec->config, frames))
734 :     {
735 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
736 :     {
737 :     i_boost_total = twopass->nns2.bytes * codec->config.keyframe_boost / 100;
738 :     i_total += twopass->nns2.bytes;
739 :     ++i_frames;
740 :     }
741 :    
742 :     total += twopass->nns2.bytes;
743 :     }
744 :     else
745 :     ++credits_frames;
746 :    
747 :     ++frames;
748 :     }
749 :    
750 :     twopass->movie_curve = ((float)(total + i_boost_total) / total);
751 :     twopass->average_frame = ((double)(total - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);
752 :    
753 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
754 :     SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
755 :    
756 :     // perform prepass to compensate for over/undersizing
757 :     frames = 0;
758 :    
759 : h 61 if (codec->config.use_alt_curve)
760 :     {
761 :     twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;
762 :     twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;
763 :     twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;
764 :     twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;
765 :     if (codec->config.alt_curve_use_auto)
766 :     {
767 :     if (twopass->movie_curve > 1.0f)
768 :     {
769 :     codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / twopass->movie_curve) * (double)codec->config.alt_curve_auto_str / 100.0);
770 :     if (codec->config.alt_curve_min_rel_qual < 20)
771 :     codec->config.alt_curve_min_rel_qual = 20;
772 :     }
773 :     else
774 :     codec->config.alt_curve_min_rel_qual = 100;
775 :     }
776 :     twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
777 :     twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
778 :     if (codec->config.alt_curve_low_dist > 100)
779 :     {
780 :     switch(codec->config.alt_curve_type)
781 :     {
782 :     case 2: // Sine Curve (high aggressiveness)
783 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
784 :     sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
785 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
786 :     sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));
787 :     break;
788 :     case 1: // Linear (medium aggressiveness)
789 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
790 :     twopass->average_frame / twopass->alt_curve_low_diff);
791 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
792 :     twopass->average_frame / twopass->alt_curve_low_diff;
793 :     break;
794 :     case 0: // Cosine Curve (low aggressiveness)
795 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
796 :     (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));
797 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
798 :     (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
799 :     }
800 :     }
801 :     }
802 :    
803 : Isibaar 3 while (1)
804 :     {
805 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||
806 :     !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
807 :     {
808 :     DWORD err = GetLastError();
809 :    
810 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
811 :     {
812 :     break;
813 :     }
814 :     else
815 :     {
816 :     CloseHandle(twopass->stats1);
817 :     CloseHandle(twopass->stats2);
818 :     twopass->stats1 = INVALID_HANDLE_VALUE;
819 :     twopass->stats2 = INVALID_HANDLE_VALUE;
820 : h 61 DEBUGERR("2pass init error - incomplete stats1/stats2 record?");
821 : Isibaar 3 return ICERR_ERROR;
822 :     }
823 :     }
824 :    
825 :     if (!codec_is_in_credits(&codec->config, frames) &&
826 :     !(twopass->nns1.quant & NNSTATS_KEYFRAME))
827 :     {
828 :     double dbytes = twopass->nns2.bytes / twopass->movie_curve;
829 :     total1 += dbytes;
830 :    
831 : h 61 if (codec->config.use_alt_curve)
832 : Isibaar 3 {
833 : h 61 if (dbytes > twopass->average_frame)
834 :     {
835 :     if (dbytes >= twopass->alt_curve_high)
836 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
837 :     else
838 :     {
839 :     switch(codec->config.alt_curve_type)
840 :     {
841 :     case 2:
842 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
843 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
844 :     break;
845 :     case 1:
846 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
847 :     (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
848 :     break;
849 :     case 0:
850 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
851 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
852 :     }
853 :     }
854 :     }
855 :     else
856 :     {
857 :     if (dbytes <= twopass->alt_curve_low)
858 :     total2 += dbytes;
859 :     else
860 :     {
861 :     switch(codec->config.alt_curve_type)
862 :     {
863 :     case 2:
864 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
865 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
866 :     break;
867 :     case 1:
868 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
869 :     (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
870 :     break;
871 :     case 0:
872 :     total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
873 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
874 :     }
875 :     }
876 :     }
877 : Isibaar 3 }
878 :     else
879 :     {
880 : h 61 if (dbytes > twopass->average_frame)
881 :     {
882 :     total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
883 :     codec->config.curve_compression_high / 100.0);
884 :     }
885 :     else
886 :     {
887 :     total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
888 :     codec->config.curve_compression_low / 100.0);
889 :     }
890 : Isibaar 3 }
891 :     }
892 :    
893 :     ++frames;
894 :     }
895 :    
896 :     twopass->curve_comp_scale = total1 / total2;
897 :    
898 : h 61 if (!codec->config.use_alt_curve)
899 : Isibaar 3 {
900 :     int asymmetric_average_frame;
901 :     char s[100];
902 :    
903 :     asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);
904 :     wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
905 :     DEBUG2P(s);
906 :     }
907 :    
908 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
909 :     SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
910 :     }
911 :     else // DLG_MODE_2PASS_2_INT
912 :     {
913 :     while (1)
914 :     {
915 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
916 :     {
917 :     DWORD err = GetLastError();
918 :    
919 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
920 :     {
921 :     break;
922 :     }
923 :     else
924 :     {
925 :     CloseHandle(twopass->stats1);
926 :     twopass->stats1 = INVALID_HANDLE_VALUE;
927 : h 61 DEBUGERR("2pass init error - incomplete stats2 record?");
928 : Isibaar 3 return ICERR_ERROR;
929 :     }
930 :     }
931 :    
932 :     if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)
933 :     {
934 :     start += twopass->nns1.bytes;
935 :     ++credits_frames;
936 :     }
937 :     else if (codec_is_in_credits(&codec->config, frames) == CREDITS_END)
938 :     {
939 :     end += twopass->nns1.bytes;
940 :     ++credits_frames;
941 :     }
942 :     else if (twopass->nns1.quant & NNSTATS_KEYFRAME)
943 :     {
944 :     i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;
945 :     total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;
946 :     ++i_frames;
947 :     }
948 :    
949 :     total += twopass->nns1.bytes;
950 :    
951 :     ++frames;
952 :     }
953 :    
954 :     // compensate for avi frame overhead
955 :     desired -= frames * 24;
956 :    
957 :     switch (codec->config.credits_mode)
958 :     {
959 :     case CREDITS_MODE_RATE :
960 :    
961 :     // credits curve = (total / desired_size) * (100 / credits_rate)
962 :     twopass->credits_start_curve = twopass->credits_end_curve =
963 :     ((float)total / desired) * ((float)100 / codec->config.credits_rate);
964 :    
965 :     start_curved = (__int64)(start / twopass->credits_start_curve);
966 :     end_curved = (__int64)(end / twopass->credits_end_curve);
967 :    
968 :     // movie curve = (total - credits) / (desired_size - curved credits)
969 :     twopass->movie_curve = (float)
970 :     (total - start - end) /
971 :     (desired - start_curved - end_curved);
972 :    
973 :     break;
974 :    
975 :     case CREDITS_MODE_QUANT :
976 :    
977 :     // movie curve = (total - credits) / (desired_size - credits)
978 :     twopass->movie_curve = (float)
979 :     (total - start - end) / (desired - start - end);
980 :    
981 :     // aid the average asymmetric frame calculation below
982 :     start_curved = start;
983 :     end_curved = end;
984 :    
985 :     break;
986 :    
987 :     case CREDITS_MODE_SIZE :
988 :    
989 :     // start curve = (start / start desired size)
990 :     twopass->credits_start_curve = (float)
991 :     (start / 1024) / codec->config.credits_start_size;
992 :    
993 :     // end curve = (end / end desired size)
994 :     twopass->credits_end_curve = (float)
995 :     (end / 1024) / codec->config.credits_end_size;
996 :    
997 :     start_curved = (__int64)(start / twopass->credits_start_curve);
998 :     end_curved = (__int64)(end / twopass->credits_end_curve);
999 :    
1000 :     // movie curve = (total - credits) / (desired_size - curved credits)
1001 :     twopass->movie_curve = (float)
1002 :     (total - start - end) /
1003 :     (desired - start_curved - end_curved);
1004 :    
1005 :     break;
1006 :     }
1007 :    
1008 :     // average frame size = (desired - curved credits - curved keyframes) /
1009 :     // (frames - credits frames - keyframes)
1010 :     twopass->average_frame = (double)
1011 :     (desired - start_curved - end_curved - (i_total / twopass->movie_curve)) /
1012 :     (frames - credits_frames - i_frames);
1013 :    
1014 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
1015 :    
1016 :     // perform prepass to compensate for over/undersizing
1017 :     frames = 0;
1018 :    
1019 : h 61 if (codec->config.use_alt_curve)
1020 :     {
1021 :     twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;
1022 :     twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;
1023 :     twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;
1024 :     twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;
1025 :     if (codec->config.alt_curve_use_auto)
1026 :     {
1027 :     if (twopass->movie_curve > 1.0f)
1028 :     {
1029 :     codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / twopass->movie_curve) * (double)codec->config.alt_curve_auto_str / 100.0);
1030 :     if (codec->config.alt_curve_min_rel_qual < 20)
1031 :     codec->config.alt_curve_min_rel_qual = 20;
1032 :     }
1033 :     else
1034 :     codec->config.alt_curve_min_rel_qual = 100;
1035 :     }
1036 :     twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
1037 :     twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
1038 :     if (codec->config.alt_curve_low_dist > 100)
1039 :     {
1040 :     switch(codec->config.alt_curve_type)
1041 :     {
1042 :     case 2: // Sine Curve (high aggressiveness)
1043 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
1044 :     sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
1045 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
1046 :     sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));
1047 :     break;
1048 :     case 1: // Linear (medium aggressiveness)
1049 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
1050 :     twopass->average_frame / twopass->alt_curve_low_diff);
1051 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
1052 :     twopass->average_frame / twopass->alt_curve_low_diff;
1053 :     break;
1054 :     case 0: // Cosine Curve (low aggressiveness)
1055 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
1056 :     (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));
1057 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
1058 :     (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
1059 :     }
1060 :     }
1061 :     }
1062 :    
1063 : Isibaar 3 while (1)
1064 :     {
1065 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
1066 :     {
1067 :     DWORD err = GetLastError();
1068 :    
1069 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
1070 :     {
1071 :     break;
1072 :     }
1073 :     else
1074 :     {
1075 :     CloseHandle(twopass->stats1);
1076 :     twopass->stats1 = INVALID_HANDLE_VALUE;
1077 : h 61 DEBUGERR("2pass init error - incomplete stats2 record?");
1078 : Isibaar 3 return ICERR_ERROR;
1079 :     }
1080 :     }
1081 :    
1082 :     if (!codec_is_in_credits(&codec->config, frames) &&
1083 :     !(twopass->nns1.quant & NNSTATS_KEYFRAME))
1084 :     {
1085 :     double dbytes = twopass->nns1.bytes / twopass->movie_curve;
1086 :     total1 += dbytes;
1087 :    
1088 : h 61 if (codec->config.use_alt_curve)
1089 : Isibaar 3 {
1090 : h 61 if (dbytes > twopass->average_frame)
1091 :     {
1092 :     if (dbytes >= twopass->alt_curve_high)
1093 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
1094 :     else
1095 :     {
1096 :     switch(codec->config.alt_curve_type)
1097 :     {
1098 :     case 2:
1099 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1100 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
1101 :     break;
1102 :     case 1:
1103 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1104 :     (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
1105 :     break;
1106 :     case 0:
1107 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1108 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
1109 :     }
1110 :     }
1111 :     }
1112 :     else
1113 :     {
1114 :     if (dbytes <= twopass->alt_curve_low)
1115 :     total2 += dbytes;
1116 :     else
1117 :     {
1118 :     switch(codec->config.alt_curve_type)
1119 :     {
1120 :     case 2:
1121 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1122 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
1123 :     break;
1124 :     case 1:
1125 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1126 :     (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
1127 :     break;
1128 :     case 0:
1129 :     total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
1130 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
1131 :     }
1132 :     }
1133 :     }
1134 : Isibaar 3 }
1135 :     else
1136 :     {
1137 : h 61 if (dbytes > twopass->average_frame)
1138 :     {
1139 :     total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
1140 :     codec->config.curve_compression_high / 100.0);
1141 :     }
1142 :     else
1143 :     {
1144 :     total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
1145 :     codec->config.curve_compression_low / 100.0);
1146 :     }
1147 : Isibaar 3 }
1148 :     }
1149 :    
1150 :     ++frames;
1151 :     }
1152 :    
1153 :     twopass->curve_comp_scale = total1 / total2;
1154 :    
1155 : h 61 if (!codec->config.use_alt_curve)
1156 : Isibaar 3 {
1157 :     int asymmetric_average_frame;
1158 :     char s[100];
1159 :    
1160 :     asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);
1161 :     wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
1162 :     DEBUG2P(s);
1163 :     }
1164 :    
1165 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
1166 :     }
1167 :    
1168 : h 61 if (codec->config.use_alt_curve)
1169 :     {
1170 :     if (codec->config.alt_curve_use_auto_bonus_bias)
1171 :     codec->config.alt_curve_bonus_bias = codec->config.alt_curve_min_rel_qual;
1172 :    
1173 :     twopass->curve_bias_bonus = (total1 - total2) * (double)codec->config.alt_curve_bonus_bias / 100.0 / (double)(frames - credits_frames - i_frames);
1174 :     twopass->curve_comp_scale = ((total1 - total2) * (1.0 - (double)codec->config.alt_curve_bonus_bias / 100.0) + total2) / total2;
1175 :     }
1176 :    
1177 : Isibaar 3 twopass->overflow = 0;
1178 :    
1179 :     break;
1180 :     }
1181 :    
1182 :     return ICERR_OK;
1183 :     }
1184 :    
1185 :    
1186 :     int codec_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
1187 :     {
1188 :     switch (codec->config.mode)
1189 :     {
1190 :     case DLG_MODE_VBR_QUAL :
1191 :     if (codec_is_in_credits(&codec->config, codec->framenum))
1192 :     {
1193 :     switch (codec->config.credits_mode)
1194 :     {
1195 :     case CREDITS_MODE_RATE :
1196 :     frame->quant = codec_get_vbr_quant(&codec->config, codec->config.quality * codec->config.credits_rate / 100);
1197 :     break;
1198 :    
1199 :     case CREDITS_MODE_QUANT :
1200 :     frame->quant = codec->config.credits_quant_p;
1201 :     break;
1202 :    
1203 :     default :
1204 : h 61 DEBUGERR("Can't use credits size mode in quality mode");
1205 : Isibaar 3 return ICERR_ERROR;
1206 :     }
1207 :     }
1208 :     else
1209 :     {
1210 :     frame->quant = codec_get_vbr_quant(&codec->config, codec->config.quality);
1211 :     }
1212 :     return ICERR_OK;
1213 :    
1214 :     case DLG_MODE_VBR_QUANT :
1215 :     if (codec_is_in_credits(&codec->config, codec->framenum))
1216 :     {
1217 :     switch (codec->config.credits_mode)
1218 :     {
1219 :     case CREDITS_MODE_RATE :
1220 :     frame->quant =
1221 : h 30 codec->config.max_pquant -
1222 :     ((codec->config.max_pquant - codec->config.quant) * codec->config.credits_rate / 100);
1223 : Isibaar 3 break;
1224 :    
1225 :     case CREDITS_MODE_QUANT :
1226 :     frame->quant = codec->config.credits_quant_p;
1227 :     break;
1228 :    
1229 :     default :
1230 : h 61 DEBUGERR("Can't use credits size mode in quantizer mode");
1231 : Isibaar 3 return ICERR_ERROR;
1232 :     }
1233 :     }
1234 :     else
1235 :     {
1236 :     frame->quant = codec->config.quant;
1237 :     }
1238 :     return ICERR_OK;
1239 :    
1240 :     case DLG_MODE_2PASS_1 :
1241 :     if (codec->config.credits_mode == CREDITS_MODE_QUANT)
1242 :     {
1243 :     if (codec_is_in_credits(&codec->config, codec->framenum))
1244 :     {
1245 :     frame->quant = codec->config.credits_quant_p;
1246 :     }
1247 :     else
1248 :     {
1249 :     frame->quant = 2;
1250 :     }
1251 :     }
1252 :     else
1253 :     {
1254 :     frame->quant = 2;
1255 :     }
1256 :     return ICERR_OK;
1257 :    
1258 :     default:
1259 : h 61 DEBUGERR("get quant: invalid mode");
1260 : Isibaar 3 return ICERR_ERROR;
1261 :     }
1262 :     }
1263 :    
1264 :    
1265 :     int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
1266 :     {
1267 :     static double quant_error[32];
1268 :     static double curve_comp_error;
1269 :     static int last_quant;
1270 :    
1271 :     TWOPASS * twopass = &codec->twopass;
1272 :    
1273 :     DWORD read;
1274 :     int bytes1, bytes2;
1275 :     int overflow;
1276 :     int credits_pos;
1277 :    
1278 :     if (codec->framenum == 0)
1279 :     {
1280 :     int i;
1281 :    
1282 :     for (i=0 ; i<32 ; ++i)
1283 :     {
1284 :     quant_error[i] = 0.0;
1285 :     }
1286 :    
1287 :     curve_comp_error = 0.0;
1288 :     last_quant = 0;
1289 :     }
1290 :    
1291 :     if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))
1292 :     {
1293 : h 61 DEBUGERR("2ndpass quant: couldn't read from stats1");
1294 : Isibaar 3 return ICERR_ERROR;
1295 :     }
1296 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
1297 :     {
1298 :     if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))
1299 :     {
1300 : h 61 DEBUGERR("2ndpass quant: couldn't read from stats2");
1301 : Isibaar 3 return ICERR_ERROR;
1302 :     }
1303 :     }
1304 :    
1305 :     bytes1 = twopass->nns1.bytes;
1306 :     overflow = twopass->overflow / 8;
1307 :    
1308 :     // override codec i-frame choice (reenable in credits)
1309 :     frame->intra = (twopass->nns1.quant & NNSTATS_KEYFRAME);
1310 :    
1311 :     if (frame->intra)
1312 :     {
1313 :     overflow = 0;
1314 :     }
1315 :    
1316 :     credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1317 :    
1318 :     if (credits_pos)
1319 :     {
1320 :     if (codec->config.mode == DLG_MODE_2PASS_2_INT)
1321 :     {
1322 :     switch (codec->config.credits_mode)
1323 :     {
1324 :     case CREDITS_MODE_RATE :
1325 :     case CREDITS_MODE_SIZE :
1326 :     if (credits_pos == CREDITS_START)
1327 :     {
1328 :     bytes2 = (int)(bytes1 / twopass->credits_start_curve);
1329 :     }
1330 :     else // CREDITS_END
1331 :     {
1332 :     bytes2 = (int)(bytes1 / twopass->credits_end_curve);
1333 :     }
1334 :    
1335 :     frame->intra = -1;
1336 :     break;
1337 :    
1338 :     case CREDITS_MODE_QUANT :
1339 :     if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1340 :     {
1341 :     frame->quant = frame->intra ?
1342 :     codec->config.credits_quant_i :
1343 :     codec->config.credits_quant_p;
1344 :     }
1345 :     else
1346 :     {
1347 :     frame->quant = codec->config.credits_quant_p;
1348 :     frame->intra = -1;
1349 :     }
1350 :    
1351 :     twopass->bytes1 = bytes1;
1352 :     twopass->bytes2 = bytes1;
1353 :     twopass->desired_bytes2 = bytes1;
1354 :     return ICERR_OK;
1355 :     }
1356 :     }
1357 :     else // DLG_MODE_2PASS_2_EXT
1358 :     {
1359 :     bytes2 = twopass->nns2.bytes;
1360 :     }
1361 :     }
1362 :     else // Foxer: apply curve compression outside credits
1363 :     {
1364 :     double dbytes, curve_temp;
1365 :    
1366 :     bytes2 = (codec->config.mode == DLG_MODE_2PASS_2_INT) ? bytes1 : twopass->nns2.bytes;
1367 :    
1368 :     if (frame->intra)
1369 :     {
1370 :     dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
1371 :     twopass->movie_curve;
1372 :     }
1373 :     else
1374 :     {
1375 :     dbytes = bytes2 / twopass->movie_curve;
1376 :     }
1377 :    
1378 :     // spread the compression error across payback_delay frames
1379 :     if (codec->config.bitrate_payback_method == 0)
1380 :     {
1381 :     bytes2 = (int)(curve_comp_error / codec->config.bitrate_payback_delay);
1382 :     }
1383 :     else
1384 :     {
1385 :     bytes2 = (int)(curve_comp_error * dbytes /
1386 :     twopass->average_frame / codec->config.bitrate_payback_delay);
1387 :    
1388 :     if (labs(bytes2) > fabs(curve_comp_error))
1389 :     {
1390 :     bytes2 = (int)curve_comp_error;
1391 :     }
1392 :     }
1393 :    
1394 :     curve_comp_error -= bytes2;
1395 :    
1396 : h 61 if (codec->config.use_alt_curve)
1397 :     {
1398 :     if (!frame->intra)
1399 :     {
1400 :     if (dbytes > twopass->average_frame)
1401 :     {
1402 :     if (dbytes >= twopass->alt_curve_high)
1403 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
1404 :     else
1405 :     {
1406 :     switch(codec->config.alt_curve_type)
1407 :     {
1408 :     case 2:
1409 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1410 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
1411 :     break;
1412 :     case 1:
1413 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1414 :     (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
1415 :     break;
1416 :     case 0:
1417 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1418 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
1419 :     }
1420 :     }
1421 :     }
1422 :     else
1423 :     {
1424 :     if (dbytes <= twopass->alt_curve_low)
1425 :     curve_temp = dbytes;
1426 :     else
1427 :     {
1428 :     switch(codec->config.alt_curve_type)
1429 :     {
1430 :     case 2:
1431 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1432 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
1433 :     break;
1434 :     case 1:
1435 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1436 :     (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
1437 :     break;
1438 :     case 0:
1439 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
1440 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
1441 :     }
1442 :     }
1443 :     }
1444 :     curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
1445 :    
1446 :     bytes2 += ((int)curve_temp);
1447 :     curve_comp_error += curve_temp - ((int)curve_temp);
1448 :     }
1449 :     else
1450 :     {
1451 :     curve_comp_error += dbytes - ((int)dbytes);
1452 :     bytes2 += ((int)dbytes);
1453 :     }
1454 :     }
1455 :     else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
1456 : Isibaar 3 !frame->intra)
1457 :     {
1458 :     if (dbytes > twopass->average_frame)
1459 :     {
1460 :     curve_temp = twopass->curve_comp_scale *
1461 :     ((double)dbytes + (twopass->average_frame - dbytes) *
1462 :     codec->config.curve_compression_high / 100.0);
1463 :     }
1464 :     else
1465 :     {
1466 :     curve_temp = twopass->curve_comp_scale *
1467 :     ((double)dbytes + (twopass->average_frame - dbytes) *
1468 :     codec->config.curve_compression_low / 100.0);
1469 :     }
1470 :    
1471 :     bytes2 += ((int)curve_temp);
1472 :     curve_comp_error += curve_temp - ((int)curve_temp);
1473 :     }
1474 :     else
1475 :     {
1476 :     curve_comp_error += dbytes - ((int)dbytes);
1477 :     bytes2 += ((int)dbytes);
1478 :     }
1479 :    
1480 :     // cap bytes2 to first pass size, lowers number of quant=1 frames
1481 :     if (bytes2 > bytes1)
1482 :     {
1483 :     curve_comp_error += bytes2 - bytes1;
1484 :     bytes2 = bytes1;
1485 :     }
1486 :     else if (bytes2 < 1)
1487 :     {
1488 :     curve_comp_error += --bytes2;
1489 :     bytes2 = 1;
1490 :     }
1491 :     }
1492 :    
1493 :     twopass->desired_bytes2 = bytes2;
1494 :    
1495 :     // Foxer: scale overflow in relation to average size, so smaller frames don't get
1496 :     // too much/little bitrate
1497 :     overflow = (int)((double)overflow * bytes2 / twopass->average_frame);
1498 :    
1499 :     // Foxer: reign in overflow with huge frames
1500 :     if (labs(overflow) > labs(twopass->overflow))
1501 :     {
1502 :     overflow = twopass->overflow;
1503 :     }
1504 :    
1505 :     // Foxer: make sure overflow doesn't run away
1506 :     if (overflow > bytes2 * 6 / 10)
1507 :     {
1508 :     bytes2 += (overflow <= bytes2) ? bytes2 * 6 / 10 : overflow * 6 / 10;
1509 :     }
1510 :     else if (overflow < bytes2 * -6 / 10)
1511 :     {
1512 :     bytes2 += bytes2 * -6 / 10;
1513 :     }
1514 :     else
1515 :     {
1516 :     bytes2 += overflow;
1517 :     }
1518 :    
1519 :     if (bytes2 < 1)
1520 :     {
1521 :     bytes2 = 1;
1522 :     }
1523 :    
1524 :     twopass->bytes1 = bytes1;
1525 :     twopass->bytes2 = bytes2;
1526 :    
1527 :     // very 'simple' quant<->filesize relationship
1528 :     frame->quant = ((twopass->nns1.quant & ~NNSTATS_KEYFRAME) * bytes1) / bytes2;
1529 :    
1530 :     if (frame->quant < 1)
1531 :     {
1532 :     frame->quant = 1;
1533 :     }
1534 :     else if (frame->quant > 31)
1535 :     {
1536 :     frame->quant = 31;
1537 :     }
1538 :     else if (!frame->intra)
1539 :     {
1540 :     // Foxer: aid desired quantizer precision by accumulating decision error
1541 :     quant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1542 :     bytes1) / bytes2) - frame->quant;
1543 :    
1544 :     if (quant_error[frame->quant] >= 1.0)
1545 :     {
1546 :     quant_error[frame->quant] -= 1.0;
1547 :     ++frame->quant;
1548 :     }
1549 :     }
1550 :    
1551 :     // we're done with credits
1552 :     if (codec_is_in_credits(&codec->config, codec->framenum))
1553 :     {
1554 :     return ICERR_OK;
1555 :     }
1556 :    
1557 :     if (frame->intra)
1558 :     {
1559 :     if (frame->quant < codec->config.min_iquant)
1560 :     {
1561 :     frame->quant = codec->config.min_iquant;
1562 :     DEBUG2P("I-frame quantizer raised");
1563 :     }
1564 :     if (frame->quant > codec->config.max_iquant)
1565 :     {
1566 :     frame->quant = codec->config.max_iquant;
1567 :     DEBUG2P("I-frame quantizer lowered");
1568 :     }
1569 :     }
1570 :     else
1571 :     {
1572 : h 30 if (frame->quant > codec->config.max_pquant)
1573 : Isibaar 3 {
1574 : h 30 frame->quant = codec->config.max_pquant;
1575 : Isibaar 3 }
1576 : h 30 if (frame->quant < codec->config.min_pquant)
1577 : Isibaar 3 {
1578 : h 30 frame->quant = codec->config.min_pquant;
1579 : Isibaar 3 }
1580 :    
1581 :     // subsequent frame quants can only be +- 2
1582 :     if (last_quant)
1583 :     {
1584 :     if (frame->quant > last_quant + 2)
1585 :     {
1586 :     frame->quant = last_quant + 2;
1587 :     DEBUG2P("P-frame quantizer prevented from rising too steeply");
1588 :     }
1589 :     if (frame->quant < last_quant - 2)
1590 :     {
1591 :     frame->quant = last_quant - 2;
1592 :     DEBUG2P("P-frame quantizer prevented from falling too steeply");
1593 :     }
1594 :     }
1595 :     }
1596 :    
1597 :     last_quant = frame->quant;
1598 :    
1599 : h 30 if (codec->config.quant_type == QUANT_MODE_MOD)
1600 :     {
1601 :     frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;
1602 :     frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1603 :     }
1604 :    
1605 : Isibaar 3 return ICERR_OK;
1606 :     }
1607 :    
1608 :    
1609 :     int codec_2pass_update(CODEC* codec, XVID_ENC_FRAME* frame, XVID_ENC_STATS* stats)
1610 :     {
1611 :     static __int64 total_size;
1612 :    
1613 :     NNSTATS nns1;
1614 :     DWORD wrote;
1615 : h 30 char* quant_type;
1616 : Isibaar 3
1617 :     if (codec->framenum == 0)
1618 :     {
1619 :     total_size = 0;
1620 :     }
1621 : h 30
1622 :     quant_type = (frame->general & XVID_H263QUANT) ? "H.263" :
1623 : h 39 ((frame->general & XVID_MPEGQUANT) && (frame->general & XVID_CUSTOM_QMATRIX)) ?
1624 :     "Cust" : "MPEG";
1625 : h 30
1626 : Isibaar 3 switch (codec->config.mode)
1627 :     {
1628 :     case DLG_MODE_2PASS_1 :
1629 :     nns1.bytes = frame->length; // total bytes
1630 :     nns1.dd_v = stats->hlength; // header bytes
1631 :    
1632 :     nns1.dd_u = nns1.dd_y = 0;
1633 :     nns1.dk_v = nns1.dk_u = nns1.dk_y = 0;
1634 :     nns1.md_u = nns1.md_y = 0;
1635 :     nns1.mk_u = nns1.mk_y = 0;
1636 :    
1637 :     nns1.quant = stats->quant;
1638 :     if (frame->intra)
1639 :     {
1640 :     nns1.quant |= NNSTATS_KEYFRAME;
1641 :     }
1642 :     nns1.kblk = stats->kblks;
1643 :     nns1.mblk = stats->mblks;
1644 :     nns1.ublk = stats->ublks;
1645 :     nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1646 :    
1647 :     total_size += frame->length;
1648 : h 30
1649 :     DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, quant_type, stats->kblks, stats->mblks)
1650 : Isibaar 3
1651 :     if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS))
1652 :     {
1653 : h 61 DEBUGERR("stats1: WriteFile error");
1654 : Isibaar 3 return ICERR_ERROR;
1655 :     }
1656 :     break;
1657 :    
1658 :     case DLG_MODE_2PASS_2_INT :
1659 :     case DLG_MODE_2PASS_2_EXT :
1660 :     codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;
1661 : h 30 DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, codec_is_in_credits(&codec->config, codec->framenum))
1662 : Isibaar 3 break;
1663 :    
1664 :     default:
1665 :     break;
1666 :     }
1667 :    
1668 :     return ICERR_OK;
1669 :     }
1670 :    
1671 :    
1672 :     int codec_is_in_credits(CONFIG* config, int framenum)
1673 :     {
1674 :     if (config->credits_start)
1675 :     {
1676 :     if (framenum >= config->credits_start_begin &&
1677 :     framenum <= config->credits_start_end)
1678 :     {
1679 :     return CREDITS_START;
1680 :     }
1681 :     }
1682 :    
1683 :     if (config->credits_end)
1684 :     {
1685 :     if (framenum >= config->credits_end_begin &&
1686 :     framenum <= config->credits_end_end)
1687 :     {
1688 :     return CREDITS_END;
1689 :     }
1690 :     }
1691 :    
1692 :     return 0;
1693 :     }
1694 :    
1695 :    
1696 :     int codec_get_vbr_quant(CONFIG* config, int quality)
1697 :     {
1698 :     static float fquant_running = 0;
1699 :     static int my_quality = -1;
1700 :     int quant;
1701 :    
1702 :     // if quality changes, recalculate fquant (credits)
1703 :     if (quality != my_quality)
1704 :     {
1705 :     config->fquant = 0;
1706 :     }
1707 :    
1708 :     my_quality = quality;
1709 :    
1710 :     // desired quantiser = (maxQ-minQ)/100 * (100-qual) + minQ
1711 :     if (!config->fquant)
1712 :     {
1713 :     config->fquant =
1714 : h 30 ((float) (config->max_pquant - config->min_pquant) / 100) *
1715 : Isibaar 3 (100 - quality) +
1716 : h 30 (float) config->min_pquant;
1717 : Isibaar 3
1718 :     fquant_running = config->fquant;
1719 :     }
1720 :    
1721 : h 30 if (fquant_running < config->min_pquant)
1722 : Isibaar 3 {
1723 : h 30 fquant_running = (float) config->min_pquant;
1724 : Isibaar 3 }
1725 : h 30 else if(fquant_running > config->max_pquant)
1726 : Isibaar 3 {
1727 : h 30 fquant_running = (float) config->max_pquant;
1728 : Isibaar 3 }
1729 :    
1730 :     quant = (int) fquant_running;
1731 :    
1732 :     // add error between fquant and quant to fquant_running
1733 :     fquant_running += config->fquant - quant;
1734 :    
1735 :     return quant;
1736 :     }
1737 :    

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4