[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 679 - (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 660 twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve;
664 :     twopass->average_pframe = (double)pframe_total / pframes / twopass->movie_curve;
665 : h 102
666 :    
667 : suxen_drol 660
668 : h 102 // perform prepass to compensate for over/undersizing
669 :     frames = 0;
670 :    
671 :     if (codec->config.use_alt_curve)
672 :     {
673 : suxen_drol 660 twopass->alt_curve_low = twopass->average_pframe - twopass->average_pframe * (double)codec->config.alt_curve_low_dist / 100.0;
674 :     twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
675 :     twopass->alt_curve_high = twopass->average_pframe + twopass->average_pframe * (double)codec->config.alt_curve_high_dist / 100.0;
676 :     twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
677 : h 102 if (codec->config.alt_curve_use_auto)
678 :     {
679 :     if (twopass->movie_curve > 1.0)
680 :     {
681 :     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);
682 :     if (codec->config.alt_curve_min_rel_qual < 20)
683 :     codec->config.alt_curve_min_rel_qual = 20;
684 :     }
685 :     else
686 :     codec->config.alt_curve_min_rel_qual = 100;
687 :     }
688 :     twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
689 :     twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
690 :     if (codec->config.alt_curve_low_dist > 100)
691 :     {
692 :     switch(codec->config.alt_curve_type)
693 :     {
694 :     case 2: // Sine Curve (high aggressiveness)
695 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
696 : suxen_drol 660 sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
697 : h 102 twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
698 : suxen_drol 660 sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
699 : h 102 break;
700 :     case 1: // Linear (medium aggressiveness)
701 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
702 : suxen_drol 660 twopass->average_pframe / twopass->alt_curve_low_diff);
703 : h 102 twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
704 : suxen_drol 660 twopass->average_pframe / twopass->alt_curve_low_diff;
705 : h 102 break;
706 :     case 0: // Cosine Curve (low aggressiveness)
707 :     twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
708 : suxen_drol 660 (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));
709 : h 102 twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
710 : suxen_drol 660 (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
711 : h 102 }
712 :     }
713 :     }
714 :    
715 :     while (1)
716 :     {
717 : suxen_drol 660 if (twopass->nns_array_pos >= twopass->nns_array_length)
718 : h 102 {
719 : suxen_drol 660 twopass->nns_array_pos = 0;
720 :     break;
721 : h 102 }
722 :    
723 : suxen_drol 660 memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
724 :     twopass->nns_array_pos++;
725 :    
726 : h 528 if (frames == 0)
727 :     {
728 : suxen_drol 660 twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
729 : h 528 twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
730 :     twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
731 : suxen_drol 660 if (recminbsize > twopass->minbsize)
732 :     twopass->minbsize = recminbsize;
733 : h 552 if (recminpsize > twopass->minpsize)
734 :     twopass->minpsize = recminpsize;
735 :     if (recminisize > twopass->minisize)
736 :     twopass->minisize = recminisize;
737 : h 528 }
738 :    
739 : suxen_drol 660 // skip unnecessary frames.
740 :     if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
741 :     twopass->nns1.dd_v & NNSTATS_PADFRAME ||
742 :     twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
743 :     continue;
744 :    
745 : h 102 if (!codec_is_in_credits(&codec->config, frames) &&
746 :     !(twopass->nns1.quant & NNSTATS_KEYFRAME))
747 :     {
748 : h 528 dbytes = twopass->nns1.bytes / twopass->movie_curve;
749 : h 102 total1 += dbytes;
750 :    
751 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
752 :     dbytes *= twopass->average_pframe / twopass->average_bframe;
753 :    
754 : h 102 if (codec->config.use_alt_curve)
755 :     {
756 : suxen_drol 660 if (dbytes > twopass->average_pframe)
757 : h 102 {
758 :     if (dbytes >= twopass->alt_curve_high)
759 : h 528 dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
760 : h 102 else
761 :     {
762 :     switch(codec->config.alt_curve_type)
763 :     {
764 :     case 2:
765 : h 528 dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
766 : suxen_drol 660 sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
767 : h 102 break;
768 :     case 1:
769 : h 528 dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
770 : suxen_drol 660 (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
771 : h 102 break;
772 :     case 0:
773 : h 528 dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
774 : suxen_drol 660 (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
775 : h 102 }
776 :     }
777 :     }
778 :     else
779 :     {
780 :     if (dbytes <= twopass->alt_curve_low)
781 : h 528 dbytes2 = dbytes;
782 : h 102 else
783 :     {
784 :     switch(codec->config.alt_curve_type)
785 :     {
786 :     case 2:
787 : h 528 dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
788 : suxen_drol 660 sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
789 : h 102 break;
790 :     case 1:
791 : h 528 dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
792 : suxen_drol 660 (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
793 : h 102 break;
794 :     case 0:
795 : h 528 dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
796 : suxen_drol 660 (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
797 : h 102 }
798 :     }
799 :     }
800 :     }
801 :     else
802 :     {
803 : suxen_drol 660 if (dbytes > twopass->average_pframe)
804 : h 102 {
805 : suxen_drol 660 dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
806 : h 102 codec->config.curve_compression_high / 100.0);
807 :     }
808 :     else
809 :     {
810 : suxen_drol 660 dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
811 : h 102 codec->config.curve_compression_low / 100.0);
812 :     }
813 :     }
814 : h 528
815 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
816 :     {
817 :     dbytes2 *= twopass->average_bframe / twopass->average_pframe;
818 :     if (dbytes2 < twopass->minbsize)
819 :     dbytes2 = twopass->minbsize;
820 :     }
821 :     else
822 :     {
823 :     if (dbytes2 < twopass->minpsize)
824 :     dbytes2 = twopass->minpsize;
825 :     }
826 : h 528
827 :     total2 += dbytes2;
828 : h 102 }
829 :    
830 :     ++frames;
831 :     }
832 :    
833 :     twopass->curve_comp_scale = total1 / total2;
834 :    
835 :     if (!codec->config.use_alt_curve)
836 :     {
837 :     int asymmetric_average_frame;
838 :     char s[100];
839 :    
840 : suxen_drol 660 asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
841 : h 102 wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
842 :     DEBUG2P(s);
843 :     }
844 :     }
845 :    
846 :     if (codec->config.use_alt_curve)
847 :     {
848 :     if (codec->config.alt_curve_use_auto_bonus_bias)
849 :     codec->config.alt_curve_bonus_bias = codec->config.alt_curve_min_rel_qual;
850 :    
851 :     twopass->curve_bias_bonus = (total1 - total2) * (double)codec->config.alt_curve_bonus_bias / 100.0 / (double)(frames - credits_frames - i_frames);
852 :     twopass->curve_comp_scale = ((total1 - total2) * (1.0 - (double)codec->config.alt_curve_bonus_bias / 100.0) + total2) / total2;
853 :    
854 :    
855 :     // special info for alt curve: bias bonus and quantizer thresholds,
856 :     {
857 :     double curve_temp, dbytes;
858 :     char s[100];
859 :     int i, newquant, percent;
860 :     int oldquant = 1;
861 :    
862 : suxen_drol 660 wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_pframe));
863 : h 102 DEBUG2P(s);
864 :    
865 :     wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));
866 :     DEBUG2P(s);
867 :    
868 :     for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)
869 :     {
870 :     dbytes = i;
871 : suxen_drol 660 if (dbytes > twopass->average_pframe)
872 : h 102 {
873 :     if (dbytes >= twopass->alt_curve_high)
874 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
875 :     else
876 :     {
877 :     switch(codec->config.alt_curve_type)
878 :     {
879 :     case 2:
880 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
881 : suxen_drol 660 sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
882 : h 102 break;
883 :     case 1:
884 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
885 : suxen_drol 660 (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
886 : h 102 break;
887 :     case 0:
888 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
889 : suxen_drol 660 (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
890 : h 102 }
891 :     }
892 :     }
893 :     else
894 :     {
895 :     if (dbytes <= twopass->alt_curve_low)
896 :     curve_temp = dbytes;
897 :     else
898 :     {
899 :     switch(codec->config.alt_curve_type)
900 :     {
901 :     case 2:
902 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
903 : suxen_drol 660 sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
904 : h 102 break;
905 :     case 1:
906 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
907 : suxen_drol 660 (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
908 : h 102 break;
909 :     case 0:
910 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
911 : suxen_drol 660 (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
912 : h 102 }
913 :     }
914 :     }
915 :    
916 :     if (twopass->movie_curve > 1.0)
917 :     dbytes *= twopass->movie_curve;
918 :    
919 :     newquant = (int)(dbytes * 2.0 / (curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus));
920 :     if (newquant > 1)
921 :     {
922 :     if (newquant != oldquant)
923 :     {
924 :     oldquant = newquant;
925 : suxen_drol 660 percent = (int)((i - twopass->average_pframe) * 100.0 / twopass->average_pframe);
926 : h 102 wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);
927 :     DEBUG2P(s);
928 :     }
929 :     }
930 :     }
931 :     }
932 :     }
933 :    
934 :     twopass->overflow = 0;
935 : Foxer 342 twopass->KFoverflow = 0;
936 :     twopass->KFoverflow_partial = 0;
937 :     twopass->KF_idx = 1;
938 : h 102
939 :     break;
940 :     }
941 :    
942 :     return ICERR_OK;
943 :     }
944 :    
945 : suxen_drol 660 // NOTE: codec_2pass_get_quant() should be called for all the frames that are in the stats file(s)
946 : h 102 int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
947 :     {
948 : suxen_drol 660 static double bquant_error[32];
949 :     static double pquant_error[32];
950 : h 102 static double curve_comp_error;
951 : suxen_drol 660 static int last_bquant, last_pquant;
952 : h 102
953 :     TWOPASS * twopass = &codec->twopass;
954 :    
955 : suxen_drol 660 // DWORD read;
956 : h 102 int bytes1, bytes2;
957 :     int overflow;
958 :     int credits_pos;
959 : h 109 int capped_to_max_framesize = 0;
960 : Foxer 343 int KFdistance, KF_min_size;
961 : h 102
962 :     if (codec->framenum == 0)
963 :     {
964 :     int i;
965 :    
966 :     for (i=0 ; i<32 ; ++i)
967 :     {
968 : suxen_drol 660 bquant_error[i] = 0.0;
969 :     pquant_error[i] = 0.0;
970 : h 105 twopass->quant_count[i] = 0;
971 : h 102 }
972 :    
973 :     curve_comp_error = 0.0;
974 : suxen_drol 660 last_bquant = 0;
975 :     last_pquant = 0;
976 : h 102 }
977 :    
978 : suxen_drol 660 if (twopass->nns_array_pos >= twopass->nns_array_length)
979 : h 102 {
980 : suxen_drol 660 twopass->nns_array_pos = 0;
981 : suxen_drol 679 DEBUGERR("ERROR: VIDEO EXCEEDS 1ST PASS!!!");
982 :     return ICERR_ERROR;
983 : h 102 }
984 : suxen_drol 660
985 :     memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
986 : h 102 if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
987 : suxen_drol 660 memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
988 :     twopass->nns_array_pos++;
989 :    
990 :     bytes1 = twopass->nns1.bytes;
991 :    
992 :     // skip unnecessary frames.
993 :     if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME)
994 : h 102 {
995 : suxen_drol 660 twopass->bytes1 = bytes1;
996 :     twopass->bytes2 = bytes1;
997 :     twopass->desired_bytes2 = bytes1;
998 :     frame->intra = 3;
999 :     return 2;
1000 : h 102 }
1001 : suxen_drol 660 else if (twopass->nns1.dd_v & NNSTATS_PADFRAME)
1002 :     {
1003 :     twopass->bytes1 = bytes1;
1004 :     twopass->bytes2 = bytes1;
1005 :     twopass->desired_bytes2 = bytes1;
1006 :     frame->intra = 4;
1007 :     return 2;
1008 :     }
1009 :     else if (twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
1010 :     {
1011 :     twopass->bytes1 = bytes1;
1012 :     twopass->bytes2 = bytes1;
1013 :     twopass->desired_bytes2 = bytes1;
1014 :     frame->intra = 5;
1015 :     return 2;
1016 :     }
1017 : h 102
1018 :     overflow = twopass->overflow / 8;
1019 :    
1020 :     // override codec i-frame choice (reenable in credits)
1021 : suxen_drol 660 if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1022 :     frame->intra=1;
1023 :     else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1024 :     frame->intra=2;
1025 :     else
1026 :     frame->intra=0;
1027 : h 102
1028 : suxen_drol 660 if (frame->intra==1)
1029 : h 102 {
1030 :     overflow = 0;
1031 :     }
1032 :    
1033 :     credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1034 :    
1035 :     if (credits_pos)
1036 :     {
1037 :     if (codec->config.mode == DLG_MODE_2PASS_2_INT)
1038 :     {
1039 :     switch (codec->config.credits_mode)
1040 :     {
1041 :     case CREDITS_MODE_RATE :
1042 :     case CREDITS_MODE_SIZE :
1043 :     if (credits_pos == CREDITS_START)
1044 :     {
1045 :     bytes2 = (int)(bytes1 / twopass->credits_start_curve);
1046 :     }
1047 :     else // CREDITS_END
1048 :     {
1049 :     bytes2 = (int)(bytes1 / twopass->credits_end_curve);
1050 :     }
1051 :    
1052 :     frame->intra = -1;
1053 :     break;
1054 :    
1055 :     case CREDITS_MODE_QUANT :
1056 :     if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1057 :     {
1058 :     frame->quant = frame->intra ?
1059 :     codec->config.credits_quant_i :
1060 :     codec->config.credits_quant_p;
1061 :     }
1062 :     else
1063 :     {
1064 :     frame->quant = codec->config.credits_quant_p;
1065 :     frame->intra = -1;
1066 :     }
1067 :    
1068 :     twopass->bytes1 = bytes1;
1069 :     twopass->bytes2 = bytes1;
1070 :     twopass->desired_bytes2 = bytes1;
1071 :     return ICERR_OK;
1072 :     }
1073 :     }
1074 :     else // DLG_MODE_2PASS_2_EXT
1075 :     {
1076 : h 528 if (codec->config.credits_mode == CREDITS_MODE_QUANT)
1077 :     {
1078 :     if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1079 :     {
1080 : suxen_drol 660 frame->quant = frame->intra == 1 ?
1081 : h 528 codec->config.credits_quant_i :
1082 :     codec->config.credits_quant_p;
1083 :     }
1084 :     else
1085 :     {
1086 :     frame->quant = codec->config.credits_quant_p;
1087 :     frame->intra = -1;
1088 :     }
1089 :    
1090 :     twopass->bytes1 = bytes1;
1091 :     twopass->bytes2 = bytes1;
1092 :     twopass->desired_bytes2 = bytes1;
1093 :     return ICERR_OK;
1094 :     }
1095 :     else
1096 :     bytes2 = twopass->nns2.bytes;
1097 : h 102 }
1098 :     }
1099 :     else // Foxer: apply curve compression outside credits
1100 :     {
1101 :     double dbytes, curve_temp;
1102 :    
1103 :     bytes2 = (codec->config.mode == DLG_MODE_2PASS_2_INT) ? bytes1 : twopass->nns2.bytes;
1104 :    
1105 : suxen_drol 660 if (frame->intra==1)
1106 : h 102 {
1107 :     dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
1108 :     twopass->movie_curve;
1109 :     }
1110 :     else
1111 :     {
1112 :     dbytes = bytes2 / twopass->movie_curve;
1113 :     }
1114 :    
1115 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1116 :     dbytes *= twopass->average_pframe / twopass->average_bframe;
1117 :    
1118 : h 102 // spread the compression error across payback_delay frames
1119 :     if (codec->config.bitrate_payback_method == 0)
1120 :     {
1121 :     bytes2 = (int)(curve_comp_error / codec->config.bitrate_payback_delay);
1122 :     }
1123 :     else
1124 :     {
1125 :     bytes2 = (int)(curve_comp_error * dbytes /
1126 : suxen_drol 660 twopass->average_pframe / codec->config.bitrate_payback_delay);
1127 : h 102
1128 :     if (labs(bytes2) > fabs(curve_comp_error))
1129 :     {
1130 :     bytes2 = (int)curve_comp_error;
1131 :     }
1132 :     }
1133 :    
1134 :     curve_comp_error -= bytes2;
1135 :    
1136 :     if (codec->config.use_alt_curve)
1137 :     {
1138 : suxen_drol 660 if (!(frame->intra==1))
1139 : h 102 {
1140 : suxen_drol 660 if (dbytes > twopass->average_pframe)
1141 : h 102 {
1142 :     if (dbytes >= twopass->alt_curve_high)
1143 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
1144 :     else
1145 :     {
1146 :     switch(codec->config.alt_curve_type)
1147 :     {
1148 :     case 2:
1149 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1150 : suxen_drol 660 sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
1151 : h 102 break;
1152 :     case 1:
1153 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1154 : suxen_drol 660 (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
1155 : h 102 break;
1156 :     case 0:
1157 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1158 : suxen_drol 660 (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
1159 : h 102 }
1160 :     }
1161 :     }
1162 :     else
1163 :     {
1164 :     if (dbytes <= twopass->alt_curve_low)
1165 :     curve_temp = dbytes;
1166 :     else
1167 :     {
1168 :     switch(codec->config.alt_curve_type)
1169 :     {
1170 :     case 2:
1171 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1172 : suxen_drol 660 sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
1173 : h 102 break;
1174 :     case 1:
1175 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1176 : suxen_drol 660 (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
1177 : h 102 break;
1178 :     case 0:
1179 :     curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
1180 : suxen_drol 660 (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
1181 : h 102 }
1182 :     }
1183 :     }
1184 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1185 :     curve_temp *= twopass->average_bframe / twopass->average_pframe;
1186 :    
1187 : suxen_drol 679 curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
1188 :    
1189 : h 102 bytes2 += ((int)curve_temp);
1190 :     curve_comp_error += curve_temp - ((int)curve_temp);
1191 :     }
1192 :     else
1193 :     {
1194 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1195 :     dbytes *= twopass->average_bframe / twopass->average_pframe;
1196 :    
1197 :     bytes2 += ((int)dbytes);
1198 : h 102 curve_comp_error += dbytes - ((int)dbytes);
1199 :     }
1200 :     }
1201 :     else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
1202 : suxen_drol 660 !(frame->intra==1))
1203 : h 102 {
1204 : suxen_drol 660 if (dbytes > twopass->average_pframe)
1205 : h 102 {
1206 :     curve_temp = twopass->curve_comp_scale *
1207 : suxen_drol 660 ((double)dbytes + (twopass->average_pframe - dbytes) *
1208 : h 102 codec->config.curve_compression_high / 100.0);
1209 :     }
1210 :     else
1211 :     {
1212 :     curve_temp = twopass->curve_comp_scale *
1213 : suxen_drol 660 ((double)dbytes + (twopass->average_pframe - dbytes) *
1214 : h 102 codec->config.curve_compression_low / 100.0);
1215 :     }
1216 :    
1217 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1218 :     curve_temp *= twopass->average_bframe / twopass->average_pframe;
1219 :    
1220 : h 102 bytes2 += ((int)curve_temp);
1221 :     curve_comp_error += curve_temp - ((int)curve_temp);
1222 :     }
1223 :     else
1224 :     {
1225 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1226 :     dbytes *= twopass->average_bframe / twopass->average_pframe;
1227 :    
1228 :     bytes2 += ((int)dbytes);
1229 : h 102 curve_comp_error += dbytes - ((int)dbytes);
1230 :     }
1231 :    
1232 : h 552 // cap bytes2 to first pass size, lowers number of quant=1 frames
1233 :     if (bytes2 > bytes1)
1234 : h 102 {
1235 : h 552 curve_comp_error += bytes2 - bytes1;
1236 :     bytes2 = bytes1;
1237 : h 102 }
1238 : h 528 else
1239 : h 102 {
1240 : suxen_drol 660 if (frame->intra==1)
1241 : h 528 {
1242 : h 552 if (bytes2 < twopass->minisize)
1243 :     {
1244 :     curve_comp_error -= twopass->minisize - bytes2;
1245 :     bytes2 = twopass->minisize;
1246 :     }
1247 : h 528 }
1248 : suxen_drol 660 else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1249 :     {
1250 :     if (bytes2 < twopass->minbsize)
1251 :     bytes2 = twopass->minbsize;
1252 :     }
1253 :     else
1254 :     {
1255 :     if (bytes2 < twopass->minpsize)
1256 :     bytes2 = twopass->minpsize;
1257 :     }
1258 : h 102 }
1259 :     }
1260 :    
1261 :     twopass->desired_bytes2 = bytes2;
1262 :    
1263 : Foxer 365 // if this keyframe is too close to the next,
1264 :     // reduce it's byte allotment
1265 : suxen_drol 660 if ((frame->intra==1) && !credits_pos)
1266 : Foxer 343 {
1267 :     KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1268 :     codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];
1269 :    
1270 :     if (KFdistance < codec->config.kftreshold)
1271 :     {
1272 :     KFdistance = KFdistance - codec->config.min_key_interval;
1273 :    
1274 :     if (KFdistance >= 0)
1275 :     {
1276 :     KF_min_size = bytes2 * (100 - codec->config.kfreduction) / 100;
1277 :     if (KF_min_size < 1)
1278 :     KF_min_size = 1;
1279 :    
1280 :     bytes2 = KF_min_size + (bytes2 - KF_min_size) * KFdistance /
1281 :     (codec->config.kftreshold - codec->config.min_key_interval);
1282 :    
1283 :     if (bytes2 < 1)
1284 :     bytes2 = 1;
1285 :     }
1286 :     }
1287 :     }
1288 :    
1289 : h 102 // Foxer: scale overflow in relation to average size, so smaller frames don't get
1290 :     // too much/little bitrate
1291 : suxen_drol 660 overflow = (int)((double)overflow * bytes2 / twopass->average_pframe);
1292 : h 102
1293 :     // Foxer: reign in overflow with huge frames
1294 :     if (labs(overflow) > labs(twopass->overflow))
1295 :     {
1296 :     overflow = twopass->overflow;
1297 :     }
1298 :    
1299 :     // Foxer: make sure overflow doesn't run away
1300 : h 109 if (overflow > bytes2 * codec->config.twopass_max_overflow_improvement / 100)
1301 : h 102 {
1302 : h 109 bytes2 += (overflow <= bytes2) ? bytes2 * codec->config.twopass_max_overflow_improvement / 100 :
1303 :     overflow * codec->config.twopass_max_overflow_improvement / 100;
1304 : h 102 }
1305 : h 109 else if (overflow < bytes2 * codec->config.twopass_max_overflow_degradation / -100)
1306 : h 102 {
1307 : h 109 bytes2 += bytes2 * codec->config.twopass_max_overflow_degradation / -100;
1308 : h 102 }
1309 :     else
1310 :     {
1311 :     bytes2 += overflow;
1312 :     }
1313 :    
1314 : h 109 if (bytes2 > twopass->max_framesize)
1315 :     {
1316 :     capped_to_max_framesize = 1;
1317 :     bytes2 = twopass->max_framesize;
1318 :     }
1319 :    
1320 : h 552 // make sure to not scale below the minimum framesize
1321 :     if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1322 : h 102 {
1323 : h 552 if (bytes2 < twopass->minisize)
1324 :     bytes2 = twopass->minisize;
1325 : h 102 }
1326 : suxen_drol 660 else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1327 :     {
1328 :     if (bytes2 < twopass->minbsize)
1329 :     bytes2 = twopass->minbsize;
1330 :     }
1331 :     else
1332 :     {
1333 :     if (bytes2 < twopass->minpsize)
1334 :     bytes2 = twopass->minpsize;
1335 :     }
1336 : h 102
1337 :     twopass->bytes1 = bytes1;
1338 :     twopass->bytes2 = bytes2;
1339 :    
1340 :     // very 'simple' quant<->filesize relationship
1341 :     frame->quant = ((twopass->nns1.quant & ~NNSTATS_KEYFRAME) * bytes1) / bytes2;
1342 :    
1343 :     if (frame->quant < 1)
1344 :     {
1345 :     frame->quant = 1;
1346 :     }
1347 :     else if (frame->quant > 31)
1348 :     {
1349 :     frame->quant = 31;
1350 :     }
1351 : suxen_drol 660 else if (!(frame->intra==1))
1352 : h 102 {
1353 :     // Foxer: aid desired quantizer precision by accumulating decision error
1354 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1355 :     {
1356 :     bquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1357 :     bytes1) / bytes2) - frame->quant;
1358 : h 102
1359 : suxen_drol 660 if (bquant_error[frame->quant] >= 1.0)
1360 :     {
1361 :     bquant_error[frame->quant] -= 1.0;
1362 :     ++frame->quant;
1363 :     }
1364 :     }
1365 :     else
1366 : h 102 {
1367 : suxen_drol 660 pquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1368 :     bytes1) / bytes2) - frame->quant;
1369 :    
1370 :     if (pquant_error[frame->quant] >= 1.0)
1371 :     {
1372 :     pquant_error[frame->quant] -= 1.0;
1373 :     ++frame->quant;
1374 :     }
1375 : h 102 }
1376 :     }
1377 :    
1378 :     // we're done with credits
1379 :     if (codec_is_in_credits(&codec->config, codec->framenum))
1380 :     {
1381 :     return ICERR_OK;
1382 :     }
1383 :    
1384 : suxen_drol 660 if ((frame->intra==1))
1385 : h 102 {
1386 :     if (frame->quant < codec->config.min_iquant)
1387 :     {
1388 :     frame->quant = codec->config.min_iquant;
1389 :     DEBUG2P("I-frame quantizer raised");
1390 :     }
1391 :     if (frame->quant > codec->config.max_iquant)
1392 :     {
1393 :     frame->quant = codec->config.max_iquant;
1394 :     DEBUG2P("I-frame quantizer lowered");
1395 :     }
1396 :     }
1397 :     else
1398 :     {
1399 :     if (frame->quant > codec->config.max_pquant)
1400 :     {
1401 :     frame->quant = codec->config.max_pquant;
1402 :     }
1403 :     if (frame->quant < codec->config.min_pquant)
1404 :     {
1405 :     frame->quant = codec->config.min_pquant;
1406 :     }
1407 :    
1408 :     // subsequent frame quants can only be +- 2
1409 : suxen_drol 660 if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)
1410 : h 102 {
1411 : suxen_drol 660 if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1412 : h 102 {
1413 : suxen_drol 660 // this bframe quantizer variation
1414 :     // restriction needs to be redone.
1415 :     if (frame->quant > last_bquant + 2)
1416 :     {
1417 :     frame->quant = last_bquant + 2;
1418 :     DEBUG2P("B-frame quantizer prevented from rising too steeply");
1419 :     }
1420 :     if (frame->quant < last_bquant - 2)
1421 :     {
1422 :     frame->quant = last_bquant - 2;
1423 :     DEBUG2P("B-frame quantizer prevented from falling too steeply");
1424 :     }
1425 : h 102 }
1426 : suxen_drol 660 else
1427 : h 102 {
1428 : suxen_drol 660 if (frame->quant > last_pquant + 2)
1429 :     {
1430 :     frame->quant = last_pquant + 2;
1431 :     DEBUG2P("P-frame quantizer prevented from rising too steeply");
1432 :     }
1433 :     if (frame->quant < last_pquant - 2)
1434 :     {
1435 :     frame->quant = last_pquant - 2;
1436 :     DEBUG2P("P-frame quantizer prevented from falling too steeply");
1437 :     }
1438 : h 102 }
1439 :     }
1440 :     }
1441 :    
1442 : h 109 if (capped_to_max_framesize == 0)
1443 : suxen_drol 660 {
1444 : suxen_drol 679 if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1445 :     {
1446 : suxen_drol 660 last_bquant = frame->quant;
1447 : suxen_drol 679 last_pquant = frame->quant;
1448 :     }
1449 :     else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1450 :     last_bquant = frame->quant;
1451 : suxen_drol 660 else
1452 :     last_pquant = frame->quant;
1453 :     }
1454 : h 102
1455 :     if (codec->config.quant_type == QUANT_MODE_MOD)
1456 :     {
1457 :     frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;
1458 :     frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1459 :     }
1460 : suxen_drol 660 /*
1461 :     if (codec->config.quant_type == QUANT_MODE_MOD_NEW)
1462 :     {
1463 :     frame->general |= (frame->quant < 4) ? XVID_H263QUANT : XVID_MPEGQUANT;
1464 :     frame->general &= (frame->quant < 4) ? ~XVID_MPEGQUANT : ~XVID_H263QUANT;
1465 :     }
1466 :     */
1467 : h 102 return ICERR_OK;
1468 :     }
1469 :    
1470 :    
1471 :     int codec_2pass_update(CODEC* codec, XVID_ENC_FRAME* frame, XVID_ENC_STATS* stats)
1472 :     {
1473 :     static __int64 total_size;
1474 :    
1475 :     NNSTATS nns1;
1476 :     DWORD wrote;
1477 : Foxer 342 int credits_pos, tempdiv;
1478 : h 102 char* quant_type;
1479 : suxen_drol 660 char* frame_type;
1480 : h 102
1481 :     if (codec->framenum == 0)
1482 :     {
1483 :     total_size = 0;
1484 :     }
1485 :    
1486 :     quant_type = (frame->general & XVID_H263QUANT) ? "H.263" :
1487 :     ((frame->general & XVID_MPEGQUANT) && (frame->general & XVID_CUSTOM_QMATRIX)) ?
1488 :     "Cust" : "MPEG";
1489 :    
1490 :     switch (codec->config.mode)
1491 :     {
1492 :     case DLG_MODE_2PASS_1 :
1493 :     nns1.bytes = frame->length; // total bytes
1494 :     nns1.dd_v = stats->hlength; // header bytes
1495 :    
1496 :     nns1.dd_u = nns1.dd_y = 0;
1497 :     nns1.dk_v = nns1.dk_u = nns1.dk_y = 0;
1498 :     nns1.md_u = nns1.md_y = 0;
1499 :     nns1.mk_u = nns1.mk_y = 0;
1500 :    
1501 : h 127 // nns1.quant = stats->quant;
1502 :     nns1.quant = 2; // ugly fix for lumi masking in 1st pass returning new quant
1503 : suxen_drol 660 nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1504 :     frame_type="inter";
1505 :     if (frame->intra==1) {
1506 : h 102 nns1.quant |= NNSTATS_KEYFRAME;
1507 : suxen_drol 660 frame_type="intra";
1508 : h 102 }
1509 : suxen_drol 660 else if (frame->intra==2) {
1510 :     nns1.dd_v |= NNSTATS_BFRAME;
1511 :     frame_type="bframe";
1512 :     }
1513 :     else if (frame->intra==3) {
1514 :     nns1.dd_v |= NNSTATS_SKIPFRAME;
1515 :     frame_type="skiped";
1516 :     }
1517 :     else if (frame->intra==4) {
1518 :     nns1.dd_v |= NNSTATS_PADFRAME;
1519 :     frame_type="padded";
1520 :     }
1521 :     else if (frame->intra==5) {
1522 :     nns1.dd_v |= NNSTATS_DELAYFRAME;
1523 :     frame_type="delayed";
1524 :     }
1525 : h 102 nns1.kblk = stats->kblks;
1526 :     nns1.mblk = stats->mblks;
1527 :     nns1.ublk = stats->ublks;
1528 :    
1529 :     total_size += frame->length;
1530 :    
1531 : suxen_drol 660 DEBUG1ST(frame->length, (int)total_size/1024, frame_type, frame->quant, quant_type, stats->kblks, stats->mblks)
1532 : h 102
1533 : suxen_drol 660
1534 : h 102 if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS))
1535 :     {
1536 :     DEBUGERR("stats1: WriteFile error");
1537 :     return ICERR_ERROR;
1538 :     }
1539 :     break;
1540 :    
1541 :     case DLG_MODE_2PASS_2_INT :
1542 :     case DLG_MODE_2PASS_2_EXT :
1543 : h 105 credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1544 : suxen_drol 660 if (!(codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&
1545 :     !(codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) &&
1546 :     !(codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME))
1547 : Foxer 342 {
1548 : suxen_drol 660 if (!credits_pos)
1549 : Foxer 342 {
1550 : suxen_drol 660 codec->twopass.quant_count[frame->quant]++;
1551 :     if ((codec->twopass.nns1.quant & NNSTATS_KEYFRAME))
1552 :     {
1553 :     // calculate how much to distribute per frame in
1554 :     // order to make up for this keyframe's overflow
1555 : Foxer 365
1556 : suxen_drol 660 codec->twopass.overflow += codec->twopass.KFoverflow;
1557 :     codec->twopass.KFoverflow = codec->twopass.desired_bytes2 - frame->length;
1558 : h 105
1559 : suxen_drol 660 tempdiv = (codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1560 :     codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1]);
1561 : Foxer 342
1562 : suxen_drol 660 if (tempdiv > 1)
1563 :     {
1564 :     // non-consecutive keyframes
1565 :     codec->twopass.KFoverflow_partial = codec->twopass.KFoverflow / (tempdiv - 1);
1566 :     }
1567 :     else
1568 :     {
1569 :     // consecutive keyframes
1570 :     codec->twopass.overflow += codec->twopass.KFoverflow;
1571 :     codec->twopass.KFoverflow = 0;
1572 :     codec->twopass.KFoverflow_partial = 0;
1573 :     }
1574 :     codec->twopass.KF_idx++;
1575 : Foxer 342 }
1576 :     else
1577 :     {
1578 : suxen_drol 660 // distribute part of the keyframe overflow
1579 :    
1580 :     codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length +
1581 :     codec->twopass.KFoverflow_partial;
1582 :     codec->twopass.KFoverflow -= codec->twopass.KFoverflow_partial;
1583 : Foxer 342 }
1584 :     }
1585 :     else
1586 :     {
1587 : suxen_drol 660 codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;
1588 : Foxer 365
1589 : suxen_drol 660 // ugly fix for credits..
1590 :     codec->twopass.overflow += codec->twopass.KFoverflow;
1591 :     codec->twopass.KFoverflow = 0;
1592 :     codec->twopass.KFoverflow_partial = 0;
1593 :     // end of ugly fix.
1594 : Foxer 342 }
1595 :     }
1596 :    
1597 : suxen_drol 660 frame_type="inter";
1598 :     if (frame->intra==1) {
1599 :     frame_type="intra";
1600 : Foxer 342 }
1601 : suxen_drol 660 else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME) {
1602 :     frame_type="bframe";
1603 :     }
1604 :     else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {
1605 :     frame_type="skipped";
1606 :     frame->quant = 2;
1607 : suxen_drol 679 codec->twopass.bytes1 = 1;
1608 :     codec->twopass.desired_bytes2 = 1;
1609 :     frame->length = 1;
1610 : suxen_drol 660 }
1611 :     else if (codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) {
1612 :     frame_type="padded";
1613 :     frame->quant = 2;
1614 : suxen_drol 679 codec->twopass.bytes1 = 7;
1615 :     codec->twopass.desired_bytes2 = 7;
1616 :     frame->length = 7;
1617 : suxen_drol 660 }
1618 :     else if (codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {
1619 :     frame_type="delayed";
1620 :     frame->quant = 2;
1621 : suxen_drol 679 codec->twopass.bytes1 = 1;
1622 :     codec->twopass.desired_bytes2 = 1;
1623 :     frame->length = 1;
1624 : suxen_drol 660 }
1625 : Foxer 342
1626 : suxen_drol 660 DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
1627 : h 102 break;
1628 :    
1629 :     default:
1630 :     break;
1631 :     }
1632 :    
1633 :     return ICERR_OK;
1634 :     }
1635 :    
1636 : h 105 void codec_2pass_finish(CODEC* codec)
1637 :     {
1638 :     int i;
1639 :     char s[100];
1640 : suxen_drol 660
1641 :     if (codec->twopass.nns1_array)
1642 : suxen_drol 679 {
1643 : suxen_drol 660 free(codec->twopass.nns1_array);
1644 : suxen_drol 679 codec->twopass.nns1_array = NULL;
1645 :     }
1646 : suxen_drol 660 if (codec->twopass.nns2_array)
1647 : suxen_drol 679 {
1648 : suxen_drol 660 free(codec->twopass.nns2_array);
1649 : suxen_drol 679 codec->twopass.nns2_array = NULL;
1650 :     }
1651 : suxen_drol 660 codec->twopass.nns_array_size = 0;
1652 :     codec->twopass.nns_array_length = 0;
1653 :     codec->twopass.nns_array_pos = 0;
1654 :    
1655 : h 105 if (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT)
1656 :     {
1657 :     // output the quantizer distribution for this encode.
1658 : h 102
1659 : h 105 OutputDebugString("Quantizer distribution for 2nd pass:");
1660 :     for (i=1; i<=31; i++)
1661 :     {
1662 :     if (codec->twopass.quant_count[i])
1663 :     {
1664 :     wsprintf(s, "Q:%i:%i", i, codec->twopass.quant_count[i]);
1665 :     OutputDebugString(s);
1666 :     }
1667 :     }
1668 :     return;
1669 :     }
1670 : h 552 }
1671 :    

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