Mercurial > mplayer.hg
annotate loader/ldt_keeper.c @ 36316:139f2b064ef9
Don't subsequently calculate original_aspect from last movie_aspect.
Instead, differentiate between the original aspect ratio stored in or
determined from the video file and the forced, i.e. current, aspect
ratio (e.g. forced by command line override).
This enables multiple independent instances of vd.c again which has
been broken by introducing a static variable in r36401.
Without the subsequent calculation of original_aspect it now contains
nothing but the pure video file aspect ratio which makes it possible
to use movie_aspect -1 to set the original aspect ratio which explains
the changes in command.c and gui/dialog/menu.c.
The changes in vd_mpegpes due to the impact of original_aspect will
fix a bug there at the same time where the condition in order to call
mpcodecs_config_vo() should only trigger once when the encoded aspect
changes. So far, the forced, i.e. current, aspect has been checked.
The whole is related to enabling special argument -1 to switch_ratio
started in r36391.
author | ib |
---|---|
date | Wed, 07 Aug 2013 20:41:34 +0000 |
parents | b1d68e8f28c0 |
children |
rev | line source |
---|---|
2067 | 1 /** |
2 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
3 * This file MUST be in main library because LDT must | |
4 * be modified before program creates first thread | |
5 * - avifile includes this file from C++ code | |
6 * and initializes it at the start of player! | |
7386 | 7 * it might sound like a hack and it really is - but |
8 * as aviplay is deconding video with more than just one | |
9 * thread currently it's necessary to do it this way | |
10 * this might change in the future | |
2067 | 11 */ |
12 | |
7386 | 13 /* applied some modification to make make our xine friend more happy */ |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
14537
diff
changeset
|
14 |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
14537
diff
changeset
|
15 /* |
18783 | 16 * Modified for use with MPlayer, detailed changelog at |
17 * http://svn.mplayerhq.hu/mplayer/trunk/ | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
14537
diff
changeset
|
18 */ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
14537
diff
changeset
|
19 |
35905 | 20 #define _BSD_SOURCE |
21 | |
26105 | 22 #include "config.h" |
2139 | 23 #include "ldt_keeper.h" |
24 | |
2067 | 25 #include <string.h> |
26 #include <stdlib.h> | |
27 #include <errno.h> | |
28 #include <fcntl.h> | |
33412
2a2e9b6551d8
configure: Convert HAVE_SYS_MMAN_H into a 0/1 definition.
diego
parents:
32537
diff
changeset
|
29 #if HAVE_SYS_MMAN_H |
2067 | 30 #include <sys/mman.h> |
26111
eb82d1524b6d
#include osdep/mman.h if sys/mman.h is not available.
diego
parents:
26105
diff
changeset
|
31 #else |
eb82d1524b6d
#include osdep/mman.h if sys/mman.h is not available.
diego
parents:
26105
diff
changeset
|
32 #include "osdep/mmap.h" |
26105 | 33 #endif |
2067 | 34 #include <sys/types.h> |
35 #include <stdio.h> | |
36 #include <unistd.h> | |
21187
d9cedf7b8069
added mmap_anon to osdep lib. Used in loader for now
nplourde
parents:
18878
diff
changeset
|
37 #include "osdep/mmap_anon.h" |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
38 #include "mp_msg.h" |
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
39 #include "help_mp.h" |
2067 | 40 #ifdef __linux__ |
41 #include <asm/unistd.h> | |
42 #include <asm/ldt.h> | |
8213 | 43 // 2.5.xx+ calls this user_desc: |
44 #include <linux/version.h> | |
45 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,47) | |
46 #define modify_ldt_ldt_s user_desc | |
47 #endif | |
13351
698fe63084d3
declare modify_ldt with syscall3 macro for older glibcs patch by Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
faust3
parents:
10821
diff
changeset
|
48 /// declare modify_ldt with the _syscall3 macro for older glibcs |
13361 | 49 #if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)) |
13351
698fe63084d3
declare modify_ldt with syscall3 macro for older glibcs patch by Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
faust3
parents:
10821
diff
changeset
|
50 _syscall3( int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount ); |
698fe63084d3
declare modify_ldt with syscall3 macro for older glibcs patch by Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
faust3
parents:
10821
diff
changeset
|
51 #else |
7386 | 52 int modify_ldt(int func, void *ptr, unsigned long bytecount); |
13351
698fe63084d3
declare modify_ldt with syscall3 macro for older glibcs patch by Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
faust3
parents:
10821
diff
changeset
|
53 #endif |
2067 | 54 #else |
15566 | 55 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) |
5872 | 56 #include <machine/segments.h> |
2067 | 57 #include <machine/sysarch.h> |
30483
74d33572f1ff
Merge some preprocessor conditionals where appropriate.
diego
parents:
29263
diff
changeset
|
58 #elif defined(__APPLE__) |
26054
d9b11d83367f
Add missing #includes for Mac OS X, fixes the warning
diego
parents:
25849
diff
changeset
|
59 #include <architecture/i386/table.h> |
d9b11d83367f
Add missing #includes for Mac OS X, fixes the warning
diego
parents:
25849
diff
changeset
|
60 #include <i386/user_ldt.h> |
30483
74d33572f1ff
Merge some preprocessor conditionals where appropriate.
diego
parents:
29263
diff
changeset
|
61 #elif defined(__svr4__) |
2067 | 62 #include <sys/segment.h> |
63 #include <sys/sysi86.h> | |
64 | |
22715
363c84953547
check that definition of prototype of sysi86(int, void*) doesn't conflict; fixed compilation in opensolaris
nicodvb
parents:
21290
diff
changeset
|
65 /* solaris x86: add missing prototype for sysi86(), but only when sysi86(int, void*) is known to be valid */ |
35954 | 66 #if HAVE_SYSI86 |
7386 | 67 int sysi86(int, void*); |
18362
29b2221982b3
Add a check for sysi86() on Solaris systems, solving a build failure on Solaris
diego
parents:
17605
diff
changeset
|
68 #endif |
2067 | 69 |
2139 | 70 #ifndef NUMSYSLDTS /* SunOS 2.5.1 does not define NUMSYSLDTS */ |
71 #define NUMSYSLDTS 6 /* Let's hope the SunOS 5.8 value is OK */ | |
2067 | 72 #endif |
73 | |
74 #define TEB_SEL_IDX NUMSYSLDTS | |
75 #endif | |
76 | |
77 #define LDT_ENTRIES 8192 | |
78 #define LDT_ENTRY_SIZE 8 | |
79 #pragma pack(4) | |
80 struct modify_ldt_ldt_s { | |
81 unsigned int entry_number; | |
82 unsigned long base_addr; | |
83 unsigned int limit; | |
84 unsigned int seg_32bit:1; | |
85 unsigned int contents:2; | |
86 unsigned int read_exec_only:1; | |
87 unsigned int limit_in_pages:1; | |
88 unsigned int seg_not_present:1; | |
89 unsigned int useable:1; | |
90 }; | |
91 | |
92 #define MODIFY_LDT_CONTENTS_DATA 0 | |
93 #define MODIFY_LDT_CONTENTS_STACK 1 | |
94 #define MODIFY_LDT_CONTENTS_CODE 2 | |
95 #endif | |
96 | |
97 | |
98 /* user level (privilege level: 3) ldt (1<<2) segment selector */ | |
99 #define LDT_SEL(idx) ((idx) << 3 | 1 << 2 | 3) | |
100 | |
7386 | 101 /* i got this value from wine sources, it's the first free LDT entry */ |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
102 #if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(LDT_AUTO_ALLOC) |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
103 #define TEB_SEL_IDX LDT_AUTO_ALLOC |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
104 #define USE_LDT_AA |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
105 #endif |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
106 |
2067 | 107 #ifndef TEB_SEL_IDX |
7386 | 108 #define TEB_SEL_IDX 17 |
2067 | 109 #endif |
7386 | 110 |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
111 static unsigned int fs_ldt = TEB_SEL_IDX; |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
112 |
2067 | 113 |
114 /** | |
115 * here is a small logical problem with Restore for multithreaded programs - | |
116 * in C++ we use static class for this... | |
117 */ | |
118 | |
119 void Setup_FS_Segment(void) | |
120 { | |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
121 unsigned int ldt_desc = LDT_SEL(fs_ldt); |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
122 |
27757
b5a46071062a
Replace all occurrences of '__volatile__' and '__volatile' by plain 'volatile'.
diego
parents:
26111
diff
changeset
|
123 __asm__ volatile( |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
124 "movl %0,%%eax; movw %%ax, %%fs" : : "r" (ldt_desc) |
14212
540903a59fc0
add missing registers in clobber list, fixes bug #169
reimar
parents:
13361
diff
changeset
|
125 :"eax" |
2067 | 126 ); |
127 } | |
128 | |
7386 | 129 /* we don't need this - use modify_ldt instead */ |
130 #if 0 | |
2067 | 131 #ifdef __linux__ |
132 /* XXX: why is this routine from libc redefined here? */ | |
133 /* NOTE: the redefined version ignores the count param, count is hardcoded as 16 */ | |
134 static int LDT_Modify( int func, struct modify_ldt_ldt_s *ptr, | |
135 unsigned long count ) | |
136 { | |
137 int res; | |
138 #ifdef __PIC__ | |
27757
b5a46071062a
Replace all occurrences of '__volatile__' and '__volatile' by plain 'volatile'.
diego
parents:
26111
diff
changeset
|
139 __asm__ volatile( "pushl %%ebx\n\t" |
2067 | 140 "movl %2,%%ebx\n\t" |
141 "int $0x80\n\t" | |
142 "popl %%ebx" | |
143 : "=a" (res) | |
144 : "0" (__NR_modify_ldt), | |
145 "r" (func), | |
146 "c" (ptr), | |
147 "d"(16)//sizeof(*ptr) from kernel point of view | |
148 :"esi" ); | |
149 #else | |
27757
b5a46071062a
Replace all occurrences of '__volatile__' and '__volatile' by plain 'volatile'.
diego
parents:
26111
diff
changeset
|
150 __asm__ volatile("int $0x80" |
2067 | 151 : "=a" (res) |
152 : "0" (__NR_modify_ldt), | |
153 "b" (func), | |
154 "c" (ptr), | |
155 "d"(16) | |
156 :"esi"); | |
157 #endif /* __PIC__ */ | |
158 if (res >= 0) return res; | |
159 errno = -res; | |
160 return -1; | |
161 } | |
162 #endif | |
7386 | 163 #endif |
2067 | 164 |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
165 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) |
2067 | 166 static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content ) |
167 { | |
168 *buffer++ = ((content->base_addr & 0x0000ffff) << 16) | | |
169 (content->limit & 0x0ffff); | |
170 *buffer = (content->base_addr & 0xff000000) | | |
171 ((content->base_addr & 0x00ff0000)>>16) | | |
172 (content->limit & 0xf0000) | | |
173 (content->contents << 10) | | |
174 ((content->read_exec_only == 0) << 9) | | |
175 ((content->seg_32bit != 0) << 22) | | |
176 ((content->limit_in_pages != 0) << 23) | | |
177 0xf000; | |
178 } | |
179 #endif | |
180 | |
8223 | 181 void* fs_seg=0; |
7386 | 182 |
183 ldt_fs_t* Setup_LDT_Keeper(void) | |
2067 | 184 { |
185 struct modify_ldt_ldt_s array; | |
186 int ret; | |
30702 | 187 ldt_fs_t* ldt_fs = malloc(sizeof(ldt_fs_t)); |
2067 | 188 |
7386 | 189 if (!ldt_fs) |
190 return NULL; | |
2067 | 191 |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
192 #ifdef __APPLE__ |
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
193 if (getenv("DYLD_BIND_AT_LAUNCH") == NULL) |
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
194 mp_msg(MSGT_LOADER, MSGL_WARN, MSGTR_LOADER_DYLD_Warning); |
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
195 #endif /* __APPLE__ */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
196 |
8223 | 197 fs_seg= |
21248 | 198 ldt_fs->fs_seg = mmap_anon(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, 0); |
7386 | 199 if (ldt_fs->fs_seg == (void*)-1) |
2067 | 200 { |
201 perror("ERROR: Couldn't allocate memory for fs segment"); | |
7386 | 202 free(ldt_fs); |
203 return NULL; | |
2067 | 204 } |
7386 | 205 *(void**)((char*)ldt_fs->fs_seg+0x18) = ldt_fs->fs_seg; |
14537 | 206 memset(&array, 0, sizeof(array)); |
7386 | 207 array.base_addr=(int)ldt_fs->fs_seg; |
2067 | 208 array.entry_number=TEB_SEL_IDX; |
209 array.limit=array.base_addr+getpagesize()-1; | |
210 array.seg_32bit=1; | |
211 array.read_exec_only=0; | |
212 array.seg_not_present=0; | |
213 array.contents=MODIFY_LDT_CONTENTS_DATA; | |
214 array.limit_in_pages=0; | |
215 #ifdef __linux__ | |
7386 | 216 //ret=LDT_Modify(0x1, &array, sizeof(struct modify_ldt_ldt_s)); |
217 ret=modify_ldt(0x1, &array, sizeof(struct modify_ldt_ldt_s)); | |
2067 | 218 if(ret<0) |
219 { | |
220 perror("install_fs"); | |
221 printf("Couldn't install fs segment, expect segfault\n"); | |
222 } | |
30483
74d33572f1ff
Merge some preprocessor conditionals where appropriate.
diego
parents:
29263
diff
changeset
|
223 #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) |
2067 | 224 { |
225 unsigned long d[2]; | |
226 | |
227 LDT_EntryToBytes( d, &array ); | |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
228 #ifdef USE_LDT_AA |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
229 ret = i386_set_ldt(LDT_AUTO_ALLOC, (union descriptor *)d, 1); |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
230 array.entry_number = ret; |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
231 fs_ldt = ret; |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
232 #else |
2067 | 233 ret = i386_set_ldt(array.entry_number, (union descriptor *)d, 1); |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
234 #endif |
2067 | 235 if (ret < 0) |
236 { | |
237 perror("install_fs"); | |
238 printf("Couldn't install fs segment, expect segfault\n"); | |
239 printf("Did you reconfigure the kernel with \"options USER_LDT\"?\n"); | |
17605 | 240 #ifdef __OpenBSD__ |
241 printf("On newer OpenBSD systems did you set machdep.userldt to 1?\n"); | |
242 #endif | |
2067 | 243 } |
244 } | |
30483
74d33572f1ff
Merge some preprocessor conditionals where appropriate.
diego
parents:
29263
diff
changeset
|
245 #elif defined(__svr4__) |
2070
c1edbb8bfc0c
(solaris x86) C++ style variable declaration not at the start of a block does
jkeil
parents:
2069
diff
changeset
|
246 { |
2139 | 247 struct ssd ssd; |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
248 ssd.sel = LDT_SEL(TEB_SEL_IDX); |
2139 | 249 ssd.bo = array.base_addr; |
250 ssd.ls = array.limit - array.base_addr; | |
251 ssd.acc1 = ((array.read_exec_only == 0) << 1) | | |
252 (array.contents << 2) | | |
253 0xf0; /* P(resent) | DPL3 | S */ | |
254 ssd.acc2 = 0x4; /* byte limit, 32-bit segment */ | |
255 if (sysi86(SI86DSCR, &ssd) < 0) { | |
256 perror("sysi86(SI86DSCR)"); | |
257 printf("Couldn't install fs segment, expect segfault\n"); | |
258 } | |
2070
c1edbb8bfc0c
(solaris x86) C++ style variable declaration not at the start of a block does
jkeil
parents:
2069
diff
changeset
|
259 } |
30499 | 260 #elif defined(__OS2__) |
261 /* convert flat addr to sel idx for LDT_SEL() */ | |
262 fs_ldt = (uintptr_t)fs_seg >> 16; | |
2067 | 263 #endif |
264 | |
265 Setup_FS_Segment(); | |
266 | |
18878 | 267 ldt_fs->prev_struct = malloc(8); |
7386 | 268 *(void**)array.base_addr = ldt_fs->prev_struct; |
269 | |
270 return ldt_fs; | |
2067 | 271 } |
272 | |
7386 | 273 void Restore_LDT_Keeper(ldt_fs_t* ldt_fs) |
2067 | 274 { |
7386 | 275 if (ldt_fs == NULL || ldt_fs->fs_seg == 0) |
2067 | 276 return; |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30702
diff
changeset
|
277 free(ldt_fs->prev_struct); |
7386 | 278 munmap((char*)ldt_fs->fs_seg, getpagesize()); |
279 ldt_fs->fs_seg = 0; | |
280 free(ldt_fs); | |
2067 | 281 } |