--- divx4.c 2002/04/27 23:51:59 1.8 +++ divx4.c 2002/06/09 23:05:35 1.13 @@ -1,50 +1,49 @@ /************************************************************************** * - * XVID MPEG-4 VIDEO CODEC - * opendivx api wrapper + * XVID MPEG-4 VIDEO CODEC + * - OpenDivx API wrapper - * - * This program is an implementation of a part of one or more MPEG-4 - * 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. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * This program is an implementation of a part of one or more MPEG-4 + * 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. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * - * History: + * History: * - * 26.02.2001 fixed dec_csp bugs - * 26.12.2001 xvid_init() support - * 22.12.2001 removed some compiler warnings - * 16.12.2001 inital version; (c)2001 peter ross + * 26.02.2001 fixed dec_csp bugs + * 26.12.2001 xvid_init() support + * 22.12.2001 removed some compiler warnings + * 16.12.2001 inital version; (c)2001 peter ross + * + * $Id: divx4.c,v 1.13 2002/06/09 23:05:35 edgomez Exp $ * *************************************************************************/ -#ifndef FREEBSD -#include -#else #include -#endif -#include // memset +#include +#include #include "xvid.h" #include "divx4.h" @@ -53,7 +52,17 @@ #define EMULATED_DIVX_VERSION 20011001 -// decore +/************************************************************************** + * Divx Instance Structure + * + * This chain list datatype allows XviD do instanciate multiples divx4 + * sessions. + * + * ToDo : The way this chain list is used does not guarantee reentrance + * because they are not protected by any kind of mutex to allow + * only one modifier. We should add a mutex for each element in + * the chainlist. + *************************************************************************/ typedef struct DINST @@ -66,397 +75,616 @@ } DINST; - -static DINST * dhead = NULL; +typedef struct EINST +{ + struct EINST * next; + void * handle; + int quality; -DINST * dinst_find(unsigned long key) -{ - DINST * dcur = dhead; +} EINST; - while (dcur) - { - if (dcur->key == key) - { - return dcur; - } - dcur = dcur->next; - } +/************************************************************************** + * Global data (needed to emulate correctly exported symbols from divx4) + *************************************************************************/ - return NULL; -} +/* This is not used in this module but is required by some divx4 encoders*/ +int quiet_encore = 1; +/************************************************************************** + * Local data + *************************************************************************/ -DINST * dinst_add(unsigned long key) -{ - DINST * dnext = dhead; +/* The Divx4 instance chainlist */ +static DINST * dhead = NULL; +static EINST * ehead = NULL; - dhead = malloc(sizeof(DINST)); - if (dhead == NULL) - { - dhead = dnext; - return NULL; - } +/* Divx4 quality to XviD encoder motion flag presets */ +static int const divx4_motion_presets[7] = { + 0, - dhead->key = key; - dhead->next = dnext; + PMV_EARLYSTOP16, - return dhead; -} + PMV_EARLYSTOP16 | PMV_ADVANCEDDIAMOND16, + PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, -void dinst_remove(unsigned long key) -{ - DINST * dcur = dhead; + PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | + PMV_EARLYSTOP8 | PMV_HALFPELREFINE8, - if (dhead == NULL) - { - return; - } + PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | + PMV_EARLYSTOP8 | PMV_HALFPELREFINE8, - if (dcur->key == key) - { - dhead = dcur->next; - free(dcur); - return; - } + PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 | + PMV_EARLYSTOP8 | PMV_HALFPELREFINE8 +}; - while (dcur->next) - { - if (dcur->next->key == key) - { - DINST * tmp = dcur->next; - dcur->next = tmp->next; - free(tmp); - return; - } - dcur = dcur->next; - } -} +/* Divx4 quality to general encoder flag presets */ +static int const divx4_general_presets[7] = { + 0, + XVID_H263QUANT, + XVID_H263QUANT, + XVID_H263QUANT | XVID_HALFPEL, + XVID_H263QUANT | XVID_INTER4V | XVID_HALFPEL, + XVID_H263QUANT | XVID_INTER4V | XVID_HALFPEL, + XVID_H263QUANT | XVID_INTER4V | XVID_HALFPEL +}; -int xvid_to_opendivx_dec_csp(int csp) -{ - switch(csp) - { - case DEC_YV12 : - return XVID_CSP_YV12; - case DEC_420 : - return XVID_CSP_I420; - case DEC_YUY2 : - return XVID_CSP_YUY2; - case DEC_UYVY : - return XVID_CSP_UYVY; - case DEC_RGB32 : - return XVID_CSP_VFLIP | XVID_CSP_RGB32; - case DEC_RGB24 : - return XVID_CSP_VFLIP | XVID_CSP_RGB24; - case DEC_RGB565 : - return XVID_CSP_VFLIP | XVID_CSP_RGB565; - case DEC_RGB555 : - return XVID_CSP_VFLIP | XVID_CSP_RGB555; - case DEC_RGB32_INV : - return XVID_CSP_RGB32; - case DEC_RGB24_INV : - return XVID_CSP_RGB24; - case DEC_RGB565_INV : - return XVID_CSP_RGB565; - case DEC_RGB555_INV : - return XVID_CSP_RGB555; - case DEC_USER : - return XVID_CSP_USER; - default : - return -1; - } -} +/************************************************************************** + * Local Prototypes + *************************************************************************/ + +/* Chain list helper functions */ +static DINST * dinst_find(unsigned long key); +static DINST * dinst_add(unsigned long key); +static void dinst_remove(unsigned long key); + +static EINST * einst_find(void *handle); +static EINST * einst_add(void *handle); +static void einst_remove(void *handle); + +/* Converts divx4 colorspaces codes to xvid codes */ +static int xvid_to_opendivx_dec_csp(int csp); +static int xvid_to_opendivx_enc_csp(int csp); +/************************************************************************** + * decore part + * + * decore is the divx4 entry point used to decompress the mpeg4 bitstream + * into a user defined image format. + *************************************************************************/ -int decore(unsigned long key, unsigned long opt, - void * param1, void * param2) +int +decore(unsigned long key, unsigned long opt, void * param1, void * param2) { + int xerr; - switch (opt) - { - case DEC_OPT_MEMORY_REQS : - { - memset(param2, 0, sizeof(DEC_MEM_REQS)); - return DEC_OK; - } + switch (opt) { + case DEC_OPT_MEMORY_REQS : + { + memset(param2, 0, sizeof(DEC_MEM_REQS)); + return DEC_OK; + } + case DEC_OPT_INIT : - { - DEC_PARAM * dparam = (DEC_PARAM *)param1; - XVID_INIT_PARAM xinit; - XVID_DEC_PARAM xparam; - DINST * dcur = dinst_find(key); - if (dcur == NULL) - { - dcur = dinst_add(key); - } - - xinit.cpu_flags = 0; - xvid_init(NULL, 0, &xinit, NULL); - - xparam.width = dparam->x_dim; - xparam.height = dparam->y_dim; - dcur->xframe.colorspace = xvid_to_opendivx_dec_csp(dparam->output_format); + { + XVID_INIT_PARAM xinit; + XVID_DEC_PARAM xparam; + DINST * dcur; + DEC_PARAM * dparam = (DEC_PARAM *)param1; + + /* Find the divx4 instance */ + if ((dcur = dinst_find(key)) == NULL) + { + dcur = dinst_add(key); + } + + /* + * XviD initialization + * XviD will detect the host cpu type and activate optimized + * functions according to the host cpu features. + */ + xinit.cpu_flags = 0; + xvid_init(NULL, 0, &xinit, NULL); + + /* XviD decoder initialization for this instance */ + xparam.width = dparam->x_dim; + xparam.height = dparam->y_dim; + dcur->xframe.colorspace = + xvid_to_opendivx_dec_csp(dparam->output_format); - xerr = decoder_create(&xparam); + xerr = decoder_create(&xparam); - dcur->handle = xparam.handle; + /* Store the xvid handle into the divx4 instance chainlist */ + dcur->handle = xparam.handle; - break; - } + break; + } case DEC_OPT_RELEASE : + { + DINST * dcur; + + /* Find the divx4 instance into the chain list */ + if ((dcur = dinst_find(key)) == NULL) { - DINST * dcur = dinst_find(key); - if (dcur == NULL) - { - return DEC_EXIT; - } + return DEC_EXIT; + } - xerr = decoder_destroy(dcur->handle); + /* Destroy the XviD decoder attached to this divx4 instance */ + xerr = decoder_destroy(dcur->handle); - dinst_remove(key); + /* Remove the divx4 instance from the chainlist */ + dinst_remove(key); - break; - } + break; + } case DEC_OPT_SETPP : - { - // DEC_SET * dset = (DEC_SET *)param1; - DINST * dcur = dinst_find(key); - if (dcur == NULL) - { - return DEC_EXIT; - } - - // dcur->xframe.pp = dset->postproc_level; + { + DINST * dcur; - return DEC_OK; + /* Find the divx4 instance into the chain list */ + if ((dcur = dinst_find(key)) == NULL) + { + return DEC_EXIT; } + /* + * We return DEC_OK but XviD has no postprocessing implemented + * in core. + */ + return DEC_OK; + } + case DEC_OPT_SETOUT : + { + DINST * dcur; + DEC_PARAM * dparam = (DEC_PARAM *)param1; + + if ((dcur = dinst_find(key)) == NULL) { - DEC_PARAM * dparam = (DEC_PARAM *)param1; - DINST * dcur = dinst_find(key); - if (dcur == NULL) - { - return DEC_EXIT; - } + return DEC_EXIT; + } - dcur->xframe.colorspace = xvid_to_opendivx_dec_csp(dparam->output_format); + /* Change the output colorspace */ + dcur->xframe.colorspace = + xvid_to_opendivx_dec_csp(dparam->output_format); - return DEC_OK; - } + return DEC_OK; + } case DEC_OPT_FRAME: - { - int csp_tmp = 0; + { + int csp_tmp = 0; + DINST * dcur; + DEC_FRAME * dframe = (DEC_FRAME *)param1; - DEC_FRAME * dframe = (DEC_FRAME *)param1; - DINST * dcur = dinst_find(key); - if (dcur == NULL) - { - return DEC_EXIT; - } + if ((dcur = dinst_find(key)) == NULL) + { + return DEC_EXIT; + } - dcur->xframe.bitstream = dframe->bitstream; - dcur->xframe.length = dframe->length; - dcur->xframe.image = dframe->bmp; - dcur->xframe.stride = dframe->stride; + /* Copy the divx4 fields to the XviD decoder structure */ + dcur->xframe.bitstream = dframe->bitstream; + dcur->xframe.length = dframe->length; + dcur->xframe.image = dframe->bmp; + dcur->xframe.stride = dframe->stride; - if (!dframe->render_flag) - { - csp_tmp = dcur->xframe.colorspace; - dcur->xframe.colorspace = XVID_CSP_NULL; - } + /* Does the frame need to be skipped ? */ + if (!dframe->render_flag) + { + /* + * Then we use the null colorspace to force XviD to + * skip the frame. The original colorspace will be + * restored after the decoder call + */ + csp_tmp = dcur->xframe.colorspace; + dcur->xframe.colorspace = XVID_CSP_NULL; + } - xerr = decoder_decode(dcur->handle, &dcur->xframe); + /* Decode the bitstream */ + xerr = decoder_decode(dcur->handle, &dcur->xframe); - if (!dframe->render_flag) - { - dcur->xframe.colorspace = csp_tmp; - } - - break; + /* Restore the real colorspace for this instance */ + if (!dframe->render_flag) + { + dcur->xframe.colorspace = csp_tmp; } + break; + } case DEC_OPT_FRAME_311 : + /* XviD does not handle Divx ;-) 3.11 yet */ return DEC_EXIT; - case DEC_OPT_VERSION: return EMULATED_DIVX_VERSION; + default : return DEC_EXIT; } + /* XviD error code -> Divx4 */ switch(xerr) { - case XVID_ERR_OK : return DEC_OK; - case XVID_ERR_MEMORY : return DEC_MEMORY; - case XVID_ERR_FORMAT : return DEC_BAD_FORMAT; - default : // case XVID_ERR_FAIL : + case XVID_ERR_OK : + return DEC_OK; + case XVID_ERR_MEMORY : + return DEC_MEMORY; + case XVID_ERR_FORMAT : + return DEC_BAD_FORMAT; + default : return DEC_EXIT; } } - - - -// encore +/************************************************************************** + * Encore Part + * + * encore is the divx4 entry point used to compress a frame to a mpeg4 + * bitstream. + *************************************************************************/ #define FRAMERATE_INCR 1001 -int divx4_motion_presets[7] = { - 0, - PMV_QUICKSTOP16, - PMV_EARLYSTOP16, - PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, - PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8, - PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8, - PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 | PMV_EARLYSTOP8 | PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8 -}; +int +encore(void * handle, int opt, void * param1, void * param2) +{ + int xerr; -int divx4_general_presets[7] = { - 0, - XVID_H263QUANT, - XVID_H263QUANT, - XVID_H263QUANT | XVID_HALFPEL, - XVID_H263QUANT | XVID_INTER4V | XVID_HALFPEL, - XVID_H263QUANT | XVID_INTER4V | XVID_HALFPEL, - XVID_H263QUANT | XVID_INTER4V | XVID_HALFPEL -}; + switch(opt) { + case ENC_OPT_INIT : + { + EINST *ecur; + ENC_PARAM * eparam = (ENC_PARAM *)param1; + XVID_INIT_PARAM xinit; + XVID_ENC_PARAM xparam; + + /* Init XviD which will detect host cpu features */ + xinit.cpu_flags = 0; + xvid_init(NULL, 0, &xinit, NULL); + + /* Settings are copied to the XviD encoder structure */ + xparam.width = eparam->x_dim; + xparam.height = eparam->y_dim; + if ((eparam->framerate - (int)eparam->framerate) == 0) + { + xparam.fincr = 1; + xparam.fbase = (int)eparam->framerate; + } + else + { + xparam.fincr = FRAMERATE_INCR; + xparam.fbase = (int)(FRAMERATE_INCR * eparam->framerate); + } + xparam.rc_bitrate = eparam->bitrate; + xparam.rc_reaction_delay_factor = 16; + xparam.rc_averaging_period = 100; + xparam.rc_buffer = 100; + xparam.min_quantizer = eparam->min_quantizer; + xparam.max_quantizer = eparam->max_quantizer; + xparam.max_key_interval = eparam->max_key_interval; -int quality; + /* Create the encoder session */ + xerr = encoder_create(&xparam); -int encore(void * handle, int opt, void * param1, void * param2) -{ - int xerr; + eparam->handle = xparam.handle; - switch(opt) - { - case ENC_OPT_INIT : + /* Create an encoder instance in the chainlist */ + if ((ecur = einst_find(xparam.handle)) == NULL) { - ENC_PARAM * eparam = (ENC_PARAM *)param1; - XVID_INIT_PARAM xinit; - XVID_ENC_PARAM xparam; + ecur = einst_add(xparam.handle); - xinit.cpu_flags = 0; - xvid_init(NULL, 0, &xinit, NULL); - - xparam.width = eparam->x_dim; - xparam.height = eparam->y_dim; - if ((eparam->framerate - (int)eparam->framerate) == 0) - { - xparam.fincr = 1; - xparam.fbase = (int)eparam->framerate; - } - else - { - xparam.fincr = FRAMERATE_INCR; - xparam.fbase = (int)(FRAMERATE_INCR * eparam->framerate); + if(ecur == NULL) { + encoder_destroy((Encoder*)xparam.handle); + return ENC_MEMORY; } - xparam.rc_bitrate = eparam->bitrate; - xparam.rc_reaction_delay_factor = 16; - xparam.rc_averaging_period = 100; - xparam.rc_buffer = 100; - xparam.min_quantizer = eparam->min_quantizer; - xparam.max_quantizer = eparam->max_quantizer; - xparam.max_key_interval = eparam->max_key_interval; - quality = eparam->quality; - xerr = encoder_create(&xparam); + } - eparam->handle = xparam.handle; + ecur->quality = eparam->quality; + if(ecur->quality < 0) ecur->quality = 0; + if(ecur->quality > 6) ecur->quality = 6; - break; - } + break; + } case ENC_OPT_RELEASE : + { + EINST *ecur; + + if ((ecur = einst_find(handle)) == NULL) { - xerr = encoder_destroy((Encoder *) handle); - break; + return ENC_FAIL; } + + einst_remove(handle); + xerr = encoder_destroy((Encoder *) handle); + + break; + } case ENC_OPT_ENCODE : case ENC_OPT_ENCODE_VBR : + { + EINST *ecur; + + ENC_FRAME * eframe = (ENC_FRAME *)param1; + ENC_RESULT * eresult = (ENC_RESULT *)param2; + XVID_ENC_FRAME xframe; + XVID_ENC_STATS xstats; + + if ((ecur = einst_find(handle)) == NULL) { - ENC_FRAME * eframe = (ENC_FRAME *)param1; - ENC_RESULT * eresult = (ENC_RESULT *)param2; - XVID_ENC_FRAME xframe; - XVID_ENC_STATS xstats; - - xframe.bitstream = eframe->bitstream; - xframe.length = eframe->length; - - xframe.motion = divx4_motion_presets[quality]; - xframe.general = divx4_general_presets[quality]; - - xframe.image = eframe->image; - switch (eframe->colorspace) - { - case ENC_CSP_RGB24 : - xframe.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB24; - break; - case ENC_CSP_YV12 : - xframe.colorspace = XVID_CSP_YV12; - break; - case ENC_CSP_YUY2 : - xframe.colorspace = XVID_CSP_YUY2; - break; - case ENC_CSP_UYVY : - xframe.colorspace = XVID_CSP_UYVY; - break; - case ENC_CSP_I420 : - xframe.colorspace = XVID_CSP_I420; - break; - } + return ENC_FAIL; + } - if (opt == ENC_OPT_ENCODE_VBR) - { - xframe.intra = eframe->intra; - xframe.quant = eframe->quant; - } - else - { - xframe.intra = -1; - xframe.quant = 0; - } - - xerr = encoder_encode((Encoder *) handle, &xframe, (eresult ? &xstats : NULL) ); + /* Copy the divx4 info into the xvid structure */ + xframe.bitstream = eframe->bitstream; + xframe.length = eframe->length; + xframe.motion = divx4_motion_presets[ecur->quality]; + xframe.general = divx4_general_presets[ecur->quality]; - if (eresult) - { - eresult->is_key_frame = xframe.intra; - eresult->quantizer = xstats.quant; - eresult->total_bits = xframe.length * 8; - eresult->motion_bits = xstats.hlength * 8; - eresult->texture_bits = eresult->total_bits - eresult->motion_bits; - } + xframe.image = eframe->image; + xframe.colorspace = + xvid_to_opendivx_enc_csp(eframe->colorspace); - eframe->length = xframe.length; + if (opt == ENC_OPT_ENCODE_VBR) + { + xframe.intra = eframe->intra; + xframe.quant = eframe->quant; + } + else + { + xframe.intra = -1; + xframe.quant = 0; + } + + /* Encode the frame */ + xerr = encoder_encode((Encoder *) handle, &xframe, (eresult ? &xstats : NULL) ); - break; + /* Copy back the xvid structure to the divx4 one */ + if (eresult) + { + eresult->is_key_frame = xframe.intra; + eresult->quantizer = xstats.quant; + eresult->total_bits = xframe.length * 8; + eresult->motion_bits = xstats.hlength * 8; + eresult->texture_bits = eresult->total_bits - eresult->motion_bits; } + eframe->length = xframe.length; + + break; + } + default: return ENC_FAIL; } + /* XviD Error code -> Divx4 error code */ switch(xerr) { - case XVID_ERR_OK : return ENC_OK; - case XVID_ERR_MEMORY : return ENC_MEMORY; - case XVID_ERR_FORMAT : return ENC_BAD_FORMAT; - default : // case XVID_ERR_FAIL : + case XVID_ERR_OK : + return ENC_OK; + case XVID_ERR_MEMORY : + return ENC_MEMORY; + case XVID_ERR_FORMAT : + return ENC_BAD_FORMAT; + default : return ENC_FAIL; } } +/************************************************************************** + * Local Functions + *************************************************************************/ + +/*************************************** + * DINST chainlist helper functions * + ***************************************/ + +/* Find an element in the chainlist according to its key value */ +static DINST * dinst_find(unsigned long key) +{ + DINST * dcur = dhead; + + while (dcur) + { + if (dcur->key == key) + { + return dcur; + } + dcur = dcur->next; + } + + return NULL; +} + + +/* Add an element to the chainlist */ +static DINST * dinst_add(unsigned long key) +{ + DINST * dnext = dhead; + + dhead = malloc(sizeof(DINST)); + if (dhead == NULL) + { + dhead = dnext; + return NULL; + } + + dhead->key = key; + dhead->next = dnext; + + return dhead; +} + + +/* Remove an elmement from the chainlist */ +static void dinst_remove(unsigned long key) +{ + DINST * dcur = dhead; + + if (dhead == NULL) + { + return; + } + + if (dcur->key == key) + { + dhead = dcur->next; + free(dcur); + return; + } + + while (dcur->next) + { + if (dcur->next->key == key) + { + DINST * tmp = dcur->next; + dcur->next = tmp->next; + free(tmp); + return; + } + dcur = dcur->next; + } +} + + +/*************************************** + * EINST chainlist helper functions * + ***************************************/ + +/* Find an element in the chainlist according to its handle */ +static EINST * einst_find(void *handle) +{ + EINST * ecur = ehead; + + while (ecur) + { + if (ecur->handle == handle) + { + return ecur; + } + ecur = ecur->next; + } + + return NULL; +} + + +/* Add an element to the chainlist */ +static EINST * einst_add(void *handle) +{ + EINST * enext = ehead; + + ehead = malloc(sizeof(EINST)); + if (ehead == NULL) + { + ehead = enext; + return NULL; + } + + ehead->handle = handle; + ehead->next = enext; + + return ehead; +} + + +/* Remove an elmement from the chainlist */ +static void einst_remove(void *handle) +{ + EINST * ecur = ehead; + + if (ehead == NULL) + { + return; + } + + if (ecur->handle == handle) + { + ehead = ecur->next; + free(ecur); + return; + } + + while (ecur->next) + { + if (ecur->next->handle == handle) + { + EINST * tmp = ecur->next; + ecur->next = tmp->next; + free(tmp); + return; + } + ecur = ecur->next; + } +} +/*************************************** + * Colorspace code converter * + ***************************************/ + +static int xvid_to_opendivx_dec_csp(int csp) +{ + + switch(csp) + { + case DEC_YV12 : + return XVID_CSP_YV12; + case DEC_420 : + return XVID_CSP_I420; + case DEC_YUY2 : + return XVID_CSP_YUY2; + case DEC_UYVY : + return XVID_CSP_UYVY; + case DEC_RGB32 : + return XVID_CSP_VFLIP | XVID_CSP_RGB32; + case DEC_RGB24 : + return XVID_CSP_VFLIP | XVID_CSP_RGB24; + case DEC_RGB565 : + return XVID_CSP_VFLIP | XVID_CSP_RGB565; + case DEC_RGB555 : + return XVID_CSP_VFLIP | XVID_CSP_RGB555; + case DEC_RGB32_INV : + return XVID_CSP_RGB32; + case DEC_RGB24_INV : + return XVID_CSP_RGB24; + case DEC_RGB565_INV : + return XVID_CSP_RGB565; + case DEC_RGB555_INV : + return XVID_CSP_RGB555; + case DEC_USER : + return XVID_CSP_USER; + default : + return -1; + } +} + +static int xvid_to_opendivx_enc_csp(int csp) +{ + + switch (csp) + { + case ENC_CSP_RGB24 : + return XVID_CSP_VFLIP | XVID_CSP_RGB24; + case ENC_CSP_YV12 : + return XVID_CSP_YV12; + case ENC_CSP_YUY2 : + return XVID_CSP_YUY2; + case ENC_CSP_UYVY : + return XVID_CSP_UYVY; + case ENC_CSP_I420 : + return XVID_CSP_I420; + default : + return -1; + } +}