dx50 = DX50
[mplayer/glamo.git] / libmpcodecs / vd_odivx.c
blob986814939a750754f63d960f1b354f3b895160d3
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
5 #include "config.h"
6 #include "mp_msg.h"
7 #include "help_mp.h"
9 #ifdef USE_DIVX
11 #include "vd_internal.h"
13 static vd_info_t info = {
14 #ifdef NEW_DECORE
15 #ifdef DECORE_DIVX5
16 "DivX5Linux lib (odivx compat.)",
17 #else
18 #ifdef DECORE_XVID
19 "XviD lib (odivx compat.)",
20 #else
21 "DivX4Linux lib (odivx compat.)",
22 #endif
23 #endif
24 #else
25 "Opendivx 0.48 codec",
26 #endif
27 "odivx",
28 "A'rpi",
29 #ifdef NEW_DECORE
30 #ifdef DECORE_XVID
31 "http://www.xvid.com",
32 #else
33 "http://www.divx.com",
34 #endif
35 #else
36 "http://www.projectmayo.org",
37 #endif
38 #ifdef NEW_DECORE
39 "native binary codec"
40 #else
41 "native codec"
42 #endif
45 LIBVD_EXTERN(odivx)
47 #ifndef NEW_DECORE
48 #include "opendivx/decore.h"
49 #include "postproc/postprocess.h"
50 #elif DECORE_XVID
51 #include <divx4.h>
52 #else
53 #include <decore.h>
54 #endif
56 #ifndef DECORE_VERSION
57 #define DECORE_VERSION 0
58 #endif
60 #if DECORE_VERSION >= 20021112
61 static void* dec_handle = NULL;
62 #endif
64 //**************************************************************************//
65 // The OpenDivX stuff:
66 //**************************************************************************//
68 #ifndef NEW_DECORE
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;
88 #endif
91 // to set/get/query special features/parameters
92 static int control(sh_video_t *sh,int cmd,void* arg,...){
93 switch(cmd){
94 case VDCTRL_QUERY_MAX_PP_LEVEL:
95 #ifdef NEW_DECORE
96 #if DECORE_VERSION >= 20021112
97 return 6; // divx4linux >= 5.0.5 -> 0..60
98 #else
99 return 10; // divx4linux < 5.0.5 -> 0..100
100 #endif
101 #else
102 return PP_QUALITY_MAX; // for opendivx
103 #endif
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);
112 #else
113 DEC_SET dec_set;
114 #ifdef NEW_DECORE
115 if(quality<0 || quality>10) quality=10;
116 dec_set.postproc_level=quality*10;
117 #else
118 if(quality<0 || quality>PP_QUALITY_MAX) quality=PP_QUALITY_MAX;
119 dec_set.postproc_level=getPpModeForQuality(quality);
120 #endif
121 decore(0x123,DEC_OPT_SETPP,&dec_set,NULL);
122 #endif
123 return CONTROL_OK;
128 return CONTROL_UNKNOWN;
131 // init driver
132 static int init(sh_video_t *sh){
133 #if DECORE_VERSION >= 20021112
134 DEC_INIT dec_init;
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);
142 switch(sh->format) {
143 case mmioFOURCC('D','I','V','3'):
144 dec_init.codec_version = 311;
145 break;
146 case mmioFOURCC('D','I','V','X'):
147 dec_init.codec_version = 412;
148 break;
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;
157 pbi->biSize=iSize;
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);
170 free(pbi);
171 #else // DECORE_VERSION < 20021112
172 DEC_PARAM dec_param;
173 DEC_SET dec_set;
175 #ifndef NEW_DECORE
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
180 #endif
181 #ifndef DECORE_DIVX5
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
186 #endif
188 memset(&dec_param,0,sizeof(dec_param));
189 #ifdef NEW_DECORE
190 dec_param.output_format=DEC_USER;
191 #else
192 dec_param.color_depth = 32;
193 #endif
194 #ifdef DECORE_DIVX5
195 switch(sh->format) {
196 case mmioFOURCC('D','I','V','3'):
197 dec_param.codec_version = 311;
198 break;
199 case mmioFOURCC('D','I','V','X'):
200 dec_param.codec_version = 400;
201 break;
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;
207 #endif
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);
221 // uninit driver
222 static void uninit(sh_video_t *sh){
223 #if DECORE_VERSION >= 20021112
224 decore(dec_handle, DEC_OPT_RELEASE, NULL, NULL);
225 dec_handle = NULL;
226 #else
227 decore(0x123,DEC_OPT_RELEASE,NULL,NULL);
228 #endif
231 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
233 // decode a frame
234 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
235 mp_image_t* mpi;
236 DEC_FRAME dec_frame;
237 #ifdef NEW_DECORE
238 #if DECORE_VERSION >= 20021112
239 DEC_FRAME_INFO dec_pic;
240 #else
241 DEC_PICTURE dec_pic;
242 #endif
243 #endif
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;
251 #ifdef NEW_DECORE
252 #if DECORE_VERSION >= 20021112
253 dec_frame.stride=sh->disp_w;
254 decore(dec_handle, DEC_OPT_FRAME, &dec_frame, &dec_pic);
255 #else
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);
260 #else
261 decore(0x123, (sh->format==mmioFOURCC('D','I','V','3'))?DEC_OPT_FRAME_311:DEC_OPT_FRAME, &dec_frame, NULL);
262 #endif
263 #endif
264 #else
265 // opendivx:
266 opendivx_src[0]=NULL;
267 decore(0x123, 0, &dec_frame, NULL);
268 #endif
270 if(flags&3) return NULL; // framedrop
272 #ifdef NEW_DECORE
273 if(!dec_pic.y) return NULL; // bad frame
274 #else
275 if(!opendivx_src[0]) return NULL; // bad frame
276 #endif
278 mpi=mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, MP_IMGFLAG_PRESERVE,
279 sh->disp_w, sh->disp_h);
280 if(!mpi) return NULL;
282 #ifdef NEW_DECORE
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;
288 #else
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];
295 #endif
297 return mpi;
300 #endif