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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1053 - (view) (download)

1 : suxen_drol 889 /**************************************************************************
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 :     * 17.04.2002 changed 1st pass quant to always be 2 (2pass_update())
27 :     * 07.04.2002 added max bitrate constraint, overflow controls (foxer)
28 :     * 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, bframes = 0, pframes = 0, credits_frames = 0, i_frames = 0, recminbsize = 0, recminpsize = 0, recminisize = 0;
45 :     __int64 bframe_total_ext = 0, pframe_total_ext = 0, pframe_total = 0, bframe_total = 0, i_total = 0, i_total_ext = 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 :     double dbytes, dbytes2;
51 :    
52 :     /* ensure free() is called safely */
53 :     codec->twopass.hintstream = NULL;
54 :     twopass->nns1_array = NULL;
55 :     twopass->nns2_array = NULL;
56 :    
57 :     if (codec->config.hinted_me)
58 :     {
59 :     codec->twopass.hintstream = malloc(100000);
60 :    
61 :     if (codec->twopass.hintstream == NULL)
62 :     {
63 :     DEBUGERR("couldn't allocate memory for mv hints");
64 :     return ICERR_ERROR;
65 :     }
66 :     }
67 :    
68 :     switch (codec->config.mode)
69 :     {
70 :     case DLG_MODE_2PASS_1 :
71 :     twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
72 :     if (twopass->stats1 == INVALID_HANDLE_VALUE)
73 :     {
74 :     DEBUGERR("2pass init error - couldn't create stats1");
75 :     return ICERR_ERROR;
76 :     }
77 :     if (WriteFile(twopass->stats1, &version, sizeof(DWORD), &wrote, 0) == 0 || wrote != sizeof(DWORD))
78 :     {
79 :     CloseHandle(twopass->stats1);
80 :     twopass->stats1 = INVALID_HANDLE_VALUE;
81 :     DEBUGERR("2pass init error - couldn't write to stats1");
82 :     return ICERR_ERROR;
83 :     }
84 :     break;
85 :    
86 :     case DLG_MODE_2PASS_2_INT :
87 :     case DLG_MODE_2PASS_2_EXT :
88 :     twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
89 :     if (twopass->stats1 == INVALID_HANDLE_VALUE)
90 :     {
91 :     DEBUGERR("2pass init error - couldn't open stats1");
92 :     return ICERR_ERROR;
93 :     }
94 :     if (ReadFile(twopass->stats1, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))
95 :     {
96 :     CloseHandle(twopass->stats1);
97 :     twopass->stats1 = INVALID_HANDLE_VALUE;
98 :     DEBUGERR("2pass init error - couldn't read from stats1");
99 :     return ICERR_ERROR;
100 :     }
101 :     if (version != -20)
102 :     {
103 :     CloseHandle(twopass->stats1);
104 :     twopass->stats1 = INVALID_HANDLE_VALUE;
105 :     DEBUGERR("2pass init error - wrong .stats version");
106 :     return ICERR_ERROR;
107 :     }
108 :    
109 :     twopass->nns1_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);
110 :     twopass->nns2_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);
111 :     twopass->nns_array_size = 10240;
112 :     twopass->nns_array_length = 0;
113 :     twopass->nns_array_pos = 0;
114 :     twopass->nns_update_pos = 0;
115 :    
116 : edgomez 1053 /* read the stats file(s) into array(s) and reorder them so they */
117 :     /* correctly represent the frames that the encoder will receive. */
118 : suxen_drol 889 if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
119 :     {
120 :     if (twopass->stats2 != INVALID_HANDLE_VALUE)
121 :     {
122 :     CloseHandle(twopass->stats2);
123 :     }
124 :    
125 :     twopass->stats2 = CreateFile(codec->config.stats2, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
126 :    
127 :     if (twopass->stats2 == INVALID_HANDLE_VALUE)
128 :     {
129 :     CloseHandle(twopass->stats1);
130 :     twopass->stats1 = INVALID_HANDLE_VALUE;
131 :     DEBUGERR("2pass init error - couldn't open stats2");
132 :     return ICERR_ERROR;
133 :     }
134 :     if (ReadFile(twopass->stats2, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))
135 :     {
136 :     CloseHandle(twopass->stats1);
137 :     twopass->stats1 = INVALID_HANDLE_VALUE;
138 :     CloseHandle(twopass->stats2);
139 :     twopass->stats2 = INVALID_HANDLE_VALUE;
140 :     DEBUGERR("2pass init error - couldn't read from stats2");
141 :     return ICERR_ERROR;
142 :     }
143 :     if (version != -20)
144 :     {
145 :     CloseHandle(twopass->stats1);
146 :     twopass->stats1 = INVALID_HANDLE_VALUE;
147 :     CloseHandle(twopass->stats2);
148 :     twopass->stats2 = INVALID_HANDLE_VALUE;
149 :     DEBUGERR("2pass init error - wrong .stats version");
150 :     return ICERR_ERROR;
151 :     }
152 :    
153 :     while (1)
154 :     {
155 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||
156 :     !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
157 :     {
158 :     DWORD err = GetLastError();
159 :    
160 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
161 :     {
162 :     break;
163 :     }
164 :     else
165 :     {
166 :     CloseHandle(twopass->stats1);
167 :     CloseHandle(twopass->stats2);
168 :     twopass->stats1 = INVALID_HANDLE_VALUE;
169 :     twopass->stats2 = INVALID_HANDLE_VALUE;
170 :     DEBUGERR("2pass init error - incomplete stats1/stats2 record?");
171 :     return ICERR_ERROR;
172 :     }
173 :     }
174 :    
175 : edgomez 1053 /* increase the allocated memory if necessary */
176 : suxen_drol 889 if (frames >= twopass->nns_array_size)
177 :     {
178 :     twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array,
179 :     sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
180 :     twopass->nns2_array = (NNSTATS*)realloc(twopass->nns2_array,
181 :     sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
182 :     twopass->nns_array_size = twopass->nns_array_size * 5 / 4 + 1;
183 :     }
184 :    
185 : edgomez 1053 /* copy this frame's stats into the arrays */
186 : suxen_drol 889 memcpy (&twopass->nns1_array[frames], &twopass->nns1, sizeof(NNSTATS));
187 :     memcpy (&twopass->nns2_array[frames], &twopass->nns2, sizeof(NNSTATS));
188 :     frames++;
189 :     }
190 :    
191 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
192 :     SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
193 :     }
194 : edgomez 1053 else /* DLG_MODE_2PASS_2_INT */
195 : suxen_drol 889 {
196 :     while (1)
197 :     {
198 :     if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
199 :     {
200 :     DWORD err = GetLastError();
201 :    
202 :     if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
203 :     {
204 :     break;
205 :     }
206 :     else
207 :     {
208 :     CloseHandle(twopass->stats1);
209 :     twopass->stats1 = INVALID_HANDLE_VALUE;
210 :     DEBUGERR("2pass init error - incomplete stats2 record?");
211 :     return ICERR_ERROR;
212 :     }
213 :     }
214 :    
215 : edgomez 1053 /* increase the allocated memory if necessary */
216 : suxen_drol 889 if (frames >= twopass->nns_array_size)
217 :     {
218 :     twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array,
219 :     sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
220 :     twopass->nns_array_size = twopass->nns_array_size * 5 / 4 + 1;
221 :     }
222 :    
223 : edgomez 1053 /* copy this frame's stats into the array */
224 : suxen_drol 889 memcpy (&twopass->nns1_array[frames], &twopass->nns1, sizeof(NNSTATS));
225 :     frames++;
226 :     }
227 :    
228 :     SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
229 :     }
230 :     twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array, sizeof(NNSTATS) * frames);
231 :     twopass->nns2_array = (NNSTATS*)realloc(twopass->nns2_array, sizeof(NNSTATS) * frames);
232 :     twopass->nns_array_size = frames;
233 :     twopass->nns_array_length = frames;
234 :     frames = 0;
235 :    
236 : edgomez 1053 /* /* this isn't necessary with the current core. */
237 :     /* reorder the array(s) so they are in the order that they were received */
238 :     /* IPBBPBB to */
239 :     /* IBBPBBP */
240 : suxen_drol 889 for (i=0; i<twopass->nns_array_length; i++)
241 :     {
242 :     NNSTATS temp_nns, temp_nns2;
243 :     int k, num_bframes;
244 :     if (twopass->nns1_array[i].dd_v & NNSTATS_BFRAME)
245 :     {
246 :     num_bframes = 1;
247 :     for (k=i+1; k<twopass->nns_array_length; k++)
248 :     {
249 :     if (twopass->nns1_array[k].dd_v & NNSTATS_BFRAME)
250 :     num_bframes++;
251 :     else
252 :     k=twopass->nns_array_length;
253 :     }
254 :    
255 :     i--;
256 :     memcpy (&temp_nns, &twopass->nns1_array[i], sizeof(NNSTATS));
257 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
258 :     memcpy (&temp_nns2, &twopass->nns2_array[i], sizeof(NNSTATS));
259 :    
260 :     for (k=0; k<num_bframes; k++)
261 :     {
262 :     memcpy(&twopass->nns1_array[i], &twopass->nns1_array[i+1], sizeof(NNSTATS));
263 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
264 :     memcpy(&twopass->nns2_array[i], &twopass->nns2_array[i+1], sizeof(NNSTATS));
265 :     i++;
266 :     }
267 :    
268 :     memcpy(&twopass->nns1_array[i], &temp_nns, sizeof(NNSTATS));
269 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
270 :     memcpy(&twopass->nns2_array[i], &temp_nns2, sizeof(NNSTATS));
271 :     }
272 :     }
273 :     */
274 : edgomez 1053 /* continue with the initialization.. */
275 : suxen_drol 889 if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
276 :     {
277 :     while (1)
278 :     {
279 :     if (twopass->nns_array_pos >= twopass->nns_array_length)
280 :     {
281 :     twopass->nns_array_pos = 0;
282 :     break;
283 :     }
284 :    
285 :     memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
286 :     memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
287 :     twopass->nns_array_pos++;
288 :    
289 :     /* XXX: remove
290 :     skip unnecessary frames.
291 :     if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
292 :     twopass->nns1.dd_v & NNSTATS_PADFRAME ||
293 :     twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
294 :     continue;
295 :     */
296 :    
297 :     if (!codec_is_in_credits(&codec->config, frames))
298 :     {
299 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
300 :     {
301 :     i_total += twopass->nns2.bytes;
302 :     i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;
303 :     twopass->keyframe_locations[i_frames] = frames;
304 :     ++i_frames;
305 :     }
306 :     else
307 :     {
308 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
309 :     {
310 :     bframe_total += twopass->nns1.bytes;
311 :     bframe_total_ext += twopass->nns2.bytes;
312 :     bframes++;
313 :     }
314 :     else
315 :     {
316 :     pframe_total += twopass->nns1.bytes;
317 :     pframe_total_ext += twopass->nns2.bytes;
318 :     pframes++;
319 :     }
320 :     }
321 :     }
322 :     else
323 :     ++credits_frames;
324 :    
325 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
326 :     {
327 : edgomez 1053 /* this test needs to be corrected.. */
328 : suxen_drol 889 if (!(twopass->nns1.kblk + twopass->nns1.mblk))
329 :     recminisize = twopass->nns1.bytes;
330 :     }
331 :     else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
332 :     {
333 :     if (!(twopass->nns1.kblk + twopass->nns1.mblk))
334 :     recminbsize = twopass->nns1.bytes;
335 :     }
336 :     else
337 :     {
338 :     if (!(twopass->nns1.kblk + twopass->nns1.mblk))
339 :     recminpsize = twopass->nns1.bytes;
340 :     }
341 :    
342 :     ++frames;
343 :     }
344 :     twopass->keyframe_locations[i_frames] = frames;
345 :    
346 :     twopass->movie_curve = ((double)(bframe_total_ext + pframe_total_ext + i_boost_total) /
347 :     (bframe_total_ext + pframe_total_ext));
348 :    
349 :     if (bframes)
350 :     twopass->average_bframe = (double)bframe_total_ext / bframes / twopass->movie_curve;
351 :    
352 :     if (pframes)
353 :     twopass->average_pframe = (double)pframe_total_ext / pframes / twopass->movie_curve;
354 :     else
355 :     if (bframes)
356 : edgomez 1053 twopass->average_pframe = twopass->average_bframe; /* b-frame packed bitstream fix */
357 : suxen_drol 889 else
358 :     {
359 :     DEBUGERR("ERROR: No p-frames or b-frames were present in the 1st pass. Rate control cannot function properly!");
360 :     return ICERR_ERROR;
361 :     }
362 :    
363 :    
364 :    
365 : edgomez 1053 /* perform prepass to compensate for over/undersizing */
366 : suxen_drol 889 frames = 0;
367 :    
368 :     if (codec->config.use_alt_curve)
369 :     {
370 :     twopass->alt_curve_low = twopass->average_pframe - twopass->average_pframe * (double)codec->config.alt_curve_low_dist / 100.0;
371 :     twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
372 :     twopass->alt_curve_high = twopass->average_pframe + twopass->average_pframe * (double)codec->config.alt_curve_high_dist / 100.0;
373 :     twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
374 :     if (codec->config.alt_curve_use_auto)
375 :     {
376 :     if (bframe_total + pframe_total > bframe_total_ext + pframe_total_ext)
377 :     {
378 :     codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 /
379 :     ((double)(bframe_total + pframe_total) / (double)(bframe_total_ext + pframe_total_ext))) *
380 :     (double)codec->config.alt_curve_auto_str / 100.0);
381 :    
382 :     if (codec->config.alt_curve_min_rel_qual < 20)
383 :     codec->config.alt_curve_min_rel_qual = 20;
384 :     }
385 :     else
386 :     codec->config.alt_curve_min_rel_qual = 100;
387 :     }
388 :     twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
389 :     twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
390 :     if (codec->config.alt_curve_low_dist > 100)
391 :     {
392 :     switch(codec->config.alt_curve_type)
393 :     {
394 : edgomez 1053 case 2: /* Sine Curve (high aggressiveness) */
395 : suxen_drol 889 twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
396 :     sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
397 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
398 :     sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
399 :     break;
400 : edgomez 1053 case 1: /* Linear (medium aggressiveness) */
401 : suxen_drol 889 twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
402 :     twopass->average_pframe / twopass->alt_curve_low_diff);
403 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
404 :     twopass->average_pframe / twopass->alt_curve_low_diff;
405 :     break;
406 : edgomez 1053 case 0: /* Cosine Curve (low aggressiveness) */
407 : suxen_drol 889 twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
408 :     (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));
409 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
410 :     (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
411 :     }
412 :     }
413 :     }
414 :    
415 :     while (1)
416 :     {
417 :     if (twopass->nns_array_pos >= twopass->nns_array_length)
418 :     {
419 :     twopass->nns_array_pos = 0;
420 :     break;
421 :     }
422 :    
423 :     memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
424 :     memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
425 :     twopass->nns_array_pos++;
426 :    
427 :     if (frames == 0)
428 :     {
429 :     twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
430 :     twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
431 :     twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
432 :     if (recminbsize > twopass->minbsize)
433 :     twopass->minbsize = recminbsize;
434 :     if (recminpsize > twopass->minpsize)
435 :     twopass->minpsize = recminpsize;
436 :     if (recminisize > twopass->minisize)
437 :     twopass->minisize = recminisize;
438 :     }
439 :    
440 :     /* XXX: remove
441 :     skip unnecessary frames.
442 :     if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
443 :     twopass->nns1.dd_v & NNSTATS_PADFRAME ||
444 :     twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
445 :     continue;
446 :     */
447 :    
448 :     if (!codec_is_in_credits(&codec->config, frames) &&
449 :     !(twopass->nns1.quant & NNSTATS_KEYFRAME))
450 :     {
451 :     dbytes = twopass->nns2.bytes / twopass->movie_curve;
452 :     total1 += dbytes;
453 :    
454 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
455 :     dbytes *= twopass->average_pframe / twopass->average_bframe;
456 :    
457 :     if (codec->config.use_alt_curve)
458 :     {
459 :     if (dbytes > twopass->average_pframe)
460 :     {
461 :     if (dbytes >= twopass->alt_curve_high)
462 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
463 :     else
464 :     {
465 :     switch(codec->config.alt_curve_type)
466 :     {
467 :     case 2:
468 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
469 :     sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
470 :     break;
471 :     case 1:
472 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
473 :     (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
474 :     break;
475 :     case 0:
476 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
477 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
478 :     }
479 :     }
480 :     }
481 :     else
482 :     {
483 :     if (dbytes <= twopass->alt_curve_low)
484 :     dbytes2 = dbytes;
485 :     else
486 :     {
487 :     switch(codec->config.alt_curve_type)
488 :     {
489 :     case 2:
490 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
491 :     sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
492 :     break;
493 :     case 1:
494 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
495 :     (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
496 :     break;
497 :     case 0:
498 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
499 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
500 :     }
501 :     }
502 :     }
503 :     }
504 :     else
505 :     {
506 :     if (dbytes > twopass->average_pframe)
507 :     {
508 :     dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
509 :     codec->config.curve_compression_high / 100.0);
510 :     }
511 :     else
512 :     {
513 :     dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
514 :     codec->config.curve_compression_low / 100.0);
515 :     }
516 :     }
517 :    
518 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
519 :     {
520 :     dbytes2 *= twopass->average_bframe / twopass->average_pframe;
521 :     if (dbytes2 < twopass->minbsize)
522 :     dbytes2 = twopass->minbsize;
523 :     }
524 :     else
525 :     {
526 :     if (dbytes2 < twopass->minpsize)
527 :     dbytes2 = twopass->minpsize;
528 :     }
529 :    
530 :     total2 += dbytes2;
531 :     }
532 :    
533 :     ++frames;
534 :     }
535 :    
536 :     twopass->curve_comp_scale = total1 / total2;
537 :    
538 :     if (!codec->config.use_alt_curve)
539 :     {
540 :     int asymmetric_average_frame;
541 :     char s[100];
542 :    
543 :     asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
544 :     wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
545 :     DEBUG2P(s);
546 :     }
547 :     }
548 : edgomez 1053 else /* DLG_MODE_2PASS_2_INT */
549 : suxen_drol 889 {
550 :     while (1)
551 :     {
552 :     if (twopass->nns_array_pos >= twopass->nns_array_length)
553 :     {
554 :     twopass->nns_array_pos = 0;
555 :     break;
556 :     }
557 :    
558 :     memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
559 :     twopass->nns_array_pos++;
560 :    
561 :     /* XXX: remove
562 :     skip unnecessary frames.
563 :     if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
564 :     twopass->nns1.dd_v & NNSTATS_PADFRAME ||
565 :     twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
566 :     continue;
567 :     */
568 :    
569 :     if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)
570 :     {
571 :     start += twopass->nns1.bytes;
572 :     ++credits_frames;
573 :     }
574 :     else if (codec_is_in_credits(&codec->config, frames) == CREDITS_END)
575 :     {
576 :     end += twopass->nns1.bytes;
577 :     ++credits_frames;
578 :     }
579 :     else if (twopass->nns1.quant & NNSTATS_KEYFRAME)
580 :     {
581 :     i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;
582 :     twopass->keyframe_locations[i_frames] = frames;
583 :     ++i_frames;
584 :     }
585 :     else
586 :     {
587 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
588 :     {
589 :     bframe_total += twopass->nns1.bytes;
590 :     bframes++;
591 :     }
592 :     else
593 :     {
594 :     pframe_total += twopass->nns1.bytes;
595 :     pframes++;
596 :     }
597 :     }
598 :    
599 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
600 :     {
601 : edgomez 1053 /* this test needs to be corrected.. */
602 : suxen_drol 889 if (!(twopass->nns1.kblk + twopass->nns1.mblk))
603 :     recminisize = twopass->nns1.bytes;
604 :     }
605 :     else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
606 :     {
607 :     if (!(twopass->nns1.kblk + twopass->nns1.mblk))
608 :     recminbsize = twopass->nns1.bytes;
609 :     }
610 :     else
611 :     {
612 :     if (!(twopass->nns1.kblk + twopass->nns1.mblk))
613 :     recminpsize = twopass->nns1.bytes;
614 :     }
615 :    
616 :     ++frames;
617 :     }
618 :     twopass->keyframe_locations[i_frames] = frames;
619 :    
620 : edgomez 1053 /* compensate for avi frame overhead */
621 : suxen_drol 889 desired -= frames * 24;
622 :    
623 :     switch (codec->config.credits_mode)
624 :     {
625 :     case CREDITS_MODE_RATE :
626 :    
627 : edgomez 1053 /* credits curve = (total / desired_size) * (100 / credits_rate) */
628 : suxen_drol 889 twopass->credits_start_curve = twopass->credits_end_curve =
629 :     ((double)(bframe_total + pframe_total + i_total + start + end) / desired) *
630 :     ((double)100 / codec->config.credits_rate);
631 :    
632 :     start_curved = (__int64)(start / twopass->credits_start_curve);
633 :     end_curved = (__int64)(end / twopass->credits_end_curve);
634 :    
635 : edgomez 1053 /* movie curve = (total - credits) / (desired_size - curved credits) */
636 : suxen_drol 889 twopass->movie_curve = (double)
637 :     (bframe_total + pframe_total + i_total) /
638 :     (desired - start_curved - end_curved);
639 :    
640 :     break;
641 :    
642 :     case CREDITS_MODE_QUANT :
643 :    
644 : edgomez 1053 /* movie curve = (total - credits) / (desired_size - credits) */
645 : suxen_drol 889 twopass->movie_curve = (double)
646 :     (bframe_total + pframe_total + i_total) / (desired - start - end);
647 :    
648 : edgomez 1053 /* aid the average asymmetric frame calculation below */
649 : suxen_drol 889 start_curved = start;
650 :     end_curved = end;
651 :    
652 :     break;
653 :    
654 :     case CREDITS_MODE_SIZE :
655 :    
656 : edgomez 1053 /* start curve = (start / start desired size) */
657 : suxen_drol 889 twopass->credits_start_curve = (double)
658 :     (start / 1024) / codec->config.credits_start_size;
659 :    
660 : edgomez 1053 /* end curve = (end / end desired size) */
661 : suxen_drol 889 twopass->credits_end_curve = (double)
662 :     (end / 1024) / codec->config.credits_end_size;
663 :    
664 :     start_curved = (__int64)(start / twopass->credits_start_curve);
665 :     end_curved = (__int64)(end / twopass->credits_end_curve);
666 :    
667 : edgomez 1053 /* movie curve = (total - credits) / (desired_size - curved credits) */
668 : suxen_drol 889 twopass->movie_curve = (double)
669 :     (bframe_total + pframe_total + i_total) /
670 :     (desired - start_curved - end_curved);
671 :    
672 :     break;
673 :     }
674 :    
675 :     if (bframes)
676 :     twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve;
677 :    
678 :     if (pframes)
679 :     twopass->average_pframe = (double)pframe_total / pframes / twopass->movie_curve;
680 :     else
681 :     if (bframes)
682 : edgomez 1053 twopass->average_pframe = twopass->average_bframe; /* b-frame packed bitstream fix */
683 : suxen_drol 889 else
684 :     {
685 :     DEBUGERR("ERROR: No p-frames or b-frames were present in the 1st pass. Rate control cannot function properly!");
686 :     return ICERR_ERROR;
687 :     }
688 :    
689 :    
690 :    
691 : edgomez 1053 /* perform prepass to compensate for over/undersizing */
692 : suxen_drol 889 frames = 0;
693 :    
694 :     if (codec->config.use_alt_curve)
695 :     {
696 :     twopass->alt_curve_low = twopass->average_pframe - twopass->average_pframe * (double)codec->config.alt_curve_low_dist / 100.0;
697 :     twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
698 :     twopass->alt_curve_high = twopass->average_pframe + twopass->average_pframe * (double)codec->config.alt_curve_high_dist / 100.0;
699 :     twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
700 :     if (codec->config.alt_curve_use_auto)
701 :     {
702 :     if (twopass->movie_curve > 1.0)
703 :     {
704 :     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);
705 :     if (codec->config.alt_curve_min_rel_qual < 20)
706 :     codec->config.alt_curve_min_rel_qual = 20;
707 :     }
708 :     else
709 :     codec->config.alt_curve_min_rel_qual = 100;
710 :     }
711 :     twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
712 :     twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
713 :     if (codec->config.alt_curve_low_dist > 100)
714 :     {
715 :     switch(codec->config.alt_curve_type)
716 :     {
717 : edgomez 1053 case 2: /* Sine Curve (high aggressiveness) */
718 : suxen_drol 889 twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
719 :     sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
720 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
721 :     sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
722 :     break;
723 : edgomez 1053 case 1: /* Linear (medium aggressiveness) */
724 : suxen_drol 889 twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
725 :     twopass->average_pframe / twopass->alt_curve_low_diff);
726 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
727 :     twopass->average_pframe / twopass->alt_curve_low_diff;
728 :     break;
729 : edgomez 1053 case 0: /* Cosine Curve (low aggressiveness) */
730 : suxen_drol 889 twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
731 :     (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));
732 :     twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
733 :     (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
734 :     }
735 :     }
736 :     }
737 :    
738 :     while (1)
739 :     {
740 :     if (twopass->nns_array_pos >= twopass->nns_array_length)
741 :     {
742 :     twopass->nns_array_pos = 0;
743 :     break;
744 :     }
745 :    
746 :     memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
747 :     twopass->nns_array_pos++;
748 :    
749 :     if (frames == 0)
750 :     {
751 :     twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
752 :     twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
753 :     twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
754 :     if (recminbsize > twopass->minbsize)
755 :     twopass->minbsize = recminbsize;
756 :     if (recminpsize > twopass->minpsize)
757 :     twopass->minpsize = recminpsize;
758 :     if (recminisize > twopass->minisize)
759 :     twopass->minisize = recminisize;
760 :     }
761 :    
762 :     /* XXX: remove
763 :     skip unnecessary frames.
764 :     if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
765 :     twopass->nns1.dd_v & NNSTATS_PADFRAME ||
766 :     twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
767 :     continue;
768 :     */
769 :    
770 :     if (!codec_is_in_credits(&codec->config, frames) &&
771 :     !(twopass->nns1.quant & NNSTATS_KEYFRAME))
772 :     {
773 :     dbytes = twopass->nns1.bytes / twopass->movie_curve;
774 :     total1 += dbytes;
775 :    
776 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
777 :     dbytes *= twopass->average_pframe / twopass->average_bframe;
778 :    
779 :     if (codec->config.use_alt_curve)
780 :     {
781 :     if (dbytes > twopass->average_pframe)
782 :     {
783 :     if (dbytes >= twopass->alt_curve_high)
784 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
785 :     else
786 :     {
787 :     switch(codec->config.alt_curve_type)
788 :     {
789 :     case 2:
790 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
791 :     sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
792 :     break;
793 :     case 1:
794 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
795 :     (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
796 :     break;
797 :     case 0:
798 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
799 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
800 :     }
801 :     }
802 :     }
803 :     else
804 :     {
805 :     if (dbytes <= twopass->alt_curve_low)
806 :     dbytes2 = dbytes;
807 :     else
808 :     {
809 :     switch(codec->config.alt_curve_type)
810 :     {
811 :     case 2:
812 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
813 :     sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
814 :     break;
815 :     case 1:
816 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
817 :     (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
818 :     break;
819 :     case 0:
820 :     dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
821 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
822 :     }
823 :     }
824 :     }
825 :     }
826 :     else
827 :     {
828 :     if (dbytes > twopass->average_pframe)
829 :     {
830 :     dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
831 :     codec->config.curve_compression_high / 100.0);
832 :     }
833 :     else
834 :     {
835 :     dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
836 :     codec->config.curve_compression_low / 100.0);
837 :     }
838 :     }
839 :    
840 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
841 :     {
842 :     dbytes2 *= twopass->average_bframe / twopass->average_pframe;
843 :     if (dbytes2 < twopass->minbsize)
844 :     dbytes2 = twopass->minbsize;
845 :     }
846 :     else
847 :     {
848 :     if (dbytes2 < twopass->minpsize)
849 :     dbytes2 = twopass->minpsize;
850 :     }
851 :    
852 :     total2 += dbytes2;
853 :     }
854 :    
855 :     ++frames;
856 :     }
857 :    
858 :     twopass->curve_comp_scale = total1 / total2;
859 :    
860 :     if (!codec->config.use_alt_curve)
861 :     {
862 :     int asymmetric_average_frame;
863 :     char s[100];
864 :    
865 :     asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
866 :     wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
867 :     DEBUG2P(s);
868 :     }
869 :     }
870 :    
871 :     if (codec->config.use_alt_curve)
872 :     {
873 :     if (codec->config.alt_curve_use_auto_bonus_bias)
874 :     codec->config.alt_curve_bonus_bias = codec->config.alt_curve_min_rel_qual;
875 :    
876 :     twopass->curve_bias_bonus = (total1 - total2) * (double)codec->config.alt_curve_bonus_bias / 100.0 / (double)(frames - credits_frames - i_frames);
877 :     twopass->curve_comp_scale = ((total1 - total2) * (1.0 - (double)codec->config.alt_curve_bonus_bias / 100.0) + total2) / total2;
878 :    
879 :    
880 : edgomez 1053 /* special info for alt curve: bias bonus and quantizer thresholds, */
881 : suxen_drol 889 {
882 :     double curve_temp, dbytes;
883 :     char s[100];
884 :     int i, newquant, percent;
885 :     int oldquant = 1;
886 :    
887 :     wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_pframe));
888 :     DEBUG2P(s);
889 :    
890 :     wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));
891 :     DEBUG2P(s);
892 :    
893 :     for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)
894 :     {
895 :     dbytes = i;
896 :     if (dbytes > twopass->average_pframe)
897 :     {
898 :     if (dbytes >= twopass->alt_curve_high)
899 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
900 :     else
901 :     {
902 :     switch(codec->config.alt_curve_type)
903 :     {
904 :     case 2:
905 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
906 :     sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
907 :     break;
908 :     case 1:
909 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
910 :     (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
911 :     break;
912 :     case 0:
913 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
914 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
915 :     }
916 :     }
917 :     }
918 :     else
919 :     {
920 :     if (dbytes <= twopass->alt_curve_low)
921 :     curve_temp = dbytes;
922 :     else
923 :     {
924 :     switch(codec->config.alt_curve_type)
925 :     {
926 :     case 2:
927 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
928 :     sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
929 :     break;
930 :     case 1:
931 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
932 :     (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
933 :     break;
934 :     case 0:
935 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
936 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
937 :     }
938 :     }
939 :     }
940 :    
941 :     if (twopass->movie_curve > 1.0)
942 :     dbytes *= twopass->movie_curve;
943 :    
944 :     newquant = (int)(dbytes * 2.0 / (curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus));
945 :     if (newquant > 1)
946 :     {
947 :     if (newquant != oldquant)
948 :     {
949 :     oldquant = newquant;
950 :     percent = (int)((i - twopass->average_pframe) * 100.0 / twopass->average_pframe);
951 :     wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);
952 :     DEBUG2P(s);
953 :     }
954 :     }
955 :     }
956 :     }
957 :     }
958 :    
959 :     twopass->overflow = 0;
960 :     twopass->KFoverflow = 0;
961 :     twopass->KFoverflow_partial = 0;
962 :     twopass->KF_idx = 1;
963 :    
964 :     break;
965 :     }
966 :    
967 :     return ICERR_OK;
968 :     }
969 :    
970 :     // NOTE: codec_2pass_get_quant() should be called for all the frames that are in the stats file(s)
971 :     int codec_2pass_get_quant(CODEC* codec, xvid_enc_frame_t* frame)
972 :     {
973 :     static double bquant_error[32];
974 :     static double pquant_error[32];
975 :     static double curve_comp_error;
976 :     static int last_bquant, last_pquant;
977 :    
978 :     TWOPASS * twopass = &codec->twopass;
979 :    
980 :     // DWORD read;
981 :     int bytes1, bytes2;
982 :     int overflow;
983 :     int credits_pos;
984 :     int capped_to_max_framesize = 0;
985 :     int KFdistance, KF_min_size;
986 :    
987 :     if (codec->framenum == 0)
988 :     {
989 :     int i;
990 :    
991 :     for (i=0 ; i<32 ; ++i)
992 :     {
993 :     bquant_error[i] = 0.0;
994 :     pquant_error[i] = 0.0;
995 :     twopass->quant_count[i] = 0;
996 :     }
997 :    
998 :     curve_comp_error = 0.0;
999 :     last_bquant = 0;
1000 :     last_pquant = 0;
1001 :     }
1002 :    
1003 :     if (twopass->nns_array_pos >= twopass->nns_array_length)
1004 :     {
1005 : edgomez 1053 /* fix for VirtualDub 1.4.13 bframe handling */
1006 : suxen_drol 889 if (codec->config.max_bframes > 0 &&
1007 :     codec->framenum < twopass->nns_array_length + codec->config.max_bframes)
1008 :     {
1009 :     frame->type = XVID_TYPE_BVOP;
1010 :     frame->quant = 2; /* XXX: ugly eof fix */
1011 :     return ICERR_OK;
1012 :     }
1013 :     else
1014 :     {
1015 :     DEBUGERR("ERROR: VIDEO EXCEEDS 1ST PASS!!!");
1016 :     return ICERR_ERROR;
1017 :     }
1018 :     }
1019 :    
1020 :     memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
1021 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
1022 :     memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
1023 :     twopass->nns_array_pos++;
1024 :    
1025 :     bytes1 = twopass->nns1.bytes;
1026 :    
1027 :     /* XXX: remove
1028 :     skip unnecessary frames.
1029 :     if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME)
1030 :     {
1031 :     twopass->bytes1 = bytes1;
1032 :     twopass->bytes2 = bytes1;
1033 :     twopass->desired_bytes2 = bytes1;
1034 :     frame->intra = 3;
1035 :     return ICERR_OK;
1036 :     }
1037 :     else if (twopass->nns1.dd_v & NNSTATS_PADFRAME)
1038 :     {
1039 :     twopass->bytes1 = bytes1;
1040 :     twopass->bytes2 = bytes1;
1041 :     twopass->desired_bytes2 = bytes1;
1042 :     frame->intra = 4;
1043 :     return ICERR_OK;
1044 :     }
1045 :     else if (twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
1046 :     {
1047 :     twopass->bytes1 = bytes1;
1048 :     twopass->bytes2 = bytes1;
1049 :     twopass->desired_bytes2 = bytes1;
1050 :     frame->intra = 5;
1051 :     return ICERR_OK;
1052 :     } */
1053 :    
1054 :     overflow = twopass->overflow / 8;
1055 :    
1056 :     // override codec i-frame choice (reenable in credits)
1057 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1058 :     {
1059 :     frame->type = XVID_TYPE_IVOP;
1060 :     overflow = 0;
1061 :     }
1062 :     else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1063 :     {
1064 :     frame->type = XVID_TYPE_BVOP;
1065 :     }
1066 :     else
1067 :     {
1068 :     frame->type = XVID_TYPE_PVOP;
1069 :     }
1070 :    
1071 :     credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1072 :    
1073 :     if (credits_pos)
1074 :     {
1075 :     if (codec->config.mode == DLG_MODE_2PASS_2_INT)
1076 :     {
1077 :     switch (codec->config.credits_mode)
1078 :     {
1079 :     case CREDITS_MODE_RATE :
1080 :     case CREDITS_MODE_SIZE :
1081 :     if (credits_pos == CREDITS_START)
1082 :     {
1083 :     bytes2 = (int)(bytes1 / twopass->credits_start_curve);
1084 :     }
1085 : edgomez 1053 else /* CREDITS_END */
1086 : suxen_drol 889 {
1087 :     bytes2 = (int)(bytes1 / twopass->credits_end_curve);
1088 :     }
1089 :    
1090 :     frame->type = XVID_TYPE_AUTO;
1091 :     break;
1092 :    
1093 :     case CREDITS_MODE_QUANT :
1094 :     if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1095 :     {
1096 :     frame->quant = (frame->type==XVID_TYPE_IVOP) ?
1097 :     codec->config.credits_quant_i :
1098 :     codec->config.credits_quant_p;
1099 :     }
1100 :     else
1101 :     {
1102 :     frame->quant = codec->config.credits_quant_p;
1103 :     frame->type = XVID_TYPE_AUTO;
1104 :     }
1105 :    
1106 :     twopass->bytes1 = bytes1;
1107 :     twopass->bytes2 = bytes1;
1108 :     twopass->desired_bytes2 = bytes1;
1109 :     return ICERR_OK;
1110 :     }
1111 :     }
1112 : edgomez 1053 else /* DLG_MODE_2PASS_2_EXT */
1113 : suxen_drol 889 {
1114 :     if (codec->config.credits_mode == CREDITS_MODE_QUANT)
1115 :     {
1116 :     if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1117 :     {
1118 :     frame->quant = (frame->type == XVID_TYPE_IVOP) ?
1119 :     codec->config.credits_quant_i :
1120 :     codec->config.credits_quant_p;
1121 :     }
1122 :     else
1123 :     {
1124 :     frame->quant = codec->config.credits_quant_p;
1125 :     frame->type = XVID_TYPE_AUTO;
1126 :     }
1127 :    
1128 :     twopass->bytes1 = bytes1;
1129 :     twopass->bytes2 = bytes1;
1130 :     twopass->desired_bytes2 = bytes1;
1131 :     return ICERR_OK;
1132 :     }
1133 :     else
1134 :     bytes2 = twopass->nns2.bytes;
1135 :     }
1136 :     }
1137 : edgomez 1053 else /* Foxer: apply curve compression outside credits */
1138 : suxen_drol 889 {
1139 :     double dbytes, curve_temp;
1140 :    
1141 :     bytes2 = (codec->config.mode == DLG_MODE_2PASS_2_INT) ? bytes1 : twopass->nns2.bytes;
1142 :    
1143 :     if (frame->type == XVID_TYPE_IVOP)
1144 :     {
1145 :     dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
1146 :     twopass->movie_curve;
1147 :     }
1148 :     else
1149 :     {
1150 :     dbytes = bytes2 / twopass->movie_curve;
1151 :     }
1152 :    
1153 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1154 :     dbytes *= twopass->average_pframe / twopass->average_bframe;
1155 :    
1156 : edgomez 1053 /* spread the compression error across payback_delay frames */
1157 : suxen_drol 889 if (codec->config.bitrate_payback_method == 0)
1158 :     {
1159 :     bytes2 = (int)(curve_comp_error / codec->config.bitrate_payback_delay);
1160 :     }
1161 :     else
1162 :     {
1163 :     bytes2 = (int)(curve_comp_error * dbytes /
1164 :     twopass->average_pframe / codec->config.bitrate_payback_delay);
1165 :    
1166 :     if (labs(bytes2) > fabs(curve_comp_error))
1167 :     {
1168 :     bytes2 = (int)curve_comp_error;
1169 :     }
1170 :     }
1171 :    
1172 :     curve_comp_error -= bytes2;
1173 :    
1174 :     if (codec->config.use_alt_curve)
1175 :     {
1176 :     if (frame->type != XVID_TYPE_IVOP)
1177 :     {
1178 :     if (dbytes > twopass->average_pframe)
1179 :     {
1180 :     if (dbytes >= twopass->alt_curve_high)
1181 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
1182 :     else
1183 :     {
1184 :     switch(codec->config.alt_curve_type)
1185 :     {
1186 :     case 2:
1187 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1188 :     sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
1189 :     break;
1190 :     case 1:
1191 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1192 :     (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
1193 :     break;
1194 :     case 0:
1195 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1196 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
1197 :     }
1198 :     }
1199 :     }
1200 :     else
1201 :     {
1202 :     if (dbytes <= twopass->alt_curve_low)
1203 :     curve_temp = dbytes;
1204 :     else
1205 :     {
1206 :     switch(codec->config.alt_curve_type)
1207 :     {
1208 :     case 2:
1209 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1210 :     sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
1211 :     break;
1212 :     case 1:
1213 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1214 :     (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
1215 :     break;
1216 :     case 0:
1217 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
1218 :     (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
1219 :     }
1220 :     }
1221 :     }
1222 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1223 :     curve_temp *= twopass->average_bframe / twopass->average_pframe;
1224 :    
1225 :     curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
1226 :    
1227 :     bytes2 += ((int)curve_temp);
1228 :     curve_comp_error += curve_temp - ((int)curve_temp);
1229 :     }
1230 :     else
1231 :     {
1232 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1233 :     dbytes *= twopass->average_bframe / twopass->average_pframe;
1234 :    
1235 :     bytes2 += ((int)dbytes);
1236 :     curve_comp_error += dbytes - ((int)dbytes);
1237 :     }
1238 :     }
1239 :     else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
1240 :     frame->type != XVID_TYPE_IVOP)
1241 :     {
1242 :     if (dbytes > twopass->average_pframe)
1243 :     {
1244 :     curve_temp = twopass->curve_comp_scale *
1245 :     ((double)dbytes + (twopass->average_pframe - dbytes) *
1246 :     codec->config.curve_compression_high / 100.0);
1247 :     }
1248 :     else
1249 :     {
1250 :     curve_temp = twopass->curve_comp_scale *
1251 :     ((double)dbytes + (twopass->average_pframe - dbytes) *
1252 :     codec->config.curve_compression_low / 100.0);
1253 :     }
1254 :    
1255 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1256 :     curve_temp *= twopass->average_bframe / twopass->average_pframe;
1257 :    
1258 :     bytes2 += ((int)curve_temp);
1259 :     curve_comp_error += curve_temp - ((int)curve_temp);
1260 :     }
1261 :     else
1262 :     {
1263 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1264 :     dbytes *= twopass->average_bframe / twopass->average_pframe;
1265 :    
1266 :     bytes2 += ((int)dbytes);
1267 :     curve_comp_error += dbytes - ((int)dbytes);
1268 :     }
1269 :    
1270 : edgomez 1053 /* cap bytes2 to first pass size, lowers number of quant=1 frames */
1271 : suxen_drol 889 if (bytes2 > bytes1)
1272 :     {
1273 :     curve_comp_error += bytes2 - bytes1;
1274 :     bytes2 = bytes1;
1275 :     }
1276 :     else
1277 :     {
1278 :     if (frame->type == XVID_TYPE_IVOP)
1279 :     {
1280 :     if (bytes2 < twopass->minisize)
1281 :     {
1282 :     curve_comp_error -= twopass->minisize - bytes2;
1283 :     bytes2 = twopass->minisize;
1284 :     }
1285 :     }
1286 :     else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1287 :     {
1288 :     if (bytes2 < twopass->minbsize)
1289 :     bytes2 = twopass->minbsize;
1290 :     }
1291 :     else
1292 :     {
1293 :     if (bytes2 < twopass->minpsize)
1294 :     bytes2 = twopass->minpsize;
1295 :     }
1296 :     }
1297 :     }
1298 :    
1299 :     twopass->desired_bytes2 = bytes2;
1300 :    
1301 :     // if this keyframe is too close to the next,
1302 :     // reduce it's byte allotment
1303 :     if (frame->type == XVID_TYPE_IVOP && !credits_pos)
1304 :     {
1305 :     KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1306 :     codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];
1307 :    
1308 :     if (KFdistance < codec->config.kftreshold)
1309 :     {
1310 :     KFdistance = KFdistance - codec->config.min_key_interval;
1311 :    
1312 :     if (KFdistance >= 0)
1313 :     {
1314 :     KF_min_size = bytes2 * (100 - codec->config.kfreduction) / 100;
1315 :     if (KF_min_size < 1)
1316 :     KF_min_size = 1;
1317 :    
1318 :     bytes2 = KF_min_size + (bytes2 - KF_min_size) * KFdistance /
1319 :     (codec->config.kftreshold - codec->config.min_key_interval);
1320 :    
1321 :     if (bytes2 < 1)
1322 :     bytes2 = 1;
1323 :     }
1324 :     }
1325 :     }
1326 :    
1327 :     // Foxer: scale overflow in relation to average size, so smaller frames don't get
1328 :     // too much/little bitrate
1329 :     overflow = (int)((double)overflow * bytes2 / twopass->average_pframe);
1330 :    
1331 :     // Foxer: reign in overflow with huge frames
1332 :     if (labs(overflow) > labs(twopass->overflow))
1333 :     {
1334 :     overflow = twopass->overflow;
1335 :     }
1336 :    
1337 :     // Foxer: make sure overflow doesn't run away
1338 :     if (overflow > bytes2 * codec->config.twopass_max_overflow_improvement / 100)
1339 :     {
1340 :     bytes2 += (overflow <= bytes2) ? bytes2 * codec->config.twopass_max_overflow_improvement / 100 :
1341 :     overflow * codec->config.twopass_max_overflow_improvement / 100;
1342 :     }
1343 :     else if (overflow < bytes2 * codec->config.twopass_max_overflow_degradation / -100)
1344 :     {
1345 :     bytes2 += bytes2 * codec->config.twopass_max_overflow_degradation / -100;
1346 :     }
1347 :     else
1348 :     {
1349 :     bytes2 += overflow;
1350 :     }
1351 :    
1352 :     if (bytes2 > twopass->max_framesize)
1353 :     {
1354 :     capped_to_max_framesize = 1;
1355 :     bytes2 = twopass->max_framesize;
1356 :     }
1357 :    
1358 :     // make sure to not scale below the minimum framesize
1359 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1360 :     {
1361 :     if (bytes2 < twopass->minisize)
1362 :     bytes2 = twopass->minisize;
1363 :     }
1364 :     else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1365 :     {
1366 :     if (bytes2 < twopass->minbsize)
1367 :     bytes2 = twopass->minbsize;
1368 :     }
1369 :     else
1370 :     {
1371 :     if (bytes2 < twopass->minpsize)
1372 :     bytes2 = twopass->minpsize;
1373 :     }
1374 :    
1375 :     twopass->bytes1 = bytes1;
1376 :     twopass->bytes2 = bytes2;
1377 :    
1378 :     // very 'simple' quant<->filesize relationship
1379 :     frame->quant = ((twopass->nns1.quant & ~NNSTATS_KEYFRAME) * bytes1) / bytes2;
1380 :    
1381 :     if (frame->quant < 1)
1382 :     {
1383 :     frame->quant = 1;
1384 :     }
1385 :     else if (frame->quant > 31)
1386 :     {
1387 :     frame->quant = 31;
1388 :     }
1389 :     else if (frame->type != XVID_TYPE_IVOP)
1390 :     {
1391 : edgomez 1053 /* Foxer: aid desired quantizer precision by accumulating decision error */
1392 : suxen_drol 889 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1393 :     {
1394 :     bquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1395 :     bytes1) / bytes2) - frame->quant;
1396 :    
1397 :     if (bquant_error[frame->quant] >= 1.0)
1398 :     {
1399 :     bquant_error[frame->quant] -= 1.0;
1400 :     ++frame->quant;
1401 :     }
1402 :     }
1403 :     else
1404 :     {
1405 :     pquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1406 :     bytes1) / bytes2) - frame->quant;
1407 :    
1408 :     if (pquant_error[frame->quant] >= 1.0)
1409 :     {
1410 :     pquant_error[frame->quant] -= 1.0;
1411 :     ++frame->quant;
1412 :     }
1413 :     }
1414 :     }
1415 :    
1416 :     // we're done with credits
1417 :     if (codec_is_in_credits(&codec->config, codec->framenum))
1418 :     {
1419 :     return ICERR_OK;
1420 :     }
1421 :    
1422 :     if (frame->type == XVID_TYPE_IVOP)
1423 :     {
1424 :     if (frame->quant < codec->config.min_iquant)
1425 :     {
1426 :     frame->quant = codec->config.min_iquant;
1427 :     DEBUG2P("I-frame quantizer raised");
1428 :     }
1429 :     if (frame->quant > codec->config.max_iquant)
1430 :     {
1431 :     frame->quant = codec->config.max_iquant;
1432 :     DEBUG2P("I-frame quantizer lowered");
1433 :     }
1434 :     }
1435 :     else
1436 :     {
1437 :     if (frame->quant > codec->config.max_pquant)
1438 :     {
1439 :     frame->quant = codec->config.max_pquant;
1440 :     }
1441 :     if (frame->quant < codec->config.min_pquant)
1442 :     {
1443 :     frame->quant = codec->config.min_pquant;
1444 :     }
1445 :    
1446 : edgomez 1053 /* subsequent frame quants can only be +- 2 */
1447 : suxen_drol 889 if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)
1448 :     {
1449 :     if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1450 :     {
1451 : edgomez 1053 /* this bframe quantizer variation */
1452 :     /* restriction needs to be redone. */
1453 : suxen_drol 889 if (frame->quant > last_bquant + 2)
1454 :     {
1455 :     frame->quant = last_bquant + 2;
1456 :     DEBUG2P("B-frame quantizer prevented from rising too steeply");
1457 :     }
1458 :     if (frame->quant < last_bquant - 2)
1459 :     {
1460 :     frame->quant = last_bquant - 2;
1461 :     DEBUG2P("B-frame quantizer prevented from falling too steeply");
1462 :     }
1463 :     }
1464 :     else
1465 :     {
1466 :     if (frame->quant > last_pquant + 2)
1467 :     {
1468 :     frame->quant = last_pquant + 2;
1469 :     DEBUG2P("P-frame quantizer prevented from rising too steeply");
1470 :     }
1471 :     if (frame->quant < last_pquant - 2)
1472 :     {
1473 :     frame->quant = last_pquant - 2;
1474 :     DEBUG2P("P-frame quantizer prevented from falling too steeply");
1475 :     }
1476 :     }
1477 :     }
1478 :     }
1479 :    
1480 :     if (capped_to_max_framesize == 0)
1481 :     {
1482 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1483 :     {
1484 :     last_bquant = frame->quant;
1485 :     last_pquant = frame->quant;
1486 :     }
1487 :     else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1488 :     last_bquant = frame->quant;
1489 :     else
1490 :     last_pquant = frame->quant;
1491 :     }
1492 :    
1493 :     /* XXX: vol/vop issues
1494 :     if (codec->config.quant_type == QUANT_MODE_MOD)
1495 :     {
1496 : edgomez 949 frame->general |= (frame->quant < 4) ? XVID_VOL_MPEGQUANT : XVID_H263QUANT;
1497 :     frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_VOL_MPEGQUANT;
1498 : suxen_drol 889 }
1499 :    
1500 :     if (codec->config.quant_type == QUANT_MODE_MOD_NEW)
1501 :     {
1502 : edgomez 949 frame->general |= (frame->quant < 4) ? XVID_H263QUANT : XVID_VOL_MPEGQUANT;
1503 :     frame->general &= (frame->quant < 4) ? ~XVID_VOL_MPEGQUANT : ~XVID_H263QUANT;
1504 : suxen_drol 889 }
1505 :     */
1506 :    
1507 :     return ICERR_OK;
1508 :     }
1509 :    
1510 :    
1511 :     int codec_2pass_update(CODEC* codec, xvid_enc_stats_t* stats)
1512 :     {
1513 :     static __int64 total_size;
1514 :    
1515 :     NNSTATS nns1;
1516 :     DWORD wrote;
1517 :     int credits_pos, tempdiv;
1518 :     char tmp[140];
1519 :     char* quant_type;
1520 :     char* frame_type;
1521 :    
1522 :     if (codec->twopass.nns_update_pos == 0)
1523 :     {
1524 :     total_size = 0;
1525 :     }
1526 :    
1527 : edgomez 949 quant_type = (stats->vol_flags & XVID_VOL_MPEGQUANT) ? "MPEG" : "H.263";
1528 : suxen_drol 889 if (stats->type == XVID_TYPE_IVOP)
1529 :     frame_type = "IVOP";
1530 :     else if (stats->type == XVID_TYPE_BVOP)
1531 :     frame_type = "BVOP";
1532 :     else
1533 :     frame_type = "PVOP";
1534 :    
1535 :     switch (codec->config.mode)
1536 :     {
1537 :     case DLG_MODE_2PASS_1 :
1538 : edgomez 1053 nns1.bytes = stats->length; /* total bytes */
1539 : suxen_drol 889 nns1.dd_v = 0;
1540 :     nns1.dd_u = nns1.dd_y = 0;
1541 :     nns1.dk_v = nns1.dk_u = nns1.dk_y = 0;
1542 :     nns1.md_u = nns1.md_y = 0;
1543 :     nns1.mk_u = nns1.mk_y = 0;
1544 :    
1545 :     // nns1.quant = stats->quant;
1546 : edgomez 1053 nns1.quant = 2; /* ugly fix for lumi masking in 1st pass returning new quant */
1547 : suxen_drol 889 nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1548 :    
1549 :     switch(stats->type)
1550 :     {
1551 :     case XVID_TYPE_IVOP :
1552 :     nns1.quant |= NNSTATS_KEYFRAME;
1553 :     break;
1554 :    
1555 :     case XVID_TYPE_BVOP :
1556 :     nns1.dd_v |= NNSTATS_BFRAME;
1557 :     break;
1558 :    
1559 :     case XVID_TYPE_PVOP :
1560 :     case XVID_TYPE_SVOP :
1561 :     break;
1562 :     }
1563 :     nns1.kblk = stats->kblks;
1564 :     nns1.mblk = stats->mblks;
1565 :     nns1.ublk = stats->ublks;
1566 :    
1567 :     total_size += stats->length;
1568 :    
1569 :     DEBUG1ST(stats->length, (int)total_size/1024, frame_type, stats->quant, quant_type, stats->kblks, stats->mblks)
1570 :    
1571 :    
1572 :     if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS))
1573 :     {
1574 :     DEBUGERR("stats1: WriteFile error");
1575 :     return ICERR_ERROR;
1576 :     }
1577 :     break;
1578 :    
1579 :     case DLG_MODE_2PASS_2_INT :
1580 :     case DLG_MODE_2PASS_2_EXT :
1581 :     credits_pos = codec_is_in_credits(&codec->config, codec->twopass.nns_update_pos);
1582 :     if (!credits_pos)
1583 :     {
1584 :     codec->twopass.quant_count[stats->quant]++;
1585 : edgomez 1053 /* if ((codec->twopass.nns1.quant & NNSTATS_KEYFRAME)) */
1586 : suxen_drol 889 if ((codec->twopass.nns1_array[codec->twopass.nns_update_pos].quant & NNSTATS_KEYFRAME))
1587 :     {
1588 : edgomez 1053 /* calculate how much to distribute per frame in */
1589 :     /* order to make up for this keyframe's overflow */
1590 : suxen_drol 889
1591 :     codec->twopass.overflow += codec->twopass.KFoverflow;
1592 : edgomez 1053 /* codec->twopass.KFoverflow = codec->twopass.desired_bytes2 - frame->length; */
1593 :     /* XXX: very ugly hack for bframs; this affects twopass quality */
1594 : suxen_drol 889 codec->twopass.KFoverflow = codec->twopass.nns2_array[codec->twopass.nns_update_pos].bytes/*codec->twopass.desired_bytes2*/ - stats->length;
1595 :    
1596 :     tempdiv = (codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1597 :     codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1]);
1598 :    
1599 :     if (tempdiv > 1)
1600 :     {
1601 : edgomez 1053 /* non-consecutive keyframes */
1602 : suxen_drol 889 codec->twopass.KFoverflow_partial = codec->twopass.KFoverflow / (tempdiv - 1);
1603 :     }
1604 :     else
1605 :     {
1606 : edgomez 1053 /* consecutive keyframes */
1607 : suxen_drol 889 codec->twopass.overflow += codec->twopass.KFoverflow;
1608 :     codec->twopass.KFoverflow = 0;
1609 :     codec->twopass.KFoverflow_partial = 0;
1610 :     }
1611 :     codec->twopass.KF_idx++;
1612 :     }
1613 :     else
1614 :     {
1615 : edgomez 1053 /* distribute part of the keyframe overflow */
1616 : suxen_drol 889
1617 : edgomez 1053 /* codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length + */
1618 :     /* codec->twopass.KFoverflow_partial; */
1619 : suxen_drol 889 codec->twopass.overflow += codec->twopass.nns2_array[codec->twopass.nns_update_pos].bytes/*codec->twopass.desired_bytes2*/ - stats->length +
1620 :     codec->twopass.KFoverflow_partial;
1621 :     codec->twopass.KFoverflow -= codec->twopass.KFoverflow_partial;
1622 :     }
1623 :     }
1624 :     else
1625 :     {
1626 : edgomez 1053 /* codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length; */
1627 : suxen_drol 889 codec->twopass.overflow += codec->twopass.nns2_array[codec->twopass.nns_update_pos].bytes/*codec->twopass.desired_bytes2*/ - stats->length;
1628 :    
1629 : edgomez 1053 /* ugly fix for credits.. */
1630 : suxen_drol 889 codec->twopass.overflow += codec->twopass.KFoverflow;
1631 :     codec->twopass.KFoverflow = 0;
1632 :     codec->twopass.KFoverflow_partial = 0;
1633 : edgomez 1053 /* end of ugly fix. */
1634 : suxen_drol 889 }
1635 :    
1636 :     /* XXX: remove
1637 :     frame_type="inter";
1638 :     if (frame->intra==1) {
1639 :     frame_type="intra";
1640 :     }
1641 :     else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME) {
1642 :     frame_type="bframe";
1643 :     }
1644 :     else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {
1645 :     frame_type="skipped";
1646 :     frame->quant = 2;
1647 :     codec->twopass.bytes1 = 1;
1648 :     codec->twopass.desired_bytes2 = 1;
1649 :     frame->length = 1;
1650 :     }
1651 :     else if (codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) {
1652 :     frame_type="padded";
1653 :     frame->quant = 2;
1654 :     codec->twopass.bytes1 = 7;
1655 :     codec->twopass.desired_bytes2 = 7;
1656 :     frame->length = 7;
1657 :     }
1658 :     else if (codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {
1659 :     frame_type="delayed";
1660 :     frame->quant = 2;
1661 :     codec->twopass.bytes1 = 1;
1662 :     codec->twopass.desired_bytes2 = 1;
1663 :     frame->length = 1;
1664 :     }
1665 :     */
1666 :    
1667 : edgomez 1053 /* DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos) */
1668 : suxen_drol 889 wsprintf(tmp, "[%i] 2nd-pass: quant:%d %s %s stats1:%d scaled:%d actual:%d overflow:%d %s",
1669 :     codec->twopass.nns_update_pos,
1670 :     stats->quant,
1671 :     quant_type,
1672 :     frame_type,
1673 :     codec->twopass.nns1_array[codec->twopass.nns_update_pos].bytes,
1674 :     codec->twopass.nns2_array[codec->twopass.nns_update_pos].bytes, /* codec->twopass.desired_bytes2, */
1675 :     stats->length,
1676 :     codec->twopass.overflow,
1677 :     credits_pos ? "credits" : "movie");
1678 :     OutputDebugString(tmp);
1679 :    
1680 :     codec->twopass.nns_update_pos++;
1681 :     break;
1682 :    
1683 :     default:
1684 :     break;
1685 :     }
1686 :    
1687 :     return ICERR_OK;
1688 :     }
1689 :    
1690 :     void codec_2pass_finish(CODEC* codec)
1691 :     {
1692 :     int i;
1693 :     char s[100];
1694 :    
1695 :     if (codec->twopass.nns1_array)
1696 :     {
1697 :     free(codec->twopass.nns1_array);
1698 :     codec->twopass.nns1_array = NULL;
1699 :     }
1700 :     if (codec->twopass.nns2_array)
1701 :     {
1702 :     free(codec->twopass.nns2_array);
1703 :     codec->twopass.nns2_array = NULL;
1704 :     }
1705 :     codec->twopass.nns_array_size = 0;
1706 :     codec->twopass.nns_array_length = 0;
1707 :     codec->twopass.nns_array_pos = 0;
1708 :    
1709 :     if (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT)
1710 :     {
1711 : edgomez 1053 /* output the quantizer distribution for this encode. */
1712 : suxen_drol 889
1713 :     OutputDebugString("Quantizer distribution for 2nd pass:");
1714 :     for (i=1; i<=31; i++)
1715 :     {
1716 :     if (codec->twopass.quant_count[i])
1717 :     {
1718 :     wsprintf(s, "Q:%i:%i", i, codec->twopass.quant_count[i]);
1719 :     OutputDebugString(s);
1720 :     }
1721 :     }
1722 :     return;
1723 :     }
1724 :     }
1725 :    

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