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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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