13 #include "vd_internal.h"
15 static vd_info_t info
= {
20 "XviD lib (divx4 compat.)",
28 "http://www.xvid.com",
30 "http://www.divx.com",
43 #define USE_DIVX_BUILTIN_PP
45 #ifndef DECORE_VERSION
46 #define DECORE_VERSION 0
49 #if DECORE_VERSION >= 20021112
50 static void* dec_handle
= NULL
;
53 // to set/get/query special features/parameters
54 static int control(sh_video_t
*sh
,int cmd
,void* arg
,...){
56 #ifdef USE_DIVX_BUILTIN_PP
57 case VDCTRL_QUERY_MAX_PP_LEVEL
:
58 #if DECORE_VERSION >= 20021112
59 return 6; // divx4linux >= 5.0.5 -> 0..60
61 return 10; // divx4linux < 5.0.5 -> 0..100
63 case VDCTRL_SET_PP_LEVEL
: {
64 int quality
=*((int*)arg
);
65 #if DECORE_VERSION >= 20021112
66 int32_t iInstruction
, iPostproc
;
67 if(quality
<0 || quality
>6) quality
=6;
68 iInstruction
= DEC_ADJ_POSTPROCESSING
| DEC_ADJ_SET
;
69 iPostproc
= quality
*10;
70 decore(dec_handle
, DEC_OPT_ADJUST
, &iInstruction
, &iPostproc
);
73 if(quality
<0 || quality
>10) quality
=10;
74 dec_set
.postproc_level
=quality
*10;
75 decore(0x123,DEC_OPT_SETPP
,&dec_set
,NULL
);
80 #if DECORE_VERSION >= 20011010
81 case VDCTRL_SET_EQUALIZER
: {
86 value
=va_arg(ap
, int);
89 if(!strcasecmp(arg
,"Brightness"))
90 #if DECORE_VERSION >= 20021112
91 option
=DEC_ADJ_BRIGHTNESS
| DEC_ADJ_SET
;
93 option
=DEC_GAMMA_BRIGHTNESS
;
95 else if(!strcasecmp(arg
, "Contrast"))
96 #if DECORE_VERSION >= 20021112
97 option
=DEC_ADJ_CONTRAST
| DEC_ADJ_SET
;
99 option
=DEC_GAMMA_CONTRAST
;
101 else if(!strcasecmp(arg
,"Saturation"))
102 #if DECORE_VERSION >= 20021112
103 option
=DEC_ADJ_SATURATION
| DEC_ADJ_SET
;
105 option
=DEC_GAMMA_SATURATION
;
107 else return CONTROL_FALSE
;
109 value
= (value
* 128) / 100;
110 #if DECORE_VERSION >= 20021112
111 decore(dec_handle
, DEC_OPT_ADJUST
, &option
, &value
);
113 decore(0x123, DEC_OPT_GAMMA
, (void *)option
, (void *) value
);
121 return CONTROL_UNKNOWN
;
125 static int init(sh_video_t
*sh
){
126 #if DECORE_VERSION >= 20021112
128 int iSize
=sizeof(DivXBitmapInfoHeader
);
129 DivXBitmapInfoHeader
* pbi
=malloc(iSize
);
130 int32_t iInstruction
;
132 if(!mpcodecs_config_vo(sh
,sh
->disp_w
,sh
->disp_h
,IMGFMT_YUY2
)) return 0;
134 memset(&dec_init
, 0, sizeof(dec_init
));
135 memset(pbi
, 0, iSize
);
138 case mmioFOURCC('D','I','V','3'):
139 dec_init
.codec_version
= 311;
141 case mmioFOURCC('D','I','V','X'):
142 dec_init
.codec_version
= 412;
144 case mmioFOURCC('D','X','5','0'):
145 default: // Fallback to DivX 5 behaviour
146 dec_init
.codec_version
= 500;
149 // no smoothing of the CPU load
150 dec_init
.smooth_playback
= 0;
154 switch(sh
->codec
->outfmt
[sh
->outfmtidx
]){
156 pbi
->biCompression
=mmioFOURCC('Y','V','1','2');
160 pbi
->biCompression
=mmioFOURCC('Y','U','Y','2');
164 pbi
->biCompression
=mmioFOURCC('U','Y','V','Y');
168 pbi
->biCompression
=mmioFOURCC('I','4','2','0');
172 pbi
->biCompression
=0;
177 pbi
->biCompression
=3;
182 pbi
->biCompression
=0;
187 pbi
->biCompression
=0;
192 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,"Unsupported out_fmt: 0x%X\n",sh
->codec
->outfmt
[sh
->outfmtidx
]);
196 pbi
->biWidth
= sh
->disp_w
;
197 pbi
->biHeight
= sh
->disp_h
;
199 decore(&dec_handle
, DEC_OPT_INIT
, &dec_init
, NULL
);
200 decore(dec_handle
, DEC_OPT_SETOUT
, pbi
, NULL
);
202 #ifdef USE_DIVX_BUILTIN_PP
203 iInstruction
= DEC_ADJ_POSTPROCESSING
| DEC_ADJ_SET
;
204 decore(dec_handle
, DEC_OPT_ADJUST
, &iInstruction
, &divx_quality
);
208 #else // DECORE_VERSION < 20021112
214 if(sh
->format
==mmioFOURCC('D','I','V','3')){
215 mp_msg(MSGT_DECVIDEO
,MSGL_INFO
,"DivX 3.x not supported by opendivx decore - it requires divx4linux\n");
216 return 0; // not supported
220 if(sh
->format
==mmioFOURCC('D','X','5','0')){
221 mp_msg(MSGT_DECVIDEO
,MSGL_INFO
,"DivX 5.00 not supported by divx4linux decore - it requires divx5linux\n");
222 return 0; // not supported
226 if(!mpcodecs_config_vo(sh
,sh
->disp_w
,sh
->disp_h
,IMGFMT_YUY2
)) return 0;
228 memset(&dec_param
,0,sizeof(dec_param
));
230 switch(sh
->codec
->outfmt
[sh
->outfmtidx
]){
231 case IMGFMT_YV12
: dec_param
.output_format
=DEC_YV12
;bits
=12;break;
232 case IMGFMT_YUY2
: dec_param
.output_format
=DEC_YUY2
;break;
233 case IMGFMT_UYVY
: dec_param
.output_format
=DEC_UYVY
;break;
234 case IMGFMT_I420
: dec_param
.output_format
=DEC_420
;bits
=12;break;
235 case IMGFMT_BGR15
: dec_param
.output_format
=DEC_RGB555_INV
;break;
236 case IMGFMT_BGR16
: dec_param
.output_format
=DEC_RGB565_INV
;break;
237 case IMGFMT_BGR24
: dec_param
.output_format
=DEC_RGB24_INV
;bits
=24;break;
238 case IMGFMT_BGR32
: dec_param
.output_format
=DEC_RGB32_INV
;bits
=32;break;
240 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,"Unsupported out_fmt: 0x%X\n",sh
->codec
->outfmt
[sh
->outfmtidx
]);
245 case mmioFOURCC('D','I','V','3'):
246 dec_param
.codec_version
= 311;
248 case mmioFOURCC('D','I','V','X'):
249 dec_param
.codec_version
= 400;
251 case mmioFOURCC('D','X','5','0'):
252 default: // Fallback to DivX 5 behaviour
253 dec_param
.codec_version
= 500;
255 dec_param
.build_number
= 0;
257 dec_param
.x_dim
= sh
->disp_w
;
258 dec_param
.y_dim
= sh
->disp_h
;
259 decore(0x123, DEC_OPT_INIT
, &dec_param
, NULL
);
261 #ifdef USE_DIVX_BUILTIN_PP
262 dec_set
.postproc_level
= divx_quality
;
263 decore(0x123, DEC_OPT_SETPP
, &dec_set
, NULL
);
265 #endif // DECORE_VERSION
267 mp_msg(MSGT_DECVIDEO
,MSGL_V
,"INFO: DivX4Linux video codec init OK!\n");
273 static void uninit(sh_video_t
*sh
){
274 #if DECORE_VERSION >= 20021112
275 decore(dec_handle
, DEC_OPT_RELEASE
, NULL
, NULL
);
278 decore(0x123,DEC_OPT_RELEASE
,NULL
,NULL
);
282 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
285 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
){
288 #ifndef USE_DIVX_BUILTIN_PP
289 DEC_FRAME_INFO frameinfo
;
292 if(len
<=0) return NULL
; // skipped frame
294 dec_frame
.length
= len
;
295 dec_frame
.bitstream
= data
;
296 dec_frame
.render_flag
= (flags
&VDFLAGS_DROPFRAME
)?0:1;
298 mpi
=mpcodecs_get_image(sh
, MP_IMGTYPE_TEMP
, MP_IMGFLAG_PRESERVE
| MP_IMGFLAG_ACCEPT_WIDTH
,
299 sh
->disp_w
, sh
->disp_h
);
300 if(!mpi
) return NULL
;
302 dec_frame
.bmp
=mpi
->planes
[0];
303 dec_frame
.stride
=mpi
->width
;
306 #if DECORE_VERSION >= 20021112
311 #ifndef DEC_OPT_FRAME_311
314 (sh
->format
==mmioFOURCC('D','I','V','3'))?DEC_OPT_FRAME_311
:DEC_OPT_FRAME
,
317 #ifndef USE_DIVX_BUILTIN_PP
324 #ifndef USE_DIVX_BUILTIN_PP
325 mpi
->qscale
= frameinfo
.quant_store
;
326 mpi
->qstride
= frameinfo
.quant_stride
;