Mercurial > mplayer.hg
annotate libmpcodecs/dec_video.c @ 34823:2960cd0eef6f
Initialize "result" variable since FcFontMatch only sets it on failure.
This is currently kind of pointless since we don't actually
use the result, but it is better to not take any risks.
author | reimar |
---|---|
date | Wed, 16 May 2012 21:30:07 +0000 |
parents | cdee75826a31 |
children | d29d116c0818 |
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 } | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
286 orig_w = sh_video->bih ? sh_video->bih->biWidth : sh_video->disp_w; |
31171 | 287 orig_h = sh_video->bih ? sh_video->bih->biHeight : sh_video->disp_h; |
288 sh_video->disp_w = orig_w; | |
289 sh_video->disp_h = orig_h; | |
290 // it's available, let's try to init! | |
291 if (sh_video->codec->flags & CODECS_FLAG_ALIGN16) { | |
292 // align width/height to n*16 | |
293 sh_video->disp_w = (sh_video->disp_w + 15) & (~15); | |
294 sh_video->disp_h = (sh_video->disp_h + 15) & (~15); | |
295 } | |
296 if (sh_video->bih) { | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
297 sh_video->bih->biWidth = sh_video->disp_w; |
31171 | 298 sh_video->bih->biHeight = sh_video->disp_h; |
299 } | |
300 // init() | |
301 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_OpeningVideoDecoder, | |
302 mpvdec->info->short_name, mpvdec->info->name); | |
303 // clear vf init error, it is no longer relevant | |
304 if (sh_video->vf_initialized < 0) | |
305 sh_video->vf_initialized = 0; | |
306 if (!mpvdec->init(sh_video)) { | |
307 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_VDecoderInitFailed); | |
308 sh_video->disp_w = orig_w; | |
309 sh_video->disp_h = orig_h; | |
310 if (sh_video->bih) { | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
311 sh_video->bih->biWidth = sh_video->disp_w; |
31171 | 312 sh_video->bih->biHeight = sh_video->disp_h; |
313 } | |
314 continue; // try next... | |
315 } | |
316 // Yeah! We got it! | |
317 sh_video->initialized = 1; | |
318 return 1; | |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
319 } |
5171
7145d6aba6cd
init_video() changed - now it handles codec selection
arpi
parents:
5155
diff
changeset
|
320 return 0; |
1294 | 321 } |
322 | |
31171 | 323 int init_best_video_codec(sh_video_t *sh_video, char **video_codec_list, |
324 char **video_fm_list) | |
325 { | |
326 char *vc_l_default[2] = { "", (char *) NULL }; | |
327 stringset_t selected; | |
328 // hack: | |
329 if (!video_codec_list) | |
330 video_codec_list = vc_l_default; | |
331 // Go through the codec.conf and find the best codec... | |
332 sh_video->initialized = 0; | |
333 stringset_init(&selected); | |
334 while (!sh_video->initialized && *video_codec_list) { | |
335 char *video_codec = *(video_codec_list++); | |
336 if (video_codec[0]) { | |
337 if (video_codec[0] == '-') { | |
338 // disable this codec: | |
339 stringset_add(&selected, video_codec + 1); | |
340 } else { | |
341 // forced codec by name: | |
342 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_ForcedVideoCodec, | |
343 video_codec); | |
344 init_video(sh_video, video_codec, NULL, -1, &selected); | |
345 } | |
346 } else { | |
347 int status; | |
348 // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING. | |
349 if (video_fm_list) { | |
350 char **fmlist = video_fm_list; | |
351 // try first the preferred codec families: | |
352 while (!sh_video->initialized && *fmlist) { | |
353 char *video_fm = *(fmlist++); | |
354 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_TryForceVideoFmtStr, | |
355 video_fm); | |
356 for (status = CODECS_STATUS__MAX; | |
357 status >= CODECS_STATUS__MIN; --status) | |
358 if (init_video | |
359 (sh_video, NULL, video_fm, status, &selected)) | |
360 break; | |
361 } | |
362 } | |
363 if (!sh_video->initialized) | |
364 for (status = CODECS_STATUS__MAX; status >= CODECS_STATUS__MIN; | |
365 --status) | |
366 if (init_video(sh_video, NULL, NULL, status, &selected)) | |
367 break; | |
368 } | |
7506
c1cb94198e05
-vc/-vfm accepts codec/driver _list_ now. empty list element for -vc means
arpi
parents:
7502
diff
changeset
|
369 } |
31171 | 370 stringset_free(&selected); |
371 | |
372 if (!sh_video->initialized) { | |
373 mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantFindVideoCodec, | |
374 sh_video->format); | |
375 return 0; // failed | |
7502
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
376 } |
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
377 |
31171 | 378 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_SelectedVideoCodec, |
379 sh_video->codec->name, sh_video->codec->drv, sh_video->codec->info); | |
380 return 1; // success | |
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 |
22497 | 383 void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, |
31972 | 384 int drop_frame, double pts, int *full_frame) |
22497 | 385 { |
386 mp_image_t *mpi = NULL; | |
387 unsigned int t = GetTimer(); | |
388 unsigned int t2; | |
389 double tt; | |
31953 | 390 int delay; |
391 int got_picture = 1; | |
1360 | 392 |
31953 | 393 mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); |
394 | |
395 //------------------------ frame decoded. -------------------- | |
396 | |
397 if (mpi && mpi->type == MP_IMGTYPE_INCOMPLETE) { | |
398 got_picture = 0; | |
399 mpi = NULL; | |
400 } | |
401 | |
31972 | 402 if (full_frame) |
403 *full_frame = got_picture; | |
404 | |
31953 | 405 delay = get_current_video_decoder_lag(sh_video); |
406 if (correct_pts && pts != MP_NOPTS_VALUE | |
407 && (got_picture || sh_video->num_buffered_pts < delay)) { | |
31171 | 408 if (sh_video->num_buffered_pts == |
409 sizeof(sh_video->buffered_pts) / sizeof(double)) | |
410 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); | |
411 else { | |
412 int i, j; | |
413 for (i = 0; i < sh_video->num_buffered_pts; i++) | |
414 if (sh_video->buffered_pts[i] < pts) | |
415 break; | |
416 for (j = sh_video->num_buffered_pts; j > i; j--) | |
417 sh_video->buffered_pts[j] = sh_video->buffered_pts[j - 1]; | |
418 sh_video->buffered_pts[i] = pts; | |
419 sh_video->num_buffered_pts++; | |
420 } | |
22497 | 421 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
422 |
22497 | 423 // some codecs are broken, and doesn't restore MMX state :( |
424 // it happens usually with broken/damaged files. | |
34311 | 425 if (HAVE_AMD3DNOW && gCpuCaps.has3DNow) { |
31171 | 426 __asm__ volatile ("femms\n\t":::"memory"); |
34311 | 427 } else if (HAVE_MMX && gCpuCaps.hasMMX) { |
31171 | 428 __asm__ volatile ("emms\n\t":::"memory"); |
22497 | 429 } |
1367 | 430 |
31171 | 431 t2 = GetTimer(); |
432 t = t2 - t; | |
433 tt = t * 0.000001f; | |
22497 | 434 video_time_usage += tt; |
4898 | 435 |
22497 | 436 if (!mpi || drop_frame) |
31171 | 437 return NULL; // error / skipped frame |
5040 | 438 |
22497 | 439 if (field_dominance == 0) |
31171 | 440 mpi->fields |= MP_IMGFIELD_TOP_FIRST; |
22497 | 441 else if (field_dominance == 1) |
31171 | 442 mpi->fields &= ~MP_IMGFIELD_TOP_FIRST; |
22086
8bf15e2ca61e
Add global field dominance flag instead of duplicating this "everywhere"
reimar
parents:
22012
diff
changeset
|
443 |
22497 | 444 if (correct_pts) { |
31171 | 445 if (sh_video->num_buffered_pts) { |
446 sh_video->num_buffered_pts--; | |
447 sh_video->pts = sh_video->buffered_pts[sh_video->num_buffered_pts]; | |
448 } else { | |
449 mp_msg(MSGT_CPLAYER, MSGL_ERR, | |
32523 | 450 "No pts value from demuxer to use for frame!\n"); |
31171 | 451 sh_video->pts = MP_NOPTS_VALUE; |
452 } | |
31246
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
453 if (delay >= 0) { |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
454 // 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
|
455 // 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
|
456 // H.264 frame). |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
457 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
|
458 #if 0 |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
459 // 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
|
460 // 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
|
461 // leading to incorrect error messages |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
462 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
|
463 #else |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
464 ; |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
465 #endif |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
466 else |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
467 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
|
468 } |
22497 | 469 } |
470 return mpi; | |
20902
bfb6eacd9c4a
Update OSD contents only after the correct values for the frame are known.
uau
parents:
19521
diff
changeset
|
471 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
472 |
22497 | 473 int filter_video(sh_video_t *sh_video, void *frame, double pts) |
474 { | |
475 mp_image_t *mpi = frame; | |
476 unsigned int t2 = GetTimer(); | |
477 vf_instance_t *vf = sh_video->vfilter; | |
478 // apply video filters and call the leaf vo/ve | |
479 int ret = vf->put_image(vf, mpi, pts); | |
480 if (ret > 0) { | |
31171 | 481 // draw EOSD first so it ends up below the OSD. |
482 // Note that changing this is will not work right with vf_ass and the | |
483 // vos currently always draw the EOSD first in paused mode. | |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26754
diff
changeset
|
484 #ifdef CONFIG_ASS |
31171 | 485 vf->control(vf, VFCTRL_DRAW_EOSD, NULL); |
19521 | 486 #endif |
31171 | 487 vf->control(vf, VFCTRL_DRAW_OSD, NULL); |
22497 | 488 } |
4898 | 489 |
31171 | 490 t2 = GetTimer() - t2; |
491 vout_time_usage += t2 * 0.000001; | |
1360 | 492 |
22497 | 493 return ret; |
1294 | 494 } |