[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 86, Fri Mar 29 07:18:30 2002 UTC revision 157, Fri May 3 08:37:55 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.33 2002-05-03 08:32:49 Isibaar 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 7  Line 47 
47  #include "global.h"  #include "global.h"
48  #include "utils/timer.h"  #include "utils/timer.h"
49  #include "image/image.h"  #include "image/image.h"
50    #include "motion/motion.h"
51  #include "bitstream/cbp.h"  #include "bitstream/cbp.h"
52  #include "utils/mbfunctions.h"  #include "utils/mbfunctions.h"
53  #include "bitstream/bitstream.h"  #include "bitstream/bitstream.h"
# Line 19  Line 60 
60  #include "utils/mem_align.h"  #include "utils/mem_align.h"
61    
62  #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT  #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT
63    #define SWAP(A,B)    { void * tmp = A; A = B; B = tmp; }
64    
65    
66  static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits);  static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits);
67  static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header);  static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header);
68    static void FrameCodeB(Encoder * pEnc, FRAMEINFO * frame, Bitstream * bs, uint32_t *pBits);
69    
70  static int DQtab[4] =  static int DQtab[4] =
71  {  {
# Line 35  Line 78 
78  };  };
79    
80    
81    void static image_null(IMAGE * image)
82    {
83            image->y = image->u = image->v = NULL;
84    }
85    
86    
87  int encoder_create(XVID_ENC_PARAM * pParam)  int encoder_create(XVID_ENC_PARAM * pParam)
88  {  {
89          Encoder *pEnc;          Encoder *pEnc;
# Line 78  Line 127 
127                  pParam->fincr = (int)(pParam->fincr / div);                  pParam->fincr = (int)(pParam->fincr / div);
128          }          }
129    
130          if (pParam->bitrate <= 0)          if (pParam->rc_bitrate <= 0)
131                  pParam->bitrate = 900000;                  pParam->rc_bitrate = 900000;
132    
133            if (pParam->rc_reaction_delay_factor <= 0)
134                    pParam->rc_reaction_delay_factor = 16;
135    
136          if (pParam->rc_buffersize <= 0)          if (pParam->rc_averaging_period <= 0)
137                  pParam->rc_buffersize = 16;                  pParam->rc_averaging_period = 100;
138    
139            if (pParam->rc_buffer <= 0)
140                    pParam->rc_buffer = 100;
141    
142          if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))          if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))
143                  pParam->min_quantizer = 1;                  pParam->min_quantizer = 1;
# Line 110  Line 165 
165          pEnc->mbParam.edged_width = 16 * pEnc->mbParam.mb_width + 2 * EDGE_SIZE;          pEnc->mbParam.edged_width = 16 * pEnc->mbParam.mb_width + 2 * EDGE_SIZE;
166          pEnc->mbParam.edged_height = 16 * pEnc->mbParam.mb_height + 2 * EDGE_SIZE;          pEnc->mbParam.edged_height = 16 * pEnc->mbParam.mb_height + 2 * EDGE_SIZE;
167    
168            pEnc->mbParam.fbase = pParam->fbase;
169            pEnc->mbParam.fincr = pParam->fincr;
170    
171          pEnc->sStat.fMvPrevSigma = -1;          pEnc->sStat.fMvPrevSigma = -1;
172    
173          /* Fill rate control parameters */          /* Fill rate control parameters */
174    
175          pEnc->mbParam.quant = 4;          pEnc->bitrate = pParam->rc_bitrate;
   
         pEnc->bitrate = pParam->bitrate;  
176    
177          pEnc->iFrameNum = 0;          pEnc->iFrameNum = 0;
178          pEnc->iMaxKeyInterval = pParam->max_key_interval;          pEnc->iMaxKeyInterval = pParam->max_key_interval;
179    
180          /* try to allocate memory */          /* try to allocate frame memory */
181    
182          pEnc->sCurrent.y        =       pEnc->sCurrent.u        =       pEnc->sCurrent.v        = NULL;          pEnc->current = NULL;
183          pEnc->sReference.y      =       pEnc->sReference.u      =       pEnc->sReference.v      = NULL;          pEnc->reference = NULL;
184          pEnc->vInterH.y         =       pEnc->vInterH.u         =       pEnc->vInterH.v         = NULL;          if ( (pEnc->current = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE)) == NULL ||
185          pEnc->vInterV.y         =       pEnc->vInterV.u         =       pEnc->vInterV.v         = NULL;                   (pEnc->reference = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE)) == NULL)
186          pEnc->vInterVf.y        =       pEnc->vInterVf.u        =       pEnc->vInterVf.v        = NULL;          {
187          pEnc->vInterHV.y        =       pEnc->vInterHV.u        =       pEnc->vInterHV.v        = NULL;                  if (pEnc->current) xvid_free(pEnc->current);
188          pEnc->vInterHVf.y       =       pEnc->vInterHVf.u       =       pEnc->vInterHVf.v       = NULL;                  xvid_free(pEnc);
189                    return XVID_ERR_MEMORY;
190            }
191    
192            /* try to allocate mb memory */
193    
194            pEnc->current->mbs = NULL;
195            pEnc->reference->mbs = NULL;
196    
197          pEnc->pMBs = NULL;          if ((pEnc->current->mbs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL ||
198                    (pEnc->reference->mbs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL)
199            {
200                    if (pEnc->current->mbs) xvid_free(pEnc->current->mbs);
201                    xvid_free(pEnc->current);
202                    xvid_free(pEnc->reference);
203                    xvid_free(pEnc);
204            }
205    
206          if (image_create(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||          /* try to allocate image memory */
207                  image_create(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||  
208    #ifdef _DEBUG
209            image_null(&pEnc->sOriginal);
210    #endif
211    #ifdef BFRAMES
212            image_null(&pEnc->f_refh);
213            image_null(&pEnc->f_refv);
214            image_null(&pEnc->f_refhv);
215    #endif
216            image_null(&pEnc->current->image);
217            image_null(&pEnc->reference->image);
218            image_null(&pEnc->vInterH);
219            image_null(&pEnc->vInterV);
220            image_null(&pEnc->vInterVf);
221            image_null(&pEnc->vInterHV);
222            image_null(&pEnc->vInterHVf);
223    
224            if (
225    #ifdef _DEBUG
226                    image_create(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
227    #endif
228    #ifdef BFRAMES
229                    image_create(&pEnc->f_refh, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
230                    image_create(&pEnc->f_refv, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
231                    image_create(&pEnc->f_refhv, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
232    #endif
233                    image_create(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
234                    image_create(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
235                  image_create(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||                  image_create(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
236                  image_create(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||                  image_create(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
237                  image_create(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||                  image_create(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
238                  image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||                  image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
239                  image_create(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||                  image_create(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)
                 (pEnc->pMBs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL)  
240          {          {
241                  image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  #ifdef _DEBUG
242                  image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
243    #endif
244    #ifdef BFRAMES
245                    image_destroy(&pEnc->f_refh, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
246                    image_destroy(&pEnc->f_refv, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
247                    image_destroy(&pEnc->f_refhv, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
248    #endif
249                    image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
250                    image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
251                  image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
252                  image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
253                  image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
254                  image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
255                  image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);                  image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
256                  if (pEnc)  
257                  {                  xvid_free(pEnc->current);
258                    xvid_free(pEnc->reference);
259                          xvid_free(pEnc);                          xvid_free(pEnc);
                 }  
260                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
261          }          }
262    
263          // init macroblock array  // ==============================================================================
264          for (i = 0; i < pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; i++)  #ifdef BFRAMES
265    
266            // TODO: handle malloc() == NULL
267            pEnc->max_bframes = pParam->max_bframes;
268            pEnc->bquant_ratio = pParam->bquant_ratio;
269            if (pEnc->max_bframes > 0)
270          {          {
271                  pEnc->pMBs[i].dquant = NO_CHANGE;                  int n;
272    
273                    pEnc->bframes = malloc(pEnc->max_bframes * sizeof(FRAMEINFO *));
274    
275                    for (n = 0; n < pEnc->max_bframes; n++)
276                    {
277                            pEnc->bframes[n] = malloc(sizeof(FRAMEINFO));
278                            pEnc->bframes[n]->mbs = malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height);
279    
280                            if (image_create(&pEnc->bframes[n]->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)
281                            {
282                                    return XVID_ERR_MEMORY;
283          }          }
284                    }
285            }
286            pEnc->bframenum_head = 0;
287            pEnc->bframenum_tail = 0;
288            pEnc->flush_bframes = 0;
289    
290            pEnc->mbParam.m_seconds = 0;
291            pEnc->mbParam.m_ticks = 0;
292    #endif
293    
294    
295    // ==============================================================================
296    
297    
298          pParam->handle = (void *)pEnc;          pParam->handle = (void *)pEnc;
299    
300          if (pParam->bitrate)          if (pParam->rc_bitrate)
301          {          {
302                  RateControlInit(pParam->bitrate, pParam->rc_buffersize, pParam->fbase * 100 / pParam->fincr,                  RateControlInit(pParam->rc_bitrate, pParam->rc_reaction_delay_factor,
303                            pParam->rc_averaging_period, pParam->rc_buffer, pParam->fbase * 1000 / pParam->fincr,
304                                  pParam->max_quantizer, pParam->min_quantizer);                                  pParam->max_quantizer, pParam->min_quantizer);
305          }          }
306    
         create_vlc_tables();  
307          init_timer();          init_timer();
308    
309          return XVID_ERR_OK;          return XVID_ERR_OK;
# Line 180  Line 313 
313  int encoder_destroy(Encoder * pEnc)  int encoder_destroy(Encoder * pEnc)
314  {  {
315          ENC_CHECK(pEnc);          ENC_CHECK(pEnc);
         ENC_CHECK(pEnc->sCurrent.y);  
         ENC_CHECK(pEnc->sReference.y);  
316    
317          xvid_free(pEnc->pMBs);  // =================================================================
318          image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);  #ifdef BFRAMES
319          image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          if (pEnc->max_bframes > 0)
320            {
321                    int n;
322                    for (n = 0; n < pEnc->max_bframes; n++)
323                    {
324                            image_destroy(&pEnc->bframes[n]->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
325                            free(pEnc->bframes[n]->mbs);
326                            free(pEnc->bframes[n]);
327                    }
328                    free(pEnc->bframes);
329            }
330    #endif BFRAMES
331    //====================================================================
332    
333            image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
334            image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
335          image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
336          image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
337            image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
338          image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);          image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
339            image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
340    #ifdef BFRAMES
341            image_destroy(&pEnc->f_refh, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
342            image_destroy(&pEnc->f_refv, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
343            image_destroy(&pEnc->f_refhv, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
344    #endif
345    #ifdef _DEBUG
346                    image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
347    #endif
348            xvid_free(pEnc->current->mbs);
349            xvid_free(pEnc->current);
350    
351            xvid_free(pEnc->reference->mbs);
352            xvid_free(pEnc->reference);
353    
354          xvid_free(pEnc);          xvid_free(pEnc);
355            return XVID_ERR_OK;
356    }
357    
         destroy_vlc_tables();  
358    
359    
360    // ==================================================================
361    #ifdef BFRAMES
362    int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult)
363    {
364            uint16_t x, y;
365            Bitstream bs;
366            uint32_t bits;
367    
368            ENC_CHECK(pEnc);
369            ENC_CHECK(pFrame);
370    
371            start_global_timer();
372    
373            BitstreamInit(&bs, pFrame->bitstream, 0);
374    
375    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376    // bframe "flush" code
377    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378    
379            if ((pFrame->image == NULL || pEnc->flush_bframes) &&
380                    pEnc->bframenum_head < pEnc->bframenum_tail)
381            {
382    
383                    if (pEnc->flush_bframes == 0)
384                    {
385                            // we have reached end of stream without getting a future reference
386                            // .. so encode last final frame a pframe
387                            dprintf("--- PFRAME (final frame correction) --- ");
388                            pEnc->bframenum_tail--;
389                            SWAP(pEnc->current, pEnc->reference);
390    
391                            SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_tail]);
392    
393                            FrameCodeP(pEnc, &bs, &bits, 1, 0);
394    
395                            BitstreamPad(&bs);
396                            pFrame->length = BitstreamLength(&bs);
397                            pFrame->input_consumed = 0;
398                            pFrame->intra = 0;
399          return XVID_ERR_OK;          return XVID_ERR_OK;
400  }  }
401    
402                    dprintf("--- BFRAME (flush) --- ");
403                    FrameCodeB(pEnc,
404                            pEnc->bframes[pEnc->bframenum_head],
405                             &bs, &bits);
406                    pEnc->bframenum_head++;
407    
408    
409                    BitstreamPad(&bs);
410                    pFrame->length = BitstreamLength(&bs);
411                    pFrame->input_consumed = 0;
412                    pFrame->intra = 0;
413                    return XVID_ERR_OK;
414            }
415    
416            if (pFrame->image == NULL)
417            {
418                    pFrame->length = 0;
419                    pFrame->input_consumed = 1;
420                    pFrame->intra = 0;
421                    return XVID_ERR_OK;
422            }
423    
424            if (pEnc->bframenum_head > 0)
425            {
426                    pEnc->bframenum_head = pEnc->bframenum_tail = 0;
427            }
428    
429            pEnc->flush_bframes = 0;
430    
431    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432    
433            SWAP(pEnc->current, pEnc->reference);
434    
435            pEnc->current->quant = (pFrame->quant == 0) ? RateControlGetQ(0) : pFrame->quant;
436    
437            if(pEnc->current->quant < 1)
438                    pEnc->current->quant = 1;
439    
440            if(pEnc->current->quant > 31)
441                    pEnc->current->quant = 31;
442    
443            pEnc->current->global_flags = pFrame->general;
444            pEnc->current->motion_flags = pFrame->motion;
445            pEnc->current->seconds = pEnc->mbParam.m_seconds;
446            pEnc->current->ticks = pEnc->mbParam.m_ticks;
447            //@@@ TODO: dyanmic fcode (in both directions)
448            pEnc->current->fcode = pEnc->mbParam.m_fcode;
449            pEnc->current->bcode = pEnc->mbParam.m_fcode;
450    
451            start_timer();
452            if (image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,
453                            pFrame->image, pFrame->colorspace))
454            {
455                    return XVID_ERR_FORMAT;
456            }
457            stop_conv_timer();
458    
459    #ifdef _DEBUG
460            image_copy(&pEnc->sOriginal, &pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.height);
461    #endif
462    
463    
464    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465    // lumi masking
466    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
467    
468            if ((pEnc->current->global_flags & XVID_LUMIMASKING))
469            {
470                    int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE);
471    
472                    pEnc->current->quant = adaptive_quantization(pEnc->current->image.y,
473                                                                pEnc->mbParam.edged_width,  // stride
474                                                                temp_dquants,
475                                                                pEnc->current->quant,
476                                                                pEnc->current->quant,       // min_quant
477                                                                2*pEnc->current->quant,     // max_quant
478                                                                pEnc->mbParam.mb_width,
479                                                                pEnc->mbParam.mb_height);
480    
481                    for (y = 0; y < pEnc->mbParam.mb_height; y++)
482                            for (x = 0; x < pEnc->mbParam.mb_width; x++)
483                            {
484                                    MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
485                                    pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];
486                            }
487                    xvid_free(temp_dquants);
488            }
489    
490    
491    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
492    // ivop/pvop/bvop selection
493    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494    
495            if (pEnc->iFrameNum == 0 ||
496                    pFrame->intra == 1 ||
497                    (pFrame->intra < 0 && (pEnc->iMaxKeyInterval > 0 && pEnc->iFrameNum >= pEnc->iMaxKeyInterval)) ||
498                    image_mad(&pEnc->reference->image, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.width, pEnc->mbParam.height) > 30)
499            {
500                    dprintf("--- IFRAME ---");
501    
502                    FrameCodeI(pEnc, &bs, &bits);
503    
504                    pFrame->intra = 1;
505                    pEnc->flush_bframes = 1;
506    
507                    /* note: sequences like "IIBB" decode fine with msfdam but,
508                       go screwy with divx5.00 */
509            }
510            else if (pEnc->bframenum_tail >= pEnc->max_bframes)
511            {
512                    dprintf("--- PFRAME ---");
513    
514                    FrameCodeP(pEnc, &bs, &bits, 1, 0);
515                    pFrame->intra = 0;
516                    pEnc->flush_bframes = 1;
517            }
518            else
519            {
520                    dprintf("--- BFRAME (store) ---  head=%i tail=%i", pEnc->bframenum_head, pEnc->bframenum_tail);
521    
522                    if (pFrame->bquant < 1)
523                    {
524                            pEnc->current->quant = ((pEnc->reference->quant + pEnc->current->quant) * pEnc->bquant_ratio) / 200;
525                    }
526                    else
527                    {
528                            pEnc->current->quant = pFrame->bquant;
529                    }
530    
531                    // store frame into bframe buffer & swap ref back to current
532                    SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_tail]);
533                    SWAP(pEnc->current, pEnc->reference);
534    
535                    pEnc->bframenum_tail++;
536    
537                    pFrame->intra = 0;
538                    pFrame->length = 0;
539                    pFrame->input_consumed = 1;
540    
541                    pEnc->mbParam.m_ticks += pEnc->mbParam.fincr;
542                    if (pEnc->mbParam.m_ticks > pEnc->mbParam.fbase)
543                    {
544                            pEnc->mbParam.m_seconds++;
545                            pEnc->mbParam.m_ticks = 0;
546                    }
547                    return XVID_ERR_OK;
548            }
549    
550            BitstreamPad(&bs);
551            pFrame->length = BitstreamLength(&bs);
552    
553            if (pResult)
554            {
555                    pResult->quant = pEnc->current->quant;
556                    pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
557                    pResult->kblks = pEnc->sStat.kblks;
558                    pResult->mblks = pEnc->sStat.mblks;
559                    pResult->ublks = pEnc->sStat.ublks;
560            }
561    
562    #ifdef _DEBUG
563            psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width,
564                                    pEnc->mbParam.width, pEnc->mbParam.height);
565    
566            sprintf(temp, "PSNR: %f\n", psnr);
567            DEBUG(temp);
568    #endif
569    
570            if (pFrame->quant == 0)
571            {
572                    RateControlUpdate(pEnc->current->quant, pFrame->length, pFrame->intra);
573            }
574    
575            pEnc->iFrameNum++;
576            pEnc->mbParam.m_ticks += pEnc->mbParam.fincr;
577            if (pEnc->mbParam.m_ticks > pEnc->mbParam.fbase)
578            {
579                    pEnc->mbParam.m_seconds++;
580                    pEnc->mbParam.m_ticks = 0;
581            }
582            pFrame->input_consumed = 1;
583    
584            stop_global_timer();
585            write_timer();
586    
587            return XVID_ERR_OK;
588    }
589    // ==================================================================
590    #else
591  int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult)  int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult)
592  {  {
593          uint16_t x, y;          uint16_t x, y;
594          Bitstream bs;          Bitstream bs;
595          uint32_t bits;          uint32_t bits;
596          uint16_t write_vol_header = 0;          uint16_t write_vol_header = 0;
597    #ifdef _DEBUG
598            float psnr;
599            uint8_t temp[100];
600    #endif
601    
602          start_global_timer();          start_global_timer();
603    
# Line 210  Line 606 
606          ENC_CHECK(pFrame->bitstream);          ENC_CHECK(pFrame->bitstream);
607          ENC_CHECK(pFrame->image);          ENC_CHECK(pFrame->image);
608    
609          pEnc->mbParam.global_flags = pFrame->general;          SWAP(pEnc->current, pEnc->reference);
610          pEnc->mbParam.motion_flags = pFrame->motion;  
611            pEnc->current->global_flags = pFrame->general;
612            pEnc->current->motion_flags = pFrame->motion;
613            pEnc->mbParam.hint = &pFrame->hint;
614    
615          start_timer();          start_timer();
616          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,
617                          pFrame->image, pFrame->colorspace))                          pFrame->image, pFrame->colorspace))
618          {          {
619                  return XVID_ERR_FORMAT;                  return XVID_ERR_FORMAT;
620          }          }
621          stop_conv_timer();          stop_conv_timer();
622    
623    #ifdef _DEBUG
624            image_copy(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height);
625    #endif
626    
627          EMMS();          EMMS();
628    
629          BitstreamInit(&bs, pFrame->bitstream, 0);          BitstreamInit(&bs, pFrame->bitstream, 0);
630    
631          if (pFrame->quant == 0)          if (pFrame->quant == 0)
632          {          {
633                  pEnc->mbParam.quant = RateControlGetQ(0);                  pEnc->current->quant = RateControlGetQ(0);
634          }          }
635          else          else
636          {          {
637                  pEnc->mbParam.quant = pFrame->quant;                  pEnc->current->quant = pFrame->quant;
638          }          }
639    
640          if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0)          if ((pEnc->current->global_flags & XVID_LUMIMASKING))
641          {          {
642                  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);
643    
644                  pEnc->mbParam.quant = adaptive_quantization(pEnc->sCurrent.y,                  pEnc->current->quant = adaptive_quantization(pEnc->current->image.y,
645                                                              pEnc->mbParam.width,                                                              pEnc->mbParam.edged_width,  // stride
646                                                              temp_dquants,                                                              temp_dquants,
647                                                              pEnc->mbParam.quant,                                                              pEnc->current->quant,
648                                                              pEnc->mbParam.quant,                                                              pEnc->current->quant,       // min_quant
649                                                              2*pEnc->mbParam.quant,                                                              2*pEnc->current->quant,     // max_quant
650                                                              pEnc->mbParam.mb_width,                                                              pEnc->mbParam.mb_width,
651                                                              pEnc->mbParam.mb_height);                                                              pEnc->mbParam.mb_height);
652    
653                  for (y = 0; y < pEnc->mbParam.mb_height; y++)                  for (y = 0; y < pEnc->mbParam.mb_height; y++)
654                          for (x = 0; x < pEnc->mbParam.mb_width; x++)                          for (x = 0; x < pEnc->mbParam.mb_width; x++)
655                          {                          {
656                                  MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];                                  MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
657                                  pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];                                  pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];
658                          }                          }
659                  xvid_free(temp_dquants);                  xvid_free(temp_dquants);
660          }          }
661    
662          if(pEnc->mbParam.global_flags & XVID_H263QUANT) {          if (pEnc->current->global_flags & XVID_H263QUANT) {
663                  if(pEnc->mbParam.quant_type != H263_QUANT)                  if(pEnc->mbParam.m_quant_type != H263_QUANT)
664                          write_vol_header = 1;                          write_vol_header = 1;
665                  pEnc->mbParam.quant_type = H263_QUANT;                  pEnc->mbParam.m_quant_type = H263_QUANT;
666          }          }
667          else if(pEnc->mbParam.global_flags & XVID_MPEGQUANT) {          else if(pEnc->current->global_flags & XVID_MPEGQUANT) {
668                  int ret1, ret2;                  int ret1, ret2;
669    
670                  ret1 = ret2 = 0;                  ret1 = ret2 = 0;
671    
672                  if(pEnc->mbParam.quant_type != MPEG4_QUANT)                  if(pEnc->mbParam.m_quant_type != MPEG4_QUANT)
673                          write_vol_header = 1;                          write_vol_header = 1;
674    
675                  pEnc->mbParam.quant_type = MPEG4_QUANT;                  pEnc->mbParam.m_quant_type = MPEG4_QUANT;
676    
677                  if ((pEnc->mbParam.global_flags & XVID_CUSTOM_QMATRIX) > 0) {                  if ((pEnc->current->global_flags & XVID_CUSTOM_QMATRIX) > 0) {
678                          if(pFrame->quant_intra_matrix != NULL)                          if(pFrame->quant_intra_matrix != NULL)
679                                  ret1 = set_intra_matrix(pFrame->quant_intra_matrix);                                  ret1 = set_intra_matrix(pFrame->quant_intra_matrix);
680                          if(pFrame->quant_inter_matrix != NULL)                          if(pFrame->quant_inter_matrix != NULL)
# Line 309  Line 712 
712    
713          if (pResult)          if (pResult)
714          {          {
715                  pResult->quant = pEnc->mbParam.quant;                  pResult->quant = pEnc->current->quant;
716                  pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);                  pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
717                  pResult->kblks = pEnc->sStat.kblks;                  pResult->kblks = pEnc->sStat.kblks;
718                  pResult->mblks = pEnc->sStat.mblks;                  pResult->mblks = pEnc->sStat.mblks;
# Line 320  Line 723 
723    
724          if (pFrame->quant == 0)          if (pFrame->quant == 0)
725          {          {
726                  RateControlUpdate(pEnc->mbParam.quant, pFrame->length, pFrame->intra);                  RateControlUpdate(pEnc->current->quant, pFrame->length, pFrame->intra);
727          }          }
728    
729    #ifdef _DEBUG
730            psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width,
731                                    pEnc->mbParam.width, pEnc->mbParam.height);
732    
733            sprintf(temp, "PSNR: %f\n", psnr);
734            DEBUG(temp);
735    #endif
736    
737          pEnc->iFrameNum++;          pEnc->iFrameNum++;
         image_swap(&pEnc->sCurrent, &pEnc->sReference);  
738    
739          stop_global_timer();          stop_global_timer();
740          write_timer();          write_timer();
741    
742          return XVID_ERR_OK;          return XVID_ERR_OK;
743  }  }
744    #endif
745    
746    
747  static __inline void CodeIntraMB(Encoder *pEnc, MACROBLOCK *pMB) {  static __inline void CodeIntraMB(Encoder *pEnc, MACROBLOCK *pMB) {
748    
749          pMB->mode = MODE_INTRA;          pMB->mode = MODE_INTRA;
750    
751          if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) {          /* zero mv statistics */
752            pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
753            pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
754            pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
755            pMB->sad16 = 0;
756    
757            if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
758                  if(pMB->dquant != NO_CHANGE)                  if(pMB->dquant != NO_CHANGE)
759                  {                  {
760                          pMB->mode = MODE_INTRA_Q;                          pMB->mode = MODE_INTRA_Q;
761                          pEnc->mbParam.quant += DQtab[pMB->dquant];                          pEnc->current->quant += DQtab[pMB->dquant];
762    
763                            if (pEnc->current->quant > 31) pEnc->current->quant = 31;
764                            if (pEnc->current->quant < 1) pEnc->current->quant = 1;
765                    }
766            }
767    
768            pMB->quant = pEnc->current->quant;
769    }
770    
771    
772    #define FCODEBITS       3
773    #define MODEBITS        5
774    
775    void HintedMESet(Encoder * pEnc, int * intra)
776    {
777            HINTINFO * hint;
778            Bitstream bs;
779            int length, high;
780            uint32_t x, y;
781    
782            hint = pEnc->mbParam.hint;
783    
784            if (hint->rawhints)
785            {
786                    *intra = hint->mvhint.intra;
787            }
788            else
789            {
790                    BitstreamInit(&bs, hint->hintstream, hint->hintlength);
791                    *intra = BitstreamGetBit(&bs);
792            }
793    
794            if (*intra)
795            {
796                    return;
797            }
798    
799            pEnc->current->fcode = (hint->rawhints) ? hint->mvhint.fcode : BitstreamGetBits(&bs, FCODEBITS);
800    
801            length  = pEnc->current->fcode + 5;
802            high    = 1 << (length - 1);
803    
804            for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
805            {
806                    for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
807                    {
808                            MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
809                            MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
810                            VECTOR pred[4];
811                            VECTOR tmp;
812                            int32_t dummy[4];
813                            int vec;
814    
815                            pMB->mode = (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs, MODEBITS);
816    
817                            pMB->mode = (pMB->mode == MODE_INTER_Q) ? MODE_INTER : pMB->mode;
818                            pMB->mode = (pMB->mode == MODE_INTRA_Q) ? MODE_INTRA : pMB->mode;
819    
820                            if (pMB->mode == MODE_INTER)
821                            {
822                                    tmp.x  = (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs, length);
823                                    tmp.y  = (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs, length);
824                                    tmp.x -= (tmp.x >= high) ? high*2 : 0;
825                                    tmp.y -= (tmp.y >= high) ? high*2 : 0;
826    
827                                    get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, 0, pred, dummy);
828    
829                          if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31;                                  for (vec=0 ; vec<4 ; ++vec)
830                          if (pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1;                                  {
831                                            pMB->mvs[vec].x  = tmp.x;
832                                            pMB->mvs[vec].y  = tmp.y;
833                                            pMB->pmvs[vec].x = pMB->mvs[0].x - pred[0].x;
834                                            pMB->pmvs[vec].y = pMB->mvs[0].y - pred[0].y;
835                  }                  }
836          }          }
837                            else if (pMB->mode == MODE_INTER4V)
838                            {
839                                    for (vec=0 ; vec<4 ; ++vec)
840                                    {
841                                            tmp.x  = (hint->rawhints) ? bhint->mvs[vec].x : BitstreamGetBits(&bs, length);
842                                            tmp.y  = (hint->rawhints) ? bhint->mvs[vec].y : BitstreamGetBits(&bs, length);
843                                            tmp.x -= (tmp.x >= high) ? high*2 : 0;
844                                            tmp.y -= (tmp.y >= high) ? high*2 : 0;
845    
846          pMB->quant = pEnc->mbParam.quant;                                          get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, vec, pred, dummy);
847    
848                                            pMB->mvs[vec].x  = tmp.x;
849                                            pMB->mvs[vec].y  = tmp.y;
850                                            pMB->pmvs[vec].x = pMB->mvs[vec].x - pred[0].x;
851                                            pMB->pmvs[vec].y = pMB->mvs[vec].y - pred[0].y;
852                                    }
853                            }
854                            else    // intra / stuffing / not_coded
855                            {
856                                    for (vec=0 ; vec<4 ; ++vec)
857                                    {
858                                            pMB->mvs[vec].x  = pMB->mvs[vec].y  = 0;
859                                    }
860                            }
861    
862                            if (pMB->mode == MODE_INTER4V &&
863                                    (pEnc->current->global_flags & XVID_LUMIMASKING) && pMB->dquant != NO_CHANGE)
864                            {
865                                    pMB->mode = MODE_INTRA;
866    
867                                    for (vec=0 ; vec<4 ; ++vec)
868                                    {
869                                            pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
870                                    }
871                            }
872                    }
873            }
874    }
875    
876    
877    void HintedMEGet(Encoder * pEnc, int intra)
878    {
879            HINTINFO * hint;
880            Bitstream bs;
881            uint32_t x, y;
882            int length, high;
883    
884            hint = pEnc->mbParam.hint;
885    
886            if (hint->rawhints)
887            {
888                    hint->mvhint.intra = intra;
889            }
890            else
891            {
892                    BitstreamInit(&bs, hint->hintstream, 0);
893                    BitstreamPutBit(&bs, intra);
894            }
895    
896            if (intra)
897            {
898                    if (!hint->rawhints)
899                    {
900                            BitstreamPad(&bs);
901                            hint->hintlength = BitstreamLength(&bs);
902                    }
903                    return;
904            }
905    
906            length  = pEnc->current->fcode + 5;
907            high    = 1 << (length - 1);
908    
909            if (hint->rawhints)
910            {
911                    hint->mvhint.fcode = pEnc->current->fcode;
912            }
913            else
914            {
915                    BitstreamPutBits(&bs, pEnc->current->fcode, FCODEBITS);
916            }
917    
918            for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
919            {
920                    for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
921                    {
922                            MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
923                            MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
924                            VECTOR tmp;
925    
926                            if (hint->rawhints)
927                            {
928                                    bhint->mode = pMB->mode;
929                            }
930                            else
931                            {
932                                    BitstreamPutBits(&bs, pMB->mode, MODEBITS);
933                            }
934    
935                            if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)
936                            {
937                                    tmp.x  = pMB->mvs[0].x;
938                                    tmp.y  = pMB->mvs[0].y;
939                                    tmp.x += (tmp.x < 0) ? high*2 : 0;
940                                    tmp.y += (tmp.y < 0) ? high*2 : 0;
941    
942                                    if (hint->rawhints)
943                                    {
944                                            bhint->mvs[0].x = tmp.x;
945                                            bhint->mvs[0].y = tmp.y;
946                                    }
947                                    else
948                                    {
949                                            BitstreamPutBits(&bs, tmp.x, length);
950                                            BitstreamPutBits(&bs, tmp.y, length);
951                                    }
952                            }
953                            else if (pMB->mode == MODE_INTER4V)
954                            {
955                                    int vec;
956    
957                                    for (vec=0 ; vec<4 ; ++vec)
958                                    {
959                                            tmp.x  = pMB->mvs[vec].x;
960                                            tmp.y  = pMB->mvs[vec].y;
961                                            tmp.x += (tmp.x < 0) ? high*2 : 0;
962                                            tmp.y += (tmp.y < 0) ? high*2 : 0;
963    
964                                            if (hint->rawhints)
965                                            {
966                                                    bhint->mvs[vec].x = tmp.x;
967                                                    bhint->mvs[vec].y = tmp.y;
968                                            }
969                                            else
970                                            {
971                                                    BitstreamPutBits(&bs, tmp.x, length);
972                                                    BitstreamPutBits(&bs, tmp.y, length);
973                                            }
974                                    }
975                            }
976                    }
977            }
978    
979            if (!hint->rawhints)
980            {
981                    BitstreamPad(&bs);
982                    hint->hintlength = BitstreamLength(&bs);
983            }
984  }  }
985    
986    
# Line 361  Line 993 
993          uint16_t x, y;          uint16_t x, y;
994    
995          pEnc->iFrameNum = 0;          pEnc->iFrameNum = 0;
996          pEnc->mbParam.rounding_type = 1;          pEnc->mbParam.m_rounding_type = 1;
997          pEnc->mbParam.coding_type = I_VOP;          pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
998            pEnc->current->coding_type = I_VOP;
999    
1000          BitstreamWriteVolHeader(bs, &pEnc->mbParam);          BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
1001          BitstreamWriteVopHeader(bs, &pEnc->mbParam);          BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
1002    
1003          *pBits = BitstreamPos(bs);          *pBits = BitstreamPos(bs);
1004    
# Line 376  Line 1009 
1009          for (y = 0; y < pEnc->mbParam.mb_height; y++)          for (y = 0; y < pEnc->mbParam.mb_height; y++)
1010                  for (x = 0; x < pEnc->mbParam.mb_width; x++)                  for (x = 0; x < pEnc->mbParam.mb_width; x++)
1011                  {                  {
1012                          MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];                          MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1013    
1014                          CodeIntraMB(pEnc, pMB);                          CodeIntraMB(pEnc, pMB);
1015    
1016                          MBTransQuantIntra(&pEnc->mbParam, pMB, x, y, dct_codes, qcoeff, &pEnc->sCurrent);                          MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
1017    
1018                          start_timer();                          start_timer();
1019                          MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs);                          MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
1020                          stop_prediction_timer();                          stop_prediction_timer();
1021    
1022                          start_timer();                          start_timer();
1023                          MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat);                          MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
1024                          stop_coding_timer();                          stop_coding_timer();
1025                  }                  }
1026    
# Line 397  Line 1030 
1030          pEnc->sStat.fMvPrevSigma = -1;          pEnc->sStat.fMvPrevSigma = -1;
1031          pEnc->sStat.iMvSum = 0;          pEnc->sStat.iMvSum = 0;
1032          pEnc->sStat.iMvCount = 0;          pEnc->sStat.iMvCount = 0;
1033          pEnc->mbParam.fixed_code = 2;          pEnc->mbParam.m_fcode = 2;
1034    
1035            if (pEnc->current->global_flags & XVID_HINTEDME_GET)
1036            {
1037                    HintedMEGet(pEnc, 1);
1038            }
1039    
1040          return 1;                                        // intra          return 1;                                        // intra
1041  }  }
# Line 415  Line 1053 
1053          int iLimit;          int iLimit;
1054          uint32_t x, y;          uint32_t x, y;
1055          int iSearchRange;          int iSearchRange;
1056          bool bIntra;          int bIntra;
1057    
1058          IMAGE *pCurrent = &pEnc->sCurrent;          /* IMAGE *pCurrent = &pEnc->current->image; */
1059          IMAGE *pRef = &pEnc->sReference;          IMAGE *pRef = &pEnc->reference->image;
1060    
1061          start_timer();          start_timer();
1062          image_setedges(pRef,          image_setedges(pRef,
# Line 426  Line 1064 
1064                         pEnc->mbParam.edged_height,                         pEnc->mbParam.edged_height,
1065                         pEnc->mbParam.width,                         pEnc->mbParam.width,
1066                         pEnc->mbParam.height,                         pEnc->mbParam.height,
1067                         pEnc->mbParam.global_flags & XVID_INTERLACING);                         pEnc->current->global_flags & XVID_INTERLACING);
1068          stop_edges_timer();          stop_edges_timer();
1069    
1070          pEnc->mbParam.rounding_type = 1 - pEnc->mbParam.rounding_type;          pEnc->mbParam.m_rounding_type = 1 - pEnc->mbParam.m_rounding_type;
1071            pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
1072            pEnc->current->fcode = pEnc->mbParam.m_fcode;
1073    
1074          if (!force_inter)          if (!force_inter)
1075                  iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD);                  iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD);
1076          else          else
1077                  iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;                  iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
1078    
1079          if ((pEnc->mbParam.global_flags & XVID_HALFPEL) > 0) {          if ((pEnc->current->global_flags & XVID_HALFPEL)) {
1080                  start_timer();                  start_timer();
1081                  image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,                  image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1082                                    pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,                                    pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
1083                                    pEnc->mbParam.rounding_type);                                    pEnc->current->rounding_type);
1084                  stop_inter_timer();                  stop_inter_timer();
1085          }          }
1086    
1087          start_timer();          start_timer();
1088          bIntra = MotionEstimation(pEnc->pMBs, &pEnc->mbParam, &pEnc->sReference,          if (pEnc->current->global_flags & XVID_HINTEDME_SET)
1089                                    &pEnc->vInterH, &pEnc->vInterV,          {
1090                                    &pEnc->vInterHV, &pEnc->sCurrent, iLimit);                  HintedMESet(pEnc, &bIntra);
1091            }
1092            else
1093            {
1094                    bIntra = MotionEstimation(
1095                            &pEnc->mbParam,
1096                            pEnc->current,
1097                            pEnc->reference,
1098                            &pEnc->vInterH,
1099                            &pEnc->vInterV,
1100                            &pEnc->vInterHV,
1101                            iLimit);
1102            }
1103          stop_motion_timer();          stop_motion_timer();
1104    
1105          if (bIntra == 1)          if (bIntra == 1)
1106            {
1107                  return FrameCodeI(pEnc, bs, pBits);                  return FrameCodeI(pEnc, bs, pBits);
1108            }
1109    
1110          pEnc->mbParam.coding_type = P_VOP;          pEnc->current->coding_type = P_VOP;
1111    
1112          if(vol_header)          if(vol_header)
1113                  BitstreamWriteVolHeader(bs, &pEnc->mbParam);                  BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
1114    
1115          BitstreamWriteVopHeader(bs, &pEnc->mbParam);          BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
1116    
1117          *pBits = BitstreamPos(bs);          *pBits = BitstreamPos(bs);
1118    
# Line 471  Line 1125 
1125          {          {
1126                  for(x = 0; x < pEnc->mbParam.mb_width; x++)                  for(x = 0; x < pEnc->mbParam.mb_width; x++)
1127                  {                  {
1128                          MACROBLOCK * pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width];                          MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1129    
1130                          bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);                          bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
1131    
# Line 480  Line 1134 
1134                                  start_timer();                                  start_timer();
1135                                  MBMotionCompensation(pMB,                                  MBMotionCompensation(pMB,
1136                                                       x, y,                                                       x, y,
1137                                                       &pEnc->sReference,                                                       &pEnc->reference->image,
1138                                                       &pEnc->vInterH,                                                       &pEnc->vInterH,
1139                                                       &pEnc->vInterV,                                                       &pEnc->vInterV,
1140                                                       &pEnc->vInterHV,                                                       &pEnc->vInterHV,
1141                                                       &pEnc->sCurrent,                                                       &pEnc->current->image,
1142                                                       dct_codes,                                                       dct_codes,
1143                                                       pEnc->mbParam.width,                                                       pEnc->mbParam.width,
1144                                                       pEnc->mbParam.height,                                                       pEnc->mbParam.height,
1145                                                       pEnc->mbParam.edged_width,                                                       pEnc->mbParam.edged_width,
1146                                                       pEnc->mbParam.rounding_type);                                                       pEnc->current->rounding_type);
1147                                  stop_comp_timer();                                  stop_comp_timer();
1148    
1149                                  if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) {                                  if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
1150                                          if(pMB->dquant != NO_CHANGE) {                                          if(pMB->dquant != NO_CHANGE) {
1151                                                  pMB->mode = MODE_INTER_Q;                                                  pMB->mode = MODE_INTER_Q;
1152                                                  pEnc->mbParam.quant += DQtab[pMB->dquant];                                                  pEnc->current->quant += DQtab[pMB->dquant];
1153                                                  if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31;                                                  if (pEnc->current->quant > 31) pEnc->current->quant = 31;
1154                                                  else if(pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1;                                                  else if(pEnc->current->quant < 1) pEnc->current->quant = 1;
1155                                          }                                          }
1156                                  }                                  }
1157                                  pMB->quant = pEnc->mbParam.quant;                                  pMB->quant = pEnc->current->quant;
1158    
1159                                  pMB->field_pred = 0;                                  pMB->field_pred = 0;
1160    
1161                                  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);
1162                          }                          }
1163                          else                          else
1164                          {                          {
1165                                  CodeIntraMB(pEnc, pMB);                                  CodeIntraMB(pEnc, pMB);
1166                                  MBTransQuantIntra(&pEnc->mbParam, pMB, x, y, dct_codes, qcoeff, pCurrent);                                  MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
1167                          }                          }
1168    
1169                          start_timer();                          start_timer();
1170                          MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs);                          MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
1171                          stop_prediction_timer();                          stop_prediction_timer();
1172    
1173                          if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)                          if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)
# Line 534  Line 1188 
1188                          }                          }
1189    
1190                          start_timer();                          start_timer();
1191                          MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat);                          MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
1192                          stop_coding_timer();                          stop_coding_timer();
1193                  }                  }
1194          }          }
1195    
1196          emms();          emms();
1197    
1198            if (pEnc->current->global_flags & XVID_HINTEDME_GET)
1199            {
1200                    HintedMEGet(pEnc, 0);
1201            }
1202    
1203          if (pEnc->sStat.iMvCount == 0)          if (pEnc->sStat.iMvCount == 0)
1204                  pEnc->sStat.iMvCount = 1;                  pEnc->sStat.iMvCount = 1;
1205    
1206          fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);          fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);
1207    
1208          iSearchRange = 1 << (3 + pEnc->mbParam.fixed_code);          iSearchRange = 1 << (3 + pEnc->mbParam.m_fcode);
1209    
1210          if ((fSigma > iSearchRange / 3)          if ((fSigma > iSearchRange / 3)
1211              && (pEnc->mbParam.fixed_code <= 3)) // maximum search range 128              && (pEnc->mbParam.m_fcode <= 3))    // maximum search range 128
1212          {          {
1213                  pEnc->mbParam.fixed_code++;                  pEnc->mbParam.m_fcode++;
1214                  iSearchRange *= 2;                  iSearchRange *= 2;
1215          }          }
1216          else if ((fSigma < iSearchRange / 6)          else if ((fSigma < iSearchRange / 6)
1217                   && (pEnc->sStat.fMvPrevSigma >= 0)                   && (pEnc->sStat.fMvPrevSigma >= 0)
1218                   && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)                   && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)
1219                   && (pEnc->mbParam.fixed_code >= 2))    // minimum search range 16                   && (pEnc->mbParam.m_fcode >= 2))       // minimum search range 16
1220          {          {
1221                  pEnc->mbParam.fixed_code--;                  pEnc->mbParam.m_fcode--;
1222                  iSearchRange /= 2;                  iSearchRange /= 2;
1223          }          }
1224    
# Line 569  Line 1228 
1228    
1229          return 0;                                        // inter          return 0;                                        // inter
1230  }  }
1231    
1232    
1233    #ifdef BFRAMES
1234    static void FrameCodeB(Encoder * pEnc, FRAMEINFO * frame, Bitstream * bs, uint32_t *pBits)
1235    {
1236        int16_t dct_codes[6*64];
1237        int16_t qcoeff[6*64];
1238        uint32_t x, y;
1239            VECTOR forward;
1240            VECTOR backward;
1241    
1242        IMAGE *f_ref = &pEnc->reference->image;
1243            IMAGE *b_ref = &pEnc->current->image;
1244    
1245            // forward
1246            image_setedges(f_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height, frame->global_flags & XVID_INTERLACING);
1247            start_timer();
1248            image_interpolate(f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1249                    pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
1250            stop_inter_timer();
1251    
1252            // backward
1253            image_setedges(b_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height, frame->global_flags & XVID_INTERLACING);
1254        start_timer();
1255            image_interpolate(b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1256                    pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
1257            stop_inter_timer();
1258    
1259            start_timer();
1260            MotionEstimationBVOP(&pEnc->mbParam, frame,
1261                    pEnc->reference->mbs, f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1262                    pEnc->current->mbs, b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV);
1263    
1264    
1265            stop_motion_timer();
1266    
1267            /*if (test_quant_type(&pEnc->mbParam, pEnc->current))
1268            {
1269                    BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type);
1270            }*/
1271    
1272        frame->coding_type = B_VOP;
1273        BitstreamWriteVopHeader(bs, &pEnc->mbParam, frame);
1274    
1275        *pBits = BitstreamPos(bs);
1276    
1277        pEnc->sStat.iTextBits = 0;
1278        pEnc->sStat.iMvSum = 0;
1279        pEnc->sStat.iMvCount = 0;
1280            pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
1281    
1282    
1283        for (y = 0; y < pEnc->mbParam.mb_height; y++)
1284            {
1285                    // reset prediction
1286    
1287                    forward.x = 0;
1288                    forward.y = 0;
1289                    backward.x = 0;
1290                    backward.y = 0;
1291    
1292                    for (x = 0; x < pEnc->mbParam.mb_width; x++)
1293                    {
1294                            MACROBLOCK * f_mb = &pEnc->reference->mbs[x + y * pEnc->mbParam.mb_width];
1295                            MACROBLOCK * b_mb = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1296                            MACROBLOCK * mb = &frame->mbs[x + y * pEnc->mbParam.mb_width];
1297    
1298                            // decoder ignores mb when refence block is INTER(0,0), CBP=0
1299                            if (mb->mode == MODE_NOT_CODED)
1300                            {
1301                                    mb->mvs[0].x = 0;
1302                                    mb->mvs[0].y = 0;
1303                                    continue;
1304                            }
1305    
1306                            MBMotionCompensationBVOP(&pEnc->mbParam, mb, x, y, &frame->image,
1307                                            f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1308                                            b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1309                                            dct_codes);
1310    
1311                            mb->quant = frame->quant;
1312                            mb->cbp = MBTransQuantInter(&pEnc->mbParam, frame, mb, x, y, dct_codes, qcoeff);
1313                            //mb->cbp = MBTransQuantBVOP(&pEnc->mbParam, x, y, dct_codes, qcoeff, &frame->image, frame->quant);
1314    
1315    
1316                            if ((mb->mode == MODE_INTERPOLATE || mb->mode == MODE_DIRECT) &&
1317                                    mb->cbp == 0 &&
1318                                    mb->mvs[0].x == 0 &&
1319                                    mb->mvs[0].y == 0)
1320                            {
1321                                    mb->mode = 5;  // skipped
1322                            }
1323    
1324                            if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_FORWARD)
1325                            {
1326                                    mb->pmvs[0].x = mb->mvs[0].x - forward.x;
1327                                    mb->pmvs[0].y = mb->mvs[0].y - forward.y;
1328                                    forward.x = mb->mvs[0].x;
1329                                    forward.y = mb->mvs[0].y;
1330                            }
1331    
1332                            if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_BACKWARD)
1333                            {
1334                                    mb->b_pmvs[0].x = mb->b_mvs[0].x - backward.x;
1335                                    mb->b_pmvs[0].y = mb->b_mvs[0].y - backward.y;
1336                                    backward.x = mb->b_mvs[0].x;
1337                                    backward.y = mb->b_mvs[0].y;
1338                            }
1339    
1340    //                      printf("[%i %i] M=%i CBP=%i MVX=%i MVY=%i %i,%i  %i,%i\n", x, y, pMB->mode, pMB->cbp, pMB->mvs[0].x, bmb->pmvs[0].x, bmb->pmvs[0].y, forward.x, forward.y);
1341    
1342                            start_timer();
1343                            MBCodingBVOP(mb, qcoeff, frame->fcode, frame->bcode, bs, &pEnc->sStat);
1344                            stop_coding_timer();
1345                    }
1346            }
1347    
1348            emms();
1349    
1350            // TODO: dynamic fcode/bcode ???
1351    
1352            *pBits = BitstreamPos(bs) - *pBits;
1353    }
1354    #endif

Legend:
Removed from v.86  
changed lines
  Added in v.157

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