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

Diff of /vfw/src/2pass.c

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

revision 1.7.2.7, Fri Dec 20 05:35:56 2002 UTC revision 1.11, Sat Sep 28 02:01:56 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, bframes = 0, pframes = 0, credits_frames = 0, i_frames = 0, recminbsize = 0, recminpsize = 0, recminisize = 0;          int     frames = 0, credits_frames = 0, i_frames = 0, recminpsize = 0, recminisize = 0;
45          __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;          __int64 total_ext = 0, total = 0, i_total = 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    
         /* ensure free() is called safely */  
         codec->twopass.hintstream = NULL;  
         twopass->nns1_array = NULL;  
         twopass->nns2_array = NULL;  
   
52          if (codec->config.hinted_me)          if (codec->config.hinted_me)
53          {          {
54                  codec->twopass.hintstream = malloc(100000);                  codec->twopass.hintstream = malloc(100000);
# Line 106  Line 101 
101                          return ICERR_ERROR;                          return ICERR_ERROR;
102                  }                  }
103    
                 twopass->nns1_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);  
                 twopass->nns2_array = (NNSTATS*)malloc(sizeof(NNSTATS) * 10240);  
                 twopass->nns_array_size = 10240;  
                 twopass->nns_array_length = 0;  
                 twopass->nns_array_pos = 0;  
   
                 // read the stats file(s) into array(s) and reorder them so they  
                 // correctly represent the frames that the encoder will receive.  
104                  if (codec->config.mode == DLG_MODE_2PASS_2_EXT)                  if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
105                  {                  {
106                          if (twopass->stats2 != INVALID_HANDLE_VALUE)                          if (twopass->stats2 != INVALID_HANDLE_VALUE)
# Line 171  Line 158 
158                                          }                                          }
159                                  }                                  }
160    
                                 // increase the allocated memory if necessary  
                                 if (frames >= twopass->nns_array_size)  
                                 {  
                                         twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array,  
                                                 sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));  
                                         twopass->nns2_array = (NNSTATS*)realloc(twopass->nns2_array,  
                                                 sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));  
                                         twopass->nns_array_size = twopass->nns_array_size * 5 / 4 + 1;  
                                 }  
   
                                 // copy this frame's stats into the arrays  
                                 memcpy (&twopass->nns1_array[frames], &twopass->nns1, sizeof(NNSTATS));  
                                 memcpy (&twopass->nns2_array[frames], &twopass->nns2, sizeof(NNSTATS));  
                                 frames++;  
                         }  
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
                         SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);  
                 }  
                 else    // DLG_MODE_2PASS_2_INT  
                 {  
                         while (1)  
                         {  
                                 if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))  
                                 {  
                                         DWORD err = GetLastError();  
   
                                         if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)  
                                         {  
                                                 break;  
                                         }  
                                         else  
                                         {  
                                                 CloseHandle(twopass->stats1);  
                                                 twopass->stats1 = INVALID_HANDLE_VALUE;  
                                                 DEBUGERR("2pass init error - incomplete stats2 record?");  
                                                 return ICERR_ERROR;  
                                         }  
                                 }  
   
                                 // increase the allocated memory if necessary  
                                 if (frames >= twopass->nns_array_size)  
                                 {  
                                         twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array,  
                                                 sizeof(NNSTATS) * (twopass->nns_array_size * 5 / 4 + 1));  
                                         twopass->nns_array_size = twopass->nns_array_size * 5 / 4 + 1;  
                                 }  
   
                                 // copy this frame's stats into the array  
                                 memcpy (&twopass->nns1_array[frames], &twopass->nns1, sizeof(NNSTATS));  
                                 frames++;  
                         }  
   
                         SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);  
                 }  
                 twopass->nns1_array = (NNSTATS*)realloc(twopass->nns1_array, sizeof(NNSTATS) * frames);  
                 twopass->nns2_array = (NNSTATS*)realloc(twopass->nns2_array, sizeof(NNSTATS) * frames);  
                 twopass->nns_array_size = frames;  
                 twopass->nns_array_length = frames;  
                 frames = 0;  
   
 /* // this isn't necessary with the current core.  
                 // reorder the array(s) so they are in the order that they were received  
                 // IPBBPBB to  
                 // IBBPBBP  
                 for (i=0; i<twopass->nns_array_length; i++)  
                 {  
                         NNSTATS temp_nns, temp_nns2;  
                         int k, num_bframes;  
                         if (twopass->nns1_array[i].dd_v & NNSTATS_BFRAME)  
                         {  
                                 num_bframes = 1;  
                                 for (k=i+1; k<twopass->nns_array_length; k++)  
                                 {  
                                         if (twopass->nns1_array[k].dd_v & NNSTATS_BFRAME)  
                                                 num_bframes++;  
                                         else  
                                                 k=twopass->nns_array_length;  
                                 }  
   
                                 i--;  
                                 memcpy (&temp_nns, &twopass->nns1_array[i], sizeof(NNSTATS));  
                                 if (codec->config.mode == DLG_MODE_2PASS_2_EXT)  
                                         memcpy (&temp_nns2, &twopass->nns2_array[i], sizeof(NNSTATS));  
   
                                 for (k=0; k<num_bframes; k++)  
                                 {  
                                         memcpy(&twopass->nns1_array[i], &twopass->nns1_array[i+1], sizeof(NNSTATS));  
                                         if (codec->config.mode == DLG_MODE_2PASS_2_EXT)  
                                                 memcpy(&twopass->nns2_array[i], &twopass->nns2_array[i+1], sizeof(NNSTATS));  
                                         i++;  
                                 }  
   
                                 memcpy(&twopass->nns1_array[i], &temp_nns, sizeof(NNSTATS));  
                                 if (codec->config.mode == DLG_MODE_2PASS_2_EXT)  
                                         memcpy(&twopass->nns2_array[i], &temp_nns2, sizeof(NNSTATS));  
                         }  
                 }  
 */  
                 // continue with the initialization..  
                 if (codec->config.mode == DLG_MODE_2PASS_2_EXT)  
                 {  
                         while (1)  
                         {  
                                 if (twopass->nns_array_pos >= twopass->nns_array_length)  
                                 {  
                                         twopass->nns_array_pos = 0;  
                                         break;  
                                 }  
   
                                 memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));  
                                 memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));  
                                 twopass->nns_array_pos++;  
   
                                 // skip unnecessary frames.  
                                 if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||  
                                         twopass->nns1.dd_v & NNSTATS_PADFRAME ||  
                                         twopass->nns1.dd_v & NNSTATS_DELAYFRAME)  
                                         continue;  
   
161                                  if (!codec_is_in_credits(&codec->config, frames))                                  if (!codec_is_in_credits(&codec->config, frames))
162                                  {                                  {
163                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)
164                                          {                                          {
                                                 i_total += twopass->nns2.bytes;  
165                                                  i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;                                                  i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;
166                                                    i_total += twopass->nns2.bytes;
167                                                  twopass->keyframe_locations[i_frames] = frames;                                                  twopass->keyframe_locations[i_frames] = frames;
168                                                  ++i_frames;                                                  ++i_frames;
169                                          }                                          }
170                                          else  
171                                          {                                          total += twopass->nns1.bytes;
172                                                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)                                          total_ext += twopass->nns2.bytes;
                                                 {  
                                                         bframe_total += twopass->nns1.bytes;  
                                                         bframe_total_ext += twopass->nns2.bytes;  
                                                         bframes++;  
                                                 }  
                                                 else  
                                                 {  
                                                         pframe_total += twopass->nns1.bytes;  
                                                         pframe_total_ext += twopass->nns2.bytes;  
                                                         pframes++;  
                                                 }  
                                         }  
173                                  }                                  }
174                                  else                                  else
175                                          ++credits_frames;                                          ++credits_frames;
176    
177                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)
178                                  {                                  {
                                         // this test needs to be corrected..  
179                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))
180                                                  recminisize = twopass->nns1.bytes;                                                  recminisize = twopass->nns1.bytes;
181                                  }                                  }
                                 else if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                 {  
                                         if (!(twopass->nns1.kblk + twopass->nns1.mblk))  
                                                 recminbsize = twopass->nns1.bytes;  
                                 }  
182                                  else                                  else
183                                  {                                  {
184                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))
# Line 340  Line 189 
189                          }                          }
190                          twopass->keyframe_locations[i_frames] = frames;                          twopass->keyframe_locations[i_frames] = frames;
191    
192                          twopass->movie_curve = ((double)(bframe_total_ext + pframe_total_ext + i_boost_total) /                          twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);
193                                  (bframe_total_ext + pframe_total_ext));                          twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);
   
                         if (bframes)  
                                 twopass->average_bframe = (double)bframe_total_ext / bframes / twopass->movie_curve;  
   
                         if (pframes)  
                                 twopass->average_pframe = (double)pframe_total_ext / pframes / twopass->movie_curve;  
                         else  
                                 if (bframes)  
                                         twopass->average_pframe = twopass->average_bframe;  // b-frame packed bitstream fix  
                                 else  
                                 {  
                                         DEBUGERR("ERROR:  No p-frames or b-frames were present in the 1st pass.  Rate control cannot function properly!");  
                                         return ICERR_ERROR;  
                                 }  
   
194    
195                            SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
196                            SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
197    
198                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
199                          frames = 0;                          frames = 0;
200    
201                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
202                          {                          {
203                                  twopass->alt_curve_low = twopass->average_pframe - twopass->average_pframe * (double)codec->config.alt_curve_low_dist / 100.0;                                  twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;
204                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;
205                                  twopass->alt_curve_high = twopass->average_pframe + twopass->average_pframe * (double)codec->config.alt_curve_high_dist / 100.0;                                  twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;
206                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;
207                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
208                                  {                                  {
209                                          if (bframe_total + pframe_total > bframe_total_ext + pframe_total_ext)                                          if (total > total_ext)
210                                          {                                          {
211                                                  codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 /                                                  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);
                                                         ((double)(bframe_total + pframe_total) / (double)(bframe_total_ext + pframe_total_ext))) *  
                                                         (double)codec->config.alt_curve_auto_str / 100.0);  
   
212                                                  if (codec->config.alt_curve_min_rel_qual < 20)                                                  if (codec->config.alt_curve_min_rel_qual < 20)
213                                                          codec->config.alt_curve_min_rel_qual = 20;                                                          codec->config.alt_curve_min_rel_qual = 20;
214                                          }                                          }
# Line 390  Line 223 
223                                          {                                          {
224                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
225                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
226                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
227                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
228                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));
229                                                  break;                                                  break;
230                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
231                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
232                                                          twopass->average_pframe / twopass->alt_curve_low_diff);                                                          twopass->average_frame / twopass->alt_curve_low_diff);
233                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
234                                                          twopass->average_pframe / twopass->alt_curve_low_diff;                                                          twopass->average_frame / twopass->alt_curve_low_diff;
235                                                  break;                                                  break;
236                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
237                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
238                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));
239                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
240                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
241                                          }                                          }
242                                  }                                  }
243                          }                          }
244    
245                          while (1)                          while (1)
246                          {                          {
247                                  if (twopass->nns_array_pos >= twopass->nns_array_length)                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||
248                                            !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
249                                    {
250                                            DWORD err = GetLastError();
251    
252                                            if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
253                                  {                                  {
                                         twopass->nns_array_pos = 0;  
254                                          break;                                          break;
255                                  }                                  }
256                                            else
257                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));                                          {
258                                  memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));                                                  CloseHandle(twopass->stats1);
259                                  twopass->nns_array_pos++;                                                  CloseHandle(twopass->stats2);
260                                                    twopass->stats1 = INVALID_HANDLE_VALUE;
261                                                    twopass->stats2 = INVALID_HANDLE_VALUE;
262                                                    DEBUGERR("2pass init error - incomplete stats1/stats2 record?");
263                                                    return ICERR_ERROR;
264                                            }
265                                    }
266    
267                                  if (frames == 0)                                  if (frames == 0)
268                                  {                                  {
                                         twopass->minbsize = (twopass->nns1.kblk + 88) / 8;  
269                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
270                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
                                         if (recminbsize > twopass->minbsize)  
                                                 twopass->minbsize = recminbsize;  
271                                          if (recminpsize > twopass->minpsize)                                          if (recminpsize > twopass->minpsize)
272                                                  twopass->minpsize = recminpsize;                                                  twopass->minpsize = recminpsize;
273                                          if (recminisize > twopass->minisize)                                          if (recminisize > twopass->minisize)
274                                                  twopass->minisize = recminisize;                                                  twopass->minisize = recminisize;
275                                  }                                  }
276    
                                 // skip unnecessary frames.  
                                 if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||  
                                         twopass->nns1.dd_v & NNSTATS_PADFRAME ||  
                                         twopass->nns1.dd_v & NNSTATS_DELAYFRAME)  
                                         continue;  
   
277                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
278                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
279                                  {                                  {
280                                          dbytes = twopass->nns2.bytes / twopass->movie_curve;                                          dbytes = twopass->nns2.bytes / twopass->movie_curve;
281                                          total1 += dbytes;                                          total1 += dbytes;
282    
                                         if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                                 dbytes *= twopass->average_pframe / twopass->average_bframe;  
   
283                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
284                                          {                                          {
285                                                  if (dbytes > twopass->average_pframe)                                                  if (dbytes > twopass->average_frame)
286                                                  {                                                  {
287                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
288                                                                  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 461  Line 292 
292                                                                  {                                                                  {
293                                                                  case 2:                                                                  case 2:
294                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
295                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
296                                                                          break;                                                                          break;
297                                                                  case 1:                                                                  case 1:
298                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
299                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
300                                                                          break;                                                                          break;
301                                                                  case 0:                                                                  case 0:
302                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
303                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
304                                                                  }                                                                  }
305                                                          }                                                          }
306                                                  }                                                  }
# Line 483  Line 314 
314                                                                  {                                                                  {
315                                                                  case 2:                                                                  case 2:
316                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
317                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
318                                                                          break;                                                                          break;
319                                                                  case 1:                                                                  case 1:
320                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
321                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
322                                                                          break;                                                                          break;
323                                                                  case 0:                                                                  case 0:
324                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
325                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
326                                                                  }                                                                  }
327                                                          }                                                          }
328                                                  }                                                  }
329                                          }                                          }
330                                          else                                          else
331                                          {                                          {
332                                                  if (dbytes > twopass->average_pframe)                                                  if (dbytes > twopass->average_frame)
333                                                  {                                                  {
334                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *
335                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
336                                                  }                                                  }
337                                                  else                                                  else
338                                                  {                                                  {
339                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *
340                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
341                                                  }                                                  }
342                                          }                                          }
343    
                                         if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                         {  
                                                 dbytes2 *= twopass->average_bframe / twopass->average_pframe;  
                                                 if (dbytes2 < twopass->minbsize)  
                                                         dbytes2 = twopass->minbsize;  
                                         }  
                                         else  
                                         {  
344                                                  if (dbytes2 < twopass->minpsize)                                                  if (dbytes2 < twopass->minpsize)
345                                                          dbytes2 = twopass->minpsize;                                                          dbytes2 = twopass->minpsize;
                                         }  
346    
347                                          total2 += dbytes2;                                          total2 += dbytes2;
348                                  }                                  }
# Line 535  Line 357 
357                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
358                                  char s[100];                                  char s[100];
359    
360                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);
361                                  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);
362                                  DEBUG2P(s);                                  DEBUG2P(s);
363                          }                          }
364    
365                            SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
366                            SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN);
367                  }                  }
368                  else    // DLG_MODE_2PASS_2_INT                  else    // DLG_MODE_2PASS_2_INT
369                  {                  {
370                          while (1)                          while (1)
371                          {                          {
372                                  if (twopass->nns_array_pos >= twopass->nns_array_length)                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
373                                    {
374                                            DWORD err = GetLastError();
375    
376                                            if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
377                                  {                                  {
                                         twopass->nns_array_pos = 0;  
378                                          break;                                          break;
379                                  }                                  }
380                                            else
381                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));                                          {
382                                  twopass->nns_array_pos++;                                                  CloseHandle(twopass->stats1);
383                                                    twopass->stats1 = INVALID_HANDLE_VALUE;
384                                  // skip unnecessary frames.                                                  DEBUGERR("2pass init error - incomplete stats2 record?");
385                                  if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||                                                  return ICERR_ERROR;
386                                          twopass->nns1.dd_v & NNSTATS_PADFRAME ||                                          }
387                                          twopass->nns1.dd_v & NNSTATS_DELAYFRAME)                                  }
                                         continue;  
388    
389                                  if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)                                  if (codec_is_in_credits(&codec->config, frames) == CREDITS_START)
390                                  {                                  {
# Line 572  Line 399 
399                                  else if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                  else if (twopass->nns1.quant & NNSTATS_KEYFRAME)
400                                  {                                  {
401                                          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;
402                                            total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;
403                                          twopass->keyframe_locations[i_frames] = frames;                                          twopass->keyframe_locations[i_frames] = frames;
404                                          ++i_frames;                                          ++i_frames;
405                                  }                                  }
406                                  else  
407                                  {                                  total += twopass->nns1.bytes;
                                         if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                         {  
                                                 bframe_total += twopass->nns1.bytes;  
                                                 bframes++;  
                                         }  
                                         else  
                                         {  
                                                 pframe_total += twopass->nns1.bytes;  
                                                 pframes++;  
                                         }  
                                 }  
408    
409                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                  if (twopass->nns1.quant & NNSTATS_KEYFRAME)
410                                  {                                  {
                                         // this test needs to be corrected..  
411                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))
412                                                  recminisize = twopass->nns1.bytes;                                                  recminisize = twopass->nns1.bytes;
413                                  }                                  }
                                 else if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                 {  
                                         if (!(twopass->nns1.kblk + twopass->nns1.mblk))  
                                                 recminbsize = twopass->nns1.bytes;  
                                 }  
414                                  else                                  else
415                                  {                                  {
416                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))                                          if (!(twopass->nns1.kblk + twopass->nns1.mblk))
# Line 619  Line 430 
430    
431                                  // credits curve = (total / desired_size) * (100 / credits_rate)                                  // credits curve = (total / desired_size) * (100 / credits_rate)
432                                  twopass->credits_start_curve = twopass->credits_end_curve =                                  twopass->credits_start_curve = twopass->credits_end_curve =
433                                          ((double)(bframe_total + pframe_total + i_total + start + end) / desired) *                                          ((double)total / desired) * ((double)100 / codec->config.credits_rate);
                                         ((double)100 / codec->config.credits_rate);  
434    
435                                  start_curved = (__int64)(start / twopass->credits_start_curve);                                  start_curved = (__int64)(start / twopass->credits_start_curve);
436                                  end_curved = (__int64)(end / twopass->credits_end_curve);                                  end_curved = (__int64)(end / twopass->credits_end_curve);
437    
438                                  // movie curve = (total - credits) / (desired_size - curved credits)                                  // movie curve = (total - credits) / (desired_size - curved credits)
439                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
440                                          (bframe_total + pframe_total + i_total) /                                          (total - start - end) /
441                                          (desired - start_curved - end_curved);                                          (desired - start_curved - end_curved);
442    
443                                  break;                                  break;
# Line 636  Line 446 
446    
447                                  // movie curve = (total - credits) / (desired_size - credits)                                  // movie curve = (total - credits) / (desired_size - credits)
448                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
449                                          (bframe_total + pframe_total + i_total) / (desired - start - end);                                          (total - start - end) / (desired - start - end);
450    
451                                  // aid the average asymmetric frame calculation below                                  // aid the average asymmetric frame calculation below
452                                  start_curved = start;                                  start_curved = start;
# Line 659  Line 469 
469    
470                                  // movie curve = (total - credits) / (desired_size - curved credits)                                  // movie curve = (total - credits) / (desired_size - curved credits)
471                                  twopass->movie_curve = (double)                                  twopass->movie_curve = (double)
472                                          (bframe_total + pframe_total + i_total) /                                          (total - start - end) /
473                                          (desired - start_curved - end_curved);                                          (desired - start_curved - end_curved);
474    
475                                  break;                                  break;
476                          }                          }
477    
478                          if (bframes)                          // average frame size = (desired - curved credits - curved keyframes) /
479                                  twopass->average_bframe = (double)bframe_total / bframes / twopass->movie_curve;                          //      (frames - credits frames - keyframes)
480                            twopass->average_frame = (double)
481                          if (pframes)                                  (desired - start_curved - end_curved - (i_total / twopass->movie_curve)) /
482                                  twopass->average_pframe = (double)pframe_total / pframes / twopass->movie_curve;                                  (frames - credits_frames - i_frames);
                         else  
                                 if (bframes)  
                                         twopass->average_pframe = twopass->average_bframe;  // b-frame packed bitstream fix  
                                 else  
                                 {  
                                         DEBUGERR("ERROR:  No p-frames or b-frames were present in the 1st pass.  Rate control cannot function properly!");  
                                         return ICERR_ERROR;  
                                 }  
   
483    
484                            SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
485    
486                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
487                          frames = 0;                          frames = 0;
488    
489                          if (codec->config.use_alt_curve)                          if (codec->config.use_alt_curve)
490                          {                          {
491                                  twopass->alt_curve_low = twopass->average_pframe - twopass->average_pframe * (double)codec->config.alt_curve_low_dist / 100.0;                                  twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;
492                                  twopass->alt_curve_low_diff = twopass->average_pframe - twopass->alt_curve_low;                                  twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;
493                                  twopass->alt_curve_high = twopass->average_pframe + twopass->average_pframe * (double)codec->config.alt_curve_high_dist / 100.0;                                  twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;
494                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_pframe;                                  twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;
495                                  if (codec->config.alt_curve_use_auto)                                  if (codec->config.alt_curve_use_auto)
496                                  {                                  {
497                                          if (twopass->movie_curve > 1.0)                                          if (twopass->movie_curve > 1.0)
# Line 709  Line 511 
511                                          {                                          {
512                                          case 2: // Sine Curve (high aggressiveness)                                          case 2: // Sine Curve (high aggressiveness)
513                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
514                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
515                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
516                                                          sin(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff));                                                          sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));
517                                                  break;                                                  break;
518                                          case 1: // Linear (medium aggressiveness)                                          case 1: // Linear (medium aggressiveness)
519                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
520                                                          twopass->average_pframe / twopass->alt_curve_low_diff);                                                          twopass->average_frame / twopass->alt_curve_low_diff);
521                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
522                                                          twopass->average_pframe / twopass->alt_curve_low_diff;                                                          twopass->average_frame / twopass->alt_curve_low_diff;
523                                                  break;                                                  break;
524                                          case 0: // Cosine Curve (low aggressiveness)                                          case 0: // Cosine Curve (low aggressiveness)
525                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +                                                  twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
526                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff))));                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));
527                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *                                                  twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
528                                                          (1.0 - cos(DEG2RAD * (twopass->average_pframe * 90.0 / twopass->alt_curve_low_diff)));                                                          (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
529                                          }                                          }
530                                  }                                  }
531                          }                          }
532    
533                          while (1)                          while (1)
534                          {                          {
535                                  if (twopass->nns_array_pos >= twopass->nns_array_length)                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
536                                    {
537                                            DWORD err = GetLastError();
538    
539                                            if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS)
540                                  {                                  {
                                         twopass->nns_array_pos = 0;  
541                                          break;                                          break;
542                                  }                                  }
543                                            else
544                                  memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));                                          {
545                                  twopass->nns_array_pos++;                                                  CloseHandle(twopass->stats1);
546                                                    twopass->stats1 = INVALID_HANDLE_VALUE;
547                                                    DEBUGERR("2pass init error - incomplete stats2 record?");
548                                                    return ICERR_ERROR;
549                                            }
550                                    }
551    
552                                  if (frames == 0)                                  if (frames == 0)
553                                  {                                  {
                                         twopass->minbsize = (twopass->nns1.kblk + 88) / 8;  
554                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;                                          twopass->minpsize = (twopass->nns1.kblk + 88) / 8;
555                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;                                          twopass->minisize = ((twopass->nns1.kblk * 22) + 240) / 8;
                                         if (recminbsize > twopass->minbsize)  
                                                 twopass->minbsize = recminbsize;  
556                                          if (recminpsize > twopass->minpsize)                                          if (recminpsize > twopass->minpsize)
557                                                  twopass->minpsize = recminpsize;                                                  twopass->minpsize = recminpsize;
558                                          if (recminisize > twopass->minisize)                                          if (recminisize > twopass->minisize)
559                                                  twopass->minisize = recminisize;                                                  twopass->minisize = recminisize;
560                                  }                                  }
561    
                                 // skip unnecessary frames.  
                                 if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME ||  
                                         twopass->nns1.dd_v & NNSTATS_PADFRAME ||  
                                         twopass->nns1.dd_v & NNSTATS_DELAYFRAME)  
                                         continue;  
   
562                                  if (!codec_is_in_credits(&codec->config, frames) &&                                  if (!codec_is_in_credits(&codec->config, frames) &&
563                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))                                          !(twopass->nns1.quant & NNSTATS_KEYFRAME))
564                                  {                                  {
565                                          dbytes = twopass->nns1.bytes / twopass->movie_curve;                                          dbytes = twopass->nns1.bytes / twopass->movie_curve;
566                                          total1 += dbytes;                                          total1 += dbytes;
567    
                                         if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                                 dbytes *= twopass->average_pframe / twopass->average_bframe;  
   
568                                          if (codec->config.use_alt_curve)                                          if (codec->config.use_alt_curve)
569                                          {                                          {
570                                                  if (dbytes > twopass->average_pframe)                                                  if (dbytes > twopass->average_frame)
571                                                  {                                                  {
572                                                          if (dbytes >= twopass->alt_curve_high)                                                          if (dbytes >= twopass->alt_curve_high)
573                                                                  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 779  Line 577 
577                                                                  {                                                                  {
578                                                                  case 2:                                                                  case 2:
579                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
580                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
581                                                                          break;                                                                          break;
582                                                                  case 1:                                                                  case 1:
583                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
584                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
585                                                                          break;                                                                          break;
586                                                                  case 0:                                                                  case 0:
587                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
588                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
589                                                                  }                                                                  }
590                                                          }                                                          }
591                                                  }                                                  }
# Line 801  Line 599 
599                                                                  {                                                                  {
600                                                                  case 2:                                                                  case 2:
601                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
602                                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));                                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
603                                                                          break;                                                                          break;
604                                                                  case 1:                                                                  case 1:
605                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
606                                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);                                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
607                                                                          break;                                                                          break;
608                                                                  case 0:                                                                  case 0:
609                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *                                                                  dbytes2 = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
610                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));                                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
611                                                                  }                                                                  }
612                                                          }                                                          }
613                                                  }                                                  }
614                                          }                                          }
615                                          else                                          else
616                                          {                                          {
617                                                  if (dbytes > twopass->average_pframe)                                                  if (dbytes > twopass->average_frame)
618                                                  {                                                  {
619                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *
620                                                                  codec->config.curve_compression_high / 100.0);                                                                  codec->config.curve_compression_high / 100.0);
621                                                  }                                                  }
622                                                  else                                                  else
623                                                  {                                                  {
624                                                          dbytes2 = ((double)dbytes + (twopass->average_pframe - dbytes) *                                                          dbytes2 = ((double)dbytes + (twopass->average_frame - dbytes) *
625                                                                  codec->config.curve_compression_low / 100.0);                                                                  codec->config.curve_compression_low / 100.0);
626                                                  }                                                  }
627                                          }                                          }
628    
                                         if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                         {  
                                                 dbytes2 *= twopass->average_bframe / twopass->average_pframe;  
                                                 if (dbytes2 < twopass->minbsize)  
                                                         dbytes2 = twopass->minbsize;  
                                         }  
                                         else  
                                         {  
629                                                  if (dbytes2 < twopass->minpsize)                                                  if (dbytes2 < twopass->minpsize)
630                                                          dbytes2 = twopass->minpsize;                                                          dbytes2 = twopass->minpsize;
                                         }  
631    
632                                          total2 += dbytes2;                                          total2 += dbytes2;
633                                  }                                  }
# Line 853  Line 642 
642                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
643                                  char s[100];                                  char s[100];
644    
645                                  asymmetric_average_frame = (int)(twopass->average_pframe * twopass->curve_comp_scale);                                  asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale);
646                                  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);
647                                  DEBUG2P(s);                                  DEBUG2P(s);
648                          }                          }
649    
650                            SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
651                  }                  }
652    
653                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
# Line 875  Line 666 
666                                  int i, newquant, percent;                                  int i, newquant, percent;
667                                  int oldquant = 1;                                  int oldquant = 1;
668    
669                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_pframe));                                  wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_frame));
670                                  DEBUG2P(s);                                  DEBUG2P(s);
671    
672                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));                                  wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus));
# Line 884  Line 675 
675                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)                                  for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++)
676                                  {                                  {
677                                          dbytes = i;                                          dbytes = i;
678                                          if (dbytes > twopass->average_pframe)                                          if (dbytes > twopass->average_frame)
679                                          {                                          {
680                                                  if (dbytes >= twopass->alt_curve_high)                                                  if (dbytes >= twopass->alt_curve_high)
681                                                          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 894  Line 685 
685                                                          {                                                          {
686                                                          case 2:                                                          case 2:
687                                                          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 *
688                                                                  sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));                                                                  sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
689                                                                  break;                                                                  break;
690                                                          case 1:                                                          case 1:
691                                                          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 *
692                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
693                                                                  break;                                                                  break;
694                                                          case 0:                                                          case 0:
695                                                          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 *
696                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
697                                                          }                                                          }
698                                                  }                                                  }
699                                          }                                          }
# Line 916  Line 707 
707                                                          {                                                          {
708                                                          case 2:                                                          case 2:
709                                                          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 *
710                                                                  sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));                                                                  sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
711                                                                  break;                                                                  break;
712                                                          case 1:                                                          case 1:
713                                                          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 *
714                                                                  (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);                                                                  (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
715                                                                  break;                                                                  break;
716                                                          case 0:                                                          case 0:
717                                                          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 *
718                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));                                                                  (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
719                                                          }                                                          }
720                                                  }                                                  }
721                                          }                                          }
# Line 938  Line 729 
729                                                  if (newquant != oldquant)                                                  if (newquant != oldquant)
730                                                  {                                                  {
731                                                          oldquant = newquant;                                                          oldquant = newquant;
732                                                          percent = (int)((i - twopass->average_pframe) * 100.0 / twopass->average_pframe);                                                          percent = (int)((i - twopass->average_frame) * 100.0 / twopass->average_frame);
733                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);                                                          wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent);
734                                                          DEBUG2P(s);                                                          DEBUG2P(s);
735                                                  }                                                  }
# Line 958  Line 749 
749          return ICERR_OK;          return ICERR_OK;
750  }  }
751    
752  // NOTE: codec_2pass_get_quant() should be called for all the frames that are in the stats file(s)  
753  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)  int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
754  {  {
755          static double bquant_error[32];          static double quant_error[32];
         static double pquant_error[32];  
756          static double curve_comp_error;          static double curve_comp_error;
757          static int last_bquant, last_pquant;          static int last_quant;
758    
759          TWOPASS * twopass = &codec->twopass;          TWOPASS * twopass = &codec->twopass;
760    
761  //      DWORD read;          DWORD read;
762          int bytes1, bytes2;          int bytes1, bytes2;
763          int overflow;          int overflow;
764          int credits_pos;          int credits_pos;
# Line 981  Line 771 
771    
772                  for (i=0 ; i<32 ; ++i)                  for (i=0 ; i<32 ; ++i)
773                  {                  {
774                          bquant_error[i] = 0.0;                          quant_error[i] = 0.0;
                         pquant_error[i] = 0.0;  
775                          twopass->quant_count[i] = 0;                          twopass->quant_count[i] = 0;
776                  }                  }
777    
778                  curve_comp_error = 0.0;                  curve_comp_error = 0.0;
779                  last_bquant = 0;                  last_quant = 0;
                 last_pquant = 0;  
780          }          }
781    
782          if (twopass->nns_array_pos >= twopass->nns_array_length)          if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))
         {  
                 // fix for VirtualDub 1.4.13 bframe handling  
                 if (codec->config.max_bframes > 0 &&  
                         codec->framenum < twopass->nns_array_length + codec->config.max_bframes)  
783                  {                  {
784                          return ICERR_OK;                  DEBUGERR("2ndpass quant: couldn't read from stats1");
                 }  
                 else  
                 {  
                         DEBUGERR("ERROR: VIDEO EXCEEDS 1ST PASS!!!");  
785                          return ICERR_ERROR;                          return ICERR_ERROR;
786                  }                  }
         }  
   
         memcpy(&twopass->nns1, &twopass->nns1_array[twopass->nns_array_pos], sizeof(NNSTATS));  
787          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
                 memcpy(&twopass->nns2, &twopass->nns2_array[twopass->nns_array_pos], sizeof(NNSTATS));  
         twopass->nns_array_pos++;  
   
         bytes1 = twopass->nns1.bytes;  
   
         // skip unnecessary frames.  
         if (twopass->nns1.dd_v & NNSTATS_SKIPFRAME)  
788          {          {
789                  twopass->bytes1 = bytes1;                  if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))
                 twopass->bytes2 = bytes1;  
                 twopass->desired_bytes2 = bytes1;  
                 frame->intra = 3;  
                 return ICERR_OK;  
         }  
         else if (twopass->nns1.dd_v & NNSTATS_PADFRAME)  
790          {          {
791                  twopass->bytes1 = bytes1;                          DEBUGERR("2ndpass quant: couldn't read from stats2");
792                  twopass->bytes2 = bytes1;                          return ICERR_ERROR;
                 twopass->desired_bytes2 = bytes1;  
                 frame->intra = 4;  
                 return ICERR_OK;  
793          }          }
         else if (twopass->nns1.dd_v & NNSTATS_DELAYFRAME)  
         {  
                 twopass->bytes1 = bytes1;  
                 twopass->bytes2 = bytes1;  
                 twopass->desired_bytes2 = bytes1;  
                 frame->intra = 5;  
                 return ICERR_OK;  
794          }          }
795    
796            bytes1 = twopass->nns1.bytes;
797          overflow = twopass->overflow / 8;          overflow = twopass->overflow / 8;
798    
799          // override codec i-frame choice (reenable in credits)          // override codec i-frame choice (reenable in credits)
800          if (twopass->nns1.quant & NNSTATS_KEYFRAME)          frame->intra = (twopass->nns1.quant & NNSTATS_KEYFRAME);
                 frame->intra=1;  
         else if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                 frame->intra=2;  
         else  
                 frame->intra=0;  
801    
802          if (frame->intra==1)          if (frame->intra)
803          {          {
804                  overflow = 0;                  overflow = 0;
805          }          }
# Line 1101  Line 851 
851                          {                          {
852                                  if (codec->config.credits_quant_i != codec->config.credits_quant_p)                                  if (codec->config.credits_quant_i != codec->config.credits_quant_p)
853                                  {                                  {
854                                          frame->quant = frame->intra == 1 ?                                          frame->quant = frame->intra ?
855                                                  codec->config.credits_quant_i :                                                  codec->config.credits_quant_i :
856                                                  codec->config.credits_quant_p;                                                  codec->config.credits_quant_p;
857                                  }                                  }
# Line 1126  Line 876 
876    
877                  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;
878    
879                  if (frame->intra==1)                  if (frame->intra)
880                  {                  {
881                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /                          dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) /
882                                  twopass->movie_curve;                                  twopass->movie_curve;
# Line 1136  Line 886 
886                          dbytes = bytes2 / twopass->movie_curve;                          dbytes = bytes2 / twopass->movie_curve;
887                  }                  }
888    
                 if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                         dbytes *= twopass->average_pframe / twopass->average_bframe;  
   
889                  // spread the compression error across payback_delay frames                  // spread the compression error across payback_delay frames
890                  if (codec->config.bitrate_payback_method == 0)                  if (codec->config.bitrate_payback_method == 0)
891                  {                  {
# Line 1147  Line 894 
894                  else                  else
895                  {                  {
896                          bytes2 = (int)(curve_comp_error * dbytes /                          bytes2 = (int)(curve_comp_error * dbytes /
897                                  twopass->average_pframe / codec->config.bitrate_payback_delay);                                  twopass->average_frame / codec->config.bitrate_payback_delay);
898    
899                          if (labs(bytes2) > fabs(curve_comp_error))                          if (labs(bytes2) > fabs(curve_comp_error))
900                          {                          {
# Line 1159  Line 906 
906    
907                  if (codec->config.use_alt_curve)                  if (codec->config.use_alt_curve)
908                  {                  {
909                          if (!(frame->intra==1))                          if (!frame->intra)
910                          {                          {
911                                  if (dbytes > twopass->average_pframe)                                  if (dbytes > twopass->average_frame)
912                                  {                                  {
913                                          if (dbytes >= twopass->alt_curve_high)                                          if (dbytes >= twopass->alt_curve_high)
914                                                  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 1171  Line 918 
918                                                  {                                                  {
919                                                  case 2:                                                  case 2:
920                                                  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 *
921                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff)));                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
922                                                          break;                                                          break;
923                                                  case 1:                                                  case 1:
924                                                  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 *
925                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_high_diff);                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
926                                                          break;                                                          break;
927                                                  case 0:                                                  case 0:
928                                                  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 *
929                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_high_diff))));                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
930                                                  }                                                  }
931                                          }                                          }
932                                  }                                  }
# Line 1193  Line 940 
940                                                  {                                                  {
941                                                  case 2:                                                  case 2:
942                                                  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 *
943                                                          sin(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff)));                                                          sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
944                                                          break;                                                          break;
945                                                  case 1:                                                  case 1:
946                                                  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 *
947                                                          (dbytes - twopass->average_pframe) / twopass->alt_curve_low_diff);                                                          (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
948                                                          break;                                                          break;
949                                                  case 0:                                                  case 0:
950                                                  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 *
951                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_pframe) * 90.0 / twopass->alt_curve_low_diff))));                                                          (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
952                                                  }                                                  }
953                                          }                                          }
954                                  }                                  }
                                 if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                         curve_temp *= twopass->average_bframe / twopass->average_pframe;  
   
955                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;                                  curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
956    
957                                  bytes2 += ((int)curve_temp);                                  bytes2 += ((int)curve_temp);
# Line 1215  Line 959 
959                          }                          }
960                          else                          else
961                          {                          {
                                 if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                         dbytes *= twopass->average_bframe / twopass->average_pframe;  
   
                                 bytes2 += ((int)dbytes);  
962                                  curve_comp_error += dbytes - ((int)dbytes);                                  curve_comp_error += dbytes - ((int)dbytes);
963                                    bytes2 += ((int)dbytes);
964                          }                          }
965                  }                  }
966                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&                  else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
967                          !(frame->intra==1))                          !frame->intra)
968                  {                  {
969                          if (dbytes > twopass->average_pframe)                          if (dbytes > twopass->average_frame)
970                          {                          {
971                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
972                                          ((double)dbytes + (twopass->average_pframe - dbytes) *                                          ((double)dbytes + (twopass->average_frame - dbytes) *
973                                          codec->config.curve_compression_high / 100.0);                                          codec->config.curve_compression_high / 100.0);
974                          }                          }
975                          else                          else
976                          {                          {
977                                  curve_temp = twopass->curve_comp_scale *                                  curve_temp = twopass->curve_comp_scale *
978                                          ((double)dbytes + (twopass->average_pframe - dbytes) *                                          ((double)dbytes + (twopass->average_frame - dbytes) *
979                                          codec->config.curve_compression_low / 100.0);                                          codec->config.curve_compression_low / 100.0);
980                          }                          }
981    
                         if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                 curve_temp *= twopass->average_bframe / twopass->average_pframe;  
   
982                          bytes2 += ((int)curve_temp);                          bytes2 += ((int)curve_temp);
983                          curve_comp_error += curve_temp - ((int)curve_temp);                          curve_comp_error += curve_temp - ((int)curve_temp);
984                  }                  }
985                  else                  else
986                  {                  {
                         if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                                 dbytes *= twopass->average_bframe / twopass->average_pframe;  
   
                         bytes2 += ((int)dbytes);  
987                          curve_comp_error += dbytes - ((int)dbytes);                          curve_comp_error += dbytes - ((int)dbytes);
988                            bytes2 += ((int)dbytes);
989                  }                  }
990    
991                  // cap bytes2 to first pass size, lowers number of quant=1 frames                  // cap bytes2 to first pass size, lowers number of quant=1 frames
# Line 1261  Line 996 
996                  }                  }
997                  else                  else
998                  {                  {
999                          if (frame->intra==1)                          if (frame->intra)
1000                          {                          {
1001                                  if (bytes2 < twopass->minisize)                                  if (bytes2 < twopass->minisize)
1002                                  {                                  {
# Line 1269  Line 1004 
1004                                          bytes2 = twopass->minisize;                                          bytes2 = twopass->minisize;
1005                                  }                                  }
1006                          }                          }
1007                          else if (twopass->nns1.dd_v & NNSTATS_BFRAME)                          else if (bytes2 < twopass->minpsize)
                         {  
                                 if (bytes2 < twopass->minbsize)  
                                         bytes2 = twopass->minbsize;  
                         }  
                         else  
                         {  
                                 if (bytes2 < twopass->minpsize)  
1008                                          bytes2 = twopass->minpsize;                                          bytes2 = twopass->minpsize;
1009                          }                          }
1010                  }                  }
         }  
1011    
1012          twopass->desired_bytes2 = bytes2;          twopass->desired_bytes2 = bytes2;
1013    
1014          // if this keyframe is too close to the next,          // if this keyframe is too close to the next,
1015          // reduce it's byte allotment          // reduce it's byte allotment
1016          if ((frame->intra==1) && !credits_pos)          if (frame->intra && !credits_pos)
1017          {          {
1018                  KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -                  KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1019                          codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];                          codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];
# Line 1312  Line 1039 
1039    
1040          // 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
1041          // too much/little bitrate          // too much/little bitrate
1042          overflow = (int)((double)overflow * bytes2 / twopass->average_pframe);          overflow = (int)((double)overflow * bytes2 / twopass->average_frame);
1043    
1044          // Foxer: reign in overflow with huge frames          // Foxer: reign in overflow with huge frames
1045          if (labs(overflow) > labs(twopass->overflow))          if (labs(overflow) > labs(twopass->overflow))
# Line 1347  Line 1074 
1074                  if (bytes2 < twopass->minisize)                  if (bytes2 < twopass->minisize)
1075                          bytes2 = twopass->minisize;                          bytes2 = twopass->minisize;
1076          }          }
1077          else if (twopass->nns1.dd_v & NNSTATS_BFRAME)          else if (bytes2 < twopass->minpsize)
         {  
                 if (bytes2 < twopass->minbsize)  
                         bytes2 = twopass->minbsize;  
         }  
         else  
         {  
                 if (bytes2 < twopass->minpsize)  
1078                          bytes2 = twopass->minpsize;                          bytes2 = twopass->minpsize;
         }  
1079    
1080          twopass->bytes1 = bytes1;          twopass->bytes1 = bytes1;
1081          twopass->bytes2 = bytes2;          twopass->bytes2 = bytes2;
# Line 1372  Line 1091 
1091          {          {
1092                  frame->quant = 31;                  frame->quant = 31;
1093          }          }
1094          else if (!(frame->intra==1))          else if (!frame->intra)
1095          {          {
1096                  // Foxer: aid desired quantizer precision by accumulating decision error                  // Foxer: aid desired quantizer precision by accumulating decision error
1097                  if (twopass->nns1.dd_v & NNSTATS_BFRAME)                  quant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *
                 {  
                         bquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *  
                                 bytes1) / bytes2) - frame->quant;  
   
                         if (bquant_error[frame->quant] >= 1.0)  
                         {  
                                 bquant_error[frame->quant] -= 1.0;  
                                 ++frame->quant;  
                         }  
                 }  
                 else  
                 {  
                         pquant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) *  
1098                                  bytes1) / bytes2) - frame->quant;                                  bytes1) / bytes2) - frame->quant;
1099    
1100                          if (pquant_error[frame->quant] >= 1.0)                  if (quant_error[frame->quant] >= 1.0)
1101                          {                          {
1102                                  pquant_error[frame->quant] -= 1.0;                          quant_error[frame->quant] -= 1.0;
1103                                  ++frame->quant;                                  ++frame->quant;
1104                          }                          }
1105                  }                  }
         }  
1106    
1107          // we're done with credits          // we're done with credits
1108          if (codec_is_in_credits(&codec->config, codec->framenum))          if (codec_is_in_credits(&codec->config, codec->framenum))
# Line 1405  Line 1110 
1110                  return ICERR_OK;                  return ICERR_OK;
1111          }          }
1112    
1113          if ((frame->intra==1))          if (frame->intra)
1114          {          {
1115                  if (frame->quant < codec->config.min_iquant)                  if (frame->quant < codec->config.min_iquant)
1116                  {                  {
# Line 1430  Line 1135 
1135                  }                  }
1136    
1137                  // subsequent frame quants can only be +- 2                  // subsequent frame quants can only be +- 2
1138                  if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)                  if (last_quant && capped_to_max_framesize == 0)
1139                  {                  {
1140                          if (twopass->nns1.dd_v & NNSTATS_BFRAME)                          if (frame->quant > last_quant + 2)
1141                          {                          {
1142                                  // this bframe quantizer variation                                  frame->quant = last_quant + 2;
                                 // restriction needs to be redone.  
                                 if (frame->quant > last_bquant + 2)  
                                 {  
                                         frame->quant = last_bquant + 2;  
                                         DEBUG2P("B-frame quantizer prevented from rising too steeply");  
                                 }  
                                 if (frame->quant < last_bquant - 2)  
                                 {  
                                         frame->quant = last_bquant - 2;  
                                         DEBUG2P("B-frame quantizer prevented from falling too steeply");  
                                 }  
                         }  
                         else  
                         {  
                                 if (frame->quant > last_pquant + 2)  
                                 {  
                                         frame->quant = last_pquant + 2;  
1143                                          DEBUG2P("P-frame quantizer prevented from rising too steeply");                                          DEBUG2P("P-frame quantizer prevented from rising too steeply");
1144                                  }                                  }
1145                                  if (frame->quant < last_pquant - 2)                          if (frame->quant < last_quant - 2)
1146                                  {                                  {
1147                                          frame->quant = last_pquant - 2;                                  frame->quant = last_quant - 2;
1148                                          DEBUG2P("P-frame quantizer prevented from falling too steeply");                                          DEBUG2P("P-frame quantizer prevented from falling too steeply");
1149                                  }                                  }
1150                          }                          }
1151                  }                  }
         }  
1152    
1153          if (capped_to_max_framesize == 0)          if (capped_to_max_framesize == 0)
1154          {                  last_quant = frame->quant;
                 if (twopass->nns1.quant & NNSTATS_KEYFRAME)  
                 {  
                         last_bquant = frame->quant;  
                         last_pquant = frame->quant;  
                 }  
                 else if (twopass->nns1.dd_v & NNSTATS_BFRAME)  
                         last_bquant = frame->quant;  
                 else  
                         last_pquant = frame->quant;  
         }  
1155    
1156          if (codec->config.quant_type == QUANT_MODE_MOD)          if (codec->config.quant_type == QUANT_MODE_MOD)
1157          {          {
# Line 1482  Line 1159 
1159                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;                  frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1160          }          }
1161    
         if (codec->config.quant_type == QUANT_MODE_MOD_NEW)  
         {  
                 frame->general |= (frame->quant < 4) ? XVID_H263QUANT : XVID_MPEGQUANT;  
                 frame->general &= (frame->quant < 4) ? ~XVID_MPEGQUANT : ~XVID_H263QUANT;  
         }  
   
1162          return ICERR_OK;          return ICERR_OK;
1163  }  }
1164    
# Line 1500  Line 1171 
1171          DWORD wrote;          DWORD wrote;
1172          int credits_pos, tempdiv;          int credits_pos, tempdiv;
1173          char* quant_type;          char* quant_type;
         char* frame_type;  
1174    
1175          if (codec->framenum == 0)          if (codec->framenum == 0)
1176          {          {
# Line 1524  Line 1194 
1194    
1195  //              nns1.quant = stats->quant;  //              nns1.quant = stats->quant;
1196                  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
1197                  nns1.lum_noise[0] = nns1.lum_noise[1] = 1;                  if (frame->intra)
1198                  frame_type="inter";                  {
                 if (frame->intra==1) {  
1199                          nns1.quant |= NNSTATS_KEYFRAME;                          nns1.quant |= NNSTATS_KEYFRAME;
                         frame_type="intra";  
                 }  
                 else if (frame->intra==2) {  
                         nns1.dd_v |= NNSTATS_BFRAME;  
                         frame_type="bframe";  
                 }  
                 else if (frame->intra==3) {  
                         nns1.dd_v |= NNSTATS_SKIPFRAME;  
                         frame_type="skiped";  
                 }  
                 else if (frame->intra==4) {  
                         nns1.dd_v |= NNSTATS_PADFRAME;  
                         frame_type="padded";  
                 }  
                 else if (frame->intra==5) {  
                         nns1.dd_v |= NNSTATS_DELAYFRAME;  
                         frame_type="delayed";  
1200                  }                  }
1201                  nns1.kblk = stats->kblks;                  nns1.kblk = stats->kblks;
1202                  nns1.mblk = stats->mblks;                  nns1.mblk = stats->mblks;
1203                  nns1.ublk = stats->ublks;                  nns1.ublk = stats->ublks;
1204                    nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1205    
1206                  total_size += frame->length;                  total_size += frame->length;
1207    
1208                  DEBUG1ST(frame->length, (int)total_size/1024, frame_type, frame->quant, quant_type, stats->kblks, stats->mblks)                  DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, quant_type, stats->kblks, stats->mblks)
   
1209    
1210                  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))
1211                  {                  {
# Line 1565  Line 1217 
1217          case DLG_MODE_2PASS_2_INT :          case DLG_MODE_2PASS_2_INT :
1218          case DLG_MODE_2PASS_2_EXT :          case DLG_MODE_2PASS_2_EXT :
1219                  credits_pos = codec_is_in_credits(&codec->config, codec->framenum);                  credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
                 if (!(codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&  
                         !(codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) &&  
                         !(codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME))  
                 {  
1220                          if (!credits_pos)                          if (!credits_pos)
1221                          {                          {
1222                                  codec->twopass.quant_count[frame->quant]++;                                  codec->twopass.quant_count[frame->quant]++;
# Line 1616  Line 1264 
1264                                  codec->twopass.KFoverflow_partial = 0;                                  codec->twopass.KFoverflow_partial = 0;
1265                                  // end of ugly fix.                                  // end of ugly fix.
1266                          }                          }
                 }  
1267    
1268                  frame_type="inter";                  DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
                 if (frame->intra==1) {  
                         frame_type="intra";  
                 }  
                 else if (codec->twopass.nns1.dd_v & NNSTATS_BFRAME) {  
                         frame_type="bframe";  
                 }  
                 else if (codec->twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {  
                         frame_type="skipped";  
                         frame->quant = 2;  
                         codec->twopass.bytes1 = 1;  
                         codec->twopass.desired_bytes2 = 1;  
                         frame->length = 1;  
                 }  
                 else if (codec->twopass.nns1.dd_v & NNSTATS_PADFRAME) {  
                         frame_type="padded";  
                         frame->quant = 2;  
                         codec->twopass.bytes1 = 7;  
                         codec->twopass.desired_bytes2 = 7;  
                         frame->length = 7;  
                 }  
                 else if (codec->twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {  
                         frame_type="delayed";  
                         frame->quant = 2;  
                         codec->twopass.bytes1 = 1;  
                         codec->twopass.desired_bytes2 = 1;  
                         frame->length = 1;  
                 }  
   
                 DEBUG2ND(frame->quant, quant_type, frame_type, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)  
1269                  break;                  break;
1270    
1271          default:          default:
# Line 1661  Line 1279 
1279  {  {
1280          int i;          int i;
1281          char s[100];          char s[100];
   
         if (codec->twopass.nns1_array)  
         {  
                 free(codec->twopass.nns1_array);  
                 codec->twopass.nns1_array = NULL;  
         }  
         if (codec->twopass.nns2_array)  
         {  
                 free(codec->twopass.nns2_array);  
                 codec->twopass.nns2_array = NULL;  
         }  
         codec->twopass.nns_array_size = 0;  
         codec->twopass.nns_array_length = 0;  
         codec->twopass.nns_array_pos = 0;  
   
1282          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)
1283          {          {
1284                  // output the quantizer distribution for this encode.                  // output the quantizer distribution for this encode.

Legend:
Removed from v.1.7.2.7  
changed lines
  Added in v.1.11

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