14
#include "osdep/timer.h"
15
#include "osdep/shmem.h"
21
#include "codec-cfg.h"
23
#include "libvo/video_out.h"
29
#include "dec_video.h"
31
#ifdef DYNAMIC_PLUGINS
35
// ===================================================================
37
extern double video_time_usage;
38
extern double vout_time_usage;
40
#include "cpudetect.h"
44
vd_functions_t* mpvdec=NULL;
46
int get_video_quality_max(sh_video_t *sh_video){
47
vf_instance_t* vf=sh_video->vfilter;
49
int ret=vf->control(vf,VFCTRL_QUERY_MAX_PP_LEVEL,NULL);
51
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_UsingExternalPP,ret);
56
int ret=mpvdec->control(sh_video,VDCTRL_QUERY_MAX_PP_LEVEL,NULL);
58
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_UsingCodecPP,ret);
62
// mp_msg(MSGT_DECVIDEO,MSGL_INFO,"[PP] Sorry, postprocessing is not available\n");
66
void set_video_quality(sh_video_t *sh_video,int quality){
67
vf_instance_t* vf=sh_video->vfilter;
69
int ret=vf->control(vf,VFCTRL_SET_PP_LEVEL, (void*)(&quality));
70
if(ret==CONTROL_TRUE) return; // success
73
mpvdec->control(sh_video,VDCTRL_SET_PP_LEVEL, (void*)(&quality));
76
int set_video_colors(sh_video_t *sh_video,char *item,int value)
78
vf_instance_t* vf=sh_video->vfilter;
84
mp_dbg(MSGT_DECVIDEO,MSGL_V,"set video colors %s=%d \n", item, value);
87
int ret = vf->control(vf, VFCTRL_SET_EQUALIZER, &data);
88
if (ret == CONTROL_TRUE)
91
/* try software control */
93
if( mpvdec->control(sh_video,VDCTRL_SET_EQUALIZER, item, (int *)value)
94
== CONTROL_OK) return 1;
95
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_VideoAttributeNotSupportedByVO_VD,item);
99
int get_video_colors(sh_video_t *sh_video,char *item,int *value)
101
vf_instance_t* vf=sh_video->vfilter;
106
mp_dbg(MSGT_DECVIDEO,MSGL_V,"get video colors %s \n", item);
109
int ret = vf->control(vf, VFCTRL_GET_EQUALIZER, &data);
110
if (ret == CONTROL_TRUE){
115
/* try software control */
116
if(mpvdec) return mpvdec->control(sh_video,VDCTRL_GET_EQUALIZER, item, value);
120
int set_rectangle(sh_video_t *sh_video,int param,int value)
122
vf_instance_t* vf=sh_video->vfilter;
123
int data[] = {param, value};
125
mp_dbg(MSGT_DECVIDEO,MSGL_V,"set rectangle \n");
128
int ret = vf->control(vf, VFCTRL_CHANGE_RECTANGLE, data);
135
void resync_video_stream(sh_video_t *sh_video)
137
if(mpvdec) mpvdec->control(sh_video, VDCTRL_RESYNC_STREAM, NULL);
140
void uninit_video(sh_video_t *sh_video){
141
if(!sh_video->inited) return;
142
mp_msg(MSGT_DECVIDEO,MSGL_V,MSGTR_UninitVideoStr,sh_video->codec->drv);
143
mpvdec->uninit(sh_video);
144
#ifdef DYNAMIC_PLUGINS
145
if (sh_video->dec_handle)
146
dlclose(sh_video->dec_handle);
148
vf_uninit_filter_chain(sh_video->vfilter);
154
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_AvailableVideoFm);
156
mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_DRIVERS\n");
157
mp_msg(MSGT_DECVIDEO,MSGL_INFO," vfm: info: (comment)\n");
158
for (i=0; mpcodecs_vd_drivers[i] != NULL; i++)
159
mp_msg(MSGT_DECVIDEO,MSGL_INFO,"%8s %s (%s)\n",
160
mpcodecs_vd_drivers[i]->info->short_name,
161
mpcodecs_vd_drivers[i]->info->name,
162
mpcodecs_vd_drivers[i]->info->comment);
165
int init_video(sh_video_t *sh_video,char* codecname,char* vfm,int status){
167
unsigned int orig_fourcc=sh_video->bih?sh_video->bih->biCompression:0;
168
sh_video->codec=NULL;
169
sh_video->vf_inited=0;
170
if (codecname && codecname[0] == '+') {
171
codecname = &codecname[1];
177
// restore original fourcc:
178
if(sh_video->bih) sh_video->bih->biCompression=orig_fourcc;
179
if(!(sh_video->codec=find_video_codec(sh_video->format,
180
sh_video->bih?((unsigned int*) &sh_video->bih->biCompression):NULL,
181
sh_video->codec,force) )) break;
182
// ok we found one codec
183
if(sh_video->codec->flags&CODECS_FLAG_SELECTED) continue; // already tried & failed
184
if(codecname && strcmp(sh_video->codec->name,codecname)) continue; // -vc
185
if(vfm && strcmp(sh_video->codec->drv,vfm)) continue; // vfm doesn't match
186
if(!force && sh_video->codec->status<status) continue; // too unstable
187
sh_video->codec->flags|=CODECS_FLAG_SELECTED; // tagging it
188
// ok, it matches all rules, let's find the driver!
189
for (i=0; mpcodecs_vd_drivers[i] != NULL; i++)
190
// if(mpcodecs_vd_drivers[i]->info->id==sh_video->codec->driver) break;
191
if(!strcmp(mpcodecs_vd_drivers[i]->info->short_name,sh_video->codec->drv)) break;
192
mpvdec=mpcodecs_vd_drivers[i];
193
#ifdef DYNAMIC_PLUGINS
196
/* try to open shared decoder plugin */
199
vd_functions_t *funcs_sym;
202
buf_len = strlen(MPLAYER_LIBDIR)+strlen(sh_video->codec->drv)+16;
203
buf = malloc(buf_len);
206
snprintf(buf, buf_len, "%s/mplayer/vd_%s.so", MPLAYER_LIBDIR, sh_video->codec->drv);
207
mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "Trying to open external plugin: %s\n", buf);
208
sh_video->dec_handle = dlopen(buf, RTLD_LAZY);
209
if (!sh_video->dec_handle)
211
snprintf(buf, buf_len, "mpcodecs_vd_%s", sh_video->codec->drv);
212
funcs_sym = dlsym(sh_video->dec_handle, buf);
213
if (!funcs_sym || !funcs_sym->info || !funcs_sym->init ||
214
!funcs_sym->uninit || !funcs_sym->control || !funcs_sym->decode)
216
info_sym = funcs_sym->info;
217
if (strcmp(info_sym->short_name, sh_video->codec->drv))
221
mp_msg(MSGT_DECVIDEO, MSGL_V, "Using external decoder plugin (%s/mplayer/vd_%s.so)!\n",
222
MPLAYER_LIBDIR, sh_video->codec->drv);
225
if(!mpvdec){ // driver not available (==compiled in)
226
mp_msg(MSGT_DECVIDEO,MSGL_WARN,MSGTR_VideoCodecFamilyNotAvailableStr,
227
sh_video->codec->name, sh_video->codec->drv);
230
// it's available, let's try to init!
231
if(sh_video->codec->flags & CODECS_FLAG_ALIGN16){
232
// align width/height to n*16
233
// FIXME: save orig w/h, and restore if codec init failed!
235
sh_video->disp_w=sh_video->bih->biWidth=(sh_video->bih->biWidth+15)&(~15);
236
sh_video->disp_h=sh_video->bih->biHeight=(sh_video->bih->biHeight+15)&(~15);
238
sh_video->disp_w=(sh_video->disp_w+15)&(~15);
239
sh_video->disp_h=(sh_video->disp_h+15)&(~15);
243
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_OpeningVideoDecoder,mpvdec->info->short_name,mpvdec->info->name);
244
if(!mpvdec->init(sh_video)){
245
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_VDecoderInitFailed);
246
continue; // try next...
255
extern char *get_path(char *filename);
257
int init_best_video_codec(sh_video_t *sh_video,char** video_codec_list,char** video_fm_list){
258
char* vc_l_default[2]={"",(char*)NULL};
260
if(!video_codec_list) video_codec_list=vc_l_default;
261
// Go through the codec.conf and find the best codec...
263
codecs_reset_selection(0);
264
while(!sh_video->inited && *video_codec_list){
265
char* video_codec=*(video_codec_list++);
267
if(video_codec[0]=='-'){
268
// disable this codec:
269
select_codec(video_codec+1,0);
271
// forced codec by name:
272
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_ForcedVideoCodec,video_codec);
273
init_video(sh_video,video_codec,NULL,-1);
277
// try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING.
279
char** fmlist=video_fm_list;
280
// try first the preferred codec families:
281
while(!sh_video->inited && *fmlist){
282
char* video_fm=*(fmlist++);
283
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_TryForceVideoFmtStr,video_fm);
284
for(status=CODECS_STATUS__MAX;status>=CODECS_STATUS__MIN;--status)
285
if(init_video(sh_video,NULL,video_fm,status)) break;
288
if(!sh_video->inited)
289
for(status=CODECS_STATUS__MAX;status>=CODECS_STATUS__MIN;--status)
290
if(init_video(sh_video,NULL,NULL,status)) break;
294
if(!sh_video->inited){
295
mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CantFindVideoCodec,sh_video->format);
296
mp_msg(MSGT_DECAUDIO,MSGL_HINT, MSGTR_RTFMCodecs);
300
mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_SelectedVideoCodec,
301
sh_video->codec->name,sh_video->codec->drv,sh_video->codec->info);
305
extern int vo_directrendering;
307
int decode_video(sh_video_t *sh_video,unsigned char *start,int in_size,int drop_frame){
309
mp_image_t *mpi=NULL;
310
unsigned int t=GetTimer();
315
//if(!(sh_video->ds->flags&1) || sh_video->ds->pack_no<5)
316
mpi=mpvdec->decode(sh_video, start, in_size, drop_frame);
318
//------------------------ frame decoded. --------------------
321
// some codecs are broken, and doesn't restore MMX state :(
322
// it happens usually with broken/damaged files.
323
if(gCpuCaps.has3DNow){
324
__asm __volatile ("femms\n\t":::"memory");
326
else if(gCpuCaps.hasMMX){
327
__asm __volatile ("emms\n\t":::"memory");
331
t2=GetTimer();t=t2-t;
333
video_time_usage+=tt;
335
if(!mpi || drop_frame) return 0; // error / skipped frame
337
//vo_draw_image(video_out,mpi);
338
vf=sh_video->vfilter;
339
ret = vf->put_image(vf,mpi); // apply video filters and call the leaf vo/ve
340
if(ret>0) vf->control(vf,VFCTRL_DRAW_OSD,NULL);