[svn] / branches / dev-api-3 / xvidcore / src / encoder.c Repository:
ViewVC logotype

Diff of /branches/dev-api-3/xvidcore/src/encoder.c

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

revision 78, Thu Mar 28 20:57:25 2002 UTC revision 147, Sun Apr 28 23:31:00 2002 UTC
# Line 1  Line 1 
1    /**************************************************************************
2     *
3     *  XVID MPEG-4 VIDEO CODEC
4     *  -  Encoder main module  -
5     *
6     *  This program is an implementation of a part of one or more MPEG-4
7     *  Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
8     *  to use this software module in hardware or software products are
9     *  advised that its use may infringe existing patents or copyrights, and
10     *  any such use would be at such party's own risk.  The original
11     *  developer of this software module and his/her company, and subsequent
12     *  editors and their companies, will have no liability for use of this
13     *  software or modifications or derivatives thereof.
14     *
15     *  This program is free software; you can redistribute it and/or modify
16     *  it under the terms of the GNU General Public License as published by
17     *  the Free Software Foundation; either version 2 of the License, or
18     *  (at your option) any later version.
19     *
20     *  This program is distributed in the hope that it will be useful,
21     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     *  GNU General Public License for more details.
24     *
25     *  You should have received a copy of the GNU General Public License
26     *  along with this program; if not, write to the Free Software
27     *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
28     *
29     ***************************************************************************/
30    
31    /****************************************************************************
32     *
33     *  History
34     *
35     *  14.04.2002 added FrameCodeB()
36     *
37     *  $Id: encoder.c,v 1.30 2002-04-28 23:31:00 edgomez Exp $
38     *
39     ***************************************************************************/
40    
41  #include <stdlib.h>  #include <stdlib.h>
42  #include <stdio.h>  #include <stdio.h>
43  #include <math.h>  #include <math.h>
# Line 19  Line 59 
59  #include "utils/mem_align.h"  #include "utils/mem_align.h"
60    
61  #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT  #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT
62    #define SWAP(A,B)    { void * tmp = A; A = B; B = tmp; }
63    
64    
65  static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits);  static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits);
# Line 35  Line 76 
76  };  };
77    
78    
79    void static image_null(IMAGE * image)
80    {
81            image->y = image->u = image->v = NULL;
82    }
83    
84    
85  int encoder_create(XVID_ENC_PARAM * pParam)  int encoder_create(XVID_ENC_PARAM * pParam)
86  {  {
87          Encoder *pEnc;          Encoder *pEnc;
# Line 78  Line 125 
125                  pParam->fincr = (int)(pParam->fincr / div);                  pParam->fincr = (int)(pParam->fincr / div);
126          }          }
127    
128          if (pParam->bitrate <= 0)          if (pParam->rc_bitrate <= 0)
129                  pParam->bitrate = 900000;                  pParam->rc_bitrate = 900000;
130    
131            if (pParam->rc_reaction_delay_factor <= 0)
132                    pParam->rc_reaction_delay_factor = 16;
133    
134          if (pParam->rc_buffersize <= 0)          if (pParam->rc_averaging_period <= 0)
135                  pParam->rc_buffersize = 16;                  pParam->rc_averaging_period = 100;
136    
137            if (pParam->rc_buffer <= 0)
138                    pParam->rc_buffer = 100;
139    
140          if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))          if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))
141                  pParam->min_quantizer = 1;                  pParam->min_quantizer = 1;
# Line 114  Line 167 
167    
168          /* Fill rate control parameters */          /* Fill rate control parameters */
169    
170          pEnc->mbParam.quant = 4;          pEnc->bitrate = pParam->rc_bitrate;
   
         pEnc->bitrate = pParam->bitrate;  
171    
172          pEnc->iFrameNum = 0;          pEnc->iFrameNum = 0;
173          pEnc->iMaxKeyInterval = pParam->max_key_interval;          pEnc->iMaxKeyInterval = pParam->max_key_interval;
174    
175          if (image_create(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          /* try to allocate frame memory */
         {  
                 xvid_free(pEnc);  
                 return XVID_ERR_MEMORY;  
         }  
176    
177          if (image_create(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          pEnc->current = NULL;
178            pEnc->reference = NULL;
179            if ( (pEnc->current = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE)) == NULL ||
180                     (pEnc->reference = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE)) == NULL)
181          {          {
182                  image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  if (pEnc->current) xvid_free(pEnc->current);
183                  xvid_free(pEnc);                  xvid_free(pEnc);
184                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
185          }          }
186    
187          if (image_create(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          /* try to allocate mb memory */
         {  
                 image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
                 xvid_free(pEnc);  
                 return XVID_ERR_MEMORY;  
         }  
188    
189          if (image_create(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)          pEnc->current->mbs = NULL;
190          {          pEnc->reference->mbs = NULL;
                 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);  
                 xvid_free(pEnc);  
                 return XVID_ERR_MEMORY;  
         }  
191    
192          if (image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)  #ifdef _DEBUG
193          {  #ifdef WIN32
194                  image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  OutputDebugString("malloc mbs");
195                  image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  #endif
196                  image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  #endif
197                  image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
198            if ((pEnc->current->mbs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL ||
199                    (pEnc->reference->mbs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL)
200            {
201                    if (pEnc->current->mbs) xvid_free(pEnc->current->mbs);
202                    xvid_free(pEnc->current);
203                    xvid_free(pEnc->reference);
204                  xvid_free(pEnc);                  xvid_free(pEnc);
                 return XVID_ERR_MEMORY;  
205          }          }
206    
207          pEnc->pMBs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE);          /* try to allocate image memory */
208          if (pEnc->pMBs == NULL)  
209          {  #ifdef _DEBUG
210                  image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_null(&pEnc->sOriginal);
211                  image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  #endif
212            image_null(&pEnc->current->image);
213            image_null(&pEnc->reference->image);
214            image_null(&pEnc->vInterH);
215            image_null(&pEnc->vInterV);
216            image_null(&pEnc->vInterVf);
217            image_null(&pEnc->vInterHV);
218            image_null(&pEnc->vInterHVf);
219    
220    #ifdef _DEBUG
221    #ifdef WIN32
222    OutputDebugString("malloc images");
223    #endif
224    #endif
225            if (
226    #ifdef _DEBUG
227                    image_create(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
228    #endif
229                    image_create(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
230                    image_create(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
231                    image_create(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
232                    image_create(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
233                    image_create(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
234                    image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
235                    image_create(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)
236            {
237    #ifdef _DEBUG
238                    image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
239    #endif
240                    image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
241                    image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
242                  image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
243                  image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
244                    image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
245                  image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
246                    image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
247    
248                    xvid_free(pEnc->current);
249                    xvid_free(pEnc->reference);
250                  xvid_free(pEnc);                  xvid_free(pEnc);
251                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
252          }          }
253    
         // init macroblock array  
         for (i = 0; i < pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; i++)  
         {  
                 pEnc->pMBs[i].dquant = NO_CHANGE;  
         }  
   
254          pParam->handle = (void *)pEnc;          pParam->handle = (void *)pEnc;
255    
256          if (pParam->bitrate)          if (pParam->rc_bitrate)
257          {          {
258                  RateControlInit(pParam->bitrate, pParam->rc_buffersize, pParam->fbase * 100 / pParam->fincr,                  RateControlInit(pParam->rc_bitrate, pParam->rc_reaction_delay_factor,
259                            pParam->rc_averaging_period, pParam->rc_buffer, pParam->fbase * 1000 / pParam->fincr,
260                                  pParam->max_quantizer, pParam->min_quantizer);                                  pParam->max_quantizer, pParam->min_quantizer);
261          }          }
262    
         create_vlc_tables();  
263          init_timer();          init_timer();
264    
265          return XVID_ERR_OK;          return XVID_ERR_OK;
# Line 197  Line 269 
269  int encoder_destroy(Encoder * pEnc)  int encoder_destroy(Encoder * pEnc)
270  {  {
271          ENC_CHECK(pEnc);          ENC_CHECK(pEnc);
         ENC_CHECK(pEnc->sCurrent.y);  
         ENC_CHECK(pEnc->sReference.y);  
272    
273          xvid_free(pEnc->pMBs);          image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
274          image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
         image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  
275          image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
276          image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
277            image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
278          image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
279          xvid_free(pEnc);          image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
280    #ifdef _DEBUG
281                    image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
282    #endif
283            xvid_free(pEnc->current->mbs);
284            xvid_free(pEnc->current);
285    
286          destroy_vlc_tables();          xvid_free(pEnc->reference->mbs);
287            xvid_free(pEnc->reference);
288    
289            xvid_free(pEnc);
290          return XVID_ERR_OK;          return XVID_ERR_OK;
291  }  }
292    
# Line 219  Line 296 
296          Bitstream bs;          Bitstream bs;
297          uint32_t bits;          uint32_t bits;
298          uint16_t write_vol_header = 0;          uint16_t write_vol_header = 0;
299    #ifdef _DEBUG
300            float psnr;
301            uint8_t temp[100];
302    #endif
303    
304          start_global_timer();          start_global_timer();
305    
# Line 227  Line 308 
308          ENC_CHECK(pFrame->bitstream);          ENC_CHECK(pFrame->bitstream);
309          ENC_CHECK(pFrame->image);          ENC_CHECK(pFrame->image);
310    
311          pEnc->mbParam.global_flags = pFrame->general;          SWAP(pEnc->current, pEnc->reference);
312          pEnc->mbParam.motion_flags = pFrame->motion;  
313            pEnc->current->global_flags = pFrame->general;
314            pEnc->current->motion_flags = pFrame->motion;
315            pEnc->mbParam.hint = &pFrame->hint;
316    
317          start_timer();          start_timer();
318          if (image_input(&pEnc->sCurrent, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,          if (image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,
319                          pFrame->image, pFrame->colorspace))                          pFrame->image, pFrame->colorspace))
320          {          {
321                  return XVID_ERR_FORMAT;                  return XVID_ERR_FORMAT;
322          }          }
323          stop_conv_timer();          stop_conv_timer();
324    
325    #ifdef _DEBUG
326            image_copy(&pEnc->sOriginal, &pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.height);
327    #endif
328    
329          EMMS();          EMMS();
330    
331          BitstreamInit(&bs, pFrame->bitstream, 0);          BitstreamInit(&bs, pFrame->bitstream, 0);
332    
333          if (pFrame->quant == 0)          if (pFrame->quant == 0)
334          {          {
335                  pEnc->mbParam.quant = RateControlGetQ(0);                  pEnc->current->quant = RateControlGetQ(0);
336          }          }
337          else          else
338          {          {
339                  pEnc->mbParam.quant = pFrame->quant;                  pEnc->current->quant = pFrame->quant;
340          }          }
341    
342          if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0)          if ((pEnc->current->global_flags & XVID_LUMIMASKING))
343          {          {
344                  int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE);                  int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE);
345    
346                  pEnc->mbParam.quant = adaptive_quantization(pEnc->sCurrent.y,                  pEnc->current->quant = adaptive_quantization(pEnc->current->image.y,
347                                                              pEnc->mbParam.width,                                                              pEnc->mbParam.edged_width,  // stride
348                                                              temp_dquants,                                                              temp_dquants,
349                                                              pFrame->quant,                                                              pEnc->current->quant,
350                                                              pFrame->quant,                                                              pEnc->current->quant,       // min_quant
351                                                              2*pFrame->quant,                                                              2*pEnc->current->quant,     // max_quant
352                                                              pEnc->mbParam.mb_width,                                                              pEnc->mbParam.mb_width,
353                                                              pEnc->mbParam.mb_height);                                                              pEnc->mbParam.mb_height);
354    
355                  for (y = 0; y < pEnc->mbParam.mb_height; y++)                  for (y = 0; y < pEnc->mbParam.mb_height; y++)
356                          for (x = 0; x < pEnc->mbParam.mb_width; x++)                          for (x = 0; x < pEnc->mbParam.mb_width; x++)
357                          {                          {
358                                  MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];                                  MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
359                                  pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];                                  pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];
360                          }                          }
361                  xvid_free(temp_dquants);                  xvid_free(temp_dquants);
362          }          }
363    
364          if(pEnc->mbParam.global_flags & XVID_H263QUANT) {          if (pEnc->current->global_flags & XVID_H263QUANT) {
365                  if(pEnc->mbParam.quant_type != H263_QUANT)                  if(pEnc->mbParam.m_quant_type != H263_QUANT)
366                          write_vol_header = 1;                          write_vol_header = 1;
367                  pEnc->mbParam.quant_type = H263_QUANT;                  pEnc->mbParam.m_quant_type = H263_QUANT;
368          }          }
369          else if(pEnc->mbParam.global_flags & XVID_MPEGQUANT) {          else if(pEnc->current->global_flags & XVID_MPEGQUANT) {
370                  int ret1, ret2;                  int ret1, ret2;
371    
372                  ret1 = ret2 = 0;                  ret1 = ret2 = 0;
373    
374                  if(pEnc->mbParam.quant_type != MPEG4_QUANT)                  if(pEnc->mbParam.m_quant_type != MPEG4_QUANT)
375                          write_vol_header = 1;                          write_vol_header = 1;
376    
377                  pEnc->mbParam.quant_type = MPEG4_QUANT;                  pEnc->mbParam.m_quant_type = MPEG4_QUANT;
378    
379                  if ((pEnc->mbParam.global_flags & XVID_CUSTOM_QMATRIX) > 0) {                  if ((pEnc->current->global_flags & XVID_CUSTOM_QMATRIX) > 0) {
380                          if(pFrame->quant_intra_matrix != NULL)                          if(pFrame->quant_intra_matrix != NULL)
381                                  ret1 = set_intra_matrix(pFrame->quant_intra_matrix);                                  ret1 = set_intra_matrix(pFrame->quant_intra_matrix);
382                          if(pFrame->quant_inter_matrix != NULL)                          if(pFrame->quant_inter_matrix != NULL)
# Line 326  Line 414 
414    
415          if (pResult)          if (pResult)
416          {          {
417                  pResult->quant = pEnc->mbParam.quant;                  pResult->quant = pEnc->current->quant;
418                  pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);                  pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
419                  pResult->kblks = pEnc->sStat.kblks;                  pResult->kblks = pEnc->sStat.kblks;
420                  pResult->mblks = pEnc->sStat.mblks;                  pResult->mblks = pEnc->sStat.mblks;
# Line 337  Line 425 
425    
426          if (pFrame->quant == 0)          if (pFrame->quant == 0)
427          {          {
428                  RateControlUpdate(pEnc->mbParam.quant, pFrame->length, pFrame->intra);                  RateControlUpdate(pEnc->current->quant, pFrame->length, pFrame->intra);
429          }          }
430    
431    #ifdef _DEBUG
432            psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width,
433                                    pEnc->mbParam.width, pEnc->mbParam.height);
434    
435            sprintf(temp, "PSNR: %f\n", psnr);
436            DEBUG(temp);
437    #endif
438    
439          pEnc->iFrameNum++;          pEnc->iFrameNum++;
         image_swap(&pEnc->sCurrent, &pEnc->sReference);  
440    
441          stop_global_timer();          stop_global_timer();
442          write_timer();          write_timer();
# Line 354  Line 449 
449    
450          pMB->mode = MODE_INTRA;          pMB->mode = MODE_INTRA;
451    
452          if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) {          /* zero mv statistics */
453            pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
454            pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
455            pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
456            pMB->sad16 = 0;
457    
458            if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
459                  if(pMB->dquant != NO_CHANGE)                  if(pMB->dquant != NO_CHANGE)
460                  {                  {
461                          pMB->mode = MODE_INTRA_Q;                          pMB->mode = MODE_INTRA_Q;
462                          pEnc->mbParam.quant += DQtab[pMB->dquant];                          pEnc->current->quant += DQtab[pMB->dquant];
463    
464                            if (pEnc->current->quant > 31) pEnc->current->quant = 31;
465                            if (pEnc->current->quant < 1) pEnc->current->quant = 1;
466                    }
467            }
468    
469            pMB->quant = pEnc->current->quant;
470    }
471    
472    
473    #define FCODEBITS       3
474    #define MODEBITS        5
475    
476    void HintedMESet(Encoder * pEnc, int * intra)
477    {
478            HINTINFO * hint;
479            Bitstream bs;
480            int length, high;
481            uint32_t x, y;
482    
483            hint = pEnc->mbParam.hint;
484    
485            if (hint->rawhints)
486            {
487                    *intra = hint->mvhint.intra;
488            }
489            else
490            {
491                    BitstreamInit(&bs, hint->hintstream, hint->hintlength);
492                    *intra = BitstreamGetBit(&bs);
493            }
494    
495            if (*intra)
496            {
497                    return;
498            }
499    
500            pEnc->current->fcode = (hint->rawhints) ? hint->mvhint.fcode : BitstreamGetBits(&bs, FCODEBITS);
501    
502            length  = pEnc->current->fcode + 5;
503            high    = 1 << (length - 1);
504    
505            for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
506            {
507                    for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
508                    {
509                            MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
510                            MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
511                            VECTOR pred[4];
512                            VECTOR tmp;
513                            int32_t dummy[4];
514                            int vec;
515    
516                            pMB->mode = (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs, MODEBITS);
517    
518                            pMB->mode = (pMB->mode == MODE_INTER_Q) ? MODE_INTER : pMB->mode;
519                            pMB->mode = (pMB->mode == MODE_INTRA_Q) ? MODE_INTRA : pMB->mode;
520    
521                            if (pMB->mode == MODE_INTER)
522                            {
523                                    tmp.x  = (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs, length);
524                                    tmp.y  = (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs, length);
525                                    tmp.x -= (tmp.x >= high) ? high*2 : 0;
526                                    tmp.y -= (tmp.y >= high) ? high*2 : 0;
527    
528                                    get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, 0, pred, dummy);
529    
530                                    for (vec=0 ; vec<4 ; ++vec)
531                                    {
532                                            pMB->mvs[vec].x  = tmp.x;
533                                            pMB->mvs[vec].y  = tmp.y;
534                                            pMB->pmvs[vec].x = pMB->mvs[0].x - pred[0].x;
535                                            pMB->pmvs[vec].y = pMB->mvs[0].y - pred[0].y;
536                                    }
537                            }
538                            else if (pMB->mode == MODE_INTER4V)
539                            {
540                                    for (vec=0 ; vec<4 ; ++vec)
541                                    {
542                                            tmp.x  = (hint->rawhints) ? bhint->mvs[vec].x : BitstreamGetBits(&bs, length);
543                                            tmp.y  = (hint->rawhints) ? bhint->mvs[vec].y : BitstreamGetBits(&bs, length);
544                                            tmp.x -= (tmp.x >= high) ? high*2 : 0;
545                                            tmp.y -= (tmp.y >= high) ? high*2 : 0;
546    
547                                            get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, vec, pred, dummy);
548    
549                                            pMB->mvs[vec].x  = tmp.x;
550                                            pMB->mvs[vec].y  = tmp.y;
551                                            pMB->pmvs[vec].x = pMB->mvs[vec].x - pred[0].x;
552                                            pMB->pmvs[vec].y = pMB->mvs[vec].y - pred[0].y;
553                                    }
554                            }
555                            else    // intra / stuffing / not_coded
556                            {
557                                    for (vec=0 ; vec<4 ; ++vec)
558                                    {
559                                            pMB->mvs[vec].x  = pMB->mvs[vec].y  = 0;
560                                    }
561                            }
562    
563                            if (pMB->mode == MODE_INTER4V &&
564                                    (pEnc->current->global_flags & XVID_LUMIMASKING) && pMB->dquant != NO_CHANGE)
565                            {
566                                    pMB->mode = MODE_INTRA;
567    
568                          if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31;                                  for (vec=0 ; vec<4 ; ++vec)
569                          if (pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1;                                  {
570                                            pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
571                                    }
572                            }
573                    }
574                  }                  }
575          }          }
576    
577          pMB->quant = pEnc->mbParam.quant;  
578    void HintedMEGet(Encoder * pEnc, int intra)
579    {
580            HINTINFO * hint;
581            Bitstream bs;
582            uint32_t x, y;
583            int length, high;
584    
585            hint = pEnc->mbParam.hint;
586    
587            if (hint->rawhints)
588            {
589                    hint->mvhint.intra = intra;
590            }
591            else
592            {
593                    BitstreamInit(&bs, hint->hintstream, 0);
594                    BitstreamPutBit(&bs, intra);
595            }
596    
597            if (intra)
598            {
599                    if (!hint->rawhints)
600                    {
601                            BitstreamPad(&bs);
602                            hint->hintlength = BitstreamLength(&bs);
603                    }
604                    return;
605            }
606    
607            length  = pEnc->current->fcode + 5;
608            high    = 1 << (length - 1);
609    
610            if (hint->rawhints)
611            {
612                    hint->mvhint.fcode = pEnc->current->fcode;
613            }
614            else
615            {
616                    BitstreamPutBits(&bs, pEnc->current->fcode, FCODEBITS);
617            }
618    
619            for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
620            {
621                    for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
622                    {
623                            MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
624                            MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
625                            VECTOR tmp;
626    
627                            if (hint->rawhints)
628                            {
629                                    bhint->mode = pMB->mode;
630                            }
631                            else
632                            {
633                                    BitstreamPutBits(&bs, pMB->mode, MODEBITS);
634                            }
635    
636                            if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)
637                            {
638                                    tmp.x  = pMB->mvs[0].x;
639                                    tmp.y  = pMB->mvs[0].y;
640                                    tmp.x += (tmp.x < 0) ? high*2 : 0;
641                                    tmp.y += (tmp.y < 0) ? high*2 : 0;
642    
643                                    if (hint->rawhints)
644                                    {
645                                            bhint->mvs[0].x = tmp.x;
646                                            bhint->mvs[0].y = tmp.y;
647                                    }
648                                    else
649                                    {
650                                            BitstreamPutBits(&bs, tmp.x, length);
651                                            BitstreamPutBits(&bs, tmp.y, length);
652                                    }
653                            }
654                            else if (pMB->mode == MODE_INTER4V)
655                            {
656                                    int vec;
657    
658                                    for (vec=0 ; vec<4 ; ++vec)
659                                    {
660                                            tmp.x  = pMB->mvs[vec].x;
661                                            tmp.y  = pMB->mvs[vec].y;
662                                            tmp.x += (tmp.x < 0) ? high*2 : 0;
663                                            tmp.y += (tmp.y < 0) ? high*2 : 0;
664    
665                                            if (hint->rawhints)
666                                            {
667                                                    bhint->mvs[vec].x = tmp.x;
668                                                    bhint->mvs[vec].y = tmp.y;
669                                            }
670                                            else
671                                            {
672                                                    BitstreamPutBits(&bs, tmp.x, length);
673                                                    BitstreamPutBits(&bs, tmp.y, length);
674                                            }
675                                    }
676                            }
677                    }
678            }
679    
680            if (!hint->rawhints)
681            {
682                    BitstreamPad(&bs);
683                    hint->hintlength = BitstreamLength(&bs);
684            }
685  }  }
686    
687    
# Line 378  Line 694 
694          uint16_t x, y;          uint16_t x, y;
695    
696          pEnc->iFrameNum = 0;          pEnc->iFrameNum = 0;
697          pEnc->mbParam.rounding_type = 1;          pEnc->mbParam.m_rounding_type = 1;
698          pEnc->mbParam.coding_type = I_VOP;          pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
699            pEnc->current->coding_type = I_VOP;
700    
701          BitstreamWriteVolHeader(bs, &pEnc->mbParam);          BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
702          BitstreamWriteVopHeader(bs, &pEnc->mbParam);          BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
703    
704          *pBits = BitstreamPos(bs);          *pBits = BitstreamPos(bs);
705    
# Line 393  Line 710 
710          for (y = 0; y < pEnc->mbParam.mb_height; y++)          for (y = 0; y < pEnc->mbParam.mb_height; y++)
711                  for (x = 0; x < pEnc->mbParam.mb_width; x++)                  for (x = 0; x < pEnc->mbParam.mb_width; x++)
712                  {                  {
713                          MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];                          MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
714    
715                          CodeIntraMB(pEnc, pMB);                          CodeIntraMB(pEnc, pMB);
716    
717                          MBTransQuantIntra(&pEnc->mbParam, pMB, x, y, dct_codes, qcoeff, &pEnc->sCurrent);                          MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
718    
719                          start_timer();                          start_timer();
720                          MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs);                          MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
721                          stop_prediction_timer();                          stop_prediction_timer();
722    
723                          start_timer();                          start_timer();
724                          MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat);                          MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
725                          stop_coding_timer();                          stop_coding_timer();
726                  }                  }
727    
# Line 414  Line 731 
731          pEnc->sStat.fMvPrevSigma = -1;          pEnc->sStat.fMvPrevSigma = -1;
732          pEnc->sStat.iMvSum = 0;          pEnc->sStat.iMvSum = 0;
733          pEnc->sStat.iMvCount = 0;          pEnc->sStat.iMvCount = 0;
734          pEnc->mbParam.fixed_code = 2;          pEnc->mbParam.m_fcode = 2;
735    
736            if (pEnc->current->global_flags & XVID_HINTEDME_GET)
737            {
738                    HintedMEGet(pEnc, 1);
739            }
740    
741          return 1;                                        // intra          return 1;                                        // intra
742  }  }
# Line 432  Line 754 
754          int iLimit;          int iLimit;
755          uint32_t x, y;          uint32_t x, y;
756          int iSearchRange;          int iSearchRange;
757          bool bIntra;          int bIntra;
758    
759          IMAGE *pCurrent = &pEnc->sCurrent;          /* IMAGE *pCurrent = &pEnc->current->image; */
760          IMAGE *pRef = &pEnc->sReference;          IMAGE *pRef = &pEnc->reference->image;
761    
762          start_timer();          start_timer();
763          image_setedges(pRef,          image_setedges(pRef,
# Line 443  Line 765 
765                         pEnc->mbParam.edged_height,                         pEnc->mbParam.edged_height,
766                         pEnc->mbParam.width,                         pEnc->mbParam.width,
767                         pEnc->mbParam.height,                         pEnc->mbParam.height,
768                         pEnc->mbParam.global_flags & XVID_INTERLACING);                         pEnc->current->global_flags & XVID_INTERLACING);
769          stop_edges_timer();          stop_edges_timer();
770    
771          pEnc->mbParam.rounding_type = 1 - pEnc->mbParam.rounding_type;          pEnc->mbParam.m_rounding_type = 1 - pEnc->mbParam.m_rounding_type;
772            pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
773            pEnc->current->fcode = pEnc->mbParam.m_fcode;
774    
775          if (!force_inter)          if (!force_inter)
776                  iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD);                  iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD);
777          else          else
778                  iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;                  iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
779    
780          if ((pEnc->mbParam.global_flags & XVID_HALFPEL) > 0) {          if ((pEnc->current->global_flags & XVID_HALFPEL)) {
781                  start_timer();                  start_timer();
782                  image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,                  image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
783                                    pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,                                    pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
784                                    pEnc->mbParam.rounding_type);                                    pEnc->current->rounding_type);
785                  stop_inter_timer();                  stop_inter_timer();
786          }          }
787    
788          start_timer();          start_timer();
789          bIntra = MotionEstimation(pEnc->pMBs, &pEnc->mbParam, &pEnc->sReference,          if (pEnc->current->global_flags & XVID_HINTEDME_SET)
790                                    &pEnc->vInterH, &pEnc->vInterV,          {
791                                    &pEnc->vInterHV, &pEnc->sCurrent, iLimit);                  HintedMESet(pEnc, &bIntra);
792            }
793            else
794            {
795                    bIntra = MotionEstimation(
796                            &pEnc->mbParam,
797                            pEnc->current,
798                            pEnc->reference,
799                            &pEnc->vInterH,
800                            &pEnc->vInterV,
801                            &pEnc->vInterHV,
802                            iLimit);
803            }
804          stop_motion_timer();          stop_motion_timer();
805    
806          if (bIntra == 1)          if (bIntra == 1)
807            {
808                  return FrameCodeI(pEnc, bs, pBits);                  return FrameCodeI(pEnc, bs, pBits);
809            }
810    
811          pEnc->mbParam.coding_type = P_VOP;          pEnc->current->coding_type = P_VOP;
812    
813          if(vol_header)          if(vol_header)
814                  BitstreamWriteVolHeader(bs, &pEnc->mbParam);                  BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
815    
816          BitstreamWriteVopHeader(bs, &pEnc->mbParam);          BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
817    
818          *pBits = BitstreamPos(bs);          *pBits = BitstreamPos(bs);
819    
# Line 488  Line 826 
826          {          {
827                  for(x = 0; x < pEnc->mbParam.mb_width; x++)                  for(x = 0; x < pEnc->mbParam.mb_width; x++)
828                  {                  {
829                          MACROBLOCK * pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];                          MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
830    
831                          bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);                          bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
832    
# Line 497  Line 835 
835                                  start_timer();                                  start_timer();
836                                  MBMotionCompensation(pMB,                                  MBMotionCompensation(pMB,
837                                                       x, y,                                                       x, y,
838                                                       &pEnc->sReference,                                                       &pEnc->reference->image,
839                                                       &pEnc->vInterH,                                                       &pEnc->vInterH,
840                                                       &pEnc->vInterV,                                                       &pEnc->vInterV,
841                                                       &pEnc->vInterHV,                                                       &pEnc->vInterHV,
842                                                       &pEnc->sCurrent,                                                       &pEnc->current->image,
843                                                       dct_codes,                                                       dct_codes,
844                                                       pEnc->mbParam.width,                                                       pEnc->mbParam.width,
845                                                       pEnc->mbParam.height,                                                       pEnc->mbParam.height,
846                                                       pEnc->mbParam.edged_width,                                                       pEnc->mbParam.edged_width,
847                                                       pEnc->mbParam.rounding_type);                                                       pEnc->current->rounding_type);
848                                  stop_comp_timer();                                  stop_comp_timer();
849    
850                                  if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) {                                  if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
851                                          if(pMB->dquant != NO_CHANGE) {                                          if(pMB->dquant != NO_CHANGE) {
852                                                  pMB->mode = MODE_INTER_Q;                                                  pMB->mode = MODE_INTER_Q;
853                                                  pEnc->mbParam.quant += DQtab[pMB->dquant];                                                  pEnc->current->quant += DQtab[pMB->dquant];
854                                                  if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31;                                                  if (pEnc->current->quant > 31) pEnc->current->quant = 31;
855                                                  else if(pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1;                                                  else if(pEnc->current->quant < 1) pEnc->current->quant = 1;
856                                          }                                          }
857                                  }                                  }
858                                  pMB->quant = pEnc->mbParam.quant;                                  pMB->quant = pEnc->current->quant;
859    
860                                  pMB->field_pred = 0;                                  pMB->field_pred = 0;
861    
862                                  pMB->cbp = MBTransQuantInter(&pEnc->mbParam, pMB, x, y, dct_codes, qcoeff, pCurrent);                                  pMB->cbp = MBTransQuantInter(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
863                          }                          }
864                          else                          else
865                          {                          {
866                                  CodeIntraMB(pEnc, pMB);                                  CodeIntraMB(pEnc, pMB);
867                                  MBTransQuantIntra(&pEnc->mbParam, pMB, x, y, dct_codes, qcoeff, pCurrent);                                  MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
868                          }                          }
869    
870                          start_timer();                          start_timer();
871                          MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs);                          MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
872                          stop_prediction_timer();                          stop_prediction_timer();
873    
874                          if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)                          if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)
# Line 551  Line 889 
889                          }                          }
890    
891                          start_timer();                          start_timer();
892                          MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat);                          MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
893                          stop_coding_timer();                          stop_coding_timer();
894                  }                  }
895          }          }
896    
897          emms();          emms();
898    
899            if (pEnc->current->global_flags & XVID_HINTEDME_GET)
900            {
901                    HintedMEGet(pEnc, 0);
902            }
903    
904          if (pEnc->sStat.iMvCount == 0)          if (pEnc->sStat.iMvCount == 0)
905                  pEnc->sStat.iMvCount = 1;                  pEnc->sStat.iMvCount = 1;
906    
907          fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);          fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);
908    
909          iSearchRange = 1 << (3 + pEnc->mbParam.fixed_code);          iSearchRange = 1 << (3 + pEnc->mbParam.m_fcode);
910    
911          if ((fSigma > iSearchRange / 3)          if ((fSigma > iSearchRange / 3)
912              && (pEnc->mbParam.fixed_code <= 3)) // maximum search range 128              && (pEnc->mbParam.m_fcode <= 3))    // maximum search range 128
913          {          {
914                  pEnc->mbParam.fixed_code++;                  pEnc->mbParam.m_fcode++;
915                  iSearchRange *= 2;                  iSearchRange *= 2;
916          }          }
917          else if ((fSigma < iSearchRange / 6)          else if ((fSigma < iSearchRange / 6)
918                   && (pEnc->sStat.fMvPrevSigma >= 0)                   && (pEnc->sStat.fMvPrevSigma >= 0)
919                   && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)                   && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)
920                   && (pEnc->mbParam.fixed_code >= 2))    // minimum search range 16                   && (pEnc->mbParam.m_fcode >= 2))       // minimum search range 16
921          {          {
922                  pEnc->mbParam.fixed_code--;                  pEnc->mbParam.m_fcode--;
923                  iSearchRange /= 2;                  iSearchRange /= 2;
924          }          }
925    
# Line 586  Line 929 
929    
930          return 0;                                        // inter          return 0;                                        // inter
931  }  }
932    
933    
934    #if 0
935    
936    static void FrameCodeB(Encoder * pEnc, FRAMEINFO * frame, Bitstream * bs, uint32_t *pBits)
937    {
938            int16_t dct_codes[6][64];
939            int16_t qcoeff[6][64];
940            uint32_t x, y;
941            VECTOR forward;
942            VECTOR backward;
943    
944            IMAGE *f_ref = &pEnc->reference->image;
945            IMAGE *b_ref = &pEnc->current->image;
946    
947            /* forward  */
948            image_setedges(f_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height);
949            start_timer();
950            image_interpolate(f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
951                              pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
952            stop_inter_timer();
953    
954            /* backward */
955            image_setedges(b_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height);
956            start_timer();
957            image_interpolate(b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
958                              pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
959            stop_inter_timer();
960    
961            start_timer();
962            MotionEstimationBVOP(&pEnc->mbParam, frame,
963                                 pEnc->reference->mbs, f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
964                                 pEnc->current->mbs, b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV);
965    
966            stop_motion_timer();
967    
968            if (test_quant_type(&pEnc->mbParam, pEnc->current))
969            {
970                    BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type);
971            }
972    
973            frame->coding_type = B_VOP;
974            BitstreamWriteVopHeader(bs, B_VOP, frame->tick, 0,
975                                    frame->quant, frame->fcode, frame->bcode);
976    
977            *pBits = BitstreamPos(bs);
978    
979            pEnc->sStat.iTextBits = 0;
980            pEnc->sStat.iMvSum = 0;
981            pEnc->sStat.iMvCount = 0;
982            pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
983    
984    
985            for (y = 0; y < pEnc->mbParam.mb_height; y++)
986            {
987                    // reset prediction
988    
989                    forward.x = 0;
990                    forward.y = 0;
991                    backward.x = 0;
992                    backward.y = 0;
993    
994                    for (x = 0; x < pEnc->mbParam.mb_width; x++)
995                    {
996                            MACROBLOCK * f_mb = &pEnc->reference->mbs[x + y * pEnc->mbParam.mb_width];
997                            MACROBLOCK * b_mb = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
998                            MACROBLOCK * mb = &frame->mbs[x + y * pEnc->mbParam.mb_width];
999    
1000                            // decoder ignores mb when refence block is INTER(0,0), CBP=0
1001                            if (mb->mode == MODE_NOT_CODED)
1002                            {
1003                                    mb->mvs[0].x = 0;
1004                                    mb->mvs[0].y = 0;
1005                                    continue;
1006                            }
1007    
1008                            MBMotionCompensationBVOP(&pEnc->mbParam, mb, x, y, &frame->image,
1009                                                     f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1010                                                     b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1011                                                     dct_codes);
1012    
1013                            mb->quant = frame->quant;
1014                            mb->cbp = MBTransQuantInter(&pEnc->mbParam, frame, x, y, dct_codes, qcoeff);
1015                            //mb->cbp = MBTransQuantBVOP(&pEnc->mbParam, x, y, dct_codes, qcoeff, &frame->image, frame->quant);
1016    
1017    
1018                            if ((mb->mode == MODE_INTERPOLATE || mb->mode == MODE_DIRECT) &&
1019                                mb->cbp == 0 &&
1020                                mb->mvs[0].x == 0 &&
1021                                mb->mvs[0].y == 0)
1022                            {
1023                                    mb->mode = 5;  // skipped
1024                            }
1025    
1026                            if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_FORWARD)
1027                            {
1028                                    mb->pmvs[0].x = mb->mvs[0].x - forward.x;
1029                                    mb->pmvs[0].y = mb->mvs[0].y - forward.y;
1030                                    forward.x = mb->mvs[0].x;
1031                                    forward.y = mb->mvs[0].y;
1032                            }
1033    
1034                            if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_BACKWARD)
1035                            {
1036                                    mb->b_pmvs[0].x = mb->b_mvs[0].x - backward.x;
1037                                    mb->b_pmvs[0].y = mb->b_mvs[0].y - backward.y;
1038                                    backward.x = mb->b_mvs[0].x;
1039                                    backward.y = mb->b_mvs[0].y;
1040                            }
1041    
1042                            /*
1043                              printf("[%i %i] M=%i CBP=%i MVX=%i MVY=%i %i,%i  %i,%i\n",
1044                                   x,
1045                                   y,
1046                                   pMB->mode,
1047                                   pMB->cbp,
1048                                   pMB->mvs[0].x,
1049                                   bmb->pmvs[0].x,
1050                                   bmb->pmvs[0].y,
1051                                   forward.x,
1052                                   forward.y);
1053                            */
1054    
1055                            start_timer();
1056                            MBCodingBVOP(frame, mb, qcoeff, bs, &pEnc->sStat);
1057                            stop_coding_timer();
1058                    }
1059            }
1060    
1061            emms();
1062    
1063            // TODO: dynamic fcode/bcode ???
1064    
1065            *pBits = BitstreamPos(bs) - *pBits;
1066    
1067    }
1068    
1069    #endif

Legend:
Removed from v.78  
changed lines
  Added in v.147

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