Mercurial > mplayer.hg
annotate libmpcodecs/dec_video.c @ 32439:2f1ccd169a7f
Improve vd_ffmpeg aspect handling to respect container aspect if possible
(i.e. until the first resolution or aspect change) and to use correct
aspect if only resolution changes but not the pixel aspect.
author | reimar |
---|---|
date | Fri, 22 Oct 2010 17:36:11 +0000 |
parents | dcdcbe7f6713 |
children | d80bbc5868de |
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" |
31927 | 43 #include "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); |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
179 #ifdef CONFIG_DYNAMIC_PLUGINS |
8152 | 180 if (sh_video->dec_handle) |
31171 | 181 dlclose(sh_video->dec_handle); |
8152 | 182 #endif |
5737 | 183 vf_uninit_filter_chain(sh_video->vfilter); |
31927 | 184 eosd_uninit(); |
31171 | 185 sh_video->initialized = 0; |
1654 | 186 } |
187 | |
31171 | 188 void vfm_help(void) |
189 { | |
7191
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
190 int i; |
31171 | 191 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
|
192 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_DRIVERS\n"); |
31171 | 193 mp_msg(MSGT_DECVIDEO, MSGL_INFO, " vfm: info: (comment)\n"); |
194 for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) | |
195 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "%8s %s (%s)\n", | |
196 mpcodecs_vd_drivers[i]->info->short_name, | |
197 mpcodecs_vd_drivers[i]->info->name, | |
198 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
|
199 } |
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
200 |
31171 | 201 static int init_video(sh_video_t *sh_video, char *codecname, char *vfm, |
202 int status, stringset_t *selected) | |
203 { | |
16325 | 204 int force = 0; |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
205 unsigned int orig_fourcc = sh_video->bih ? sh_video->bih->biCompression : 0; |
31171 | 206 sh_video->codec = NULL; |
207 sh_video->vf_initialized = 0; | |
16321
efbfac98cab1
Allow forcing of demuxers and codecs by prepending '+'
reimar
parents:
15789
diff
changeset
|
208 if (codecname && codecname[0] == '+') { |
31171 | 209 codecname = &codecname[1]; |
210 force = 1; | |
16321
efbfac98cab1
Allow forcing of demuxers and codecs by prepending '+'
reimar
parents:
15789
diff
changeset
|
211 } |
6230
936aa617e829
restore original bih->biCompression if codec init failed
arpi
parents:
6138
diff
changeset
|
212 |
31171 | 213 while (1) { |
214 int i; | |
215 int orig_w, orig_h; | |
216 // restore original fourcc: | |
217 if (sh_video->bih) | |
218 sh_video->bih->biCompression = orig_fourcc; | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
219 if (!(sh_video->codec = |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
220 find_video_codec(sh_video->format, |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
221 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
|
222 sh_video->codec, force))) |
31171 | 223 break; |
224 // ok we found one codec | |
225 if (stringset_test(selected, sh_video->codec->name)) | |
226 continue; // already tried & failed | |
227 if (codecname && strcmp(sh_video->codec->name, codecname)) | |
228 continue; // -vc | |
229 if (vfm && strcmp(sh_video->codec->drv, vfm)) | |
230 continue; // vfm doesn't match | |
231 if (!force && sh_video->codec->status < status) | |
232 continue; // too unstable | |
233 stringset_add(selected, sh_video->codec->name); // tagging it | |
234 // ok, it matches all rules, let's find the driver! | |
235 for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) | |
236 // if(mpcodecs_vd_drivers[i]->info->id==sh_video->codec->driver) break; | |
237 if (!strcmp | |
238 (mpcodecs_vd_drivers[i]->info->short_name, | |
239 sh_video->codec->drv)) | |
240 break; | |
241 mpvdec = mpcodecs_vd_drivers[i]; | |
27397
d47744b95b78
Give a CONFIG_ prefix to preprocessor directives that lacked one and
diego
parents:
27341
diff
changeset
|
242 #ifdef CONFIG_DYNAMIC_PLUGINS |
31171 | 243 if (!mpvdec) { |
244 /* try to open shared decoder plugin */ | |
245 int buf_len; | |
246 char *buf; | |
247 vd_functions_t *funcs_sym; | |
248 vd_info_t *info_sym; | |
8152 | 249 |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
250 buf_len = strlen(MPLAYER_LIBDIR) + |
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
251 strlen(sh_video->codec->drv) + 16; |
31171 | 252 buf = malloc(buf_len); |
253 if (!buf) | |
254 break; | |
255 snprintf(buf, buf_len, "%s/mplayer/vd_%s.so", MPLAYER_LIBDIR, | |
256 sh_video->codec->drv); | |
257 mp_msg(MSGT_DECVIDEO, MSGL_DBG2, | |
258 "Trying to open external plugin: %s\n", buf); | |
259 sh_video->dec_handle = dlopen(buf, RTLD_LAZY); | |
260 if (!sh_video->dec_handle) | |
261 break; | |
262 snprintf(buf, buf_len, "mpcodecs_vd_%s", sh_video->codec->drv); | |
263 funcs_sym = dlsym(sh_video->dec_handle, buf); | |
264 if (!funcs_sym || !funcs_sym->info || !funcs_sym->init | |
265 || !funcs_sym->uninit || !funcs_sym->control | |
266 || !funcs_sym->decode) | |
267 break; | |
268 info_sym = funcs_sym->info; | |
269 if (strcmp(info_sym->short_name, sh_video->codec->drv)) | |
270 break; | |
271 free(buf); | |
272 mpvdec = funcs_sym; | |
273 mp_msg(MSGT_DECVIDEO, MSGL_V, | |
274 "Using external decoder plugin (%s/mplayer/vd_%s.so)!\n", | |
275 MPLAYER_LIBDIR, sh_video->codec->drv); | |
276 } | |
8152 | 277 #endif |
31171 | 278 if (!mpvdec) { // driver not available (==compiled in) |
279 mp_msg(MSGT_DECVIDEO, MSGL_WARN, | |
280 MSGTR_VideoCodecFamilyNotAvailableStr, | |
281 sh_video->codec->name, sh_video->codec->drv); | |
282 continue; | |
283 } | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
284 orig_w = sh_video->bih ? sh_video->bih->biWidth : sh_video->disp_w; |
31171 | 285 orig_h = sh_video->bih ? sh_video->bih->biHeight : sh_video->disp_h; |
286 sh_video->disp_w = orig_w; | |
287 sh_video->disp_h = orig_h; | |
288 // it's available, let's try to init! | |
289 if (sh_video->codec->flags & CODECS_FLAG_ALIGN16) { | |
290 // align width/height to n*16 | |
291 sh_video->disp_w = (sh_video->disp_w + 15) & (~15); | |
292 sh_video->disp_h = (sh_video->disp_h + 15) & (~15); | |
293 } | |
294 if (sh_video->bih) { | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
295 sh_video->bih->biWidth = sh_video->disp_w; |
31171 | 296 sh_video->bih->biHeight = sh_video->disp_h; |
297 } | |
298 // init() | |
299 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_OpeningVideoDecoder, | |
300 mpvdec->info->short_name, mpvdec->info->name); | |
301 // clear vf init error, it is no longer relevant | |
302 if (sh_video->vf_initialized < 0) | |
303 sh_video->vf_initialized = 0; | |
304 if (!mpvdec->init(sh_video)) { | |
305 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_VDecoderInitFailed); | |
306 sh_video->disp_w = orig_w; | |
307 sh_video->disp_h = orig_h; | |
308 if (sh_video->bih) { | |
31989
e648473842bd
cosmetics: Repair some of the damage that 'indent' caused.
diego
parents:
31972
diff
changeset
|
309 sh_video->bih->biWidth = sh_video->disp_w; |
31171 | 310 sh_video->bih->biHeight = sh_video->disp_h; |
311 } | |
312 continue; // try next... | |
313 } | |
314 // Yeah! We got it! | |
315 sh_video->initialized = 1; | |
316 return 1; | |
4902
7c4edfe929c8
implemented basic wrapper functions to new libmpcodecs api
arpi
parents:
4901
diff
changeset
|
317 } |
5171
7145d6aba6cd
init_video() changed - now it handles codec selection
arpi
parents:
5155
diff
changeset
|
318 return 0; |
1294 | 319 } |
320 | |
31171 | 321 int init_best_video_codec(sh_video_t *sh_video, char **video_codec_list, |
322 char **video_fm_list) | |
323 { | |
324 char *vc_l_default[2] = { "", (char *) NULL }; | |
325 stringset_t selected; | |
326 // hack: | |
327 if (!video_codec_list) | |
328 video_codec_list = vc_l_default; | |
329 // Go through the codec.conf and find the best codec... | |
330 sh_video->initialized = 0; | |
331 stringset_init(&selected); | |
332 while (!sh_video->initialized && *video_codec_list) { | |
333 char *video_codec = *(video_codec_list++); | |
334 if (video_codec[0]) { | |
335 if (video_codec[0] == '-') { | |
336 // disable this codec: | |
337 stringset_add(&selected, video_codec + 1); | |
338 } else { | |
339 // forced codec by name: | |
340 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_ForcedVideoCodec, | |
341 video_codec); | |
342 init_video(sh_video, video_codec, NULL, -1, &selected); | |
343 } | |
344 } else { | |
345 int status; | |
346 // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING. | |
347 if (video_fm_list) { | |
348 char **fmlist = video_fm_list; | |
349 // try first the preferred codec families: | |
350 while (!sh_video->initialized && *fmlist) { | |
351 char *video_fm = *(fmlist++); | |
352 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_TryForceVideoFmtStr, | |
353 video_fm); | |
354 for (status = CODECS_STATUS__MAX; | |
355 status >= CODECS_STATUS__MIN; --status) | |
356 if (init_video | |
357 (sh_video, NULL, video_fm, status, &selected)) | |
358 break; | |
359 } | |
360 } | |
361 if (!sh_video->initialized) | |
362 for (status = CODECS_STATUS__MAX; status >= CODECS_STATUS__MIN; | |
363 --status) | |
364 if (init_video(sh_video, NULL, NULL, status, &selected)) | |
365 break; | |
366 } | |
7506
c1cb94198e05
-vc/-vfm accepts codec/driver _list_ now. empty list element for -vc means
arpi
parents:
7502
diff
changeset
|
367 } |
31171 | 368 stringset_free(&selected); |
369 | |
370 if (!sh_video->initialized) { | |
371 mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantFindVideoCodec, | |
372 sh_video->format); | |
373 return 0; // failed | |
7502
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
374 } |
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
375 |
31171 | 376 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_SelectedVideoCodec, |
377 sh_video->codec->name, sh_video->codec->drv, sh_video->codec->info); | |
378 return 1; // success | |
7502
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
379 } |
6a2b6f3d619c
best audio/video codec selection & init moved to libmpcodecs
arpi
parents:
7368
diff
changeset
|
380 |
22497 | 381 void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, |
31972 | 382 int drop_frame, double pts, int *full_frame) |
22497 | 383 { |
384 mp_image_t *mpi = NULL; | |
385 unsigned int t = GetTimer(); | |
386 unsigned int t2; | |
387 double tt; | |
31953 | 388 int delay; |
389 int got_picture = 1; | |
1360 | 390 |
31953 | 391 mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); |
392 | |
393 //------------------------ frame decoded. -------------------- | |
394 | |
395 if (mpi && mpi->type == MP_IMGTYPE_INCOMPLETE) { | |
396 got_picture = 0; | |
397 mpi = NULL; | |
398 } | |
399 | |
31972 | 400 if (full_frame) |
401 *full_frame = got_picture; | |
402 | |
31953 | 403 delay = get_current_video_decoder_lag(sh_video); |
404 if (correct_pts && pts != MP_NOPTS_VALUE | |
405 && (got_picture || sh_video->num_buffered_pts < delay)) { | |
31171 | 406 if (sh_video->num_buffered_pts == |
407 sizeof(sh_video->buffered_pts) / sizeof(double)) | |
408 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); | |
409 else { | |
410 int i, j; | |
411 for (i = 0; i < sh_video->num_buffered_pts; i++) | |
412 if (sh_video->buffered_pts[i] < pts) | |
413 break; | |
414 for (j = sh_video->num_buffered_pts; j > i; j--) | |
415 sh_video->buffered_pts[j] = sh_video->buffered_pts[j - 1]; | |
416 sh_video->buffered_pts[i] = pts; | |
417 sh_video->num_buffered_pts++; | |
418 } | |
22497 | 419 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18889
diff
changeset
|
420 |
28290 | 421 #if HAVE_MMX |
22497 | 422 // some codecs are broken, and doesn't restore MMX state :( |
423 // it happens usually with broken/damaged files. | |
424 if (gCpuCaps.has3DNow) { | |
31171 | 425 __asm__ volatile ("femms\n\t":::"memory"); |
426 } else if (gCpuCaps.hasMMX) { | |
427 __asm__ volatile ("emms\n\t":::"memory"); | |
22497 | 428 } |
3160 | 429 #endif |
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, | |
450 "No pts value from demuxer to " "use for frame!\n"); | |
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 } |