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

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