Mercurial > mplayer.hg
annotate libmpcodecs/dec_video.c @ 32714:5248e989612a
Remove libswscale subdirectory.
libswscale has been moved to FFmpeg since some time and only kept in the
MPlayer repository for historical reasons and difficulty in moving code
complete with history between Subversion repositories.
FFmpeg now contains libswscale directly without indirection through an
svn:externals property, so no reason to keep libswscale in MPlayer remains.
author | diego |
---|---|
date | Thu, 20 Jan 2011 09:41:43 +0000 |
parents | fc443754da3d |
children | 277ec491a8a7 |
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) { | |
84 int ret = vf->control(vf, VFCTRL_SET_PP_LEVEL, (void *) (&quality)); | |
85 if (ret == CONTROL_TRUE) | |
86 return; // success | |
87 } | |
88 if (mpvdec) | |
89 mpvdec->control(sh_video, VDCTRL_SET_PP_LEVEL, (void *) (&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; |
111 mp_msg(MSGT_DECVIDEO, MSGL_V, MSGTR_VideoAttributeNotSupportedByVO_VD, | |
112 item); | |
6780 | 113 return 0; |
114 } | |
115 | |
31171 | 116 int get_video_colors(sh_video_t *sh_video, const char *item, int *value) |
6780 | 117 { |
31171 | 118 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
|
119 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
|
120 |
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 data.item = item; |
6786 | 122 |
31171 | 123 mp_dbg(MSGT_DECVIDEO, MSGL_V, "get video colors %s \n", item); |
124 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
|
125 int ret = vf->control(vf, VFCTRL_GET_EQUALIZER, &data); |
31171 | 126 if (ret == CONTROL_TRUE) { |
127 *value = data.value; | |
128 return 1; | |
129 } | |
6786 | 130 } |
6780 | 131 /* try software control */ |
31171 | 132 if (mpvdec) |
133 return mpvdec->control(sh_video, VDCTRL_GET_EQUALIZER, item, value); | |
1429 | 134 return 0; |
135 } | |
1294 | 136 |
31171 | 137 int set_rectangle(sh_video_t *sh_video, int param, int value) |
6887 | 138 { |
31171 | 139 vf_instance_t *vf = sh_video->vfilter; |
140 int data[] = { param, value }; | |
6887 | 141 |
31171 | 142 mp_dbg(MSGT_DECVIDEO, MSGL_V, "set rectangle \n"); |
143 if (vf) { | |
6887 | 144 int ret = vf->control(vf, VFCTRL_CHANGE_RECTANGLE, data); |
31171 | 145 if (ret) |
146 return 1; | |
6887 | 147 } |
148 return 0; | |
149 } | |
150 | |
11977
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
parents:
10683
diff
changeset
|
151 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
|
152 { |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
153 sh_video->timer = 0; |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
154 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
|
155 sh_video->num_buffered_pts = 0; |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
156 sh_video->last_pts = MP_NOPTS_VALUE; |
31171 | 157 if (mpvdec) |
158 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
|
159 } |
efb37725d616
flushing stuff after seeking (finally we can view MPEG without thouse blocks after seeking with -vc ffmpeg12)
michael
parents:
10683
diff
changeset
|
160 |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
161 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
|
162 { |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
163 int ret; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
164 |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
165 if (!mpvdec) |
31171 | 166 return -1; |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
167 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
|
168 if (ret >= 10) |
31171 | 169 return ret - 10; |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
170 return -1; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
171 } |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
172 |
31171 | 173 void uninit_video(sh_video_t *sh_video) |
174 { | |
175 if (!sh_video->initialized) | |
176 return; | |
177 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
|
178 mpvdec->uninit(sh_video); |
32595 | 179 mpvdec = NULL; |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
180 #ifdef CONFIG_DYNAMIC_PLUGINS |
8152 | 181 if (sh_video->dec_handle) |
31171 | 182 dlclose(sh_video->dec_handle); |
8152 | 183 #endif |
5737 | 184 vf_uninit_filter_chain(sh_video->vfilter); |
31927 | 185 eosd_uninit(); |
31171 | 186 sh_video->initialized = 0; |
1654 | 187 } |
188 | |
31171 | 189 void vfm_help(void) |
190 { | |
7191
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
191 int i; |
31171 | 192 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
|
193 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_DRIVERS\n"); |
31171 | 194 mp_msg(MSGT_DECVIDEO, MSGL_INFO, " vfm: info: (comment)\n"); |
195 for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) | |
196 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "%8s %s (%s)\n", | |
197 mpcodecs_vd_drivers[i]->info->short_name, | |
198 mpcodecs_vd_drivers[i]->info->name, | |
199 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
|
200 } |
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
201 |
31171 | 202 static int init_video(sh_video_t *sh_video, char *codecname, char *vfm, |
203 int status, stringset_t *selected) | |
204 { | |
16325 | 205 int force = 0; |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
206 unsigned int orig_fourcc = sh_video->bih ? sh_video->bih->biCompression : 0; |
31171 | 207 sh_video->codec = NULL; |
208 sh_video->vf_initialized = 0; | |
16321
efbfac98cab1
Allow forcing of demuxers and codecs by prepending '+'
reimar
parents:
15789
diff
changeset
|
209 if (codecname && codecname[0] == '+') { |
31171 | 210 codecname = &codecname[1]; |
211 force = 1; | |
16321
efbfac98cab1
Allow forcing of demuxers and codecs by prepending '+'
reimar
parents:
15789
diff
changeset
|
212 } |
6230
936aa617e829
restore original bih->biCompression if codec init failed
arpi
parents:
6138
diff
changeset
|
213 |
31171 | 214 while (1) { |
215 int i; | |
216 int orig_w, orig_h; | |
217 // restore original fourcc: | |
218 if (sh_video->bih) | |
219 sh_video->bih->biCompression = orig_fourcc; | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
220 if (!(sh_video->codec = |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
221 find_video_codec(sh_video->format, |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
222 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
|
223 sh_video->codec, force))) |
31171 | 224 break; |
225 // ok we found one codec | |
226 if (stringset_test(selected, sh_video->codec->name)) | |
227 continue; // already tried & failed | |
228 if (codecname && strcmp(sh_video->codec->name, codecname)) | |
229 continue; // -vc | |
230 if (vfm && strcmp(sh_video->codec->drv, vfm)) | |
231 continue; // vfm doesn't match | |
232 if (!force && sh_video->codec->status < status) | |
233 continue; // too unstable | |
234 stringset_add(selected, sh_video->codec->name); // tagging it | |
235 // ok, it matches all rules, let's find the driver! | |
236 for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) | |
237 // if(mpcodecs_vd_drivers[i]->info->id==sh_video->codec->driver) break; | |
238 if (!strcmp | |
239 (mpcodecs_vd_drivers[i]->info->short_name, | |
240 sh_video->codec->drv)) | |
241 break; | |
242 mpvdec = mpcodecs_vd_drivers[i]; | |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
243 #ifdef CONFIG_DYNAMIC_PLUGINS |
31171 | 244 if (!mpvdec) { |
245 /* try to open shared decoder plugin */ | |
246 int buf_len; | |
247 char *buf; | |
248 vd_functions_t *funcs_sym; | |
249 vd_info_t *info_sym; | |
8152 | 250 |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
251 buf_len = strlen(MPLAYER_LIBDIR) + |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
252 strlen(sh_video->codec->drv) + 16; |
31171 | 253 buf = malloc(buf_len); |
254 if (!buf) | |
255 break; | |
256 snprintf(buf, buf_len, "%s/mplayer/vd_%s.so", MPLAYER_LIBDIR, | |
257 sh_video->codec->drv); | |
258 mp_msg(MSGT_DECVIDEO, MSGL_DBG2, | |
259 "Trying to open external plugin: %s\n", buf); | |
260 sh_video->dec_handle = dlopen(buf, RTLD_LAZY); | |
261 if (!sh_video->dec_handle) | |
262 break; | |
263 snprintf(buf, buf_len, "mpcodecs_vd_%s", sh_video->codec->drv); | |
264 funcs_sym = dlsym(sh_video->dec_handle, buf); | |
265 if (!funcs_sym || !funcs_sym->info || !funcs_sym->init | |
266 || !funcs_sym->uninit || !funcs_sym->control | |
267 || !funcs_sym->decode) | |
268 break; | |
269 info_sym = funcs_sym->info; | |
270 if (strcmp(info_sym->short_name, sh_video->codec->drv)) | |
271 break; | |
272 free(buf); | |
273 mpvdec = funcs_sym; | |
274 mp_msg(MSGT_DECVIDEO, MSGL_V, | |
275 "Using external decoder plugin (%s/mplayer/vd_%s.so)!\n", | |
276 MPLAYER_LIBDIR, sh_video->codec->drv); | |
277 } | |
8152 | 278 #endif |
31171 | 279 if (!mpvdec) { // driver not available (==compiled in) |
280 mp_msg(MSGT_DECVIDEO, MSGL_WARN, | |
281 MSGTR_VideoCodecFamilyNotAvailableStr, | |
282 sh_video->codec->name, sh_video->codec->drv); | |
283 continue; | |
284 } | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
285 orig_w = sh_video->bih ? sh_video->bih->biWidth : sh_video->disp_w; |
31171 | 286 orig_h = sh_video->bih ? sh_video->bih->biHeight : sh_video->disp_h; |
287 sh_video->disp_w = orig_w; | |
288 sh_video->disp_h = orig_h; | |
289 // it's available, let's try to init! | |
290 if (sh_video->codec->flags & CODECS_FLAG_ALIGN16) { | |
291 // align width/height to n*16 | |
292 sh_video->disp_w = (sh_video->disp_w + 15) & (~15); | |
293 sh_video->disp_h = (sh_video->disp_h + 15) & (~15); | |
294 } | |
295 if (sh_video->bih) { | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
296 sh_video->bih->biWidth = sh_video->disp_w; |
31171 | 297 sh_video->bih->biHeight = sh_video->disp_h; |
298 } | |
299 // init() | |
300 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_OpeningVideoDecoder, | |
301 mpvdec->info->short_name, mpvdec->info->name); | |
302 // clear vf init error, it is no longer relevant | |
303 if (sh_video->vf_initialized < 0) | |
304 sh_video->vf_initialized = 0; | |
305 if (!mpvdec->init(sh_video)) { | |
306 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_VDecoderInitFailed); | |
307 sh_video->disp_w = orig_w; | |
308 sh_video->disp_h = orig_h; | |
309 if (sh_video->bih) { | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
310 sh_video->bih->biWidth = sh_video->disp_w; |
31171 | 311 sh_video->bih->biHeight = sh_video->disp_h; |
312 } | |
313 continue; // try next... | |
314 } | |
315 // Yeah! We got it! | |
316 sh_video->initialized = 1; | |
317 return 1; | |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
318 } |
5171
7145d6aba6cd
init_video() changed - now it handles codec selection
arpi
parents:
5155
diff
changeset
|
319 return 0; |
1294 | 320 } |
321 | |
31171 | 322 int init_best_video_codec(sh_video_t *sh_video, char **video_codec_list, |
323 char **video_fm_list) | |
324 { | |
325 char *vc_l_default[2] = { "", (char *) NULL }; | |
326 stringset_t selected; | |
327 // hack: | |
328 if (!video_codec_list) | |
329 video_codec_list = vc_l_default; | |
330 // Go through the codec.conf and find the best codec... | |
331 sh_video->initialized = 0; | |
332 stringset_init(&selected); | |
333 while (!sh_video->initialized && *video_codec_list) { | |
334 char *video_codec = *(video_codec_list++); | |
335 if (video_codec[0]) { | |
336 if (video_codec[0] == '-') { | |
337 // disable this codec: | |
338 stringset_add(&selected, video_codec + 1); | |
339 } else { | |
340 // forced codec by name: | |
341 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_ForcedVideoCodec, | |
342 video_codec); | |
343 init_video(sh_video, video_codec, NULL, -1, &selected); | |
344 } | |
345 } else { | |
346 int status; | |
347 // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING. | |
348 if (video_fm_list) { | |
349 char **fmlist = video_fm_list; | |
350 // try first the preferred codec families: | |
351 while (!sh_video->initialized && *fmlist) { | |
352 char *video_fm = *(fmlist++); | |
353 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_TryForceVideoFmtStr, | |
354 video_fm); | |
355 for (status = CODECS_STATUS__MAX; | |
356 status >= CODECS_STATUS__MIN; --status) | |
357 if (init_video | |
358 (sh_video, NULL, video_fm, status, &selected)) | |
359 break; | |
360 } | |
361 } | |
362 if (!sh_video->initialized) | |
363 for (status = CODECS_STATUS__MAX; status >= CODECS_STATUS__MIN; | |
364 --status) | |
365 if (init_video(sh_video, NULL, NULL, status, &selected)) | |
366 break; | |
367 } | |
7506
c1cb94198e05
-vc/-vfm accepts codec/driver _list_ now. empty list element for -vc means
arpi
parents:
7502
diff
changeset
|
368 } |
31171 | 369 stringset_free(&selected); |
370 | |
371 if (!sh_video->initialized) { | |
372 mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantFindVideoCodec, | |
373 sh_video->format); | |
374 return 0; // failed | |
7502
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
375 } |
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
376 |
31171 | 377 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_SelectedVideoCodec, |
378 sh_video->codec->name, sh_video->codec->drv, sh_video->codec->info); | |
379 return 1; // success | |
7502
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
380 } |
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
381 |
22497 | 382 void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, |
31972 | 383 int drop_frame, double pts, int *full_frame) |
22497 | 384 { |
385 mp_image_t *mpi = NULL; | |
386 unsigned int t = GetTimer(); | |
387 unsigned int t2; | |
388 double tt; | |
31953 | 389 int delay; |
390 int got_picture = 1; | |
1360 | 391 |
31953 | 392 mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); |
393 | |
394 //------------------------ frame decoded. -------------------- | |
395 | |
396 if (mpi && mpi->type == MP_IMGTYPE_INCOMPLETE) { | |
397 got_picture = 0; | |
398 mpi = NULL; | |
399 } | |
400 | |
31972 | 401 if (full_frame) |
402 *full_frame = got_picture; | |
403 | |
31953 | 404 delay = get_current_video_decoder_lag(sh_video); |
405 if (correct_pts && pts != MP_NOPTS_VALUE | |
406 && (got_picture || sh_video->num_buffered_pts < delay)) { | |
31171 | 407 if (sh_video->num_buffered_pts == |
408 sizeof(sh_video->buffered_pts) / sizeof(double)) | |
409 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); | |
410 else { | |
411 int i, j; | |
412 for (i = 0; i < sh_video->num_buffered_pts; i++) | |
413 if (sh_video->buffered_pts[i] < pts) | |
414 break; | |
415 for (j = sh_video->num_buffered_pts; j > i; j--) | |
416 sh_video->buffered_pts[j] = sh_video->buffered_pts[j - 1]; | |
417 sh_video->buffered_pts[i] = pts; | |
418 sh_video->num_buffered_pts++; | |
419 } | |
22497 | 420 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
421 |
28290 | 422 #if HAVE_MMX |
22497 | 423 // some codecs are broken, and doesn't restore MMX state :( |
424 // it happens usually with broken/damaged files. | |
425 if (gCpuCaps.has3DNow) { | |
31171 | 426 __asm__ volatile ("femms\n\t":::"memory"); |
427 } else if (gCpuCaps.hasMMX) { | |
428 __asm__ volatile ("emms\n\t":::"memory"); | |
22497 | 429 } |
3160 | 430 #endif |
1367 | 431 |
31171 | 432 t2 = GetTimer(); |
433 t = t2 - t; | |
434 tt = t * 0.000001f; | |
22497 | 435 video_time_usage += tt; |
4898 | 436 |
22497 | 437 if (!mpi || drop_frame) |
31171 | 438 return NULL; // error / skipped frame |
5040 | 439 |
22497 | 440 if (field_dominance == 0) |
31171 | 441 mpi->fields |= MP_IMGFIELD_TOP_FIRST; |
22497 | 442 else if (field_dominance == 1) |
31171 | 443 mpi->fields &= ~MP_IMGFIELD_TOP_FIRST; |
22086
8bf15e2ca61e
Add global field dominance flag instead of duplicating this "everywhere"
reimar
parents:
22012
diff
changeset
|
444 |
22497 | 445 if (correct_pts) { |
31171 | 446 if (sh_video->num_buffered_pts) { |
447 sh_video->num_buffered_pts--; | |
448 sh_video->pts = sh_video->buffered_pts[sh_video->num_buffered_pts]; | |
449 } else { | |
450 mp_msg(MSGT_CPLAYER, MSGL_ERR, | |
32523 | 451 "No pts value from demuxer to use for frame!\n"); |
31171 | 452 sh_video->pts = MP_NOPTS_VALUE; |
453 } | |
31246
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
454 if (delay >= 0) { |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
455 // 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
|
456 // 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
|
457 // H.264 frame). |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
458 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
|
459 #if 0 |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
460 // 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
|
461 // 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
|
462 // leading to incorrect error messages |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
463 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
|
464 #else |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
465 ; |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
466 #endif |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
467 else |
cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
reimar
parents:
31171
diff
changeset
|
468 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
|
469 } |
22497 | 470 } |
471 return mpi; | |
20902
bfb6eacd9c4a
Update OSD contents only after the correct values for the frame are known.
uau
parents:
19521
diff
changeset
|
472 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
473 |
22497 | 474 int filter_video(sh_video_t *sh_video, void *frame, double pts) |
475 { | |
476 mp_image_t *mpi = frame; | |
477 unsigned int t2 = GetTimer(); | |
478 vf_instance_t *vf = sh_video->vfilter; | |
479 // apply video filters and call the leaf vo/ve | |
480 int ret = vf->put_image(vf, mpi, pts); | |
481 if (ret > 0) { | |
31171 | 482 // draw EOSD first so it ends up below the OSD. |
483 // Note that changing this is will not work right with vf_ass and the | |
484 // vos currently always draw the EOSD first in paused mode. | |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26754
diff
changeset
|
485 #ifdef CONFIG_ASS |
31171 | 486 vf->control(vf, VFCTRL_DRAW_EOSD, NULL); |
19521 | 487 #endif |
31171 | 488 vf->control(vf, VFCTRL_DRAW_OSD, NULL); |
22497 | 489 } |
4898 | 490 |
31171 | 491 t2 = GetTimer() - t2; |
492 vout_time_usage += t2 * 0.000001; | |
1360 | 493 |
22497 | 494 return ret; |
1294 | 495 } |