2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "osdep/timer.h"
30 #include "osdep/shmem.h"
32 #include "stream/stream.h"
33 #include "libmpdemux/demuxer.h"
34 #include "libmpdemux/parse_es.h"
36 #include "codec-cfg.h"
38 #include "libvo/video_out.h"
39 #include "libvo/csputils.h"
41 #include "libmpdemux/stheader.h"
45 #include "dec_video.h"
47 // ===================================================================
49 extern double video_time_usage
;
50 extern double vout_time_usage
;
52 #include "cpudetect.h"
54 int field_dominance
= -1;
58 int get_video_quality_max(sh_video_t
*sh_video
)
60 vf_instance_t
*vf
= sh_video
->vfilter
;
62 int ret
= vf
->control(vf
, VFCTRL_QUERY_MAX_PP_LEVEL
, NULL
);
64 mp_tmsg(MSGT_DECVIDEO
, MSGL_INFO
, "[PP] Using external postprocessing filter, max q = %d.\n", ret
);
68 const struct vd_functions
*vd
= sh_video
->vd_driver
;
70 int ret
= vd
->control(sh_video
, VDCTRL_QUERY_MAX_PP_LEVEL
, NULL
);
72 mp_tmsg(MSGT_DECVIDEO
, MSGL_INFO
, "[PP] Using codec's postprocessing, max q = %d.\n", ret
);
79 void set_video_quality(sh_video_t
*sh_video
, int quality
)
81 vf_instance_t
*vf
= sh_video
->vfilter
;
83 int ret
= vf
->control(vf
, VFCTRL_SET_PP_LEVEL
, (void *) (&quality
));
84 if (ret
== CONTROL_TRUE
)
87 const struct vd_functions
*vd
= sh_video
->vd_driver
;
89 vd
->control(sh_video
, VDCTRL_SET_PP_LEVEL
, (void *) (&quality
));
92 int set_video_colors(sh_video_t
*sh_video
, const char *item
, int value
)
94 vf_instance_t
*vf
= sh_video
->vfilter
;
100 mp_dbg(MSGT_DECVIDEO
, MSGL_V
, "set video colors %s=%d \n", item
, value
);
102 int ret
= vf
->control(vf
, VFCTRL_SET_EQUALIZER
, &data
);
103 if (ret
== CONTROL_TRUE
)
106 /* try software control */
107 const struct vd_functions
*vd
= sh_video
->vd_driver
;
109 vd
->control(sh_video
, VDCTRL_SET_EQUALIZER
, (void *)item
, value
)
112 mp_tmsg(MSGT_DECVIDEO
, MSGL_V
, "Video attribute '%s' is not supported by selected vo & vd.\n",
117 int get_video_colors(sh_video_t
*sh_video
, const char *item
, int *value
)
119 vf_instance_t
*vf
= sh_video
->vfilter
;
124 mp_dbg(MSGT_DECVIDEO
, MSGL_V
, "get video colors %s \n", item
);
126 int ret
= vf
->control(vf
, VFCTRL_GET_EQUALIZER
, &data
);
127 if (ret
== CONTROL_TRUE
) {
132 /* try software control */
133 const struct vd_functions
*vd
= sh_video
->vd_driver
;
135 return vd
->control(sh_video
, VDCTRL_GET_EQUALIZER
, (void *)item
, value
);
139 void get_detected_video_colorspace(struct sh_video
*sh
, struct mp_csp_details
*csp
)
141 struct MPOpts
*opts
= sh
->opts
;
142 struct vf_instance
*vf
= sh
->vfilter
;
144 csp
->format
= opts
->requested_colorspace
;
145 csp
->levels_in
= opts
->requested_input_range
;
146 csp
->levels_out
= opts
->requested_output_range
;
148 if (csp
->format
== MP_CSP_AUTO
)
149 csp
->format
= mp_csp_guess_colorspace(vf
->w
, vf
->h
);
150 if (csp
->levels_in
== MP_CSP_LEVELS_AUTO
)
151 csp
->levels_in
= MP_CSP_LEVELS_TV
;
152 if (csp
->levels_out
== MP_CSP_LEVELS_AUTO
)
153 csp
->levels_out
= MP_CSP_LEVELS_PC
;
156 void set_video_colorspace(struct sh_video
*sh
)
158 struct vf_instance
*vf
= sh
->vfilter
;
160 struct mp_csp_details requested
;
161 get_detected_video_colorspace(sh
, &requested
);
162 vf
->control(vf
, VFCTRL_SET_YUV_COLORSPACE
, &requested
);
164 struct mp_csp_details actual
= MP_CSP_DETAILS_DEFAULTS
;
165 vf
->control(vf
, VFCTRL_GET_YUV_COLORSPACE
, &actual
);
167 int success
= actual
.format
== requested
.format
168 && actual
.levels_in
== requested
.levels_in
169 && actual
.levels_out
== requested
.levels_out
;
172 mp_tmsg(MSGT_DECVIDEO
, MSGL_WARN
,
173 "Colorspace details not fully supported by selected vo.\n");
175 if (actual
.format
!= requested
.format
176 && requested
.format
== MP_CSP_SMPTE_240M
) {
177 // BT.709 is pretty close, much better than BT.601
178 requested
.format
= MP_CSP_BT_709
;
179 vf
->control(vf
, VFCTRL_SET_YUV_COLORSPACE
, &requested
);
184 int set_rectangle(sh_video_t
*sh_video
, int param
, int value
)
186 vf_instance_t
*vf
= sh_video
->vfilter
;
187 int data
[] = { param
, value
};
189 mp_dbg(MSGT_DECVIDEO
, MSGL_V
, "set rectangle \n");
191 int ret
= vf
->control(vf
, VFCTRL_CHANGE_RECTANGLE
, data
);
198 void resync_video_stream(sh_video_t
*sh_video
)
200 const struct vd_functions
*vd
= sh_video
->vd_driver
;
202 vd
->control(sh_video
, VDCTRL_RESYNC_STREAM
, NULL
);
203 sh_video
->prev_codec_reordered_pts
= MP_NOPTS_VALUE
;
204 sh_video
->prev_sorted_pts
= MP_NOPTS_VALUE
;
207 void video_reset_aspect(struct sh_video
*sh_video
)
209 int r
= sh_video
->vd_driver
->control(sh_video
, VDCTRL_RESET_ASPECT
, NULL
);
211 mpcodecs_config_vo(sh_video
, sh_video
->disp_w
, sh_video
->disp_h
, 0);
214 int get_current_video_decoder_lag(sh_video_t
*sh_video
)
216 const struct vd_functions
*vd
= sh_video
->vd_driver
;
219 int ret
= vd
->control(sh_video
, VDCTRL_QUERY_UNSEEN_FRAMES
, NULL
);
225 void uninit_video(sh_video_t
*sh_video
)
227 if (!sh_video
->initialized
)
229 mp_tmsg(MSGT_DECVIDEO
, MSGL_V
, "Uninit video: %s\n", sh_video
->codec
->drv
);
230 sh_video
->vd_driver
->uninit(sh_video
);
231 vf_uninit_filter_chain(sh_video
->vfilter
);
232 sh_video
->initialized
= 0;
238 mp_tmsg(MSGT_DECVIDEO
, MSGL_INFO
, "Available (compiled-in) video codec families/drivers:\n");
239 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VIDEO_DRIVERS\n");
240 mp_msg(MSGT_DECVIDEO
, MSGL_INFO
, " vfm: info: (comment)\n");
241 for (i
= 0; mpcodecs_vd_drivers
[i
] != NULL
; i
++)
242 mp_msg(MSGT_DECVIDEO
, MSGL_INFO
, "%8s %s (%s)\n",
243 mpcodecs_vd_drivers
[i
]->info
->short_name
,
244 mpcodecs_vd_drivers
[i
]->info
->name
,
245 mpcodecs_vd_drivers
[i
]->info
->comment
);
248 static int init_video(sh_video_t
*sh_video
, char *codecname
, char *vfm
,
249 int status
, stringset_t
*selected
)
252 unsigned int orig_fourcc
=
253 sh_video
->bih
? sh_video
->bih
->biCompression
: 0;
254 sh_video
->codec
= NULL
;
255 sh_video
->vf_initialized
= 0;
256 if (codecname
&& codecname
[0] == '+') {
257 codecname
= &codecname
[1];
264 // restore original fourcc:
266 sh_video
->bih
->biCompression
= orig_fourcc
;
269 find_video_codec(sh_video
->format
,
270 sh_video
->bih
? ((unsigned int *) &sh_video
->
271 bih
->biCompression
) : NULL
,
272 sh_video
->codec
, force
)))
274 // ok we found one codec
275 if (stringset_test(selected
, sh_video
->codec
->name
))
276 continue; // already tried & failed
277 if (codecname
&& strcmp(sh_video
->codec
->name
, codecname
))
279 if (vfm
&& strcmp(sh_video
->codec
->drv
, vfm
))
280 continue; // vfm doesn't match
281 if (!force
&& sh_video
->codec
->status
< status
)
282 continue; // too unstable
283 stringset_add(selected
, sh_video
->codec
->name
); // tagging it
284 // ok, it matches all rules, let's find the driver!
285 for (i
= 0; mpcodecs_vd_drivers
[i
] != NULL
; i
++)
286 if (!strcmp(mpcodecs_vd_drivers
[i
]->info
->short_name
,
287 sh_video
->codec
->drv
))
289 sh_video
->vd_driver
= mpcodecs_vd_drivers
[i
];
290 if (!sh_video
->vd_driver
) { // driver not available (==compiled in)
291 mp_tmsg(MSGT_DECVIDEO
, MSGL_WARN
,
292 _("Requested video codec family [%s] (vfm=%s) not available.\nEnable it at compilation.\n"),
293 sh_video
->codec
->name
, sh_video
->codec
->drv
);
296 orig_w
= sh_video
->bih
? sh_video
->bih
->biWidth
: sh_video
->disp_w
;
297 orig_h
= sh_video
->bih
? sh_video
->bih
->biHeight
: sh_video
->disp_h
;
298 sh_video
->disp_w
= orig_w
;
299 sh_video
->disp_h
= orig_h
;
300 // it's available, let's try to init!
301 if (sh_video
->codec
->flags
& CODECS_FLAG_ALIGN16
) {
302 // align width/height to n*16
303 sh_video
->disp_w
= (sh_video
->disp_w
+ 15) & (~15);
304 sh_video
->disp_h
= (sh_video
->disp_h
+ 15) & (~15);
307 sh_video
->bih
->biWidth
= sh_video
->disp_w
;
308 sh_video
->bih
->biHeight
= sh_video
->disp_h
;
312 const struct vd_functions
*vd
= sh_video
->vd_driver
;
313 mp_tmsg(MSGT_DECVIDEO
, MSGL_INFO
, "Opening video decoder: [%s] %s\n",
314 vd
->info
->short_name
, vd
->info
->name
);
315 // clear vf init error, it is no longer relevant
316 if (sh_video
->vf_initialized
< 0)
317 sh_video
->vf_initialized
= 0;
318 if (!vd
->init(sh_video
)) {
319 mp_tmsg(MSGT_DECVIDEO
, MSGL_INFO
, "VDecoder init failed :(\n");
320 sh_video
->disp_w
= orig_w
;
321 sh_video
->disp_h
= orig_h
;
323 sh_video
->bih
->biWidth
= sh_video
->disp_w
;
324 sh_video
->bih
->biHeight
= sh_video
->disp_h
;
326 continue; // try next...
329 sh_video
->initialized
= 1;
330 sh_video
->prev_codec_reordered_pts
= MP_NOPTS_VALUE
;
331 sh_video
->prev_sorted_pts
= MP_NOPTS_VALUE
;
337 int init_best_video_codec(sh_video_t
*sh_video
, char **video_codec_list
,
338 char **video_fm_list
)
340 char *vc_l_default
[2] = { "", (char *) NULL
};
341 stringset_t selected
;
343 if (!video_codec_list
)
344 video_codec_list
= vc_l_default
;
345 // Go through the codec.conf and find the best codec...
346 sh_video
->initialized
= 0;
347 stringset_init(&selected
);
348 while (!sh_video
->initialized
&& *video_codec_list
) {
349 char *video_codec
= *(video_codec_list
++);
350 if (video_codec
[0]) {
351 if (video_codec
[0] == '-') {
352 // disable this codec:
353 stringset_add(&selected
, video_codec
+ 1);
355 // forced codec by name:
356 mp_tmsg(MSGT_DECVIDEO
, MSGL_INFO
, "Forced video codec: %s\n",
358 init_video(sh_video
, video_codec
, NULL
, -1, &selected
);
362 // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING.
364 char **fmlist
= video_fm_list
;
365 // try first the preferred codec families:
366 while (!sh_video
->initialized
&& *fmlist
) {
367 char *video_fm
= *(fmlist
++);
368 mp_tmsg(MSGT_DECVIDEO
, MSGL_INFO
, "Trying to force video codec driver family %s...\n",
370 for (status
= CODECS_STATUS__MAX
;
371 status
>= CODECS_STATUS__MIN
; --status
)
373 (sh_video
, NULL
, video_fm
, status
, &selected
))
377 if (!sh_video
->initialized
)
378 for (status
= CODECS_STATUS__MAX
; status
>= CODECS_STATUS__MIN
;
380 if (init_video(sh_video
, NULL
, NULL
, status
, &selected
))
384 stringset_free(&selected
);
386 if (!sh_video
->initialized
) {
387 mp_tmsg(MSGT_DECVIDEO
, MSGL_ERR
, "Cannot find codec matching selected -vo and video format 0x%X.\n",
392 mp_tmsg(MSGT_DECVIDEO
, MSGL_INFO
, "Selected video codec: [%s] vfm: %s (%s)\n",
393 sh_video
->codec
->name
, sh_video
->codec
->drv
, sh_video
->codec
->info
);
397 void *decode_video(sh_video_t
*sh_video
, struct demux_packet
*packet
,
398 unsigned char *start
, int in_size
,
399 int drop_frame
, double pts
)
401 mp_image_t
*mpi
= NULL
;
402 unsigned int t
= GetTimer();
405 struct MPOpts
*opts
= sh_video
->opts
;
407 if (opts
->correct_pts
&& pts
!= MP_NOPTS_VALUE
) {
408 int delay
= get_current_video_decoder_lag(sh_video
);
410 if (delay
> sh_video
->num_buffered_pts
)
412 // this is disabled because vd_ffmpeg reports the same lag
413 // after seek even when there are no buffered frames,
414 // leading to incorrect error messages
415 mp_msg(MSGT_DECVIDEO
, MSGL_ERR
, "Not enough buffered pts\n");
420 sh_video
->num_buffered_pts
= delay
;
422 if (sh_video
->num_buffered_pts
==
423 sizeof(sh_video
->buffered_pts
) / sizeof(double))
424 mp_msg(MSGT_DECVIDEO
, MSGL_ERR
, "Too many buffered pts\n");
427 for (i
= 0; i
< sh_video
->num_buffered_pts
; i
++)
428 if (sh_video
->buffered_pts
[i
] < pts
)
430 for (j
= sh_video
->num_buffered_pts
; j
> i
; j
--)
431 sh_video
->buffered_pts
[j
] = sh_video
->buffered_pts
[j
- 1];
432 sh_video
->buffered_pts
[i
] = pts
;
433 sh_video
->num_buffered_pts
++;
437 if (sh_video
->vd_driver
->decode2
) {
438 mpi
= sh_video
->vd_driver
->decode2(sh_video
, packet
, start
, in_size
,
441 mpi
= sh_video
->vd_driver
->decode(sh_video
, start
, in_size
,
443 pts
= MP_NOPTS_VALUE
;
446 //------------------------ frame decoded. --------------------
449 // some codecs are broken, and doesn't restore MMX state :(
450 // it happens usually with broken/damaged files.
451 if (gCpuCaps
.has3DNow
) {
452 __asm__
volatile("femms\n\t":::"memory");
453 } else if (gCpuCaps
.hasMMX
) {
454 __asm__
volatile("emms\n\t":::"memory");
461 video_time_usage
+= tt
;
463 if (!mpi
|| drop_frame
)
464 return NULL
; // error / skipped frame
466 if (field_dominance
== 0)
467 mpi
->fields
|= MP_IMGFIELD_TOP_FIRST
;
468 else if (field_dominance
== 1)
469 mpi
->fields
&= ~MP_IMGFIELD_TOP_FIRST
;
471 double prevpts
= sh_video
->codec_reordered_pts
;
472 sh_video
->prev_codec_reordered_pts
= prevpts
;
473 sh_video
->codec_reordered_pts
= pts
;
474 if (prevpts
!= MP_NOPTS_VALUE
&& pts
<= prevpts
475 || pts
== MP_NOPTS_VALUE
)
476 sh_video
->num_reordered_pts_problems
++;
477 prevpts
= sh_video
->sorted_pts
;
478 if (opts
->correct_pts
) {
479 if (sh_video
->num_buffered_pts
) {
480 sh_video
->num_buffered_pts
--;
481 sh_video
->sorted_pts
=
482 sh_video
->buffered_pts
[sh_video
->num_buffered_pts
];
484 mp_msg(MSGT_CPLAYER
, MSGL_ERR
,
485 "No pts value from demuxer to use for frame!\n");
486 sh_video
->sorted_pts
= MP_NOPTS_VALUE
;
489 pts
= sh_video
->sorted_pts
;
490 if (prevpts
!= MP_NOPTS_VALUE
&& pts
<= prevpts
491 || pts
== MP_NOPTS_VALUE
)
492 sh_video
->num_sorted_pts_problems
++;
496 int filter_video(sh_video_t
*sh_video
, void *frame
, double pts
)
498 mp_image_t
*mpi
= frame
;
499 unsigned int t2
= GetTimer();
500 vf_instance_t
*vf
= sh_video
->vfilter
;
501 // apply video filters and call the leaf vo/ve
502 int ret
= vf
->put_image(vf
, mpi
, pts
);
504 t2
= GetTimer() - t2
;
505 vout_time_usage
+= t2
* 0.000001;