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

Diff of /trunk/vfw/src/codec.c

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

revision 5, Fri Mar 8 19:23:56 2002 UTC revision 61, Sat Mar 23 06:58:56 2002 UTC
# Line 23  Line 23 
23   *   *
24   *      History:   *      History:
25   *   *
26   *      ... ???   *      23.03.2002      daniel smith <danielsmith@astroboymail.com>
27     *                              changed inter4v to only be in modes 5 or 6
28     *                              fixed null mode crash ?
29     *                              merged foxer's alternative 2-pass code
30     *                              added DEBUGERR output on errors instead of returning
31     *      16.03.2002      daniel smith <danielsmith@astroboymail.com>
32     *                              changed BITMAPV4HEADER to BITMAPINFOHEADER
33     *                                      - prevents memcpy crash in compress_get_format()
34     *                              credits are processed in external 2pass mode
35     *                              motion search precision = 0 now effective in 2-pass
36     *                              modulated quantization
37     *                              added DX50 fourcc
38   *      01.12.2001      inital version; (c)2001 peter ross <suxen_drol@hotmail.com>   *      01.12.2001      inital version; (c)2001 peter ross <suxen_drol@hotmail.com>
39   *   *
40   *************************************************************************/   *************************************************************************/
# Line 46  Line 57 
57          or XVID_CSP_NULL if failure          or XVID_CSP_NULL if failure
58  */  */
59    
60  int get_colorspace(BITMAPV4HEADER * hdr)  int get_colorspace(BITMAPINFOHEADER * hdr)
61  {  {
62          if (hdr->bV4Height < 0)          if (hdr->biHeight < 0)
63          {          {
64                  DEBUG("colorspace: inverted input format not supported");                  DEBUGERR("colorspace: inverted input format not supported");
65                  return XVID_CSP_NULL;                  return XVID_CSP_NULL;
66          }          }
67    
68          switch(hdr->bV4V4Compression)          switch(hdr->biCompression)
69          {          {
70          case BI_RGB :          case BI_RGB :
71                  if (hdr->bV4BitCount == 16)                  if (hdr->biBitCount == 16)
72                  {                  {
73                          DEBUG("RGB16 (RGB555)");                          DEBUG("RGB16 (RGB555)");
74                          return XVID_CSP_VFLIP | XVID_CSP_RGB555;                          return XVID_CSP_VFLIP | XVID_CSP_RGB555;
75                  }                  }
76                  if (hdr->bV4BitCount == 24)                  if (hdr->biBitCount == 24)
77                  {                  {
78                          DEBUG("RGB24");                          DEBUG("RGB24");
79                          return XVID_CSP_VFLIP | XVID_CSP_RGB24;                          return XVID_CSP_VFLIP | XVID_CSP_RGB24;
80                  }                  }
81                  if (hdr->bV4BitCount == 32)                  if (hdr->biBitCount == 32)
82                  {                  {
83                          DEBUG("RGB32");                          DEBUG("RGB32");
84                          return XVID_CSP_VFLIP | XVID_CSP_RGB32;                          return XVID_CSP_VFLIP | XVID_CSP_RGB32;
85                  }                  }
86    
87                  DEBUG1("BI_RGB unsupported", hdr->bV4BitCount);                  DEBUG1("BI_RGB unsupported", hdr->biBitCount);
88                  return XVID_CSP_NULL;                  return XVID_CSP_NULL;
89    
90          case BI_BITFIELDS :  // how do these work in BITMAPINFOHEADER ???
91                  if(hdr->bV4BitCount == 16 &&  /*      case BI_BITFIELDS :
92                    if (hdr->biBitCount == 16
93                    if(hdr->biBitCount == 16 &&
94                          hdr->bV4RedMask == 0x7c00 &&                          hdr->bV4RedMask == 0x7c00 &&
95                          hdr->bV4GreenMask == 0x3e0 &&                          hdr->bV4GreenMask == 0x3e0 &&
96                          hdr->bV4BlueMask == 0x1f)                          hdr->bV4BlueMask == 0x1f)
# Line 96  Line 109 
109    
110                  DEBUG1("BI_FIELDS unsupported", hdr->bV4BitCount);                  DEBUG1("BI_FIELDS unsupported", hdr->bV4BitCount);
111                  return XVID_CSP_NULL;                  return XVID_CSP_NULL;
112    */
113          case FOURCC_I420:          case FOURCC_I420:
114          case FOURCC_IYUV:          case FOURCC_IYUV:
115                  DEBUG("IYUY");                  DEBUG("IYUY");
# Line 121  Line 134 
134                  return XVID_CSP_UYVY;                  return XVID_CSP_UYVY;
135    
136          }          }
137          DEBUGFOURCC("colorspace: unknown", hdr->bV4V4Compression);          DEBUGFOURCC("colorspace: unknown", hdr->biCompression);
138          return XVID_CSP_NULL;          return XVID_CSP_NULL;
139  }  }
140    
# Line 133  Line 146 
146    
147  LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)  LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
148  {  {
149          BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader;          BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
150          BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader;          BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
151    
152          if (get_colorspace(inhdr) == XVID_CSP_NULL)          if (get_colorspace(inhdr) == XVID_CSP_NULL)
153          {          {
# Line 146  Line 159 
159                  return ICERR_OK;                  return ICERR_OK;
160          }          }
161    
162          if (inhdr->bV4Width != outhdr->bV4Width || inhdr->bV4Height != outhdr->bV4Height ||          if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight ||
163                  (outhdr->bV4V4Compression != FOURCC_XVID && outhdr->bV4V4Compression != FOURCC_DIVX))                  (outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX))
164          {          {
165                  return ICERR_BADFORMAT;                  return ICERR_BADFORMAT;
166          }          }
# Line 158  Line 171 
171    
172  LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)  LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
173  {  {
174          BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader;          BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
175          BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader;          BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
176    
177          if (get_colorspace(inhdr) == XVID_CSP_NULL)          if (get_colorspace(inhdr) == XVID_CSP_NULL)
178          {          {
# Line 171  Line 184 
184                  return sizeof(BITMAPV4HEADER);                  return sizeof(BITMAPV4HEADER);
185          }          }
186    
187          memcpy(outhdr, inhdr, sizeof(BITMAPV4HEADER));          memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
188          outhdr->bV4Size = sizeof(BITMAPV4HEADER);          outhdr->biSize = sizeof(BITMAPINFOHEADER);
189          outhdr->bV4BitCount = 24;  // or 16          outhdr->biBitCount = 24;  // or 16
190          outhdr->bV4SizeImage = compress_get_size(codec, lpbiInput, lpbiOutput);          outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput);
191          outhdr->bV4XPelsPerMeter = 0;          outhdr->biXPelsPerMeter = 0;
192          outhdr->bV4YPelsPerMeter = 0;          outhdr->biYPelsPerMeter = 0;
193          outhdr->bV4ClrUsed = 0;          outhdr->biClrUsed = 0;
194          outhdr->bV4ClrImportant = 0;          outhdr->biClrImportant = 0;
195    
196          if (codec->config.fourcc_used == 0)          if (codec->config.fourcc_used == 0)
197          {          {
198                  outhdr->bV4V4Compression = FOURCC_XVID;                  outhdr->biCompression = FOURCC_XVID;
199            }
200            else if (codec->config.fourcc_used == 1)
201            {
202                    outhdr->biCompression = FOURCC_DIVX;
203          }          }
204          else          else
205          {          {
206                  outhdr->bV4V4Compression = FOURCC_DIVX;                  outhdr->biCompression = FOURCC_DX50;
207          }          }
208    
209          return ICERR_OK;          return ICERR_OK;
# Line 195  Line 212 
212    
213  LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)  LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
214  {  {
215          BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader;          return lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3;
         return outhdr->bV4Width * outhdr->bV4Height * 3;  
216  }  }
217    
218    
# Line 211  Line 227 
227    
228  LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)  LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
229  {  {
         BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader;  
230          XVID_ENC_PARAM param;          XVID_ENC_PARAM param;
231          XVID_INIT_PARAM init_param;          XVID_INIT_PARAM init_param;
232    
# Line 238  Line 253 
253                  param.bitrate = 0;                  param.bitrate = 0;
254                  break;                  break;
255    
256            case DLG_MODE_NULL :
257                    return ICERR_OK;
258    
259          default :          default :
260                  break;                  break;
261          }          }
# Line 253  Line 271 
271          if((codec->config.cpu & XVID_CPU_FORCE) <= 0)          if((codec->config.cpu & XVID_CPU_FORCE) <= 0)
272                  codec->config.cpu = init_param.cpu_flags;                  codec->config.cpu = init_param.cpu_flags;
273    
274          param.width = inhdr->bV4Width;          param.width = lpbiInput->bmiHeader.biWidth;
275          param.height = inhdr->bV4Height;          param.height = lpbiInput->bmiHeader.biHeight;
276          param.fincr = codec->fincr;          param.fincr = codec->fincr;
277          param.fbase = codec->fbase;          param.fbase = codec->fbase;
278    
279          param.rc_buffersize = codec->config.rc_buffersize;          param.rc_buffersize = codec->config.rc_buffersize;
280    
281          param.min_quantizer = codec->config.min_quant;          param.min_quantizer = codec->config.min_pquant;
282          param.max_quantizer = codec->config.max_quant;          param.max_quantizer = codec->config.max_pquant;
283          param.max_key_interval = codec->config.max_key_interval;          param.max_key_interval = codec->config.max_key_interval;
284    
285          switch(xvid_encore(0, XVID_ENC_CREATE, &param, NULL))          switch(xvid_encore(0, XVID_ENC_CREATE, &param, NULL))
# Line 308  Line 326 
326    
327  LRESULT compress(CODEC * codec, ICCOMPRESS * icc)  LRESULT compress(CODEC * codec, ICCOMPRESS * icc)
328  {  {
329          BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)icc->lpbiInput;          BITMAPINFOHEADER * inhdr = icc->lpbiInput;
330          BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)icc->lpbiOutput;          BITMAPINFOHEADER * outhdr = icc->lpbiOutput;
331          XVID_ENC_FRAME frame;          XVID_ENC_FRAME frame;
332          XVID_ENC_STATS stats;          XVID_ENC_STATS stats;
333    
# Line 324  Line 342 
342    
343          frame.general = 0;          frame.general = 0;
344          frame.motion = 0;          frame.motion = 0;
345            frame.intra = -1;
         if(codec->config.motion_search == 0)  
                 frame.intra = 1;  
346    
347          frame.general |= XVID_HALFPEL;          frame.general |= XVID_HALFPEL;
348    
349          if(codec->config.motion_search > 3)          if(codec->config.motion_search > 4)
350                  frame.general |= XVID_INTER4V;                  frame.general |= XVID_INTER4V;
351    
         // we actually need "default/custom" selectbox for both inter/intra  
         // this will do for now  
   
         if (codec->config.quant_type == QUANT_MODE_CUSTOM)  
         {  
                 frame.general |= XVID_CUSTOM_QMATRIX;  
                 frame.quant_intra_matrix = codec->config.qmatrix_intra;  
                 frame.quant_inter_matrix = codec->config.qmatrix_inter;  
         }  
         else  
         {  
                 frame.quant_intra_matrix = NULL;  
                 frame.quant_inter_matrix = NULL;  
         }  
   
         if(codec->config.quant_type == 0)  
                 frame.general |= XVID_H263QUANT;  
         else  
                 frame.general |= XVID_MPEGQUANT;  
   
352          if(((codec->config.mode == DLG_MODE_2PASS_1) ? 0 : codec->config.lum_masking) == 1)          if(((codec->config.mode == DLG_MODE_2PASS_1) ? 0 : codec->config.lum_masking) == 1)
353                  frame.general |= XVID_LUMIMASKING;                  frame.general |= XVID_LUMIMASKING;
354    
# Line 360  Line 356 
356    
357          frame.image = icc->lpInput;          frame.image = icc->lpInput;
358    
359          if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL) {          if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL)
360                  return ICERR_BADFORMAT;                  return ICERR_BADFORMAT;
         }  
361    
362          frame.bitstream = icc->lpOutput;          frame.bitstream = icc->lpOutput;
363          frame.length = icc->lpbiOutput->biSizeImage;          frame.length = icc->lpbiOutput->biSizeImage;
         frame.intra = -1;  
364    
365          switch (codec->config.mode)          switch (codec->config.mode)
366          {          {
# Line 391  Line 385 
385                  }                  }
386                  if (codec->config.dummy2pass)                  if (codec->config.dummy2pass)
387                  {                  {
388                          outhdr->bV4SizeImage = codec->twopass.bytes2;                          outhdr->biSizeImage = codec->twopass.bytes2;
389                          *icc->lpdwFlags = (codec->twopass.nns1.quant & NNSTATS_KEYFRAME) ? AVIIF_KEYFRAME : 0;                          *icc->lpdwFlags = (codec->twopass.nns1.quant & NNSTATS_KEYFRAME) ? AVIIF_KEYFRAME : 0;
390                          return ICERR_OK;                          return ICERR_OK;
391                  }                  }
392                  break;                  break;
393    
394          case DLG_MODE_NULL :          case DLG_MODE_NULL :
395                  outhdr->bV4SizeImage = 0;                  outhdr->biSizeImage = 0;
396                  *icc->lpdwFlags = AVIIF_KEYFRAME;                  *icc->lpdwFlags = AVIIF_KEYFRAME;
397                  return ICERR_OK;                  return ICERR_OK;
398    
399          default :          default :
400                  DEBUG("Invalid encoding mode");                  DEBUGERR("Invalid encoding mode");
401                  return ICERR_ERROR;                  return ICERR_ERROR;
402          }          }
403    
404          // force keyframe spacing in 2-pass modes          if (codec->config.quant_type == QUANT_MODE_H263)
405          if ((codec->keyspacing < codec->config.min_key_interval && codec->framenum) &&          {
406                  (codec->config.mode == DLG_MODE_2PASS_1 || codec->config.mode == DLG_MODE_2PASS_2_INT ||                  frame.general |= XVID_H263QUANT;
407                  codec->config.mode == DLG_MODE_2PASS_2_EXT))          }
408            else
409            {
410                    frame.general |= XVID_MPEGQUANT;
411    
412                    // we actually need "default/custom" selectbox for both inter/intra
413                    // this will do for now
414                    if (codec->config.quant_type == QUANT_MODE_CUSTOM)
415                    {
416                            frame.general |= XVID_CUSTOM_QMATRIX;
417                            frame.quant_intra_matrix = codec->config.qmatrix_intra;
418                            frame.quant_inter_matrix = codec->config.qmatrix_inter;
419                    }
420                    else
421                    {
422                            frame.quant_intra_matrix = NULL;
423                            frame.quant_inter_matrix = NULL;
424                    }
425            }
426    
427            // force keyframe spacing in 2-pass 1st pass
428            if (codec->config.motion_search == 0)
429            {
430                    frame.intra = 1;
431            }
432            else if ((codec->keyspacing < codec->config.min_key_interval && codec->framenum) &&
433                    (codec->config.mode == DLG_MODE_2PASS_1))
434          {          {
435                  DEBUG("current frame forced to p-frame");                  DEBUG("current frame forced to p-frame");
436                  frame.intra = 0;                  frame.intra = 0;
# Line 438  Line 458 
458                  *icc->lpdwFlags = 0;                  *icc->lpdwFlags = 0;
459          }          }
460    
461          outhdr->bV4SizeImage = frame.length;          outhdr->biSizeImage = frame.length;
462    
463          if (codec->config.mode == DLG_MODE_2PASS_1)          if (codec->config.mode == DLG_MODE_2PASS_1 && codec->config.discard1pass)
         {  
                 if (codec->config.discard1pass)  
464                  {                  {
465                          outhdr->bV4SizeImage = 0;                  outhdr->biSizeImage = 0;
                 }  
466          }          }
467    
468          codec_2pass_update(codec, &frame, &stats);          codec_2pass_update(codec, &frame, &stats);
# Line 462  Line 479 
479    
480  LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput)  LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput)
481  {  {
482          BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader;          BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
483          BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader;          BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
484    
485          if (lpbiInput == NULL)          if (lpbiInput == NULL)
486          {          {
487                  return ICERR_ERROR;                  return ICERR_ERROR;
488          }          }
489    
490          if (inhdr->bV4V4Compression != FOURCC_XVID && inhdr->bV4V4Compression != FOURCC_DIVX)          if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX)
491          {          {
492                  return ICERR_BADFORMAT;                  return ICERR_BADFORMAT;
493          }          }
# Line 480  Line 497 
497                  return ICERR_OK;                  return ICERR_OK;
498          }          }
499    
500          if (inhdr->bV4Width != outhdr->bV4Width ||          if (inhdr->biWidth != outhdr->biWidth ||
501                  inhdr->bV4Height != outhdr->bV4Height ||                  inhdr->biHeight != outhdr->biHeight ||
502                  get_colorspace(outhdr) == XVID_CSP_NULL)                  get_colorspace(outhdr) == XVID_CSP_NULL)
503          {          {
504                  return ICERR_BADFORMAT;                  return ICERR_BADFORMAT;
# Line 493  Line 510 
510    
511  LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)  LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
512  {  {
513          BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader;          BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
514          BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader;          BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
515          LRESULT result;          LRESULT result;
516    
517          if (lpbiOutput == NULL)          if (lpbiOutput == NULL)
518          {          {
519                  return sizeof(BITMAPV4HEADER);                  return sizeof(BITMAPINFOHEADER);
520          }          }
521    
522          result = decompress_query(codec, lpbiInput, lpbiOutput);          result = decompress_query(codec, lpbiInput, lpbiOutput);
# Line 508  Line 525 
525                  return result;                  return result;
526          }          }
527    
528          memcpy(outhdr, inhdr, sizeof(BITMAPV4HEADER));          memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
529          outhdr->bV4Size = sizeof(BITMAPV4HEADER);          outhdr->biSize = sizeof(BITMAPINFOHEADER);
530          outhdr->bV4V4Compression = FOURCC_YUY2;          outhdr->biCompression = FOURCC_YUY2;
531          outhdr->bV4SizeImage = outhdr->bV4Width * outhdr->bV4Height * outhdr->bV4BitCount;          outhdr->biSizeImage = outhdr->biWidth * outhdr->biHeight * outhdr->biBitCount;
532          outhdr->bV4XPelsPerMeter = 0;          outhdr->biXPelsPerMeter = 0;
533          outhdr->bV4YPelsPerMeter = 0;          outhdr->biYPelsPerMeter = 0;
534          outhdr->bV4ClrUsed = 0;          outhdr->biClrUsed = 0;
535          outhdr->bV4ClrImportant = 0;          outhdr->biClrImportant = 0;
536    
537          return ICERR_OK;          return ICERR_OK;
538  }  }
# Line 523  Line 540 
540    
541  LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)  LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
542  {  {
         BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader;  
         BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader;  
543          XVID_DEC_PARAM param;          XVID_DEC_PARAM param;
544          XVID_INIT_PARAM init_param;          XVID_INIT_PARAM init_param;
545    
# Line 535  Line 550 
550                  codec->config.cpu = init_param.cpu_flags;                  codec->config.cpu = init_param.cpu_flags;
551          }          }
552    
553          param.width = inhdr->bV4Width;          param.width = lpbiInput->bmiHeader.biWidth;
554          param.height = inhdr->bV4Height;          param.height = lpbiInput->bmiHeader.biHeight;
555    
556          switch(xvid_decore(0, XVID_DEC_CREATE, &param, NULL))          switch(xvid_decore(0, XVID_DEC_CREATE, &param, NULL))
557          {          {
# Line 569  Line 584 
584    
585  LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd)  LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd)
586  {  {
         BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)icd->lpbiInput;  
         BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)icd->lpbiOutput;  
587          XVID_DEC_FRAME frame;          XVID_DEC_FRAME frame;
588    
589          frame.bitstream = icd->lpInput;          frame.bitstream = icd->lpInput;
# Line 581  Line 594 
594    
595          if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE)))          if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE)))
596          {          {
597                  if ((frame.colorspace = get_colorspace(outhdr)) == XVID_CSP_NULL)                  if ((frame.colorspace = get_colorspace(icd->lpbiOutput)) == XVID_CSP_NULL)
598                  {                  {
599                          return ICERR_BADFORMAT;                          return ICERR_BADFORMAT;
600                  }                  }
# Line 625  Line 638 
638                  twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);                  twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
639                  if (twopass->stats1 == INVALID_HANDLE_VALUE)                  if (twopass->stats1 == INVALID_HANDLE_VALUE)
640                  {                  {
641                          DEBUG("2pass init error - couldn't create stats1");                          DEBUGERR("2pass init error - couldn't create stats1");
642                          return ICERR_ERROR;                          return ICERR_ERROR;
643                  }                  }
644                  if (WriteFile(twopass->stats1, &version, sizeof(DWORD), &wrote, 0) == 0 || wrote != sizeof(DWORD))                  if (WriteFile(twopass->stats1, &version, sizeof(DWORD), &wrote, 0) == 0 || wrote != sizeof(DWORD))
645                  {                  {
646                          CloseHandle(twopass->stats1);                          CloseHandle(twopass->stats1);
647                          twopass->stats1 = INVALID_HANDLE_VALUE;                          twopass->stats1 = INVALID_HANDLE_VALUE;
648                          DEBUG("2pass init error - couldn't write to stats1");                          DEBUGERR("2pass init error - couldn't write to stats1");
649                          return ICERR_ERROR;                          return ICERR_ERROR;
650                  }                  }
651                  break;                  break;
# Line 642  Line 655 
655                  twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);                  twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
656                  if (twopass->stats1 == INVALID_HANDLE_VALUE)                  if (twopass->stats1 == INVALID_HANDLE_VALUE)
657                  {                  {
658                          DEBUG("2pass init error - couldn't open stats1");                          DEBUGERR("2pass init error - couldn't open stats1");
659                          return ICERR_ERROR;                          return ICERR_ERROR;
660                  }                  }
661                  if (ReadFile(twopass->stats1, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))                  if (ReadFile(twopass->stats1, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))
662                  {                  {
663                          CloseHandle(twopass->stats1);                          CloseHandle(twopass->stats1);
664                          twopass->stats1 = INVALID_HANDLE_VALUE;                          twopass->stats1 = INVALID_HANDLE_VALUE;
665                          DEBUG("2pass init error - couldn't read from stats1");                          DEBUGERR("2pass init error - couldn't read from stats1");
666                          return ICERR_ERROR;                          return ICERR_ERROR;
667                  }                  }
668                  if (version != -20)                  if (version != -20)
669                  {                  {
670                          CloseHandle(twopass->stats1);                          CloseHandle(twopass->stats1);
671                          twopass->stats1 = INVALID_HANDLE_VALUE;                          twopass->stats1 = INVALID_HANDLE_VALUE;
672                          DEBUG("2pass init error - wrong .stats version");                          DEBUGERR("2pass init error - wrong .stats version");
673                          return ICERR_ERROR;                          return ICERR_ERROR;
674                  }                  }
675    
# Line 673  Line 686 
686                          {                          {
687                                  CloseHandle(twopass->stats1);                                  CloseHandle(twopass->stats1);
688                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                  twopass->stats1 = INVALID_HANDLE_VALUE;
689                                  DEBUG("2pass init error - couldn't open stats2");                                  DEBUGERR("2pass init error - couldn't open stats2");
690                                  return ICERR_ERROR;                                  return ICERR_ERROR;
691                          }                          }
692                          if (ReadFile(twopass->stats2, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))                          if (ReadFile(twopass->stats2, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD))
# Line 682  Line 695 
695                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                  twopass->stats1 = INVALID_HANDLE_VALUE;
696                                  CloseHandle(twopass->stats2);                                  CloseHandle(twopass->stats2);
697                                  twopass->stats2 = INVALID_HANDLE_VALUE;                                  twopass->stats2 = INVALID_HANDLE_VALUE;
698                                  DEBUG("2pass init error - couldn't read from stats2");                                  DEBUGERR("2pass init error - couldn't read from stats2");
699                                  return ICERR_ERROR;                                  return ICERR_ERROR;
700                          }                          }
701                          if (version != -20)                          if (version != -20)
# Line 691  Line 704 
704                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                  twopass->stats1 = INVALID_HANDLE_VALUE;
705                                  CloseHandle(twopass->stats2);                                  CloseHandle(twopass->stats2);
706                                  twopass->stats2 = INVALID_HANDLE_VALUE;                                  twopass->stats2 = INVALID_HANDLE_VALUE;
707                                  DEBUG("2pass init error - wrong .stats version");                                  DEBUGERR("2pass init error - wrong .stats version");
708                                  return ICERR_ERROR;                                  return ICERR_ERROR;
709                          }                          }
710    
# Line 712  Line 725 
725                                                  CloseHandle(twopass->stats2);                                                  CloseHandle(twopass->stats2);
726                                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                                  twopass->stats1 = INVALID_HANDLE_VALUE;
727                                                  twopass->stats2 = INVALID_HANDLE_VALUE;                                                  twopass->stats2 = INVALID_HANDLE_VALUE;
728                                                  DEBUG("2pass init error - incomplete stats1/stats2 record?");                                                  DEBUGERR("2pass init error - incomplete stats1/stats2 record?");
729                                                  return ICERR_ERROR;                                                  return ICERR_ERROR;
730                                          }                                          }
731                                  }                                  }
# Line 743  Line 756 
756                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
757                          frames = 0;                          frames = 0;
758    
759                            if (codec->config.use_alt_curve)
760                            {
761                                    twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;
762                                    twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;
763                                    twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;
764                                    twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;
765                                    if (codec->config.alt_curve_use_auto)
766                                    {
767                                            if (twopass->movie_curve > 1.0f)
768                                            {
769                                                    codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / twopass->movie_curve) * (double)codec->config.alt_curve_auto_str / 100.0);
770                                                    if (codec->config.alt_curve_min_rel_qual < 20)
771                                                            codec->config.alt_curve_min_rel_qual = 20;
772                                            }
773                                            else
774                                                    codec->config.alt_curve_min_rel_qual = 100;
775                                    }
776                                    twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
777                                    twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
778                                    if (codec->config.alt_curve_low_dist > 100)
779                                    {
780                                            switch(codec->config.alt_curve_type)
781                                            {
782                                            case 2: // Sine Curve (high aggressiveness)
783                                                    twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
784                                                            sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
785                                                    twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
786                                                            sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));
787                                                    break;
788                                            case 1: // Linear (medium aggressiveness)
789                                                    twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
790                                                            twopass->average_frame / twopass->alt_curve_low_diff);
791                                                    twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
792                                                            twopass->average_frame / twopass->alt_curve_low_diff;
793                                                    break;
794                                            case 0: // Cosine Curve (low aggressiveness)
795                                                    twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
796                                                            (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));
797                                                    twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
798                                                            (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
799                                            }
800                                    }
801                            }
802    
803                          while (1)                          while (1)
804                          {                          {
805                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) ||
# Line 760  Line 817 
817                                                  CloseHandle(twopass->stats2);                                                  CloseHandle(twopass->stats2);
818                                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                                  twopass->stats1 = INVALID_HANDLE_VALUE;
819                                                  twopass->stats2 = INVALID_HANDLE_VALUE;                                                  twopass->stats2 = INVALID_HANDLE_VALUE;
820                                                  DEBUG("2pass init error - incomplete stats1/stats2 record?");                                                  DEBUGERR("2pass init error - incomplete stats1/stats2 record?");
821                                                  return ICERR_ERROR;                                                  return ICERR_ERROR;
822                                          }                                          }
823                                  }                                  }
# Line 771  Line 828 
828                                          double dbytes = twopass->nns2.bytes / twopass->movie_curve;                                          double dbytes = twopass->nns2.bytes / twopass->movie_curve;
829                                          total1 += dbytes;                                          total1 += dbytes;
830    
831                                            if (codec->config.use_alt_curve)
832                                            {
833                                                    if (dbytes > twopass->average_frame)
834                                                    {
835                                                            if (dbytes >= twopass->alt_curve_high)
836                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
837                                                            else
838                                                            {
839                                                                    switch(codec->config.alt_curve_type)
840                                                                    {
841                                                                    case 2:
842                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
843                                                                            sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
844                                                                            break;
845                                                                    case 1:
846                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
847                                                                            (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
848                                                                            break;
849                                                                    case 0:
850                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
851                                                                            (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
852                                                                    }
853                                                            }
854                                                    }
855                                                    else
856                                                    {
857                                                            if (dbytes <= twopass->alt_curve_low)
858                                                                    total2 += dbytes;
859                                                            else
860                                                            {
861                                                                    switch(codec->config.alt_curve_type)
862                                                                    {
863                                                                    case 2:
864                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
865                                                                            sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
866                                                                            break;
867                                                                    case 1:
868                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
869                                                                            (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
870                                                                            break;
871                                                                    case 0:
872                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
873                                                                            (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
874                                                                    }
875                                                            }
876                                                    }
877                                            }
878                                            else
879                                            {
880                                          if (dbytes > twopass->average_frame)                                          if (dbytes > twopass->average_frame)
881                                          {                                          {
882                                                  total2 += ((double)dbytes + (twopass->average_frame - dbytes) *                                                  total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
# Line 782  Line 888 
888                                                          codec->config.curve_compression_low / 100.0);                                                          codec->config.curve_compression_low / 100.0);
889                                          }                                          }
890                                  }                                  }
891                                    }
892    
893                                  ++frames;                                  ++frames;
894                          }                          }
895    
896                          twopass->curve_comp_scale = total1 / total2;                          twopass->curve_comp_scale = total1 / total2;
897    
898                            if (!codec->config.use_alt_curve)
899                          {                          {
900                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
901                                  char s[100];                                  char s[100];
# Line 816  Line 924 
924                                          {                                          {
925                                                  CloseHandle(twopass->stats1);                                                  CloseHandle(twopass->stats1);
926                                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                                  twopass->stats1 = INVALID_HANDLE_VALUE;
927                                                  DEBUG("2pass init error - incomplete stats2 record?");                                                  DEBUGERR("2pass init error - incomplete stats2 record?");
928                                                  return ICERR_ERROR;                                                  return ICERR_ERROR;
929                                          }                                          }
930                                  }                                  }
# Line 908  Line 1016 
1016                          // perform prepass to compensate for over/undersizing                          // perform prepass to compensate for over/undersizing
1017                          frames = 0;                          frames = 0;
1018    
1019                            if (codec->config.use_alt_curve)
1020                            {
1021                                    twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0;
1022                                    twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low;
1023                                    twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0;
1024                                    twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame;
1025                                    if (codec->config.alt_curve_use_auto)
1026                                    {
1027                                            if (twopass->movie_curve > 1.0f)
1028                                            {
1029                                                    codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / twopass->movie_curve) * (double)codec->config.alt_curve_auto_str / 100.0);
1030                                                    if (codec->config.alt_curve_min_rel_qual < 20)
1031                                                            codec->config.alt_curve_min_rel_qual = 20;
1032                                            }
1033                                            else
1034                                                    codec->config.alt_curve_min_rel_qual = 100;
1035                                    }
1036                                    twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0;
1037                                    twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual;
1038                                    if (codec->config.alt_curve_low_dist > 100)
1039                                    {
1040                                            switch(codec->config.alt_curve_type)
1041                                            {
1042                                            case 2: // Sine Curve (high aggressiveness)
1043                                                    twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
1044                                                            sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
1045                                                    twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
1046                                                            sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff));
1047                                                    break;
1048                                            case 1: // Linear (medium aggressiveness)
1049                                                    twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
1050                                                            twopass->average_frame / twopass->alt_curve_low_diff);
1051                                                    twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
1052                                                            twopass->average_frame / twopass->alt_curve_low_diff;
1053                                                    break;
1054                                            case 0: // Cosine Curve (low aggressiveness)
1055                                                    twopass->alt_curve_qual_dev *= 2.0 / (1.0 +
1056                                                            (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))));
1057                                                    twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev *
1058                                                            (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)));
1059                                            }
1060                                    }
1061                            }
1062    
1063                          while (1)                          while (1)
1064                          {                          {
1065                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))                                  if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS))
# Line 922  Line 1074 
1074                                          {                                          {
1075                                                  CloseHandle(twopass->stats1);                                                  CloseHandle(twopass->stats1);
1076                                                  twopass->stats1 = INVALID_HANDLE_VALUE;                                                  twopass->stats1 = INVALID_HANDLE_VALUE;
1077                                                  DEBUG("2pass init error - incomplete stats2 record?");                                                  DEBUGERR("2pass init error - incomplete stats2 record?");
1078                                                  return ICERR_ERROR;                                                  return ICERR_ERROR;
1079                                          }                                          }
1080                                  }                                  }
# Line 933  Line 1085 
1085                                          double dbytes = twopass->nns1.bytes / twopass->movie_curve;                                          double dbytes = twopass->nns1.bytes / twopass->movie_curve;
1086                                          total1 += dbytes;                                          total1 += dbytes;
1087    
1088                                            if (codec->config.use_alt_curve)
1089                                            {
1090                                                    if (dbytes > twopass->average_frame)
1091                                                    {
1092                                                            if (dbytes >= twopass->alt_curve_high)
1093                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
1094                                                            else
1095                                                            {
1096                                                                    switch(codec->config.alt_curve_type)
1097                                                                    {
1098                                                                    case 2:
1099                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1100                                                                            sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
1101                                                                            break;
1102                                                                    case 1:
1103                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1104                                                                            (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
1105                                                                            break;
1106                                                                    case 0:
1107                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1108                                                                            (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
1109                                                                    }
1110                                                            }
1111                                                    }
1112                                                    else
1113                                                    {
1114                                                            if (dbytes <= twopass->alt_curve_low)
1115                                                                    total2 += dbytes;
1116                                                            else
1117                                                            {
1118                                                                    switch(codec->config.alt_curve_type)
1119                                                                    {
1120                                                                    case 2:
1121                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1122                                                                            sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
1123                                                                            break;
1124                                                                    case 1:
1125                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1126                                                                            (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
1127                                                                            break;
1128                                                                    case 0:
1129                                                                    total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
1130                                                                            (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
1131                                                                    }
1132                                                            }
1133                                                    }
1134                                            }
1135                                            else
1136                                            {
1137                                          if (dbytes > twopass->average_frame)                                          if (dbytes > twopass->average_frame)
1138                                          {                                          {
1139                                                  total2 += ((double)dbytes + (twopass->average_frame - dbytes) *                                                  total2 += ((double)dbytes + (twopass->average_frame - dbytes) *
# Line 944  Line 1145 
1145                                                          codec->config.curve_compression_low / 100.0);                                                          codec->config.curve_compression_low / 100.0);
1146                                          }                                          }
1147                                  }                                  }
1148                                    }
1149    
1150                                  ++frames;                                  ++frames;
1151                          }                          }
1152    
1153                          twopass->curve_comp_scale = total1 / total2;                          twopass->curve_comp_scale = total1 / total2;
1154    
1155                            if (!codec->config.use_alt_curve)
1156                          {                          {
1157                                  int asymmetric_average_frame;                                  int asymmetric_average_frame;
1158                                  char s[100];                                  char s[100];
# Line 962  Line 1165 
1165                          SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);                          SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN);
1166                  }                  }
1167    
1168                    if (codec->config.use_alt_curve)
1169                    {
1170                            if (codec->config.alt_curve_use_auto_bonus_bias)
1171                                    codec->config.alt_curve_bonus_bias = codec->config.alt_curve_min_rel_qual;
1172    
1173                            twopass->curve_bias_bonus = (total1 - total2) * (double)codec->config.alt_curve_bonus_bias / 100.0 / (double)(frames - credits_frames - i_frames);
1174                            twopass->curve_comp_scale = ((total1 - total2) * (1.0 - (double)codec->config.alt_curve_bonus_bias / 100.0) + total2) / total2;
1175                    }
1176    
1177                  twopass->overflow = 0;                  twopass->overflow = 0;
1178    
1179                  break;                  break;
# Line 989  Line 1201 
1201                                  break;                                  break;
1202    
1203                          default :                          default :
1204                                  DEBUG("Can't use credits size mode in quality mode");                                  DEBUGERR("Can't use credits size mode in quality mode");
1205                                  return ICERR_ERROR;                                  return ICERR_ERROR;
1206                          }                          }
1207                  }                  }
# Line 1006  Line 1218 
1218                          {                          {
1219                          case CREDITS_MODE_RATE :                          case CREDITS_MODE_RATE :
1220                                  frame->quant =                                  frame->quant =
1221                                          codec->config.max_quant -                                          codec->config.max_pquant -
1222                                          ((codec->config.max_quant - codec->config.quant) * codec->config.credits_rate / 100);                                          ((codec->config.max_pquant - codec->config.quant) * codec->config.credits_rate / 100);
1223                                  break;                                  break;
1224    
1225                          case CREDITS_MODE_QUANT :                          case CREDITS_MODE_QUANT :
# Line 1015  Line 1227 
1227                                  break;                                  break;
1228    
1229                          default :                          default :
1230                                  DEBUG("Can't use credits size mode in quantizer mode");                                  DEBUGERR("Can't use credits size mode in quantizer mode");
1231                                  return ICERR_ERROR;                                  return ICERR_ERROR;
1232                          }                          }
1233                  }                  }
# Line 1044  Line 1256 
1256                  return ICERR_OK;                  return ICERR_OK;
1257    
1258          default:          default:
1259                  DEBUG("get quant: invalid mode");                  DEBUGERR("get quant: invalid mode");
1260                  return ICERR_ERROR;                  return ICERR_ERROR;
1261          }          }
1262  }  }
# Line 1078  Line 1290 
1290    
1291          if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))          if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))
1292          {          {
1293                  DEBUG("2ndpass quant: couldn't read from stats1");                  DEBUGERR("2ndpass quant: couldn't read from stats1");
1294                  return ICERR_ERROR;                  return ICERR_ERROR;
1295          }          }
1296          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)          if (codec->config.mode == DLG_MODE_2PASS_2_EXT)
1297          {          {
1298                  if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))                  if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS))
1299                  {                  {
1300                          DEBUG("2ndpass quant: couldn't read from stats2");                          DEBUGERR("2ndpass quant: couldn't read from stats2");
1301                          return ICERR_ERROR;                          return ICERR_ERROR;
1302                  }                  }
1303          }          }
# Line 1181  Line 1393 
1393    
1394                  curve_comp_error -= bytes2;                  curve_comp_error -= bytes2;
1395    
1396                  if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&                  if (codec->config.use_alt_curve)
1397                    {
1398                            if (!frame->intra)
1399                            {
1400                                    if (dbytes > twopass->average_frame)
1401                                    {
1402                                            if (dbytes >= twopass->alt_curve_high)
1403                                                    curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev);
1404                                            else
1405                                            {
1406                                                    switch(codec->config.alt_curve_type)
1407                                                    {
1408                                                    case 2:
1409                                                    curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1410                                                            sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)));
1411                                                            break;
1412                                                    case 1:
1413                                                    curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1414                                                            (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff);
1415                                                            break;
1416                                                    case 0:
1417                                                    curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1418                                                            (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))));
1419                                                    }
1420                                            }
1421                                    }
1422                                    else
1423                                    {
1424                                            if (dbytes <= twopass->alt_curve_low)
1425                                                    curve_temp = dbytes;
1426                                            else
1427                                            {
1428                                                    switch(codec->config.alt_curve_type)
1429                                                    {
1430                                                    case 2:
1431                                                    curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1432                                                            sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)));
1433                                                            break;
1434                                                    case 1:
1435                                                    curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev *
1436                                                            (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff);
1437                                                            break;
1438                                                    case 0:
1439                                                    curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev *
1440                                                            (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))));
1441                                                    }
1442                                            }
1443                                    }
1444                                    curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus;
1445    
1446                                    bytes2 += ((int)curve_temp);
1447                                    curve_comp_error += curve_temp - ((int)curve_temp);
1448                            }
1449                            else
1450                            {
1451                                    curve_comp_error += dbytes - ((int)dbytes);
1452                                    bytes2 += ((int)dbytes);
1453                            }
1454                    }
1455                    else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) &&
1456                          !frame->intra)                          !frame->intra)
1457                  {                  {
1458                          if (dbytes > twopass->average_frame)                          if (dbytes > twopass->average_frame)
# Line 1298  Line 1569 
1569          }          }
1570          else          else
1571          {          {
1572                  if (frame->quant > codec->config.max_quant)                  if (frame->quant > codec->config.max_pquant)
1573                  {                  {
1574                          frame->quant = codec->config.max_quant;                          frame->quant = codec->config.max_pquant;
1575                  }                  }
1576                  if (frame->quant < codec->config.min_quant)                  if (frame->quant < codec->config.min_pquant)
1577                  {                  {
1578                          frame->quant = codec->config.min_quant;                          frame->quant = codec->config.min_pquant;
1579                  }                  }
1580    
1581                  // subsequent frame quants can only be +- 2                  // subsequent frame quants can only be +- 2
# Line 1325  Line 1596 
1596    
1597          last_quant = frame->quant;          last_quant = frame->quant;
1598    
1599            if (codec->config.quant_type == QUANT_MODE_MOD)
1600            {
1601                    frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT;
1602                    frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT;
1603            }
1604    
1605          return ICERR_OK;          return ICERR_OK;
1606  }  }
1607    
# Line 1335  Line 1612 
1612    
1613          NNSTATS nns1;          NNSTATS nns1;
1614          DWORD wrote;          DWORD wrote;
1615            char* quant_type;
1616    
1617          if (codec->framenum == 0)          if (codec->framenum == 0)
1618          {          {
1619                  total_size = 0;                  total_size = 0;
1620          }          }
1621    
1622            quant_type = (frame->general & XVID_H263QUANT) ? "H.263" :
1623                    ((frame->general & XVID_MPEGQUANT) && (frame->general & XVID_CUSTOM_QMATRIX)) ?
1624                    "Cust" : "MPEG";
1625    
1626          switch (codec->config.mode)          switch (codec->config.mode)
1627          {          {
1628          case DLG_MODE_2PASS_1 :          case DLG_MODE_2PASS_1 :
# Line 1363  Line 1645 
1645                  nns1.lum_noise[0] = nns1.lum_noise[1] = 1;                  nns1.lum_noise[0] = nns1.lum_noise[1] = 1;
1646    
1647                  total_size += frame->length;                  total_size += frame->length;
1648                  DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, stats->kblks, stats->mblks)  
1649                    DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, quant_type, stats->kblks, stats->mblks)
1650    
1651                  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))
1652                  {                  {
1653                          DEBUG("stats1: WriteFile error");                          DEBUGERR("stats1: WriteFile error");
1654                          return ICERR_ERROR;                          return ICERR_ERROR;
1655                  }                  }
1656                  break;                  break;
# Line 1375  Line 1658 
1658          case DLG_MODE_2PASS_2_INT :          case DLG_MODE_2PASS_2_INT :
1659          case DLG_MODE_2PASS_2_EXT :          case DLG_MODE_2PASS_2_EXT :
1660                  codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;                  codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;
1661                  DEBUG2ND(frame->quant, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, codec_is_in_credits(&codec->config, codec->framenum))                  DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, codec_is_in_credits(&codec->config, codec->framenum))
1662                  break;                  break;
1663    
1664          default:          default:
# Line 1388  Line 1671 
1671    
1672  int codec_is_in_credits(CONFIG* config, int framenum)  int codec_is_in_credits(CONFIG* config, int framenum)
1673  {  {
         if (config->mode == DLG_MODE_2PASS_2_EXT)  
         {  
                 return 0;  
         }  
   
1674          if (config->credits_start)          if (config->credits_start)
1675          {          {
1676                  if (framenum >= config->credits_start_begin &&                  if (framenum >= config->credits_start_begin &&
# Line 1433  Line 1711 
1711          if (!config->fquant)          if (!config->fquant)
1712          {          {
1713                  config->fquant =                  config->fquant =
1714                          ((float) (config->max_quant - config->min_quant) / 100) *                          ((float) (config->max_pquant - config->min_pquant) / 100) *
1715                          (100 - quality) +                          (100 - quality) +
1716                          (float) config->min_quant;                          (float) config->min_pquant;
1717    
1718                  fquant_running = config->fquant;                  fquant_running = config->fquant;
1719          }          }
1720    
1721          if (fquant_running < config->min_quant)          if (fquant_running < config->min_pquant)
1722          {          {
1723                  fquant_running = (float) config->min_quant;                  fquant_running = (float) config->min_pquant;
1724          }          }
1725          else if(fquant_running > config->max_quant)          else if(fquant_running > config->max_pquant)
1726          {          {
1727                  fquant_running = (float) config->max_quant;                  fquant_running = (float) config->max_pquant;
1728          }          }
1729    
1730          quant = (int) fquant_running;          quant = (int) fquant_running;

Legend:
Removed from v.5  
changed lines
  Added in v.61

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