[svn] / trunk / vfw / src / 2pass.c Repository:
ViewVC logotype

Annotation of /trunk/vfw/src/2pass.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 127 - (view) (download)

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

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