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

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

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

trunk/vfw/src/2pass.c revision 109, Mon Apr 8 12:51:41 2002 UTC branches/dev-api-3/vfw/src/2pass.c revision 687, Thu Nov 28 07:43:16 2002 UTC
# Line 23  Line 23 
23   *   *
24   *      History:   *      History:
25   *   *
26     *      17.04.2002      changed 1st pass quant to always be 2 (2pass_update())
27   *      07.04.2002      added max bitrate constraint, overflow controls (foxer)   *      07.04.2002      added max bitrate constraint, overflow controls (foxer)
28   *      31.03.2002      inital version;   *      31.03.2002      inital version;
29   *   *
# Line 40  Line 41 
41          DWORD version = -20;          DWORD version = -20;
42          DWORD read, wrote;          DWORD read, wrote;
43    
44          int     frames = 0, credits_frames = 0, i_frames = 0;          int     frames = 0, bframes = 0, pframes = 0, credits_frames = 0, i_frames = 0, recminbsize = 0, recminpsize = 0, recminisize = 0;
45          __int64 total_ext = 0, total = 0, i_total = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0;          __int64 bframe_total_ext = 0, pframe_total_ext = 0, pframe_total = 0, bframe_total = 0, i_total = 0, i_total_ext = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0;
46          __int64 desired = (__int64)codec->config.desired_size * 1024;          __int64 desired = (__int64)codec->config.desired_size * 1024;
47    
48          double total1 = 0.0;          double total1 = 0.0;
49          double total2 = 0.0;          double total2 = 0.0;
50            double dbytes, dbytes2;
51    
52          if (codec->config.hinted_me)          if (codec->config.hinted_me)
53          {          {
# Line 99  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 156  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;
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;
337    
338                            twopass->movie_curve = ((double)(bframe_total_ext + pframe_total_ext + i_boost_total) /
339                                    (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    
                         twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);  
                         twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);  
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 208  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                                    memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
417                                    twopass->nns_array_pos++;
418    
419                                    if (frames == 0)
420                                          {                                          {
421                                                  CloseHandle(twopass->stats1);                                          twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
422                                                  CloseHandle(twopass->stats2);                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
423                                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
424                                                  twopass->stats2 = INVALID_HANDLE_VALUE;                                          if (recminbsize > twopass->minbsize)
425                                                  DEBUGERR("2pass init error - incomplete stats1/stats2 record?");                                                  twopass->minbsize = recminbsize;
426                                                  return ICERR_ERROR;                                          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                                          double 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                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
453                                                          else                                                          else
454                                                          {                                                          {
455                                                                  switch(codec->config.alt_curve_type)                                                                  switch(codec->config.alt_curve_type)
456                                                                  {                                                                  {
457                                                                  case 2:                                                                  case 2:
458                                                                  total2 += 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                                                                  total2 += 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                                                                  total2 += 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                                                  }                                                  }
471                                                  else                                                  else
472                                                  {                                                  {
473                                                          if (dbytes <= twopass->alt_curve_low)                                                          if (dbytes <= twopass->alt_curve_low)
474                                                                  total2 += dbytes;                                                                  dbytes2 = dbytes;
475                                                          else                                                          else
476                                                          {                                                          {
477                                                                  switch(codec->config.alt_curve_type)                                                                  switch(codec->config.alt_curve_type)
478                                                                  {                                                                  {
479                                                                  case 2:                                                                  case 2:
480                                                                  total2 += 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                                                                  total2 += 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                                                                  total2 += 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                                                          total2 += ((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                                                          total2 += ((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)
517                                                            dbytes2 = twopass->minpsize;
518                                            }
519    
520                                            total2 += dbytes2;
521                                  }                                  }
522    
523                                  ++frames;                                  ++frames;
# Line 327  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 369  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;
570                                          total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;                                          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                          }                          }
606                            twopass->keyframe_locations[i_frames] = frames;
607    
608                          // compensate for avi frame overhead                          // compensate for avi frame overhead
609                          desired -= frames * 24;                          desired -= frames * 24;
# Line 387  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 403  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 426  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) /                          if (bframes)
664                          //      (frames - credits frames - keyframes)                                  twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve;
665                          twopass->average_frame = (double)  
666                                  (desired - start_curved - end_curved - (i_total / twopass->movie_curve)) /                          if (pframes)
667                                  (frames - credits_frames - i_frames);                                  twopass->average_pframe = (double)pframe_total / pframes / twopass->movie_curve;
668                            else
669                                    if (bframes)
670                                            twopass->average_pframe = twopass->average_bframe;  // b-frame packed bitstream fix
671                                    else
672                                    {
673                                            DEBUGERR("ERROR:  No p-frames or b-frames were present in the 1st pass.  Rate control cannot function properly!");
674                                            return ICERR_ERROR;
675                                    }
676    
677    
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
678    
679                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
680                          frames = 0;                          frames = 0;
681    
682                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
683                          {                          {
684                                  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;
685                                  twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
686                                  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;
687                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
688                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
689                                  {                                  {
690                                          if (twopass->movie_curve > 1.0)                                          if (twopass->movie_curve > 1.0)
# Line 468  Line 704 
704                                          {                                          {
705                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
706                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
707                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
708                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
709                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
710                                                  break;                                                  break;
711                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
712                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
713                                                          twopass->average_frame / twopass->alt_curve_low_diff);                                                          twopass->average_pframe / twopass->alt_curve_low_diff);
714                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
715                                                          twopass->average_frame / twopass->alt_curve_low_diff;                                                          twopass->average_pframe / twopass->alt_curve_low_diff;
716                                                  break;                                                  break;
717                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
718                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
719                                                          (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))));
720                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
721                                                          (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)));
722                                          }                                          }
723                                  }                                  }
724                          }                          }
725    
726                          while (1)                          while (1)
727                          {                          {
728                                  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)  
729                                          {                                          {
730                                            twopass->nns_array_pos = 0;
731                                                  break;                                                  break;
732                                          }                                          }
733                                          else  
734                                    memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
735                                    twopass->nns_array_pos++;
736    
737                                    if (frames == 0)
738                                          {                                          {
739                                                  CloseHandle(twopass->stats1);                                          twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
740                                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
741                                                  DEBUGERR("2pass init error - incomplete stats2 record?");                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
742                                                  return ICERR_ERROR;                                          if (recminbsize > twopass->minbsize)
743                                          }                                                  twopass->minbsize = recminbsize;
744                                            if (recminpsize > twopass->minpsize)
745                                                    twopass->minpsize = recminpsize;
746                                            if (recminisize > twopass->minisize)
747                                                    twopass->minisize = recminisize;
748                                  }                                  }
749    
750                                    // skip unnecessary frames.
751                                    if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
752                                            twopass->nns1.dd_v & NNSTATS_PADFRAME ||
753                                            twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
754                                            continue;
755    
756                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
757                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
758                                  {                                  {
759                                          double dbytes = twopass->nns1.bytes / twopass->movie_curve;                                          dbytes = twopass->nns1.bytes / twopass->movie_curve;
760                                          total1 += dbytes;                                          total1 += dbytes;
761    
762                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
763                                                    dbytes *= twopass->average_pframe / twopass->average_bframe;
764    
765                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
766                                          {                                          {
767                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
768                                                  {                                                  {
769                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
770                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
771                                                          else                                                          else
772                                                          {                                                          {
773                                                                  switch(codec->config.alt_curve_type)                                                                  switch(codec->config.alt_curve_type)
774                                                                  {                                                                  {
775                                                                  case 2:                                                                  case 2:
776                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
777                                                                          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)));
778                                                                          break;                                                                          break;
779                                                                  case 1:                                                                  case 1:
780                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
781                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
782                                                                          break;                                                                          break;
783                                                                  case 0:                                                                  case 0:
784                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
785                                                                          (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))));
786                                                                  }                                                                  }
787                                                          }                                                          }
788                                                  }                                                  }
789                                                  else                                                  else
790                                                  {                                                  {
791                                                          if (dbytes <= twopass->alt_curve_low)                                                          if (dbytes <= twopass->alt_curve_low)
792                                                                  total2 += dbytes;                                                                  dbytes2 = dbytes;
793                                                          else                                                          else
794                                                          {                                                          {
795                                                                  switch(codec->config.alt_curve_type)                                                                  switch(codec->config.alt_curve_type)
796                                                                  {                                                                  {
797                                                                  case 2:                                                                  case 2:
798                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
799                                                                          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)));
800                                                                          break;                                                                          break;
801                                                                  case 1:                                                                  case 1:
802                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
803                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
804                                                                          break;                                                                          break;
805                                                                  case 0:                                                                  case 0:
806                                                                  total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
807                                                                          (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))));
808                                                                  }                                                                  }
809                                                          }                                                          }
810                                                  }                                                  }
811                                          }                                          }
812                                          else                                          else
813                                          {                                          {
814                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
815                                                  {                                                  {
816                                                          total2 += ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
817                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
818                                                  }                                                  }
819                                                  else                                                  else
820                                                  {                                                  {
821                                                          total2 += ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
822                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
823                                                  }                                                  }
824                                          }                                          }
825    
826                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
827                                            {
828                                                    dbytes2 *= twopass->average_bframe / twopass->average_pframe;
829                                                    if (dbytes2 < twopass->minbsize)
830                                                            dbytes2 = twopass->minbsize;
831                                            }
832                                            else
833                                            {
834                                                    if (dbytes2 < twopass->minpsize)
835                                                            dbytes2 = twopass->minpsize;
836                                            }
837    
838                                            total2 += dbytes2;
839                                  }                                  }
840    
841                                  ++frames;                                  ++frames;
# Line 584  Line 848 
848                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
849                                  char s[100];                                  char s[100];
850    
851                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
852                                  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);
853                                  DEBUG2P(s);                                  DEBUG2P(s);
854                          }                          }
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
855                  }                  }
856    
857                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
# Line 608  Line 870 
870                                  int i, newquant, percent;                                  int i, newquant, percent;
871                                  int oldquant = 1;                                  int oldquant = 1;
872    
873                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_frame));                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_pframe));
874                                  DEBUG2P(s);                                  DEBUG2P(s);
875    
876                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));
# Line 617  Line 879 
879                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)
880                                  {                                  {
881                                          dbytes = i;                                          dbytes = i;
882                                          if (dbytes > twopass->average_frame)                                          if (dbytes > twopass->average_pframe)
883                                          {                                          {
884                                                  if (dbytes >= twopass->alt_curve_high)                                                  if (dbytes >= twopass->alt_curve_high)
885                                                          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 627  Line 889 
889                                                          {                                                          {
890                                                          case 2:                                                          case 2:
891                                                          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 *
892                                                                  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)));
893                                                                  break;                                                                  break;
894                                                          case 1:                                                          case 1:
895                                                          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 *
896                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
897                                                                  break;                                                                  break;
898                                                          case 0:                                                          case 0:
899                                                          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 *
900                                                                  (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))));
901                                                          }                                                          }
902                                                  }                                                  }
903                                          }                                          }
# Line 649  Line 911 
911                                                          {                                                          {
912                                                          case 2:                                                          case 2:
913                                                          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 *
914                                                                  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)));
915                                                                  break;                                                                  break;
916                                                          case 1:                                                          case 1:
917                                                          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 *
918                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
919                                                                  break;                                                                  break;
920                                                          case 0:                                                          case 0:
921                                                          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 *
922                                                                  (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))));
923                                                          }                                                          }
924                                                  }                                                  }
925                                          }                                          }
# Line 671  Line 933 
933                                                  if (newquant != oldquant)                                                  if (newquant != oldquant)
934                                                  {                                                  {
935                                                          oldquant = newquant;                                                          oldquant = newquant;
936                                                          percent = (int)((i - twopass->average_frame) * 100.0 / twopass->average_frame);                                                          percent = (int)((i - twopass->average_pframe) * 100.0 / twopass->average_pframe);
937                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);
938                                                          DEBUG2P(s);                                                          DEBUG2P(s);
939                                                  }                                                  }
# Line 681  Line 943 
943                  }                  }
944    
945                  twopass->overflow = 0;                  twopass->overflow = 0;
946                    twopass->KFoverflow = 0;
947                    twopass->KFoverflow_partial = 0;
948                    twopass->KF_idx = 1;
949    
950                  break;                  break;
951          }          }
# Line 688  Line 953 
953          return ICERR_OK;          return ICERR_OK;
954  }  }
955    
956    // NOTE: codec_2pass_get_quant() should be called for all the frames that are in the stats file(s)
957  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
958  {  {
959          static double quant_error[32];          static double bquant_error[32];
960            static double pquant_error[32];
961          static double curve_comp_error;          static double curve_comp_error;
962          static int last_quant;          static int last_bquant, last_pquant;
963    
964          TWOPASS * twopass = &codec->twopass;          TWOPASS * twopass = &codec->twopass;
965    
966          DWORD read;  //      DWORD read;
967          int bytes1, bytes2;          int bytes1, bytes2;
968          int overflow;          int overflow;
969          int credits_pos;          int credits_pos;
970          int capped_to_max_framesize = 0;          int capped_to_max_framesize = 0;
971            int KFdistance, KF_min_size;
972    
973          if (codec->framenum == 0)          if (codec->framenum == 0)
974          {          {
# Line 709  Line 976 
976    
977                  for (i=0 ; i<32 ; ++i)                  for (i=0 ; i<32 ; ++i)
978                  {                  {
979                          quant_error[i] = 0.0;                          bquant_error[i] = 0.0;
980                            pquant_error[i] = 0.0;
981                          twopass->quant_count[i] = 0;                          twopass->quant_count[i] = 0;
982                  }                  }
983    
984                  curve_comp_error = 0.0;                  curve_comp_error = 0.0;
985                  last_quant = 0;                  last_bquant = 0;
986                    last_pquant = 0;
987          }          }
988    
989          if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))          if (twopass->nns_array_pos >= twopass->nns_array_length)
990          {          {
991                  DEBUGERR("2ndpass quant: couldn't read from stats1");                  twopass->nns_array_pos = 0;
992                    DEBUGERR("ERROR: VIDEO EXCEEDS 1ST PASS!!!");
993                  return ICERR_ERROR;                  return ICERR_ERROR;
994          }          }
995    
996            memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
997          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
998                    memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
999            twopass->nns_array_pos++;
1000    
1001            bytes1 = twopass->nns1.bytes;
1002    
1003            // skip unnecessary frames.
1004            if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME)
1005          {          {
1006                  if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))                  twopass->bytes1 = bytes1;
1007                    twopass->bytes2 = bytes1;
1008                    twopass->desired_bytes2 = bytes1;
1009                    frame->intra = 3;
1010                    return 2;
1011            }
1012            else if (twopass->nns1.dd_v & NNSTATS_PADFRAME)
1013                  {                  {
1014                          DEBUGERR("2ndpass quant: couldn't read from stats2");                  twopass->bytes1 = bytes1;
1015                          return ICERR_ERROR;                  twopass->bytes2 = bytes1;
1016                    twopass->desired_bytes2 = bytes1;
1017                    frame->intra = 4;
1018                    return 2;
1019                  }                  }
1020            else if (twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
1021            {
1022                    twopass->bytes1 = bytes1;
1023                    twopass->bytes2 = bytes1;
1024                    twopass->desired_bytes2 = bytes1;
1025                    frame->intra = 5;
1026                    return 2;
1027          }          }
1028    
         bytes1 = twopass->nns1.bytes;  
1029          overflow = twopass->overflow / 8;          overflow = twopass->overflow / 8;
1030    
1031          // override codec i-frame choice (reenable in credits)          // override codec i-frame choice (reenable in credits)
1032          frame->intra = (twopass->nns1.quant & NNSTATS_KEYFRAME);          if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1033                    frame->intra=1;
1034            else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1035                    frame->intra=2;
1036            else
1037                    frame->intra=0;
1038    
1039          if (frame->intra)          if (frame->intra==1)
1040          {          {
1041                  overflow = 0;                  overflow = 0;
1042          }          }
# Line 785  Line 1084 
1084                  }                  }
1085                  else    // DLG_MODE_2PASS_2_EXT                  else    // DLG_MODE_2PASS_2_EXT
1086                  {                  {
1087                            if (codec->config.credits_mode == CREDITS_MODE_QUANT)
1088                            {
1089                                    if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1090                                    {
1091                                            frame->quant = frame->intra == 1 ?
1092                                                    codec->config.credits_quant_i :
1093                                                    codec->config.credits_quant_p;
1094                                    }
1095                                    else
1096                                    {
1097                                            frame->quant = codec->config.credits_quant_p;
1098                                            frame->intra = -1;
1099                                    }
1100    
1101                                    twopass->bytes1 = bytes1;
1102                                    twopass->bytes2 = bytes1;
1103                                    twopass->desired_bytes2 = bytes1;
1104                                    return ICERR_OK;
1105                            }
1106                            else
1107                          bytes2 = twopass->nns2.bytes;                          bytes2 = twopass->nns2.bytes;
1108                  }                  }
1109          }          }
# Line 794  Line 1113 
1113    
1114                  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;
1115    
1116                  if (frame->intra)                  if (frame->intra==1)
1117                  {                  {
1118                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
1119                                  twopass->movie_curve;                                  twopass->movie_curve;
# Line 804  Line 1123 
1123                          dbytes = bytes2 / twopass->movie_curve;                          dbytes = bytes2 / twopass->movie_curve;
1124                  }                  }
1125    
1126                    if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1127                            dbytes *= twopass->average_pframe / twopass->average_bframe;
1128    
1129                  // spread the compression error across payback_delay frames                  // spread the compression error across payback_delay frames
1130                  if (codec->config.bitrate_payback_method == 0)                  if (codec->config.bitrate_payback_method == 0)
1131                  {                  {
# Line 812  Line 1134 
1134                  else                  else
1135                  {                  {
1136                          bytes2 = (int)(curve_comp_error * dbytes /                          bytes2 = (int)(curve_comp_error * dbytes /
1137                                  twopass->average_frame / codec->config.bitrate_payback_delay);                                  twopass->average_pframe / codec->config.bitrate_payback_delay);
1138    
1139                          if (labs(bytes2) > fabs(curve_comp_error))                          if (labs(bytes2) > fabs(curve_comp_error))
1140                          {                          {
# Line 824  Line 1146 
1146    
1147                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
1148                  {                  {
1149                          if (!frame->intra)                          if (!(frame->intra==1))
1150                          {                          {
1151                                  if (dbytes > twopass->average_frame)                                  if (dbytes > twopass->average_pframe)
1152                                  {                                  {
1153                                          if (dbytes >= twopass->alt_curve_high)                                          if (dbytes >= twopass->alt_curve_high)
1154                                                  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 836  Line 1158 
1158                                                  {                                                  {
1159                                                  case 2:                                                  case 2:
1160                                                  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 *
1161                                                          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)));
1162                                                          break;                                                          break;
1163                                                  case 1:                                                  case 1:
1164                                                  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 *
1165                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
1166                                                          break;                                                          break;
1167                                                  case 0:                                                  case 0:
1168                                                  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 *
1169                                                          (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))));
1170                                                  }                                                  }
1171                                          }                                          }
1172                                  }                                  }
# Line 858  Line 1180 
1180                                                  {                                                  {
1181                                                  case 2:                                                  case 2:
1182                                                  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 *
1183                                                          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)));
1184                                                          break;                                                          break;
1185                                                  case 1:                                                  case 1:
1186                                                  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 *
1187                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
1188                                                          break;                                                          break;
1189                                                  case 0:                                                  case 0:
1190                                                  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 *
1191                                                          (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))));
1192                                                  }                                                  }
1193                                          }                                          }
1194                                  }                                  }
1195                                    if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1196                                            curve_temp *= twopass->average_bframe / twopass->average_pframe;
1197    
1198                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
1199    
1200                                  bytes2 += ((int)curve_temp);                                  bytes2 += ((int)curve_temp);
# Line 877  Line 1202 
1202                          }                          }
1203                          else                          else
1204                          {                          {
1205                                  curve_comp_error += dbytes - ((int)dbytes);                                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1206                                            dbytes *= twopass->average_bframe / twopass->average_pframe;
1207    
1208                                  bytes2 += ((int)dbytes);                                  bytes2 += ((int)dbytes);
1209                                    curve_comp_error += dbytes - ((int)dbytes);
1210                          }                          }
1211                  }                  }
1212                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
1213                          !frame->intra)                          !(frame->intra==1))
1214                  {                  {
1215                          if (dbytes > twopass->average_frame)                          if (dbytes > twopass->average_pframe)
1216                          {                          {
1217                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
1218                                          ((double)dbytes + (twopass->average_frame - dbytes) *                                          ((double)dbytes + (twopass->average_pframe - dbytes) *
1219                                          codec->config.curve_compression_high / 100.0);                                          codec->config.curve_compression_high / 100.0);
1220                          }                          }
1221                          else                          else
1222                          {                          {
1223                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
1224                                          ((double)dbytes + (twopass->average_frame - dbytes) *                                          ((double)dbytes + (twopass->average_pframe - dbytes) *
1225                                          codec->config.curve_compression_low / 100.0);                                          codec->config.curve_compression_low / 100.0);
1226                          }                          }
1227    
1228                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1229                                    curve_temp *= twopass->average_bframe / twopass->average_pframe;
1230    
1231                          bytes2 += ((int)curve_temp);                          bytes2 += ((int)curve_temp);
1232                          curve_comp_error += curve_temp - ((int)curve_temp);                          curve_comp_error += curve_temp - ((int)curve_temp);
1233                  }                  }
1234                  else                  else
1235                  {                  {
1236                          curve_comp_error += dbytes - ((int)dbytes);                          if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1237                                    dbytes *= twopass->average_bframe / twopass->average_pframe;
1238    
1239                          bytes2 += ((int)dbytes);                          bytes2 += ((int)dbytes);
1240                            curve_comp_error += dbytes - ((int)dbytes);
1241                  }                  }
1242    
1243                  // cap bytes2 to first pass size, lowers number of quant=1 frames                  // cap bytes2 to first pass size, lowers number of quant=1 frames
# Line 912  Line 1246 
1246                          curve_comp_error += bytes2 - bytes1;                          curve_comp_error += bytes2 - bytes1;
1247                          bytes2 = bytes1;                          bytes2 = bytes1;
1248                  }                  }
1249                  else if (bytes2 < 1)                  else
1250                  {                  {
1251                          curve_comp_error += --bytes2;                          if (frame->intra==1)
1252                          bytes2 = 1;                          {
1253                                    if (bytes2 < twopass->minisize)
1254                                    {
1255                                            curve_comp_error -= twopass->minisize - bytes2;
1256                                            bytes2 = twopass->minisize;
1257                                    }
1258                            }
1259                            else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1260                            {
1261                                    if (bytes2 < twopass->minbsize)
1262                                            bytes2 = twopass->minbsize;
1263                            }
1264                            else
1265                            {
1266                                    if (bytes2 < twopass->minpsize)
1267                                            bytes2 = twopass->minpsize;
1268                            }
1269                  }                  }
1270          }          }
1271    
1272          twopass->desired_bytes2 = bytes2;          twopass->desired_bytes2 = bytes2;
1273    
1274            // if this keyframe is too close to the next,
1275            // reduce it's byte allotment
1276            if ((frame->intra==1) && !credits_pos)
1277            {
1278                    KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1279                            codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];
1280    
1281                    if (KFdistance < codec->config.kftreshold)
1282                    {
1283                            KFdistance = KFdistance - codec->config.min_key_interval;
1284    
1285                            if (KFdistance >= 0)
1286                            {
1287                                    KF_min_size = bytes2 * (100 - codec->config.kfreduction) / 100;
1288                                    if (KF_min_size < 1)
1289                                            KF_min_size = 1;
1290    
1291                                    bytes2 = KF_min_size + (bytes2 - KF_min_size) * KFdistance /
1292                                            (codec->config.kftreshold - codec->config.min_key_interval);
1293    
1294                                    if (bytes2 < 1)
1295                                            bytes2 = 1;
1296                            }
1297                    }
1298            }
1299    
1300          // 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
1301          // too much/little bitrate          // too much/little bitrate
1302          overflow = (int)((double)overflow * bytes2 / twopass->average_frame);          overflow = (int)((double)overflow * bytes2 / twopass->average_pframe);
1303    
1304          // Foxer: reign in overflow with huge frames          // Foxer: reign in overflow with huge frames
1305          if (labs(overflow) > labs(twopass->overflow))          if (labs(overflow) > labs(twopass->overflow))
# Line 952  Line 1328 
1328                  bytes2 = twopass->max_framesize;                  bytes2 = twopass->max_framesize;
1329          }          }
1330    
1331          if (bytes2 < 1)          // make sure to not scale below the minimum framesize
1332            if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1333          {          {
1334                  bytes2 = 1;                  if (bytes2 < twopass->minisize)
1335                            bytes2 = twopass->minisize;
1336            }
1337            else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1338            {
1339                    if (bytes2 < twopass->minbsize)
1340                            bytes2 = twopass->minbsize;
1341            }
1342            else
1343            {
1344                    if (bytes2 < twopass->minpsize)
1345                            bytes2 = twopass->minpsize;
1346          }          }
1347    
1348          twopass->bytes1 = bytes1;          twopass->bytes1 = bytes1;
# Line 971  Line 1359 
1359          {          {
1360                  frame->quant = 31;                  frame->quant = 31;
1361          }          }
1362          else if (!frame->intra)          else if (!(frame->intra==1))
1363          {          {
1364                  // Foxer: aid desired quantizer precision by accumulating decision error                  // Foxer: aid desired quantizer precision by accumulating decision error
1365                  quant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1366                    {
1367                            bquant_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 (bquant_error[frame->quant] >= 1.0)
1371                  {                  {
1372                          quant_error[frame->quant] -= 1.0;                                  bquant_error[frame->quant] -= 1.0;
1373                          ++frame->quant;                          ++frame->quant;
1374                  }                  }
1375          }          }
1376                    else
1377                    {
1378                            pquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1379                                    bytes1) / bytes2) - frame->quant;
1380    
1381                            if (pquant_error[frame->quant] >= 1.0)
1382                            {
1383                                    pquant_error[frame->quant] -= 1.0;
1384                                    ++frame->quant;
1385                            }
1386                    }
1387            }
1388    
1389          // we're done with credits          // we're done with credits
1390          if (codec_is_in_credits(&codec->config, codec->framenum))          if (codec_is_in_credits(&codec->config, codec->framenum))
# Line 990  Line 1392 
1392                  return ICERR_OK;                  return ICERR_OK;
1393          }          }
1394    
1395          if (frame->intra)          if ((frame->intra==1))
1396          {          {
1397                  if (frame->quant < codec->config.min_iquant)                  if (frame->quant < codec->config.min_iquant)
1398                  {                  {
# Line 1015  Line 1417 
1417                  }                  }
1418    
1419                  // subsequent frame quants can only be +- 2                  // subsequent frame quants can only be +- 2
1420                  if (last_quant && capped_to_max_framesize == 0)                  if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)
1421                    {
1422                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1423                            {
1424                                    // this bframe quantizer variation
1425                                    // restriction needs to be redone.
1426                                    if (frame->quant > last_bquant + 2)
1427                                    {
1428                                            frame->quant = last_bquant + 2;
1429                                            DEBUG2P("B-frame quantizer prevented from rising too steeply");
1430                                    }
1431                                    if (frame->quant < last_bquant - 2)
1432                                    {
1433                                            frame->quant = last_bquant - 2;
1434                                            DEBUG2P("B-frame quantizer prevented from falling too steeply");
1435                                    }
1436                            }
1437                            else
1438                  {                  {
1439                          if (frame->quant > last_quant + 2)                                  if (frame->quant > last_pquant + 2)
1440                          {                          {
1441                                  frame->quant = last_quant + 2;                                          frame->quant = last_pquant + 2;
1442                                  DEBUG2P("P-frame quantizer prevented from rising too steeply");                                  DEBUG2P("P-frame quantizer prevented from rising too steeply");
1443                          }                          }
1444                          if (frame->quant < last_quant - 2)                                  if (frame->quant < last_pquant - 2)
1445                          {                          {
1446                                  frame->quant = last_quant - 2;                                          frame->quant = last_pquant - 2;
1447                                  DEBUG2P("P-frame quantizer prevented from falling too steeply");                                  DEBUG2P("P-frame quantizer prevented from falling too steeply");
1448                          }                          }
1449                  }                  }
1450          }          }
1451            }
1452    
1453          if (capped_to_max_framesize == 0)          if (capped_to_max_framesize == 0)
1454                  last_quant = frame->quant;          {
1455                    if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1456                    {
1457                            last_bquant = frame->quant;
1458                            last_pquant = frame->quant;
1459                    }
1460                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1461                            last_bquant = frame->quant;
1462                    else
1463                            last_pquant = frame->quant;
1464            }
1465    
1466          if (codec->config.quant_type == QUANT_MODE_MOD)          if (codec->config.quant_type == QUANT_MODE_MOD)
1467          {          {
1468                  frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;                  frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;
1469                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1470          }          }
1471    /*
1472            if (codec->config.quant_type == QUANT_MODE_MOD_NEW)
1473            {
1474                    frame->general |= (frame->quant < 4) ? XVID_H263QUANT : XVID_MPEGQUANT;
1475                    frame->general &= (frame->quant < 4) ? ~XVID_MPEGQUANT : ~XVID_H263QUANT;
1476            }
1477    */
1478          return ICERR_OK;          return ICERR_OK;
1479  }  }
1480    
# Line 1049  Line 1485 
1485    
1486          NNSTATS nns1;          NNSTATS nns1;
1487          DWORD wrote;          DWORD wrote;
1488          int credits_pos;          int credits_pos, tempdiv;
1489          char* quant_type;          char* quant_type;
1490            char* frame_type;
1491    
1492          if (codec->framenum == 0)          if (codec->framenum == 0)
1493          {          {
# Line 1072  Line 1509 
1509                  nns1.md_u = nns1.md_y = 0;                  nns1.md_u = nns1.md_y = 0;
1510                  nns1.mk_u = nns1.mk_y = 0;                  nns1.mk_u = nns1.mk_y = 0;
1511    
1512                  nns1.quant = stats->quant;  //              nns1.quant = stats->quant;
1513                  if (frame->intra)                  nns1.quant = 2;                         // ugly fix for lumi masking in 1st pass returning new quant
1514                  {                  nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1515                    frame_type="inter";
1516                    if (frame->intra==1) {
1517                          nns1.quant |= NNSTATS_KEYFRAME;                          nns1.quant |= NNSTATS_KEYFRAME;
1518                            frame_type="intra";
1519                    }
1520                    else if (frame->intra==2) {
1521                            nns1.dd_v |= NNSTATS_BFRAME;
1522                            frame_type="bframe";
1523                    }
1524                    else if (frame->intra==3) {
1525                            nns1.dd_v |= NNSTATS_SKIPFRAME;
1526                            frame_type="skiped";
1527                    }
1528                    else if (frame->intra==4) {
1529                            nns1.dd_v |= NNSTATS_PADFRAME;
1530                            frame_type="padded";
1531                    }
1532                    else if (frame->intra==5) {
1533                            nns1.dd_v |= NNSTATS_DELAYFRAME;
1534                            frame_type="delayed";
1535                  }                  }
1536                  nns1.kblk = stats->kblks;                  nns1.kblk = stats->kblks;
1537                  nns1.mblk = stats->mblks;                  nns1.mblk = stats->mblks;
1538                  nns1.ublk = stats->ublks;                  nns1.ublk = stats->ublks;
                 nns1.lum_noise[0] = nns1.lum_noise[1] = 1;  
1539    
1540                  total_size += frame->length;                  total_size += frame->length;
1541    
1542                  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)
1543    
1544    
1545                  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))
1546                  {                  {
# Line 1095  Line 1551 
1551    
1552          case DLG_MODE_2PASS_2_INT :          case DLG_MODE_2PASS_2_INT :
1553          case DLG_MODE_2PASS_2_EXT :          case DLG_MODE_2PASS_2_EXT :
                 codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;  
   
1554                  credits_pos = codec_is_in_credits(&codec->config, codec->framenum);                  credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1555                    if (!(codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&
1556                            !(codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) &&
1557                            !(codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME))
1558                    {
1559                  if (!credits_pos)                  if (!credits_pos)
1560                            {
1561                          codec->twopass.quant_count[frame->quant]++;                          codec->twopass.quant_count[frame->quant]++;
1562                                    if ((codec->twopass.nns1.quant & NNSTATS_KEYFRAME))
1563                                    {
1564                                            // calculate how much to distribute per frame in
1565                                            // order to make up for this keyframe's overflow
1566    
1567                                            codec->twopass.overflow += codec->twopass.KFoverflow;
1568                                            codec->twopass.KFoverflow = codec->twopass.desired_bytes2 - frame->length;
1569    
1570                                            tempdiv = (codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1571                                                    codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1]);
1572    
1573                  DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)                                          if (tempdiv > 1)
1574                                            {
1575                                                    // non-consecutive keyframes
1576                                                    codec->twopass.KFoverflow_partial = codec->twopass.KFoverflow / (tempdiv - 1);
1577                                            }
1578                                            else
1579                                            {
1580                                                    // consecutive keyframes
1581                                                    codec->twopass.overflow += codec->twopass.KFoverflow;
1582                                                    codec->twopass.KFoverflow = 0;
1583                                                    codec->twopass.KFoverflow_partial = 0;
1584                                            }
1585                                            codec->twopass.KF_idx++;
1586                                    }
1587                                    else
1588                                    {
1589                                            // distribute part of the keyframe overflow
1590    
1591                                            codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length +
1592                                                    codec->twopass.KFoverflow_partial;
1593                                            codec->twopass.KFoverflow -= codec->twopass.KFoverflow_partial;
1594                                    }
1595                            }
1596                            else
1597                            {
1598                                    codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;
1599    
1600                                    // ugly fix for credits..
1601                                    codec->twopass.overflow += codec->twopass.KFoverflow;
1602                                    codec->twopass.KFoverflow = 0;
1603                                    codec->twopass.KFoverflow_partial = 0;
1604                                    // end of ugly fix.
1605                            }
1606                    }
1607    
1608                    frame_type="inter";
1609                    if (frame->intra==1) {
1610                            frame_type="intra";
1611                    }
1612                    else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME) {
1613                            frame_type="bframe";
1614                    }
1615                    else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {
1616                            frame_type="skipped";
1617                            frame->quant = 2;
1618                            codec->twopass.bytes1 = 1;
1619                            codec->twopass.desired_bytes2 = 1;
1620                            frame->length = 1;
1621                    }
1622                    else if (codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) {
1623                            frame_type="padded";
1624                            frame->quant = 2;
1625                            codec->twopass.bytes1 = 7;
1626                            codec->twopass.desired_bytes2 = 7;
1627                            frame->length = 7;
1628                    }
1629                    else if (codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {
1630                            frame_type="delayed";
1631                            frame->quant = 2;
1632                            codec->twopass.bytes1 = 1;
1633                            codec->twopass.desired_bytes2 = 1;
1634                            frame->length = 1;
1635                    }
1636    
1637                    DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
1638                  break;                  break;
1639    
1640          default:          default:
# Line 1115  Line 1648 
1648  {  {
1649          int i;          int i;
1650          char s[100];          char s[100];
1651    
1652            if (codec->twopass.nns1_array)
1653            {
1654                    free(codec->twopass.nns1_array);
1655                    codec->twopass.nns1_array = NULL;
1656            }
1657            if (codec->twopass.nns2_array)
1658            {
1659                    free(codec->twopass.nns2_array);
1660                    codec->twopass.nns2_array = NULL;
1661            }
1662            codec->twopass.nns_array_size = 0;
1663            codec->twopass.nns_array_length = 0;
1664            codec->twopass.nns_array_pos = 0;
1665    
1666          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)
1667          {          {
1668                  // output the quantizer distribution for this encode.                  // output the quantizer distribution for this encode.
# Line 1131  Line 1679 
1679                  return;                  return;
1680          }          }
1681  }  }
1682    

Legend:
Removed from v.109  
changed lines
  Added in v.687

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