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

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