[svn] / branches / dev-api-3 / vfw / src / 2pass.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-3/vfw/src/2pass.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 109 - (view) (download)
Original Path: trunk/vfw/src/2pass.c

1 : h 102 /**************************************************************************
2 :     *
3 :     * XVID 2PASS CODE
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 109 * 07.04.2002 added max bitrate constraint, overflow controls (foxer)
27 : h 102 * 31.03.2002 inital version;
28 :     *
29 :     *************************************************************************/
30 :    
31 :     #include <windows.h>
32 :     #include <math.h>
33 :    
34 :     #include "2pass.h"
35 :    
36 :    
37 :     int codec_2pass_init(CODEC* codec)
38 :     {
39 :     TWOPASS *twopass = &codec->twopass;
40 :     DWORD version = -20;
41 :     DWORD read, wrote;
42 :    
43 :     int frames = 0, credits_frames = 0, i_frames = 0;
44 :     __int64 total_ext = 0, total = 0, i_total = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0;
45 :     __int64 desired = (__int64)codec->config.desired_size * 1024;
46 :    
47 :     double total1 = 0.0;
48 :     double total2 = 0.0;
49 :    
50 :     if (codec->config.hinted_me)
51 :     {
52 :     codec->twopass.hintstream = malloc(100000);
53 :    
54 :     if (codec->twopass.hintstream == NULL)
55 :     {
56 :     DEBUGERR("couldn't allocate memory for mv hints");
57 :     return ICERR_ERROR;
58 :     }
59 :     }
60 :    
61 :     switch (codec->config.mode)
62 :     {
63 :     case DLG_MODE_2PASS_1 :
64 :     twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
65 :     if (twopass->stats1 == INVALID_HANDLE_VALUE)
66 :     {
67 :     DEBUGERR("2pass init error - couldn't create stats1");
68 :     return ICERR_ERROR;
69 :     }
70 :     if (WriteFile(twopass->stats1, &version, sizeof(DWORD), &wrote, 0) == 0 || wrote != sizeof(DWORD))
71 :     {
72 :     CloseHandle(twopass->stats1);
73 :     twopass->stats1 = INVALID_HANDLE_VALUE;
74 :     DEBUGERR("2pass init error - couldn't write to stats1");
75 :     return ICERR_ERROR;
76 :     }
77 :     break;
78 :    
79 :     case DLG_MODE_2PASS_2_INT :
80 :     case DLG_MODE_2PASS_2_EXT :
81 :     twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
82 :     if (twopass->stats1 == INVALID_HANDLE_VALUE)
83 :     {
84 :     DEBUGERR("2pass init error - couldn't open stats1");
85 :     return ICERR_ERROR;
86 :     }
87 :     if (ReadFile(twopass->stats1, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))
88 :     {
89 :     CloseHandle(twopass->stats1);
90 :     twopass->stats1 = INVALID_HANDLE_VALUE;
91 :     DEBUGERR("2pass init error - couldn't read from stats1");
92 :     return ICERR_ERROR;
93 :     }
94 :     if (version != -20)
95 :     {
96 :     CloseHandle(twopass->stats1);
97 :     twopass->stats1 = INVALID_HANDLE_VALUE;
98 :     DEBUGERR("2pass init error - wrong .stats version");
99 :     return ICERR_ERROR;
100 :     }
101 :    
102 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
103 :     {
104 :     if (twopass->stats2 != INVALID_HANDLE_VALUE)
105 :     {
106 :     CloseHandle(twopass->stats2);
107 :     }
108 :    
109 :     twopass->stats2 = CreateFile(codec->config.stats2, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
110 :    
111 :     if (twopass->stats2 == INVALID_HANDLE_VALUE)
112 :     {
113 :     CloseHandle(twopass->stats1);
114 :     twopass->stats1 = INVALID_HANDLE_VALUE;
115 :     DEBUGERR("2pass init error - couldn't open stats2");
116 :     return ICERR_ERROR;
117 :     }
118 :     if (ReadFile(twopass->stats2, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))
119 :     {
120 :     CloseHandle(twopass->stats1);
121 :     twopass->stats1 = INVALID_HANDLE_VALUE;
122 :     CloseHandle(twopass->stats2);
123 :     twopass->stats2 = INVALID_HANDLE_VALUE;
124 :     DEBUGERR("2pass init error - couldn't read from stats2");
125 :     return ICERR_ERROR;
126 :     }
127 :     if (version != -20)
128 :     {
129 :     CloseHandle(twopass->stats1);
130 :     twopass->stats1 = INVALID_HANDLE_VALUE;
131 :     CloseHandle(twopass->stats2);
132 :     twopass->stats2 = INVALID_HANDLE_VALUE;
133 :     DEBUGERR("2pass init error - wrong .stats version");
134 :     return ICERR_ERROR;
135 :     }
136 :    
137 :     while (1)
138 :     {
139 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||
140 :     !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
141 :     {
142 :     DWORD err = GetLastError();
143 :    
144 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
145 :     {
146 :     break;
147 :     }
148 :     else
149 :     {
150 :     CloseHandle(twopass->stats1);
151 :     CloseHandle(twopass->stats2);
152 :     twopass->stats1 = INVALID_HANDLE_VALUE;
153 :     twopass->stats2 = INVALID_HANDLE_VALUE;
154 :     DEBUGERR("2pass init error - incomplete stats1/stats2 record?");
155 :     return ICERR_ERROR;
156 :     }
157 :     }
158 :    
159 :     if (!codec_is_in_credits(&codec->config, frames))
160 :     {
161 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
162 :     {
163 :     i_boost_total = twopass->nns2.bytes * codec->config.keyframe_boost / 100;
164 :     i_total += twopass->nns2.bytes;
165 :     ++i_frames;
166 :     }
167 :    
168 :     total += twopass->nns1.bytes;
169 :     total_ext += twopass->nns2.bytes;
170 :     }
171 :     else
172 :     ++credits_frames;
173 :    
174 :     ++frames;
175 :     }
176 :    
177 :     twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);
178 :     twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);
179 :    
180 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
181 :     SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
182 :    
183 :     // perform prepass to compensate for over/undersizing
184 :     frames = 0;
185 :    
186 :     if (codec->config.use_alt_curve)
187 :     {
188 :     twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;
189 :     twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;
190 :     twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;
191 :     twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;
192 :     if (codec->config.alt_curve_use_auto)
193 :     {
194 :     if (total > total_ext)
195 :     {
196 :     codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / ((double)total / (double)total_ext)) * (double)codec->config.alt_curve_auto_str / 100.0);
197 :     if (codec->config.alt_curve_min_rel_qual < 20)
198 :     codec->config.alt_curve_min_rel_qual = 20;
199 :     }
200 :     else
201 :     codec->config.alt_curve_min_rel_qual = 100;
202 :     }
203 :     twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
204 :     twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
205 :     if (codec->config.alt_curve_low_dist > 100)
206 :     {
207 :     switch(codec->config.alt_curve_type)
208 :     {
209 :     case 2: // Sine Curve (high aggressiveness)
210 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
211 :     sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
212 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
213 :     sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));
214 :     break;
215 :     case 1: // Linear (medium aggressiveness)
216 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
217 :     twopass->average_frame / twopass->alt_curve_low_diff);
218 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
219 :     twopass->average_frame / twopass->alt_curve_low_diff;
220 :     break;
221 :     case 0: // Cosine Curve (low aggressiveness)
222 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
223 :     (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));
224 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
225 :     (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
226 :     }
227 :     }
228 :     }
229 :    
230 :     while (1)
231 :     {
232 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||
233 :     !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
234 :     {
235 :     DWORD err = GetLastError();
236 :    
237 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
238 :     {
239 :     break;
240 :     }
241 :     else
242 :     {
243 :     CloseHandle(twopass->stats1);
244 :     CloseHandle(twopass->stats2);
245 :     twopass->stats1 = INVALID_HANDLE_VALUE;
246 :     twopass->stats2 = INVALID_HANDLE_VALUE;
247 :     DEBUGERR("2pass init error - incomplete stats1/stats2 record?");
248 :     return ICERR_ERROR;
249 :     }
250 :     }
251 :    
252 :     if (!codec_is_in_credits(&codec->config, frames) &&
253 :     !(twopass->nns1.quant & NNSTATS_KEYFRAME))
254 :     {
255 :     double dbytes = twopass->nns2.bytes / twopass->movie_curve;
256 :     total1 += dbytes;
257 :    
258 :     if (codec->config.use_alt_curve)
259 :     {
260 :     if (dbytes > twopass->average_frame)
261 :     {
262 :     if (dbytes >= twopass->alt_curve_high)
263 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
264 :     else
265 :     {
266 :     switch(codec->config.alt_curve_type)
267 :     {
268 :     case 2:
269 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
270 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
271 :     break;
272 :     case 1:
273 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
274 :     (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
275 :     break;
276 :     case 0:
277 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
278 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
279 :     }
280 :     }
281 :     }
282 :     else
283 :     {
284 :     if (dbytes <= twopass->alt_curve_low)
285 :     total2 += dbytes;
286 :     else
287 :     {
288 :     switch(codec->config.alt_curve_type)
289 :     {
290 :     case 2:
291 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
292 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
293 :     break;
294 :     case 1:
295 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
296 :     (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
297 :     break;
298 :     case 0:
299 :     total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
300 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
301 :     }
302 :     }
303 :     }
304 :     }
305 :     else
306 :     {
307 :     if (dbytes > twopass->average_frame)
308 :     {
309 :     total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
310 :     codec->config.curve_compression_high / 100.0);
311 :     }
312 :     else
313 :     {
314 :     total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
315 :     codec->config.curve_compression_low / 100.0);
316 :     }
317 :     }
318 :     }
319 :    
320 :     ++frames;
321 :     }
322 :    
323 :     twopass->curve_comp_scale = total1 / total2;
324 :    
325 :     if (!codec->config.use_alt_curve)
326 :     {
327 :     int asymmetric_average_frame;
328 :     char s[100];
329 :    
330 :     asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);
331 :     wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
332 :     DEBUG2P(s);
333 :     }
334 :    
335 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
336 :     SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
337 :     }
338 :     else // DLG_MODE_2PASS_2_INT
339 :     {
340 :     while (1)
341 :     {
342 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
343 :     {
344 :     DWORD err = GetLastError();
345 :    
346 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
347 :     {
348 :     break;
349 :     }
350 :     else
351 :     {
352 :     CloseHandle(twopass->stats1);
353 :     twopass->stats1 = INVALID_HANDLE_VALUE;
354 :     DEBUGERR("2pass init error - incomplete stats2 record?");
355 :     return ICERR_ERROR;
356 :     }
357 :     }
358 :    
359 :     if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)
360 :     {
361 :     start += twopass->nns1.bytes;
362 :     ++credits_frames;
363 :     }
364 :     else if (codec_is_in_credits(&codec->config, frames) == CREDITS_END)
365 :     {
366 :     end += twopass->nns1.bytes;
367 :     ++credits_frames;
368 :     }
369 :     else if (twopass->nns1.quant & NNSTATS_KEYFRAME)
370 :     {
371 :     i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;
372 :     total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;
373 :     ++i_frames;
374 :     }
375 :    
376 :     total += twopass->nns1.bytes;
377 :    
378 :     ++frames;
379 :     }
380 :    
381 :     // compensate for avi frame overhead
382 :     desired -= frames * 24;
383 :    
384 :     switch (codec->config.credits_mode)
385 :     {
386 :     case CREDITS_MODE_RATE :
387 :    
388 :     // credits curve = (total / desired_size) * (100 / credits_rate)
389 :     twopass->credits_start_curve = twopass->credits_end_curve =
390 :     ((double)total / desired) * ((double)100 / codec->config.credits_rate);
391 :    
392 :     start_curved = (__int64)(start / twopass->credits_start_curve);
393 :     end_curved = (__int64)(end / twopass->credits_end_curve);
394 :    
395 :     // movie curve = (total - credits) / (desired_size - curved credits)
396 :     twopass->movie_curve = (double)
397 :     (total - start - end) /
398 :     (desired - start_curved - end_curved);
399 :    
400 :     break;
401 :    
402 :     case CREDITS_MODE_QUANT :
403 :    
404 :     // movie curve = (total - credits) / (desired_size - credits)
405 :     twopass->movie_curve = (double)
406 :     (total - start - end) / (desired - start - end);
407 :    
408 :     // aid the average asymmetric frame calculation below
409 :     start_curved = start;
410 :     end_curved = end;
411 :    
412 :     break;
413 :    
414 :     case CREDITS_MODE_SIZE :
415 :    
416 :     // start curve = (start / start desired size)
417 :     twopass->credits_start_curve = (double)
418 :     (start / 1024) / codec->config.credits_start_size;
419 :    
420 :     // end curve = (end / end desired size)
421 :     twopass->credits_end_curve = (double)
422 :     (end / 1024) / codec->config.credits_end_size;
423 :    
424 :     start_curved = (__int64)(start / twopass->credits_start_curve);
425 :     end_curved = (__int64)(end / twopass->credits_end_curve);
426 :    
427 :     // movie curve = (total - credits) / (desired_size - curved credits)
428 :     twopass->movie_curve = (double)
429 :     (total - start - end) /
430 :     (desired - start_curved - end_curved);
431 :    
432 :     break;
433 :     }
434 :    
435 :     // average frame size = (desired - curved credits - curved keyframes) /
436 :     // (frames - credits frames - keyframes)
437 :     twopass->average_frame = (double)
438 :     (desired - start_curved - end_curved - (i_total / twopass->movie_curve)) /
439 :     (frames - credits_frames - i_frames);
440 :    
441 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
442 :    
443 :     // perform prepass to compensate for over/undersizing
444 :     frames = 0;
445 :    
446 :     if (codec->config.use_alt_curve)
447 :     {
448 :     twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;
449 :     twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;
450 :     twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;
451 :     twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;
452 :     if (codec->config.alt_curve_use_auto)
453 :     {
454 :     if (twopass->movie_curve > 1.0)
455 :     {
456 :     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);
457 :     if (codec->config.alt_curve_min_rel_qual < 20)
458 :     codec->config.alt_curve_min_rel_qual = 20;
459 :     }
460 :     else
461 :     codec->config.alt_curve_min_rel_qual = 100;
462 :     }
463 :     twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
464 :     twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
465 :     if (codec->config.alt_curve_low_dist > 100)
466 :     {
467 :     switch(codec->config.alt_curve_type)
468 :     {
469 :     case 2: // Sine Curve (high aggressiveness)
470 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
471 :     sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
472 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
473 :     sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));
474 :     break;
475 :     case 1: // Linear (medium aggressiveness)
476 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
477 :     twopass->average_frame / twopass->alt_curve_low_diff);
478 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
479 :     twopass->average_frame / twopass->alt_curve_low_diff;
480 :     break;
481 :     case 0: // Cosine Curve (low aggressiveness)
482 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
483 :     (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));
484 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
485 :     (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
486 :     }
487 :     }
488 :     }
489 :    
490 :     while (1)
491 :     {
492 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
493 :     {
494 :     DWORD err = GetLastError();
495 :    
496 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
497 :     {
498 :     break;
499 :     }
500 :     else
501 :     {
502 :     CloseHandle(twopass->stats1);
503 :     twopass->stats1 = INVALID_HANDLE_VALUE;
504 :     DEBUGERR("2pass init error - incomplete stats2 record?");
505 :     return ICERR_ERROR;
506 :     }
507 :     }
508 :    
509 :     if (!codec_is_in_credits(&codec->config, frames) &&
510 :     !(twopass->nns1.quant & NNSTATS_KEYFRAME))
511 :     {
512 :     double dbytes = twopass->nns1.bytes / twopass->movie_curve;
513 :     total1 += dbytes;
514 :    
515 :     if (codec->config.use_alt_curve)
516 :     {
517 :     if (dbytes > twopass->average_frame)
518 :     {
519 :     if (dbytes >= twopass->alt_curve_high)
520 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
521 :     else
522 :     {
523 :     switch(codec->config.alt_curve_type)
524 :     {
525 :     case 2:
526 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
527 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
528 :     break;
529 :     case 1:
530 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
531 :     (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
532 :     break;
533 :     case 0:
534 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
535 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
536 :     }
537 :     }
538 :     }
539 :     else
540 :     {
541 :     if (dbytes <= twopass->alt_curve_low)
542 :     total2 += dbytes;
543 :     else
544 :     {
545 :     switch(codec->config.alt_curve_type)
546 :     {
547 :     case 2:
548 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
549 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
550 :     break;
551 :     case 1:
552 :     total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
553 :     (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
554 :     break;
555 :     case 0:
556 :     total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
557 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
558 :     }
559 :     }
560 :     }
561 :     }
562 :     else
563 :     {
564 :     if (dbytes > twopass->average_frame)
565 :     {
566 :     total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
567 :     codec->config.curve_compression_high / 100.0);
568 :     }
569 :     else
570 :     {
571 :     total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
572 :     codec->config.curve_compression_low / 100.0);
573 :     }
574 :     }
575 :     }
576 :    
577 :     ++frames;
578 :     }
579 :    
580 :     twopass->curve_comp_scale = total1 / total2;
581 :    
582 :     if (!codec->config.use_alt_curve)
583 :     {
584 :     int asymmetric_average_frame;
585 :     char s[100];
586 :    
587 :     asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);
588 :     wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
589 :     DEBUG2P(s);
590 :     }
591 :    
592 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
593 :     }
594 :    
595 :     if (codec->config.use_alt_curve)
596 :     {
597 :     if (codec->config.alt_curve_use_auto_bonus_bias)
598 :     codec->config.alt_curve_bonus_bias = codec->config.alt_curve_min_rel_qual;
599 :    
600 :     twopass->curve_bias_bonus = (total1 - total2) * (double)codec->config.alt_curve_bonus_bias / 100.0 / (double)(frames - credits_frames - i_frames);
601 :     twopass->curve_comp_scale = ((total1 - total2) * (1.0 - (double)codec->config.alt_curve_bonus_bias / 100.0) + total2) / total2;
602 :    
603 :    
604 :     // special info for alt curve: bias bonus and quantizer thresholds,
605 :     {
606 :     double curve_temp, dbytes;
607 :     char s[100];
608 :     int i, newquant, percent;
609 :     int oldquant = 1;
610 :    
611 :     wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_frame));
612 :     DEBUG2P(s);
613 :    
614 :     wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));
615 :     DEBUG2P(s);
616 :    
617 :     for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)
618 :     {
619 :     dbytes = i;
620 :     if (dbytes > twopass->average_frame)
621 :     {
622 :     if (dbytes >= twopass->alt_curve_high)
623 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
624 :     else
625 :     {
626 :     switch(codec->config.alt_curve_type)
627 :     {
628 :     case 2:
629 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
630 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
631 :     break;
632 :     case 1:
633 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
634 :     (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
635 :     break;
636 :     case 0:
637 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
638 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
639 :     }
640 :     }
641 :     }
642 :     else
643 :     {
644 :     if (dbytes <= twopass->alt_curve_low)
645 :     curve_temp = dbytes;
646 :     else
647 :     {
648 :     switch(codec->config.alt_curve_type)
649 :     {
650 :     case 2:
651 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
652 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
653 :     break;
654 :     case 1:
655 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
656 :     (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
657 :     break;
658 :     case 0:
659 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
660 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
661 :     }
662 :     }
663 :     }
664 :    
665 :     if (twopass->movie_curve > 1.0)
666 :     dbytes *= twopass->movie_curve;
667 :    
668 :     newquant = (int)(dbytes * 2.0 / (curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus));
669 :     if (newquant > 1)
670 :     {
671 :     if (newquant != oldquant)
672 :     {
673 :     oldquant = newquant;
674 :     percent = (int)((i - twopass->average_frame) * 100.0 / twopass->average_frame);
675 :     wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);
676 :     DEBUG2P(s);
677 :     }
678 :     }
679 :     }
680 :     }
681 :     }
682 :    
683 :     twopass->overflow = 0;
684 :    
685 :     break;
686 :     }
687 :    
688 :     return ICERR_OK;
689 :     }
690 :    
691 :    
692 :     int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
693 :     {
694 :     static double quant_error[32];
695 :     static double curve_comp_error;
696 :     static int last_quant;
697 :    
698 :     TWOPASS * twopass = &codec->twopass;
699 :    
700 :     DWORD read;
701 :     int bytes1, bytes2;
702 :     int overflow;
703 :     int credits_pos;
704 : h 109 int capped_to_max_framesize = 0;
705 : h 102
706 :     if (codec->framenum == 0)
707 :     {
708 :     int i;
709 :    
710 :     for (i=0 ; i<32 ; ++i)
711 :     {
712 :     quant_error[i] = 0.0;
713 : h 105 twopass->quant_count[i] = 0;
714 : h 102 }
715 :    
716 :     curve_comp_error = 0.0;
717 :     last_quant = 0;
718 :     }
719 :    
720 :     if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))
721 :     {
722 :     DEBUGERR("2ndpass quant: couldn't read from stats1");
723 :     return ICERR_ERROR;
724 :     }
725 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
726 :     {
727 :     if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))
728 :     {
729 :     DEBUGERR("2ndpass quant: couldn't read from stats2");
730 :     return ICERR_ERROR;
731 :     }
732 :     }
733 :    
734 :     bytes1 = twopass->nns1.bytes;
735 :     overflow = twopass->overflow / 8;
736 :    
737 :     // override codec i-frame choice (reenable in credits)
738 :     frame->intra = (twopass->nns1.quant & NNSTATS_KEYFRAME);
739 :    
740 :     if (frame->intra)
741 :     {
742 :     overflow = 0;
743 :     }
744 :    
745 :     credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
746 :    
747 :     if (credits_pos)
748 :     {
749 :     if (codec->config.mode == DLG_MODE_2PASS_2_INT)
750 :     {
751 :     switch (codec->config.credits_mode)
752 :     {
753 :     case CREDITS_MODE_RATE :
754 :     case CREDITS_MODE_SIZE :
755 :     if (credits_pos == CREDITS_START)
756 :     {
757 :     bytes2 = (int)(bytes1 / twopass->credits_start_curve);
758 :     }
759 :     else // CREDITS_END
760 :     {
761 :     bytes2 = (int)(bytes1 / twopass->credits_end_curve);
762 :     }
763 :    
764 :     frame->intra = -1;
765 :     break;
766 :    
767 :     case CREDITS_MODE_QUANT :
768 :     if (codec->config.credits_quant_i != codec->config.credits_quant_p)
769 :     {
770 :     frame->quant = frame->intra ?
771 :     codec->config.credits_quant_i :
772 :     codec->config.credits_quant_p;
773 :     }
774 :     else
775 :     {
776 :     frame->quant = codec->config.credits_quant_p;
777 :     frame->intra = -1;
778 :     }
779 :    
780 :     twopass->bytes1 = bytes1;
781 :     twopass->bytes2 = bytes1;
782 :     twopass->desired_bytes2 = bytes1;
783 :     return ICERR_OK;
784 :     }
785 :     }
786 :     else // DLG_MODE_2PASS_2_EXT
787 :     {
788 :     bytes2 = twopass->nns2.bytes;
789 :     }
790 :     }
791 :     else // Foxer: apply curve compression outside credits
792 :     {
793 :     double dbytes, curve_temp;
794 :    
795 :     bytes2 = (codec->config.mode == DLG_MODE_2PASS_2_INT) ? bytes1 : twopass->nns2.bytes;
796 :    
797 :     if (frame->intra)
798 :     {
799 :     dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
800 :     twopass->movie_curve;
801 :     }
802 :     else
803 :     {
804 :     dbytes = bytes2 / twopass->movie_curve;
805 :     }
806 :    
807 :     // spread the compression error across payback_delay frames
808 :     if (codec->config.bitrate_payback_method == 0)
809 :     {
810 :     bytes2 = (int)(curve_comp_error / codec->config.bitrate_payback_delay);
811 :     }
812 :     else
813 :     {
814 :     bytes2 = (int)(curve_comp_error * dbytes /
815 :     twopass->average_frame / codec->config.bitrate_payback_delay);
816 :    
817 :     if (labs(bytes2) > fabs(curve_comp_error))
818 :     {
819 :     bytes2 = (int)curve_comp_error;
820 :     }
821 :     }
822 :    
823 :     curve_comp_error -= bytes2;
824 :    
825 :     if (codec->config.use_alt_curve)
826 :     {
827 :     if (!frame->intra)
828 :     {
829 :     if (dbytes > twopass->average_frame)
830 :     {
831 :     if (dbytes >= twopass->alt_curve_high)
832 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
833 :     else
834 :     {
835 :     switch(codec->config.alt_curve_type)
836 :     {
837 :     case 2:
838 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
839 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
840 :     break;
841 :     case 1:
842 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
843 :     (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
844 :     break;
845 :     case 0:
846 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
847 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
848 :     }
849 :     }
850 :     }
851 :     else
852 :     {
853 :     if (dbytes <= twopass->alt_curve_low)
854 :     curve_temp = dbytes;
855 :     else
856 :     {
857 :     switch(codec->config.alt_curve_type)
858 :     {
859 :     case 2:
860 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
861 :     sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
862 :     break;
863 :     case 1:
864 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
865 :     (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
866 :     break;
867 :     case 0:
868 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
869 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
870 :     }
871 :     }
872 :     }
873 :     curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
874 :    
875 :     bytes2 += ((int)curve_temp);
876 :     curve_comp_error += curve_temp - ((int)curve_temp);
877 :     }
878 :     else
879 :     {
880 :     curve_comp_error += dbytes - ((int)dbytes);
881 :     bytes2 += ((int)dbytes);
882 :     }
883 :     }
884 :     else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
885 :     !frame->intra)
886 :     {
887 :     if (dbytes > twopass->average_frame)
888 :     {
889 :     curve_temp = twopass->curve_comp_scale *
890 :     ((double)dbytes + (twopass->average_frame - dbytes) *
891 :     codec->config.curve_compression_high / 100.0);
892 :     }
893 :     else
894 :     {
895 :     curve_temp = twopass->curve_comp_scale *
896 :     ((double)dbytes + (twopass->average_frame - dbytes) *
897 :     codec->config.curve_compression_low / 100.0);
898 :     }
899 :    
900 :     bytes2 += ((int)curve_temp);
901 :     curve_comp_error += curve_temp - ((int)curve_temp);
902 :     }
903 :     else
904 :     {
905 :     curve_comp_error += dbytes - ((int)dbytes);
906 :     bytes2 += ((int)dbytes);
907 :     }
908 :    
909 :     // cap bytes2 to first pass size, lowers number of quant=1 frames
910 :     if (bytes2 > bytes1)
911 :     {
912 :     curve_comp_error += bytes2 - bytes1;
913 :     bytes2 = bytes1;
914 :     }
915 :     else if (bytes2 < 1)
916 :     {
917 :     curve_comp_error += --bytes2;
918 :     bytes2 = 1;
919 :     }
920 :     }
921 :    
922 :     twopass->desired_bytes2 = bytes2;
923 :    
924 :     // Foxer: scale overflow in relation to average size, so smaller frames don't get
925 :     // too much/little bitrate
926 :     overflow = (int)((double)overflow * bytes2 / twopass->average_frame);
927 :    
928 :     // Foxer: reign in overflow with huge frames
929 :     if (labs(overflow) > labs(twopass->overflow))
930 :     {
931 :     overflow = twopass->overflow;
932 :     }
933 :    
934 :     // Foxer: make sure overflow doesn't run away
935 : h 109 if (overflow > bytes2 * codec->config.twopass_max_overflow_improvement / 100)
936 : h 102 {
937 : h 109 bytes2 += (overflow <= bytes2) ? bytes2 * codec->config.twopass_max_overflow_improvement / 100 :
938 :     overflow * codec->config.twopass_max_overflow_improvement / 100;
939 : h 102 }
940 : h 109 else if (overflow < bytes2 * codec->config.twopass_max_overflow_degradation / -100)
941 : h 102 {
942 : h 109 bytes2 += bytes2 * codec->config.twopass_max_overflow_degradation / -100;
943 : h 102 }
944 :     else
945 :     {
946 :     bytes2 += overflow;
947 :     }
948 :    
949 : h 109 if (bytes2 > twopass->max_framesize)
950 :     {
951 :     capped_to_max_framesize = 1;
952 :     bytes2 = twopass->max_framesize;
953 :     }
954 :    
955 : h 102 if (bytes2 < 1)
956 :     {
957 :     bytes2 = 1;
958 :     }
959 :    
960 :     twopass->bytes1 = bytes1;
961 :     twopass->bytes2 = bytes2;
962 :    
963 :     // very 'simple' quant<->filesize relationship
964 :     frame->quant = ((twopass->nns1.quant & ~NNSTATS_KEYFRAME) * bytes1) / bytes2;
965 :    
966 :     if (frame->quant < 1)
967 :     {
968 :     frame->quant = 1;
969 :     }
970 :     else if (frame->quant > 31)
971 :     {
972 :     frame->quant = 31;
973 :     }
974 :     else if (!frame->intra)
975 :     {
976 :     // Foxer: aid desired quantizer precision by accumulating decision error
977 :     quant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
978 :     bytes1) / bytes2) - frame->quant;
979 :    
980 :     if (quant_error[frame->quant] >= 1.0)
981 :     {
982 :     quant_error[frame->quant] -= 1.0;
983 :     ++frame->quant;
984 :     }
985 :     }
986 :    
987 :     // we're done with credits
988 :     if (codec_is_in_credits(&codec->config, codec->framenum))
989 :     {
990 :     return ICERR_OK;
991 :     }
992 :    
993 :     if (frame->intra)
994 :     {
995 :     if (frame->quant < codec->config.min_iquant)
996 :     {
997 :     frame->quant = codec->config.min_iquant;
998 :     DEBUG2P("I-frame quantizer raised");
999 :     }
1000 :     if (frame->quant > codec->config.max_iquant)
1001 :     {
1002 :     frame->quant = codec->config.max_iquant;
1003 :     DEBUG2P("I-frame quantizer lowered");
1004 :     }
1005 :     }
1006 :     else
1007 :     {
1008 :     if (frame->quant > codec->config.max_pquant)
1009 :     {
1010 :     frame->quant = codec->config.max_pquant;
1011 :     }
1012 :     if (frame->quant < codec->config.min_pquant)
1013 :     {
1014 :     frame->quant = codec->config.min_pquant;
1015 :     }
1016 :    
1017 :     // subsequent frame quants can only be +- 2
1018 : h 109 if (last_quant && capped_to_max_framesize == 0)
1019 : h 102 {
1020 :     if (frame->quant > last_quant + 2)
1021 :     {
1022 :     frame->quant = last_quant + 2;
1023 :     DEBUG2P("P-frame quantizer prevented from rising too steeply");
1024 :     }
1025 :     if (frame->quant < last_quant - 2)
1026 :     {
1027 :     frame->quant = last_quant - 2;
1028 :     DEBUG2P("P-frame quantizer prevented from falling too steeply");
1029 :     }
1030 :     }
1031 :     }
1032 :    
1033 : h 109 if (capped_to_max_framesize == 0)
1034 :     last_quant = frame->quant;
1035 : h 102
1036 :     if (codec->config.quant_type == QUANT_MODE_MOD)
1037 :     {
1038 :     frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;
1039 :     frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1040 :     }
1041 :    
1042 :     return ICERR_OK;
1043 :     }
1044 :    
1045 :    
1046 :     int codec_2pass_update(CODEC* codec, XVID_ENC_FRAME* frame, XVID_ENC_STATS* stats)
1047 :     {
1048 :     static __int64 total_size;
1049 :    
1050 :     NNSTATS nns1;
1051 :     DWORD wrote;
1052 : h 105 int credits_pos;
1053 : h 102 char* quant_type;
1054 :    
1055 :     if (codec->framenum == 0)
1056 :     {
1057 :     total_size = 0;
1058 :     }
1059 :    
1060 :     quant_type = (frame->general & XVID_H263QUANT) ? "H.263" :
1061 :     ((frame->general & XVID_MPEGQUANT) && (frame->general & XVID_CUSTOM_QMATRIX)) ?
1062 :     "Cust" : "MPEG";
1063 :    
1064 :     switch (codec->config.mode)
1065 :     {
1066 :     case DLG_MODE_2PASS_1 :
1067 :     nns1.bytes = frame->length; // total bytes
1068 :     nns1.dd_v = stats->hlength; // header bytes
1069 :    
1070 :     nns1.dd_u = nns1.dd_y = 0;
1071 :     nns1.dk_v = nns1.dk_u = nns1.dk_y = 0;
1072 :     nns1.md_u = nns1.md_y = 0;
1073 :     nns1.mk_u = nns1.mk_y = 0;
1074 :    
1075 :     nns1.quant = stats->quant;
1076 :     if (frame->intra)
1077 :     {
1078 :     nns1.quant |= NNSTATS_KEYFRAME;
1079 :     }
1080 :     nns1.kblk = stats->kblks;
1081 :     nns1.mblk = stats->mblks;
1082 :     nns1.ublk = stats->ublks;
1083 :     nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1084 :    
1085 :     total_size += frame->length;
1086 :    
1087 :     DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, quant_type, stats->kblks, stats->mblks)
1088 :    
1089 :     if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS))
1090 :     {
1091 :     DEBUGERR("stats1: WriteFile error");
1092 :     return ICERR_ERROR;
1093 :     }
1094 :     break;
1095 :    
1096 :     case DLG_MODE_2PASS_2_INT :
1097 :     case DLG_MODE_2PASS_2_EXT :
1098 :     codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;
1099 : h 105
1100 :     credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1101 :     if (!credits_pos)
1102 :     codec->twopass.quant_count[frame->quant]++;
1103 :    
1104 :     DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
1105 : h 102 break;
1106 :    
1107 :     default:
1108 :     break;
1109 :     }
1110 :    
1111 :     return ICERR_OK;
1112 :     }
1113 :    
1114 : h 105 void codec_2pass_finish(CODEC* codec)
1115 :     {
1116 :     int i;
1117 :     char s[100];
1118 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT)
1119 :     {
1120 :     // output the quantizer distribution for this encode.
1121 : h 102
1122 : h 105 OutputDebugString("Quantizer distribution for 2nd pass:");
1123 :     for (i=1; i<=31; i++)
1124 :     {
1125 :     if (codec->twopass.quant_count[i])
1126 :     {
1127 :     wsprintf(s, "Q:%i:%i", i, codec->twopass.quant_count[i]);
1128 :     OutputDebugString(s);
1129 :     }
1130 :     }
1131 :     return;
1132 :     }
1133 :     }

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