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

Diff of /xvidcore/src/divx4.c

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

revision 1.10, Sun Apr 28 20:03:14 2002 UTC revision 1.20, Sat Nov 16 23:38:16 2002 UTC
# Line 1  Line 1 
1  /**************************************************************************  /**************************************************************************
2   *   *
3   *      XVID MPEG-4 VIDEO CODEC   *      XVID MPEG-4 VIDEO CODEC
4   *      OpenDivx API wrapper   *  - OpenDivx API wrapper -
5   *   *
6   *      This program is an implementation of a part of one or more MPEG-4   *  Copyright(C) 2001-2002 Peter Ross <pross@xvid.org>
  *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  
  *      to use this software module in hardware or software products are  
  *      advised that its use may infringe existing patents or copyrights, and  
  *      any such use would be at such party's own risk.  The original  
  *      developer of this software module and his/her company, and subsequent  
  *      editors and their companies, will have no liability for use of this  
  *      software or modifications or derivatives thereof.  
7   *   *
8   *      This program is free software; you can redistribute it and/or modify   *  This file is part of XviD, a free MPEG-4 video encoder/decoder
9   *      it under the terms of the GNU General Public License as published by   *
10     *  XviD is free software; you can redistribute it and/or modify it
11     *  under the terms of the GNU General Public License as published by
12   *      the Free Software Foundation; either version 2 of the License, or   *      the Free Software Foundation; either version 2 of the License, or
13   *      (at your option) any later version.   *      (at your option) any later version.
14   *   *
# Line 24  Line 19 
19   *   *
20   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
21   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
22   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23   *   *
24   *************************************************************************/   *  Under section 8 of the GNU General Public License, the copyright
25     *  holders of XVID explicitly forbid distribution in the following
26  /**************************************************************************   *  countries:
27   *   *
28   *      History:   *    - Japan
29   *   *    - United States of America
30   *      26.02.2001      fixed dec_csp bugs   *
31   *      26.12.2001      xvid_init() support   *  Linking XviD statically or dynamically with other modules is making a
32   *      22.12.2001      removed some compiler warnings   *  combined work based on XviD.  Thus, the terms and conditions of the
33   *      16.12.2001      inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>   *  GNU General Public License cover the whole combination.
34     *
35     *  As a special exception, the copyright holders of XviD give you
36     *  permission to link XviD with independent modules that communicate with
37     *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the
38     *  license terms of these independent modules, and to copy and distribute
39     *  the resulting combined work under terms of your choice, provided that
40     *  every copy of the combined work is accompanied by a complete copy of
41     *  the source code of XviD (the version of XviD used to produce the
42     *  combined work), being distributed under the terms of the GNU General
43     *  Public License plus this exception.  An independent module is a module
44     *  which is not derived from or based on XviD.
45     *
46     *  Note that people who make modified versions of XviD are not obligated
47     *  to grant this special exception for their modified versions; it is
48     *  their choice whether to do so.  The GNU General Public License gives
49     *  permission to release a modified version without this exception; this
50     *  exception also makes it possible to release a modified version which
51     *  carries forward this exception.
52   *   *
53   * $Id$   * $Id$
54   *   *
# Line 43  Line 56 
56    
57  #include <stdlib.h>  #include <stdlib.h>
58  #include <string.h>  #include <string.h>
59    #include <stdio.h>
60    
61  #include "xvid.h"  #include "xvid.h"
62  #include "divx4.h"  #include "divx4.h"
# Line 72  Line 86 
86          void * handle;          void * handle;
87          XVID_DEC_FRAME xframe;          XVID_DEC_FRAME xframe;
88    
89  } DINST;  }
90    DINST;
91    
92    typedef struct EINST
93    {
94            struct EINST *next;
95    
96            void *handle;
97            int quality;
98    
99    }
100    EINST;
101    
102  /**************************************************************************  /**************************************************************************
103   * Global data (needed to emulate correctly exported symbols from divx4)   * Global data (needed to emulate correctly exported symbols from divx4)
# Line 87  Line 112 
112    
113  /* The Divx4 instance chainlist */  /* The Divx4 instance chainlist */
114  static DINST * dhead = NULL;  static DINST * dhead = NULL;
115    static EINST *ehead = NULL;
116    
117  /* Divx4 quality to XviD encoder motion flag presets */  /* Divx4 quality to XviD encoder motion flag presets */
118  static int const divx4_motion_presets[7] = {  static int const divx4_motion_presets[7] = {
119          0,          0,
120    
         PMV_QUICKSTOP16,  
   
121          PMV_EARLYSTOP16,          PMV_EARLYSTOP16,
122    
123            PMV_EARLYSTOP16 | PMV_ADVANCEDDIAMOND16,
124    
125          PMV_EARLYSTOP16 | PMV_HALFPELREFINE16,          PMV_EARLYSTOP16 | PMV_HALFPELREFINE16,
126    
127          PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 |          PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 |
128          PMV_EARLYSTOP8  | PMV_HALFPELDIAMOND8,                  PMV_HALFPELREFINE8,
129    
130          PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 |          PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 |
131          PMV_EARLYSTOP8  | PMV_HALFPELDIAMOND8,                  PMV_HALFPELREFINE8,
132    
133          PMV_EARLYSTOP16    | PMV_HALFPELREFINE16 |          PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 | PMV_EARLYSTOP8 |
134          PMV_EXTSEARCH16    | PMV_EARLYSTOP8 |                  PMV_HALFPELREFINE8
         PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8  
135  };  };
136    
137    
# Line 121  Line 146 
146          XVID_H263QUANT | XVID_INTER4V | XVID_HALFPEL          XVID_H263QUANT | XVID_INTER4V | XVID_HALFPEL
147  };  };
148    
 /*  
  * Current divx4 encoder quality  
  * ToDo : this data should not be shared between encoder instances  
  */  
 static int quality;  
   
149  /**************************************************************************  /**************************************************************************
150   * Local Prototypes   * Local Prototypes
151   *************************************************************************/   *************************************************************************/
# Line 136  Line 155 
155  static DINST * dinst_add(unsigned long key);  static DINST * dinst_add(unsigned long key);
156  static void    dinst_remove(unsigned long key);  static void    dinst_remove(unsigned long key);
157    
158    static EINST *einst_find(void *handle);
159    static EINST *einst_add(void *handle);
160    static void einst_remove(void *handle);
161    
162  /* Converts divx4 colorspaces codes to xvid codes */  /* Converts divx4 colorspaces codes to xvid codes */
163  static int xvid_to_opendivx_dec_csp(int csp);  static int xvid_to_opendivx_dec_csp(int csp);
164  static int xvid_to_opendivx_enc_csp(int csp);  static int xvid_to_opendivx_enc_csp(int csp);
# Line 148  Line 171 
171   *************************************************************************/   *************************************************************************/
172    
173  int  int
174  decore(unsigned long key, unsigned long opt, void * param1, void * param2)  decore(unsigned long key,
175               unsigned long opt,
176               void *param1,
177               void *param2)
178  {  {
179    
180          int xerr;          int xerr;
# Line 169  Line 195 
195                  DEC_PARAM * dparam = (DEC_PARAM *)param1;                  DEC_PARAM * dparam = (DEC_PARAM *)param1;
196    
197                  /* Find the divx4 instance */                  /* Find the divx4 instance */
198                  if ((dcur = dinst_find(key)) == NULL)                          if ((dcur = dinst_find(key)) == NULL) {
                 {  
199                          dcur = dinst_add(key);                          dcur = dinst_add(key);
200                  }                  }
201    
# Line 201  Line 226 
226                  DINST * dcur;                  DINST * dcur;
227    
228                  /* Find the divx4 instance into the chain list */                  /* Find the divx4 instance into the chain list */
229                  if ((dcur = dinst_find(key)) == NULL)                          if ((dcur = dinst_find(key)) == NULL) {
                 {  
230                          return DEC_EXIT;                          return DEC_EXIT;
231                  }                  }
232    
# Line 220  Line 244 
244                  DINST * dcur;                  DINST * dcur;
245    
246                  /* Find the divx4 instance into the chain list */                  /* Find the divx4 instance into the chain list */
247                  if ((dcur = dinst_find(key)) == NULL)                          if ((dcur = dinst_find(key)) == NULL) {
                 {  
248                          return DEC_EXIT;                          return DEC_EXIT;
249                  }                  }
250    
# Line 237  Line 260 
260                  DINST * dcur;                  DINST * dcur;
261                  DEC_PARAM * dparam = (DEC_PARAM *)param1;                  DEC_PARAM * dparam = (DEC_PARAM *)param1;
262    
263                  if ((dcur = dinst_find(key)) == NULL)                          if ((dcur = dinst_find(key)) == NULL) {
                 {  
264                          return DEC_EXIT;                          return DEC_EXIT;
265                  }                  }
266    
# Line 255  Line 277 
277                  DINST * dcur;                  DINST * dcur;
278                  DEC_FRAME * dframe = (DEC_FRAME *)param1;                  DEC_FRAME * dframe = (DEC_FRAME *)param1;
279    
280                  if ((dcur = dinst_find(key)) == NULL)                          if ((dcur = dinst_find(key)) == NULL) {
                 {  
281                          return DEC_EXIT;                          return DEC_EXIT;
282                  }                  }
283    
# Line 267  Line 288 
288                  dcur->xframe.stride = dframe->stride;                  dcur->xframe.stride = dframe->stride;
289    
290                  /* Does the frame need to be skipped ? */                  /* Does the frame need to be skipped ? */
291                  if (!dframe->render_flag)                          if (!dframe->render_flag) {
                 {  
292                          /*                          /*
293                           * Then we use the null colorspace to force XviD to                           * Then we use the null colorspace to force XviD to
294                           * skip the frame. The original colorspace will be                           * skip the frame. The original colorspace will be
# Line 282  Line 302 
302                  xerr = decoder_decode(dcur->handle, &dcur->xframe);                  xerr = decoder_decode(dcur->handle, &dcur->xframe);
303    
304                  /* Restore the real colorspace for this instance */                  /* Restore the real colorspace for this instance */
305                  if (!dframe->render_flag)                          if (!dframe->render_flag) {
                 {  
306                          dcur->xframe.colorspace = csp_tmp;                          dcur->xframe.colorspace = csp_tmp;
307                  }                  }
308    
# Line 303  Line 322 
322    
323    
324          /* XviD error code -> Divx4 */          /* XviD error code -> Divx4 */
325          switch(xerr)          switch (xerr) {
         {  
326          case XVID_ERR_OK :          case XVID_ERR_OK :
327                  return DEC_OK;                  return DEC_OK;
328          case XVID_ERR_MEMORY :          case XVID_ERR_MEMORY :
# Line 326  Line 344 
344  #define FRAMERATE_INCR          1001  #define FRAMERATE_INCR          1001
345    
346  int  int
347  encore(void * handle, int opt, void * param1, void * param2)  encore(void *handle,
348               int opt,
349               void *param1,
350               void *param2)
351  {  {
352    
353          int xerr;          int xerr;
# Line 334  Line 355 
355          switch(opt) {          switch(opt) {
356          case ENC_OPT_INIT :          case ENC_OPT_INIT :
357          {          {
358                            EINST *ecur;
359                  ENC_PARAM * eparam = (ENC_PARAM *)param1;                  ENC_PARAM * eparam = (ENC_PARAM *)param1;
360                  XVID_INIT_PARAM xinit;                  XVID_INIT_PARAM xinit;
361                  XVID_ENC_PARAM xparam;                  XVID_ENC_PARAM xparam;
# Line 345  Line 367 
367                  /* Settings are copied to the XviD encoder structure */                  /* Settings are copied to the XviD encoder structure */
368                  xparam.width = eparam->x_dim;                  xparam.width = eparam->x_dim;
369                  xparam.height = eparam->y_dim;                  xparam.height = eparam->y_dim;
370                  if ((eparam->framerate - (int)eparam->framerate) == 0)                          if ((eparam->framerate - (int) eparam->framerate) == 0) {
                 {  
371                          xparam.fincr = 1;                          xparam.fincr = 1;
372                          xparam.fbase = (int)eparam->framerate;                          xparam.fbase = (int)eparam->framerate;
373                  }                          } else {
                 else  
                 {  
374                          xparam.fincr = FRAMERATE_INCR;                          xparam.fincr = FRAMERATE_INCR;
375                          xparam.fbase = (int)(FRAMERATE_INCR * eparam->framerate);                          xparam.fbase = (int)(FRAMERATE_INCR * eparam->framerate);
376                  }                  }
# Line 362  Line 381 
381                  xparam.min_quantizer = eparam->min_quantizer;                  xparam.min_quantizer = eparam->min_quantizer;
382                  xparam.max_quantizer = eparam->max_quantizer;                  xparam.max_quantizer = eparam->max_quantizer;
383                  xparam.max_key_interval = eparam->max_key_interval;                  xparam.max_key_interval = eparam->max_key_interval;
                 quality = eparam->quality;  
384    
385                  /* Create the encoder session */                  /* Create the encoder session */
386                  xerr = encoder_create(&xparam);                  xerr = encoder_create(&xparam);
387    
388                  eparam->handle = xparam.handle;                  eparam->handle = xparam.handle;
389    
390                            /* Create an encoder instance in the chainlist */
391                            if ((ecur = einst_find(xparam.handle)) == NULL) {
392                                    ecur = einst_add(xparam.handle);
393    
394                                    if (ecur == NULL) {
395                                            encoder_destroy((Encoder *) xparam.handle);
396                                            return ENC_MEMORY;
397                                    }
398    
399                            }
400    
401                            ecur->quality = eparam->quality;
402                            if (ecur->quality < 0)
403                                    ecur->quality = 0;
404                            if (ecur->quality > 6)
405                                    ecur->quality = 6;
406    
407                  break;                  break;
408          }          }
409    
410          case ENC_OPT_RELEASE :          case ENC_OPT_RELEASE :
411          {          {
412                            EINST *ecur;
413    
414                            if ((ecur = einst_find(handle)) == NULL) {
415                                    return ENC_FAIL;
416                            }
417    
418                            einst_remove(handle);
419                  xerr = encoder_destroy((Encoder *) handle);                  xerr = encoder_destroy((Encoder *) handle);
420    
421                  break;                  break;
422          }          }
423    
424          case ENC_OPT_ENCODE :          case ENC_OPT_ENCODE :
425          case ENC_OPT_ENCODE_VBR :          case ENC_OPT_ENCODE_VBR :
426          {          {
427                            EINST *ecur;
428    
429                  ENC_FRAME * eframe = (ENC_FRAME *)param1;                  ENC_FRAME * eframe = (ENC_FRAME *)param1;
430                  ENC_RESULT * eresult = (ENC_RESULT *)param2;                  ENC_RESULT * eresult = (ENC_RESULT *)param2;
431                  XVID_ENC_FRAME xframe;                  XVID_ENC_FRAME xframe;
432                  XVID_ENC_STATS xstats;                  XVID_ENC_STATS xstats;
433    
434                            if ((ecur = einst_find(handle)) == NULL) {
435                                    return ENC_FAIL;
436                            }
437    
438                  /* Copy the divx4 info into the xvid structure */                  /* Copy the divx4 info into the xvid structure */
439                  xframe.bitstream = eframe->bitstream;                  xframe.bitstream = eframe->bitstream;
440                  xframe.length = eframe->length;                  xframe.length = eframe->length;
441                            xframe.motion = divx4_motion_presets[ecur->quality];
442                  xframe.motion = divx4_motion_presets[quality];                          xframe.general = divx4_general_presets[ecur->quality];
                 xframe.general = divx4_general_presets[quality];  
443    
444                  xframe.image = eframe->image;                  xframe.image = eframe->image;
445                  xframe.colorspace =                          xframe.colorspace = xvid_to_opendivx_enc_csp(eframe->colorspace);
                         xvid_to_opendivx_enc_csp(eframe->colorspace);  
446    
447                  if (opt == ENC_OPT_ENCODE_VBR)                          if (opt == ENC_OPT_ENCODE_VBR) {
                 {  
448                          xframe.intra = eframe->intra;                          xframe.intra = eframe->intra;
449                          xframe.quant = eframe->quant;                          xframe.quant = eframe->quant;
450                  }                          } else {
                 else  
                 {  
451                          xframe.intra = -1;                          xframe.intra = -1;
452                          xframe.quant = 0;                          xframe.quant = 0;
453                  }                  }
454    
455                  /* Encode the frame */                  /* Encode the frame */
456                  xerr = encoder_encode((Encoder *) handle, &xframe, (eresult ? &xstats : NULL) );                          xerr =
457                                    encoder_encode((Encoder *) handle, &xframe,
458                                                               (eresult ? &xstats : NULL));
459    
460                  /* Copy back the xvid structure to the divx4 one */                  /* Copy back the xvid structure to the divx4 one */
461                  if (eresult)                          if (eresult) {
                 {  
462                          eresult->is_key_frame = xframe.intra;                          eresult->is_key_frame = xframe.intra;
463                          eresult->quantizer = xstats.quant;                          eresult->quantizer = xstats.quant;
464                          eresult->total_bits = xframe.length * 8;                          eresult->total_bits = xframe.length * 8;
465                          eresult->motion_bits = xstats.hlength * 8;                          eresult->motion_bits = xstats.hlength * 8;
466                          eresult->texture_bits = eresult->total_bits - eresult->motion_bits;                                  eresult->texture_bits =
467                                            eresult->total_bits - eresult->motion_bits;
468                  }                  }
469    
470                  eframe->length = xframe.length;                  eframe->length = xframe.length;
# Line 431  Line 477 
477          }          }
478    
479          /* XviD Error code  -> Divx4 error code */          /* XviD Error code  -> Divx4 error code */
480          switch(xerr)          switch (xerr) {
         {  
481          case XVID_ERR_OK :          case XVID_ERR_OK :
482                  return ENC_OK;                  return ENC_OK;
483          case XVID_ERR_MEMORY :          case XVID_ERR_MEMORY :
# Line 453  Line 498 
498   ***************************************/   ***************************************/
499    
500  /* Find an element in the chainlist according to its key value */  /* Find an element in the chainlist according to its key value */
501  static DINST * dinst_find(unsigned long key)  static DINST *
502    dinst_find(unsigned long key)
503  {  {
504          DINST * dcur = dhead;          DINST * dcur = dhead;
505    
506          while (dcur)          while (dcur) {
507          {                  if (dcur->key == key) {
                 if (dcur->key == key)  
                 {  
508                          return dcur;                          return dcur;
509                  }                  }
510                  dcur = dcur->next;                  dcur = dcur->next;
# Line 471  Line 515 
515    
516    
517  /* Add an element to the chainlist */  /* Add an element to the chainlist */
518  static DINST * dinst_add(unsigned long key)  static DINST *
519    dinst_add(unsigned long key)
520  {  {
521          DINST * dnext = dhead;          DINST * dnext = dhead;
522    
523          dhead = malloc(sizeof(DINST));          dhead = malloc(sizeof(DINST));
524          if (dhead == NULL)          if (dhead == NULL) {
         {  
525                  dhead = dnext;                  dhead = dnext;
526                  return NULL;                  return NULL;
527          }          }
# Line 490  Line 534 
534    
535    
536  /* Remove an elmement from the chainlist */  /* Remove an elmement from the chainlist */
537  static void dinst_remove(unsigned long key)  static void
538    dinst_remove(unsigned long key)
539  {  {
540          DINST * dcur = dhead;          DINST * dcur = dhead;
541    
542          if (dhead == NULL)          if (dhead == NULL) {
         {  
543                  return;                  return;
544          }          }
545    
546          if (dcur->key == key)          if (dcur->key == key) {
         {  
547                  dhead = dcur->next;                  dhead = dcur->next;
548                  free(dcur);                  free(dcur);
549                  return;                  return;
550          }          }
551    
552          while (dcur->next)          while (dcur->next) {
553          {                  if (dcur->next->key == key) {
                 if (dcur->next->key == key)  
                 {  
554                          DINST * tmp = dcur->next;                          DINST * tmp = dcur->next;
555    
556                          dcur->next = tmp->next;                          dcur->next = tmp->next;
557                          free(tmp);                          free(tmp);
558                          return;                          return;
# Line 519  Line 561 
561          }          }
562  }  }
563    
564    
565  /***************************************  /***************************************
566   * Colorspace code converter           *   * EINST chainlist helper functions    *
567   ***************************************/   ***************************************/
568    
569  static int xvid_to_opendivx_dec_csp(int csp)  /* Find an element in the chainlist according to its handle */
570    static EINST *
571    einst_find(void *handle)
572    {
573            EINST *ecur = ehead;
574    
575            while (ecur) {
576                    if (ecur->handle == handle) {
577                            return ecur;
578                    }
579                    ecur = ecur->next;
580            }
581    
582            return NULL;
583    }
584    
585    
586    /* Add an element to the chainlist */
587    static EINST *
588    einst_add(void *handle)
589    {
590            EINST *enext = ehead;
591    
592            ehead = malloc(sizeof(EINST));
593            if (ehead == NULL) {
594                    ehead = enext;
595                    return NULL;
596            }
597    
598            ehead->handle = handle;
599            ehead->next = enext;
600    
601            return ehead;
602    }
603    
604    
605    /* Remove an elmement from the chainlist */
606    static void
607    einst_remove(void *handle)
608  {  {
609            EINST *ecur = ehead;
610    
611            if (ehead == NULL) {
612                    return;
613            }
614    
615            if (ecur->handle == handle) {
616                    ehead = ecur->next;
617                    free(ecur);
618                    return;
619            }
620    
621            while (ecur->next) {
622                    if (ecur->next->handle == handle) {
623                            EINST *tmp = ecur->next;
624    
625          switch(csp)                          ecur->next = tmp->next;
626                            free(tmp);
627                            return;
628                    }
629                    ecur = ecur->next;
630            }
631    }
632    
633    /***************************************
634     * Colorspace code converter           *
635     ***************************************/
636    
637    static int
638    xvid_to_opendivx_dec_csp(int csp)
639          {          {
640    
641            switch (csp) {
642          case DEC_YV12 :          case DEC_YV12 :
643                  return XVID_CSP_YV12;                  return XVID_CSP_YV12;
644          case DEC_420 :          case DEC_420 :
# Line 559  Line 670 
670          }          }
671  }  }
672    
673  static int xvid_to_opendivx_enc_csp(int csp)  static int
674    xvid_to_opendivx_enc_csp(int csp)
675  {  {
676    
677          switch (csp)          switch (csp) {
         {  
678          case ENC_CSP_RGB24 :          case ENC_CSP_RGB24 :
679                  return XVID_CSP_VFLIP | XVID_CSP_RGB24;                  return XVID_CSP_VFLIP | XVID_CSP_RGB24;
680          case ENC_CSP_YV12 :          case ENC_CSP_YV12 :

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.20

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