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

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