[cvs] / xvidcore / src / plugins / plugin_2pass1.c Repository:
ViewVC logotype

Diff of /xvidcore/src/plugins/plugin_2pass1.c

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

revision 1.1.2.6, Tue Jul 29 23:02:34 2003 UTC revision 1.1.2.14, Sat Dec 20 22:22:26 2003 UTC
# Line 27  Line 27 
27   *****************************************************************************/   *****************************************************************************/
28    
29  #include <stdio.h>  #include <stdio.h>
30    #include <errno.h> /* errno var (or function with recent libc) */
31    #include <string.h> /* strerror() */
32    
33  #include "../xvid.h"  #include "../xvid.h"
34  #include "../image/image.h"  #include "../image/image.h"
35    
36    
37    /* This preprocessor constant controls wheteher or not, first pass is done
38     * using fast ME routines to speed up the 2pass process at the expense of
39     * less precise first pass stats */
40    #define FAST1PASS
41    
42    
43  /* context struct */  /* context struct */
44  typedef struct  typedef struct
45  {  {
# Line 60  Line 68 
68      rc->stat_file = NULL;      rc->stat_file = NULL;
69    
70          /* Open the 1st pass file */          /* Open the 1st pass file */
71          if((rc->stat_file = fopen(param->filename, "w+")) == NULL)          if((rc->stat_file = fopen(param->filename, "w+b")) == NULL)
72                  return(XVID_ERR_FAIL);                  return(XVID_ERR_FAIL);
73    
74            /* I swear xvidcore isn't buggy, but when using mencoder+xvid4 i observe
75             * this weird bug.
76             *
77             * Symptoms: The stats file grows until it's fclosed, but at this moment
78             *           a large part of the file is filled by 0x00 bytes w/o any
79             *           reasonable cause. The stats file is then completly unusable
80             *
81             * So far, i think i found "the why":
82             *  - take a MPEG stream containing 2 sequences (concatenate 2 MPEG files
83             *    together)
84             *  - Encode this MPEG file
85             *
86             * It should trigger the bug
87             *
88             * I think this is caused by some kind of race condition on mencoder module
89             * start/stop.
90             *  - mencoder encodes the first sequence
91             *    + xvid4 module opens xvid-twopass.stats and writes stats in it.
92             *  - mencoder detects the second sequence and initialize a second
93             *    module and stops the old encoder
94             *    + new xvid4 module opens a new xvid-twopass.stats, old xvid4
95             *      module closes it
96             *
97             * This is IT, got a racing condition.
98             * Unbuffered IO, may help ... */
99            setbuf(rc->stat_file, NULL);
100    
101          /*          /*
102           * The File Header           * The File Header
103           */           */
104  #if 0          fprintf(rc->stat_file, "# XviD 2pass stat file (core version %d.%d.%d)\n",
105          fprintf(rc->stat_file, "# XviD 2pass stat file\n");                          XVID_VERSION_MAJOR(XVID_VERSION),
106      fprintf(rc->stat_file, "version %i.%i.%i\n",XVID_MAJOR(XVID_VERSION), XVID_MINOR(XVID_VERSION), XVID_PATCH(XVID_VERSION));                          XVID_VERSION_MINOR(XVID_VERSION),
107          fprintf(rc->stat_file, "start\n");                          XVID_VERSION_PATCH(XVID_VERSION));
108      fprintf(rc->stat_file, "type quantizer length kblocks mblocks ublocks\n");          fprintf(rc->stat_file, "# Please do not modify this file\n\n");
 #endif  
109    
110      rc->fq_error = 0;      rc->fq_error = 0;
111    
# Line 82  Line 116 
116    
117  static int rc_2pass1_destroy(rc_2pass1_t * rc, xvid_plg_destroy_t * destroy)  static int rc_2pass1_destroy(rc_2pass1_t * rc, xvid_plg_destroy_t * destroy)
118  {  {
119          fclose(rc->stat_file);          if (rc->stat_file) {
120                    if (fclose(rc->stat_file) == EOF) {
121          free(rc);                          DPRINTF(XVID_DEBUG_RC, "Error closing stats file (%s)", strerror(errno));
122                    }
123            }
124            rc->stat_file = NULL; /* Just a paranoid reset */
125            free(rc); /* as the container structure is freed anyway */
126          return(0);          return(0);
127  }  }
128    
# Line 93  Line 131 
131  {  {
132       if (data->quant <= 0) {       if (data->quant <= 0) {
133          if (data->zone && data->zone->mode == XVID_ZONE_QUANT) {          if (data->zone && data->zone->mode == XVID_ZONE_QUANT) {
134                            /* We disable no options in quant zones, as their implementation is
135                             * based on the fact we do first pass exactly the same way as the
136                             * second one to have exact zone size */
137              rc->fq_error += (double)data->zone->increment / (double)data->zone->base;              rc->fq_error += (double)data->zone->increment / (double)data->zone->base;
138              data->quant = (int)rc->fq_error;              data->quant = (int)rc->fq_error;
139              rc->fq_error -= data->quant;              rc->fq_error -= data->quant;
   
140          }else {          }else {
141              data->quant = 2;              data->quant = 2;
142    
143    #ifdef FAST1PASS
144                            /* Given the fact our 2pass algorithm is based on very simple
145                             * rules, we can disable some options that are too CPU intensive
146                             * and do not provide the 2nd pass any benefit */
147    
148                            /* First disable some motion flags */
149                            data->motion_flags &= ~XVID_ME_CHROMA_PVOP;
150                            data->motion_flags &= ~XVID_ME_CHROMA_BVOP;
151                            data->motion_flags &= ~XVID_ME_USESQUARES16;
152                            data->motion_flags &= ~XVID_ME_ADVANCEDDIAMOND16;
153                            data->motion_flags &= ~XVID_ME_EXTSEARCH16;
154    
155                            /* And enable fast replacements */
156                            data->motion_flags |= XVID_ME_FAST_MODEINTERPOLATE;
157                            data->motion_flags |= XVID_ME_SKIP_DELTASEARCH;
158                            data->motion_flags |= XVID_ME_FASTREFINE16;
159                            data->motion_flags |= XVID_ME_BFRAME_EARLYSTOP;
160    
161                            /* Now VOP flags (no fast replacements) */
162                            data->vop_flags &= ~XVID_VOP_MODEDECISION_RD;
163                            data->vop_flags &= ~XVID_VOP_FAST_MODEDECISION_RD;
164                            data->vop_flags &= ~XVID_VOP_TRELLISQUANT;
165                            data->vop_flags &= ~XVID_VOP_INTER4V;
166                            data->vop_flags &= ~XVID_VOP_HQACPRED;
167    
168                            /* Finnaly VOL flags
169                             *
170                             * NB: Qpel cannot be disable because this option really changes
171                             *     too much the texture data compressibility, and thus the
172                             *     second pass gets confused by too much impredictability
173                             *     of frame sizes, and actually hurts quality */
174                            data->vol_flags &= ~XVID_VOL_GMC;
175    #endif
176          }          }
177      }      }
178      return 0;           return(0);
179  }  }
180    
181    
182  static int rc_2pass1_after(rc_2pass1_t * rc, xvid_plg_data_t * data)  static int rc_2pass1_after(rc_2pass1_t * rc, xvid_plg_data_t * data)
183  {  {
184          char type;          char type;
185            xvid_enc_stats_t *stats = &data->stats;
186    
187          /* Frame type in ascii I/P/B */          /* Frame type in ascii I/P/B */
188          switch(data->type) {          switch(stats->type) {
189          case XVID_TYPE_IVOP:          case XVID_TYPE_IVOP:
190                  type = 'i';                  type = 'i';
191                  break;                  break;
# Line 129  Line 204 
204    
205          /* write the resulting statistics */          /* write the resulting statistics */
206    
207          fprintf(rc->stat_file, "%c %d %d %d %d %d\n",          fprintf(rc->stat_file, "%c %d %d %d %d %d %d\n",
208          type,          type,
209                  data->quant,                          stats->quant,
210                  data->kblks,                          stats->kblks,
211          data->mblks,                          stats->mblks,
212          data->ublks,                          stats->ublks,
213          data->length);                          stats->length,
214                            stats->hlength);
215    
216          return(0);          return(0);
217  }  }
# Line 147  Line 223 
223      switch(opt)      switch(opt)
224      {      {
225      case XVID_PLG_INFO :      case XVID_PLG_INFO :
226            case XVID_PLG_FRAME :
227          return 0;          return 0;
228    
229      case XVID_PLG_CREATE :      case XVID_PLG_CREATE :

Legend:
Removed from v.1.1.2.6  
changed lines
  Added in v.1.1.2.14

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