Mercurial > mplayer.hg
annotate libmpcodecs/dec_video.c @ 37088:3a9a804e488b
mixer: do not unmute to volume 0, instead unmute to max.
It's not very useful for unmute to still result in volume 0.
Plus it makes it easier to enable sound for devices that were
on mute at startup.
author | reimar |
---|---|
date | Tue, 06 May 2014 19:02:02 +0000 |
parents | 0d7459fc4354 |
children |
rev | line source |
---|---|
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
1 /* |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
2 * This file is part of MPlayer. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
3 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
7 * (at your option) any later version. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
8 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
12 * GNU General Public License for more details. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
13 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
30378
diff
changeset
|
17 */ |
2775 | 18 |
19 #include "config.h" | |
1294 | 20 |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
1430 | 23 #include <unistd.h> |
1294 | 24 |
1567 | 25 #include "mp_msg.h" |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1949
diff
changeset
|
26 #include "help_mp.h" |
32061
dcdcbe7f6713
Move video_time_usage / vout_time_usage extern var declarations to mpcommon.h.
diego
parents:
31989
diff
changeset
|
27 #include "mpcommon.h" |
1294 | 28 |
9380 | 29 #include "osdep/timer.h" |
30 #include "osdep/shmem.h" | |
1327
b12e1817bcc2
some cleanup - fixed warnings, removed old stuff, moved audio resync to dec_audio
arpi
parents:
1309
diff
changeset
|
31 |
22599
4faee1254928
Add explicit location for headers from the stream/ directory.
diego
parents:
22498
diff
changeset
|
32 #include "stream/stream.h" |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22599
diff
changeset
|
33 #include "libmpdemux/demuxer.h" |
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22599
diff
changeset
|
34 #include "libmpdemux/parse_es.h" |
1294 | 35 |
36 #include "codec-cfg.h" | |
37 | |
38 #include "libvo/video_out.h" | |
39 | |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22599
diff
changeset
|
40 #include "libmpdemux/stheader.h" |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
41 #include "vd.h" |
5507
d0d029fda134
video filter layer - written from scratch, but inspired a lot by Fredrik Kuivinen's patch
arpi
parents:
5328
diff
changeset
|
42 #include "vf.h" |
32460 | 43 #include "sub/eosd.h" |
4188 | 44 |
2563 | 45 #include "dec_video.h" |
46 | |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
47 #ifdef CONFIG_DYNAMIC_PLUGINS |
8152 | 48 #include <dlfcn.h> |
49 #endif | |
50 | |
3144 | 51 #include "cpudetect.h" |
52 | |
31171 | 53 int field_dominance = -1; |
22086
8bf15e2ca61e
Add global field dominance flag instead of duplicating this "everywhere"
reimar
parents:
22012
diff
changeset
|
54 |
31171 | 55 int divx_quality = 0; |
1294 | 56 |
31171 | 57 const vd_functions_t *mpvdec = NULL; |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
58 |
31171 | 59 int get_video_quality_max(sh_video_t *sh_video) |
60 { | |
61 vf_instance_t *vf = sh_video->vfilter; | |
62 if (vf) { | |
63 int ret = vf->control(vf, VFCTRL_QUERY_MAX_PP_LEVEL, NULL); | |
64 if (ret > 0) { | |
65 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_UsingExternalPP, ret); | |
66 return ret; | |
67 } | |
5519 | 68 } |
31171 | 69 if (mpvdec) { |
70 int ret = mpvdec->control(sh_video, VDCTRL_QUERY_MAX_PP_LEVEL, NULL); | |
71 if (ret > 0) { | |
72 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_UsingCodecPP, ret); | |
73 return ret; | |
74 } | |
5519 | 75 } |
6138
523014df7d32
big cosmetics patch, cleanup of messages printed by mplayer and libs.
arpi
parents:
5984
diff
changeset
|
76 // mp_msg(MSGT_DECVIDEO,MSGL_INFO,"[PP] Sorry, postprocessing is not available\n"); |
31171 | 77 return 0; |
1429 | 78 } |
79 | |
31171 | 80 void set_video_quality(sh_video_t *sh_video, int quality) |
81 { | |
82 vf_instance_t *vf = sh_video->vfilter; | |
83 if (vf) { | |
33836 | 84 int ret = vf->control(vf, VFCTRL_SET_PP_LEVEL, &quality); |
31171 | 85 if (ret == CONTROL_TRUE) |
86 return; // success | |
87 } | |
88 if (mpvdec) | |
33836 | 89 mpvdec->control(sh_video, VDCTRL_SET_PP_LEVEL, &quality); |
1429 | 90 } |
91 | |
31171 | 92 int set_video_colors(sh_video_t *sh_video, const char *item, int value) |
4395 | 93 { |
31171 | 94 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
parents:
6800
diff
changeset
|
95 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
parents:
6800
diff
changeset
|
96 |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
97 data.item = item; |
6832
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
parents:
6800
diff
changeset
|
98 data.value = value; |
6786 | 99 |
31171 | 100 mp_dbg(MSGT_DECVIDEO, MSGL_V, "set video colors %s=%d \n", item, value); |
101 if (vf) { | |
102 int ret = vf->control(vf, VFCTRL_SET_EQUALIZER, &data); | |
103 if (ret == CONTROL_TRUE) | |
104 return 1; | |
6785 | 105 } |
6780 | 106 /* try software control */ |
31171 | 107 if (mpvdec) |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
108 if (mpvdec->control(sh_video, VDCTRL_SET_EQUALIZER, item, |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
109 (int *) value) == CONTROL_OK) |
31171 | 110 return 1; |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
32595
diff
changeset
|
111 mp_msg(MSGT_DECVIDEO, MSGL_V, |
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
32595
diff
changeset
|
112 "Video attribute '%s' is not supported by selected vo & vd.\n", |
31171 | 113 item); |
6780 | 114 return 0; |
115 } | |
116 | |
31171 | 117 int get_video_colors(sh_video_t *sh_video, const char *item, int *value) |
6780 | 118 { |
31171 | 119 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
parents:
6800
diff
changeset
|
120 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
parents:
6800
diff
changeset
|
121 |
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
parents:
6800
diff
changeset
|
122 data.item = item; |
6786 | 123 |
31171 | 124 mp_dbg(MSGT_DECVIDEO, MSGL_V, "get video colors %s \n", item); |
125 if (vf) { | |
6832
54578e5a8050
... removed from vf's control(), sing struct for equalizer. based on patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
arpi
parents:
6800
diff
changeset
|
126 int ret = vf->control(vf, VFCTRL_GET_EQUALIZER, &data); |
31171 | 127 if (ret == CONTROL_TRUE) { |
128 *value = data.value; | |
129 return 1; | |
130 } | |
6786 | 131 } |
6780 | 132 /* try software control */ |
31171 | 133 if (mpvdec) |
134 return mpvdec->control(sh_video, VDCTRL_GET_EQUALIZER, item, value); | |
1429 | 135 return 0; |
136 } | |
1294 | 137 |
31171 | 138 int set_rectangle(sh_video_t *sh_video, int param, int value) |
6887 | 139 { |
31171 | 140 vf_instance_t *vf = sh_video->vfilter; |
141 int data[] = { param, value }; | |
6887 | 142 |
31171 | 143 mp_dbg(MSGT_DECVIDEO, MSGL_V, "set rectangle \n"); |
144 if (vf) { | |
6887 | 145 int ret = vf->control(vf, VFCTRL_CHANGE_RECTANGLE, data); |
31171 | 146 if (ret) |
147 return 1; | |
6887 | 148 } |
149 return 0; | |
150 } | |
151 | |
11977
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
parents:
10683
diff
changeset
|
152 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
parents:
10683
diff
changeset
|
153 { |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
154 sh_video->timer = 0; |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
155 sh_video->next_frame_time = 0; |
30378
8339bca8e4b4
Move the resync-related code into more consistent places instead of having it
reimar
parents:
29168
diff
changeset
|
156 sh_video->num_buffered_pts = 0; |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
157 sh_video->last_pts = MP_NOPTS_VALUE; |
31171 | 158 if (mpvdec) |
159 mpvdec->control(sh_video, VDCTRL_RESYNC_STREAM, NULL); | |
11977
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
parents:
10683
diff
changeset
|
160 } |
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
parents:
10683
diff
changeset
|
161 |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
162 int get_current_video_decoder_lag(sh_video_t *sh_video) |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
163 { |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
164 int ret; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
165 |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
166 if (!mpvdec) |
31171 | 167 return -1; |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
168 ret = mpvdec->control(sh_video, VDCTRL_QUERY_UNSEEN_FRAMES, NULL); |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
169 if (ret >= 10) |
31171 | 170 return ret - 10; |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
171 return -1; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
172 } |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
173 |
31171 | 174 void uninit_video(sh_video_t *sh_video) |
175 { | |
176 if (!sh_video->initialized) | |
177 return; | |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
32595
diff
changeset
|
178 mp_msg(MSGT_DECVIDEO, MSGL_V, "Uninit video: %s\n", sh_video->codec->drv); |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
179 mpvdec->uninit(sh_video); |
32595 | 180 mpvdec = NULL; |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
181 #ifdef CONFIG_DYNAMIC_PLUGINS |
8152 | 182 if (sh_video->dec_handle) |
31171 | 183 dlclose(sh_video->dec_handle); |
8152 | 184 #endif |
5737 | 185 vf_uninit_filter_chain(sh_video->vfilter); |
31927 | 186 eosd_uninit(); |
31171 | 187 sh_video->initialized = 0; |
1654 | 188 } |
189 | |
31171 | 190 void vfm_help(void) |
191 { | |
7191
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
192 int i; |
31171 | 193 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_AvailableVideoFm); |
18237
4231482179b6
Get ride of the several if(identify) messy lines and rearangment of some of the output, both patches by Kiriuja mplayer-patches AT en-directo_net, his changes are barely unrelated, nevertheless Im commiting them thogeter just for the sake of my mental healt, I had both patches already applied on my local three
reynaldo
parents:
18190
diff
changeset
|
194 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_DRIVERS\n"); |
31171 | 195 mp_msg(MSGT_DECVIDEO, MSGL_INFO, " vfm: info: (comment)\n"); |
196 for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) | |
197 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "%8s %s (%s)\n", | |
198 mpcodecs_vd_drivers[i]->info->short_name, | |
199 mpcodecs_vd_drivers[i]->info->name, | |
200 mpcodecs_vd_drivers[i]->info->comment); | |
7191
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
201 } |
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
202 |
31171 | 203 static int init_video(sh_video_t *sh_video, char *codecname, char *vfm, |
204 int status, stringset_t *selected) | |
205 { | |
16325 | 206 int force = 0; |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
207 unsigned int orig_fourcc = sh_video->bih ? sh_video->bih->biCompression : 0; |
31171 | 208 sh_video->codec = NULL; |
209 sh_video->vf_initialized = 0; | |
16321
efbfac98cab1
Allow forcing of demuxers and codecs by prepending '+'
reimar
parents:
15789
diff
changeset
|
210 if (codecname && codecname[0] == '+') { |
31171 | 211 codecname = &codecname[1]; |
212 force = 1; | |
16321
efbfac98cab1
Allow forcing of demuxers and codecs by prepending '+'
reimar
parents:
15789
diff
changeset
|
213 } |
6230
936aa617e829
restore original bih->biCompression if codec init failed
arpi
parents:
6138
diff
changeset
|
214 |
31171 | 215 while (1) { |
216 int i; | |
217 int orig_w, orig_h; | |
218 // restore original fourcc: | |
219 if (sh_video->bih) | |
220 sh_video->bih->biCompression = orig_fourcc; | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
221 if (!(sh_video->codec = |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
222 find_video_codec(sh_video->format, |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
223 sh_video->bih ? ((unsigned int *) &sh_video->bih->biCompression) : NULL, |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
224 sh_video->codec, force))) |
31171 | 225 break; |
226 // ok we found one codec | |
227 if (stringset_test(selected, sh_video->codec->name)) | |
228 continue; // already tried & failed | |
229 if (codecname && strcmp(sh_video->codec->name, codecname)) | |
230 continue; // -vc | |
231 if (vfm && strcmp(sh_video->codec->drv, vfm)) | |
232 continue; // vfm doesn't match | |
233 if (!force && sh_video->codec->status < status) | |
234 continue; // too unstable | |
235 stringset_add(selected, sh_video->codec->name); // tagging it | |
236 // ok, it matches all rules, let's find the driver! | |
237 for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) | |
238 // if(mpcodecs_vd_drivers[i]->info->id==sh_video->codec->driver) break; | |
239 if (!strcmp | |
240 (mpcodecs_vd_drivers[i]->info->short_name, | |
241 sh_video->codec->drv)) | |
242 break; | |
243 mpvdec = mpcodecs_vd_drivers[i]; | |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
244 #ifdef CONFIG_DYNAMIC_PLUGINS |
31171 | 245 if (!mpvdec) { |
246 /* try to open shared decoder plugin */ | |
247 int buf_len; | |
248 char *buf; | |
249 vd_functions_t *funcs_sym; | |
250 vd_info_t *info_sym; | |
8152 | 251 |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
252 buf_len = strlen(MPLAYER_LIBDIR) + |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
253 strlen(sh_video->codec->drv) + 16; |
31171 | 254 buf = malloc(buf_len); |
255 if (!buf) | |
256 break; | |
257 snprintf(buf, buf_len, "%s/mplayer/vd_%s.so", MPLAYER_LIBDIR, | |
258 sh_video->codec->drv); | |
259 mp_msg(MSGT_DECVIDEO, MSGL_DBG2, | |
260 "Trying to open external plugin: %s\n", buf); | |
261 sh_video->dec_handle = dlopen(buf, RTLD_LAZY); | |
262 if (!sh_video->dec_handle) | |
263 break; | |
264 snprintf(buf, buf_len, "mpcodecs_vd_%s", sh_video->codec->drv); | |
265 funcs_sym = dlsym(sh_video->dec_handle, buf); | |
266 if (!funcs_sym || !funcs_sym->info || !funcs_sym->init | |
267 || !funcs_sym->uninit || !funcs_sym->control | |
268 || !funcs_sym->decode) | |
269 break; | |
270 info_sym = funcs_sym->info; | |
271 if (strcmp(info_sym->short_name, sh_video->codec->drv)) | |
272 break; | |
273 free(buf); | |
274 mpvdec = funcs_sym; | |
275 mp_msg(MSGT_DECVIDEO, MSGL_V, | |
276 "Using external decoder plugin (%s/mplayer/vd_%s.so)!\n", | |
277 MPLAYER_LIBDIR, sh_video->codec->drv); | |
278 } | |
8152 | 279 #endif |
31171 | 280 if (!mpvdec) { // driver not available (==compiled in) |
281 mp_msg(MSGT_DECVIDEO, MSGL_WARN, | |
282 MSGTR_VideoCodecFamilyNotAvailableStr, | |
283 sh_video->codec->name, sh_video->codec->drv); | |
284 continue; | |
285 } | |
35304 | 286 /* only allow dummy codecs if specified via -vc */ |
287 if (sh_video->codec->flags & CODECS_FLAG_DUMMY && !codecname) { | |
288 continue; | |
289 } | |
290 | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
291 orig_w = sh_video->bih ? sh_video->bih->biWidth : sh_video->disp_w; |
31171 | 292 orig_h = sh_video->bih ? sh_video->bih->biHeight : sh_video->disp_h; |
293 sh_video->disp_w = orig_w; | |
294 sh_video->disp_h = orig_h; | |
295 // it's available, let's try to init! | |
296 if (sh_video->codec->flags & CODECS_FLAG_ALIGN16) { | |
297 // align width/height to n*16 | |
298 sh_video->disp_w = (sh_video->disp_w + 15) & (~15); | |
299 sh_video->disp_h = (sh_video->disp_h + 15) & (~15); | |
300 } | |
301 if (sh_video->bih) { | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
302 sh_video->bih->biWidth = sh_video->disp_w; |
31171 | 303 sh_video->bih->biHeight = sh_video->disp_h; |
304 } | |
305 // init() | |
306 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_OpeningVideoDecoder, | |
307 mpvdec->info->short_name, mpvdec->info->name); | |
308 // clear vf init error, it is no longer relevant | |
309 if (sh_video->vf_initialized < 0) | |
310 sh_video->vf_initialized = 0; | |
311 if (!mpvdec->init(sh_video)) { | |
312 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_VDecoderInitFailed); | |
313 sh_video->disp_w = orig_w; | |
314 sh_video->disp_h = orig_h; | |
315 if (sh_video->bih) { | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
316 sh_video->bih->biWidth = sh_video->disp_w; |
31171 | 317 sh_video->bih->biHeight = sh_video->disp_h; |
318 } | |
319 continue; // try next... | |
320 } | |
321 // Yeah! We got it! | |
322 sh_video->initialized = 1; | |
323 return 1; | |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
324 } |
5171
7145d6aba6cd
init_video() changed - now it handles codec selection
arpi
parents:
5155
diff
changeset
|
325 return 0; |
1294 | 326 } |
327 | |
31171 | 328 int init_best_video_codec(sh_video_t *sh_video, char **video_codec_list, |
329 char **video_fm_list) | |
330 { | |
331 char *vc_l_default[2] = { "", (char *) NULL }; | |
332 stringset_t selected; | |
333 // hack: | |
334 if (!video_codec_list) | |
335 video_codec_list = vc_l_default; | |
336 // Go through the codec.conf and find the best codec... | |
337 sh_video->initialized = 0; | |
338 stringset_init(&selected); | |
339 while (!sh_video->initialized && *video_codec_list) { | |
340 char *video_codec = *(video_codec_list++); | |
341 if (video_codec[0]) { | |
342 if (video_codec[0] == '-') { | |
343 // disable this codec: | |
344 stringset_add(&selected, video_codec + 1); | |
345 } else { | |
346 // forced codec by name: | |
347 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_ForcedVideoCodec, | |
348 video_codec); | |
349 init_video(sh_video, video_codec, NULL, -1, &selected); | |
350 } | |
351 } else { | |
352 int status; | |
353 // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING. | |
354 if (video_fm_list) { | |
355 char **fmlist = video_fm_list; | |
356 // try first the preferred codec families: | |
357 while (!sh_video->initialized && *fmlist) { | |
358 char *video_fm = *(fmlist++); | |
359 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_TryForceVideoFmtStr, | |
360 video_fm); | |
361 for (status = CODECS_STATUS__MAX; | |
362 status >= CODECS_STATUS__MIN; --status) | |
363 if (init_video | |
364 (sh_video, NULL, video_fm, status, &selected)) | |
365 break; | |
366 } | |
367 } | |
368 if (!sh_video->initialized) | |
369 for (status = CODECS_STATUS__MAX; status >= CODECS_STATUS__MIN; | |
370 --status) | |
371 if (init_video(sh_video, NULL, NULL, status, &selected)) | |
372 break; | |
373 } | |
7506
c1cb94198e05
-vc/-vfm accepts codec/driver _list_ now. empty list element for -vc means
arpi
parents:
7502
diff
changeset
|
374 } |
31171 | 375 stringset_free(&selected); |
376 | |
377 if (!sh_video->initialized) { | |
378 mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantFindVideoCodec, | |
379 sh_video->format); | |
380 return 0; // failed | |
7502
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
381 } |
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
382 |
31171 | 383 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_SelectedVideoCodec, |
384 sh_video->codec->name, sh_video->codec->drv, sh_video->codec->info); | |
385 return 1; // success | |
7502
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
386 } |
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
387 |
22497 | 388 void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, |
31972 | 389 int drop_frame, double pts, int *full_frame) |
22497 | 390 { |
391 mp_image_t *mpi = NULL; | |
392 unsigned int t = GetTimer(); | |
393 unsigned int t2; | |
394 double tt; | |
31953 | 395 int delay; |
396 int got_picture = 1; | |
1360 | 397 |
31953 | 398 mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); |
399 | |
400 //------------------------ frame decoded. -------------------- | |
401 | |
402 if (mpi && mpi->type == MP_IMGTYPE_INCOMPLETE) { | |
403 got_picture = 0; | |
404 mpi = NULL; | |
405 } | |
406 | |
31972 | 407 if (full_frame) |
408 *full_frame = got_picture; | |
409 | |
31953 | 410 delay = get_current_video_decoder_lag(sh_video); |
411 if (correct_pts && pts != MP_NOPTS_VALUE | |
412 && (got_picture || sh_video->num_buffered_pts < delay)) { | |
31171 | 413 if (sh_video->num_buffered_pts == |
414 sizeof(sh_video->buffered_pts) / sizeof(double)) | |
415 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); | |
416 else { | |
417 int i, j; | |
418 for (i = 0; i < sh_video->num_buffered_pts; i++) | |
419 if (sh_video->buffered_pts[i] < pts) | |
420 break; | |
421 for (j = sh_video->num_buffered_pts; j > i; j--) | |
422 sh_video->buffered_pts[j] = sh_video->buffered_pts[j - 1]; | |
423 sh_video->buffered_pts[i] = pts; | |
424 sh_video->num_buffered_pts++; | |
425 } | |
22497 | 426 } |
36421 | 427 if (correct_pts && mpi && drop_frame && sh_video->num_buffered_pts > 0) |
428 sh_video->num_buffered_pts--; | |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
429 |
22497 | 430 // some codecs are broken, and doesn't restore MMX state :( |
431 // it happens usually with broken/damaged files. | |
34311 | 432 if (HAVE_AMD3DNOW && gCpuCaps.has3DNow) { |
31171 | 433 __asm__ volatile ("femms\n\t":::"memory"); |
34311 | 434 } else if (HAVE_MMX && gCpuCaps.hasMMX) { |
31171 | 435 __asm__ volatile ("emms\n\t":::"memory"); |
22497 | 436 } |
1367 | 437 |
31171 | 438 t2 = GetTimer(); |
439 t = t2 - t; | |
440 tt = t * 0.000001f; | |
22497 | 441 video_time_usage += tt; |
4898 | 442 |
22497 | 443 if (!mpi || drop_frame) |
31171 | 444 return NULL; // error / skipped frame |
5040 | 445 |
22497 | 446 if (field_dominance == 0) |
31171 | 447 mpi->fields |= MP_IMGFIELD_TOP_FIRST; |
22497 | 448 else if (field_dominance == 1) |
31171 | 449 mpi->fields &= ~MP_IMGFIELD_TOP_FIRST; |
22086
8bf15e2ca61e
Add global field dominance flag instead of duplicating this "everywhere"
reimar
parents:
22012
diff
changeset
|
450 |
22497 | 451 if (correct_pts) { |
31171 | 452 if (sh_video->num_buffered_pts) { |
453 sh_video->num_buffered_pts--; | |
454 sh_video->pts = sh_video->buffered_pts[sh_video->num_buffered_pts]; | |
455 } else { | |
456 mp_msg(MSGT_CPLAYER, MSGL_ERR, | |
32523 | 457 "No pts value from demuxer to use for frame!\n"); |
31171 | 458 sh_video->pts = MP_NOPTS_VALUE; |
459 } | |
31246
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
460 if (delay >= 0) { |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
461 // limit buffered pts only afterwards so we do not get confused |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
462 // by packets that produce no output (e.g. a single field of a |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
463 // H.264 frame). |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
464 if (delay > sh_video->num_buffered_pts) |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
465 #if 0 |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
466 // this is disabled because vd_ffmpeg reports the same lag |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
467 // after seek even when there are no buffered frames, |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
468 // leading to incorrect error messages |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
469 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Not enough buffered pts\n"); |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
470 #else |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
471 ; |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
472 #endif |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
473 else |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
474 sh_video->num_buffered_pts = delay; |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
475 } |
22497 | 476 } |
477 return mpi; | |
20902
bfb6eacd9c4a
Update OSD contents only after the correct values for the frame are known.
uau
parents:
19521
diff
changeset
|
478 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
479 |
22497 | 480 int filter_video(sh_video_t *sh_video, void *frame, double pts) |
481 { | |
482 mp_image_t *mpi = frame; | |
483 unsigned int t2 = GetTimer(); | |
484 vf_instance_t *vf = sh_video->vfilter; | |
485 // apply video filters and call the leaf vo/ve | |
486 int ret = vf->put_image(vf, mpi, pts); | |
487 if (ret > 0) { | |
31171 | 488 // draw EOSD first so it ends up below the OSD. |
489 // Note that changing this is will not work right with vf_ass and the | |
490 // vos currently always draw the EOSD first in paused mode. | |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26754
diff
changeset
|
491 #ifdef CONFIG_ASS |
31171 | 492 vf->control(vf, VFCTRL_DRAW_EOSD, NULL); |
19521 | 493 #endif |
31171 | 494 vf->control(vf, VFCTRL_DRAW_OSD, NULL); |
22497 | 495 } |
4898 | 496 |
31171 | 497 t2 = GetTimer() - t2; |
498 vout_time_usage += t2 * 0.000001; | |
1360 | 499 |
22497 | 500 return ret; |
1294 | 501 } |