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

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

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

revision 528, Mon Sep 23 06:11:34 2002 UTC revision 714, Sat Dec 14 05:39:54 2002 UTC
# Line 41  Line 41 
41          DWORD version = -20;          DWORD version = -20;
42          DWORD read, wrote;          DWORD read, wrote;
43    
44          int     frames = 0, credits_frames = 0, i_frames = 0;          int     frames = 0, bframes = 0, pframes = 0, credits_frames = 0, i_frames = 0, recminbsize = 0, recminpsize = 0, recminisize = 0;
45          __int64 total_ext = 0, total = 0, i_total = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0;          __int64 bframe_total_ext = 0, pframe_total_ext = 0, pframe_total = 0, bframe_total = 0, i_total = 0, i_total_ext = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0;
46          __int64 desired = (__int64)codec->config.desired_size * 1024;          __int64 desired = (__int64)codec->config.desired_size * 1024;
47    
48          double total1 = 0.0;          double total1 = 0.0;
49          double total2 = 0.0;          double total2 = 0.0;
50          double dbytes, dbytes2;          double dbytes, dbytes2;
51    
52            /* ensure free() is called safely */
53            codec->twopass.hintstream = NULL;
54            twopass->nns1_array = NULL;
55            twopass->nns2_array = NULL;
56    
57          if (codec->config.hinted_me)          if (codec->config.hinted_me)
58          {          {
59                  codec->twopass.hintstream = malloc(100000);                  codec->twopass.hintstream = malloc(100000);
# Line 101  Line 106 
106                          return ICERR_ERROR;                          return ICERR_ERROR;
107                  }                  }
108    
109                    twopass->nns1_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);
110                    twopass->nns2_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);
111                    twopass->nns_array_size = 10240;
112                    twopass->nns_array_length = 0;
113                    twopass->nns_array_pos = 0;
114    
115                    // read the stats file(s) into array(s) and reorder them so they
116                    // correctly represent the frames that the encoder will receive.
117                  if (codec->config.mode == DLG_MODE_2PASS_2_EXT)                  if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
118                  {                  {
119                          if (twopass->stats2 != INVALID_HANDLE_VALUE)                          if (twopass->stats2 != INVALID_HANDLE_VALUE)
# Line 158  Line 171 
171                                          }                                          }
172                                  }                                  }
173    
174                                    // increase the allocated memory if necessary
175                                    if (frames >= twopass->nns_array_size)
176                                    {
177                                            twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array,
178                                                    sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
179                                            twopass->nns2_array = (NNSTATS*)realloc(twopass->nns2_array,
180                                                    sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
181                                            twopass->nns_array_size = twopass->nns_array_size * 5 / 4 + 1;
182                                    }
183    
184                                    // copy this frame's stats into the arrays
185                                    memcpy (&twopass->nns1_array[frames], &twopass->nns1, sizeof(NNSTATS));
186                                    memcpy (&twopass->nns2_array[frames], &twopass->nns2, sizeof(NNSTATS));
187                                    frames++;
188                            }
189    
190                            SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
191                            SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
192                    }
193                    else    // DLG_MODE_2PASS_2_INT
194                    {
195                            while (1)
196                            {
197                                    if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
198                                    {
199                                            DWORD err = GetLastError();
200    
201                                            if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
202                                            {
203                                                    break;
204                                            }
205                                            else
206                                            {
207                                                    CloseHandle(twopass->stats1);
208                                                    twopass->stats1 = INVALID_HANDLE_VALUE;
209                                                    DEBUGERR("2pass init error - incomplete stats2 record?");
210                                                    return ICERR_ERROR;
211                                            }
212                                    }
213    
214                                    // increase the allocated memory if necessary
215                                    if (frames >= twopass->nns_array_size)
216                                    {
217                                            twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array,
218                                                    sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));
219                                            twopass->nns_array_size = twopass->nns_array_size * 5 / 4 + 1;
220                                    }
221    
222                                    // copy this frame's stats into the array
223                                    memcpy (&twopass->nns1_array[frames], &twopass->nns1, sizeof(NNSTATS));
224                                    frames++;
225                            }
226    
227                            SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
228                    }
229                    twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array, sizeof(NNSTATS) * frames);
230                    twopass->nns2_array = (NNSTATS*)realloc(twopass->nns2_array, sizeof(NNSTATS) * frames);
231                    twopass->nns_array_size = frames;
232                    twopass->nns_array_length = frames;
233                    frames = 0;
234    
235    /* // this isn't necessary with the current core.
236                    // reorder the array(s) so they are in the order that they were received
237                    // IPBBPBB to
238                    // IBBPBBP
239                    for (i=0; i<twopass->nns_array_length; i++)
240                    {
241                            NNSTATS temp_nns, temp_nns2;
242                            int k, num_bframes;
243                            if (twopass->nns1_array[i].dd_v & NNSTATS_BFRAME)
244                            {
245                                    num_bframes = 1;
246                                    for (k=i+1; k<twopass->nns_array_length; k++)
247                                    {
248                                            if (twopass->nns1_array[k].dd_v & NNSTATS_BFRAME)
249                                                    num_bframes++;
250                                            else
251                                                    k=twopass->nns_array_length;
252                                    }
253    
254                                    i--;
255                                    memcpy (&temp_nns, &twopass->nns1_array[i], sizeof(NNSTATS));
256                                    if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
257                                            memcpy (&temp_nns2, &twopass->nns2_array[i], sizeof(NNSTATS));
258    
259                                    for (k=0; k<num_bframes; k++)
260                                    {
261                                            memcpy(&twopass->nns1_array[i], &twopass->nns1_array[i+1], sizeof(NNSTATS));
262                                            if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
263                                                    memcpy(&twopass->nns2_array[i], &twopass->nns2_array[i+1], sizeof(NNSTATS));
264                                            i++;
265                                    }
266    
267                                    memcpy(&twopass->nns1_array[i], &temp_nns, sizeof(NNSTATS));
268                                    if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
269                                            memcpy(&twopass->nns2_array[i], &temp_nns2, sizeof(NNSTATS));
270                            }
271                    }
272    */
273                    // continue with the initialization..
274                    if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
275                    {
276                            while (1)
277                            {
278                                    if (twopass->nns_array_pos >= twopass->nns_array_length)
279                                    {
280                                            twopass->nns_array_pos = 0;
281                                            break;
282                                    }
283    
284                                    memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
285                                    memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
286                                    twopass->nns_array_pos++;
287    
288                                    // skip unnecessary frames.
289                                    if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
290                                            twopass->nns1.dd_v & NNSTATS_PADFRAME ||
291                                            twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
292                                            continue;
293    
294                                  if (!codec_is_in_credits(&codec->config, frames))                                  if (!codec_is_in_credits(&codec->config, frames))
295                                  {                                  {
296                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)
297                                          {                                          {
                                                 i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;  
298                                                  i_total += twopass->nns2.bytes;                                                  i_total += twopass->nns2.bytes;
299                                                    i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;
300                                                  twopass->keyframe_locations[i_frames] = frames;                                                  twopass->keyframe_locations[i_frames] = frames;
301                                                  ++i_frames;                                                  ++i_frames;
302                                          }                                          }
303                                            else
304                                          total += twopass->nns1.bytes;                                          {
305                                          total_ext += twopass->nns2.bytes;                                                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
306                                                    {
307                                                            bframe_total += twopass->nns1.bytes;
308                                                            bframe_total_ext += twopass->nns2.bytes;
309                                                            bframes++;
310                                                    }
311                                                    else
312                                                    {
313                                                            pframe_total += twopass->nns1.bytes;
314                                                            pframe_total_ext += twopass->nns2.bytes;
315                                                            pframes++;
316                                                    }
317                                            }
318                                  }                                  }
319                                  else                                  else
320                                          ++credits_frames;                                          ++credits_frames;
321    
322                                    if (twopass->nns1.quant & NNSTATS_KEYFRAME)
323                                    {
324                                            // this test needs to be corrected..
325                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
326                                                    recminisize = twopass->nns1.bytes;
327                                    }
328                                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
329                                    {
330                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
331                                                    recminbsize = twopass->nns1.bytes;
332                                    }
333                                    else
334                                    {
335                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
336                                                    recminpsize = twopass->nns1.bytes;
337                                    }
338    
339                                  ++frames;                                  ++frames;
340                          }                          }
341                          twopass->keyframe_locations[i_frames] = frames;                          twopass->keyframe_locations[i_frames] = frames;
342    
343                          twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);                          twopass->movie_curve = ((double)(bframe_total_ext + pframe_total_ext + i_boost_total) /
344                          twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);                                  (bframe_total_ext + pframe_total_ext));
345    
346                            if (bframes)
347                                    twopass->average_bframe = (double)bframe_total_ext / bframes / twopass->movie_curve;
348    
349                            if (pframes)
350                                    twopass->average_pframe = (double)pframe_total_ext / pframes / twopass->movie_curve;
351                            else
352                                    if (bframes)
353                                            twopass->average_pframe = twopass->average_bframe;  // b-frame packed bitstream fix
354                                    else
355                                    {
356                                            DEBUGERR("ERROR:  No p-frames or b-frames were present in the 1st pass.  Rate control cannot function properly!");
357                                            return ICERR_ERROR;
358                                    }
359    
360    
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
                         SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);  
361    
362                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
363                          frames = 0;                          frames = 0;
364    
365                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
366                          {                          {
367                                  twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;                                  twopass->alt_curve_low = twopass->average_pframe - twopass->average_pframe * (double)codec->config.alt_curve_low_dist / 100.0;
368                                  twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
369                                  twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;                                  twopass->alt_curve_high = twopass->average_pframe + twopass->average_pframe * (double)codec->config.alt_curve_high_dist / 100.0;
370                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
371                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
372                                  {                                  {
373                                          if (total > total_ext)                                          if (bframe_total + pframe_total > bframe_total_ext + pframe_total_ext)
374                                          {                                          {
375                                                  codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / ((double)total / (double)total_ext)) * (double)codec->config.alt_curve_auto_str / 100.0);                                                  codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 /
376                                                            ((double)(bframe_total + pframe_total) / (double)(bframe_total_ext + pframe_total_ext))) *
377                                                            (double)codec->config.alt_curve_auto_str / 100.0);
378    
379                                                  if (codec->config.alt_curve_min_rel_qual < 20)                                                  if (codec->config.alt_curve_min_rel_qual < 20)
380                                                          codec->config.alt_curve_min_rel_qual = 20;                                                          codec->config.alt_curve_min_rel_qual = 20;
381                                          }                                          }
# Line 212  Line 390 
390                                          {                                          {
391                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
392                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
393                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
394                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
395                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
396                                                  break;                                                  break;
397                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
398                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
399                                                          twopass->average_frame / twopass->alt_curve_low_diff);                                                          twopass->average_pframe / twopass->alt_curve_low_diff);
400                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
401                                                          twopass->average_frame / twopass->alt_curve_low_diff;                                                          twopass->average_pframe / twopass->alt_curve_low_diff;
402                                                  break;                                                  break;
403                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
404                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
405                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));
406                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
407                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
408                                          }                                          }
409                                  }                                  }
410                          }                          }
411    
412                          while (1)                          while (1)
413                          {                          {
414                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||                                  if (twopass->nns_array_pos >= twopass->nns_array_length)
                                         !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))  
                                 {  
                                         DWORD err = GetLastError();  
   
                                         if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)  
415                                          {                                          {
416                                            twopass->nns_array_pos = 0;
417                                                  break;                                                  break;
418                                          }                                          }
419                                          else  
420                                          {                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
421                                                  CloseHandle(twopass->stats1);                                  memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
422                                                  CloseHandle(twopass->stats2);                                  twopass->nns_array_pos++;
                                                 twopass->stats1 = INVALID_HANDLE_VALUE;  
                                                 twopass->stats2 = INVALID_HANDLE_VALUE;  
                                                 DEBUGERR("2pass init error - incomplete stats1/stats2 record?");  
                                                 return ICERR_ERROR;  
                                         }  
                                 }  
423    
424                                  if (frames == 0)                                  if (frames == 0)
425                                  {                                  {
426                                            twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
427                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
428                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
429                                            if (recminbsize > twopass->minbsize)
430                                                    twopass->minbsize = recminbsize;
431                                            if (recminpsize > twopass->minpsize)
432                                                    twopass->minpsize = recminpsize;
433                                            if (recminisize > twopass->minisize)
434                                                    twopass->minisize = recminisize;
435                                  }                                  }
436    
437                                    // skip unnecessary frames.
438                                    if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
439                                            twopass->nns1.dd_v & NNSTATS_PADFRAME ||
440                                            twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
441                                            continue;
442    
443                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
444                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
445                                  {                                  {
446                                          dbytes = twopass->nns2.bytes / twopass->movie_curve;                                          dbytes = twopass->nns2.bytes / twopass->movie_curve;
447                                          total1 += dbytes;                                          total1 += dbytes;
448    
449                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
450                                                    dbytes *= twopass->average_pframe / twopass->average_bframe;
451    
452                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
453                                          {                                          {
454                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
455                                                  {                                                  {
456                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
457                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
# Line 277  Line 461 
461                                                                  {                                                                  {
462                                                                  case 2:                                                                  case 2:
463                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
464                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
465                                                                          break;                                                                          break;
466                                                                  case 1:                                                                  case 1:
467                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
468                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
469                                                                          break;                                                                          break;
470                                                                  case 0:                                                                  case 0:
471                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
472                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
473                                                                  }                                                                  }
474                                                          }                                                          }
475                                                  }                                                  }
# Line 299  Line 483 
483                                                                  {                                                                  {
484                                                                  case 2:                                                                  case 2:
485                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
486                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
487                                                                          break;                                                                          break;
488                                                                  case 1:                                                                  case 1:
489                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
490                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
491                                                                          break;                                                                          break;
492                                                                  case 0:                                                                  case 0:
493                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
494                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
495                                                                  }                                                                  }
496                                                          }                                                          }
497                                                  }                                                  }
498                                          }                                          }
499                                          else                                          else
500                                          {                                          {
501                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
502                                                  {                                                  {
503                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
504                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
505                                                  }                                                  }
506                                                  else                                                  else
507                                                  {                                                  {
508                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
509                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
510                                                  }                                                  }
511                                          }                                          }
512    
513                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
514                                            {
515                                                    dbytes2 *= twopass->average_bframe / twopass->average_pframe;
516                                                    if (dbytes2 < twopass->minbsize)
517                                                            dbytes2 = twopass->minbsize;
518                                            }
519                                            else
520                                            {
521                                          if (dbytes2 < twopass->minpsize)                                          if (dbytes2 < twopass->minpsize)
522                                                  dbytes2 = twopass->minpsize;                                                  dbytes2 = twopass->minpsize;
523                                            }
524    
525                                          total2 += dbytes2;                                          total2 += dbytes2;
526                                  }                                  }
# Line 342  Line 535 
535                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
536                                  char s[100];                                  char s[100];
537    
538                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
539                                  wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);                                  wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
540                                  DEBUG2P(s);                                  DEBUG2P(s);
541                          }                          }
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
                         SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);  
542                  }                  }
543                  else    // DLG_MODE_2PASS_2_INT                  else    // DLG_MODE_2PASS_2_INT
544                  {                  {
545                          while (1)                          while (1)
546                          {                          {
547                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))                                  if (twopass->nns_array_pos >= twopass->nns_array_length)
                                 {  
                                         DWORD err = GetLastError();  
   
                                         if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)  
548                                          {                                          {
549                                            twopass->nns_array_pos = 0;
550                                                  break;                                                  break;
551                                          }                                          }
552                                          else  
553                                          {                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
554                                                  CloseHandle(twopass->stats1);                                  twopass->nns_array_pos++;
555                                                  twopass->stats1 = INVALID_HANDLE_VALUE;  
556                                                  DEBUGERR("2pass init error - incomplete stats2 record?");                                  // skip unnecessary frames.
557                                                  return ICERR_ERROR;                                  if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
558                                          }                                          twopass->nns1.dd_v & NNSTATS_PADFRAME ||
559                                  }                                          twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
560                                            continue;
561    
562                                  if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)                                  if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)
563                                  {                                  {
# Line 384  Line 572 
572                                  else if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                  else if (twopass->nns1.quant & NNSTATS_KEYFRAME)
573                                  {                                  {
574                                          i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;                                          i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;
                                         total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;  
575                                          twopass->keyframe_locations[i_frames] = frames;                                          twopass->keyframe_locations[i_frames] = frames;
576                                          ++i_frames;                                          ++i_frames;
577                                  }                                  }
578                                    else
579                                    {
580                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
581                                            {
582                                                    bframe_total += twopass->nns1.bytes;
583                                                    bframes++;
584                                            }
585                                            else
586                                            {
587                                                    pframe_total += twopass->nns1.bytes;
588                                                    pframes++;
589                                            }
590                                    }
591    
592                                  total += twopass->nns1.bytes;                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)
593                                    {
594                                            // this test needs to be corrected..
595                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
596                                                    recminisize = twopass->nns1.bytes;
597                                    }
598                                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
599                                    {
600                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
601                                                    recminbsize = twopass->nns1.bytes;
602                                    }
603                                    else
604                                    {
605                                            if (!(twopass->nns1.kblk + twopass->nns1.mblk))
606                                                    recminpsize = twopass->nns1.bytes;
607                                    }
608    
609                                  ++frames;                                  ++frames;
610                          }                          }
# Line 404  Line 619 
619    
620                                  // credits curve = (total / desired_size) * (100 / credits_rate)                                  // credits curve = (total / desired_size) * (100 / credits_rate)
621                                  twopass->credits_start_curve = twopass->credits_end_curve =                                  twopass->credits_start_curve = twopass->credits_end_curve =
622                                          ((double)total / desired) * ((double)100 / codec->config.credits_rate);                                          ((double)(bframe_total + pframe_total + i_total + start + end) / desired) *
623                                            ((double)100 / codec->config.credits_rate);
624    
625                                  start_curved = (__int64)(start / twopass->credits_start_curve);                                  start_curved = (__int64)(start / twopass->credits_start_curve);
626                                  end_curved = (__int64)(end / twopass->credits_end_curve);                                  end_curved = (__int64)(end / twopass->credits_end_curve);
627    
628                                  // movie curve = (total - credits) / (desired_size - curved credits)                                  // movie curve = (total - credits) / (desired_size - curved credits)
629                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
630                                          (total - start - end) /                                          (bframe_total + pframe_total + i_total) /
631                                          (desired - start_curved - end_curved);                                          (desired - start_curved - end_curved);
632    
633                                  break;                                  break;
# Line 420  Line 636 
636    
637                                  // movie curve = (total - credits) / (desired_size - credits)                                  // movie curve = (total - credits) / (desired_size - credits)
638                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
639                                          (total - start - end) / (desired - start - end);                                          (bframe_total + pframe_total + i_total) / (desired - start - end);
640    
641                                  // aid the average asymmetric frame calculation below                                  // aid the average asymmetric frame calculation below
642                                  start_curved = start;                                  start_curved = start;
# Line 443  Line 659 
659    
660                                  // movie curve = (total - credits) / (desired_size - curved credits)                                  // movie curve = (total - credits) / (desired_size - curved credits)
661                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
662                                          (total - start - end) /                                          (bframe_total + pframe_total + i_total) /
663                                          (desired - start_curved - end_curved);                                          (desired - start_curved - end_curved);
664    
665                                  break;                                  break;
666                          }                          }
667    
668                          // average frame size = (desired - curved credits - curved keyframes) /                          if (bframes)
669                          //      (frames - credits frames - keyframes)                                  twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve;
670                          twopass->average_frame = (double)  
671                                  (desired - start_curved - end_curved - (i_total / twopass->movie_curve)) /                          if (pframes)
672                                  (frames - credits_frames - i_frames);                                  twopass->average_pframe = (double)pframe_total / pframes / twopass->movie_curve;
673                            else
674                                    if (bframes)
675                                            twopass->average_pframe = twopass->average_bframe;  // b-frame packed bitstream fix
676                                    else
677                                    {
678                                            DEBUGERR("ERROR:  No p-frames or b-frames were present in the 1st pass.  Rate control cannot function properly!");
679                                            return ICERR_ERROR;
680                                    }
681    
682    
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
683    
684                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
685                          frames = 0;                          frames = 0;
686    
687                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
688                          {                          {
689                                  twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;                                  twopass->alt_curve_low = twopass->average_pframe - twopass->average_pframe * (double)codec->config.alt_curve_low_dist / 100.0;
690                                  twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;
691                                  twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;                                  twopass->alt_curve_high = twopass->average_pframe + twopass->average_pframe * (double)codec->config.alt_curve_high_dist / 100.0;
692                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;
693                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
694                                  {                                  {
695                                          if (twopass->movie_curve > 1.0)                                          if (twopass->movie_curve > 1.0)
# Line 485  Line 709 
709                                          {                                          {
710                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
711                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
712                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
713                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
714                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));
715                                                  break;                                                  break;
716                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
717                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
718                                                          twopass->average_frame / twopass->alt_curve_low_diff);                                                          twopass->average_pframe / twopass->alt_curve_low_diff);
719                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
720                                                          twopass->average_frame / twopass->alt_curve_low_diff;                                                          twopass->average_pframe / twopass->alt_curve_low_diff;
721                                                  break;                                                  break;
722                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
723                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
724                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));
725                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
726                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));
727                                          }                                          }
728                                  }                                  }
729                          }                          }
730    
731                          while (1)                          while (1)
732                          {                          {
733                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))                                  if (twopass->nns_array_pos >= twopass->nns_array_length)
                                 {  
                                         DWORD err = GetLastError();  
   
                                         if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)  
734                                          {                                          {
735                                            twopass->nns_array_pos = 0;
736                                                  break;                                                  break;
737                                          }                                          }
738                                          else  
739                                          {                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
740                                                  CloseHandle(twopass->stats1);                                  twopass->nns_array_pos++;
                                                 twopass->stats1 = INVALID_HANDLE_VALUE;  
                                                 DEBUGERR("2pass init error - incomplete stats2 record?");  
                                                 return ICERR_ERROR;  
                                         }  
                                 }  
741    
742                                  if (frames == 0)                                  if (frames == 0)
743                                  {                                  {
744                                            twopass->minbsize = (twopass->nns1.kblk + 88) / 8;
745                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
746                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
747                                            if (recminbsize > twopass->minbsize)
748                                                    twopass->minbsize = recminbsize;
749                                            if (recminpsize > twopass->minpsize)
750                                                    twopass->minpsize = recminpsize;
751                                            if (recminisize > twopass->minisize)
752                                                    twopass->minisize = recminisize;
753                                  }                                  }
754    
755                                    // skip unnecessary frames.
756                                    if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||
757                                            twopass->nns1.dd_v & NNSTATS_PADFRAME ||
758                                            twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
759                                            continue;
760    
761                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
762                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
763                                  {                                  {
764                                          dbytes = twopass->nns1.bytes / twopass->movie_curve;                                          dbytes = twopass->nns1.bytes / twopass->movie_curve;
765                                          total1 += dbytes;                                          total1 += dbytes;
766    
767                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
768                                                    dbytes *= twopass->average_pframe / twopass->average_bframe;
769    
770                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
771                                          {                                          {
772                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
773                                                  {                                                  {
774                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
775                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
# Line 547  Line 779 
779                                                                  {                                                                  {
780                                                                  case 2:                                                                  case 2:
781                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
782                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
783                                                                          break;                                                                          break;
784                                                                  case 1:                                                                  case 1:
785                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
786                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
787                                                                          break;                                                                          break;
788                                                                  case 0:                                                                  case 0:
789                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
790                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
791                                                                  }                                                                  }
792                                                          }                                                          }
793                                                  }                                                  }
# Line 569  Line 801 
801                                                                  {                                                                  {
802                                                                  case 2:                                                                  case 2:
803                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
804                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
805                                                                          break;                                                                          break;
806                                                                  case 1:                                                                  case 1:
807                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
808                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
809                                                                          break;                                                                          break;
810                                                                  case 0:                                                                  case 0:
811                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
812                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
813                                                                  }                                                                  }
814                                                          }                                                          }
815                                                  }                                                  }
816                                          }                                          }
817                                          else                                          else
818                                          {                                          {
819                                                  if (dbytes > twopass->average_frame)                                                  if (dbytes > twopass->average_pframe)
820                                                  {                                                  {
821                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
822                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
823                                                  }                                                  }
824                                                  else                                                  else
825                                                  {                                                  {
826                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *
827                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
828                                                  }                                                  }
829                                          }                                          }
830    
831                                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
832                                            {
833                                                    dbytes2 *= twopass->average_bframe / twopass->average_pframe;
834                                                    if (dbytes2 < twopass->minbsize)
835                                                            dbytes2 = twopass->minbsize;
836                                            }
837                                            else
838                                            {
839                                          if (dbytes2 < twopass->minpsize)                                          if (dbytes2 < twopass->minpsize)
840                                                  dbytes2 = twopass->minpsize;                                                  dbytes2 = twopass->minpsize;
841                                            }
842    
843                                          total2 += dbytes2;                                          total2 += dbytes2;
844                                  }                                  }
# Line 612  Line 853 
853                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
854                                  char s[100];                                  char s[100];
855    
856                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);
857                                  wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);                                  wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame);
858                                  DEBUG2P(s);                                  DEBUG2P(s);
859                          }                          }
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
860                  }                  }
861    
862                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
# Line 636  Line 875 
875                                  int i, newquant, percent;                                  int i, newquant, percent;
876                                  int oldquant = 1;                                  int oldquant = 1;
877    
878                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_frame));                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_pframe));
879                                  DEBUG2P(s);                                  DEBUG2P(s);
880    
881                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));
# Line 645  Line 884 
884                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)
885                                  {                                  {
886                                          dbytes = i;                                          dbytes = i;
887                                          if (dbytes > twopass->average_frame)                                          if (dbytes > twopass->average_pframe)
888                                          {                                          {
889                                                  if (dbytes >= twopass->alt_curve_high)                                                  if (dbytes >= twopass->alt_curve_high)
890                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
# Line 655  Line 894 
894                                                          {                                                          {
895                                                          case 2:                                                          case 2:
896                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
897                                                                  sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));                                                                  sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));
898                                                                  break;                                                                  break;
899                                                          case 1:                                                          case 1:
900                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
901                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
902                                                                  break;                                                                  break;
903                                                          case 0:                                                          case 0:
904                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
905                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));
906                                                          }                                                          }
907                                                  }                                                  }
908                                          }                                          }
# Line 677  Line 916 
916                                                          {                                                          {
917                                                          case 2:                                                          case 2:
918                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
919                                                                  sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));                                                                  sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));
920                                                                  break;                                                                  break;
921                                                          case 1:                                                          case 1:
922                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
923                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
924                                                                  break;                                                                  break;
925                                                          case 0:                                                          case 0:
926                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                          curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
927                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));
928                                                          }                                                          }
929                                                  }                                                  }
930                                          }                                          }
# Line 699  Line 938 
938                                                  if (newquant != oldquant)                                                  if (newquant != oldquant)
939                                                  {                                                  {
940                                                          oldquant = newquant;                                                          oldquant = newquant;
941                                                          percent = (int)((i - twopass->average_frame) * 100.0 / twopass->average_frame);                                                          percent = (int)((i - twopass->average_pframe) * 100.0 / twopass->average_pframe);
942                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);
943                                                          DEBUG2P(s);                                                          DEBUG2P(s);
944                                                  }                                                  }
# Line 719  Line 958 
958          return ICERR_OK;          return ICERR_OK;
959  }  }
960    
961    // NOTE: codec_2pass_get_quant() should be called for all the frames that are in the stats file(s)
962  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
963  {  {
964          static double quant_error[32];          static double bquant_error[32];
965            static double pquant_error[32];
966          static double curve_comp_error;          static double curve_comp_error;
967          static int last_quant;          static int last_bquant, last_pquant;
968    
969          TWOPASS * twopass = &codec->twopass;          TWOPASS * twopass = &codec->twopass;
970    
971          DWORD read;  //      DWORD read;
972          int bytes1, bytes2;          int bytes1, bytes2;
973          int overflow;          int overflow;
974          int credits_pos;          int credits_pos;
# Line 741  Line 981 
981    
982                  for (i=0 ; i<32 ; ++i)                  for (i=0 ; i<32 ; ++i)
983                  {                  {
984                          quant_error[i] = 0.0;                          bquant_error[i] = 0.0;
985                            pquant_error[i] = 0.0;
986                          twopass->quant_count[i] = 0;                          twopass->quant_count[i] = 0;
987                  }                  }
988    
989                  curve_comp_error = 0.0;                  curve_comp_error = 0.0;
990                  last_quant = 0;                  last_bquant = 0;
991                    last_pquant = 0;
992          }          }
993    
994          if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))          if (twopass->nns_array_pos >= twopass->nns_array_length)
995          {          {
996                  DEBUGERR("2ndpass quant: couldn't read from stats1");                  twopass->nns_array_pos = 0;
997                    DEBUGERR("ERROR: VIDEO EXCEEDS 1ST PASS!!!");
998                  return ICERR_ERROR;                  return ICERR_ERROR;
999          }          }
1000    
1001            memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));
1002          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
1003                    memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));
1004            twopass->nns_array_pos++;
1005    
1006            bytes1 = twopass->nns1.bytes;
1007    
1008            // skip unnecessary frames.
1009            if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME)
1010          {          {
1011                  if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))                  twopass->bytes1 = bytes1;
1012                    twopass->bytes2 = bytes1;
1013                    twopass->desired_bytes2 = bytes1;
1014                    frame->intra = 3;
1015                    return 2;
1016            }
1017            else if (twopass->nns1.dd_v & NNSTATS_PADFRAME)
1018                  {                  {
1019                          DEBUGERR("2ndpass quant: couldn't read from stats2");                  twopass->bytes1 = bytes1;
1020                          return ICERR_ERROR;                  twopass->bytes2 = bytes1;
1021                    twopass->desired_bytes2 = bytes1;
1022                    frame->intra = 4;
1023                    return 2;
1024                  }                  }
1025            else if (twopass->nns1.dd_v & NNSTATS_DELAYFRAME)
1026            {
1027                    twopass->bytes1 = bytes1;
1028                    twopass->bytes2 = bytes1;
1029                    twopass->desired_bytes2 = bytes1;
1030                    frame->intra = 5;
1031                    return 2;
1032          }          }
1033    
         bytes1 = twopass->nns1.bytes;  
1034          overflow = twopass->overflow / 8;          overflow = twopass->overflow / 8;
1035    
1036          // override codec i-frame choice (reenable in credits)          // override codec i-frame choice (reenable in credits)
1037          frame->intra = (twopass->nns1.quant & NNSTATS_KEYFRAME);          if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1038                    frame->intra=1;
1039            else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1040                    frame->intra=2;
1041            else
1042                    frame->intra=0;
1043    
1044          if (frame->intra)          if (frame->intra==1)
1045          {          {
1046                  overflow = 0;                  overflow = 0;
1047          }          }
# Line 821  Line 1093 
1093                          {                          {
1094                                  if (codec->config.credits_quant_i != codec->config.credits_quant_p)                                  if (codec->config.credits_quant_i != codec->config.credits_quant_p)
1095                                  {                                  {
1096                                          frame->quant = frame->intra ?                                          frame->quant = frame->intra == 1 ?
1097                                                  codec->config.credits_quant_i :                                                  codec->config.credits_quant_i :
1098                                                  codec->config.credits_quant_p;                                                  codec->config.credits_quant_p;
1099                                  }                                  }
# Line 846  Line 1118 
1118    
1119                  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;
1120    
1121                  if (frame->intra)                  if (frame->intra==1)
1122                  {                  {
1123                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
1124                                  twopass->movie_curve;                                  twopass->movie_curve;
# Line 856  Line 1128 
1128                          dbytes = bytes2 / twopass->movie_curve;                          dbytes = bytes2 / twopass->movie_curve;
1129                  }                  }
1130    
1131                    if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1132                            dbytes *= twopass->average_pframe / twopass->average_bframe;
1133    
1134                  // spread the compression error across payback_delay frames                  // spread the compression error across payback_delay frames
1135                  if (codec->config.bitrate_payback_method == 0)                  if (codec->config.bitrate_payback_method == 0)
1136                  {                  {
# Line 864  Line 1139 
1139                  else                  else
1140                  {                  {
1141                          bytes2 = (int)(curve_comp_error * dbytes /                          bytes2 = (int)(curve_comp_error * dbytes /
1142                                  twopass->average_frame / codec->config.bitrate_payback_delay);                                  twopass->average_pframe / codec->config.bitrate_payback_delay);
1143    
1144                          if (labs(bytes2) > fabs(curve_comp_error))                          if (labs(bytes2) > fabs(curve_comp_error))
1145                          {                          {
# Line 876  Line 1151 
1151    
1152                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
1153                  {                  {
1154                          if (!frame->intra)                          if (!(frame->intra==1))
1155                          {                          {
1156                                  if (dbytes > twopass->average_frame)                                  if (dbytes > twopass->average_pframe)
1157                                  {                                  {
1158                                          if (dbytes >= twopass->alt_curve_high)                                          if (dbytes >= twopass->alt_curve_high)
1159                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
# Line 888  Line 1163 
1163                                                  {                                                  {
1164                                                  case 2:                                                  case 2:
1165                                                  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 *
1166                                                          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)));
1167                                                          break;                                                          break;
1168                                                  case 1:                                                  case 1:
1169                                                  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 *
1170                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);
1171                                                          break;                                                          break;
1172                                                  case 0:                                                  case 0:
1173                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1174                                                          (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))));
1175                                                  }                                                  }
1176                                          }                                          }
1177                                  }                                  }
# Line 910  Line 1185 
1185                                                  {                                                  {
1186                                                  case 2:                                                  case 2:
1187                                                  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 *
1188                                                          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)));
1189                                                          break;                                                          break;
1190                                                  case 1:                                                  case 1:
1191                                                  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 *
1192                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);
1193                                                          break;                                                          break;
1194                                                  case 0:                                                  case 0:
1195                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                  curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
1196                                                          (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))));
1197                                                  }                                                  }
1198                                          }                                          }
1199                                  }                                  }
1200                                    if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1201                                            curve_temp *= twopass->average_bframe / twopass->average_pframe;
1202    
1203                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
1204    
1205                                  bytes2 += ((int)curve_temp);                                  bytes2 += ((int)curve_temp);
# Line 929  Line 1207 
1207                          }                          }
1208                          else                          else
1209                          {                          {
1210                                  curve_comp_error += dbytes - ((int)dbytes);                                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1211                                            dbytes *= twopass->average_bframe / twopass->average_pframe;
1212    
1213                                  bytes2 += ((int)dbytes);                                  bytes2 += ((int)dbytes);
1214                                    curve_comp_error += dbytes - ((int)dbytes);
1215                          }                          }
1216                  }                  }
1217                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
1218                          !frame->intra)                          !(frame->intra==1))
1219                  {                  {
1220                          if (dbytes > twopass->average_frame)                          if (dbytes > twopass->average_pframe)
1221                          {                          {
1222                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
1223                                          ((double)dbytes + (twopass->average_frame - dbytes) *                                          ((double)dbytes + (twopass->average_pframe - dbytes) *
1224                                          codec->config.curve_compression_high / 100.0);                                          codec->config.curve_compression_high / 100.0);
1225                          }                          }
1226                          else                          else
1227                          {                          {
1228                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
1229                                          ((double)dbytes + (twopass->average_frame - dbytes) *                                          ((double)dbytes + (twopass->average_pframe - dbytes) *
1230                                          codec->config.curve_compression_low / 100.0);                                          codec->config.curve_compression_low / 100.0);
1231                          }                          }
1232    
1233                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1234                                    curve_temp *= twopass->average_bframe / twopass->average_pframe;
1235    
1236                          bytes2 += ((int)curve_temp);                          bytes2 += ((int)curve_temp);
1237                          curve_comp_error += curve_temp - ((int)curve_temp);                          curve_comp_error += curve_temp - ((int)curve_temp);
1238                  }                  }
1239                  else                  else
1240                  {                  {
1241                          curve_comp_error += dbytes - ((int)dbytes);                          if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1242                                    dbytes *= twopass->average_bframe / twopass->average_pframe;
1243    
1244                          bytes2 += ((int)dbytes);                          bytes2 += ((int)dbytes);
1245                            curve_comp_error += dbytes - ((int)dbytes);
1246                  }                  }
1247    
1248                  if (frame->intra)                  // cap bytes2 to first pass size, lowers number of quant=1 frames
1249                    if (bytes2 > bytes1)
1250                    {
1251                            curve_comp_error += bytes2 - bytes1;
1252                            bytes2 = bytes1;
1253                    }
1254                    else
1255                    {
1256                            if (frame->intra==1)
1257                  {                  {
1258                          if (bytes2 < twopass->minisize)                          if (bytes2 < twopass->minisize)
1259                          {                          {
# Line 966  Line 1261 
1261                                  bytes2 = twopass->minisize;                                  bytes2 = twopass->minisize;
1262                          }                          }
1263                  }                  }
1264                  else                          else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
                 {  
                         // cap bytes2 to first pass size, lowers number of quant=1 frames  
                         if (bytes2 > bytes1)  
1265                          {                          {
1266                                  curve_comp_error += bytes2 - bytes1;                                  if (bytes2 < twopass->minbsize)
1267                                  bytes2 = bytes1;                                          bytes2 = twopass->minbsize;
1268                          }                          }
1269                          else if (bytes2 < twopass->minpsize)                          else
1270                            {
1271                                    if (bytes2 < twopass->minpsize)
1272                                  bytes2 = twopass->minpsize;                                  bytes2 = twopass->minpsize;
1273                  }                  }
1274          }          }
1275            }
1276    
1277          twopass->desired_bytes2 = bytes2;          twopass->desired_bytes2 = bytes2;
1278    
1279          // if this keyframe is too close to the next,          // if this keyframe is too close to the next,
1280          // reduce it's byte allotment          // reduce it's byte allotment
1281          if (frame->intra && !credits_pos)          if ((frame->intra==1) && !credits_pos)
1282          {          {
1283                  KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -                  KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1284                          codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];                          codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];
# Line 1009  Line 1304 
1304    
1305          // 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
1306          // too much/little bitrate          // too much/little bitrate
1307          overflow = (int)((double)overflow * bytes2 / twopass->average_frame *          overflow = (int)((double)overflow * bytes2 / twopass->average_pframe);
                 (bytes1 - bytes2) / bytes1);  
1308    
1309          // Foxer: reign in overflow with huge frames          // Foxer: reign in overflow with huge frames
1310          if (labs(overflow) > labs(twopass->overflow))          if (labs(overflow) > labs(twopass->overflow))
# Line 1039  Line 1333 
1333                  bytes2 = twopass->max_framesize;                  bytes2 = twopass->max_framesize;
1334          }          }
1335    
1336          if (bytes2 < 1)          // make sure to not scale below the minimum framesize
1337            if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1338          {          {
1339                  bytes2 = 1;                  if (bytes2 < twopass->minisize)
1340                            bytes2 = twopass->minisize;
1341            }
1342            else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1343            {
1344                    if (bytes2 < twopass->minbsize)
1345                            bytes2 = twopass->minbsize;
1346            }
1347            else
1348            {
1349                    if (bytes2 < twopass->minpsize)
1350                            bytes2 = twopass->minpsize;
1351          }          }
1352    
1353          twopass->bytes1 = bytes1;          twopass->bytes1 = bytes1;
# Line 1058  Line 1364 
1364          {          {
1365                  frame->quant = 31;                  frame->quant = 31;
1366          }          }
1367          else if (!frame->intra)          else if (!(frame->intra==1))
1368          {          {
1369                  // Foxer: aid desired quantizer precision by accumulating decision error                  // Foxer: aid desired quantizer precision by accumulating decision error
1370                  quant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1371                    {
1372                            bquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1373                          bytes1) / bytes2) - frame->quant;                          bytes1) / bytes2) - frame->quant;
1374    
1375                  if (quant_error[frame->quant] >= 1.0)                          if (bquant_error[frame->quant] >= 1.0)
1376                  {                  {
1377                          quant_error[frame->quant] -= 1.0;                                  bquant_error[frame->quant] -= 1.0;
1378                          ++frame->quant;                          ++frame->quant;
1379                  }                  }
1380          }          }
1381                    else
1382                    {
1383                            pquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
1384                                    bytes1) / bytes2) - frame->quant;
1385    
1386                            if (pquant_error[frame->quant] >= 1.0)
1387                            {
1388                                    pquant_error[frame->quant] -= 1.0;
1389                                    ++frame->quant;
1390                            }
1391                    }
1392            }
1393    
1394          // we're done with credits          // we're done with credits
1395          if (codec_is_in_credits(&codec->config, codec->framenum))          if (codec_is_in_credits(&codec->config, codec->framenum))
# Line 1077  Line 1397 
1397                  return ICERR_OK;                  return ICERR_OK;
1398          }          }
1399    
1400          if (frame->intra)          if ((frame->intra==1))
1401          {          {
1402                  if (frame->quant < codec->config.min_iquant)                  if (frame->quant < codec->config.min_iquant)
1403                  {                  {
# Line 1102  Line 1422 
1422                  }                  }
1423    
1424                  // subsequent frame quants can only be +- 2                  // subsequent frame quants can only be +- 2
1425                  if (last_quant && capped_to_max_framesize == 0)                  if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)
1426                    {
1427                            if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1428                            {
1429                                    // this bframe quantizer variation
1430                                    // restriction needs to be redone.
1431                                    if (frame->quant > last_bquant + 2)
1432                                    {
1433                                            frame->quant = last_bquant + 2;
1434                                            DEBUG2P("B-frame quantizer prevented from rising too steeply");
1435                                    }
1436                                    if (frame->quant < last_bquant - 2)
1437                                    {
1438                                            frame->quant = last_bquant - 2;
1439                                            DEBUG2P("B-frame quantizer prevented from falling too steeply");
1440                                    }
1441                            }
1442                            else
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 rising too steeply");                                  DEBUG2P("P-frame quantizer prevented from rising too steeply");
1448                          }                          }
1449                          if (frame->quant < last_quant - 2)                                  if (frame->quant < last_pquant - 2)
1450                          {                          {
1451                                  frame->quant = last_quant - 2;                                          frame->quant = last_pquant - 2;
1452                                  DEBUG2P("P-frame quantizer prevented from falling too steeply");                                  DEBUG2P("P-frame quantizer prevented from falling too steeply");
1453                          }                          }
1454                  }                  }
1455          }          }
1456            }
1457    
1458          if (capped_to_max_framesize == 0)          if (capped_to_max_framesize == 0)
1459                  last_quant = frame->quant;          {
1460                    if (twopass->nns1.quant & NNSTATS_KEYFRAME)
1461                    {
1462                            last_bquant = frame->quant;
1463                            last_pquant = frame->quant;
1464                    }
1465                    else if (twopass->nns1.dd_v & NNSTATS_BFRAME)
1466                            last_bquant = frame->quant;
1467                    else
1468                            last_pquant = frame->quant;
1469            }
1470    
1471          if (codec->config.quant_type == QUANT_MODE_MOD)          if (codec->config.quant_type == QUANT_MODE_MOD)
1472          {          {
1473                  frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;                  frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;
1474                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1475          }          }
1476    /*
1477            if (codec->config.quant_type == QUANT_MODE_MOD_NEW)
1478            {
1479                    frame->general |= (frame->quant < 4) ? XVID_H263QUANT : XVID_MPEGQUANT;
1480                    frame->general &= (frame->quant < 4) ? ~XVID_MPEGQUANT : ~XVID_H263QUANT;
1481            }
1482    */
1483          return ICERR_OK;          return ICERR_OK;
1484  }  }
1485    
# Line 1138  Line 1492 
1492          DWORD wrote;          DWORD wrote;
1493          int credits_pos, tempdiv;          int credits_pos, tempdiv;
1494          char* quant_type;          char* quant_type;
1495            char* frame_type;
1496    
1497          if (codec->framenum == 0)          if (codec->framenum == 0)
1498          {          {
# Line 1161  Line 1516 
1516    
1517  //              nns1.quant = stats->quant;  //              nns1.quant = stats->quant;
1518                  nns1.quant = 2;                         // ugly fix for lumi masking in 1st pass returning new quant                  nns1.quant = 2;                         // ugly fix for lumi masking in 1st pass returning new quant
1519                  if (frame->intra)                  nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1520                  {                  frame_type="inter";
1521                    if (frame->intra==1) {
1522                          nns1.quant |= NNSTATS_KEYFRAME;                          nns1.quant |= NNSTATS_KEYFRAME;
1523                            frame_type="intra";
1524                    }
1525                    else if (frame->intra==2) {
1526                            nns1.dd_v |= NNSTATS_BFRAME;
1527                            frame_type="bframe";
1528                    }
1529                    else if (frame->intra==3) {
1530                            nns1.dd_v |= NNSTATS_SKIPFRAME;
1531                            frame_type="skiped";
1532                    }
1533                    else if (frame->intra==4) {
1534                            nns1.dd_v |= NNSTATS_PADFRAME;
1535                            frame_type="padded";
1536                    }
1537                    else if (frame->intra==5) {
1538                            nns1.dd_v |= NNSTATS_DELAYFRAME;
1539                            frame_type="delayed";
1540                  }                  }
1541                  nns1.kblk = stats->kblks;                  nns1.kblk = stats->kblks;
1542                  nns1.mblk = stats->mblks;                  nns1.mblk = stats->mblks;
1543                  nns1.ublk = stats->ublks;                  nns1.ublk = stats->ublks;
                 nns1.lum_noise[0] = nns1.lum_noise[1] = 1;  
1544    
1545                  total_size += frame->length;                  total_size += frame->length;
1546    
1547                  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)
1548    
1549    
1550                  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))
1551                  {                  {
# Line 1184  Line 1557 
1557          case DLG_MODE_2PASS_2_INT :          case DLG_MODE_2PASS_2_INT :
1558          case DLG_MODE_2PASS_2_EXT :          case DLG_MODE_2PASS_2_EXT :
1559                  credits_pos = codec_is_in_credits(&codec->config, codec->framenum);                  credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1560                    if (!(codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&
1561                            !(codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) &&
1562                            !(codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME))
1563                    {
1564                  if (!credits_pos)                  if (!credits_pos)
1565                  {                  {
1566                          codec->twopass.quant_count[frame->quant]++;                          codec->twopass.quant_count[frame->quant]++;
# Line 1231  Line 1608 
1608                          codec->twopass.KFoverflow_partial = 0;                          codec->twopass.KFoverflow_partial = 0;
1609                          // end of ugly fix.                          // end of ugly fix.
1610                  }                  }
1611                    }
1612    
1613                  DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)                  frame_type="inter";
1614                    if (frame->intra==1) {
1615                            frame_type="intra";
1616                    }
1617                    else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME) {
1618                            frame_type="bframe";
1619                    }
1620                    else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {
1621                            frame_type="skipped";
1622                            frame->quant = 2;
1623                            codec->twopass.bytes1 = 1;
1624                            codec->twopass.desired_bytes2 = 1;
1625                            frame->length = 1;
1626                    }
1627                    else if (codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) {
1628                            frame_type="padded";
1629                            frame->quant = 2;
1630                            codec->twopass.bytes1 = 7;
1631                            codec->twopass.desired_bytes2 = 7;
1632                            frame->length = 7;
1633                    }
1634                    else if (codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {
1635                            frame_type="delayed";
1636                            frame->quant = 2;
1637                            codec->twopass.bytes1 = 1;
1638                            codec->twopass.desired_bytes2 = 1;
1639                            frame->length = 1;
1640                    }
1641    
1642                    DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
1643                  break;                  break;
1644    
1645          default:          default:
# Line 1246  Line 1653 
1653  {  {
1654          int i;          int i;
1655          char s[100];          char s[100];
1656    
1657            if (codec->twopass.nns1_array)
1658            {
1659                    free(codec->twopass.nns1_array);
1660                    codec->twopass.nns1_array = NULL;
1661            }
1662            if (codec->twopass.nns2_array)
1663            {
1664                    free(codec->twopass.nns2_array);
1665                    codec->twopass.nns2_array = NULL;
1666            }
1667            codec->twopass.nns_array_size = 0;
1668            codec->twopass.nns_array_length = 0;
1669            codec->twopass.nns_array_pos = 0;
1670    
1671          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)
1672          {          {
1673                  // output the quantizer distribution for this encode.                  // output the quantizer distribution for this encode.
# Line 1262  Line 1684 
1684                  return;                  return;
1685          }          }
1686  }  }
1687    

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

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