[svn] / trunk / xvidcore / src / encoder.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/encoder.c

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

revision 4, Fri Mar 8 19:17:46 2002 UTC revision 403, Wed Sep 4 21:41:57 2002 UTC
# Line 1  Line 1 
1    /*****************************************************************************
2     *
3     *  XVID MPEG-4 VIDEO CODEC
4     *  -  Encoder main module  -
5     *
6     *  Copyright(C) 2002 Michael Militzer
7     *
8     *  This program is an implementation of a part of one or more MPEG-4
9     *  Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
10     *  to use this software module in hardware or software products are
11     *  advised that its use may infringe existing patents or copyrights, and
12     *  any such use would be at such party's own risk.  The original
13     *  developer of this software module and his/her company, and subsequent
14     *  editors and their companies, will have no liability for use of this
15     *  software or modifications or derivatives thereof.
16     *
17     *  This program is free software; you can redistribute it and/or modify
18     *  it under the terms of the GNU General Public License as published by
19     *  the Free Software Foundation; either version 2 of the License, or
20     *  (at your option) any later version.
21     *
22     *  This program is distributed in the hope that it will be useful,
23     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
24     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25     *  GNU General Public License for more details.
26     *
27     *  You should have received a copy of the GNU General Public License
28     *  along with this program; if not, write to the Free Software
29     *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
30     *
31     ****************************************************************************/
32    
33  #include <stdlib.h>  #include <stdlib.h>
34  #include <stdio.h>  #include <stdio.h>
35  #include <math.h>  #include <math.h>
36    #include <string.h>
37    
38  #include "encoder.h"  #include "encoder.h"
39  #include "prediction/mbprediction.h"  #include "prediction/mbprediction.h"
40  #include "global.h"  #include "global.h"
41  #include "utils/timer.h"  #include "utils/timer.h"
42  #include "image/image.h"  #include "image/image.h"
43    #include "motion/motion.h"
44  #include "bitstream/cbp.h"  #include "bitstream/cbp.h"
45  #include "utils/mbfunctions.h"  #include "utils/mbfunctions.h"
46  #include "bitstream/bitstream.h"  #include "bitstream/bitstream.h"
# Line 16  Line 50 
50  #include "bitstream/mbcoding.h"  #include "bitstream/mbcoding.h"
51  #include "quant/adapt_quant.h"  #include "quant/adapt_quant.h"
52  #include "quant/quant_matrix.h"  #include "quant/quant_matrix.h"
53    #include "utils/mem_align.h"
54    
55  #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT  #ifdef _SMP
56    #include "motion/smp_motion_est.h"
57    #endif
58    /*****************************************************************************
59     * Local macros
60     ****************************************************************************/
61    
62    #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT
63    #define SWAP(A,B)    { void * tmp = A; A = B; B = tmp; }
64    
65  static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits);  /*****************************************************************************
66  static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header);   * Local function prototypes
67     ****************************************************************************/
68    
69    static int FrameCodeI(Encoder * pEnc,
70                                              Bitstream * bs,
71                                              uint32_t * pBits);
72    
73    static int FrameCodeP(Encoder * pEnc,
74                                              Bitstream * bs,
75                                              uint32_t * pBits,
76                                              bool force_inter,
77                                              bool vol_header);
78    
79    /*****************************************************************************
80     * Local data
81     ****************************************************************************/
82    
83  static int DQtab[4] =  static int DQtab[4] = {
 {  
84          -1, -2, 1, 2          -1, -2, 1, 2
85  };  };
86    
87  static int iDQtab[5] =  static int iDQtab[5] = {
 {  
88          1, 0, NO_CHANGE, 2, 3          1, 0, NO_CHANGE, 2, 3
89  };  };
90    
91    
92  int encoder_create(XVID_ENC_PARAM * pParam)  static void __inline
93    image_null(IMAGE * image)
94    {
95            image->y = image->u = image->v = NULL;
96    }
97    
98    
99    /*****************************************************************************
100     * Encoder creation
101     *
102     * This function creates an Encoder instance, it allocates all necessary
103     * image buffers (reference, current and bframes) and initialize the internal
104     * xvid encoder paremeters according to the XVID_ENC_PARAM input parameter.
105     *
106     * The code seems to be very long but is very basic, mainly memory allocation
107     * and cleaning code.
108     *
109     * Returned values :
110     *    - XVID_ERR_OK     - no errors
111     *    - XVID_ERR_MEMORY - the libc could not allocate memory, the function
112     *                        cleans the structure before exiting.
113     *                        pParam->handle is also set to NULL.
114     *
115     ****************************************************************************/
116    
117    int
118    encoder_create(XVID_ENC_PARAM * pParam)
119  {  {
120      Encoder *pEnc;      Encoder *pEnc;
121          uint32_t i;          int i;
122    
123      pParam->handle = NULL;      pParam->handle = NULL;
124    
# Line 48  Line 129 
129      ENC_CHECK(!(pParam->width % 2));      ENC_CHECK(!(pParam->width % 2));
130      ENC_CHECK(!(pParam->height % 2));      ENC_CHECK(!(pParam->height % 2));
131    
132          if (pParam->fincr <= 0 || pParam->fbase <= 0)          /* Fps */
133          {  
134            if (pParam->fincr <= 0 || pParam->fbase <= 0) {
135                  pParam->fincr = 1;                  pParam->fincr = 1;
136                  pParam->fbase = 25;                  pParam->fbase = 25;
137          }          }
138    
139          // simplify the "fincr/fbase" fraction          /*
140          // (neccessary, since windows supplies us with huge numbers)           * Simplify the "fincr/fbase" fraction
141             * (neccessary, since windows supplies us with huge numbers)
142             */
143    
144          i = pParam->fincr;          i = pParam->fincr;
145          while (i > 1)          while (i > 1) {
146          {                  if (pParam->fincr % i == 0 && pParam->fbase % i == 0) {
                 if (pParam->fincr % i == 0 && pParam->fbase % i == 0)  
                 {  
147                          pParam->fincr /= i;                          pParam->fincr /= i;
148                          pParam->fbase /= i;                          pParam->fbase /= i;
149                          i = pParam->fincr;                          i = pParam->fincr;
# Line 70  Line 152 
152                  i--;                  i--;
153          }          }
154    
155          if (pParam->fbase > 65535)          if (pParam->fbase > 65535) {
         {  
156                  float div = (float)pParam->fbase / 65535;                  float div = (float)pParam->fbase / 65535;
157    
158                  pParam->fbase = (int)(pParam->fbase / div);                  pParam->fbase = (int)(pParam->fbase / div);
159                  pParam->fincr = (int)(pParam->fincr / div);                  pParam->fincr = (int)(pParam->fincr / div);
160          }          }
161    
162          if (pParam->bitrate <= 0)          /* Bitrate allocator defaults */
163                  pParam->bitrate = 900000;  
164            if (pParam->rc_bitrate <= 0)
165                    pParam->rc_bitrate = 900000;
166    
167            if (pParam->rc_reaction_delay_factor <= 0)
168                    pParam->rc_reaction_delay_factor = 16;
169    
170            if (pParam->rc_averaging_period <= 0)
171                    pParam->rc_averaging_period = 100;
172    
173      if (pParam->rc_buffersize <= 0)          if (pParam->rc_buffer <= 0)
174                  pParam->rc_buffersize = pParam->bitrate * pParam->fbase;                  pParam->rc_buffer = 100;
175    
176            /* Max and min quantizers */
177    
178      if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))      if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))
179                  pParam->min_quantizer = 1;                  pParam->min_quantizer = 1;
# Line 89  Line 181 
181      if ((pParam->max_quantizer <= 0) || (pParam->max_quantizer > 31))      if ((pParam->max_quantizer <= 0) || (pParam->max_quantizer > 31))
182                  pParam->max_quantizer = 31;                  pParam->max_quantizer = 31;
183    
     if (pParam->max_key_interval == 0)          /* 1 keyframe each 10 seconds */  
                 pParam->max_key_interval = 10 * pParam->fincr / pParam->fbase;  
   
184      if (pParam->max_quantizer < pParam->min_quantizer)      if (pParam->max_quantizer < pParam->min_quantizer)
185                  pParam->max_quantizer = pParam->min_quantizer;                  pParam->max_quantizer = pParam->min_quantizer;
186    
187      if ((pEnc = (Encoder *) malloc(sizeof(Encoder))) == NULL)          /* 1 keyframe each 10 seconds */
188    
189            if (pParam->max_key_interval <= 0)
190                    pParam->max_key_interval = 10 * pParam->fincr / pParam->fbase;
191    
192            pEnc = (Encoder *) xvid_malloc(sizeof(Encoder), CACHE_LINE);
193            if (pEnc == NULL)
194                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
195    
196            /* Zero the Encoder Structure */
197    
198            memset(pEnc, 0, sizeof(Encoder));
199    
200          /* Fill members of Encoder structure */          /* Fill members of Encoder structure */
201    
202      pEnc->mbParam.width = pParam->width;      pEnc->mbParam.width = pParam->width;
# Line 109  Line 208 
208          pEnc->mbParam.edged_width = 16 * pEnc->mbParam.mb_width + 2 * EDGE_SIZE;          pEnc->mbParam.edged_width = 16 * pEnc->mbParam.mb_width + 2 * EDGE_SIZE;
209          pEnc->mbParam.edged_height = 16 * pEnc->mbParam.mb_height + 2 * EDGE_SIZE;          pEnc->mbParam.edged_height = 16 * pEnc->mbParam.mb_height + 2 * EDGE_SIZE;
210    
211            pEnc->mbParam.fbase = pParam->fbase;
212            pEnc->mbParam.fincr = pParam->fincr;
213    
214            pEnc->mbParam.m_quant_type = H263_QUANT;
215    
216    #ifdef _SMP
217            pEnc->mbParam.num_threads = MIN(pParam->num_threads, MAXNUMTHREADS);
218    #endif
219    
220      pEnc->sStat.fMvPrevSigma = -1;      pEnc->sStat.fMvPrevSigma = -1;
221    
222          /* Fill rate control parameters */          /* Fill rate control parameters */
223    
224      pEnc->mbParam.quant = 4;          pEnc->bitrate = pParam->rc_bitrate;
   
         pEnc->bitrate = pParam->bitrate;  
225    
226      pEnc->iFrameNum = 0;      pEnc->iFrameNum = 0;
227      pEnc->iMaxKeyInterval = pParam->max_key_interval;      pEnc->iMaxKeyInterval = pParam->max_key_interval;
228    
229      if (image_create(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          /* try to allocate frame memory */
     {  
                 free(pEnc);  
                 return XVID_ERR_MEMORY;  
     }  
230    
231          if (image_create(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          pEnc->current = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE);
232      {          pEnc->reference = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE);
                 image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 free(pEnc);  
                 return XVID_ERR_MEMORY;  
     }  
233    
234      if (image_create(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          if (pEnc->current == NULL || pEnc->reference == NULL)
235      {                  goto xvid_err_memory1;
                 image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 free(pEnc);  
                 return XVID_ERR_MEMORY;  
     }  
236    
237      if (image_create(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          /* try to allocate mb memory */
238      {  
239                  image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          pEnc->current->mbs =
240                  image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width *
241                  image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                                          pEnc->mbParam.mb_height, CACHE_LINE);
242                  free(pEnc);          pEnc->reference->mbs =
243                  return XVID_ERR_MEMORY;                  xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width *
244      }                                          pEnc->mbParam.mb_height, CACHE_LINE);
245    
246            if (pEnc->current->mbs == NULL || pEnc->reference->mbs == NULL)
247                    goto xvid_err_memory2;
248    
249            /* try to allocate image memory */
250    
251    #ifdef _DEBUG_PSNR
252            image_null(&pEnc->sOriginal);
253    #endif
254            image_null(&pEnc->current->image);
255            image_null(&pEnc->reference->image);
256            image_null(&pEnc->vInterH);
257            image_null(&pEnc->vInterV);
258            image_null(&pEnc->vInterVf);
259            image_null(&pEnc->vInterHV);
260            image_null(&pEnc->vInterHVf);
261    
262    #ifdef _DEBUG_PSNR
263            if (image_create
264                    (&pEnc->sOriginal, pEnc->mbParam.edged_width,
265                     pEnc->mbParam.edged_height) < 0)
266                    goto xvid_err_memory3;
267    #endif
268            if (image_create
269                    (&pEnc->current->image, pEnc->mbParam.edged_width,
270                     pEnc->mbParam.edged_height) < 0)
271                    goto xvid_err_memory3;
272            if (image_create
273                    (&pEnc->reference->image, pEnc->mbParam.edged_width,
274                     pEnc->mbParam.edged_height) < 0)
275                    goto xvid_err_memory3;
276            if (image_create
277                    (&pEnc->vInterH, pEnc->mbParam.edged_width,
278                     pEnc->mbParam.edged_height) < 0)
279                    goto xvid_err_memory3;
280            if (image_create
281                    (&pEnc->vInterV, pEnc->mbParam.edged_width,
282                     pEnc->mbParam.edged_height) < 0)
283                    goto xvid_err_memory3;
284            if (image_create
285                    (&pEnc->vInterVf, pEnc->mbParam.edged_width,
286                     pEnc->mbParam.edged_height) < 0)
287                    goto xvid_err_memory3;
288            if (image_create
289                    (&pEnc->vInterHV, pEnc->mbParam.edged_width,
290                     pEnc->mbParam.edged_height) < 0)
291                    goto xvid_err_memory3;
292            if (image_create
293                    (&pEnc->vInterHVf, pEnc->mbParam.edged_width,
294                     pEnc->mbParam.edged_height) < 0)
295                    goto xvid_err_memory3;
296    
297      if (image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          pParam->handle = (void *) pEnc;
     {  
                 image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 free(pEnc);  
                 return XVID_ERR_MEMORY;  
     }  
298    
299          pEnc->pMBs = malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height);          if (pParam->rc_bitrate) {
300          if (pEnc->pMBs == NULL)                  RateControlInit(&pEnc->rate_control, pParam->rc_bitrate,
301          {                                                  pParam->rc_reaction_delay_factor,
302                  image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                                                  pParam->rc_averaging_period, pParam->rc_buffer,
303                  image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                                                  pParam->fbase * 1000 / pParam->fincr,
304                  image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                                                  pParam->max_quantizer, pParam->min_quantizer);
                 image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 free(pEnc);  
                 return XVID_ERR_MEMORY;  
305          }          }
306    
307          // init macroblock array          init_timer();
         for (i = 0; i < pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; i++)  
         {  
                 pEnc->pMBs[i].dquant = NO_CHANGE;  
         }  
308    
309      pParam->handle = (void *)pEnc;          return XVID_ERR_OK;
310    
311          if (pParam->bitrate)          /*
312          {           * We handle all XVID_ERR_MEMORY here, this makes the code lighter
313                  RateControlInit(pParam->bitrate, pParam->rc_buffersize, pParam->fbase, pParam->width,           */
314                                                  pParam->height, pParam->max_quantizer, pParam->min_quantizer);  
315          }    xvid_err_memory3:
316    #ifdef _DEBUG_PSNR
317            image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width,
318                                      pEnc->mbParam.edged_height);
319    #endif
320    
321            image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width,
322                                      pEnc->mbParam.edged_height);
323            image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width,
324                                      pEnc->mbParam.edged_height);
325            image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width,
326                                      pEnc->mbParam.edged_height);
327            image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width,
328                                      pEnc->mbParam.edged_height);
329            image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width,
330                                      pEnc->mbParam.edged_height);
331            image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width,
332                                      pEnc->mbParam.edged_height);
333            image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width,
334                                      pEnc->mbParam.edged_height);
335    
336      xvid_err_memory2:
337            xvid_free(pEnc->current->mbs);
338            xvid_free(pEnc->reference->mbs);
339    
340      xvid_err_memory1:
341            xvid_free(pEnc->current);
342            xvid_free(pEnc->reference);
343            xvid_free(pEnc);
344    
345          create_vlc_tables();          pParam->handle = NULL;
346    
347          return XVID_ERR_OK;          return XVID_ERR_MEMORY;
348  }  }
349    
350    /*****************************************************************************
351     * Encoder destruction
352     *
353     * This function destroy the entire encoder structure created by a previous
354     * successful encoder_create call.
355     *
356     * Returned values (for now only one returned value) :
357     *    - XVID_ERR_OK     - no errors
358     *
359     ****************************************************************************/
360    
361  int encoder_destroy(Encoder * pEnc)  int
362    encoder_destroy(Encoder * pEnc)
363  {  {
364    
365      ENC_CHECK(pEnc);      ENC_CHECK(pEnc);
     ENC_CHECK(pEnc->sCurrent.y);  
     ENC_CHECK(pEnc->sReference.y);  
366    
367          free(pEnc->pMBs);          /* All images, reference, current etc ... */
368      image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width,
369      image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                                    pEnc->mbParam.edged_height);
370      image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width,
371      image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                                    pEnc->mbParam.edged_height);
372      image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width,
373      free(pEnc);                                    pEnc->mbParam.edged_height);
374            image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width,
375                                      pEnc->mbParam.edged_height);
376            image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width,
377                                      pEnc->mbParam.edged_height);
378            image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width,
379                                      pEnc->mbParam.edged_height);
380            image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width,
381                                      pEnc->mbParam.edged_height);
382    
383    #ifdef _DEBUG_PSNR
384            image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width,
385                                      pEnc->mbParam.edged_height);
386    #endif
387    
388            /* Encoder structure */
389            xvid_free(pEnc->current->mbs);
390            xvid_free(pEnc->current);
391    
392            xvid_free(pEnc->reference->mbs);
393            xvid_free(pEnc->reference);
394    
395          destroy_vlc_tables();          xvid_free(pEnc);
396    
397      return XVID_ERR_OK;      return XVID_ERR_OK;
398  }  }
399    
400  int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult)  
401    void inc_frame_num(Encoder * pEnc)
402    {
403            pEnc->mbParam.m_ticks += pEnc->mbParam.fincr;
404            pEnc->mbParam.m_seconds = pEnc->mbParam.m_ticks / pEnc->mbParam.fbase;
405            pEnc->mbParam.m_ticks = pEnc->mbParam.m_ticks % pEnc->mbParam.fbase;
406    }
407    
408    /*****************************************************************************
409     * "original" IP frame encoder entry point
410     *
411     * Returned values :
412     *    - XVID_ERR_OK     - no errors
413     *    - XVID_ERR_FORMAT - the image subsystem reported the image had a wrong
414     *                        format
415     ****************************************************************************/
416    
417    int
418    encoder_encode(Encoder * pEnc,
419                               XVID_ENC_FRAME * pFrame,
420                               XVID_ENC_STATS * pResult)
421  {  {
422      uint16_t x, y;      uint16_t x, y;
423      Bitstream bs;      Bitstream bs;
424      uint32_t bits;      uint32_t bits;
         uint16_t quant_type = 0;  
425          uint16_t write_vol_header = 0;          uint16_t write_vol_header = 0;
426    
427      IMAGE *pCurrent = &(pEnc->sCurrent);  #ifdef _DEBUG_PSNR
428            float psnr;
429            uint8_t temp[128];
430    #endif
431    
432          start_global_timer();          start_global_timer();
433    
# Line 228  Line 436 
436      ENC_CHECK(pFrame->bitstream);      ENC_CHECK(pFrame->bitstream);
437      ENC_CHECK(pFrame->image);      ENC_CHECK(pFrame->image);
438    
439          pEnc->mbParam.global_flags = pFrame->general;          SWAP(pEnc->current, pEnc->reference);
440          pEnc->mbParam.motion_flags = pFrame->motion;  
441            pEnc->current->global_flags = pFrame->general;
442            pEnc->current->motion_flags = pFrame->motion;
443            pEnc->current->seconds = pEnc->mbParam.m_seconds;
444            pEnc->current->ticks = pEnc->mbParam.m_ticks;
445            pEnc->mbParam.hint = &pFrame->hint;
446    
447          start_timer();          start_timer();
448          if (image_input(&pEnc->sCurrent, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,          if (image_input
449                                          pFrame->image, pFrame->colorspace))                  (&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height,
450          {                   pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace) < 0)
451                  return XVID_ERR_FORMAT;                  return XVID_ERR_FORMAT;
         }  
452          stop_conv_timer();          stop_conv_timer();
453    
454    #ifdef _DEBUG_PSNR
455            image_copy(&pEnc->sOriginal, &pEnc->current->image,
456                               pEnc->mbParam.edged_width, pEnc->mbParam.height);
457    #endif
458    
459            emms();
460    
461      BitstreamInit(&bs, pFrame->bitstream, 0);      BitstreamInit(&bs, pFrame->bitstream, 0);
462    
463          if (pFrame->quant == 0)          if (pFrame->quant == 0) {
464          {                  pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0);
465                  pEnc->mbParam.quant = RateControlGetQ(0);          } else {
466          }                  pEnc->current->quant = pFrame->quant;
         else  
         {  
                 pEnc->mbParam.quant = pFrame->quant;  
467          }          }
468    
469          if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0)          if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
470          {                  int *temp_dquants =
471                  int * temp_dquants = (int *) malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int));                          (int *) xvid_malloc(pEnc->mbParam.mb_width *
472                                                                    pEnc->mbParam.mb_height * sizeof(int),
473                                                                    CACHE_LINE);
474    
475                  pEnc->mbParam.quant = adaptive_quantization(pEnc->sCurrent.y, pEnc->mbParam.width,                  pEnc->current->quant =
476                          temp_dquants, pFrame->quant, pFrame->quant,                          adaptive_quantization(pEnc->current->image.y,
477                          2*pFrame->quant, pEnc->mbParam.mb_width, pEnc->mbParam.mb_height);                                                                    pEnc->mbParam.edged_width, temp_dquants,
478                                                                      pEnc->current->quant, pEnc->current->quant,
479                                                                      2 * pEnc->current->quant,
480                                                                      pEnc->mbParam.mb_width,
481                                                                      pEnc->mbParam.mb_height);
482    
483                  for (y = 0; y < pEnc->mbParam.mb_height; y++)                  for (y = 0; y < pEnc->mbParam.mb_height; y++) {
484                          for (x = 0; x < pEnc->mbParam.mb_width; x++)  
485                          {  #define OFFSET(x,y) ((x) + (y)*pEnc->mbParam.mb_width)
486                                  MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];  
487                                  pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];                          for (x = 0; x < pEnc->mbParam.mb_width; x++) {
488    
489    
490                                    MACROBLOCK *pMB = &pEnc->current->mbs[OFFSET(x, y)];
491    
492                                    pMB->dquant = iDQtab[temp_dquants[OFFSET(x, y)] + 2];
493                          }                          }
494                  free(temp_dquants);  
495    #undef OFFSET
496          }          }
497    
498          if(pEnc->mbParam.global_flags & XVID_H263QUANT)                  xvid_free(temp_dquants);
499                  quant_type = H263_QUANT;          }
         else if(pEnc->mbParam.global_flags & XVID_MPEGQUANT)  
                 quant_type = MPEG4_QUANT;  
500    
501          if(pEnc->mbParam.quant_type != quant_type) {          if (pEnc->current->global_flags & XVID_H263QUANT) {
502                  pEnc->mbParam.quant_type = quant_type;                  if (pEnc->mbParam.m_quant_type != H263_QUANT)
503                  write_vol_header = 1;                  write_vol_header = 1;
504          }                  pEnc->mbParam.m_quant_type = H263_QUANT;
505          else          } else if (pEnc->current->global_flags & XVID_MPEGQUANT) {
506                  write_vol_header = 0;                  int matrix1_changed, matrix2_changed;
507    
508          if ((pEnc->mbParam.global_flags & XVID_CUSTOM_QMATRIX) > 0)                  matrix1_changed = matrix2_changed = 0;
509          {  
510                  int ret1, ret2;                  if (pEnc->mbParam.m_quant_type != MPEG4_QUANT)
511                  ret1 = set_intra_matrix(pFrame->quant_intra_matrix);                          write_vol_header = 1;
512                  ret2 = set_inter_matrix(pFrame->quant_inter_matrix);  
513                    pEnc->mbParam.m_quant_type = MPEG4_QUANT;
514    
515                    if ((pEnc->current->global_flags & XVID_CUSTOM_QMATRIX) > 0) {
516                            if (pFrame->quant_intra_matrix != NULL)
517                                    matrix1_changed = set_intra_matrix(pFrame->quant_intra_matrix);
518                            if (pFrame->quant_inter_matrix != NULL)
519                                    matrix2_changed = set_inter_matrix(pFrame->quant_inter_matrix);
520                    } else {
521                            matrix1_changed = set_intra_matrix(get_default_intra_matrix());
522                            matrix2_changed = set_inter_matrix(get_default_inter_matrix());
523                    }
524                  if(write_vol_header == 0)                  if(write_vol_header == 0)
525                          write_vol_header = ret1 | ret2;                          write_vol_header = matrix1_changed | matrix2_changed;
526          }          }
527    
528          if (pFrame->intra < 0)          if (pFrame->intra < 0) {
529      {                  if ((pEnc->iFrameNum == 0)
530                  if ((pEnc->iFrameNum == 0) || ((pEnc->iMaxKeyInterval > 0)                          || ((pEnc->iMaxKeyInterval > 0)
531                          && (pEnc->iFrameNum >= pEnc->iMaxKeyInterval)))                                  && (pEnc->iFrameNum >= pEnc->iMaxKeyInterval))) {
   
532                          pFrame->intra = FrameCodeI(pEnc, &bs, &bits);                          pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
533                  else                  } else {
534                          pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header);                          pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header);
535      }      }
536      else          } else {
537      {                  if (pFrame->intra == 1) {
                 if (pFrame->intra == 1)  
538                      pFrame->intra = FrameCodeI(pEnc, &bs, &bits);                      pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
539                  else                  } else {
540                          pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header);                          pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header);
541      }      }
542    
543            }
544    
545          BitstreamPutBits(&bs, 0xFFFF, 16);          BitstreamPutBits(&bs, 0xFFFF, 16);
546      BitstreamPutBits(&bs, 0xFFFF, 16);      BitstreamPutBits(&bs, 0xFFFF, 16);
547      BitstreamPad(&bs);      BitstreamPad(&bs);
548      pFrame->length = BitstreamLength(&bs);      pFrame->length = BitstreamLength(&bs);
549    
550          if (pResult)          if (pResult) {
551      {                  pResult->quant = pEnc->current->quant;
                 pResult->quant = pEnc->mbParam.quant;  
552                  pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);                  pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
553                  pResult->kblks = pEnc->sStat.kblks;                  pResult->kblks = pEnc->sStat.kblks;
554                  pResult->mblks = pEnc->sStat.mblks;                  pResult->mblks = pEnc->sStat.mblks;
555                  pResult->ublks = pEnc->sStat.ublks;                  pResult->ublks = pEnc->sStat.ublks;
556      }      }
557    
558      if (pEnc->bitrate)          emms();
559          {  
560                  RateControlUpdate(pEnc->mbParam.quant, pFrame->length, pFrame->intra);          if (pFrame->quant == 0) {
561          }                  RateControlUpdate(&pEnc->rate_control, pEnc->current->quant,
562                                                      pFrame->length, pFrame->intra);
563            }
564    #ifdef _DEBUG_PSNR
565            psnr =
566                    image_psnr(&pEnc->sOriginal, &pEnc->current->image,
567                                       pEnc->mbParam.edged_width, pEnc->mbParam.width,
568                                       pEnc->mbParam.height);
569    
570            snprintf(temp, 127, "PSNR: %f\n", psnr);
571            DEBUG(temp);
572    #endif
573    
574            inc_frame_num(pEnc);
575          pEnc->iFrameNum++;          pEnc->iFrameNum++;
     image_swap(&pEnc->sCurrent, &pEnc->sReference);  
576    
577          stop_global_timer();          stop_global_timer();
578          write_timer();          write_timer();
# Line 334  Line 581 
581  }  }
582    
583    
584  static __inline void CodeIntraMB(Encoder *pEnc, MACROBLOCK *pMB) {  static __inline void
585    CodeIntraMB(Encoder * pEnc,
586                            MACROBLOCK * pMB)
587    {
588    
589          pMB->mode = MODE_INTRA;          pMB->mode = MODE_INTRA;
590    
591          if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) {          /* zero mv statistics */
592                  if(pMB->dquant != NO_CHANGE)          pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
593                  {          pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
594            pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
595            pMB->sad16 = 0;
596    
597            if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
598                    if (pMB->dquant != NO_CHANGE) {
599                          pMB->mode = MODE_INTRA_Q;                          pMB->mode = MODE_INTRA_Q;
600                          pEnc->mbParam.quant += DQtab[pMB->dquant];                          pEnc->current->quant += DQtab[pMB->dquant];
601    
602                            if (pEnc->current->quant > 31)
603                                    pEnc->current->quant = 31;
604                            if (pEnc->current->quant < 1)
605                                    pEnc->current->quant = 1;
606                    }
607            }
608    
609            pMB->quant = pEnc->current->quant;
610    }
611    
612    
613    #define FCODEBITS       3
614    #define MODEBITS        5
615    
616    void
617    HintedMESet(Encoder * pEnc,
618                            int *intra)
619    {
620            HINTINFO *hint;
621            Bitstream bs;
622            int length, high;
623            uint32_t x, y;
624    
625            hint = pEnc->mbParam.hint;
626    
627            if (hint->rawhints) {
628                    *intra = hint->mvhint.intra;
629            } else {
630                    BitstreamInit(&bs, hint->hintstream, hint->hintlength);
631                    *intra = BitstreamGetBit(&bs);
632            }
633    
634            if (*intra) {
635                    return;
636            }
637    
638            pEnc->current->fcode =
639                    (hint->rawhints) ? hint->mvhint.fcode : BitstreamGetBits(&bs,
640                                                                                                                                     FCODEBITS);
641    
642            length = pEnc->current->fcode + 5;
643            high = 1 << (length - 1);
644    
645            for (y = 0; y < pEnc->mbParam.mb_height; ++y) {
646                    for (x = 0; x < pEnc->mbParam.mb_width; ++x) {
647                            MACROBLOCK *pMB =
648                                    &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
649                            MVBLOCKHINT *bhint =
650                                    &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
651                            VECTOR pred;
652                            VECTOR tmp;
653                            int vec;
654    
655                            pMB->mode =
656                                    (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs,
657                                                                                                                                      MODEBITS);
658    
659                            pMB->mode = (pMB->mode == MODE_INTER_Q) ? MODE_INTER : pMB->mode;
660                            pMB->mode = (pMB->mode == MODE_INTRA_Q) ? MODE_INTRA : pMB->mode;
661    
662                            if (pMB->mode == MODE_INTER) {
663                                    tmp.x =
664                                            (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs,
665                                                                                                                                                      length);
666                                    tmp.y =
667                                            (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs,
668                                                                                                                                                      length);
669                                    tmp.x -= (tmp.x >= high) ? high * 2 : 0;
670                                    tmp.y -= (tmp.y >= high) ? high * 2 : 0;
671    
672                                    pred = get_pmv2(pEnc->current->mbs,pEnc->mbParam.mb_width,0,x,y,0);
673    
674                                    for (vec = 0; vec < 4; ++vec) {
675                                            pMB->mvs[vec].x = tmp.x;
676                                            pMB->mvs[vec].y = tmp.y;
677                                            pMB->pmvs[vec].x = pMB->mvs[0].x - pred.x;
678                                            pMB->pmvs[vec].y = pMB->mvs[0].y - pred.y;
679                                    }
680                            } else if (pMB->mode == MODE_INTER4V) {
681                                    for (vec = 0; vec < 4; ++vec) {
682                                            tmp.x =
683                                                    (hint->rawhints) ? bhint->mvs[vec].
684                                                    x : BitstreamGetBits(&bs, length);
685                                            tmp.y =
686                                                    (hint->rawhints) ? bhint->mvs[vec].
687                                                    y : BitstreamGetBits(&bs, length);
688                                            tmp.x -= (tmp.x >= high) ? high * 2 : 0;
689                                            tmp.y -= (tmp.y >= high) ? high * 2 : 0;
690    
691                                            pred = get_pmv2(pEnc->current->mbs,pEnc->mbParam.mb_width,0,x,y,vec);
692    
693                                            pMB->mvs[vec].x = tmp.x;
694                                            pMB->mvs[vec].y = tmp.y;
695                                            pMB->pmvs[vec].x = pMB->mvs[vec].x - pred.x;
696                                            pMB->pmvs[vec].y = pMB->mvs[vec].y - pred.y;
697                                    }
698                            } else                          // intra / stuffing / not_coded
699                            {
700                                    for (vec = 0; vec < 4; ++vec) {
701                                            pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
702                                    }
703                            }
704    
705                            if (pMB->mode == MODE_INTER4V &&
706                                    (pEnc->current->global_flags & XVID_LUMIMASKING)
707                                    && pMB->dquant != NO_CHANGE) {
708                                    pMB->mode = MODE_INTRA;
709    
710                                    for (vec = 0; vec < 4; ++vec) {
711                                            pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
712                                    }
713                            }
714                    }
715            }
716    }
717    
718    
719    void
720    HintedMEGet(Encoder * pEnc,
721                            int intra)
722    {
723            HINTINFO *hint;
724            Bitstream bs;
725            uint32_t x, y;
726            int length, high;
727    
728            hint = pEnc->mbParam.hint;
729    
730            if (hint->rawhints) {
731                    hint->mvhint.intra = intra;
732            } else {
733                    BitstreamInit(&bs, hint->hintstream, 0);
734                    BitstreamPutBit(&bs, intra);
735            }
736    
737            if (intra) {
738                    if (!hint->rawhints) {
739                            BitstreamPad(&bs);
740                            hint->hintlength = BitstreamLength(&bs);
741                    }
742                    return;
743            }
744    
745            length = pEnc->current->fcode + 5;
746            high = 1 << (length - 1);
747    
748            if (hint->rawhints) {
749                    hint->mvhint.fcode = pEnc->current->fcode;
750            } else {
751                    BitstreamPutBits(&bs, pEnc->current->fcode, FCODEBITS);
752            }
753    
754            for (y = 0; y < pEnc->mbParam.mb_height; ++y) {
755                    for (x = 0; x < pEnc->mbParam.mb_width; ++x) {
756                            MACROBLOCK *pMB =
757                                    &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
758                            MVBLOCKHINT *bhint =
759                                    &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
760                            VECTOR tmp;
761    
762                            if (hint->rawhints) {
763                                    bhint->mode = pMB->mode;
764                            } else {
765                                    BitstreamPutBits(&bs, pMB->mode, MODEBITS);
766                            }
767    
768                            if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {
769                                    tmp.x = pMB->mvs[0].x;
770                                    tmp.y = pMB->mvs[0].y;
771                                    tmp.x += (tmp.x < 0) ? high * 2 : 0;
772                                    tmp.y += (tmp.y < 0) ? high * 2 : 0;
773    
774                                    if (hint->rawhints) {
775                                            bhint->mvs[0].x = tmp.x;
776                                            bhint->mvs[0].y = tmp.y;
777                                    } else {
778                                            BitstreamPutBits(&bs, tmp.x, length);
779                                            BitstreamPutBits(&bs, tmp.y, length);
780                                    }
781                            } else if (pMB->mode == MODE_INTER4V) {
782                                    int vec;
783    
784                          if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31;                                  for (vec = 0; vec < 4; ++vec) {
785                          if (pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1;                                          tmp.x = pMB->mvs[vec].x;
786                                            tmp.y = pMB->mvs[vec].y;
787                                            tmp.x += (tmp.x < 0) ? high * 2 : 0;
788                                            tmp.y += (tmp.y < 0) ? high * 2 : 0;
789    
790                                            if (hint->rawhints) {
791                                                    bhint->mvs[vec].x = tmp.x;
792                                                    bhint->mvs[vec].y = tmp.y;
793                                            } else {
794                                                    BitstreamPutBits(&bs, tmp.x, length);
795                                                    BitstreamPutBits(&bs, tmp.y, length);
796                                            }
797                                    }
798                            }
799                  }                  }
800          }          }
801    
802          pMB->quant = pEnc->mbParam.quant;          if (!hint->rawhints) {
803                    BitstreamPad(&bs);
804                    hint->hintlength = BitstreamLength(&bs);
805            }
806  }  }
807    
808    
809  static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits)  static int
810    FrameCodeI(Encoder * pEnc,
811                       Bitstream * bs,
812                       uint32_t * pBits)
813  {  {
814      int16_t dct_codes[6][64];  
815      int16_t qcoeff[6][64];          DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
816            DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
817    
818      uint16_t x, y;      uint16_t x, y;
     IMAGE *pCurrent = &pEnc->sCurrent;  
819    
820      pEnc->iFrameNum = 0;      pEnc->iFrameNum = 0;
821      pEnc->mbParam.rounding_type = 1;          pEnc->mbParam.m_rounding_type = 1;
822      pEnc->mbParam.coding_type = I_VOP;          pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
823            pEnc->current->coding_type = I_VOP;
824    
825            BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
826    
827          BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type);          BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
         BitstreamWriteVopHeader(bs, I_VOP, pEnc->mbParam.rounding_type,  
                         pEnc->mbParam.quant,  
                         pEnc->mbParam.fixed_code);  
828    
829      *pBits = BitstreamPos(bs);      *pBits = BitstreamPos(bs);
830    
# Line 376  Line 833 
833          pEnc->sStat.mblks = pEnc->sStat.ublks = 0;          pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
834    
835      for (y = 0; y < pEnc->mbParam.mb_height; y++)      for (y = 0; y < pEnc->mbParam.mb_height; y++)
836                  for (x = 0; x < pEnc->mbParam.mb_width; x++)                  for (x = 0; x < pEnc->mbParam.mb_width; x++) {
837                  {                          MACROBLOCK *pMB =
838                      MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];                                  &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
839    
840                          CodeIntraMB(pEnc, pMB);                          CodeIntraMB(pEnc, pMB);
841    
842                          MBTransQuantIntra(&pEnc->mbParam, x, y, dct_codes, qcoeff, pCurrent);                          MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,
843                                                              dct_codes, qcoeff);
844    
845                          start_timer();                          start_timer();
846                          MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs);                          MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
847                          stop_prediction_timer();                          stop_prediction_timer();
848    
849                          start_timer();                          start_timer();
850                          MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat);                          if (pEnc->current->global_flags & XVID_GREYSCALE)
851                            {       pMB->cbp &= 0x3C;               /* keep only bits 5-2 */
852                                    qcoeff[4*64+0]=0;               /* zero, because for INTRA MBs DC value is saved */
853                                    qcoeff[5*64+0]=0;
854                            }
855                            MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
856                          stop_coding_timer();                          stop_coding_timer();
857                  }                  }
858    
# Line 399  Line 862 
862      pEnc->sStat.fMvPrevSigma = -1;      pEnc->sStat.fMvPrevSigma = -1;
863      pEnc->sStat.iMvSum = 0;      pEnc->sStat.iMvSum = 0;
864      pEnc->sStat.iMvCount = 0;      pEnc->sStat.iMvCount = 0;
865      pEnc->mbParam.fixed_code = 2;          pEnc->mbParam.m_fcode = 2;
866    
867            if (pEnc->current->global_flags & XVID_HINTEDME_GET) {
868                    HintedMEGet(pEnc, 1);
869            }
870    
871      return 1;                                    // intra      return 1;                                    // intra
872  }  }
# Line 407  Line 874 
874    
875  #define INTRA_THRESHOLD 0.5  #define INTRA_THRESHOLD 0.5
876    
877  static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header)  static int
878    FrameCodeP(Encoder * pEnc,
879                       Bitstream * bs,
880                       uint32_t * pBits,
881                       bool force_inter,
882                       bool vol_header)
883  {  {
884      float fSigma;      float fSigma;
885      int16_t dct_codes[6][64];  
886      int16_t qcoeff[6][64];          DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
887            DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
888    
889          int iLimit;          int iLimit;
890      uint32_t x, y;          int x, y, k;
891      int iSearchRange;      int iSearchRange;
892          bool bIntra;          int bIntra;
893    
894      IMAGE *pCurrent = &pEnc->sCurrent;          /* IMAGE *pCurrent = &pEnc->current->image; */
895      IMAGE *pRef = &pEnc->sReference;          IMAGE *pRef = &pEnc->reference->image;
896    
897          image_setedges(pRef,pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height);          start_timer();
898            image_setedges(pRef, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
899      pEnc->mbParam.rounding_type = 1 - pEnc->mbParam.rounding_type;                                     pEnc->mbParam.width, pEnc->mbParam.height,
900                                       pEnc->current->global_flags & XVID_INTERLACING);
901            stop_edges_timer();
902    
903            pEnc->mbParam.m_rounding_type = 1 - pEnc->mbParam.m_rounding_type;
904            pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
905            pEnc->current->fcode = pEnc->mbParam.m_fcode;
906    
907          if (!force_inter)          if (!force_inter)
908                  iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD);                  iLimit =
909                            (int) (pEnc->mbParam.mb_width * pEnc->mbParam.mb_height *
910                                       INTRA_THRESHOLD);
911      else      else
912                  iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;                  iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
913    
914          if ((pEnc->mbParam.global_flags & XVID_HALFPEL) > 0) {          if ((pEnc->current->global_flags & XVID_HALFPEL)) {
915                  start_timer();                  start_timer();
916                  image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,                  image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV,
917                          pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,                                                    &pEnc->vInterHV, pEnc->mbParam.edged_width,
918                          pEnc->mbParam.rounding_type);                                                    pEnc->mbParam.edged_height,
919                                                      pEnc->current->rounding_type);
920                  stop_inter_timer();                  stop_inter_timer();
921          }          }
922    
923          start_timer();          start_timer();
924          bIntra = MotionEstimation(pEnc->pMBs, &pEnc->mbParam, &pEnc->sReference,          if (pEnc->current->global_flags & XVID_HINTEDME_SET) {
925                                  &pEnc->vInterH, &pEnc->vInterV,                  HintedMESet(pEnc, &bIntra);
926                                  &pEnc->vInterHV, &pEnc->sCurrent, iLimit);          } else {
927    
928    #ifdef _SMP
929            if (pEnc->mbParam.num_threads > 1)
930                    bIntra =
931                            SMP_MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference,
932                                                     &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
933                                                     iLimit);
934            else
935    #endif
936                    bIntra =
937                            MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference,
938                             &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
939                             iLimit);
940    
941            }
942          stop_motion_timer();          stop_motion_timer();
943    
944          if (bIntra == 1)          if (bIntra == 1) {
945                  return FrameCodeI(pEnc, bs, pBits);                  return FrameCodeI(pEnc, bs, pBits);
946            }
947    
948      pEnc->mbParam.coding_type = P_VOP;          pEnc->current->coding_type = P_VOP;
949    
950          if(vol_header)          if(vol_header)
951                  BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type);                  BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
952    
953      BitstreamWriteVopHeader(bs, P_VOP, pEnc->mbParam.rounding_type,          BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
                          pEnc->mbParam.quant,  
                          pEnc->mbParam.fixed_code);  
954    
955      *pBits = BitstreamPos(bs);      *pBits = BitstreamPos(bs);
956    
# Line 462  Line 959 
959      pEnc->sStat.iMvCount = 0;      pEnc->sStat.iMvCount = 0;
960          pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;          pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
961    
962      for(y = 0; y < pEnc->mbParam.mb_height; y++)          for (y = 0; y < pEnc->mbParam.mb_height; y++) {
963          {                  for (x = 0; x < pEnc->mbParam.mb_width; x++) {
964                  for(x = 0; x < pEnc->mbParam.mb_width; x++)                          MACROBLOCK *pMB =
965                  {                                  &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
                         MACROBLOCK * pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];  
966    
967                      bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);                      bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
968    
969                          if (!bIntra)                          if (!bIntra) {
                     {  
970                                  start_timer();                                  start_timer();
971                                  MBMotionCompensation(pMB, x, y, &pEnc->sReference,                                  MBMotionCompensation(pMB, x, y, &pEnc->reference->image,
972                                          &pEnc->vInterH, &pEnc->vInterV,                                          &pEnc->vInterH, &pEnc->vInterV,
973                                          &pEnc->vInterHV, &pEnc->sCurrent, dct_codes,                                                                           &pEnc->vInterHV, &pEnc->current->image,
974                                          pEnc->mbParam.width,                                                                           dct_codes, pEnc->mbParam.width,
975                                          pEnc->mbParam.height,                                          pEnc->mbParam.height,
976                                          pEnc->mbParam.edged_width,                                          pEnc->mbParam.edged_width,
977                                          pEnc->mbParam.rounding_type);                                                                           pEnc->current->rounding_type);
978                                  stop_comp_timer();                                  stop_comp_timer();
979    
980                                  if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) {                                  if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
981                                          if(pMB->dquant != NO_CHANGE) {                                          if(pMB->dquant != NO_CHANGE) {
982                                                  pMB->mode = MODE_INTER_Q;                                                  pMB->mode = MODE_INTER_Q;
983                                                  pEnc->mbParam.quant += DQtab[pMB->dquant];                                                  pEnc->current->quant += DQtab[pMB->dquant];
984                                                  if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31;                                                  if (pEnc->current->quant > 31)
985                                                  else if(pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1;                                                          pEnc->current->quant = 31;
986                                                    else if (pEnc->current->quant < 1)
987                                                            pEnc->current->quant = 1;
988                                          }                                          }
989                                  }                                  }
990                                  pMB->quant = pEnc->mbParam.quant;                                  pMB->quant = pEnc->current->quant;
991    
992                                  pMB->cbp = MBTransQuantInter(&pEnc->mbParam, x, y, dct_codes, qcoeff, pCurrent);                                  pMB->field_pred = 0;
993                      }  
994                          else                                  pMB->cbp =
995                          {                                          MBTransQuantInter(&pEnc->mbParam, pEnc->current, pMB, x, y,
996                                                                              dct_codes, qcoeff);
997                            } else {
998                                  CodeIntraMB(pEnc, pMB);                                  CodeIntraMB(pEnc, pMB);
999                                  MBTransQuantIntra(&pEnc->mbParam, x, y, dct_codes, qcoeff, pCurrent);                                  MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,
1000                                                                      dct_codes, qcoeff);
1001                          }                          }
1002    
1003                      start_timer();                      start_timer();
1004                          MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs);                          MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
1005                          stop_prediction_timer();                          stop_prediction_timer();
1006    
1007                          if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)                          if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) {
                         {  
1008                                  pEnc->sStat.kblks++;                                  pEnc->sStat.kblks++;
1009                          }                          } else if (pMB->cbp || pMB->mvs[0].x || pMB->mvs[0].y ||
1010                          else if (pMB->cbp ||                                             pMB->mvs[1].x || pMB->mvs[1].y || pMB->mvs[2].x ||
1011                                          pMB->mvs[0].x || pMB->mvs[0].y ||                                             pMB->mvs[2].y || pMB->mvs[3].x || pMB->mvs[3].y) {
                                         pMB->mvs[1].x || pMB->mvs[1].y ||  
                                         pMB->mvs[2].x || pMB->mvs[2].y ||  
                                         pMB->mvs[3].x || pMB->mvs[3].y)  
                         {  
1012                                  pEnc->sStat.mblks++;                                  pEnc->sStat.mblks++;
1013                          }                          }  else {
                         else  
                         {  
1014                                  pEnc->sStat.ublks++;                                  pEnc->sStat.ublks++;
1015                          }                          }
1016    
1017                          start_timer();                          start_timer();
1018                          MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat);  
1019                            /* Finished processing the MB, now check if to CODE or SKIP */
1020    
1021                            if (pMB->cbp == 0 && pMB->mode == MODE_INTER && pMB->mvs[0].x == 0 &&
1022                                    pMB->mvs[0].y == 0) {
1023    
1024                                            MBSkip(bs);     /* without B-frames, no precautions are needed */
1025    
1026                            }
1027                            else {
1028                                    if (pEnc->current->global_flags & XVID_GREYSCALE) {
1029                                            pMB->cbp &= 0x3C;               /* keep only bits 5-2 */
1030                                            qcoeff[4*64+0]=0;               /* zero, because DC for INTRA MBs DC value is saved */
1031                                            qcoeff[5*64+0]=0;
1032                                    }
1033                                    MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
1034                            }
1035    
1036                          stop_coding_timer();                          stop_coding_timer();
1037                  }                  }
1038          }          }
1039    
1040          emms();          emms();
1041    
1042            if (pEnc->current->global_flags & XVID_HINTEDME_GET) {
1043                    HintedMEGet(pEnc, 0);
1044            }
1045    
1046          if (pEnc->sStat.iMvCount == 0)          if (pEnc->sStat.iMvCount == 0)
1047                  pEnc->sStat.iMvCount = 1;                  pEnc->sStat.iMvCount = 1;
1048    
1049      fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);      fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);
1050    
1051      iSearchRange = 1 << (3 + pEnc->mbParam.fixed_code);          iSearchRange = 1 << (3 + pEnc->mbParam.m_fcode);
1052    
1053      if ((fSigma > iSearchRange / 3)      if ((fSigma > iSearchRange / 3)
1054                  && (pEnc->mbParam.fixed_code <= 3))     // maximum search range 128                  && (pEnc->mbParam.m_fcode <= 3))        // maximum search range 128
1055      {      {
1056                  pEnc->mbParam.fixed_code++;                  pEnc->mbParam.m_fcode++;
1057                  iSearchRange *= 2;                  iSearchRange *= 2;
1058      }          } else if ((fSigma < iSearchRange / 6)
     else if ((fSigma < iSearchRange / 6)  
1059              && (pEnc->sStat.fMvPrevSigma >= 0)              && (pEnc->sStat.fMvPrevSigma >= 0)
1060              && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)              && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)
1061              && (pEnc->mbParam.fixed_code >= 2)) // minimum search range 16                             && (pEnc->mbParam.m_fcode >= 2))     // minimum search range 16
1062      {      {
1063                  pEnc->mbParam.fixed_code--;                  pEnc->mbParam.m_fcode--;
1064                  iSearchRange /= 2;                  iSearchRange /= 2;
1065      }      }
1066    
# Line 556  Line 1069 
1069          *pBits = BitstreamPos(bs) - *pBits;          *pBits = BitstreamPos(bs) - *pBits;
1070    
1071      return 0;                                    // inter      return 0;                                    // inter
1072    
1073  }  }

Legend:
Removed from v.4  
changed lines
  Added in v.403

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