[svn] / trunk / vfw / src / 2pass.c Repository:
ViewVC logotype

Diff of /trunk/vfw/src/2pass.c

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

revision 856, Sun Feb 16 03:59:01 2003 UTC revision 857, Sun Feb 16 04:23:29 2003 UTC
# Line 41  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, recminpsize = 0, recminisize = 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;          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          {          {
59                  codec->twopass.hintstream = malloc(100000);                  codec->twopass.hintstream = malloc(100000);
# Line 101  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 158  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;                                                  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)                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)
323                                  {                                  {
324                                            // this test needs to be corrected..
325                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))
326                                                  recminisize = twopass->nns1.bytes;                                                  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                                  else
334                                  {                                  {
335                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))
# Line 189  Line 340 
340                          }                          }
341                          twopass->keyframe_locations[i_frames] = frames;                          twopass->keyframe_locations[i_frames] = frames;
342    
343                          twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);                          twopass->movie_curve = ((double)(bframe_total_ext + pframe_total_ext + i_boost_total) /
344                          twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);                                  (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    
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 223  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                                                  CloseHandle(twopass->stats1);                                  memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
422                                                  CloseHandle(twopass->stats2);                                  twopass->nns_array_pos++;
                                                 twopass->stats1 = INVALID_HANDLE_VALUE;  
                                                 twopass->stats2 = INVALID_HANDLE_VALUE;  
                                                 DEBUGERR("2pass init error - incomplete stats1/stats2 record?");  
                                                 return ICERR_ERROR;  
                                         }  
                                 }  
423    
424                                  if (frames == 0)                                  if (frames == 0)
425                                  {                                  {
426                                            twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
427                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
428                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
429                                            if (recminbsize > twopass->minbsize)
430                                                    twopass->minbsize = recminbsize;
431                                          if (recminpsize > twopass->minpsize)                                          if (recminpsize > twopass->minpsize)
432                                                  twopass->minpsize = recminpsize;                                                  twopass->minpsize = recminpsize;
433                                          if (recminisize > twopass->minisize)                                          if (recminisize > twopass->minisize)
434                                                  twopass->minisize = recminisize;                                                  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                                          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                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
# Line 292  Line 461 
461                                                                  {                                                                  {
462                                                                  case 2:                                                                  case 2:
463                                                                  dbytes2 = 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                                                                  dbytes2 = 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                                                                  dbytes2 = 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                                                  }                                                  }
# Line 314  Line 483 
483                                                                  {                                                                  {
484                                                                  case 2:                                                                  case 2:
485                                                                  dbytes2 = 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                                                                  dbytes2 = 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                                                                  dbytes2 = 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                                                          dbytes2 = ((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                                                          dbytes2 = ((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)                                          if (dbytes2 < twopass->minpsize)
522                                                  dbytes2 = twopass->minpsize;                                                  dbytes2 = twopass->minpsize;
523                                            }
524    
525                                          total2 += dbytes2;                                          total2 += dbytes2;
526                                  }                                  }
# Line 357  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 399  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;
                                         total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;  
575                                          twopass->keyframe_locations[i_frames] = frames;                                          twopass->keyframe_locations[i_frames] = frames;
576                                          ++i_frames;                                          ++i_frames;
577                                  }                                  }
578                                    else
579                                  total += twopass->nns1.bytes;                                  {
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                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)
593                                  {                                  {
594                                            // this test needs to be corrected..
595                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))
596                                                  recminisize = twopass->nns1.bytes;                                                  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                                  else
604                                  {                                  {
605                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))
# Line 430  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 446  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 469  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 511  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                                                  CloseHandle(twopass->stats1);                                  twopass->nns_array_pos++;
                                                 twopass->stats1 = INVALID_HANDLE_VALUE;  
                                                 DEBUGERR("2pass init error - incomplete stats2 record?");  
                                                 return ICERR_ERROR;  
                                         }  
                                 }  
741    
742                                  if (frames == 0)                                  if (frames == 0)
743                                  {                                  {
744                                            twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
745                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
746                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
747                                            if (recminbsize > twopass->minbsize)
748                                                    twopass->minbsize = recminbsize;
749                                          if (recminpsize > twopass->minpsize)                                          if (recminpsize > twopass->minpsize)
750                                                  twopass->minpsize = recminpsize;                                                  twopass->minpsize = recminpsize;
751                                          if (recminisize > twopass->minisize)                                          if (recminisize > twopass->minisize)
752                                                  twopass->minisize = recminisize;                                                  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                                          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                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
# Line 577  Line 779 
779                                                                  {                                                                  {
780                                                                  case 2:                                                                  case 2:
781                                                                  dbytes2 = 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                                                                  dbytes2 = 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                                                                  dbytes2 = 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                                                  }                                                  }
# Line 599  Line 801 
801                                                                  {                                                                  {
802                                                                  case 2:                                                                  case 2:
803                                                                  dbytes2 = 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                                                                  dbytes2 = 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                                                                  dbytes2 = 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                                                          dbytes2 = ((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                                                          dbytes2 = ((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)                                          if (dbytes2 < twopass->minpsize)
840                                                  dbytes2 = twopass->minpsize;                                                  dbytes2 = twopass->minpsize;
841                                            }
842    
843                                          total2 += dbytes2;                                          total2 += dbytes2;
844                                  }                                  }
# Line 642  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 666  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 675  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 685  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 707  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 729  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 749  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;
# Line 771  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;                          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                  DEBUGERR("2ndpass quant: couldn't read from stats1");                          return ICERR_OK;
1001                    }
1002                    else
1003                    {
1004                            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 851  Line 1101 
1101                          {                          {
1102                                  if (codec->config.credits_quant_i != codec->config.credits_quant_p)                                  if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1103                                  {                                  {
1104                                          frame->quant = frame->intra ?                                          frame->quant = frame->intra == 1 ?
1105                                                  codec->config.credits_quant_i :                                                  codec->config.credits_quant_i :
1106                                                  codec->config.credits_quant_p;                                                  codec->config.credits_quant_p;
1107                                  }                                  }
# Line 876  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 886  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 894  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 906  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 918  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 940  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 959  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 996  Line 1261 
1261                  }                  }
1262                  else                  else
1263                  {                  {
1264                          if (frame->intra)                          if (frame->intra==1)
1265                          {                          {
1266                                  if (bytes2 < twopass->minisize)                                  if (bytes2 < twopass->minisize)
1267                                  {                                  {
# Line 1004  Line 1269 
1269                                          bytes2 = twopass->minisize;                                          bytes2 = twopass->minisize;
1270                                  }                                  }
1271                          }                          }
1272                          else if (bytes2 < twopass->minpsize)                          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;                                  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,          // if this keyframe is too close to the next,
1288          // reduce it's byte allotment          // reduce it's byte allotment
1289          if (frame->intra && !credits_pos)          if ((frame->intra==1) && !credits_pos)
1290          {          {
1291                  KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -                  KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1292                          codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];                          codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];
# Line 1039  Line 1312 
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 1074  Line 1347 
1347                  if (bytes2 < twopass->minisize)                  if (bytes2 < twopass->minisize)
1348                          bytes2 = twopass->minisize;                          bytes2 = twopass->minisize;
1349          }          }
1350          else if (bytes2 < twopass->minpsize)          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;                  bytes2 = twopass->minpsize;
1359            }
1360    
1361          twopass->bytes1 = bytes1;          twopass->bytes1 = bytes1;
1362          twopass->bytes2 = bytes2;          twopass->bytes2 = bytes2;
# Line 1091  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 1110  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 1135  Line 1430 
1430                  }                  }
1431    
1432                  // subsequent frame quants can only be +- 2                  // subsequent frame quants can only be +- 2
1433                  if (last_quant && capped_to_max_framesize == 0)                  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          if (capped_to_max_framesize == 0)          if (capped_to_max_framesize == 0)
1467                  last_quant = frame->quant;          {
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 1159  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 1171  Line 1500 
1500          DWORD wrote;          DWORD wrote;
1501          int credits_pos, tempdiv;          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 1185  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;
# Line 1194  Line 1525 
1525    
1526  //              nns1.quant = stats->quant;  //              nns1.quant = stats->quant;
1527                  nns1.quant = 2;                         // ugly fix for lumi masking in 1st pass returning new quant                  nns1.quant = 2;                         // ugly fix for lumi masking in 1st pass returning new quant
1528                  if (frame->intra)                  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 1217  Line 1566 
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);                  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)                  if (!credits_pos)
1574                  {                  {
1575                          codec->twopass.quant_count[frame->quant]++;                          codec->twopass.quant_count[frame->quant]++;
# Line 1264  Line 1617 
1617                          codec->twopass.KFoverflow_partial = 0;                          codec->twopass.KFoverflow_partial = 0;
1618                          // end of ugly fix.                          // end of ugly fix.
1619                  }                  }
1620                    }
1621    
1622                  DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)                  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 1279  Line 1662 
1662  {  {
1663          int i;          int i;
1664          char s[100];          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)          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.                  // output the quantizer distribution for this encode.

Legend:
Removed from v.856  
changed lines
  Added in v.857

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