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

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

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

revision 528, Mon Sep 23 06:11:34 2002 UTC revision 679, Wed Nov 27 11:41:45 2002 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;          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;
# Line 101  Line 101 
101                          return ICERR_ERROR;                          return ICERR_ERROR;
102                  }                  }
103    
104                    twopass->nns1_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);
105                    twopass->nns2_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);
106                    twopass->nns_array_size = 10240;
107                    twopass->nns_array_length = 0;
108                    twopass->nns_array_pos = 0;
109    
110                    // read the stats file(s) into array(s) and reorder them so they
111                    // correctly represent the frames that the encoder will receive.
112                  if (codec->config.mode == DLG_MODE_2PASS_2_EXT)                  if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
113                  {                  {
114                          if (twopass->stats2 != INVALID_HANDLE_VALUE)                          if (twopass->stats2 != INVALID_HANDLE_VALUE)
# Line 158  Line 166 
166                                          }                                          }
167                                  }                                  }
168    
169                                    // increase the allocated memory if necessary
170                                    if (frames >= twopass->nns_array_size)
171                                    {
172                                            twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array,
173                                                    sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
174                                            twopass->nns2_array = (NNSTATS*)realloc(twopass->nns2_array,
175                                                    sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
176                                            twopass->nns_array_size = twopass->nns_array_size * 5 / 4 + 1;
177                                    }
178    
179                                    // copy this frame's stats into the arrays
180                                    memcpy (&twopass->nns1_array[frames], &twopass->nns1, sizeof(NNSTATS));
181                                    memcpy (&twopass->nns2_array[frames], &twopass->nns2, sizeof(NNSTATS));
182                                    frames++;
183                            }
184    
185                            SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
186                            SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
187                    }
188                    else    // DLG_MODE_2PASS_2_INT
189                    {
190                            while (1)
191                            {
192                                    if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
193                                    {
194                                            DWORD err = GetLastError();
195    
196                                            if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
197                                            {
198                                                    break;
199                                            }
200                                            else
201                                            {
202                                                    CloseHandle(twopass->stats1);
203                                                    twopass->stats1 = INVALID_HANDLE_VALUE;
204                                                    DEBUGERR("2pass init error - incomplete stats2 record?");
205                                                    return ICERR_ERROR;
206                                            }
207                                    }
208    
209                                    // increase the allocated memory if necessary
210                                    if (frames >= twopass->nns_array_size)
211                                    {
212                                            twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array,
213                                                    sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
214                                            twopass->nns_array_size = twopass->nns_array_size * 5 / 4 + 1;
215                                    }
216    
217                                    // copy this frame's stats into the array
218                                    memcpy (&twopass->nns1_array[frames], &twopass->nns1, sizeof(NNSTATS));
219                                    frames++;
220                            }
221    
222                            SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
223                    }
224                    twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array, sizeof(NNSTATS) * frames);
225                    twopass->nns2_array = (NNSTATS*)realloc(twopass->nns2_array, sizeof(NNSTATS) * frames);
226                    twopass->nns_array_size = frames;
227                    twopass->nns_array_length = frames;
228                    frames = 0;
229    
230    /* // this isn't necessary with the current core.
231                    // reorder the array(s) so they are in the order that they were received
232                    // IPBBPBB to
233                    // IBBPBBP
234                    for (i=0; i<twopass->nns_array_length; i++)
235                    {
236                            NNSTATS temp_nns, temp_nns2;
237                            int k, num_bframes;
238                            if (twopass->nns1_array[i].dd_v & NNSTATS_BFRAME)
239                            {
240                                    num_bframes = 1;
241                                    for (k=i+1; k<twopass->nns_array_length; k++)
242                                    {
243                                            if (twopass->nns1_array[k].dd_v & NNSTATS_BFRAME)
244                                                    num_bframes++;
245                                            else
246                                                    k=twopass->nns_array_length;
247                                    }
248    
249                                    i--;
250                                    memcpy (&temp_nns, &twopass->nns1_array[i], sizeof(NNSTATS));
251                                    if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
252                                            memcpy (&temp_nns2, &twopass->nns2_array[i], sizeof(NNSTATS));
253    
254                                    for (k=0; k<num_bframes; k++)
255                                    {
256                                            memcpy(&twopass->nns1_array[i], &twopass->nns1_array[i+1], sizeof(NNSTATS));
257                                            if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
258                                                    memcpy(&twopass->nns2_array[i], &twopass->nns2_array[i+1], sizeof(NNSTATS));
259                                            i++;
260                                    }
261    
262                                    memcpy(&twopass->nns1_array[i], &temp_nns, sizeof(NNSTATS));
263                                    if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
264                                            memcpy(&twopass->nns2_array[i], &temp_nns2, sizeof(NNSTATS));
265                            }
266                    }
267    */
268                    // continue with the initialization..
269                    if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
270                    {
271                            while (1)
272                            {
273                                    if (twopass->nns_array_pos >= twopass->nns_array_length)
274                                    {
275                                            twopass->nns_array_pos = 0;
276                                            break;
277                                    }
278    
279                                    memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
280                                    memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
281                                    twopass->nns_array_pos++;
282    
283                                    // skip unnecessary frames.
284                                    if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
285                                            twopass->nns1.dd_v & NNSTATS_PADFRAME ||
286                                            twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
287                                            continue;
288    
289                                  if (!codec_is_in_credits(&codec->config, frames))                                  if (!codec_is_in_credits(&codec->config, frames))
290                                  {                                  {
291                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)
292                                          {                                          {
                                                 i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;  
293                                                  i_total += twopass->nns2.bytes;                                                  i_total += twopass->nns2.bytes;
294                                                    i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;
295                                                  twopass->keyframe_locations[i_frames] = frames;                                                  twopass->keyframe_locations[i_frames] = frames;
296                                                  ++i_frames;                                                  ++i_frames;
297                                          }                                          }
298                                            else
299                                          total += twopass->nns1.bytes;                                          {
300                                          total_ext += twopass->nns2.bytes;                                                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
301                                                    {
302                                                            bframe_total += twopass->nns1.bytes;
303                                                            bframe_total_ext += twopass->nns2.bytes;
304                                                            bframes++;
305                                                    }
306                                                    else
307                                                    {
308                                                            pframe_total += twopass->nns1.bytes;
309                                                            pframe_total_ext += twopass->nns2.bytes;
310                                                            pframes++;
311                                                    }
312                                            }
313                                  }                                  }
314                                  else                                  else
315                                          ++credits_frames;                                          ++credits_frames;
316    
317                                    if (twopass->nns1.quant & NNSTATS_KEYFRAME)
318                                    {
319                                            // this test needs to be corrected..
320                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
321                                                    recminisize = twopass->nns1.bytes;
322                                    }
323                                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
324                                    {
325                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
326                                                    recminbsize = twopass->nns1.bytes;
327                                    }
328                                    else
329                                    {
330                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
331                                                    recminpsize = twopass->nns1.bytes;
332                                    }
333    
334                                  ++frames;                                  ++frames;
335                          }                          }
336                          twopass->keyframe_locations[i_frames] = frames;                          twopass->keyframe_locations[i_frames] = frames;
337    
338                          twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);                          twopass->movie_curve = ((double)(bframe_total_ext + pframe_total_ext + i_boost_total) /
339                          twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);                                  (bframe_total_ext + pframe_total_ext));
340    
341                            if (bframes)
342                                    twopass->average_bframe = (double)bframe_total_ext / bframes / twopass->movie_curve;
343    
344                            if (pframes)
345                                    twopass->average_pframe = (double)pframe_total_ext / pframes / twopass->movie_curve;
346                            else
347                                    if (bframes)
348                                            twopass->average_pframe = twopass->average_bframe;  // b-frame packed bitstream fix
349                                    else
350                                    {
351                                            DEBUGERR("ERROR:  No p-frames or b-frames were present in the 1st pass.  Rate control cannot function properly!");
352                                            return ICERR_ERROR;
353                                    }
354    
355    
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
                         SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);  
356    
357                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
358                          frames = 0;                          frames = 0;
359    
360                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
361                          {                          {
362                                  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;
363                                  twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
364                                  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;
365                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
366                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
367                                  {                                  {
368                                          if (total > total_ext)                                          if (bframe_total + pframe_total > bframe_total_ext + pframe_total_ext)
369                                          {                                          {
370                                                  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 /
371                                                            ((double)(bframe_total + pframe_total) / (double)(bframe_total_ext + pframe_total_ext))) *
372                                                            (double)codec->config.alt_curve_auto_str / 100.0);
373    
374                                                  if (codec->config.alt_curve_min_rel_qual < 20)                                                  if (codec->config.alt_curve_min_rel_qual < 20)
375                                                          codec->config.alt_curve_min_rel_qual = 20;                                                          codec->config.alt_curve_min_rel_qual = 20;
376                                          }                                          }
# Line 212  Line 385 
385                                          {                                          {
386                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
387                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
388                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
389                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
390                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
391                                                  break;                                                  break;
392                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
393                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
394                                                          twopass->average_frame / twopass->alt_curve_low_diff);                                                          twopass->average_pframe / twopass->alt_curve_low_diff);
395                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
396                                                          twopass->average_frame / twopass->alt_curve_low_diff;                                                          twopass->average_pframe / twopass->alt_curve_low_diff;
397                                                  break;                                                  break;
398                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
399                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
400                                                          (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))));
401                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
402                                                          (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)));
403                                          }                                          }
404                                  }                                  }
405                          }                          }
406    
407                          while (1)                          while (1)
408                          {                          {
409                                  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)  
410                                          {                                          {
411                                            twopass->nns_array_pos = 0;
412                                                  break;                                                  break;
413                                          }                                          }
414                                          else  
415                                          {                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
416                                                  CloseHandle(twopass->stats1);                                  memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
417                                                  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;  
                                         }  
                                 }  
418    
419                                  if (frames == 0)                                  if (frames == 0)
420                                  {                                  {
421                                            twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
422                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
423                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
424                                            if (recminbsize > twopass->minbsize)
425                                                    twopass->minbsize = recminbsize;
426                                            if (recminpsize > twopass->minpsize)
427                                                    twopass->minpsize = recminpsize;
428                                            if (recminisize > twopass->minisize)
429                                                    twopass->minisize = recminisize;
430                                  }                                  }
431    
432                                    // skip unnecessary frames.
433                                    if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
434                                            twopass->nns1.dd_v & NNSTATS_PADFRAME ||
435                                            twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
436                                            continue;
437    
438                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
439                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
440                                  {                                  {
441                                          dbytes = twopass->nns2.bytes / twopass->movie_curve;                                          dbytes = twopass->nns2.bytes / twopass->movie_curve;
442                                          total1 += dbytes;                                          total1 += dbytes;
443    
444                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
445                                                    dbytes *= twopass->average_pframe / twopass->average_bframe;
446    
447                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
448                                          {                                          {
449                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
450                                                  {                                                  {
451                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
452                                                                  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 277  Line 456 
456                                                                  {                                                                  {
457                                                                  case 2:                                                                  case 2:
458                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
459                                                                          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)));
460                                                                          break;                                                                          break;
461                                                                  case 1:                                                                  case 1:
462                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
463                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
464                                                                          break;                                                                          break;
465                                                                  case 0:                                                                  case 0:
466                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
467                                                                          (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))));
468                                                                  }                                                                  }
469                                                          }                                                          }
470                                                  }                                                  }
# Line 299  Line 478 
478                                                                  {                                                                  {
479                                                                  case 2:                                                                  case 2:
480                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
481                                                                          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)));
482                                                                          break;                                                                          break;
483                                                                  case 1:                                                                  case 1:
484                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
485                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
486                                                                          break;                                                                          break;
487                                                                  case 0:                                                                  case 0:
488                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
489                                                                          (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))));
490                                                                  }                                                                  }
491                                                          }                                                          }
492                                                  }                                                  }
493                                          }                                          }
494                                          else                                          else
495                                          {                                          {
496                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
497                                                  {                                                  {
498                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
499                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
500                                                  }                                                  }
501                                                  else                                                  else
502                                                  {                                                  {
503                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
504                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
505                                                  }                                                  }
506                                          }                                          }
507    
508                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
509                                            {
510                                                    dbytes2 *= twopass->average_bframe / twopass->average_pframe;
511                                                    if (dbytes2 < twopass->minbsize)
512                                                            dbytes2 = twopass->minbsize;
513                                            }
514                                            else
515                                            {
516                                          if (dbytes2 < twopass->minpsize)                                          if (dbytes2 < twopass->minpsize)
517                                                  dbytes2 = twopass->minpsize;                                                  dbytes2 = twopass->minpsize;
518                                            }
519    
520                                          total2 += dbytes2;                                          total2 += dbytes2;
521                                  }                                  }
# Line 342  Line 530 
530                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
531                                  char s[100];                                  char s[100];
532    
533                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
534                                  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);
535                                  DEBUG2P(s);                                  DEBUG2P(s);
536                          }                          }
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
                         SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);  
537                  }                  }
538                  else    // DLG_MODE_2PASS_2_INT                  else    // DLG_MODE_2PASS_2_INT
539                  {                  {
540                          while (1)                          while (1)
541                          {                          {
542                                  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)  
543                                          {                                          {
544                                            twopass->nns_array_pos = 0;
545                                                  break;                                                  break;
546                                          }                                          }
547                                          else  
548                                          {                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
549                                                  CloseHandle(twopass->stats1);                                  twopass->nns_array_pos++;
550                                                  twopass->stats1 = INVALID_HANDLE_VALUE;  
551                                                  DEBUGERR("2pass init error - incomplete stats2 record?");                                  // skip unnecessary frames.
552                                                  return ICERR_ERROR;                                  if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
553                                          }                                          twopass->nns1.dd_v & NNSTATS_PADFRAME ||
554                                  }                                          twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
555                                            continue;
556    
557                                  if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)                                  if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)
558                                  {                                  {
# Line 384  Line 567 
567                                  else if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                  else if (twopass->nns1.quant & NNSTATS_KEYFRAME)
568                                  {                                  {
569                                          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;  
570                                          twopass->keyframe_locations[i_frames] = frames;                                          twopass->keyframe_locations[i_frames] = frames;
571                                          ++i_frames;                                          ++i_frames;
572                                  }                                  }
573                                    else
574                                    {
575                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
576                                            {
577                                                    bframe_total += twopass->nns1.bytes;
578                                                    bframes++;
579                                            }
580                                            else
581                                            {
582                                                    pframe_total += twopass->nns1.bytes;
583                                                    pframes++;
584                                            }
585                                    }
586    
587                                  total += twopass->nns1.bytes;                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)
588                                    {
589                                            // this test needs to be corrected..
590                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
591                                                    recminisize = twopass->nns1.bytes;
592                                    }
593                                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
594                                    {
595                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
596                                                    recminbsize = twopass->nns1.bytes;
597                                    }
598                                    else
599                                    {
600                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
601                                                    recminpsize = twopass->nns1.bytes;
602                                    }
603    
604                                  ++frames;                                  ++frames;
605                          }                          }
# Line 404  Line 614 
614    
615                                  // credits curve = (total / desired_size) * (100 / credits_rate)                                  // credits curve = (total / desired_size) * (100 / credits_rate)
616                                  twopass->credits_start_curve = twopass->credits_end_curve =                                  twopass->credits_start_curve = twopass->credits_end_curve =
617                                          ((double)total / desired) * ((double)100 / codec->config.credits_rate);                                          ((double)(bframe_total + pframe_total + i_total + start + end) / desired) *
618                                            ((double)100 / codec->config.credits_rate);
619    
620                                  start_curved = (__int64)(start / twopass->credits_start_curve);                                  start_curved = (__int64)(start / twopass->credits_start_curve);
621                                  end_curved = (__int64)(end / twopass->credits_end_curve);                                  end_curved = (__int64)(end / twopass->credits_end_curve);
622    
623                                  // movie curve = (total - credits) / (desired_size - curved credits)                                  // movie curve = (total - credits) / (desired_size - curved credits)
624                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
625                                          (total - start - end) /                                          (bframe_total + pframe_total + i_total) /
626                                          (desired - start_curved - end_curved);                                          (desired - start_curved - end_curved);
627    
628                                  break;                                  break;
# Line 420  Line 631 
631    
632                                  // movie curve = (total - credits) / (desired_size - credits)                                  // movie curve = (total - credits) / (desired_size - credits)
633                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
634                                          (total - start - end) / (desired - start - end);                                          (bframe_total + pframe_total + i_total) / (desired - start - end);
635    
636                                  // aid the average asymmetric frame calculation below                                  // aid the average asymmetric frame calculation below
637                                  start_curved = start;                                  start_curved = start;
# Line 443  Line 654 
654    
655                                  // movie curve = (total - credits) / (desired_size - curved credits)                                  // movie curve = (total - credits) / (desired_size - curved credits)
656                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
657                                          (total - start - end) /                                          (bframe_total + pframe_total + i_total) /
658                                          (desired - start_curved - end_curved);                                          (desired - start_curved - end_curved);
659    
660                                  break;                                  break;
661                          }                          }
662    
663                          // average frame size = (desired - curved credits - curved keyframes) /                          twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve;
664                          //      (frames - credits frames - keyframes)                          twopass->average_pframe = (double)pframe_total / pframes / twopass->movie_curve;
665                          twopass->average_frame = (double)  
                                 (desired - start_curved - end_curved - (i_total / twopass->movie_curve)) /  
                                 (frames - credits_frames - i_frames);  
666    
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
667    
668                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
669                          frames = 0;                          frames = 0;
670    
671                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
672                          {                          {
673                                  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;
674                                  twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
675                                  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;
676                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
677                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
678                                  {                                  {
679                                          if (twopass->movie_curve > 1.0)                                          if (twopass->movie_curve > 1.0)
# Line 485  Line 693 
693                                          {                                          {
694                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
695                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
696                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
697                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
698                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
699                                                  break;                                                  break;
700                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
701                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
702                                                          twopass->average_frame / twopass->alt_curve_low_diff);                                                          twopass->average_pframe / twopass->alt_curve_low_diff);
703                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
704                                                          twopass->average_frame / twopass->alt_curve_low_diff;                                                          twopass->average_pframe / twopass->alt_curve_low_diff;
705                                                  break;                                                  break;
706                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
707                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
708                                                          (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))));
709                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
710                                                          (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)));
711                                          }                                          }
712                                  }                                  }
713                          }                          }
714    
715                          while (1)                          while (1)
716                          {                          {
717                                  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)  
718                                          {                                          {
719                                            twopass->nns_array_pos = 0;
720                                                  break;                                                  break;
721                                          }                                          }
722                                          else  
723                                          {                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
724                                                  CloseHandle(twopass->stats1);                                  twopass->nns_array_pos++;
                                                 twopass->stats1 = INVALID_HANDLE_VALUE;  
                                                 DEBUGERR("2pass init error - incomplete stats2 record?");  
                                                 return ICERR_ERROR;  
                                         }  
                                 }  
725    
726                                  if (frames == 0)                                  if (frames == 0)
727                                  {                                  {
728                                            twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
729                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
730                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
731                                            if (recminbsize > twopass->minbsize)
732                                                    twopass->minbsize = recminbsize;
733                                            if (recminpsize > twopass->minpsize)
734                                                    twopass->minpsize = recminpsize;
735                                            if (recminisize > twopass->minisize)
736                                                    twopass->minisize = recminisize;
737                                  }                                  }
738    
739                                    // skip unnecessary frames.
740                                    if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
741                                            twopass->nns1.dd_v & NNSTATS_PADFRAME ||
742                                            twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
743                                            continue;
744    
745                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
746                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
747                                  {                                  {
748                                          dbytes = twopass->nns1.bytes / twopass->movie_curve;                                          dbytes = twopass->nns1.bytes / twopass->movie_curve;
749                                          total1 += dbytes;                                          total1 += dbytes;
750    
751                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
752                                                    dbytes *= twopass->average_pframe / twopass->average_bframe;
753    
754                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
755                                          {                                          {
756                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
757                                                  {                                                  {
758                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
759                                                                  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 547  Line 763 
763                                                                  {                                                                  {
764                                                                  case 2:                                                                  case 2:
765                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
766                                                                          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)));
767                                                                          break;                                                                          break;
768                                                                  case 1:                                                                  case 1:
769                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
770                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
771                                                                          break;                                                                          break;
772                                                                  case 0:                                                                  case 0:
773                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
774                                                                          (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))));
775                                                                  }                                                                  }
776                                                          }                                                          }
777                                                  }                                                  }
# Line 569  Line 785 
785                                                                  {                                                                  {
786                                                                  case 2:                                                                  case 2:
787                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
788                                                                          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)));
789                                                                          break;                                                                          break;
790                                                                  case 1:                                                                  case 1:
791                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
792                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
793                                                                          break;                                                                          break;
794                                                                  case 0:                                                                  case 0:
795                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
796                                                                          (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))));
797                                                                  }                                                                  }
798                                                          }                                                          }
799                                                  }                                                  }
800                                          }                                          }
801                                          else                                          else
802                                          {                                          {
803                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
804                                                  {                                                  {
805                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
806                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
807                                                  }                                                  }
808                                                  else                                                  else
809                                                  {                                                  {
810                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
811                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
812                                                  }                                                  }
813                                          }                                          }
814    
815                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
816                                            {
817                                                    dbytes2 *= twopass->average_bframe / twopass->average_pframe;
818                                                    if (dbytes2 < twopass->minbsize)
819                                                            dbytes2 = twopass->minbsize;
820                                            }
821                                            else
822                                            {
823                                          if (dbytes2 < twopass->minpsize)                                          if (dbytes2 < twopass->minpsize)
824                                                  dbytes2 = twopass->minpsize;                                                  dbytes2 = twopass->minpsize;
825                                            }
826    
827                                          total2 += dbytes2;                                          total2 += dbytes2;
828                                  }                                  }
# Line 612  Line 837 
837                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
838                                  char s[100];                                  char s[100];
839    
840                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
841                                  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);
842                                  DEBUG2P(s);                                  DEBUG2P(s);
843                          }                          }
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
844                  }                  }
845    
846                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
# Line 636  Line 859 
859                                  int i, newquant, percent;                                  int i, newquant, percent;
860                                  int oldquant = 1;                                  int oldquant = 1;
861    
862                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_frame));                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_pframe));
863                                  DEBUG2P(s);                                  DEBUG2P(s);
864    
865                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));
# Line 645  Line 868 
868                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)
869                                  {                                  {
870                                          dbytes = i;                                          dbytes = i;
871                                          if (dbytes > twopass->average_frame)                                          if (dbytes > twopass->average_pframe)
872                                          {                                          {
873                                                  if (dbytes >= twopass->alt_curve_high)                                                  if (dbytes >= twopass->alt_curve_high)
874                                                          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 655  Line 878 
878                                                          {                                                          {
879                                                          case 2:                                                          case 2:
880                                                          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 *
881                                                                  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)));
882                                                                  break;                                                                  break;
883                                                          case 1:                                                          case 1:
884                                                          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 *
885                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
886                                                                  break;                                                                  break;
887                                                          case 0:                                                          case 0:
888                                                          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 *
889                                                                  (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))));
890                                                          }                                                          }
891                                                  }                                                  }
892                                          }                                          }
# Line 677  Line 900 
900                                                          {                                                          {
901                                                          case 2:                                                          case 2:
902                                                          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 *
903                                                                  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)));
904                                                                  break;                                                                  break;
905                                                          case 1:                                                          case 1:
906                                                          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 *
907                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
908                                                                  break;                                                                  break;
909                                                          case 0:                                                          case 0:
910                                                          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 *
911                                                                  (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))));
912                                                          }                                                          }
913                                                  }                                                  }
914                                          }                                          }
# Line 699  Line 922 
922                                                  if (newquant != oldquant)                                                  if (newquant != oldquant)
923                                                  {                                                  {
924                                                          oldquant = newquant;                                                          oldquant = newquant;
925                                                          percent = (int)((i - twopass->average_frame) * 100.0 / twopass->average_frame);                                                          percent = (int)((i - twopass->average_pframe) * 100.0 / twopass->average_pframe);
926                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);
927                                                          DEBUG2P(s);                                                          DEBUG2P(s);
928                                                  }                                                  }
# Line 719  Line 942 
942          return ICERR_OK;          return ICERR_OK;
943  }  }
944    
945    // NOTE: codec_2pass_get_quant() should be called for all the frames that are in the stats file(s)
946  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
947  {  {
948          static double quant_error[32];          static double bquant_error[32];
949            static double pquant_error[32];
950          static double curve_comp_error;          static double curve_comp_error;
951          static int last_quant;          static int last_bquant, last_pquant;
952    
953          TWOPASS * twopass = &codec->twopass;          TWOPASS * twopass = &codec->twopass;
954    
955          DWORD read;  //      DWORD read;
956          int bytes1, bytes2;          int bytes1, bytes2;
957          int overflow;          int overflow;
958          int credits_pos;          int credits_pos;
# Line 741  Line 965 
965    
966                  for (i=0 ; i<32 ; ++i)                  for (i=0 ; i<32 ; ++i)
967                  {                  {
968                          quant_error[i] = 0.0;                          bquant_error[i] = 0.0;
969                            pquant_error[i] = 0.0;
970                          twopass->quant_count[i] = 0;                          twopass->quant_count[i] = 0;
971                  }                  }
972    
973                  curve_comp_error = 0.0;                  curve_comp_error = 0.0;
974                  last_quant = 0;                  last_bquant = 0;
975                    last_pquant = 0;
976          }          }
977    
978          if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))          if (twopass->nns_array_pos >= twopass->nns_array_length)
979          {          {
980                  DEBUGERR("2ndpass quant: couldn't read from stats1");                  twopass->nns_array_pos = 0;
981                    DEBUGERR("ERROR: VIDEO EXCEEDS 1ST PASS!!!");
982                  return ICERR_ERROR;                  return ICERR_ERROR;
983          }          }
984    
985            memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
986          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
987                    memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
988            twopass->nns_array_pos++;
989    
990            bytes1 = twopass->nns1.bytes;
991    
992            // skip unnecessary frames.
993            if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME)
994          {          {
995                  if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))                  twopass->bytes1 = bytes1;
996                    twopass->bytes2 = bytes1;
997                    twopass->desired_bytes2 = bytes1;
998                    frame->intra = 3;
999                    return 2;
1000            }
1001            else if (twopass->nns1.dd_v & NNSTATS_PADFRAME)
1002                  {                  {
1003                          DEBUGERR("2ndpass quant: couldn't read from stats2");                  twopass->bytes1 = bytes1;
1004                          return ICERR_ERROR;                  twopass->bytes2 = bytes1;
1005                    twopass->desired_bytes2 = bytes1;
1006                    frame->intra = 4;
1007                    return 2;
1008                  }                  }
1009            else if (twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
1010            {
1011                    twopass->bytes1 = bytes1;
1012                    twopass->bytes2 = bytes1;
1013                    twopass->desired_bytes2 = bytes1;
1014                    frame->intra = 5;
1015                    return 2;
1016          }          }
1017    
         bytes1 = twopass->nns1.bytes;  
1018          overflow = twopass->overflow / 8;          overflow = twopass->overflow / 8;
1019    
1020          // override codec i-frame choice (reenable in credits)          // override codec i-frame choice (reenable in credits)
1021          frame->intra = (twopass->nns1.quant & NNSTATS_KEYFRAME);          if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1022                    frame->intra=1;
1023            else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1024                    frame->intra=2;
1025            else
1026                    frame->intra=0;
1027    
1028          if (frame->intra)          if (frame->intra==1)
1029          {          {
1030                  overflow = 0;                  overflow = 0;
1031          }          }
# Line 821  Line 1077 
1077                          {                          {
1078                                  if (codec->config.credits_quant_i != codec->config.credits_quant_p)                                  if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1079                                  {                                  {
1080                                          frame->quant = frame->intra ?                                          frame->quant = frame->intra == 1 ?
1081                                                  codec->config.credits_quant_i :                                                  codec->config.credits_quant_i :
1082                                                  codec->config.credits_quant_p;                                                  codec->config.credits_quant_p;
1083                                  }                                  }
# Line 846  Line 1102 
1102    
1103                  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;
1104    
1105                  if (frame->intra)                  if (frame->intra==1)
1106                  {                  {
1107                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
1108                                  twopass->movie_curve;                                  twopass->movie_curve;
# Line 856  Line 1112 
1112                          dbytes = bytes2 / twopass->movie_curve;                          dbytes = bytes2 / twopass->movie_curve;
1113                  }                  }
1114    
1115                    if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1116                            dbytes *= twopass->average_pframe / twopass->average_bframe;
1117    
1118                  // spread the compression error across payback_delay frames                  // spread the compression error across payback_delay frames
1119                  if (codec->config.bitrate_payback_method == 0)                  if (codec->config.bitrate_payback_method == 0)
1120                  {                  {
# Line 864  Line 1123 
1123                  else                  else
1124                  {                  {
1125                          bytes2 = (int)(curve_comp_error * dbytes /                          bytes2 = (int)(curve_comp_error * dbytes /
1126                                  twopass->average_frame / codec->config.bitrate_payback_delay);                                  twopass->average_pframe / codec->config.bitrate_payback_delay);
1127    
1128                          if (labs(bytes2) > fabs(curve_comp_error))                          if (labs(bytes2) > fabs(curve_comp_error))
1129                          {                          {
# Line 876  Line 1135 
1135    
1136                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
1137                  {                  {
1138                          if (!frame->intra)                          if (!(frame->intra==1))
1139                          {                          {
1140                                  if (dbytes > twopass->average_frame)                                  if (dbytes > twopass->average_pframe)
1141                                  {                                  {
1142                                          if (dbytes >= twopass->alt_curve_high)                                          if (dbytes >= twopass->alt_curve_high)
1143                                                  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 888  Line 1147 
1147                                                  {                                                  {
1148                                                  case 2:                                                  case 2:
1149                                                  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 *
1150                                                          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)));
1151                                                          break;                                                          break;
1152                                                  case 1:                                                  case 1:
1153                                                  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 *
1154                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
1155                                                          break;                                                          break;
1156                                                  case 0:                                                  case 0:
1157                                                  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 *
1158                                                          (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))));
1159                                                  }                                                  }
1160                                          }                                          }
1161                                  }                                  }
# Line 910  Line 1169 
1169                                                  {                                                  {
1170                                                  case 2:                                                  case 2:
1171                                                  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 *
1172                                                          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)));
1173                                                          break;                                                          break;
1174                                                  case 1:                                                  case 1:
1175                                                  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 *
1176                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
1177                                                          break;                                                          break;
1178                                                  case 0:                                                  case 0:
1179                                                  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 *
1180                                                          (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))));
1181                                                  }                                                  }
1182                                          }                                          }
1183                                  }                                  }
1184                                    if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1185                                            curve_temp *= twopass->average_bframe / twopass->average_pframe;
1186    
1187                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
1188    
1189                                  bytes2 += ((int)curve_temp);                                  bytes2 += ((int)curve_temp);
# Line 929  Line 1191 
1191                          }                          }
1192                          else                          else
1193                          {                          {
1194                                  curve_comp_error += dbytes - ((int)dbytes);                                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1195                                            dbytes *= twopass->average_bframe / twopass->average_pframe;
1196    
1197                                  bytes2 += ((int)dbytes);                                  bytes2 += ((int)dbytes);
1198                                    curve_comp_error += dbytes - ((int)dbytes);
1199                          }                          }
1200                  }                  }
1201                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
1202                          !frame->intra)                          !(frame->intra==1))
1203                  {                  {
1204                          if (dbytes > twopass->average_frame)                          if (dbytes > twopass->average_pframe)
1205                          {                          {
1206                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
1207                                          ((double)dbytes + (twopass->average_frame - dbytes) *                                          ((double)dbytes + (twopass->average_pframe - dbytes) *
1208                                          codec->config.curve_compression_high / 100.0);                                          codec->config.curve_compression_high / 100.0);
1209                          }                          }
1210                          else                          else
1211                          {                          {
1212                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
1213                                          ((double)dbytes + (twopass->average_frame - dbytes) *                                          ((double)dbytes + (twopass->average_pframe - dbytes) *
1214                                          codec->config.curve_compression_low / 100.0);                                          codec->config.curve_compression_low / 100.0);
1215                          }                          }
1216    
1217                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1218                                    curve_temp *= twopass->average_bframe / twopass->average_pframe;
1219    
1220                          bytes2 += ((int)curve_temp);                          bytes2 += ((int)curve_temp);
1221                          curve_comp_error += curve_temp - ((int)curve_temp);                          curve_comp_error += curve_temp - ((int)curve_temp);
1222                  }                  }
1223                  else                  else
1224                  {                  {
1225                          curve_comp_error += dbytes - ((int)dbytes);                          if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1226                                    dbytes *= twopass->average_bframe / twopass->average_pframe;
1227    
1228                          bytes2 += ((int)dbytes);                          bytes2 += ((int)dbytes);
1229                            curve_comp_error += dbytes - ((int)dbytes);
1230                  }                  }
1231    
1232                  if (frame->intra)                  // cap bytes2 to first pass size, lowers number of quant=1 frames
1233                    if (bytes2 > bytes1)
1234                    {
1235                            curve_comp_error += bytes2 - bytes1;
1236                            bytes2 = bytes1;
1237                    }
1238                    else
1239                    {
1240                            if (frame->intra==1)
1241                  {                  {
1242                          if (bytes2 < twopass->minisize)                          if (bytes2 < twopass->minisize)
1243                          {                          {
# Line 966  Line 1245 
1245                                  bytes2 = twopass->minisize;                                  bytes2 = twopass->minisize;
1246                          }                          }
1247                  }                  }
1248                  else                          else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
                 {  
                         // cap bytes2 to first pass size, lowers number of quant=1 frames  
                         if (bytes2 > bytes1)  
1249                          {                          {
1250                                  curve_comp_error += bytes2 - bytes1;                                  if (bytes2 < twopass->minbsize)
1251                                  bytes2 = bytes1;                                          bytes2 = twopass->minbsize;
1252                          }                          }
1253                          else if (bytes2 < twopass->minpsize)                          else
1254                            {
1255                                    if (bytes2 < twopass->minpsize)
1256                                  bytes2 = twopass->minpsize;                                  bytes2 = twopass->minpsize;
1257                  }                  }
1258          }          }
1259            }
1260    
1261          twopass->desired_bytes2 = bytes2;          twopass->desired_bytes2 = bytes2;
1262    
1263          // if this keyframe is too close to the next,          // if this keyframe is too close to the next,
1264          // reduce it's byte allotment          // reduce it's byte allotment
1265          if (frame->intra && !credits_pos)          if ((frame->intra==1) && !credits_pos)
1266          {          {
1267                  KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -                  KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1268                          codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];                          codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];
# Line 1009  Line 1288 
1288    
1289          // 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
1290          // too much/little bitrate          // too much/little bitrate
1291          overflow = (int)((double)overflow * bytes2 / twopass->average_frame *          overflow = (int)((double)overflow * bytes2 / twopass->average_pframe);
                 (bytes1 - bytes2) / bytes1);  
1292    
1293          // Foxer: reign in overflow with huge frames          // Foxer: reign in overflow with huge frames
1294          if (labs(overflow) > labs(twopass->overflow))          if (labs(overflow) > labs(twopass->overflow))
# Line 1039  Line 1317 
1317                  bytes2 = twopass->max_framesize;                  bytes2 = twopass->max_framesize;
1318          }          }
1319    
1320          if (bytes2 < 1)          // make sure to not scale below the minimum framesize
1321            if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1322          {          {
1323                  bytes2 = 1;                  if (bytes2 < twopass->minisize)
1324                            bytes2 = twopass->minisize;
1325            }
1326            else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1327            {
1328                    if (bytes2 < twopass->minbsize)
1329                            bytes2 = twopass->minbsize;
1330            }
1331            else
1332            {
1333                    if (bytes2 < twopass->minpsize)
1334                            bytes2 = twopass->minpsize;
1335          }          }
1336    
1337          twopass->bytes1 = bytes1;          twopass->bytes1 = bytes1;
# Line 1058  Line 1348 
1348          {          {
1349                  frame->quant = 31;                  frame->quant = 31;
1350          }          }
1351          else if (!frame->intra)          else if (!(frame->intra==1))
1352          {          {
1353                  // Foxer: aid desired quantizer precision by accumulating decision error                  // Foxer: aid desired quantizer precision by accumulating decision error
1354                  quant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1355                    {
1356                            bquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1357                                    bytes1) / bytes2) - frame->quant;
1358    
1359                            if (bquant_error[frame->quant] >= 1.0)
1360                            {
1361                                    bquant_error[frame->quant] -= 1.0;
1362                                    ++frame->quant;
1363                            }
1364                    }
1365                    else
1366                    {
1367                            pquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1368                          bytes1) / bytes2) - frame->quant;                          bytes1) / bytes2) - frame->quant;
1369    
1370                  if (quant_error[frame->quant] >= 1.0)                          if (pquant_error[frame->quant] >= 1.0)
1371                  {                  {
1372                          quant_error[frame->quant] -= 1.0;                                  pquant_error[frame->quant] -= 1.0;
1373                          ++frame->quant;                          ++frame->quant;
1374                  }                  }
1375          }          }
1376            }
1377    
1378          // we're done with credits          // we're done with credits
1379          if (codec_is_in_credits(&codec->config, codec->framenum))          if (codec_is_in_credits(&codec->config, codec->framenum))
# Line 1077  Line 1381 
1381                  return ICERR_OK;                  return ICERR_OK;
1382          }          }
1383    
1384          if (frame->intra)          if ((frame->intra==1))
1385          {          {
1386                  if (frame->quant < codec->config.min_iquant)                  if (frame->quant < codec->config.min_iquant)
1387                  {                  {
# Line 1102  Line 1406 
1406                  }                  }
1407    
1408                  // subsequent frame quants can only be +- 2                  // subsequent frame quants can only be +- 2
1409                  if (last_quant && capped_to_max_framesize == 0)                  if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)
1410                    {
1411                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1412                            {
1413                                    // this bframe quantizer variation
1414                                    // restriction needs to be redone.
1415                                    if (frame->quant > last_bquant + 2)
1416                                    {
1417                                            frame->quant = last_bquant + 2;
1418                                            DEBUG2P("B-frame quantizer prevented from rising too steeply");
1419                                    }
1420                                    if (frame->quant < last_bquant - 2)
1421                                    {
1422                                            frame->quant = last_bquant - 2;
1423                                            DEBUG2P("B-frame quantizer prevented from falling too steeply");
1424                                    }
1425                            }
1426                            else
1427                  {                  {
1428                          if (frame->quant > last_quant + 2)                                  if (frame->quant > last_pquant + 2)
1429                          {                          {
1430                                  frame->quant = last_quant + 2;                                          frame->quant = last_pquant + 2;
1431                                  DEBUG2P("P-frame quantizer prevented from rising too steeply");                                  DEBUG2P("P-frame quantizer prevented from rising too steeply");
1432                          }                          }
1433                          if (frame->quant < last_quant - 2)                                  if (frame->quant < last_pquant - 2)
1434                          {                          {
1435                                  frame->quant = last_quant - 2;                                          frame->quant = last_pquant - 2;
1436                                  DEBUG2P("P-frame quantizer prevented from falling too steeply");                                  DEBUG2P("P-frame quantizer prevented from falling too steeply");
1437                          }                          }
1438                  }                  }
1439          }          }
1440            }
1441    
1442          if (capped_to_max_framesize == 0)          if (capped_to_max_framesize == 0)
1443                  last_quant = frame->quant;          {
1444                    if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1445                    {
1446                            last_bquant = frame->quant;
1447                            last_pquant = frame->quant;
1448                    }
1449                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1450                            last_bquant = frame->quant;
1451                    else
1452                            last_pquant = frame->quant;
1453            }
1454    
1455          if (codec->config.quant_type == QUANT_MODE_MOD)          if (codec->config.quant_type == QUANT_MODE_MOD)
1456          {          {
1457                  frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;                  frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;
1458                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1459          }          }
1460    /*
1461            if (codec->config.quant_type == QUANT_MODE_MOD_NEW)
1462            {
1463                    frame->general |= (frame->quant < 4) ? XVID_H263QUANT : XVID_MPEGQUANT;
1464                    frame->general &= (frame->quant < 4) ? ~XVID_MPEGQUANT : ~XVID_H263QUANT;
1465            }
1466    */
1467          return ICERR_OK;          return ICERR_OK;
1468  }  }
1469    
# Line 1138  Line 1476 
1476          DWORD wrote;          DWORD wrote;
1477          int credits_pos, tempdiv;          int credits_pos, tempdiv;
1478          char* quant_type;          char* quant_type;
1479            char* frame_type;
1480    
1481          if (codec->framenum == 0)          if (codec->framenum == 0)
1482          {          {
# Line 1161  Line 1500 
1500    
1501  //              nns1.quant = stats->quant;  //              nns1.quant = stats->quant;
1502                  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
1503                  if (frame->intra)                  nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1504                  {                  frame_type="inter";
1505                    if (frame->intra==1) {
1506                          nns1.quant |= NNSTATS_KEYFRAME;                          nns1.quant |= NNSTATS_KEYFRAME;
1507                            frame_type="intra";
1508                    }
1509                    else if (frame->intra==2) {
1510                            nns1.dd_v |= NNSTATS_BFRAME;
1511                            frame_type="bframe";
1512                    }
1513                    else if (frame->intra==3) {
1514                            nns1.dd_v |= NNSTATS_SKIPFRAME;
1515                            frame_type="skiped";
1516                    }
1517                    else if (frame->intra==4) {
1518                            nns1.dd_v |= NNSTATS_PADFRAME;
1519                            frame_type="padded";
1520                    }
1521                    else if (frame->intra==5) {
1522                            nns1.dd_v |= NNSTATS_DELAYFRAME;
1523                            frame_type="delayed";
1524                  }                  }
1525                  nns1.kblk = stats->kblks;                  nns1.kblk = stats->kblks;
1526                  nns1.mblk = stats->mblks;                  nns1.mblk = stats->mblks;
1527                  nns1.ublk = stats->ublks;                  nns1.ublk = stats->ublks;
                 nns1.lum_noise[0] = nns1.lum_noise[1] = 1;  
1528    
1529                  total_size += frame->length;                  total_size += frame->length;
1530    
1531                  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)
1532    
1533    
1534                  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))
1535                  {                  {
# Line 1184  Line 1541 
1541          case DLG_MODE_2PASS_2_INT :          case DLG_MODE_2PASS_2_INT :
1542          case DLG_MODE_2PASS_2_EXT :          case DLG_MODE_2PASS_2_EXT :
1543                  credits_pos = codec_is_in_credits(&codec->config, codec->framenum);                  credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1544                    if (!(codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&
1545                            !(codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) &&
1546                            !(codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME))
1547                    {
1548                  if (!credits_pos)                  if (!credits_pos)
1549                  {                  {
1550                          codec->twopass.quant_count[frame->quant]++;                          codec->twopass.quant_count[frame->quant]++;
# Line 1231  Line 1592 
1592                          codec->twopass.KFoverflow_partial = 0;                          codec->twopass.KFoverflow_partial = 0;
1593                          // end of ugly fix.                          // end of ugly fix.
1594                  }                  }
1595                    }
1596    
1597                  DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)                  frame_type="inter";
1598                    if (frame->intra==1) {
1599                            frame_type="intra";
1600                    }
1601                    else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME) {
1602                            frame_type="bframe";
1603                    }
1604                    else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {
1605                            frame_type="skipped";
1606                            frame->quant = 2;
1607                            codec->twopass.bytes1 = 1;
1608                            codec->twopass.desired_bytes2 = 1;
1609                            frame->length = 1;
1610                    }
1611                    else if (codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) {
1612                            frame_type="padded";
1613                            frame->quant = 2;
1614                            codec->twopass.bytes1 = 7;
1615                            codec->twopass.desired_bytes2 = 7;
1616                            frame->length = 7;
1617                    }
1618                    else if (codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {
1619                            frame_type="delayed";
1620                            frame->quant = 2;
1621                            codec->twopass.bytes1 = 1;
1622                            codec->twopass.desired_bytes2 = 1;
1623                            frame->length = 1;
1624                    }
1625    
1626                    DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
1627                  break;                  break;
1628    
1629          default:          default:
# Line 1246  Line 1637 
1637  {  {
1638          int i;          int i;
1639          char s[100];          char s[100];
1640    
1641            if (codec->twopass.nns1_array)
1642            {
1643                    free(codec->twopass.nns1_array);
1644                    codec->twopass.nns1_array = NULL;
1645            }
1646            if (codec->twopass.nns2_array)
1647            {
1648                    free(codec->twopass.nns2_array);
1649                    codec->twopass.nns2_array = NULL;
1650            }
1651            codec->twopass.nns_array_size = 0;
1652            codec->twopass.nns_array_length = 0;
1653            codec->twopass.nns_array_pos = 0;
1654    
1655          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)
1656          {          {
1657                  // output the quantizer distribution for this encode.                  // output the quantizer distribution for this encode.
# Line 1262  Line 1668 
1668                  return;                  return;
1669          }          }
1670  }  }
1671    

Legend:
Removed from v.528  
changed lines
  Added in v.679

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