Mercurial > mplayer.hg
annotate libmpdvdkit2/dvd_input.c @ 17588:79081ba52e00
Move the v{Y,C}CoeffsBank vectors into the SwsContext, filling them in just
once when the scaler is initialized, instead of building them and freeing
them over and over. This gives massive performance improvements.
patch by Alan Curry, pacman*at*TheWorld*dot*com
author | diego |
---|---|
date | Sat, 11 Feb 2006 14:16:10 +0000 |
parents | 483e955893b8 |
children | f0f54034c7e9 |
rev | line source |
---|---|
7029 | 1 /* |
2 * Copyright (C) 2002 Samuel Hocevar <sam@zoy.org>, | |
3 * Håkan Hjort <d95hjort@dtek.chalmers.se> | |
4 * | |
14938
25df9508f9a8
Mark modified files as such to comply more closely with GPL ¡ø2a.
diego
parents:
14607
diff
changeset
|
5 * Modified for use with MPlayer, changes contained in libdvdread_changes.diff. |
25df9508f9a8
Mark modified files as such to comply more closely with GPL ¡ø2a.
diego
parents:
14607
diff
changeset
|
6 * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
25df9508f9a8
Mark modified files as such to comply more closely with GPL ¡ø2a.
diego
parents:
14607
diff
changeset
|
7 * $Id$ |
25df9508f9a8
Mark modified files as such to comply more closely with GPL ¡ø2a.
diego
parents:
14607
diff
changeset
|
8 * |
7029 | 9 * This program is free software; you can redistribute it and/or modify |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. | |
22 */ | |
23 | |
15874 | 24 #include "config.h" |
25 | |
7029 | 26 #include <stdio.h> |
27 #include <stdlib.h> | |
28 #include <fcntl.h> | |
29 #include <unistd.h> | |
30 | |
31 #include "dvd_reader.h" | |
32 #include "dvd_input.h" | |
33 | |
15874 | 34 /* The function pointers that is the exported interface of this file. */ |
35 dvd_input_t (*dvdinput_open) (const char *); | |
36 int (*dvdinput_close) (dvd_input_t); | |
37 int (*dvdinput_seek) (dvd_input_t, int); | |
38 int (*dvdinput_title) (dvd_input_t, int); | |
39 int (*dvdinput_read) (dvd_input_t, void *, int, int); | |
40 char * (*dvdinput_error) (dvd_input_t); | |
7029 | 41 |
15874 | 42 #ifdef HAVE_DVDCSS_DVDCSS_H |
43 /* linking to libdvdcss */ | |
44 #include "dvdcss.h" | |
45 #define DVDcss_open(a) dvdcss_open((char*)(a)) | |
46 #define DVDcss_close dvdcss_close | |
47 #define DVDcss_seek dvdcss_seek | |
48 #define DVDcss_title dvdcss_title | |
49 #define DVDcss_read dvdcss_read | |
50 #define DVDcss_error dvdcss_error | |
51 #else | |
52 /* dlopening libdvdcss */ | |
53 #include <dlfcn.h> | |
54 typedef struct dvdcss_s *dvdcss_handle; | |
55 static dvdcss_handle (*DVDcss_open) (const char *); | |
56 static int (*DVDcss_close) (dvdcss_handle); | |
57 static int (*DVDcss_seek) (dvdcss_handle, int, int); | |
58 static int (*DVDcss_title) (dvdcss_handle, int); | |
59 static int (*DVDcss_read) (dvdcss_handle, void *, int, int); | |
60 static char * (*DVDcss_error) (dvdcss_handle); | |
61 #endif | |
7029 | 62 |
63 /* The DVDinput handle, add stuff here for new input methods. */ | |
64 struct dvd_input_s { | |
65 /* libdvdcss handle */ | |
66 dvdcss_handle dvdcss; | |
67 | |
68 /* dummy file input */ | |
69 int fd; | |
70 }; | |
71 | |
72 | |
73 /** | |
74 * initialize and open a DVD device or file. | |
75 */ | |
76 static dvd_input_t css_open(const char *target) | |
77 { | |
78 dvd_input_t dev; | |
15874 | 79 |
7029 | 80 /* Allocate the handle structure */ |
11776
12615e408fb9
Fix (possible) memory corruption. dvd_input_t is pointer to struct dvd_input_s and not a struct.
lumag
parents:
7033
diff
changeset
|
81 dev = (dvd_input_t) malloc(sizeof(struct dvd_input_s)); |
7029 | 82 if(dev == NULL) { |
83 fprintf(stderr, "libdvdread: Could not allocate memory.\n"); | |
84 return NULL; | |
85 } | |
86 | |
87 /* Really open it with libdvdcss */ | |
88 dev->dvdcss = DVDcss_open(target); | |
89 if(dev->dvdcss == 0) { | |
15874 | 90 fprintf(stderr, "libdvdread: Could not open %s with libdvdcss.\n", target); |
7029 | 91 free(dev); |
92 return NULL; | |
93 } | |
94 | |
95 return dev; | |
96 } | |
97 | |
98 /** | |
99 * return the last error message | |
100 */ | |
101 static char *css_error(dvd_input_t dev) | |
102 { | |
103 return DVDcss_error(dev->dvdcss); | |
104 } | |
105 | |
106 /** | |
107 * seek into the device. | |
108 */ | |
15874 | 109 static int css_seek(dvd_input_t dev, int blocks) |
7029 | 110 { |
15874 | 111 /* DVDINPUT_NOFLAGS should match the DVDCSS_NOFLAGS value. */ |
112 return DVDcss_seek(dev->dvdcss, blocks, DVDINPUT_NOFLAGS); | |
7029 | 113 } |
114 | |
115 /** | |
116 * set the block for the begining of a new title (key). | |
117 */ | |
118 static int css_title(dvd_input_t dev, int block) | |
119 { | |
120 return DVDcss_title(dev->dvdcss, block); | |
121 } | |
122 | |
123 /** | |
124 * read data from the device. | |
125 */ | |
126 static int css_read(dvd_input_t dev, void *buffer, int blocks, int flags) | |
127 { | |
128 return DVDcss_read(dev->dvdcss, buffer, blocks, flags); | |
129 } | |
130 | |
131 /** | |
132 * close the DVD device and clean up the library. | |
133 */ | |
134 static int css_close(dvd_input_t dev) | |
135 { | |
136 int ret; | |
137 | |
138 ret = DVDcss_close(dev->dvdcss); | |
139 | |
140 if(ret < 0) | |
141 return ret; | |
142 | |
143 free(dev); | |
144 | |
145 return 0; | |
146 } | |
147 | |
148 | |
149 | |
15874 | 150 |
151 | |
152 | |
153 /** | |
154 * initialize and open a DVD device or file. | |
155 */ | |
156 static dvd_input_t file_open(const char *target) | |
157 { | |
158 dvd_input_t dev; | |
159 | |
160 /* Allocate the library structure */ | |
161 dev = (dvd_input_t) malloc(sizeof(dvd_input_t)); | |
162 if(dev == NULL) { | |
163 fprintf(stderr, "libdvdread: Could not allocate memory.\n"); | |
164 return NULL; | |
165 } | |
166 | |
167 /* Open the device */ | |
168 dev->fd = open(target, O_RDONLY); | |
169 if(dev->fd < 0) { | |
170 perror("libdvdread: Could not open input"); | |
171 free(dev); | |
172 return NULL; | |
173 } | |
174 | |
175 return dev; | |
176 } | |
177 | |
178 /** | |
179 * return the last error message | |
180 */ | |
181 static char *file_error(dvd_input_t dev) | |
182 { | |
183 /* use strerror(errno)? */ | |
184 return (char *)"unknown error"; | |
185 } | |
186 | |
187 /** | |
188 * seek into the device. | |
189 */ | |
190 static int file_seek(dvd_input_t dev, int blocks) | |
191 { | |
192 off_t pos; | |
193 | |
194 pos = lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET); | |
195 if(pos < 0) { | |
196 return pos; | |
197 } | |
198 /* assert pos % DVD_VIDEO_LB_LEN == 0 */ | |
199 return (int) (pos / DVD_VIDEO_LB_LEN); | |
200 } | |
201 | |
202 /** | |
203 * set the block for the begining of a new title (key). | |
204 */ | |
205 static int file_title(dvd_input_t dev, int block) | |
206 { | |
207 return -1; | |
208 } | |
209 | |
210 /** | |
211 * read data from the device. | |
212 */ | |
213 static int file_read(dvd_input_t dev, void *buffer, int blocks, int flags) | |
214 { | |
215 size_t len; | |
216 ssize_t ret; | |
217 | |
218 len = (size_t)blocks * DVD_VIDEO_LB_LEN; | |
219 | |
220 while(len > 0) { | |
221 | |
222 ret = read(dev->fd, buffer, len); | |
223 | |
224 if(ret < 0) { | |
225 /* One of the reads failed, too bad. We won't even bother | |
226 * returning the reads that went ok, and as in the posix spec | |
227 * the file postition is left unspecified after a failure. */ | |
228 return ret; | |
229 } | |
230 | |
231 if(ret == 0) { | |
232 /* Nothing more to read. Return the whole blocks, if any, that we got. | |
233 and adjust the file possition back to the previous block boundary. */ | |
234 size_t bytes = (size_t)blocks * DVD_VIDEO_LB_LEN - len; | |
235 off_t over_read = -(bytes % DVD_VIDEO_LB_LEN); | |
236 /*off_t pos =*/ lseek(dev->fd, over_read, SEEK_CUR); | |
237 /* should have pos % 2048 == 0 */ | |
238 return (int) (bytes / DVD_VIDEO_LB_LEN); | |
239 } | |
240 | |
241 len -= ret; | |
242 } | |
243 | |
244 return blocks; | |
245 } | |
246 | |
247 /** | |
248 * close the DVD device and clean up. | |
249 */ | |
250 static int file_close(dvd_input_t dev) | |
251 { | |
252 int ret; | |
253 | |
254 ret = close(dev->fd); | |
255 | |
256 if(ret < 0) | |
257 return ret; | |
258 | |
259 free(dev); | |
260 | |
261 return 0; | |
262 } | |
263 | |
264 | |
7029 | 265 /** |
266 * Setup read functions with either libdvdcss or minimal DVD access. | |
267 */ | |
15874 | 268 int dvdinput_setup(void) |
7029 | 269 { |
15874 | 270 void *dvdcss_library = NULL; |
271 char **dvdcss_version = NULL; | |
272 | |
273 #ifdef HAVE_DVDCSS_DVDCSS_H | |
274 /* linking to libdvdcss */ | |
275 dvdcss_library = &dvdcss_library; /* Give it some value != NULL */ | |
276 /* the DVDcss_* functions have been #defined at the top */ | |
277 dvdcss_version = &dvdcss_interface_2; | |
278 | |
279 #else | |
280 /* dlopening libdvdcss */ | |
281 dvdcss_library = dlopen("libdvdcss.so.2", RTLD_LAZY); | |
282 | |
283 if(dvdcss_library != NULL) { | |
284 #if defined(__OpenBSD__) && !defined(__ELF__) | |
285 #define U_S "_" | |
286 #else | |
287 #define U_S | |
288 #endif | |
289 DVDcss_open = (dvdcss_handle (*)(const char*)) | |
290 dlsym(dvdcss_library, U_S "dvdcss_open"); | |
291 DVDcss_close = (int (*)(dvdcss_handle)) | |
292 dlsym(dvdcss_library, U_S "dvdcss_close"); | |
293 DVDcss_title = (int (*)(dvdcss_handle, int)) | |
294 dlsym(dvdcss_library, U_S "dvdcss_title"); | |
295 DVDcss_seek = (int (*)(dvdcss_handle, int, int)) | |
296 dlsym(dvdcss_library, U_S "dvdcss_seek"); | |
297 DVDcss_read = (int (*)(dvdcss_handle, void*, int, int)) | |
298 dlsym(dvdcss_library, U_S "dvdcss_read"); | |
299 DVDcss_error = (char* (*)(dvdcss_handle)) | |
300 dlsym(dvdcss_library, U_S "dvdcss_error"); | |
7029 | 301 |
15874 | 302 dvdcss_version = (char **)dlsym(dvdcss_library, U_S "dvdcss_interface_2"); |
303 | |
304 if(dlsym(dvdcss_library, U_S "dvdcss_crack")) { | |
305 fprintf(stderr, | |
306 "libdvdread: Old (pre-0.0.2) version of libdvdcss found.\n" | |
307 "libdvdread: You should get the latest version from " | |
308 "http://www.videolan.org/\n" ); | |
309 dlclose(dvdcss_library); | |
310 dvdcss_library = NULL; | |
311 } else if(!DVDcss_open || !DVDcss_close || !DVDcss_title || !DVDcss_seek | |
312 || !DVDcss_read || !DVDcss_error || !dvdcss_version) { | |
313 fprintf(stderr, "libdvdread: Missing symbols in libdvdcss.so.2, " | |
314 "this shouldn't happen !\n"); | |
315 dlclose(dvdcss_library); | |
316 } | |
317 } | |
318 #endif /* HAVE_DVDCSS_DVDCSS_H */ | |
319 | |
320 if(dvdcss_library != NULL) { | |
7029 | 321 /* |
322 char *psz_method = getenv( "DVDCSS_METHOD" ); | |
323 char *psz_verbose = getenv( "DVDCSS_VERBOSE" ); | |
324 fprintf(stderr, "DVDCSS_METHOD %s\n", psz_method); | |
325 fprintf(stderr, "DVDCSS_VERBOSE %s\n", psz_verbose); | |
326 */ | |
15874 | 327 /* |
328 fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD access\n", | |
329 *dvdcss_version); | |
330 */ | |
7029 | 331 |
15874 | 332 /* libdvdcss wrapper functions */ |
333 dvdinput_open = css_open; | |
334 dvdinput_close = css_close; | |
335 dvdinput_seek = css_seek; | |
336 dvdinput_title = css_title; | |
337 dvdinput_read = css_read; | |
338 dvdinput_error = css_error; | |
7029 | 339 return 1; |
340 | |
15874 | 341 } else { |
342 fprintf(stderr, "libdvdread: Encrypted DVD support unavailable.\n"); | |
343 | |
344 /* libdvdcss replacement functions */ | |
345 dvdinput_open = file_open; | |
346 dvdinput_close = file_close; | |
347 dvdinput_seek = file_seek; | |
348 dvdinput_title = file_title; | |
349 dvdinput_read = file_read; | |
350 dvdinput_error = file_error; | |
351 return 0; | |
352 } | |
7029 | 353 } |