2775
|
1
|
|
2 #include "config.h"
|
1294
|
3
|
|
4 #include <stdio.h>
|
2775
|
5 #ifdef HAVE_MALLOC_H
|
|
6 #include <malloc.h>
|
|
7 #endif
|
1294
|
8 #include <stdlib.h>
|
1430
|
9 #include <unistd.h>
|
1294
|
10
|
1567
|
11 #include "mp_msg.h"
|
1973
|
12 #include "help_mp.h"
|
1294
|
13
|
9380
|
14 #include "osdep/timer.h"
|
|
15 #include "osdep/shmem.h"
|
1327
|
16
|
1294
|
17 #include "stream.h"
|
|
18 #include "demuxer.h"
|
1375
|
19 #include "parse_es.h"
|
1294
|
20
|
|
21 #include "codec-cfg.h"
|
|
22
|
|
23 #include "libvo/video_out.h"
|
|
24
|
4188
|
25 #include "stheader.h"
|
4902
|
26 #include "vd.h"
|
5507
|
27 #include "vf.h"
|
4188
|
28
|
2563
|
29 #include "dec_video.h"
|
|
30
|
8152
|
31 #ifdef DYNAMIC_PLUGINS
|
|
32 #include <dlfcn.h>
|
|
33 #endif
|
|
34
|
2563
|
35 // ===================================================================
|
|
36
|
|
37 extern double video_time_usage;
|
|
38 extern double vout_time_usage;
|
|
39
|
3144
|
40 #include "cpudetect.h"
|
|
41
|
2563
|
42 int divx_quality=0;
|
1294
|
43
|
5180
|
44 vd_functions_t* mpvdec=NULL;
|
4902
|
45
|
1429
|
46 int get_video_quality_max(sh_video_t *sh_video){
|
5519
|
47 vf_instance_t* vf=sh_video->vfilter;
|
|
48 if(vf){
|
|
49 int ret=vf->control(vf,VFCTRL_QUERY_MAX_PP_LEVEL,NULL);
|
|
50 if(ret>0){
|
6989
|
51 mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_UsingExternalPP,ret);
|
5519
|
52 return ret;
|
|
53 }
|
|
54 }
|
4957
|
55 if(mpvdec){
|
4967
|
56 int ret=mpvdec->control(sh_video,VDCTRL_QUERY_MAX_PP_LEVEL,NULL);
|
5519
|
57 if(ret>0){
|
6989
|
58 mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_UsingCodecPP,ret);
|
5519
|
59 return ret;
|
|
60 }
|
4957
|
61 }
|
6138
|
62 // mp_msg(MSGT_DECVIDEO,MSGL_INFO,"[PP] Sorry, postprocessing is not available\n");
|
5519
|
63 return 0;
|
1429
|
64 }
|
|
65
|
|
66 void set_video_quality(sh_video_t *sh_video,int quality){
|
5519
|
67 vf_instance_t* vf=sh_video->vfilter;
|
|
68 if(vf){
|
|
69 int ret=vf->control(vf,VFCTRL_SET_PP_LEVEL, (void*)(&quality));
|
|
70 if(ret==CONTROL_TRUE) return; // success
|
|
71 }
|
4957
|
72 if(mpvdec)
|
|
73 mpvdec->control(sh_video,VDCTRL_SET_PP_LEVEL, (void*)(&quality));
|
1429
|
74 }
|
|
75
|
4395
|
76 int set_video_colors(sh_video_t *sh_video,char *item,int value)
|
|
77 {
|
6780
|
78 vf_instance_t* vf=sh_video->vfilter;
|
6832
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
79 vf_equalizer_t data;
|
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
80
|
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
81 data.item = item;
|
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
82 data.value = value;
|
6786
|
83
|
|
84 mp_dbg(MSGT_DECVIDEO,MSGL_V,"set video colors %s=%d \n", item, value);
|
6785
|
85 if (vf)
|
|
86 {
|
6832
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
87 int ret = vf->control(vf, VFCTRL_SET_EQUALIZER, &data);
|
6785
|
88 if (ret == CONTROL_TRUE)
|
|
89 return(1);
|
|
90 }
|
6780
|
91 /* try software control */
|
6800
|
92 if(mpvdec)
|
|
93 if( mpvdec->control(sh_video,VDCTRL_SET_EQUALIZER, item, (int *)value)
|
|
94 == CONTROL_OK) return 1;
|
6989
|
95 mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_VideoAttributeNotSupportedByVO_VD,item);
|
6780
|
96 return 0;
|
|
97 }
|
|
98
|
|
99 int get_video_colors(sh_video_t *sh_video,char *item,int *value)
|
|
100 {
|
|
101 vf_instance_t* vf=sh_video->vfilter;
|
6832
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
102 vf_equalizer_t data;
|
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
103
|
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
104 data.item = item;
|
6786
|
105
|
|
106 mp_dbg(MSGT_DECVIDEO,MSGL_V,"get video colors %s \n", item);
|
|
107 if (vf)
|
|
108 {
|
6832
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
109 int ret = vf->control(vf, VFCTRL_GET_EQUALIZER, &data);
|
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
110 if (ret == CONTROL_TRUE){
|
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
111 *value = data.value;
|
6786
|
112 return(1);
|
6832
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
diff
changeset
|
113 }
|
6786
|
114 }
|
6780
|
115 /* try software control */
|
|
116 if(mpvdec) return mpvdec->control(sh_video,VDCTRL_GET_EQUALIZER, item, value);
|
1429
|
117 return 0;
|
|
118 }
|
1294
|
119
|
6887
|
120 int set_rectangle(sh_video_t *sh_video,int param,int value)
|
|
121 {
|
|
122 vf_instance_t* vf=sh_video->vfilter;
|
|
123 int data[] = {param, value};
|
|
124
|
|
125 mp_dbg(MSGT_DECVIDEO,MSGL_V,"set rectangle \n");
|
|
126 if (vf)
|
|
127 {
|
|
128 int ret = vf->control(vf, VFCTRL_CHANGE_RECTANGLE, data);
|
|
129 if (ret)
|
|
130 return(1);
|
|
131 }
|
|
132 return 0;
|
|
133 }
|
|
134
|
11977
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
diff
changeset
|
135 void resync_video_stream(sh_video_t *sh_video)
|
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
diff
changeset
|
136 {
|
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
diff
changeset
|
137 if(mpvdec) mpvdec->control(sh_video, VDCTRL_RESYNC_STREAM, NULL);
|
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
diff
changeset
|
138 }
|
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
diff
changeset
|
139
|
2049
|
140 void uninit_video(sh_video_t *sh_video){
|
1654
|
141 if(!sh_video->inited) return;
|
7180
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
diff
changeset
|
142 mp_msg(MSGT_DECVIDEO,MSGL_V,MSGTR_UninitVideoStr,sh_video->codec->drv);
|
4902
|
143 mpvdec->uninit(sh_video);
|
8152
|
144 #ifdef DYNAMIC_PLUGINS
|
|
145 if (sh_video->dec_handle)
|
|
146 dlclose(sh_video->dec_handle);
|
|
147 #endif
|
5737
|
148 vf_uninit_filter_chain(sh_video->vfilter);
|
1654
|
149 sh_video->inited=0;
|
|
150 }
|
|
151
|
17566
|
152 void vfm_help(void){
|
7191
|
153 int i;
|
|
154 mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_AvailableVideoFm);
|
15789
32d9c8a0a02b
adds some more -identify output, patch by kiriuja < mplayer DASH patches PAM en DASH directo POUM net>
gpoirier
diff
changeset
|
155 if (identify)
|
32d9c8a0a02b
adds some more -identify output, patch by kiriuja < mplayer DASH patches PAM en DASH directo POUM net>
gpoirier
diff
changeset
|
156 mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_DRIVERS\n");
|
7191
|
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);
|
|
163 }
|
|
164
|
7180
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
diff
changeset
|
165 int init_video(sh_video_t *sh_video,char* codecname,char* vfm,int status){
|
16325
|
166 int force = 0;
|
6230
|
167 unsigned int orig_fourcc=sh_video->bih?sh_video->bih->biCompression:0;
|
5171
|
168 sh_video->codec=NULL;
|
5925
|
169 sh_video->vf_inited=0;
|
16321
|
170 if (codecname && codecname[0] == '+') {
|
|
171 codecname = &codecname[1];
|
|
172 force = 1;
|
|
173 }
|
6230
|
174
|
|
175 while(1){
|
|
176 int i;
|
|
177 // restore original fourcc:
|
|
178 if(sh_video->bih) sh_video->bih->biCompression=orig_fourcc;
|
16321
|
179 if(!(sh_video->codec=find_video_codec(sh_video->format,
|
6230
|
180 sh_video->bih?((unsigned int*) &sh_video->bih->biCompression):NULL,
|
16321
|
181 sh_video->codec,force) )) break;
|
5171
|
182 // ok we found one codec
|
5328
|
183 if(sh_video->codec->flags&CODECS_FLAG_SELECTED) continue; // already tried & failed
|
5171
|
184 if(codecname && strcmp(sh_video->codec->name,codecname)) continue; // -vc
|
7180
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
diff
changeset
|
185 if(vfm && strcmp(sh_video->codec->drv,vfm)) continue; // vfm doesn't match
|
16321
|
186 if(!force && sh_video->codec->status<status) continue; // too unstable
|
5328
|
187 sh_video->codec->flags|=CODECS_FLAG_SELECTED; // tagging it
|
5171
|
188 // ok, it matches all rules, let's find the driver!
|
|
189 for (i=0; mpcodecs_vd_drivers[i] != NULL; i++)
|
7180
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
diff
changeset
|
190 // if(mpcodecs_vd_drivers[i]->info->id==sh_video->codec->driver) break;
|
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
diff
changeset
|
191 if(!strcmp(mpcodecs_vd_drivers[i]->info->short_name,sh_video->codec->drv)) break;
|
5171
|
192 mpvdec=mpcodecs_vd_drivers[i];
|
8152
|
193 #ifdef DYNAMIC_PLUGINS
|
|
194 if (!mpvdec)
|
|
195 {
|
|
196 /* try to open shared decoder plugin */
|
|
197 int buf_len;
|
|
198 char *buf;
|
|
199 vd_functions_t *funcs_sym;
|
|
200 vd_info_t *info_sym;
|
|
201
|
10272
|
202 buf_len = strlen(MPLAYER_LIBDIR)+strlen(sh_video->codec->drv)+16;
|
8152
|
203 buf = malloc(buf_len);
|
|
204 if (!buf)
|
|
205 break;
|
10272
|
206 snprintf(buf, buf_len, "%s/mplayer/vd_%s.so", MPLAYER_LIBDIR, sh_video->codec->drv);
|
8152
|
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)
|
|
210 break;
|
|
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)
|
|
215 break;
|
|
216 info_sym = funcs_sym->info;
|
|
217 if (strcmp(info_sym->short_name, sh_video->codec->drv))
|
|
218 break;
|
|
219 free(buf);
|
|
220 mpvdec = funcs_sym;
|
|
221 mp_msg(MSGT_DECVIDEO, MSGL_V, "Using external decoder plugin (%s/mplayer/vd_%s.so)!\n",
|
10272
|
222 MPLAYER_LIBDIR, sh_video->codec->drv);
|
8152
|
223 }
|
|
224 #endif
|
5171
|
225 if(!mpvdec){ // driver not available (==compiled in)
|
7180
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
diff
changeset
|
226 mp_msg(MSGT_DECVIDEO,MSGL_WARN,MSGTR_VideoCodecFamilyNotAvailableStr,
|
28677d779205
-afm/-vfm migration from ID (int) to NAME (string) - simplifies code and makes dlopen()'ing possible
arpi
diff
changeset
|
227 sh_video->codec->name, sh_video->codec->drv);
|
5171
|
228 continue;
|
|
229 }
|
|
230 // it's available, let's try to init!
|
6566
|
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!
|
|
234 if(sh_video->bih){
|
|
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);
|
|
237 } else {
|
|
238 sh_video->disp_w=(sh_video->disp_w+15)&(~15);
|
|
239 sh_video->disp_h=(sh_video->disp_h+15)&(~15);
|
|
240 }
|
|
241 }
|
|
242 // init()
|
6989
|
243 mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_OpeningVideoDecoder,mpvdec->info->short_name,mpvdec->info->name);
|
5171
|
244 if(!mpvdec->init(sh_video)){
|
6989
|
245 mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_VDecoderInitFailed);
|
5171
|
246 continue; // try next...
|
|
247 }
|
|
248 // Yeah! We got it!
|
|
249 sh_video->inited=1;
|
|
250 return 1;
|
4902
|
251 }
|
5171
|
252 return 0;
|
1294
|
253 }
|
|
254
|
8123
|
255 extern char *get_path(char *filename);
|
|
256
|
7506
|
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};
|
|
259 // hack:
|
|
260 if(!video_codec_list) video_codec_list=vc_l_default;
|
7502
|
261 // Go through the codec.conf and find the best codec...
|
|
262 sh_video->inited=0;
|
|
263 codecs_reset_selection(0);
|
7506
|
264 while(!sh_video->inited && *video_codec_list){
|
|
265 char* video_codec=*(video_codec_list++);
|
|
266 if(video_codec[0]){
|
|
267 if(video_codec[0]=='-'){
|
|
268 // disable this codec:
|
|
269 select_codec(video_codec+1,0);
|
|
270 } else {
|
|
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);
|
|
274 }
|
|
275 } else {
|
7502
|
276 int status;
|
|
277 // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING.
|
7506
|
278 if(video_fm_list){
|
|
279 char** fmlist=video_fm_list;
|
|
280 // try first the preferred codec families:
|
|
281 while(!sh_video->inited && *fmlist){
|
|
282 char* video_fm=*(fmlist++);
|
7502
|
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;
|
7506
|
286 }
|
7502
|
287 }
|
|
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;
|
7506
|
291 }
|
7502
|
292 }
|
|
293
|
|
294 if(!sh_video->inited){
|
|
295 mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CantFindVideoCodec,sh_video->format);
|
10683
|
296 mp_msg(MSGT_DECAUDIO,MSGL_HINT, MSGTR_RTFMCodecs);
|
7502
|
297 return 0; // failed
|
|
298 }
|
|
299
|
16793
|
300 mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_SelectedVideoCodec,
|
7506
|
301 sh_video->codec->name,sh_video->codec->drv,sh_video->codec->info);
|
7502
|
302 return 1; // success
|
|
303 }
|
|
304
|
5224
|
305 extern int vo_directrendering;
|
4515
|
306
|
5507
|
307 int decode_video(sh_video_t *sh_video,unsigned char *start,int in_size,int drop_frame){
|
7210
|
308 vf_instance_t* vf;
|
4898
|
309 mp_image_t *mpi=NULL;
|
1360
|
310 unsigned int t=GetTimer();
|
|
311 unsigned int t2;
|
4834
|
312 double tt;
|
7368
|
313 int ret;
|
1360
|
314
|
5266
|
315 //if(!(sh_video->ds->flags&1) || sh_video->ds->pack_no<5)
|
4902
|
316 mpi=mpvdec->decode(sh_video, start, in_size, drop_frame);
|
|
317
|
1294
|
318 //------------------------ frame decoded. --------------------
|
|
319
|
3160
|
320 #ifdef ARCH_X86
|
6780
|
321 // some codecs are broken, and doesn't restore MMX state :(
|
1367
|
322 // it happens usually with broken/damaged files.
|
3144
|
323 if(gCpuCaps.has3DNow){
|
|
324 __asm __volatile ("femms\n\t":::"memory");
|
|
325 }
|
|
326 else if(gCpuCaps.hasMMX){
|
|
327 __asm __volatile ("emms\n\t":::"memory");
|
|
328 }
|
3160
|
329 #endif
|
1367
|
330
|
4834
|
331 t2=GetTimer();t=t2-t;
|
|
332 tt = t*0.000001f;
|
|
333 video_time_usage+=tt;
|
4898
|
334
|
5643
|
335 if(!mpi || drop_frame) return 0; // error / skipped frame
|
5040
|
336
|
5507
|
337 //vo_draw_image(video_out,mpi);
|
7210
|
338 vf=sh_video->vfilter;
|
7368
|
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);
|
4898
|
341
|
4834
|
342 t2=GetTimer()-t2;
|
|
343 tt=t2*0.000001f;
|
|
344 vout_time_usage+=tt;
|
1360
|
345
|
7368
|
346 return ret;
|
1294
|
347 }
|