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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/vfw/src/2pass.c revision 102, Fri Apr 5 14:42:37 2002 UTC branches/dev-api-3/vfw/src/2pass.c revision 814, Sun Feb 2 10:05:27 2003 UTC
# Line 23  Line 23 
23   *   *
24   *      History:   *      History:
25   *   *
26     *      17.04.2002      changed 1st pass quant to always be 2 (2pass_update())
27     *      07.04.2002      added max bitrate constraint, overflow controls (foxer)
28   *      31.03.2002      inital version;   *      31.03.2002      inital version;
29   *   *
30   *************************************************************************/   *************************************************************************/
# Line 39  Line 41 
41          DWORD version = -20;          DWORD version = -20;
42          DWORD read, wrote;          DWORD read, wrote;
43    
44          int     frames = 0, credits_frames = 0, i_frames = 0;          int     frames = 0, bframes = 0, pframes = 0, credits_frames = 0, i_frames = 0, recminbsize = 0, recminpsize = 0, recminisize = 0;
45          __int64 total_ext = 0, total = 0, i_total = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0;          __int64 bframe_total_ext = 0, pframe_total_ext = 0, pframe_total = 0, bframe_total = 0, i_total = 0, i_total_ext = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0;
46          __int64 desired = (__int64)codec->config.desired_size * 1024;          __int64 desired = (__int64)codec->config.desired_size * 1024;
47    
48          double total1 = 0.0;          double total1 = 0.0;
49          double total2 = 0.0;          double total2 = 0.0;
50            double dbytes, dbytes2;
51    
52            /* ensure free() is called safely */
53            codec->twopass.hintstream = NULL;
54            twopass->nns1_array = NULL;
55            twopass->nns2_array = NULL;
56    
57          if (codec->config.hinted_me)          if (codec->config.hinted_me)
58          {          {
# Line 98  Line 106 
106                          return ICERR_ERROR;                          return ICERR_ERROR;
107                  }                  }
108    
109                    twopass->nns1_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);
110                    twopass->nns2_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);
111                    twopass->nns_array_size = 10240;
112                    twopass->nns_array_length = 0;
113                    twopass->nns_array_pos = 0;
114    
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                  if (codec->config.mode == DLG_MODE_2PASS_2_EXT)                  if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
118                  {                  {
119                          if (twopass->stats2 != INVALID_HANDLE_VALUE)                          if (twopass->stats2 != INVALID_HANDLE_VALUE)
# Line 155  Line 171 
171                                          }                                          }
172                                  }                                  }
173    
174                                    // 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                                  if (!codec_is_in_credits(&codec->config, frames))                                  if (!codec_is_in_credits(&codec->config, frames))
295                                  {                                  {
296                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)
297                                          {                                          {
                                                 i_boost_total = twopass->nns2.bytes * codec->config.keyframe_boost / 100;  
298                                                  i_total += twopass->nns2.bytes;                                                  i_total += twopass->nns2.bytes;
299                                                    i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;
300                                                    twopass->keyframe_locations[i_frames] = frames;
301                                                  ++i_frames;                                                  ++i_frames;
302                                          }                                          }
303                                            else
304                                          total += twopass->nns1.bytes;                                          {
305                                          total_ext += twopass->nns2.bytes;                                                  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                                  }                                  }
319                                  else                                  else
320                                          ++credits_frames;                                          ++credits_frames;
321    
322                                    if (twopass->nns1.quant & NNSTATS_KEYFRAME)
323                                    {
324                                            // this test needs to be corrected..
325                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
326                                                    recminisize = twopass->nns1.bytes;
327                                    }
328                                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
329                                    {
330                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
331                                                    recminbsize = twopass->nns1.bytes;
332                                    }
333                                    else
334                                    {
335                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
336                                                    recminpsize = twopass->nns1.bytes;
337                                    }
338    
339                                  ++frames;                                  ++frames;
340                          }                          }
341                            twopass->keyframe_locations[i_frames] = frames;
342    
343                            twopass->movie_curve = ((double)(bframe_total_ext + pframe_total_ext + i_boost_total) /
344                                    (bframe_total_ext + pframe_total_ext));
345    
346                            if (bframes)
347                                    twopass->average_bframe = (double)bframe_total_ext / bframes / twopass->movie_curve;
348    
349                            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    
                         twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);  
                         twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);  
360    
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
                         SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);  
361    
362                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
363                          frames = 0;                          frames = 0;
364    
365                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
366                          {                          {
367                                  twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;                                  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_frame - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
369                                  twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;                                  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_frame;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
371                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
372                                  {                                  {
373                                          if (total > total_ext)                                          if (bframe_total + pframe_total > bframe_total_ext + pframe_total_ext)
374                                          {                                          {
375                                                  codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / ((double)total / (double)total_ext)) * (double)codec->config.alt_curve_auto_str / 100.0);                                                  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                                                  if (codec->config.alt_curve_min_rel_qual < 20)                                                  if (codec->config.alt_curve_min_rel_qual < 20)
380                                                          codec->config.alt_curve_min_rel_qual = 20;                                                          codec->config.alt_curve_min_rel_qual = 20;
381                                          }                                          }
# Line 207  Line 390 
390                                          {                                          {
391                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
392                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
393                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
394                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
395                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
396                                                  break;                                                  break;
397                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
398                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
399                                                          twopass->average_frame / twopass->alt_curve_low_diff);                                                          twopass->average_pframe / twopass->alt_curve_low_diff);
400                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
401                                                          twopass->average_frame / twopass->alt_curve_low_diff;                                                          twopass->average_pframe / twopass->alt_curve_low_diff;
402                                                  break;                                                  break;
403                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
404                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
405                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));
406                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
407                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
408                                          }                                          }
409                                  }                                  }
410                          }                          }
411    
412                          while (1)                          while (1)
413                          {                          {
414                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||                                  if (twopass->nns_array_pos >= twopass->nns_array_length)
                                         !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))  
                                 {  
                                         DWORD err = GetLastError();  
   
                                         if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)  
415                                          {                                          {
416                                            twopass->nns_array_pos = 0;
417                                                  break;                                                  break;
418                                          }                                          }
419                                          else  
420                                    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                                    if (frames == 0)
425                                          {                                          {
426                                                  CloseHandle(twopass->stats1);                                          twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
427                                                  CloseHandle(twopass->stats2);                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
428                                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
429                                                  twopass->stats2 = INVALID_HANDLE_VALUE;                                          if (recminbsize > twopass->minbsize)
430                                                  DEBUGERR("2pass init error - incomplete stats1/stats2 record?");                                                  twopass->minbsize = recminbsize;
431                                                  return ICERR_ERROR;                                          if (recminpsize > twopass->minpsize)
432                                          }                                                  twopass->minpsize = recminpsize;
433                                            if (recminisize > twopass->minisize)
434                                                    twopass->minisize = recminisize;
435                                  }                                  }
436    
437                                    // 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                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
444                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
445                                  {                                  {
446                                          double dbytes = twopass->nns2.bytes / twopass->movie_curve;                                          dbytes = twopass->nns2.bytes / twopass->movie_curve;
447                                          total1 += dbytes;                                          total1 += dbytes;
448    
449                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
450                                                    dbytes *= twopass->average_pframe / twopass->average_bframe;
451    
452                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
453                                          {                                          {
454                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
455                                                  {                                                  {
456                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
457                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
458                                                          else                                                          else
459                                                          {                                                          {
460                                                                  switch(codec->config.alt_curve_type)                                                                  switch(codec->config.alt_curve_type)
461                                                                  {                                                                  {
462                                                                  case 2:                                                                  case 2:
463                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
464                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
465                                                                          break;                                                                          break;
466                                                                  case 1:                                                                  case 1:
467                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
468                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
469                                                                          break;                                                                          break;
470                                                                  case 0:                                                                  case 0:
471                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
472                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
473                                                                  }                                                                  }
474                                                          }                                                          }
475                                                  }                                                  }
476                                                  else                                                  else
477                                                  {                                                  {
478                                                          if (dbytes <= twopass->alt_curve_low)                                                          if (dbytes <= twopass->alt_curve_low)
479                                                                  total2 += dbytes;                                                                  dbytes2 = dbytes;
480                                                          else                                                          else
481                                                          {                                                          {
482                                                                  switch(codec->config.alt_curve_type)                                                                  switch(codec->config.alt_curve_type)
483                                                                  {                                                                  {
484                                                                  case 2:                                                                  case 2:
485                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
486                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
487                                                                          break;                                                                          break;
488                                                                  case 1:                                                                  case 1:
489                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
490                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
491                                                                          break;                                                                          break;
492                                                                  case 0:                                                                  case 0:
493                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
494                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
495                                                                  }                                                                  }
496                                                          }                                                          }
497                                                  }                                                  }
498                                          }                                          }
499                                          else                                          else
500                                          {                                          {
501                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
502                                                  {                                                  {
503                                                          total2 += ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
504                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
505                                                  }                                                  }
506                                                  else                                                  else
507                                                  {                                                  {
508                                                          total2 += ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
509                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
510                                                  }                                                  }
511                                          }                                          }
512    
513                                            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    
525                                            total2 += dbytes2;
526                                  }                                  }
527    
528                                  ++frames;                                  ++frames;
# Line 326  Line 535 
535                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
536                                  char s[100];                                  char s[100];
537    
538                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
539                                  wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);                                  wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
540                                  DEBUG2P(s);                                  DEBUG2P(s);
541                          }                          }
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
                         SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);  
542                  }                  }
543                  else    // DLG_MODE_2PASS_2_INT                  else    // DLG_MODE_2PASS_2_INT
544                  {                  {
545                          while (1)                          while (1)
546                          {                          {
547                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))                                  if (twopass->nns_array_pos >= twopass->nns_array_length)
                                 {  
                                         DWORD err = GetLastError();  
   
                                         if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)  
548                                          {                                          {
549                                            twopass->nns_array_pos = 0;
550                                                  break;                                                  break;
551                                          }                                          }
552                                          else  
553                                          {                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
554                                                  CloseHandle(twopass->stats1);                                  twopass->nns_array_pos++;
555                                                  twopass->stats1 = INVALID_HANDLE_VALUE;  
556                                                  DEBUGERR("2pass init error - incomplete stats2 record?");                                  // skip unnecessary frames.
557                                                  return ICERR_ERROR;                                  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                                  if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)                                  if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)
563                                  {                                  {
# Line 368  Line 572 
572                                  else if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                  else if (twopass->nns1.quant & NNSTATS_KEYFRAME)
573                                  {                                  {
574                                          i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;                                          i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;
575                                          total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;                                          twopass->keyframe_locations[i_frames] = frames;
576                                          ++i_frames;                                          ++i_frames;
577                                  }                                  }
578                                    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    
592                                  total += twopass->nns1.bytes;                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)
593                                    {
594                                            // this test needs to be corrected..
595                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
596                                                    recminisize = twopass->nns1.bytes;
597                                    }
598                                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
599                                    {
600                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
601                                                    recminbsize = twopass->nns1.bytes;
602                                    }
603                                    else
604                                    {
605                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
606                                                    recminpsize = twopass->nns1.bytes;
607                                    }
608    
609                                  ++frames;                                  ++frames;
610                          }                          }
611                            twopass->keyframe_locations[i_frames] = frames;
612    
613                          // compensate for avi frame overhead                          // compensate for avi frame overhead
614                          desired -= frames * 24;                          desired -= frames * 24;
# Line 386  Line 619 
619    
620                                  // credits curve = (total / desired_size) * (100 / credits_rate)                                  // credits curve = (total / desired_size) * (100 / credits_rate)
621                                  twopass->credits_start_curve = twopass->credits_end_curve =                                  twopass->credits_start_curve = twopass->credits_end_curve =
622                                          ((double)total / desired) * ((double)100 / codec->config.credits_rate);                                          ((double)(bframe_total + pframe_total + i_total + start + end) / desired) *
623                                            ((double)100 / codec->config.credits_rate);
624    
625                                  start_curved = (__int64)(start / twopass->credits_start_curve);                                  start_curved = (__int64)(start / twopass->credits_start_curve);
626                                  end_curved = (__int64)(end / twopass->credits_end_curve);                                  end_curved = (__int64)(end / twopass->credits_end_curve);
627    
628                                  // movie curve = (total - credits) / (desired_size - curved credits)                                  // movie curve = (total - credits) / (desired_size - curved credits)
629                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
630                                          (total - start - end) /                                          (bframe_total + pframe_total + i_total) /
631                                          (desired - start_curved - end_curved);                                          (desired - start_curved - end_curved);
632    
633                                  break;                                  break;
# Line 402  Line 636 
636    
637                                  // movie curve = (total - credits) / (desired_size - credits)                                  // movie curve = (total - credits) / (desired_size - credits)
638                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
639                                          (total - start - end) / (desired - start - end);                                          (bframe_total + pframe_total + i_total) / (desired - start - end);
640    
641                                  // aid the average asymmetric frame calculation below                                  // aid the average asymmetric frame calculation below
642                                  start_curved = start;                                  start_curved = start;
# Line 425  Line 659 
659    
660                                  // movie curve = (total - credits) / (desired_size - curved credits)                                  // movie curve = (total - credits) / (desired_size - curved credits)
661                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
662                                          (total - start - end) /                                          (bframe_total + pframe_total + i_total) /
663                                          (desired - start_curved - end_curved);                                          (desired - start_curved - end_curved);
664    
665                                  break;                                  break;
666                          }                          }
667    
668                          // average frame size = (desired - curved credits - curved keyframes) /                          if (bframes)
669                          //      (frames - credits frames - keyframes)                                  twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve;
670                          twopass->average_frame = (double)  
671                                  (desired - start_curved - end_curved - (i_total / twopass->movie_curve)) /                          if (pframes)
672                                  (frames - credits_frames - i_frames);                                  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    
682    
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
683    
684                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
685                          frames = 0;                          frames = 0;
686    
687                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
688                          {                          {
689                                  twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;                                  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_frame - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
691                                  twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;                                  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_frame;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
693                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
694                                  {                                  {
695                                          if (twopass->movie_curve > 1.0)                                          if (twopass->movie_curve > 1.0)
# Line 467  Line 709 
709                                          {                                          {
710                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
711                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
712                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
713                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
714                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
715                                                  break;                                                  break;
716                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
717                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
718                                                          twopass->average_frame / twopass->alt_curve_low_diff);                                                          twopass->average_pframe / twopass->alt_curve_low_diff);
719                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
720                                                          twopass->average_frame / twopass->alt_curve_low_diff;                                                          twopass->average_pframe / twopass->alt_curve_low_diff;
721                                                  break;                                                  break;
722                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
723                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
724                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));
725                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
726                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
727                                          }                                          }
728                                  }                                  }
729                          }                          }
730    
731                          while (1)                          while (1)
732                          {                          {
733                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))                                  if (twopass->nns_array_pos >= twopass->nns_array_length)
                                 {  
                                         DWORD err = GetLastError();  
   
                                         if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)  
734                                          {                                          {
735                                            twopass->nns_array_pos = 0;
736                                                  break;                                                  break;
737                                          }                                          }
738                                          else  
739                                    memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
740                                    twopass->nns_array_pos++;
741    
742                                    if (frames == 0)
743                                          {                                          {
744                                                  CloseHandle(twopass->stats1);                                          twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
745                                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
746                                                  DEBUGERR("2pass init error - incomplete stats2 record?");                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
747                                                  return ICERR_ERROR;                                          if (recminbsize > twopass->minbsize)
748                                          }                                                  twopass->minbsize = recminbsize;
749                                            if (recminpsize > twopass->minpsize)
750                                                    twopass->minpsize = recminpsize;
751                                            if (recminisize > twopass->minisize)
752                                                    twopass->minisize = recminisize;
753                                  }                                  }
754    
755                                    // 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                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
762                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
763                                  {                                  {
764                                          double dbytes = twopass->nns1.bytes / twopass->movie_curve;                                          dbytes = twopass->nns1.bytes / twopass->movie_curve;
765                                          total1 += dbytes;                                          total1 += dbytes;
766    
767                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
768                                                    dbytes *= twopass->average_pframe / twopass->average_bframe;
769    
770                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
771                                          {                                          {
772                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
773                                                  {                                                  {
774                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
775                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
776                                                          else                                                          else
777                                                          {                                                          {
778                                                                  switch(codec->config.alt_curve_type)                                                                  switch(codec->config.alt_curve_type)
779                                                                  {                                                                  {
780                                                                  case 2:                                                                  case 2:
781                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
782                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
783                                                                          break;                                                                          break;
784                                                                  case 1:                                                                  case 1:
785                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
786                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
787                                                                          break;                                                                          break;
788                                                                  case 0:                                                                  case 0:
789                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
790                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
791                                                                  }                                                                  }
792                                                          }                                                          }
793                                                  }                                                  }
794                                                  else                                                  else
795                                                  {                                                  {
796                                                          if (dbytes <= twopass->alt_curve_low)                                                          if (dbytes <= twopass->alt_curve_low)
797                                                                  total2 += dbytes;                                                                  dbytes2 = dbytes;
798                                                          else                                                          else
799                                                          {                                                          {
800                                                                  switch(codec->config.alt_curve_type)                                                                  switch(codec->config.alt_curve_type)
801                                                                  {                                                                  {
802                                                                  case 2:                                                                  case 2:
803                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
804                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
805                                                                          break;                                                                          break;
806                                                                  case 1:                                                                  case 1:
807                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
808                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
809                                                                          break;                                                                          break;
810                                                                  case 0:                                                                  case 0:
811                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
812                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
813                                                                  }                                                                  }
814                                                          }                                                          }
815                                                  }                                                  }
816                                          }                                          }
817                                          else                                          else
818                                          {                                          {
819                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
820                                                  {                                                  {
821                                                          total2 += ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
822                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
823                                                  }                                                  }
824                                                  else                                                  else
825                                                  {                                                  {
826                                                          total2 += ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
827                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
828                                                  }                                                  }
829                                          }                                          }
830    
831                                            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    
843                                            total2 += dbytes2;
844                                  }                                  }
845    
846                                  ++frames;                                  ++frames;
# Line 583  Line 853 
853                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
854                                  char s[100];                                  char s[100];
855    
856                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
857                                  wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);                                  wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
858                                  DEBUG2P(s);                                  DEBUG2P(s);
859                          }                          }
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
860                  }                  }
861    
862                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
# Line 607  Line 875 
875                                  int i, newquant, percent;                                  int i, newquant, percent;
876                                  int oldquant = 1;                                  int oldquant = 1;
877    
878                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_frame));                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_pframe));
879                                  DEBUG2P(s);                                  DEBUG2P(s);
880    
881                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));
# Line 616  Line 884 
884                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)
885                                  {                                  {
886                                          dbytes = i;                                          dbytes = i;
887                                          if (dbytes > twopass->average_frame)                                          if (dbytes > twopass->average_pframe)
888                                          {                                          {
889                                                  if (dbytes >= twopass->alt_curve_high)                                                  if (dbytes >= twopass->alt_curve_high)
890                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
# Line 626  Line 894 
894                                                          {                                                          {
895                                                          case 2:                                                          case 2:
896                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
897                                                                  sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));                                                                  sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
898                                                                  break;                                                                  break;
899                                                          case 1:                                                          case 1:
900                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
901                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
902                                                                  break;                                                                  break;
903                                                          case 0:                                                          case 0:
904                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
905                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
906                                                          }                                                          }
907                                                  }                                                  }
908                                          }                                          }
# Line 648  Line 916 
916                                                          {                                                          {
917                                                          case 2:                                                          case 2:
918                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
919                                                                  sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));                                                                  sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
920                                                                  break;                                                                  break;
921                                                          case 1:                                                          case 1:
922                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
923                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
924                                                                  break;                                                                  break;
925                                                          case 0:                                                          case 0:
926                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
927                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
928                                                          }                                                          }
929                                                  }                                                  }
930                                          }                                          }
# Line 670  Line 938 
938                                                  if (newquant != oldquant)                                                  if (newquant != oldquant)
939                                                  {                                                  {
940                                                          oldquant = newquant;                                                          oldquant = newquant;
941                                                          percent = (int)((i - twopass->average_frame) * 100.0 / twopass->average_frame);                                                          percent = (int)((i - twopass->average_pframe) * 100.0 / twopass->average_pframe);
942                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);
943                                                          DEBUG2P(s);                                                          DEBUG2P(s);
944                                                  }                                                  }
# Line 680  Line 948 
948                  }                  }
949    
950                  twopass->overflow = 0;                  twopass->overflow = 0;
951                    twopass->KFoverflow = 0;
952                    twopass->KFoverflow_partial = 0;
953                    twopass->KF_idx = 1;
954    
955                  break;                  break;
956          }          }
# Line 687  Line 958 
958          return ICERR_OK;          return ICERR_OK;
959  }  }
960    
961    // NOTE: codec_2pass_get_quant() should be called for all the frames that are in the stats file(s)
962  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
963  {  {
964          static double quant_error[32];          static double bquant_error[32];
965            static double pquant_error[32];
966          static double curve_comp_error;          static double curve_comp_error;
967          static int last_quant;          static int last_bquant, last_pquant;
968    
969          TWOPASS * twopass = &codec->twopass;          TWOPASS * twopass = &codec->twopass;
970    
971          DWORD read;  //      DWORD read;
972          int bytes1, bytes2;          int bytes1, bytes2;
973          int overflow;          int overflow;
974          int credits_pos;          int credits_pos;
975            int capped_to_max_framesize = 0;
976            int KFdistance, KF_min_size;
977    
978          if (codec->framenum == 0)          if (codec->framenum == 0)
979          {          {
# Line 707  Line 981 
981    
982                  for (i=0 ; i<32 ; ++i)                  for (i=0 ; i<32 ; ++i)
983                  {                  {
984                          quant_error[i] = 0.0;                          bquant_error[i] = 0.0;
985                            pquant_error[i] = 0.0;
986                            twopass->quant_count[i] = 0;
987                  }                  }
988    
989                  curve_comp_error = 0.0;                  curve_comp_error = 0.0;
990                  last_quant = 0;                  last_bquant = 0;
991                    last_pquant = 0;
992          }          }
993    
994          if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))          if (twopass->nns_array_pos >= twopass->nns_array_length)
995            {
996                    // 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("2ndpass quant: couldn't read from stats1");                          DEBUGERR("ERROR: VIDEO EXCEEDS 1ST PASS!!!");
1005                  return ICERR_ERROR;                  return ICERR_ERROR;
1006          }          }
1007            }
1008    
1009            memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
1010          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
1011                    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          {          {
1019                  if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))                  twopass->bytes1 = bytes1;
1020                    twopass->bytes2 = bytes1;
1021                    twopass->desired_bytes2 = bytes1;
1022                    frame->intra = 3;
1023                    return ICERR_OK;
1024            }
1025            else if (twopass->nns1.dd_v & NNSTATS_PADFRAME)
1026                  {                  {
1027                          DEBUGERR("2ndpass quant: couldn't read from stats2");                  twopass->bytes1 = bytes1;
1028                          return ICERR_ERROR;                  twopass->bytes2 = bytes1;
1029                    twopass->desired_bytes2 = bytes1;
1030                    frame->intra = 4;
1031                    return ICERR_OK;
1032                  }                  }
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                    return ICERR_OK;
1040          }          }
1041    
         bytes1 = twopass->nns1.bytes;  
1042          overflow = twopass->overflow / 8;          overflow = twopass->overflow / 8;
1043    
1044          // override codec i-frame choice (reenable in credits)          // override codec i-frame choice (reenable in credits)
1045          frame->intra = (twopass->nns1.quant & NNSTATS_KEYFRAME);          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    
1052          if (frame->intra)          if (frame->intra==1)
1053          {          {
1054                  overflow = 0;                  overflow = 0;
1055          }          }
# Line 782  Line 1097 
1097                  }                  }
1098                  else    // DLG_MODE_2PASS_2_EXT                  else    // DLG_MODE_2PASS_2_EXT
1099                  {                  {
1100                            if (codec->config.credits_mode == CREDITS_MODE_QUANT)
1101                            {
1102                                    if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1103                                    {
1104                                            frame->quant = frame->intra == 1 ?
1105                                                    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;                          bytes2 = twopass->nns2.bytes;
1121                  }                  }
1122          }          }
# Line 791  Line 1126 
1126    
1127                  bytes2 = (codec->config.mode == DLG_MODE_2PASS_2_INT) ? bytes1 : twopass->nns2.bytes;                  bytes2 = (codec->config.mode == DLG_MODE_2PASS_2_INT) ? bytes1 : twopass->nns2.bytes;
1128    
1129                  if (frame->intra)                  if (frame->intra==1)
1130                  {                  {
1131                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
1132                                  twopass->movie_curve;                                  twopass->movie_curve;
# Line 801  Line 1136 
1136                          dbytes = bytes2 / twopass->movie_curve;                          dbytes = bytes2 / twopass->movie_curve;
1137                  }                  }
1138    
1139                    if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1140                            dbytes *= twopass->average_pframe / twopass->average_bframe;
1141    
1142                  // spread the compression error across payback_delay frames                  // spread the compression error across payback_delay frames
1143                  if (codec->config.bitrate_payback_method == 0)                  if (codec->config.bitrate_payback_method == 0)
1144                  {                  {
# Line 809  Line 1147 
1147                  else                  else
1148                  {                  {
1149                          bytes2 = (int)(curve_comp_error * dbytes /                          bytes2 = (int)(curve_comp_error * dbytes /
1150                                  twopass->average_frame / codec->config.bitrate_payback_delay);                                  twopass->average_pframe / codec->config.bitrate_payback_delay);
1151    
1152                          if (labs(bytes2) > fabs(curve_comp_error))                          if (labs(bytes2) > fabs(curve_comp_error))
1153                          {                          {
# Line 821  Line 1159 
1159    
1160                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
1161                  {                  {
1162                          if (!frame->intra)                          if (!(frame->intra==1))
1163                          {                          {
1164                                  if (dbytes > twopass->average_frame)                                  if (dbytes > twopass->average_pframe)
1165                                  {                                  {
1166                                          if (dbytes >= twopass->alt_curve_high)                                          if (dbytes >= twopass->alt_curve_high)
1167                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
# Line 833  Line 1171 
1171                                                  {                                                  {
1172                                                  case 2:                                                  case 2:
1173                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1174                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
1175                                                          break;                                                          break;
1176                                                  case 1:                                                  case 1:
1177                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1178                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
1179                                                          break;                                                          break;
1180                                                  case 0:                                                  case 0:
1181                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1182                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
1183                                                  }                                                  }
1184                                          }                                          }
1185                                  }                                  }
# Line 855  Line 1193 
1193                                                  {                                                  {
1194                                                  case 2:                                                  case 2:
1195                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1196                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
1197                                                          break;                                                          break;
1198                                                  case 1:                                                  case 1:
1199                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1200                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
1201                                                          break;                                                          break;
1202                                                  case 0:                                                  case 0:
1203                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
1204                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
1205                                                  }                                                  }
1206                                          }                                          }
1207                                  }                                  }
1208                                    if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1209                                            curve_temp *= twopass->average_bframe / twopass->average_pframe;
1210    
1211                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
1212    
1213                                  bytes2 += ((int)curve_temp);                                  bytes2 += ((int)curve_temp);
# Line 874  Line 1215 
1215                          }                          }
1216                          else                          else
1217                          {                          {
1218                                  curve_comp_error += dbytes - ((int)dbytes);                                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1219                                            dbytes *= twopass->average_bframe / twopass->average_pframe;
1220    
1221                                  bytes2 += ((int)dbytes);                                  bytes2 += ((int)dbytes);
1222                                    curve_comp_error += dbytes - ((int)dbytes);
1223                          }                          }
1224                  }                  }
1225                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
1226                          !frame->intra)                          !(frame->intra==1))
1227                  {                  {
1228                          if (dbytes > twopass->average_frame)                          if (dbytes > twopass->average_pframe)
1229                          {                          {
1230                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
1231                                          ((double)dbytes + (twopass->average_frame - dbytes) *                                          ((double)dbytes + (twopass->average_pframe - dbytes) *
1232                                          codec->config.curve_compression_high / 100.0);                                          codec->config.curve_compression_high / 100.0);
1233                          }                          }
1234                          else                          else
1235                          {                          {
1236                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
1237                                          ((double)dbytes + (twopass->average_frame - dbytes) *                                          ((double)dbytes + (twopass->average_pframe - dbytes) *
1238                                          codec->config.curve_compression_low / 100.0);                                          codec->config.curve_compression_low / 100.0);
1239                          }                          }
1240    
1241                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1242                                    curve_temp *= twopass->average_bframe / twopass->average_pframe;
1243    
1244                          bytes2 += ((int)curve_temp);                          bytes2 += ((int)curve_temp);
1245                          curve_comp_error += curve_temp - ((int)curve_temp);                          curve_comp_error += curve_temp - ((int)curve_temp);
1246                  }                  }
1247                  else                  else
1248                  {                  {
1249                          curve_comp_error += dbytes - ((int)dbytes);                          if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1250                                    dbytes *= twopass->average_bframe / twopass->average_pframe;
1251    
1252                          bytes2 += ((int)dbytes);                          bytes2 += ((int)dbytes);
1253                            curve_comp_error += dbytes - ((int)dbytes);
1254                  }                  }
1255    
1256                  // cap bytes2 to first pass size, lowers number of quant=1 frames                  // cap bytes2 to first pass size, lowers number of quant=1 frames
# Line 909  Line 1259 
1259                          curve_comp_error += bytes2 - bytes1;                          curve_comp_error += bytes2 - bytes1;
1260                          bytes2 = bytes1;                          bytes2 = bytes1;
1261                  }                  }
1262                  else if (bytes2 < 1)                  else
1263                  {                  {
1264                          curve_comp_error += --bytes2;                          if (frame->intra==1)
1265                          bytes2 = 1;                          {
1266                                    if (bytes2 < twopass->minisize)
1267                                    {
1268                                            curve_comp_error -= twopass->minisize - bytes2;
1269                                            bytes2 = twopass->minisize;
1270                                    }
1271                            }
1272                            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                  }                  }
1283          }          }
1284    
1285          twopass->desired_bytes2 = bytes2;          twopass->desired_bytes2 = bytes2;
1286    
1287            // if this keyframe is too close to the next,
1288            // reduce it's byte allotment
1289            if ((frame->intra==1) && !credits_pos)
1290            {
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          // Foxer: scale overflow in relation to average size, so smaller frames don't get          // Foxer: scale overflow in relation to average size, so smaller frames don't get
1314          // too much/little bitrate          // too much/little bitrate
1315          overflow = (int)((double)overflow * bytes2 / twopass->average_frame);          overflow = (int)((double)overflow * bytes2 / twopass->average_pframe);
1316    
1317          // Foxer: reign in overflow with huge frames          // Foxer: reign in overflow with huge frames
1318          if (labs(overflow) > labs(twopass->overflow))          if (labs(overflow) > labs(twopass->overflow))
# Line 929  Line 1321 
1321          }          }
1322    
1323          // Foxer: make sure overflow doesn't run away          // Foxer: make sure overflow doesn't run away
1324          if (overflow > bytes2 * 6 / 10)          if (overflow > bytes2 * codec->config.twopass_max_overflow_improvement / 100)
1325          {          {
1326                  bytes2 += (overflow <= bytes2) ? bytes2 * 6 / 10 : overflow * 6 / 10;                  bytes2 += (overflow <= bytes2) ? bytes2 * codec->config.twopass_max_overflow_improvement / 100 :
1327                            overflow * codec->config.twopass_max_overflow_improvement / 100;
1328          }          }
1329          else if (overflow < bytes2 * -6 / 10)          else if (overflow < bytes2 * codec->config.twopass_max_overflow_degradation / -100)
1330          {          {
1331                  bytes2 += bytes2 * -6 / 10;                  bytes2 += bytes2 * codec->config.twopass_max_overflow_degradation / -100;
1332          }          }
1333          else          else
1334          {          {
1335                  bytes2 += overflow;                  bytes2 += overflow;
1336          }          }
1337    
1338          if (bytes2 < 1)          if (bytes2 > twopass->max_framesize)
1339          {          {
1340                  bytes2 = 1;                  capped_to_max_framesize = 1;
1341                    bytes2 = twopass->max_framesize;
1342            }
1343    
1344            // make sure to not scale below the minimum framesize
1345            if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1346            {
1347                    if (bytes2 < twopass->minisize)
1348                            bytes2 = twopass->minisize;
1349            }
1350            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    
1361          twopass->bytes1 = bytes1;          twopass->bytes1 = bytes1;
# Line 961  Line 1372 
1372          {          {
1373                  frame->quant = 31;                  frame->quant = 31;
1374          }          }
1375          else if (!frame->intra)          else if (!(frame->intra==1))
1376          {          {
1377                  // Foxer: aid desired quantizer precision by accumulating decision error                  // Foxer: aid desired quantizer precision by accumulating decision error
1378                  quant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1379                    {
1380                            bquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1381                          bytes1) / bytes2) - frame->quant;                          bytes1) / bytes2) - frame->quant;
1382    
1383                  if (quant_error[frame->quant] >= 1.0)                          if (bquant_error[frame->quant] >= 1.0)
1384                  {                  {
1385                          quant_error[frame->quant] -= 1.0;                                  bquant_error[frame->quant] -= 1.0;
1386                          ++frame->quant;                          ++frame->quant;
1387                  }                  }
1388          }          }
1389                    else
1390                    {
1391                            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                    }
1400            }
1401    
1402          // we're done with credits          // we're done with credits
1403          if (codec_is_in_credits(&codec->config, codec->framenum))          if (codec_is_in_credits(&codec->config, codec->framenum))
# Line 980  Line 1405 
1405                  return ICERR_OK;                  return ICERR_OK;
1406          }          }
1407    
1408          if (frame->intra)          if ((frame->intra==1))
1409          {          {
1410                  if (frame->quant < codec->config.min_iquant)                  if (frame->quant < codec->config.min_iquant)
1411                  {                  {
# Line 1005  Line 1430 
1430                  }                  }
1431    
1432                  // subsequent frame quants can only be +- 2                  // subsequent frame quants can only be +- 2
1433                  if (last_quant)                  if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)
1434                    {
1435                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1436                  {                  {
1437                          if (frame->quant > last_quant + 2)                                  // this bframe quantizer variation
1438                                    // restriction needs to be redone.
1439                                    if (frame->quant > last_bquant + 2)
1440                          {                          {
1441                                  frame->quant = last_quant + 2;                                          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                            }
1450                            else
1451                            {
1452                                    if (frame->quant > last_pquant + 2)
1453                                    {
1454                                            frame->quant = last_pquant + 2;
1455                                  DEBUG2P("P-frame quantizer prevented from rising too steeply");                                  DEBUG2P("P-frame quantizer prevented from rising too steeply");
1456                          }                          }
1457                          if (frame->quant < last_quant - 2)                                  if (frame->quant < last_pquant - 2)
1458                          {                          {
1459                                  frame->quant = last_quant - 2;                                          frame->quant = last_pquant - 2;
1460                                  DEBUG2P("P-frame quantizer prevented from falling too steeply");                                  DEBUG2P("P-frame quantizer prevented from falling too steeply");
1461                          }                          }
1462                  }                  }
1463          }          }
1464            }
1465    
1466          last_quant = frame->quant;          if (capped_to_max_framesize == 0)
1467            {
1468                    if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1469                    {
1470                            last_bquant = frame->quant;
1471                            last_pquant = frame->quant;
1472                    }
1473                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1474                            last_bquant = frame->quant;
1475                    else
1476                            last_pquant = frame->quant;
1477            }
1478    
1479          if (codec->config.quant_type == QUANT_MODE_MOD)          if (codec->config.quant_type == QUANT_MODE_MOD)
1480          {          {
# Line 1028  Line 1482 
1482                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1483          }          }
1484    
1485            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    
1491          return ICERR_OK;          return ICERR_OK;
1492  }  }
1493    
# Line 1038  Line 1498 
1498    
1499          NNSTATS nns1;          NNSTATS nns1;
1500          DWORD wrote;          DWORD wrote;
1501            int credits_pos, tempdiv;
1502          char* quant_type;          char* quant_type;
1503            char* frame_type;
1504    
1505          if (codec->framenum == 0)          if (codec->framenum == 0)
1506          {          {
# Line 1053  Line 1515 
1515          {          {
1516          case DLG_MODE_2PASS_1 :          case DLG_MODE_2PASS_1 :
1517                  nns1.bytes = frame->length;     // total bytes                  nns1.bytes = frame->length;     // total bytes
1518                  nns1.dd_v = stats->hlength;     // header bytes  // THIS small bugger messed up 2pass encoding!
1519    //              nns1.dd_v = stats->hlength;     // header bytes
1520                    nns1.dd_v = 0;
1521                  nns1.dd_u = nns1.dd_y = 0;                  nns1.dd_u = nns1.dd_y = 0;
1522                  nns1.dk_v = nns1.dk_u = nns1.dk_y = 0;                  nns1.dk_v = nns1.dk_u = nns1.dk_y = 0;
1523                  nns1.md_u = nns1.md_y = 0;                  nns1.md_u = nns1.md_y = 0;
1524                  nns1.mk_u = nns1.mk_y = 0;                  nns1.mk_u = nns1.mk_y = 0;
1525    
1526                  nns1.quant = stats->quant;  //              nns1.quant = stats->quant;
1527                  if (frame->intra)                  nns1.quant = 2;                         // ugly fix for lumi masking in 1st pass returning new quant
1528                  {                  nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1529                    frame_type="inter";
1530                    if (frame->intra==1) {
1531                          nns1.quant |= NNSTATS_KEYFRAME;                          nns1.quant |= NNSTATS_KEYFRAME;
1532                            frame_type="intra";
1533                    }
1534                    else if (frame->intra==2) {
1535                            nns1.dd_v |= NNSTATS_BFRAME;
1536                            frame_type="bframe";
1537                    }
1538                    else if (frame->intra==3) {
1539                            nns1.dd_v |= NNSTATS_SKIPFRAME;
1540                            frame_type="skiped";
1541                    }
1542                    else if (frame->intra==4) {
1543                            nns1.dd_v |= NNSTATS_PADFRAME;
1544                            frame_type="padded";
1545                    }
1546                    else if (frame->intra==5) {
1547                            nns1.dd_v |= NNSTATS_DELAYFRAME;
1548                            frame_type="delayed";
1549                  }                  }
1550                  nns1.kblk = stats->kblks;                  nns1.kblk = stats->kblks;
1551                  nns1.mblk = stats->mblks;                  nns1.mblk = stats->mblks;
1552                  nns1.ublk = stats->ublks;                  nns1.ublk = stats->ublks;
                 nns1.lum_noise[0] = nns1.lum_noise[1] = 1;  
1553    
1554                  total_size += frame->length;                  total_size += frame->length;
1555    
1556                  DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, quant_type, stats->kblks, stats->mblks)                  DEBUG1ST(frame->length, (int)total_size/1024, frame_type, frame->quant, quant_type, stats->kblks, stats->mblks)
1557    
1558    
1559                  if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS))                  if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS))
1560                  {                  {
# Line 1083  Line 1565 
1565    
1566          case DLG_MODE_2PASS_2_INT :          case DLG_MODE_2PASS_2_INT :
1567          case DLG_MODE_2PASS_2_EXT :          case DLG_MODE_2PASS_2_EXT :
1568                    credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1569                    if (!(codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&
1570                            !(codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) &&
1571                            !(codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME))
1572                    {
1573                            if (!credits_pos)
1574                            {
1575                                    codec->twopass.quant_count[frame->quant]++;
1576                                    if ((codec->twopass.nns1.quant & NNSTATS_KEYFRAME))
1577                                    {
1578                                            // calculate how much to distribute per frame in
1579                                            // order to make up for this keyframe's overflow
1580    
1581                                            codec->twopass.overflow += codec->twopass.KFoverflow;
1582                                            codec->twopass.KFoverflow = codec->twopass.desired_bytes2 - frame->length;
1583    
1584                                            tempdiv = (codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1585                                                    codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1]);
1586    
1587                                            if (tempdiv > 1)
1588                                            {
1589                                                    // non-consecutive keyframes
1590                                                    codec->twopass.KFoverflow_partial = codec->twopass.KFoverflow / (tempdiv - 1);
1591                                            }
1592                                            else
1593                                            {
1594                                                    // consecutive keyframes
1595                                                    codec->twopass.overflow += codec->twopass.KFoverflow;
1596                                                    codec->twopass.KFoverflow = 0;
1597                                                    codec->twopass.KFoverflow_partial = 0;
1598                                            }
1599                                            codec->twopass.KF_idx++;
1600                                    }
1601                                    else
1602                                    {
1603                                            // distribute part of the keyframe overflow
1604    
1605                                            codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length +
1606                                                    codec->twopass.KFoverflow_partial;
1607                                            codec->twopass.KFoverflow -= codec->twopass.KFoverflow_partial;
1608                                    }
1609                            }
1610                            else
1611                            {
1612                  codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;                  codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;
1613                  DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, codec_is_in_credits(&codec->config, codec->framenum))  
1614                                    // ugly fix for credits..
1615                                    codec->twopass.overflow += codec->twopass.KFoverflow;
1616                                    codec->twopass.KFoverflow = 0;
1617                                    codec->twopass.KFoverflow_partial = 0;
1618                                    // end of ugly fix.
1619                            }
1620                    }
1621    
1622                    frame_type="inter";
1623                    if (frame->intra==1) {
1624                            frame_type="intra";
1625                    }
1626                    else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME) {
1627                            frame_type="bframe";
1628                    }
1629                    else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {
1630                            frame_type="skipped";
1631                            frame->quant = 2;
1632                            codec->twopass.bytes1 = 1;
1633                            codec->twopass.desired_bytes2 = 1;
1634                            frame->length = 1;
1635                    }
1636                    else if (codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) {
1637                            frame_type="padded";
1638                            frame->quant = 2;
1639                            codec->twopass.bytes1 = 7;
1640                            codec->twopass.desired_bytes2 = 7;
1641                            frame->length = 7;
1642                    }
1643                    else if (codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {
1644                            frame_type="delayed";
1645                            frame->quant = 2;
1646                            codec->twopass.bytes1 = 1;
1647                            codec->twopass.desired_bytes2 = 1;
1648                            frame->length = 1;
1649                    }
1650    
1651                    DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
1652                  break;                  break;
1653    
1654          default:          default:
# Line 1094  Line 1658 
1658          return ICERR_OK;          return ICERR_OK;
1659  }  }
1660    
1661    void codec_2pass_finish(CODEC* codec)
1662    {
1663            int i;
1664            char s[100];
1665    
1666            if (codec->twopass.nns1_array)
1667            {
1668                    free(codec->twopass.nns1_array);
1669                    codec->twopass.nns1_array = NULL;
1670            }
1671            if (codec->twopass.nns2_array)
1672            {
1673                    free(codec->twopass.nns2_array);
1674                    codec->twopass.nns2_array = NULL;
1675            }
1676            codec->twopass.nns_array_size = 0;
1677            codec->twopass.nns_array_length = 0;
1678            codec->twopass.nns_array_pos = 0;
1679    
1680            if (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT)
1681            {
1682                    // output the quantizer distribution for this encode.
1683    
1684                    OutputDebugString("Quantizer distribution for 2nd pass:");
1685                    for (i=1; i<=31; i++)
1686                    {
1687                            if (codec->twopass.quant_count[i])
1688                            {
1689                                    wsprintf(s, "Q:%i:%i", i, codec->twopass.quant_count[i]);
1690                                    OutputDebugString(s);
1691                            }
1692                    }
1693                    return;
1694            }
1695    }
1696    

Legend:
Removed from v.102  
changed lines
  Added in v.814

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