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

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