11 #include "vd_internal.h"
13 static vd_info_t info
= {
16 "DivX5Linux lib (odivx compat.)",
19 "XviD lib (odivx compat.)",
21 "DivX4Linux lib (odivx compat.)",
25 "Opendivx 0.48 codec",
31 "http://www.xvid.com",
33 "http://www.divx.com",
36 "http://www.projectmayo.org",
48 #include "opendivx/decore.h"
49 #include "postproc/postprocess.h"
56 #ifndef DECORE_VERSION
57 #define DECORE_VERSION 0
60 #if DECORE_VERSION >= 20021112
61 static void* dec_handle
= NULL
;
64 //**************************************************************************//
65 // The OpenDivX stuff:
66 //**************************************************************************//
70 static unsigned char *opendivx_src
[3];
71 static int opendivx_stride
[3];
73 // callback, the opendivx decoder calls this for each frame:
74 void convert_linux(unsigned char *puc_y
, int stride_y
,
75 unsigned char *puc_u
, unsigned char *puc_v
, int stride_uv
,
76 unsigned char *bmp
, int width_y
, int height_y
){
78 // printf("convert_yuv called %dx%d stride: %d,%d\n",width_y,height_y,stride_y,stride_uv);
80 opendivx_src
[0]=puc_y
;
81 opendivx_src
[1]=puc_u
;
82 opendivx_src
[2]=puc_v
;
84 opendivx_stride
[0]=stride_y
;
85 opendivx_stride
[1]=stride_uv
;
86 opendivx_stride
[2]=stride_uv
;
91 // to set/get/query special features/parameters
92 static int control(sh_video_t
*sh
,int cmd
,void* arg
,...){
94 case VDCTRL_QUERY_MAX_PP_LEVEL
:
96 #if DECORE_VERSION >= 20021112
97 return 6; // divx4linux >= 5.0.5 -> 0..60
99 return 10; // divx4linux < 5.0.5 -> 0..100
102 return PP_QUALITY_MAX
; // for opendivx
104 case VDCTRL_SET_PP_LEVEL
: {
105 int quality
=*((int*)arg
);
106 #if DECORE_VERSION >= 20021112
107 int32_t iInstruction
, iPostproc
;
108 if(quality
<0 || quality
>6) quality
=6;
109 iInstruction
= DEC_ADJ_POSTPROCESSING
| DEC_ADJ_SET
;
110 iPostproc
= quality
*10;
111 decore(dec_handle
, DEC_OPT_ADJUST
, &iInstruction
, &iPostproc
);
115 if(quality
<0 || quality
>10) quality
=10;
116 dec_set
.postproc_level
=quality
*10;
118 if(quality
<0 || quality
>PP_QUALITY_MAX
) quality
=PP_QUALITY_MAX
;
119 dec_set
.postproc_level
=getPpModeForQuality(quality
);
121 decore(0x123,DEC_OPT_SETPP
,&dec_set
,NULL
);
128 return CONTROL_UNKNOWN
;
132 static int init(sh_video_t
*sh
){
133 #if DECORE_VERSION >= 20021112
135 int iSize
=sizeof(DivXBitmapInfoHeader
);
136 DivXBitmapInfoHeader
* pbi
=malloc(iSize
);
137 int32_t iInstruction
;
139 memset(&dec_init
, 0, sizeof(dec_init
));
140 memset(pbi
, 0, iSize
);
143 case mmioFOURCC('D','I','V','3'):
144 dec_init
.codec_version
= 311;
146 case mmioFOURCC('D','I','V','X'):
147 dec_init
.codec_version
= 412;
149 case mmioFOURCC('D','X','5','0'):
150 default: // Fallback to DivX 5 behaviour
151 dec_init
.codec_version
= 500;
154 // no smoothing of the CPU load
155 dec_init
.smooth_playback
= 0;
159 pbi
->biCompression
=mmioFOURCC('U','S','E','R');
161 pbi
->biWidth
= sh
->disp_w
;
162 pbi
->biHeight
= sh
->disp_h
;
164 decore(&dec_handle
, DEC_OPT_INIT
, &dec_init
, NULL
);
165 decore(dec_handle
, DEC_OPT_SETOUT
, pbi
, NULL
);
167 iInstruction
= DEC_ADJ_POSTPROCESSING
| DEC_ADJ_SET
;
168 decore(dec_handle
, DEC_OPT_ADJUST
, &iInstruction
, &divx_quality
);
171 #else // DECORE_VERSION < 20021112
176 if(sh
->format
==mmioFOURCC('D','I','V','3')){
177 mp_msg(MSGT_DECVIDEO
,MSGL_INFO
,"DivX 3.x not supported by opendivx decore - it requires divx4linux\n");
178 return 0; // not supported
182 if(sh
->format
==mmioFOURCC('D','X','5','0')){
183 mp_msg(MSGT_DECVIDEO
,MSGL_INFO
,"DivX 5.00 not supported by divx4linux decore - it requires divx5linux\n");
184 return 0; // not supported
188 memset(&dec_param
,0,sizeof(dec_param
));
190 dec_param
.output_format
=DEC_USER
;
192 dec_param
.color_depth
= 32;
196 case mmioFOURCC('D','I','V','3'):
197 dec_param
.codec_version
= 311;
199 case mmioFOURCC('D','I','V','X'):
200 dec_param
.codec_version
= 400;
202 case mmioFOURCC('D','X','5','0'):
203 default: // Fallback to DivX 5 behaviour
204 dec_param
.codec_version
= 500;
206 dec_param
.build_number
= 0;
208 dec_param
.x_dim
= sh
->disp_w
;
209 dec_param
.y_dim
= sh
->disp_h
;
210 decore(0x123, DEC_OPT_INIT
, &dec_param
, NULL
);
212 dec_set
.postproc_level
= divx_quality
;
213 decore(0x123, DEC_OPT_SETPP
, &dec_set
, NULL
);
214 #endif // DECORE_VERSION
216 mp_msg(MSGT_DECVIDEO
,MSGL_V
,"INFO: OpenDivX video codec init OK!\n");
218 return mpcodecs_config_vo(sh
,sh
->disp_w
,sh
->disp_h
,IMGFMT_YV12
);
222 static void uninit(sh_video_t
*sh
){
223 #if DECORE_VERSION >= 20021112
224 decore(dec_handle
, DEC_OPT_RELEASE
, NULL
, NULL
);
227 decore(0x123,DEC_OPT_RELEASE
,NULL
,NULL
);
231 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
234 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
){
238 #if DECORE_VERSION >= 20021112
239 DEC_FRAME_INFO dec_pic
;
245 if(len
<=0) return NULL
; // skipped frame
247 dec_frame
.length
= len
;
248 dec_frame
.bitstream
= data
;
249 dec_frame
.render_flag
= (flags
&3)?0:1;
252 #if DECORE_VERSION >= 20021112
253 dec_frame
.stride
=sh
->disp_w
;
254 decore(dec_handle
, DEC_OPT_FRAME
, &dec_frame
, &dec_pic
);
256 dec_frame
.bmp
=&dec_pic
;
257 dec_pic
.y
=dec_pic
.u
=dec_pic
.v
=NULL
;
258 #ifndef DEC_OPT_FRAME_311
259 decore(0x123, DEC_OPT_FRAME
, &dec_frame
, NULL
);
261 decore(0x123, (sh
->format
==mmioFOURCC('D','I','V','3'))?DEC_OPT_FRAME_311
:DEC_OPT_FRAME
, &dec_frame
, NULL
);
266 opendivx_src
[0]=NULL
;
267 decore(0x123, 0, &dec_frame
, NULL
);
270 if(flags
&3) return NULL
; // framedrop
273 if(!dec_pic
.y
) return NULL
; // bad frame
275 if(!opendivx_src
[0]) return NULL
; // bad frame
278 mpi
=mpcodecs_get_image(sh
, MP_IMGTYPE_EXPORT
, MP_IMGFLAG_PRESERVE
,
279 sh
->disp_w
, sh
->disp_h
);
280 if(!mpi
) return NULL
;
283 mpi
->planes
[0]=dec_pic
.y
;
284 mpi
->planes
[1]=dec_pic
.u
;
285 mpi
->planes
[2]=dec_pic
.v
;
286 mpi
->stride
[0]=dec_pic
.stride_y
;
287 mpi
->stride
[1]=mpi
->stride
[2]=dec_pic
.stride_uv
;
289 mpi
->planes
[0]=opendivx_src
[0];
290 mpi
->planes
[1]=opendivx_src
[1];
291 mpi
->planes
[2]=opendivx_src
[2];
292 mpi
->stride
[0]=opendivx_stride
[0];
293 mpi
->stride
[1]=opendivx_stride
[1];
294 mpi
->stride
[2]=opendivx_stride
[2];