Mercurial > mplayer.hg
annotate libmpcodecs/dec_video.c @ 31597:1eb8dc8f96fa
Make subdelay handling work the same way for all subtitle types and also allow
changing subtitle delay to work better with vobsubs.
This probably breaks vobsub behaviour with timestamp wrapping though.
author | reimar |
---|---|
date | Sat, 10 Jul 2010 12:53:05 +0000 |
parents | cc6ee3017097 |
children | 6e0b5a97e00f |
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" |
1294 | 27 |
9380 | 28 #include "osdep/timer.h" |
29 #include "osdep/shmem.h" | |
1327
b12e1817bcc2
some cleanup - fixed warnings, removed old stuff, moved audio resync to dec_audio
arpi
parents:
1309
diff
changeset
|
30 |
22599
4faee1254928
Add explicit location for headers from the stream/ directory.
diego
parents:
22498
diff
changeset
|
31 #include "stream/stream.h" |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22599
diff
changeset
|
32 #include "libmpdemux/demuxer.h" |
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22599
diff
changeset
|
33 #include "libmpdemux/parse_es.h" |
1294 | 34 |
35 #include "codec-cfg.h" | |
36 | |
37 #include "libvo/video_out.h" | |
38 | |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22599
diff
changeset
|
39 #include "libmpdemux/stheader.h" |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
40 #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
|
41 #include "vf.h" |
4188 | 42 |
2563 | 43 #include "dec_video.h" |
44 | |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
45 #ifdef CONFIG_DYNAMIC_PLUGINS |
8152 | 46 #include <dlfcn.h> |
47 #endif | |
48 | |
2563 | 49 // =================================================================== |
50 | |
51 extern double video_time_usage; | |
52 extern double vout_time_usage; | |
53 | |
3144 | 54 #include "cpudetect.h" |
55 | |
31171 | 56 int field_dominance = -1; |
22086
8bf15e2ca61e
Add global field dominance flag instead of duplicating this "everywhere"
reimar
parents:
22012
diff
changeset
|
57 |
31171 | 58 int divx_quality = 0; |
1294 | 59 |
31171 | 60 const vd_functions_t *mpvdec = NULL; |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
61 |
31171 | 62 int get_video_quality_max(sh_video_t *sh_video) |
63 { | |
64 vf_instance_t *vf = sh_video->vfilter; | |
65 if (vf) { | |
66 int ret = vf->control(vf, VFCTRL_QUERY_MAX_PP_LEVEL, NULL); | |
67 if (ret > 0) { | |
68 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_UsingExternalPP, ret); | |
69 return ret; | |
70 } | |
5519 | 71 } |
31171 | 72 if (mpvdec) { |
73 int ret = mpvdec->control(sh_video, VDCTRL_QUERY_MAX_PP_LEVEL, NULL); | |
74 if (ret > 0) { | |
75 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_UsingCodecPP, ret); | |
76 return ret; | |
77 } | |
5519 | 78 } |
6138
523014df7d32
big cosmetics patch, cleanup of messages printed by mplayer and libs.
arpi
parents:
5984
diff
changeset
|
79 // mp_msg(MSGT_DECVIDEO,MSGL_INFO,"[PP] Sorry, postprocessing is not available\n"); |
31171 | 80 return 0; |
1429 | 81 } |
82 | |
31171 | 83 void set_video_quality(sh_video_t *sh_video, int quality) |
84 { | |
85 vf_instance_t *vf = sh_video->vfilter; | |
86 if (vf) { | |
87 int ret = vf->control(vf, VFCTRL_SET_PP_LEVEL, (void *) (&quality)); | |
88 if (ret == CONTROL_TRUE) | |
89 return; // success | |
90 } | |
91 if (mpvdec) | |
92 mpvdec->control(sh_video, VDCTRL_SET_PP_LEVEL, (void *) (&quality)); | |
1429 | 93 } |
94 | |
31171 | 95 int set_video_colors(sh_video_t *sh_video, const char *item, int value) |
4395 | 96 { |
31171 | 97 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
|
98 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
|
99 |
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
|
100 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
parents:
6800
diff
changeset
|
101 data.value = value; |
6786 | 102 |
31171 | 103 mp_dbg(MSGT_DECVIDEO, MSGL_V, "set video colors %s=%d \n", item, value); |
104 if (vf) { | |
105 int ret = vf->control(vf, VFCTRL_SET_EQUALIZER, &data); | |
106 if (ret == CONTROL_TRUE) | |
107 return 1; | |
6785 | 108 } |
6780 | 109 /* try software control */ |
31171 | 110 if (mpvdec) |
111 if (mpvdec->control | |
112 (sh_video, VDCTRL_SET_EQUALIZER, item, (int *) value) | |
113 == CONTROL_OK) | |
114 return 1; | |
115 mp_msg(MSGT_DECVIDEO, MSGL_V, MSGTR_VideoAttributeNotSupportedByVO_VD, | |
116 item); | |
6780 | 117 return 0; |
118 } | |
119 | |
31171 | 120 int get_video_colors(sh_video_t *sh_video, const char *item, int *value) |
6780 | 121 { |
31171 | 122 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
|
123 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
|
124 |
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
|
125 data.item = item; |
6786 | 126 |
31171 | 127 mp_dbg(MSGT_DECVIDEO, MSGL_V, "get video colors %s \n", item); |
128 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
|
129 int ret = vf->control(vf, VFCTRL_GET_EQUALIZER, &data); |
31171 | 130 if (ret == CONTROL_TRUE) { |
131 *value = data.value; | |
132 return 1; | |
133 } | |
6786 | 134 } |
6780 | 135 /* try software control */ |
31171 | 136 if (mpvdec) |
137 return mpvdec->control(sh_video, VDCTRL_GET_EQUALIZER, item, value); | |
1429 | 138 return 0; |
139 } | |
1294 | 140 |
31171 | 141 int set_rectangle(sh_video_t *sh_video, int param, int value) |
6887 | 142 { |
31171 | 143 vf_instance_t *vf = sh_video->vfilter; |
144 int data[] = { param, value }; | |
6887 | 145 |
31171 | 146 mp_dbg(MSGT_DECVIDEO, MSGL_V, "set rectangle \n"); |
147 if (vf) { | |
6887 | 148 int ret = vf->control(vf, VFCTRL_CHANGE_RECTANGLE, data); |
31171 | 149 if (ret) |
150 return 1; | |
6887 | 151 } |
152 return 0; | |
153 } | |
154 | |
11977
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
parents:
10683
diff
changeset
|
155 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
|
156 { |
30378
8339bca8e4b4
Move the resync-related code into more consistent places instead of having it
reimar
parents:
29168
diff
changeset
|
157 sh_video->timer = 0; |
8339bca8e4b4
Move the resync-related code into more consistent places instead of having it
reimar
parents:
29168
diff
changeset
|
158 sh_video->next_frame_time = 0; |
8339bca8e4b4
Move the resync-related code into more consistent places instead of having it
reimar
parents:
29168
diff
changeset
|
159 sh_video->num_buffered_pts = 0; |
8339bca8e4b4
Move the resync-related code into more consistent places instead of having it
reimar
parents:
29168
diff
changeset
|
160 sh_video->last_pts = MP_NOPTS_VALUE; |
31171 | 161 if (mpvdec) |
162 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
|
163 } |
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
parents:
10683
diff
changeset
|
164 |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
165 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
|
166 { |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
167 int ret; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
168 |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
169 if (!mpvdec) |
31171 | 170 return -1; |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
171 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
|
172 if (ret >= 10) |
31171 | 173 return ret - 10; |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
174 return -1; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
175 } |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
176 |
31171 | 177 void uninit_video(sh_video_t *sh_video) |
178 { | |
179 if (!sh_video->initialized) | |
180 return; | |
181 mp_msg(MSGT_DECVIDEO, MSGL_V, MSGTR_UninitVideoStr, sh_video->codec->drv); | |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
182 mpvdec->uninit(sh_video); |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
183 #ifdef CONFIG_DYNAMIC_PLUGINS |
8152 | 184 if (sh_video->dec_handle) |
31171 | 185 dlclose(sh_video->dec_handle); |
8152 | 186 #endif |
5737 | 187 vf_uninit_filter_chain(sh_video->vfilter); |
31171 | 188 sh_video->initialized = 0; |
1654 | 189 } |
190 | |
31171 | 191 void vfm_help(void) |
192 { | |
7191
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
193 int i; |
31171 | 194 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
|
195 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_DRIVERS\n"); |
31171 | 196 mp_msg(MSGT_DECVIDEO, MSGL_INFO, " vfm: info: (comment)\n"); |
197 for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) | |
198 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "%8s %s (%s)\n", | |
199 mpcodecs_vd_drivers[i]->info->short_name, | |
200 mpcodecs_vd_drivers[i]->info->name, | |
201 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
|
202 } |
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
203 |
31171 | 204 static int init_video(sh_video_t *sh_video, char *codecname, char *vfm, |
205 int status, stringset_t *selected) | |
206 { | |
16325 | 207 int force = 0; |
31171 | 208 unsigned int orig_fourcc = |
209 sh_video->bih ? sh_video->bih->biCompression : 0; | |
210 sh_video->codec = NULL; | |
211 sh_video->vf_initialized = 0; | |
16321
efbfac98cab1
Allow forcing of demuxers and codecs by prepending '+'
reimar
parents:
15789
diff
changeset
|
212 if (codecname && codecname[0] == '+') { |
31171 | 213 codecname = &codecname[1]; |
214 force = 1; | |
16321
efbfac98cab1
Allow forcing of demuxers and codecs by prepending '+'
reimar
parents:
15789
diff
changeset
|
215 } |
6230
936aa617e829
restore original bih->biCompression if codec init failed
arpi
parents:
6138
diff
changeset
|
216 |
31171 | 217 while (1) { |
218 int i; | |
219 int orig_w, orig_h; | |
220 // restore original fourcc: | |
221 if (sh_video->bih) | |
222 sh_video->bih->biCompression = orig_fourcc; | |
223 if (! | |
224 (sh_video->codec = | |
225 find_video_codec(sh_video->format, | |
226 sh_video-> | |
227 bih ? ((unsigned int *) &sh_video->bih-> | |
228 biCompression) : NULL, sh_video->codec, | |
229 force))) | |
230 break; | |
231 // ok we found one codec | |
232 if (stringset_test(selected, sh_video->codec->name)) | |
233 continue; // already tried & failed | |
234 if (codecname && strcmp(sh_video->codec->name, codecname)) | |
235 continue; // -vc | |
236 if (vfm && strcmp(sh_video->codec->drv, vfm)) | |
237 continue; // vfm doesn't match | |
238 if (!force && sh_video->codec->status < status) | |
239 continue; // too unstable | |
240 stringset_add(selected, sh_video->codec->name); // tagging it | |
241 // ok, it matches all rules, let's find the driver! | |
242 for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) | |
243 // if(mpcodecs_vd_drivers[i]->info->id==sh_video->codec->driver) break; | |
244 if (!strcmp | |
245 (mpcodecs_vd_drivers[i]->info->short_name, | |
246 sh_video->codec->drv)) | |
247 break; | |
248 mpvdec = mpcodecs_vd_drivers[i]; | |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
249 #ifdef CONFIG_DYNAMIC_PLUGINS |
31171 | 250 if (!mpvdec) { |
251 /* try to open shared decoder plugin */ | |
252 int buf_len; | |
253 char *buf; | |
254 vd_functions_t *funcs_sym; | |
255 vd_info_t *info_sym; | |
8152 | 256 |
31171 | 257 buf_len = |
258 strlen(MPLAYER_LIBDIR) + strlen(sh_video->codec->drv) + 16; | |
259 buf = malloc(buf_len); | |
260 if (!buf) | |
261 break; | |
262 snprintf(buf, buf_len, "%s/mplayer/vd_%s.so", MPLAYER_LIBDIR, | |
263 sh_video->codec->drv); | |
264 mp_msg(MSGT_DECVIDEO, MSGL_DBG2, | |
265 "Trying to open external plugin: %s\n", buf); | |
266 sh_video->dec_handle = dlopen(buf, RTLD_LAZY); | |
267 if (!sh_video->dec_handle) | |
268 break; | |
269 snprintf(buf, buf_len, "mpcodecs_vd_%s", sh_video->codec->drv); | |
270 funcs_sym = dlsym(sh_video->dec_handle, buf); | |
271 if (!funcs_sym || !funcs_sym->info || !funcs_sym->init | |
272 || !funcs_sym->uninit || !funcs_sym->control | |
273 || !funcs_sym->decode) | |
274 break; | |
275 info_sym = funcs_sym->info; | |
276 if (strcmp(info_sym->short_name, sh_video->codec->drv)) | |
277 break; | |
278 free(buf); | |
279 mpvdec = funcs_sym; | |
280 mp_msg(MSGT_DECVIDEO, MSGL_V, | |
281 "Using external decoder plugin (%s/mplayer/vd_%s.so)!\n", | |
282 MPLAYER_LIBDIR, sh_video->codec->drv); | |
283 } | |
8152 | 284 #endif |
31171 | 285 if (!mpvdec) { // driver not available (==compiled in) |
286 mp_msg(MSGT_DECVIDEO, MSGL_WARN, | |
287 MSGTR_VideoCodecFamilyNotAvailableStr, | |
288 sh_video->codec->name, sh_video->codec->drv); | |
289 continue; | |
290 } | |
291 orig_w = sh_video->bih ? sh_video->bih->biWidth : sh_video->disp_w; | |
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) { | |
302 sh_video->bih->biWidth = sh_video->disp_w; | |
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) { | |
316 sh_video->bih->biWidth = sh_video->disp_w; | |
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, |
31171 | 389 int drop_frame, double pts) |
22497 | 390 { |
391 mp_image_t *mpi = NULL; | |
392 unsigned int t = GetTimer(); | |
393 unsigned int t2; | |
394 double tt; | |
1360 | 395 |
22498
b6b1bd155b58
Allow demuxers to return packets with no pts in -correct-pts mode
uau
parents:
22497
diff
changeset
|
396 if (correct_pts && pts != MP_NOPTS_VALUE) { |
31171 | 397 if (sh_video->num_buffered_pts == |
398 sizeof(sh_video->buffered_pts) / sizeof(double)) | |
399 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); | |
400 else { | |
401 int i, j; | |
402 for (i = 0; i < sh_video->num_buffered_pts; i++) | |
403 if (sh_video->buffered_pts[i] < pts) | |
404 break; | |
405 for (j = sh_video->num_buffered_pts; j > i; j--) | |
406 sh_video->buffered_pts[j] = sh_video->buffered_pts[j - 1]; | |
407 sh_video->buffered_pts[i] = pts; | |
408 sh_video->num_buffered_pts++; | |
409 } | |
22497 | 410 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
411 |
22497 | 412 mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
413 |
22497 | 414 //------------------------ frame decoded. -------------------- |
1294 | 415 |
28290 | 416 #if HAVE_MMX |
22497 | 417 // some codecs are broken, and doesn't restore MMX state :( |
418 // it happens usually with broken/damaged files. | |
419 if (gCpuCaps.has3DNow) { | |
31171 | 420 __asm__ volatile ("femms\n\t":::"memory"); |
421 } else if (gCpuCaps.hasMMX) { | |
422 __asm__ volatile ("emms\n\t":::"memory"); | |
22497 | 423 } |
3160 | 424 #endif |
1367 | 425 |
31171 | 426 t2 = GetTimer(); |
427 t = t2 - t; | |
428 tt = t * 0.000001f; | |
22497 | 429 video_time_usage += tt; |
4898 | 430 |
22497 | 431 if (!mpi || drop_frame) |
31171 | 432 return NULL; // error / skipped frame |
5040 | 433 |
22497 | 434 if (field_dominance == 0) |
31171 | 435 mpi->fields |= MP_IMGFIELD_TOP_FIRST; |
22497 | 436 else if (field_dominance == 1) |
31171 | 437 mpi->fields &= ~MP_IMGFIELD_TOP_FIRST; |
22086
8bf15e2ca61e
Add global field dominance flag instead of duplicating this "everywhere"
reimar
parents:
22012
diff
changeset
|
438 |
22497 | 439 if (correct_pts) { |
31246
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
440 int delay = get_current_video_decoder_lag(sh_video); |
31171 | 441 if (sh_video->num_buffered_pts) { |
442 sh_video->num_buffered_pts--; | |
443 sh_video->pts = sh_video->buffered_pts[sh_video->num_buffered_pts]; | |
444 } else { | |
445 mp_msg(MSGT_CPLAYER, MSGL_ERR, | |
446 "No pts value from demuxer to " "use for frame!\n"); | |
447 sh_video->pts = MP_NOPTS_VALUE; | |
448 } | |
31246
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
449 if (delay >= 0) { |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
450 // 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
|
451 // 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
|
452 // H.264 frame). |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
453 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
|
454 #if 0 |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
455 // 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
|
456 // 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
|
457 // leading to incorrect error messages |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
458 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
|
459 #else |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
460 ; |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
461 #endif |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
462 else |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
463 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
|
464 } |
22497 | 465 } |
466 return mpi; | |
20902
bfb6eacd9c4a
Update OSD contents only after the correct values for the frame are known.
uau
parents:
19521
diff
changeset
|
467 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
468 |
22497 | 469 int filter_video(sh_video_t *sh_video, void *frame, double pts) |
470 { | |
471 mp_image_t *mpi = frame; | |
472 unsigned int t2 = GetTimer(); | |
473 vf_instance_t *vf = sh_video->vfilter; | |
474 // apply video filters and call the leaf vo/ve | |
475 int ret = vf->put_image(vf, mpi, pts); | |
476 if (ret > 0) { | |
31171 | 477 // draw EOSD first so it ends up below the OSD. |
478 // Note that changing this is will not work right with vf_ass and the | |
479 // vos currently always draw the EOSD first in paused mode. | |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26754
diff
changeset
|
480 #ifdef CONFIG_ASS |
31171 | 481 vf->control(vf, VFCTRL_DRAW_EOSD, NULL); |
19521 | 482 #endif |
31171 | 483 vf->control(vf, VFCTRL_DRAW_OSD, NULL); |
22497 | 484 } |
4898 | 485 |
31171 | 486 t2 = GetTimer() - t2; |
487 vout_time_usage += t2 * 0.000001; | |
1360 | 488 |
22497 | 489 return ret; |
1294 | 490 } |