1 | /*
|
---|
2 | * DreamDVD V0.9 - DVD-Player for Dreambox
|
---|
3 | * Copyright (C) 2007 by Seddi
|
---|
4 | *
|
---|
5 | * This DVD Player is based upon the great work from the libdvdnav project,
|
---|
6 | * a52dec library, ffmpeg and the knowledge from all the people who made
|
---|
7 | * watching DVD within linux possible.
|
---|
8 | *
|
---|
9 | * DreamDVD 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 | * DreamDVD 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-1307, USA
|
---|
22 | *
|
---|
23 | * part of libdreamdvd
|
---|
24 | */
|
---|
25 |
|
---|
26 | #include "main.h"
|
---|
27 | #include "mpegaudioenc.h"
|
---|
28 | #include "a52dec.h"
|
---|
29 | #include <asm/types.h>
|
---|
30 |
|
---|
31 | #ifdef __sh__
|
---|
32 | //aktivate LPCM Support
|
---|
33 | #define HARDWARE_SUPPORT_LPCM
|
---|
34 | #endif
|
---|
35 |
|
---|
36 | /*
|
---|
37 | * local helper functions
|
---|
38 | */
|
---|
39 | static ssize_t safe_write(int fd, const void *buf, size_t count)
|
---|
40 | {
|
---|
41 | const uint8_t *ptr = buf;
|
---|
42 | size_t written = 0;
|
---|
43 | ssize_t n;
|
---|
44 |
|
---|
45 | while (written < count) {
|
---|
46 | n = write(fd, &ptr[written], count - written);
|
---|
47 | #if defined(__sh__)
|
---|
48 | return 0;
|
---|
49 | #else
|
---|
50 | if (n < 0) {
|
---|
51 | if (errno != EINTR) {
|
---|
52 | perror("write");
|
---|
53 | return written ? written : -1;
|
---|
54 | }
|
---|
55 | } else {
|
---|
56 | written += n;
|
---|
57 | }
|
---|
58 | #endif
|
---|
59 | }
|
---|
60 |
|
---|
61 | return written;
|
---|
62 | }
|
---|
63 |
|
---|
64 | static void write_string(const char *filename, const char *string)
|
---|
65 | {
|
---|
66 | FILE *f;
|
---|
67 |
|
---|
68 | f = fopen(filename, "w");
|
---|
69 | if (f == NULL) {
|
---|
70 | perror(filename);
|
---|
71 | return;
|
---|
72 | }
|
---|
73 |
|
---|
74 | fputs(string, f);
|
---|
75 | fclose(f);
|
---|
76 | }
|
---|
77 |
|
---|
78 | static int open_pipe(int fd[2])
|
---|
79 | {
|
---|
80 | int flags;
|
---|
81 |
|
---|
82 | fd[0] = fd[1] = -1;
|
---|
83 |
|
---|
84 | if (pipe(fd) < 0) {
|
---|
85 | perror("pipe");
|
---|
86 | goto err;
|
---|
87 | }
|
---|
88 |
|
---|
89 | flags = fcntl(fd[0], F_GETFL);
|
---|
90 | if (flags < 0) {
|
---|
91 | perror("F_GETFL");
|
---|
92 | goto err;
|
---|
93 | }
|
---|
94 | if (fcntl(fd[0], F_SETFL, flags | O_NONBLOCK) < 0) {
|
---|
95 | perror("F_SETFL");
|
---|
96 | goto err;
|
---|
97 | }
|
---|
98 |
|
---|
99 | return 0;
|
---|
100 |
|
---|
101 | err:
|
---|
102 | if (fd[0] != -1) {
|
---|
103 | close(fd[0]);
|
---|
104 | fd[0] = -1;
|
---|
105 | }
|
---|
106 | if (fd[1] != -1) {
|
---|
107 | close(fd[1]);
|
---|
108 | fd[1] = -1;
|
---|
109 | }
|
---|
110 |
|
---|
111 | return -1;
|
---|
112 | }
|
---|
113 |
|
---|
114 | /*
|
---|
115 | * external functions
|
---|
116 | */
|
---|
117 |
|
---|
118 | // create ddvd handle and set defaults
|
---|
119 | struct ddvd *ddvd_create(void)
|
---|
120 | {
|
---|
121 | struct ddvd *pconfig;
|
---|
122 |
|
---|
123 | pconfig = malloc(sizeof(struct ddvd));
|
---|
124 | if (pconfig == NULL) {
|
---|
125 | perror("malloc");
|
---|
126 | return NULL;
|
---|
127 | }
|
---|
128 |
|
---|
129 | memset(pconfig, 0, sizeof(struct ddvd));
|
---|
130 |
|
---|
131 | // defaults
|
---|
132 | ddvd_set_ac3thru(pconfig, 0);
|
---|
133 | ddvd_set_language(pconfig, "en");
|
---|
134 | #if defined(__sh__)
|
---|
135 | ddvd_set_dvd_path(pconfig, "/dev/sr0");
|
---|
136 | #else
|
---|
137 | ddvd_set_dvd_path(pconfig, "/dev/cdroms/cdrom0");
|
---|
138 | #endif
|
---|
139 | ddvd_set_video(pconfig, DDVD_4_3, DDVD_LETTERBOX, DDVD_PAL);
|
---|
140 | ddvd_set_lfb(pconfig, NULL, 720, 576, 1, 720);
|
---|
141 | struct ddvd_resume resume_info;
|
---|
142 | resume_info.title=resume_info.chapter=resume_info.block=resume_info.audio_id=resume_info.audio_lock=resume_info.spu_id=resume_info.spu_lock=0;
|
---|
143 | ddvd_set_resume_pos(pconfig, resume_info);
|
---|
144 | pconfig->should_resume = 0;
|
---|
145 | pconfig->next_time_update = 0;
|
---|
146 | strcpy(pconfig->title_string, "");
|
---|
147 |
|
---|
148 | // open pipes
|
---|
149 | if (open_pipe(pconfig->key_pipe) < 0) {
|
---|
150 | ddvd_close(pconfig);
|
---|
151 | return NULL;
|
---|
152 | }
|
---|
153 | if (open_pipe(pconfig->message_pipe) < 0) {
|
---|
154 | ddvd_close(pconfig);
|
---|
155 | return NULL;
|
---|
156 | }
|
---|
157 |
|
---|
158 | return pconfig;
|
---|
159 | }
|
---|
160 |
|
---|
161 | // destroy ddvd handle
|
---|
162 | void ddvd_close(struct ddvd *pconfig)
|
---|
163 | {
|
---|
164 | if (pconfig->message_pipe[0] != -1)
|
---|
165 | close(pconfig->message_pipe[0]);
|
---|
166 | if (pconfig->message_pipe[1] != -1)
|
---|
167 | close(pconfig->message_pipe[1]);
|
---|
168 | if (pconfig->key_pipe[0] != -1)
|
---|
169 | close(pconfig->key_pipe[0]);
|
---|
170 | if (pconfig->key_pipe[1] != -1)
|
---|
171 | close(pconfig->key_pipe[1]);
|
---|
172 | if (pconfig->dvd_path != NULL)
|
---|
173 | free(pconfig->dvd_path);
|
---|
174 |
|
---|
175 | free(pconfig);
|
---|
176 | }
|
---|
177 |
|
---|
178 | // get message_pipe fd for polling functions in the host app
|
---|
179 | int ddvd_get_messagepipe_fd(struct ddvd *pconfig)
|
---|
180 | {
|
---|
181 | return pconfig->message_pipe[0];
|
---|
182 | }
|
---|
183 |
|
---|
184 | // set resume postion
|
---|
185 | void ddvd_set_resume_pos(struct ddvd *pconfig, struct ddvd_resume resume_info)
|
---|
186 | {
|
---|
187 | pconfig->resume_title = resume_info.title;
|
---|
188 | pconfig->resume_chapter = resume_info.chapter;
|
---|
189 | pconfig->resume_block = resume_info.block;
|
---|
190 | pconfig->should_resume = 1;
|
---|
191 | pconfig->resume_audio_id = resume_info.audio_id;
|
---|
192 | pconfig->resume_audio_lock = resume_info.audio_lock;
|
---|
193 | pconfig->resume_spu_id = resume_info.spu_id;
|
---|
194 | pconfig->resume_spu_lock = resume_info.spu_lock;
|
---|
195 | }
|
---|
196 |
|
---|
197 | // set framebuffer options
|
---|
198 | void ddvd_set_lfb(struct ddvd *pconfig, unsigned char *lfb, int xres, int yres, int bypp, int stride)
|
---|
199 | {
|
---|
200 | return ddvd_set_lfb_ex(pconfig, lfb, xres, yres, bypp, stride, 0);
|
---|
201 | }
|
---|
202 |
|
---|
203 | void ddvd_set_lfb_ex(struct ddvd *pconfig, unsigned char *lfb, int xres, int yres, int bypp, int stride, int canscale)
|
---|
204 | {
|
---|
205 | pconfig->lfb = lfb;
|
---|
206 | pconfig->xres = xres;
|
---|
207 | pconfig->yres = yres;
|
---|
208 | pconfig->stride = stride;
|
---|
209 | pconfig->bypp = bypp;
|
---|
210 | pconfig->canscale = canscale;
|
---|
211 | }
|
---|
212 |
|
---|
213 | // set path to dvd block device or file structure/iso
|
---|
214 | void ddvd_set_dvd_path(struct ddvd *pconfig, const char *path)
|
---|
215 | {
|
---|
216 | if (pconfig->dvd_path != NULL)
|
---|
217 | free(pconfig->dvd_path);
|
---|
218 |
|
---|
219 | pconfig->dvd_path = strdup(path);
|
---|
220 | }
|
---|
221 |
|
---|
222 | // set language
|
---|
223 | void ddvd_set_language(struct ddvd *pconfig, const char lang[2])
|
---|
224 | {
|
---|
225 | memcpy(pconfig->language, lang, 2);
|
---|
226 | }
|
---|
227 |
|
---|
228 | // set internal ac3 decoding (needs liba52 which will be dynamically loaded)
|
---|
229 | void ddvd_set_ac3thru(struct ddvd *pconfig, int ac3thru)
|
---|
230 | {
|
---|
231 | pconfig->ac3thru = ac3thru;
|
---|
232 | }
|
---|
233 |
|
---|
234 | // set video options
|
---|
235 | void ddvd_set_video_ex(struct ddvd *pconfig, int aspect, int tv_mode, int tv_mode2, int tv_system)
|
---|
236 | {
|
---|
237 | pconfig->aspect = aspect;
|
---|
238 | pconfig->tv_mode = tv_mode;
|
---|
239 | pconfig->tv_mode2 = tv_mode2;
|
---|
240 | pconfig->tv_system = tv_system;
|
---|
241 | }
|
---|
242 |
|
---|
243 | // set subtitle stream id
|
---|
244 | void ddvd_set_spu(struct ddvd *pconfig, int spu_id)
|
---|
245 | {
|
---|
246 | ddvd_send_key(pconfig, DDVD_SET_SUBTITLE);
|
---|
247 | ddvd_send_key(pconfig, spu_id);
|
---|
248 | }
|
---|
249 |
|
---|
250 | // set audio stream id
|
---|
251 | void ddvd_set_audio(struct ddvd *pconfig, int audio_id)
|
---|
252 | {
|
---|
253 | ddvd_send_key(pconfig, DDVD_SET_AUDIO);
|
---|
254 | ddvd_send_key(pconfig, audio_id);
|
---|
255 | }
|
---|
256 |
|
---|
257 | // set video options
|
---|
258 | void ddvd_set_video(struct ddvd *pconfig, int aspect, int tv_mode, int tv_system)
|
---|
259 | {
|
---|
260 | ddvd_set_video_ex(pconfig, aspect, tv_mode, tv_mode, tv_system);
|
---|
261 | }
|
---|
262 |
|
---|
263 | // send commands/keys to the main player
|
---|
264 | void ddvd_send_key(struct ddvd *pconfig, int key)
|
---|
265 | {
|
---|
266 | safe_write(pconfig->key_pipe[1], &key, sizeof(int));
|
---|
267 | }
|
---|
268 |
|
---|
269 | // skip n seconds in playing n>0 forward - n<0 backward
|
---|
270 | void ddvd_skip_seconds(struct ddvd *pconfig, int seconds)
|
---|
271 | {
|
---|
272 | if (seconds < 0)
|
---|
273 | ddvd_send_key(pconfig, DDVD_SKIP_BWD);
|
---|
274 | else
|
---|
275 | ddvd_send_key(pconfig, DDVD_SKIP_FWD);
|
---|
276 |
|
---|
277 | ddvd_send_key(pconfig, seconds);
|
---|
278 | }
|
---|
279 |
|
---|
280 | // jump to beginning of given title
|
---|
281 | void ddvd_set_title(struct ddvd *pconfig, int title)
|
---|
282 | {
|
---|
283 | ddvd_send_key(pconfig, DDVD_SET_TITLE);
|
---|
284 | ddvd_send_key(pconfig, title);
|
---|
285 | }
|
---|
286 |
|
---|
287 | // jump to beginning of given chapter
|
---|
288 | void ddvd_set_chapter(struct ddvd *pconfig, int chapter)
|
---|
289 | {
|
---|
290 | ddvd_send_key(pconfig, DDVD_SET_CHAPTER);
|
---|
291 | ddvd_send_key(pconfig, chapter);
|
---|
292 | }
|
---|
293 |
|
---|
294 | // get and process the next message from the main player
|
---|
295 | int ddvd_get_next_message(struct ddvd *pconfig, int blocked)
|
---|
296 | {
|
---|
297 | int res;
|
---|
298 | int i;
|
---|
299 |
|
---|
300 | if (ddvd_readpipe(pconfig->message_pipe[0], &res, sizeof(int), blocked) != sizeof(int))
|
---|
301 | res = DDVD_NULL;
|
---|
302 |
|
---|
303 | switch (res) // more data to process ?
|
---|
304 | {
|
---|
305 | case DDVD_COLORTABLE_UPDATE:
|
---|
306 | for (i = 0; i < 4; i++)
|
---|
307 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_col[i], sizeof(struct ddvd_color), 1);
|
---|
308 | break;
|
---|
309 | case DDVD_SHOWOSD_TIME:
|
---|
310 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_time, sizeof(pconfig->last_time), 1);
|
---|
311 | break;
|
---|
312 | case DDVD_SHOWOSD_STATE_FFWD:
|
---|
313 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_trickspeed, sizeof(pconfig->last_trickspeed), 1);
|
---|
314 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_time, sizeof(pconfig->last_time), 1);
|
---|
315 | break;
|
---|
316 | case DDVD_SHOWOSD_STATE_FBWD:
|
---|
317 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_trickspeed, sizeof(pconfig->last_trickspeed), 1);
|
---|
318 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_time, sizeof(pconfig->last_time), 1);
|
---|
319 | break;
|
---|
320 | case DDVD_SHOWOSD_STRING:
|
---|
321 | ddvd_readpipe(pconfig->message_pipe[0], pconfig->last_string, sizeof(pconfig->last_string), 1);
|
---|
322 | break;
|
---|
323 | case DDVD_SHOWOSD_AUDIO:
|
---|
324 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_audio_id, sizeof(int), 1);
|
---|
325 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_audio_lang, sizeof(uint16_t), 1);
|
---|
326 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_audio_type, sizeof(int), 1);
|
---|
327 | break;
|
---|
328 | case DDVD_SHOWOSD_SUBTITLE:
|
---|
329 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_spu_id, sizeof(int), 1);
|
---|
330 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_spu_lang, sizeof(uint16_t), 1);
|
---|
331 | break;
|
---|
332 | case DDVD_SCREEN_UPDATE:
|
---|
333 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->blit_area, sizeof(pconfig->blit_area), 1);
|
---|
334 | break;
|
---|
335 | case DDVD_SHOWOSD_ANGLE:
|
---|
336 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->angle_current, sizeof(int), 1);
|
---|
337 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->angle_num, sizeof(int), 1);
|
---|
338 | break;
|
---|
339 | case DDVD_SIZE_CHANGED:
|
---|
340 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_size, sizeof(struct ddvd_size_evt), 1);
|
---|
341 | break;
|
---|
342 | case DDVD_PROGRESSIVE_CHANGED:
|
---|
343 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_progressive, sizeof(struct ddvd_progressive_evt), 1);
|
---|
344 | break;
|
---|
345 | case DDVD_FRAMERATE_CHANGED:
|
---|
346 | ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_framerate, sizeof(struct ddvd_framerate_evt), 1);
|
---|
347 | break;
|
---|
348 | default:
|
---|
349 | break;
|
---|
350 | }
|
---|
351 | return res;
|
---|
352 | }
|
---|
353 |
|
---|
354 | // get last blit area
|
---|
355 | void ddvd_get_last_blit_area(struct ddvd *pconfig, int *x_start, int *x_end, int *y_start, int *y_end)
|
---|
356 | {
|
---|
357 | struct ddvd_resize_return *ptr = &pconfig->blit_area;
|
---|
358 | memcpy(x_start, &ptr->x_start, sizeof(int));
|
---|
359 | memcpy(x_end, &ptr->x_end, sizeof(int));
|
---|
360 | memcpy(y_start, &ptr->y_start, sizeof(int));
|
---|
361 | memcpy(y_end, &ptr->y_end, sizeof(int));
|
---|
362 | }
|
---|
363 |
|
---|
364 | /*void ddvd_get_blit_destination(struct ddvd *pconfig, int *x_offset, int *y_offset, int *width, int *height)
|
---|
365 | {
|
---|
366 | struct ddvd_resize_return *ptr = &pconfig->blit_area;
|
---|
367 |
|
---|
368 | *x_offset = ptr->x_offset;
|
---|
369 | *y_offset = ptr->y_offset;
|
---|
370 | *width = ptr->width;
|
---|
371 | *height = ptr->height;
|
---|
372 | }*/
|
---|
373 |
|
---|
374 | // get angle info
|
---|
375 | void ddvd_get_angle_info(struct ddvd*pconfig, int *current, int *num)
|
---|
376 | {
|
---|
377 | memcpy(current, &pconfig->angle_current, sizeof(pconfig->angle_current));
|
---|
378 | memcpy(num, &pconfig->angle_num, sizeof(pconfig->angle_num));
|
---|
379 | }
|
---|
380 |
|
---|
381 | // get last colortable for 8bit mode (4 colors)
|
---|
382 | void ddvd_get_last_colortable(struct ddvd *pconfig, void *colortable)
|
---|
383 | {
|
---|
384 | memcpy(colortable, pconfig->last_col, sizeof(pconfig->last_col));
|
---|
385 | }
|
---|
386 |
|
---|
387 | // get last received playing time as struct ddvd_time
|
---|
388 | void ddvd_get_last_time(struct ddvd *pconfig, void *timestamp)
|
---|
389 | {
|
---|
390 | memcpy(timestamp, &pconfig->last_time, sizeof(pconfig->last_time));
|
---|
391 | }
|
---|
392 |
|
---|
393 | // get the actual trickspeed (2-64x) when in trickmode
|
---|
394 | void ddvd_get_last_trickspeed(struct ddvd *pconfig, void *trickspeed)
|
---|
395 | {
|
---|
396 | memcpy(trickspeed, &pconfig->last_trickspeed, sizeof(pconfig->last_trickspeed));
|
---|
397 | }
|
---|
398 |
|
---|
399 | // get last text message from player
|
---|
400 | void ddvd_get_last_string(struct ddvd *pconfig, void *text)
|
---|
401 | {
|
---|
402 | memcpy(text, pconfig->last_string, sizeof(pconfig->last_string));
|
---|
403 | }
|
---|
404 |
|
---|
405 | // get the number of available audio tracks
|
---|
406 | void ddvd_get_audio_count(struct ddvd *pconfig, void *count)
|
---|
407 | {
|
---|
408 | int c = 0;
|
---|
409 | int i;
|
---|
410 | for ( i = 0; i < MAX_AUDIO; i++)
|
---|
411 | {
|
---|
412 | if ( pconfig->audio_format[i] != -1 )
|
---|
413 | c++;
|
---|
414 | }
|
---|
415 | memcpy(count, &c, sizeof(int));
|
---|
416 | }
|
---|
417 |
|
---|
418 | // get the active audio track
|
---|
419 | void ddvd_get_last_audio(struct ddvd *pconfig, void *id, void *lang, void *type)
|
---|
420 | {
|
---|
421 | memcpy(id, &pconfig->last_audio_id, sizeof(pconfig->last_audio_id));
|
---|
422 | memcpy(lang, &pconfig->last_audio_lang, sizeof(pconfig->last_audio_lang));
|
---|
423 | memcpy(type, &pconfig->last_audio_type, sizeof(pconfig->last_audio_type));
|
---|
424 | }
|
---|
425 |
|
---|
426 | // get audio track details for given audio track id
|
---|
427 | void ddvd_get_audio_byid(struct ddvd *pconfig, int audio_id, void *lang, void *type)
|
---|
428 | {
|
---|
429 | int audio_id_logical;
|
---|
430 | uint16_t audio_lang = 0xFFFF;
|
---|
431 | audio_id_logical = dvdnav_get_audio_logical_stream(dvdnav, audio_id);
|
---|
432 | audio_lang = dvdnav_audio_stream_to_lang(dvdnav, audio_id_logical);
|
---|
433 | if (audio_lang == 0xFFFF)
|
---|
434 | audio_lang = 0x2D2D;
|
---|
435 | memcpy(lang, &audio_lang, sizeof(uint16_t));
|
---|
436 | memcpy(type, &pconfig->audio_format[audio_id], sizeof(int));
|
---|
437 | }
|
---|
438 |
|
---|
439 | // get the active SPU track
|
---|
440 | void ddvd_get_last_spu(struct ddvd *pconfig, void *id, void *lang)
|
---|
441 | {
|
---|
442 | memcpy(id, &pconfig->last_spu_id, sizeof(pconfig->last_spu_id));
|
---|
443 | memcpy(lang, &pconfig->last_spu_lang, sizeof(pconfig->last_spu_lang));
|
---|
444 | }
|
---|
445 |
|
---|
446 | // get the number of available subtitle tracks
|
---|
447 | void ddvd_get_spu_count(struct ddvd *pconfig, void *count)
|
---|
448 | {
|
---|
449 | int c = 0;
|
---|
450 | int i;
|
---|
451 | for ( i = 0; i < MAX_SPU; i++)
|
---|
452 | {
|
---|
453 | if ( pconfig->spu_map[i] != -1 )
|
---|
454 | c++;
|
---|
455 | }
|
---|
456 | memcpy(count, &c, sizeof(int));
|
---|
457 | }
|
---|
458 |
|
---|
459 | // get audio track details for given subtitle track id
|
---|
460 | void ddvd_get_spu_byid(struct ddvd *pconfig, int spu_id, void *lang)
|
---|
461 | {
|
---|
462 | uint16_t spu_lang = 0xFFFF;
|
---|
463 | if (spu_id < MAX_SPU & pconfig->spu_map[spu_id] > -1)
|
---|
464 | spu_lang = dvdnav_spu_stream_to_lang(dvdnav, pconfig->spu_map[spu_id]);
|
---|
465 | memcpy(lang, &spu_lang, sizeof(uint16_t));
|
---|
466 | }
|
---|
467 |
|
---|
468 | // get dvd title string
|
---|
469 | void ddvd_get_title_string(struct ddvd *pconfig, char *title_string)
|
---|
470 | {
|
---|
471 | memcpy(title_string, pconfig->title_string, sizeof(pconfig->title_string));
|
---|
472 | }
|
---|
473 |
|
---|
474 | // get actual position for resuming
|
---|
475 | void ddvd_get_resume_pos(struct ddvd *pconfig, struct ddvd_resume *resume_info)
|
---|
476 | {
|
---|
477 | memcpy(&resume_info->title, &pconfig->resume_title, sizeof(pconfig->resume_title));
|
---|
478 | memcpy(&resume_info->chapter, &pconfig->resume_chapter, sizeof(pconfig->resume_chapter));
|
---|
479 | memcpy(&resume_info->block, &pconfig->resume_block, sizeof(pconfig->resume_block));
|
---|
480 | memcpy(&resume_info->audio_id, &pconfig->resume_audio_id, sizeof(pconfig->resume_audio_id));
|
---|
481 | memcpy(&resume_info->audio_lock, &pconfig->resume_audio_lock, sizeof(pconfig->resume_audio_lock));
|
---|
482 | memcpy(&resume_info->spu_id, &pconfig->resume_spu_id, sizeof(pconfig->resume_spu_id));
|
---|
483 | memcpy(&resume_info->spu_lock, &pconfig->resume_spu_lock, sizeof(pconfig->resume_spu_lock));
|
---|
484 | }
|
---|
485 |
|
---|
486 | void ddvd_get_last_size(struct ddvd *pconfig, int *width, int *height, int *aspect)
|
---|
487 | {
|
---|
488 | *width = pconfig->last_size.width;
|
---|
489 | *height = pconfig->last_size.height;
|
---|
490 | *aspect = pconfig->last_size.aspect;
|
---|
491 | }
|
---|
492 |
|
---|
493 | void ddvd_get_last_progressive(struct ddvd *pconfig, int *progressive)
|
---|
494 | {
|
---|
495 | *progressive = pconfig->last_progressive.progressive;
|
---|
496 | }
|
---|
497 |
|
---|
498 | void ddvd_get_last_framerate(struct ddvd *pconfig, int *framerate)
|
---|
499 | {
|
---|
500 | *framerate = pconfig->last_framerate.framerate;
|
---|
501 | }
|
---|
502 |
|
---|
503 | struct ddvd_spu_return merge(struct ddvd_spu_return a, struct ddvd_spu_return b)
|
---|
504 | {
|
---|
505 | struct ddvd_spu_return r;
|
---|
506 | r = b;
|
---|
507 |
|
---|
508 | if (a.x_start != a.x_end || a.y_start != a.y_end)
|
---|
509 | {
|
---|
510 | /* union old and new area */
|
---|
511 | if (a.x_start < r.x_start)
|
---|
512 | r.x_start = a.x_start;
|
---|
513 | if (a.y_start < r.y_start)
|
---|
514 | r.y_start = a.y_start;
|
---|
515 | if (a.x_end > r.x_end)
|
---|
516 | r.x_end = a.x_end;
|
---|
517 | if (a.y_end > r.y_end)
|
---|
518 | r.y_end = a.y_end;
|
---|
519 | }
|
---|
520 | return r;
|
---|
521 | }
|
---|
522 |
|
---|
523 | //needed for titan
|
---|
524 | #if defined(__sh__)
|
---|
525 | int ddvd_get_dvd_aspect(struct ddvd *playerconfig)
|
---|
526 | {
|
---|
527 | if(playerconfig != NULL)
|
---|
528 | return playerconfig->dvd_aspect;
|
---|
529 | else
|
---|
530 | return -1;
|
---|
531 | }
|
---|
532 | #endif
|
---|
533 |
|
---|
534 | static int calc_x_scale_offset(int dvd_aspect, int tv_mode, int tv_mode2, int tv_aspect)
|
---|
535 | {
|
---|
536 | int x_offset=0;
|
---|
537 |
|
---|
538 | if (dvd_aspect == 0 && tv_mode == DDVD_PAN_SCAN) {
|
---|
539 | switch (tv_aspect) {
|
---|
540 | case DDVD_16_10:
|
---|
541 | x_offset = (ddvd_screeninfo_xres - ddvd_screeninfo_xres * 12 / 15) / 2; // correct 16:10 (broadcom 15:9) panscan (pillarbox) overlay
|
---|
542 | break;
|
---|
543 | case DDVD_16_9:
|
---|
544 | x_offset = (ddvd_screeninfo_xres - ddvd_screeninfo_xres * 3 / 4) / 2; // correct 16:9 panscan (pillarbox) overlay
|
---|
545 | default:
|
---|
546 | break;
|
---|
547 | }
|
---|
548 | }
|
---|
549 |
|
---|
550 | if (dvd_aspect >= 2 && tv_aspect == DDVD_4_3 && tv_mode == DDVD_PAN_SCAN)
|
---|
551 | x_offset = -(ddvd_screeninfo_xres * 4 / 3 - ddvd_screeninfo_xres) / 2;
|
---|
552 |
|
---|
553 | if (dvd_aspect >= 2 && tv_aspect == DDVD_16_10 && tv_mode2 == DDVD_PAN_SCAN)
|
---|
554 | x_offset = -(ddvd_screeninfo_xres * 16 / 15 - ddvd_screeninfo_xres) / 2;
|
---|
555 |
|
---|
556 | return x_offset;
|
---|
557 | }
|
---|
558 |
|
---|
559 | static int calc_y_scale_offset(int dvd_aspect, int tv_mode, int tv_mode2, int tv_aspect)
|
---|
560 | {
|
---|
561 | int y_offset = 0;
|
---|
562 |
|
---|
563 | if (dvd_aspect == 0 && tv_mode == DDVD_LETTERBOX) {
|
---|
564 | switch (tv_aspect) {
|
---|
565 | case DDVD_16_10:
|
---|
566 | y_offset = (ddvd_screeninfo_yres * 15 / 12 - ddvd_screeninfo_yres) / 2; // correct 16:10 (broacom 15:9) letterbox overlay
|
---|
567 | break;
|
---|
568 | case DDVD_16_9:
|
---|
569 | y_offset = (ddvd_screeninfo_yres * 4 / 3 - ddvd_screeninfo_yres) / 2; // correct 16:9 letterbox overlay
|
---|
570 | default:
|
---|
571 | break;
|
---|
572 | }
|
---|
573 | }
|
---|
574 |
|
---|
575 | if (dvd_aspect >= 2 && tv_aspect == DDVD_4_3 && tv_mode == DDVD_LETTERBOX)
|
---|
576 | y_offset = -(ddvd_screeninfo_yres - ddvd_screeninfo_yres * 3 / 4) / 2;
|
---|
577 |
|
---|
578 | if (dvd_aspect >= 2 && tv_aspect == DDVD_16_10 && tv_mode2 == DDVD_LETTERBOX)
|
---|
579 | y_offset = -(ddvd_screeninfo_yres - ddvd_screeninfo_yres * 15 / 16) / 2;
|
---|
580 |
|
---|
581 | return y_offset;
|
---|
582 | }
|
---|
583 |
|
---|
584 | #if CONFIG_API_VERSION >= 3
|
---|
585 | static int readMpegProc(char *str, int decoder)
|
---|
586 | {
|
---|
587 | int val = -1;
|
---|
588 | char tmp[64];
|
---|
589 | sprintf(tmp, "/proc/stb/vmpeg/%d/%s", decoder, str);
|
---|
590 | FILE *f = fopen(tmp, "r");
|
---|
591 | if (f)
|
---|
592 | {
|
---|
593 | fscanf(f, "%x", &val);
|
---|
594 | fclose(f);
|
---|
595 | }
|
---|
596 | return val;
|
---|
597 | }
|
---|
598 |
|
---|
599 | static int readApiSize(int fd, int *xres, int *yres, int *aspect)
|
---|
600 | {
|
---|
601 | video_size_t size;
|
---|
602 | if (!ioctl(fd, VIDEO_GET_SIZE, &size))
|
---|
603 | {
|
---|
604 | *xres = size.w;
|
---|
605 | *yres = size.h;
|
---|
606 | *aspect = size.aspect_ratio == 0 ? 2 : 3; // convert dvb api to etsi
|
---|
607 | return 0;
|
---|
608 | }
|
---|
609 | return -1;
|
---|
610 | }
|
---|
611 |
|
---|
612 | static int readApiFrameRate(int fd, int *framerate)
|
---|
613 | {
|
---|
614 | unsigned int frate;
|
---|
615 | if (!ioctl(fd, VIDEO_GET_FRAME_RATE, &frate))
|
---|
616 | {
|
---|
617 | *framerate = frate;
|
---|
618 | return 0;
|
---|
619 | }
|
---|
620 | return -1;
|
---|
621 | }
|
---|
622 | #endif
|
---|
623 |
|
---|
624 | // the main player loop
|
---|
625 | enum ddvd_result ddvd_run(struct ddvd *playerconfig)
|
---|
626 | {
|
---|
627 | if (playerconfig->lfb == NULL) {
|
---|
628 | printf("Frame/backbuffer not given to libdreamdvd. Will not start the player !\n");
|
---|
629 | return DDVD_INVAL;
|
---|
630 | }
|
---|
631 |
|
---|
632 | // we need to know the first vts_change and the next cell change for resuming a dvd
|
---|
633 | int first_vts_change = 1;
|
---|
634 | int next_cell_change = 0;
|
---|
635 | int ddvd_have_ntsc = -1;
|
---|
636 |
|
---|
637 | ddvd_screeninfo_xres = playerconfig->xres;
|
---|
638 | ddvd_screeninfo_yres = playerconfig->yres;
|
---|
639 | ddvd_screeninfo_stride = playerconfig->stride;
|
---|
640 | int ddvd_screeninfo_bypp = playerconfig->bypp;
|
---|
641 | int message_pipe = playerconfig->message_pipe[1];
|
---|
642 | int key_pipe = playerconfig->key_pipe[0];
|
---|
643 | unsigned char *p_lfb = playerconfig->lfb;
|
---|
644 | enum ddvd_result res = DDVD_OK;
|
---|
645 | int msg;
|
---|
646 | // try to load liba52.so.0 for softdecoding
|
---|
647 | #if defined(__sh__)
|
---|
648 | #else
|
---|
649 | int have_liba52 = ddvd_load_liba52();
|
---|
650 | #endif
|
---|
651 |
|
---|
652 | // decide which resize routine we should use
|
---|
653 | // on 4bpp mode we use bicubic resize for sd skins because we get much better results with subtitles and the speed is ok
|
---|
654 | // for hd skins we use nearest neighbor resize because upscaling to hd is too slow with bicubic resize
|
---|
655 | if (ddvd_screeninfo_bypp == 1)
|
---|
656 | ddvd_resize_pixmap = ddvd_resize_pixmap_spu = &ddvd_resize_pixmap_1bpp;
|
---|
657 | else if (ddvd_screeninfo_xres > 720)
|
---|
658 | ddvd_resize_pixmap = ddvd_resize_pixmap_spu = &ddvd_resize_pixmap_xbpp;
|
---|
659 | else
|
---|
660 | {
|
---|
661 | ddvd_resize_pixmap = &ddvd_resize_pixmap_xbpp;
|
---|
662 | ddvd_resize_pixmap_spu = &ddvd_resize_pixmap_xbpp_smooth;
|
---|
663 | }
|
---|
664 |
|
---|
665 | uint8_t *last_iframe = NULL;
|
---|
666 | uint8_t *spu_buffer = NULL;
|
---|
667 | uint8_t *spu_backbuffer = NULL;
|
---|
668 |
|
---|
669 | // init backbuffer (SPU)
|
---|
670 | ddvd_lbb = malloc(720 * 576); // the spu backbuffer is always max DVD PAL 720x576 pixel (NTSC 720x480)
|
---|
671 | if (ddvd_lbb == NULL) {
|
---|
672 | perror("SPU-Backbuffer <mem allocation failed>");
|
---|
673 | res = DDVD_NOMEM;
|
---|
674 | goto err_malloc;
|
---|
675 | }
|
---|
676 | ddvd_lbb2 = malloc(ddvd_screeninfo_xres * ddvd_screeninfo_yres * ddvd_screeninfo_bypp);
|
---|
677 | if (ddvd_lbb2 == NULL) {
|
---|
678 | perror("SPU-Backbuffer <mem allocation failed>");
|
---|
679 | res = DDVD_NOMEM;
|
---|
680 | goto err_malloc;
|
---|
681 | }
|
---|
682 |
|
---|
683 | last_iframe = malloc(320 * 1024);
|
---|
684 | if (last_iframe == NULL) {
|
---|
685 | perror("malloc");
|
---|
686 | res = DDVD_NOMEM;
|
---|
687 | goto err_malloc;
|
---|
688 | }
|
---|
689 |
|
---|
690 | spu_buffer = malloc(2 * (128 * 1024));
|
---|
691 | if (spu_buffer == NULL) {
|
---|
692 | perror("malloc");
|
---|
693 | res = DDVD_NOMEM;
|
---|
694 | goto err_malloc;
|
---|
695 | }
|
---|
696 |
|
---|
697 | spu_backbuffer = malloc(NUM_SPU_BACKBUFFER * 2 * (128 * 1024));
|
---|
698 | if (spu_backbuffer == NULL) {
|
---|
699 | perror("malloc");
|
---|
700 | res = DDVD_NOMEM;
|
---|
701 | goto err_malloc;
|
---|
702 | }
|
---|
703 |
|
---|
704 | struct ddvd_resize_return blit_area;
|
---|
705 |
|
---|
706 | memset(ddvd_lbb, 0, 720 * 576);
|
---|
707 | memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres); //clear screen
|
---|
708 | blit_area.x_start = blit_area.y_start = 0;
|
---|
709 | blit_area.x_end = ddvd_screeninfo_xres - 1;
|
---|
710 | blit_area.y_end = ddvd_screeninfo_yres - 1;
|
---|
711 | blit_area.x_offset = 0;
|
---|
712 | blit_area.y_offset = 0;
|
---|
713 | blit_area.width = ddvd_screeninfo_xres;
|
---|
714 | blit_area.height = ddvd_screeninfo_yres;
|
---|
715 |
|
---|
716 | msg = DDVD_SCREEN_UPDATE;
|
---|
717 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
718 | safe_write(message_pipe, &blit_area, sizeof(struct ddvd_resize_return));
|
---|
719 |
|
---|
720 | printf("Opening output...\n");
|
---|
721 |
|
---|
722 | #if CONFIG_API_VERSION == 1
|
---|
723 | ddvd_output_fd = open("/dev/video", O_WRONLY);
|
---|
724 | if (ddvd_output_fd == -1) {
|
---|
725 | perror("/dev/video");
|
---|
726 | res = DDVD_BUSY;
|
---|
727 | goto err_open_output_fd;
|
---|
728 | }
|
---|
729 |
|
---|
730 | ddvd_fdvideo = open("/dev/dvb/card0/video0", O_RDWR);
|
---|
731 | if (ddvd_fdvideo == -1) {
|
---|
732 | perror("/dev/dvb/card0/video0");
|
---|
733 | res = DDVD_BUSY;
|
---|
734 | goto err_open_fdvideo;
|
---|
735 | }
|
---|
736 |
|
---|
737 | ddvd_fdaudio = open("/dev/dvb/card0/audio0", O_RDWR);
|
---|
738 | if (ddvd_fdaudio == -1) {
|
---|
739 | perror("/dev/dvb/card0/audio0");
|
---|
740 | res = DDVD_BUSY;
|
---|
741 | goto err_open_fdaudio;
|
---|
742 | }
|
---|
743 |
|
---|
744 | ddvd_ac3_fd = open("/dev/sound/dsp1", O_RDWR);
|
---|
745 | if (ddvd_ac3_fd == -1) {
|
---|
746 | perror("/dev/sound/dsp1");
|
---|
747 | res = DDVD_BUSY;
|
---|
748 | goto err_open_ac3_fd;
|
---|
749 | }
|
---|
750 |
|
---|
751 | if (ioctl(ddvd_fdvideo, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
|
---|
752 | perror("VIDEO_SELECT_SOURCE");
|
---|
753 | if (ioctl(ddvd_fdvideo, VIDEO_CLEAR_BUFFER) < 0)
|
---|
754 | perror("VIDEO_CLEAR_BUFFER");
|
---|
755 | if (ioctl(ddvd_fdvideo, VIDEO_PLAY) < 0)
|
---|
756 | perror("VIDEO_PLAY");
|
---|
757 |
|
---|
758 | if (ioctl(ddvd_fdaudio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) < 0)
|
---|
759 | perror("AUDIO_SELECT_SOURCE");
|
---|
760 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
761 | perror("AUDIO_CLEAR_BUFFER");
|
---|
762 | if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
|
---|
763 | perror("AUDIO_PLAY");
|
---|
764 |
|
---|
765 | #elif CONFIG_API_VERSION == 3
|
---|
766 | ddvd_output_fd = ddvd_fdvideo = open("/dev/dvb/adapter0/video0", O_RDWR);
|
---|
767 | if (ddvd_fdvideo == -1) {
|
---|
768 | perror("/dev/dvb/adapter0/video0");
|
---|
769 | res = DDVD_BUSY;
|
---|
770 | goto err_open_fdvideo;
|
---|
771 | }
|
---|
772 |
|
---|
773 | ddvd_ac3_fd = ddvd_fdaudio = open("/dev/dvb/adapter0/audio0", O_RDWR);
|
---|
774 | if (ddvd_fdaudio == -1) {
|
---|
775 | perror("/dev/dvb/adapter0/audio0");
|
---|
776 | res = DDVD_BUSY;
|
---|
777 | goto err_open_ac3_fd;
|
---|
778 | }
|
---|
779 |
|
---|
780 | if (ioctl(ddvd_fdvideo, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
|
---|
781 | perror("VIDEO_SELECT_SOURCE");
|
---|
782 | if (ioctl(ddvd_fdvideo, VIDEO_CLEAR_BUFFER) < 0)
|
---|
783 | perror("VIDEO_CLEAR_BUFFER");
|
---|
784 | if (ioctl(ddvd_fdvideo, VIDEO_SET_STREAMTYPE, 0) < 0) // set mpeg2
|
---|
785 | perror("VIDEO_SET_STREAMTYPE");
|
---|
786 | if (ioctl(ddvd_fdvideo, VIDEO_PLAY) < 0)
|
---|
787 | perror("VIDEO_PLAY");
|
---|
788 |
|
---|
789 | if (ioctl(ddvd_fdaudio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) < 0)
|
---|
790 | perror("AUDIO_SELECT_SOURCE");
|
---|
791 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
792 | perror("AUDIO_CLEAR_BUFFER");
|
---|
793 | if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
|
---|
794 | perror("AUDIO_PLAY");
|
---|
795 | #else
|
---|
796 | #error please define CONFIG_API_VERSION to be 1 or 3
|
---|
797 | #endif
|
---|
798 |
|
---|
799 | int i;
|
---|
800 | // show startup screen
|
---|
801 | #if SHOW_START_SCREEN == 1
|
---|
802 | #if CONFIG_API_VERSION == 1
|
---|
803 | //that really sucks but there is no other way
|
---|
804 | for (i = 0; i < 10; i++)
|
---|
805 | safe_write(ddvd_output_fd, ddvd_startup_logo, sizeof(ddvd_startup_logo));
|
---|
806 | #else
|
---|
807 | unsigned char pes_header[] = { 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x00, 0x00 };
|
---|
808 | safe_write(ddvd_output_fd, pes_header, sizeof(pes_header));
|
---|
809 | safe_write(ddvd_output_fd, ddvd_startup_logo, sizeof(ddvd_startup_logo));
|
---|
810 | #endif
|
---|
811 | #endif
|
---|
812 |
|
---|
813 | int audio_type = DDVD_UNKNOWN;
|
---|
814 |
|
---|
815 | #if CONFIG_API_VERSION == 3
|
---|
816 | ddvd_set_pcr_offset();
|
---|
817 | #endif
|
---|
818 |
|
---|
819 | uint8_t mem[DVD_VIDEO_LB_LEN];
|
---|
820 | uint8_t *buf = mem;
|
---|
821 | int result, event, len;
|
---|
822 |
|
---|
823 | unsigned char lpcm_data[2048 * 6 * 6 /*4608 */ ];
|
---|
824 | int mpa_header_length;
|
---|
825 | int mpa_count, mpa_count2;
|
---|
826 | uint8_t mpa_data[2048 * 4];
|
---|
827 | int ac3_len;
|
---|
828 | int16_t ac3_tmp[2048 * 6 * 6];
|
---|
829 |
|
---|
830 | ddvd_mpa_init(48000, 192000); //init MPA Encoder with 48kHz and 192k Bitrate
|
---|
831 |
|
---|
832 | int ac3thru = 1;
|
---|
833 | #if defined(__sh__)
|
---|
834 | #else
|
---|
835 | if (have_liba52) {
|
---|
836 | state = a52_init(0); //init AC3 Decoder
|
---|
837 | ac3thru = playerconfig->ac3thru;
|
---|
838 | }
|
---|
839 | #endif
|
---|
840 |
|
---|
841 | char osdtext[512];
|
---|
842 | strcpy(osdtext, "");
|
---|
843 |
|
---|
844 | int tv_aspect = playerconfig->aspect; //0-> 4:3 lb 1-> 4:3 ps 2-> 16:9 3-> always 16:9
|
---|
845 | int tv_mode = playerconfig->tv_mode;
|
---|
846 | int tv_mode2 = playerconfig->tv_mode2; // just used when tv_aspect is 16:10 and dvd_aspect is 16:9
|
---|
847 | int dvd_aspect = 0; //0-> 4:3 2-> 16:9
|
---|
848 | int dvd_scale_perm = 0;
|
---|
849 | int tv_scale = 0; //0-> off 1-> letterbox 2-> panscan
|
---|
850 | int spu_active_id = -1;
|
---|
851 | int finished = 0;
|
---|
852 | int audio_id;
|
---|
853 | int report_audio_info = 0;
|
---|
854 |
|
---|
855 | struct ddvd_spu_return last_spu_return;
|
---|
856 | struct ddvd_resize_return last_blit_area;
|
---|
857 | memcpy(&last_blit_area,&blit_area,sizeof(struct ddvd_resize_return));
|
---|
858 | last_spu_return.x_start = last_spu_return.y_start = 0;
|
---|
859 | last_spu_return.x_end = last_spu_return.y_end = 0;
|
---|
860 |
|
---|
861 | ddvd_trickmode = TOFF;
|
---|
862 | ddvd_trickspeed = 0;
|
---|
863 |
|
---|
864 | int rccode;
|
---|
865 | int ismute = 0;
|
---|
866 |
|
---|
867 | if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
|
---|
868 | perror("AUDIO_SET_AV_SYNC");
|
---|
869 | #if CONFIG_API_VERSION == 1
|
---|
870 | // set video system
|
---|
871 | int pal_ntsc = playerconfig->tv_system;
|
---|
872 | int saa;
|
---|
873 | if (pal_ntsc == 1)
|
---|
874 | saa = SAA_NTSC;
|
---|
875 | else
|
---|
876 | saa = SAA_PAL;
|
---|
877 | int saafd = open("/dev/dbox/saa0", O_RDWR);
|
---|
878 | if (saafd >= 0) {
|
---|
879 | if (ioctl(saafd, SAAIOSENC, &saa) < 0)
|
---|
880 | perror("SAAIOSENC");
|
---|
881 | close(saafd);
|
---|
882 | }
|
---|
883 | #else
|
---|
884 | {
|
---|
885 | struct ddvd_size_evt evt;
|
---|
886 | int msg = DDVD_SIZE_CHANGED;
|
---|
887 | readApiSize(ddvd_fdvideo, &evt.width, &evt.height, &evt.aspect);
|
---|
888 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
889 | safe_write(message_pipe, &evt, sizeof(evt));
|
---|
890 | }
|
---|
891 | {
|
---|
892 | struct ddvd_framerate_evt evt;
|
---|
893 | int msg = DDVD_FRAMERATE_CHANGED;
|
---|
894 | readApiFrameRate(ddvd_fdvideo, &evt.framerate);
|
---|
895 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
896 | safe_write(message_pipe, &evt, sizeof(evt));
|
---|
897 | }
|
---|
898 | {
|
---|
899 | struct ddvd_progressive_evt evt;
|
---|
900 | int msg = DDVD_PROGRESSIVE_CHANGED;
|
---|
901 | evt.progressive = readMpegProc("progressive", 0);
|
---|
902 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
903 | safe_write(message_pipe, &evt, sizeof(evt));
|
---|
904 | }
|
---|
905 | #endif
|
---|
906 |
|
---|
907 | /* open dvdnav handle */
|
---|
908 | printf("Opening DVD...%s\n", playerconfig->dvd_path);
|
---|
909 | if (dvdnav_open(&dvdnav, playerconfig->dvd_path) != DVDNAV_STATUS_OK) {
|
---|
910 | printf("Error on dvdnav_open\n");
|
---|
911 | sprintf(osdtext, "Error: Cant open DVD Source: %s", playerconfig->dvd_path);
|
---|
912 | msg = DDVD_SHOWOSD_STRING;
|
---|
913 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
914 | safe_write(message_pipe, &osdtext, sizeof(osdtext));
|
---|
915 | res = DDVD_FAIL_OPEN;
|
---|
916 | goto err_dvdnav_open;
|
---|
917 | }
|
---|
918 |
|
---|
919 | // nit: dekativate cache, does not work with all dvd
|
---|
920 | // on some dvd menu is not allays displayed
|
---|
921 | //#if defined(__sh__)
|
---|
922 | /* set read ahead cache usage to yes for ufs910 */
|
---|
923 | // if (dvdnav_set_readahead_flag(dvdnav, 1) != DVDNAV_STATUS_OK) {
|
---|
924 | //#else
|
---|
925 | /* set read ahead cache usage to no */
|
---|
926 | if (dvdnav_set_readahead_flag(dvdnav, 0) != DVDNAV_STATUS_OK) {
|
---|
927 | //#endif
|
---|
928 | printf("Error on dvdnav_set_readahead_flag: %s\n", dvdnav_err_to_string(dvdnav));
|
---|
929 | res = DDVD_FAIL_PREFS;
|
---|
930 | goto err_dvdnav;
|
---|
931 | }
|
---|
932 |
|
---|
933 | /* set the language */
|
---|
934 | if (dvdnav_menu_language_select(dvdnav, playerconfig->language) != DVDNAV_STATUS_OK ||
|
---|
935 | dvdnav_audio_language_select(dvdnav, playerconfig->language) != DVDNAV_STATUS_OK ||
|
---|
936 | dvdnav_spu_language_select(dvdnav, playerconfig->language) != DVDNAV_STATUS_OK) {
|
---|
937 | printf("Error on setting languages: %s\n", dvdnav_err_to_string(dvdnav));
|
---|
938 | res = DDVD_FAIL_PREFS;
|
---|
939 | goto err_dvdnav;
|
---|
940 | }
|
---|
941 |
|
---|
942 | /* set the PGC positioning flag to have position information relatively to the
|
---|
943 | * whole feature instead of just relatively to the current chapter */
|
---|
944 | if (dvdnav_set_PGC_positioning_flag(dvdnav, 1) != DVDNAV_STATUS_OK) {
|
---|
945 | printf("Error on dvdnav_set_PGC_positioning_flag: %s\n", dvdnav_err_to_string(dvdnav));
|
---|
946 | res = DDVD_FAIL_PREFS;
|
---|
947 | goto err_dvdnav;
|
---|
948 | }
|
---|
949 |
|
---|
950 | int audio_lock = 0;
|
---|
951 | int spu_lock = 0;
|
---|
952 | for (i=0; i < MAX_AUDIO; i++)
|
---|
953 | playerconfig->audio_format[i] = -1;
|
---|
954 |
|
---|
955 | for (i=0; i < MAX_SPU; i++)
|
---|
956 | playerconfig->spu_map[i] = -1;
|
---|
957 |
|
---|
958 | unsigned long long vpts, apts, spts, pts;
|
---|
959 |
|
---|
960 | audio_id = dvdnav_get_active_audio_stream(dvdnav);
|
---|
961 | ddvd_playmode = PLAY;
|
---|
962 |
|
---|
963 | ddvd_lbb_changed = 0;
|
---|
964 |
|
---|
965 | unsigned long long spu_backpts[NUM_SPU_BACKBUFFER];
|
---|
966 |
|
---|
967 | ddvd_play_empty(FALSE);
|
---|
968 | ddvd_get_time(); //set timestamp
|
---|
969 |
|
---|
970 | playerconfig->in_menu = 0;
|
---|
971 |
|
---|
972 | const char *dvd_titlestring;
|
---|
973 | if (dvdnav_get_title_string(dvdnav, &dvd_titlestring) == DVDNAV_STATUS_OK)
|
---|
974 | strcpy(playerconfig->title_string, dvd_titlestring);
|
---|
975 |
|
---|
976 | msg = DDVD_SHOWOSD_TITLESTRING;
|
---|
977 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
978 |
|
---|
979 | /* the read loop which regularly calls dvdnav_get_next_block
|
---|
980 | * and handles the returned events */
|
---|
981 | int reached_eof = 0;
|
---|
982 | int reached_sof = 0;
|
---|
983 |
|
---|
984 | while (!finished) {
|
---|
985 | pci_t *pci = 0;
|
---|
986 | dsi_t *dsi = 0;
|
---|
987 | int buttonN = -1;
|
---|
988 | int in_menu = 0;
|
---|
989 |
|
---|
990 | /* the main reading function */
|
---|
991 | if (ddvd_playmode == PLAY) { //skip when not in play mode
|
---|
992 | // trickmode
|
---|
993 | if (ddvd_trickmode) {
|
---|
994 | if (ddvd_trick_timer_end <= ddvd_get_time()) {
|
---|
995 | if (ddvd_trickmode == FASTBW) { //jump back ?
|
---|
996 | uint32_t pos, len;
|
---|
997 | dvdnav_get_position(dvdnav, &pos, &len);
|
---|
998 | //90000 = 1 Sek. -> 45000 = 0.5 Sek. -> Speed Faktor=2
|
---|
999 | int64_t posneu = ((pos * ddvd_lastCellEventInfo.pgc_length) / len) - (45000 * 2 * ddvd_trickspeed);
|
---|
1000 | int64_t posneu2 = posneu <= 0 ? 0 : (posneu * len) / ddvd_lastCellEventInfo.pgc_length;
|
---|
1001 | dvdnav_sector_search(dvdnav, posneu2, SEEK_SET);
|
---|
1002 | if (posneu < 0) { // reached begin of movie
|
---|
1003 | reached_sof = 1;
|
---|
1004 | msg = DDVD_SHOWOSD_TIME;
|
---|
1005 | } else {
|
---|
1006 | msg = DDVD_SHOWOSD_STATE_FBWD;
|
---|
1007 | }
|
---|
1008 | } else if (ddvd_trickmode == FASTFW) { //jump forward ?
|
---|
1009 | uint32_t pos, len;
|
---|
1010 | dvdnav_get_position(dvdnav, &pos, &len);
|
---|
1011 | //90000 = 1 Sek. -> 22500 = 0.25 Sek. -> Speed Faktor=2
|
---|
1012 | int64_t posneu = ((pos * ddvd_lastCellEventInfo.pgc_length) / len) + (22500 * 2 * ddvd_trickspeed);
|
---|
1013 | int64_t posneu2 = (posneu * len) / ddvd_lastCellEventInfo.pgc_length;
|
---|
1014 | if (posneu2 && len && posneu2 >= len) { // reached end of movie
|
---|
1015 | posneu2 = len - 250;
|
---|
1016 | reached_eof = 1;
|
---|
1017 | msg = DDVD_SHOWOSD_TIME;
|
---|
1018 | } else {
|
---|
1019 | msg = DDVD_SHOWOSD_STATE_FFWD;
|
---|
1020 | }
|
---|
1021 | dvdnav_sector_search(dvdnav, posneu2, SEEK_SET);
|
---|
1022 | }
|
---|
1023 | ddvd_trick_timer_end = ddvd_get_time() + 300;
|
---|
1024 | ddvd_lpcm_count = 0;
|
---|
1025 | }
|
---|
1026 | }
|
---|
1027 |
|
---|
1028 | // nit: dekativate cache, does not work with all dvd
|
---|
1029 | // on some dvd menu is not allays displayed
|
---|
1030 | //#if defined(__sh__)
|
---|
1031 | // result = dvdnav_get_next_cache_block(dvdnav, &buf, &event, &len);
|
---|
1032 | //#else
|
---|
1033 | result = dvdnav_get_next_block(dvdnav, buf, &event, &len);
|
---|
1034 | //#endif
|
---|
1035 | if (result == DVDNAV_STATUS_ERR) {
|
---|
1036 | printf("Error getting next block: %s\n", dvdnav_err_to_string(dvdnav));
|
---|
1037 | sprintf(osdtext, "Error: Getting next block: %s", dvdnav_err_to_string(dvdnav));
|
---|
1038 | msg = DDVD_SHOWOSD_STRING;
|
---|
1039 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1040 | safe_write(message_pipe, &osdtext, sizeof(osdtext));
|
---|
1041 | res = DDVD_FAIL_READ;
|
---|
1042 | goto err_dvdnav;
|
---|
1043 | }
|
---|
1044 |
|
---|
1045 | send_message:
|
---|
1046 | // send OSD Data
|
---|
1047 | if (msg > 0) {
|
---|
1048 | struct ddvd_time info;
|
---|
1049 | switch (msg) {
|
---|
1050 | case DDVD_SHOWOSD_TIME:
|
---|
1051 | info = ddvd_get_osd_time(playerconfig);
|
---|
1052 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1053 | safe_write(message_pipe, &info, sizeof(struct ddvd_time));
|
---|
1054 | break;
|
---|
1055 | case DDVD_SHOWOSD_STATE_FFWD:
|
---|
1056 | info = ddvd_get_osd_time(playerconfig);
|
---|
1057 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1058 | safe_write(message_pipe, &ddvd_trickspeed, sizeof(int));
|
---|
1059 | safe_write(message_pipe, &info, sizeof(struct ddvd_time));
|
---|
1060 | break;
|
---|
1061 | case DDVD_SHOWOSD_STATE_FBWD:
|
---|
1062 | info = ddvd_get_osd_time(playerconfig);
|
---|
1063 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1064 | safe_write(message_pipe, &ddvd_trickspeed, sizeof(int));
|
---|
1065 | safe_write(message_pipe, &info, sizeof(struct ddvd_time));
|
---|
1066 | break;
|
---|
1067 | default:
|
---|
1068 | break;
|
---|
1069 | }
|
---|
1070 | msg = 0;
|
---|
1071 | }
|
---|
1072 |
|
---|
1073 | if (reached_eof) {
|
---|
1074 | msg = DDVD_EOF_REACHED;
|
---|
1075 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1076 | reached_eof = 0;
|
---|
1077 | }
|
---|
1078 |
|
---|
1079 | if (reached_sof) {
|
---|
1080 | msg = DDVD_SOF_REACHED;
|
---|
1081 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1082 | reached_sof = 0;
|
---|
1083 | }
|
---|
1084 |
|
---|
1085 | if (ddvd_get_time() > playerconfig->next_time_update) {
|
---|
1086 | msg = DDVD_SHOWOSD_TIME;
|
---|
1087 | goto send_message;
|
---|
1088 | }
|
---|
1089 | // send iFrame
|
---|
1090 | if (ddvd_iframesend < 0) {
|
---|
1091 | #if CONFIG_API_VERSION == 1
|
---|
1092 | ddvd_device_clear();
|
---|
1093 | #endif
|
---|
1094 | ddvd_iframesend = 0;
|
---|
1095 | }
|
---|
1096 |
|
---|
1097 | if (ddvd_iframesend > 0) {
|
---|
1098 | #if CONFIG_API_VERSION == 1
|
---|
1099 | ddvd_device_clear();
|
---|
1100 | #endif
|
---|
1101 | if (ddvd_still_frame && ddvd_last_iframe_len) {
|
---|
1102 | #if 0
|
---|
1103 | static int ifnum = 0;
|
---|
1104 | static char ifname[255];
|
---|
1105 | snprintf(ifname, 255, "/tmp/dvd.iframe.%3.3d.asm.pes", ifnum++);
|
---|
1106 | FILE *f = fopen(ifname, "wb");
|
---|
1107 | fwrite(last_iframe, 1, ddvd_last_iframe_len, f);
|
---|
1108 | fclose(f);
|
---|
1109 | #endif
|
---|
1110 |
|
---|
1111 | #if CONFIG_API_VERSION == 1
|
---|
1112 | //that really sucks but there is no other way
|
---|
1113 | int i;
|
---|
1114 | for (i = 0; i < 10; i++)
|
---|
1115 | safe_write(ddvd_output_fd, last_iframe, ddvd_last_iframe_len);
|
---|
1116 | #else
|
---|
1117 | safe_write(ddvd_output_fd, last_iframe, ddvd_last_iframe_len);
|
---|
1118 | #endif
|
---|
1119 | //printf("Show iframe with size: %d\n",ddvd_last_iframe_len);
|
---|
1120 | ddvd_last_iframe_len = 0;
|
---|
1121 | }
|
---|
1122 |
|
---|
1123 | ddvd_iframesend = -1;
|
---|
1124 | }
|
---|
1125 | // wait timer
|
---|
1126 | if (ddvd_wait_timer_active) {
|
---|
1127 | if (ddvd_wait_timer_end <= ddvd_get_time()) {
|
---|
1128 | ddvd_wait_timer_active = 0;
|
---|
1129 | dvdnav_still_skip(dvdnav);
|
---|
1130 | //printf("wait timer done\n");
|
---|
1131 | }
|
---|
1132 | }
|
---|
1133 | // SPU timer
|
---|
1134 | if (ddvd_spu_timer_active) {
|
---|
1135 | if (ddvd_spu_timer_end <= ddvd_get_time()) {
|
---|
1136 | ddvd_spu_timer_active = 0;
|
---|
1137 | /* the last_spu bbox is still filled with the correct value, no need to blit full screen */
|
---|
1138 | /* TODO: only clear part of backbuffer */
|
---|
1139 | memset(ddvd_lbb, 0, 720 * 576); //clear SPU backbuffer
|
---|
1140 | ddvd_lbb_changed = 1;
|
---|
1141 | }
|
---|
1142 | }
|
---|
1143 |
|
---|
1144 | switch (event) {
|
---|
1145 | case DVDNAV_BLOCK_OK:
|
---|
1146 | /* We have received a regular block of the currently playing MPEG stream.
|
---|
1147 | * So we do some demuxing and decoding. */
|
---|
1148 | {
|
---|
1149 |
|
---|
1150 | // collect audio data
|
---|
1151 | int stream_type = buf[14 + buf[14 + 8] + 9];
|
---|
1152 | if (((buf[14 + 3]) & 0xF0) == 0xC0)
|
---|
1153 | playerconfig->audio_format[(buf[14 + 3]) - 0xC0] = DDVD_MPEG;
|
---|
1154 | if ((buf[14 + 3]) == 0xBD && (stream_type & 0xF8) == 0x80)
|
---|
1155 | playerconfig->audio_format[stream_type - 0x80] = DDVD_AC3;
|
---|
1156 | if ((buf[14 + 3]) == 0xBD && (stream_type & 0xF8) == 0x88)
|
---|
1157 | playerconfig->audio_format[stream_type - 0x88] = DDVD_DTS;
|
---|
1158 | if ((buf[14 + 3]) == 0xBD && (stream_type & 0xF8) == 0xA0)
|
---|
1159 | playerconfig->audio_format[stream_type - 0xA0] = DDVD_LPCM;
|
---|
1160 |
|
---|
1161 | if ((buf[14 + 3] & 0xF0) == 0xE0) { // video
|
---|
1162 | int pes_len = ((buf[14+4]<<8)|buf[14+5]) + 6;
|
---|
1163 | int padding = len - (14 + pes_len);
|
---|
1164 | if (buf[14 + 7] & 128) {
|
---|
1165 | /* damn gcc bug */
|
---|
1166 | vpts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
|
---|
1167 | vpts |= buf[14 + 10] << 22;
|
---|
1168 | vpts |= (buf[14 + 11] >> 1) << 15;
|
---|
1169 | vpts |= buf[14 + 12] << 7;
|
---|
1170 | vpts |= (buf[14 + 14] >> 1);
|
---|
1171 | //printf("VPTS? %X\n",(int)vpts);
|
---|
1172 | }
|
---|
1173 | #if CONFIG_API_VERSION == 1
|
---|
1174 | // Eliminate 00 00 01 B4 sequence error packet because it breaks the pallas mpeg decoder
|
---|
1175 | // This is very strange because the 00 00 01 B4 is partly inside the header extension ...
|
---|
1176 | if (buf[21] == 0x00 && buf[22] == 0x00 && buf[23] == 0x01 && buf[24] == 0xB4) {
|
---|
1177 | buf[21] = 0x01;
|
---|
1178 | }
|
---|
1179 | if (buf[22] == 0x00 && buf[23] == 0x00 && buf[24] == 0x01 && buf[25] == 0xB4) {
|
---|
1180 | buf[22] = 0x01;
|
---|
1181 | }
|
---|
1182 | #endif
|
---|
1183 | // if we have 16:9 Zoom Mode on the DVD and we use a "always 16:9" mode on tv we have
|
---|
1184 | // to patch the mpeg header and the Sequence Display Extension inside the Stream in some cases
|
---|
1185 | if (dvd_aspect == 3 && ((tv_aspect == DDVD_16_9 && (tv_mode == DDVD_PAN_SCAN || tv_mode == DDVD_LETTERBOX)) ||
|
---|
1186 | (tv_aspect == DDVD_16_10 && (tv_mode2 == DDVD_PAN_SCAN || tv_mode2 == DDVD_LETTERBOX)))) {
|
---|
1187 | int z=0;
|
---|
1188 | for (z=0; z<2040; z++)
|
---|
1189 | {
|
---|
1190 | if (buf[z] == 0x0 && buf[z+1] == 0x0 && buf[z+2] ==0x01 && buf[z+3] == 0xB5 && (buf[z+4] == 0x22 || buf[z+4] == 0x23))
|
---|
1191 | {
|
---|
1192 | buf[z+5]=0x22;
|
---|
1193 | buf[z+5]=0x0B;
|
---|
1194 | buf[z+6]=0x42;
|
---|
1195 | buf[z+7]=0x12;
|
---|
1196 | buf[z+8]=0x00;
|
---|
1197 | }
|
---|
1198 | }
|
---|
1199 | if (buf[33] == 0 && buf[33 + 1] == 0 && buf[33 + 2] == 1 && buf[33 + 3] == 0xB3) {
|
---|
1200 | buf[33 + 7] = (buf[33 + 7] & 0xF) + 0x30;
|
---|
1201 | }
|
---|
1202 | if (buf[36] == 0 && buf[36 + 1] == 0 && buf[36 + 2] == 1 && buf[36 + 3] == 0xB3) {
|
---|
1203 | buf[36 + 7] = (buf[36 + 7] & 0xF) + 0x30;
|
---|
1204 | }
|
---|
1205 | }
|
---|
1206 |
|
---|
1207 | // check yres for detecting ntsc/pal
|
---|
1208 | if (ddvd_have_ntsc == -1) {
|
---|
1209 | if ((buf[33] == 0 && buf[33 + 1] == 0 && buf[33 + 2] == 1 && buf[33 + 3] == 0xB3 && ((buf[33+5] & 0xF) << 8) + buf[33+6] == 0x1E0)
|
---|
1210 | || (buf[36] == 0 && buf[36 + 1] == 0 && buf[36 + 2] == 1 && buf[36 + 3] == 0xB3 && ((buf[36+5] & 0xF) << 8) + buf[36+6] == 0x1E0))
|
---|
1211 | ddvd_have_ntsc = 1;
|
---|
1212 | else
|
---|
1213 | ddvd_have_ntsc = 0;
|
---|
1214 | }
|
---|
1215 |
|
---|
1216 | if (padding > 8) {
|
---|
1217 | memcpy(buf+14+pes_len, "\x00\x00\x01\xE0\x00\x00\x80\x00\x00", 9);
|
---|
1218 | pes_len += 9;
|
---|
1219 | }
|
---|
1220 |
|
---|
1221 | safe_write(ddvd_output_fd, buf + 14, pes_len);
|
---|
1222 |
|
---|
1223 | if (padding && padding < 9)
|
---|
1224 | safe_write(ddvd_output_fd, "\x00\x00\x01\xE0\x00\x00\x80\x00\x00", 9);
|
---|
1225 |
|
---|
1226 | // 14+8 header_length
|
---|
1227 | // 14+(header_length)+3 -> start mpeg header
|
---|
1228 | // buf[14+buf[14+8]+3] start mpeg header
|
---|
1229 |
|
---|
1230 | int datalen = (buf[19] + (buf[18] << 8) + 6) - buf[14 + 8]; // length mpeg packet
|
---|
1231 | int data = buf[14 + buf[14 + 8] + 3]; // start mpeg packet(header)
|
---|
1232 |
|
---|
1233 | int do_copy = (ddvd_iframerun == 0x01) && !(buf[data] == 0 && buf[data + 1] == 0 && buf[data + 2] == 1) ? 1 : 0;
|
---|
1234 | int have_pictureheader = 0;
|
---|
1235 | int haveslice = 0;
|
---|
1236 | int setrun = 0;
|
---|
1237 |
|
---|
1238 | while (datalen > 3) {
|
---|
1239 | if (buf[data] == 0 && buf[data + 1] == 0 && buf[data + 2] == 1) {
|
---|
1240 | if (buf[data + 3] == 0x00 && datalen > 6) { //picture
|
---|
1241 | if (!setrun) {
|
---|
1242 | ddvd_iframerun = ((buf[data + 5] >> 3) & 0x07);
|
---|
1243 | setrun = 1;
|
---|
1244 | }
|
---|
1245 | if (ddvd_iframerun < 0x01 || 0x03 < ddvd_iframerun) {
|
---|
1246 | data++;
|
---|
1247 | datalen--;
|
---|
1248 | continue;
|
---|
1249 | }
|
---|
1250 | have_pictureheader = 1;
|
---|
1251 | data += 5;
|
---|
1252 | datalen -= 5;
|
---|
1253 | datalen = 6;
|
---|
1254 | } else if (buf[data + 3] == 0xB3 && datalen >= 8) { //sequence header
|
---|
1255 | ddvd_last_iframe_len = 0; // clear iframe buffer
|
---|
1256 | data += 7;
|
---|
1257 | datalen -= 7;
|
---|
1258 | } else if (buf[data + 3] == 0xBE) { //padding stream
|
---|
1259 | break;
|
---|
1260 | } else if (0x01 <= buf[data + 3] && buf[data + 3] <= 0xaf) { //slice ?
|
---|
1261 | if (!have_pictureheader && ddvd_last_iframe_len == 0)
|
---|
1262 | haveslice = 1;
|
---|
1263 | }
|
---|
1264 | }
|
---|
1265 | data++;
|
---|
1266 | datalen--;
|
---|
1267 | }
|
---|
1268 | if ((ddvd_iframerun <= 0x01 || do_copy) && ddvd_still_frame) {
|
---|
1269 | if (haveslice)
|
---|
1270 | ddvd_iframerun = 0xFF;
|
---|
1271 | else if (ddvd_last_iframe_len < (320 * 1024) - ((buf[19] + (buf[18] << 8) + 6) - buf[14 + 8])) {
|
---|
1272 | int len = buf[19] + (buf[18] << 8) + 6;
|
---|
1273 | int skip = buf[14+8] + 9; // skip complete pes header
|
---|
1274 | len -= skip;
|
---|
1275 | if (ddvd_last_iframe_len == 0) { // add simple pes header without pts
|
---|
1276 | memcpy(last_iframe, "\x00\x00\x01\xE0\x00\x00\x80\x00\x00", 9);
|
---|
1277 | ddvd_last_iframe_len += 9;
|
---|
1278 | }
|
---|
1279 | memcpy(last_iframe + ddvd_last_iframe_len, buf + 14 + skip, len);
|
---|
1280 | ddvd_last_iframe_len += len;
|
---|
1281 | }
|
---|
1282 | }
|
---|
1283 | } else if ((buf[14 + 3]) == 0xC0 + audio_id) // mpeg audio
|
---|
1284 | {
|
---|
1285 | if (audio_type != DDVD_MPEG) {
|
---|
1286 | //printf("Switch to MPEG Audio\n");
|
---|
1287 | #ifdef __sh__
|
---|
1288 | //stop audio bevor change encoding
|
---|
1289 | if (ioctl(ddvd_fdaudio, AUDIO_STOP) < 0)
|
---|
1290 | perror("AUDIO_STOP");
|
---|
1291 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
1292 | perror("AUDIO_CLEAR_BUFFER");
|
---|
1293 | #endif
|
---|
1294 | if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
|
---|
1295 | perror("AUDIO_SET_AV_SYNC");
|
---|
1296 | if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 1) < 0)
|
---|
1297 | perror("AUDIO_SET_BYPASS_MODE");
|
---|
1298 | #ifdef __sh__
|
---|
1299 | //start audio after encoding set
|
---|
1300 | if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
|
---|
1301 | perror("AUDIO_PLAY");
|
---|
1302 | #endif
|
---|
1303 | audio_type = DDVD_MPEG;
|
---|
1304 | }
|
---|
1305 |
|
---|
1306 | if (buf[14 + 7] & 128) {
|
---|
1307 | /* damn gcc bug */
|
---|
1308 | apts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
|
---|
1309 | apts |= buf[14 + 10] << 22;
|
---|
1310 | apts |= (buf[14 + 11] >> 1) << 15;
|
---|
1311 | apts |= buf[14 + 12] << 7;
|
---|
1312 | apts |= (buf[14 + 14] >> 1);
|
---|
1313 | //printf("APTS? %X\n",(int)apts);
|
---|
1314 | }
|
---|
1315 |
|
---|
1316 | safe_write(ddvd_ac3_fd, buf + 14, buf[19] + (buf[18] << 8) + 6);
|
---|
1317 | } else if ((buf[14 + 3]) == 0xBD && (buf[14 + buf[14 + 8] + 9]) == 0xA0 + audio_id) // lpcm audio
|
---|
1318 | {
|
---|
1319 | if (audio_type != DDVD_LPCM) {
|
---|
1320 | //printf("Switch to LPCM Audio\n");
|
---|
1321 | #ifdef __sh__
|
---|
1322 | //stop audio bevor change encoding
|
---|
1323 | if (ioctl(ddvd_fdaudio, AUDIO_STOP) < 0)
|
---|
1324 | perror("AUDIO_STOP");
|
---|
1325 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
1326 | perror("AUDIO_CLEAR_BUFFER");
|
---|
1327 | #endif
|
---|
1328 | if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
|
---|
1329 | perror("AUDIO_SET_AV_SYNC");
|
---|
1330 | #ifdef HARDWARE_SUPPORT_LPCM
|
---|
1331 | if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 6) < 0)
|
---|
1332 | #else
|
---|
1333 | if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 0) < 0)
|
---|
1334 | #endif
|
---|
1335 | perror("AUDIO_SET_BYPASS_MODE");
|
---|
1336 | #ifdef __sh__
|
---|
1337 | //start audio after encoding set
|
---|
1338 | if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
|
---|
1339 | perror("AUDIO_PLAY");
|
---|
1340 | #endif
|
---|
1341 | audio_type = DDVD_LPCM;
|
---|
1342 | ddvd_lpcm_count = 0;
|
---|
1343 | }
|
---|
1344 | if (buf[14 + 7] & 128) {
|
---|
1345 | /* damn gcc bug */
|
---|
1346 | apts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
|
---|
1347 | apts |= buf[14 + 10] << 22;
|
---|
1348 | apts |= (buf[14 + 11] >> 1) << 15;
|
---|
1349 | apts |= buf[14 + 12] << 7;
|
---|
1350 | apts |= (buf[14 + 14] >> 1);
|
---|
1351 | //printf("APTS? %X\n",(int)apts);
|
---|
1352 | }
|
---|
1353 | #ifndef HARDWARE_SUPPORT_LPCM
|
---|
1354 | int i = 0;
|
---|
1355 | char abuf[(((buf[18] << 8) | buf[19]) - buf[22] - 14)];
|
---|
1356 | #if BYTE_ORDER == BIG_ENDIAN
|
---|
1357 | // just copy, byte order is correct on ppc machines
|
---|
1358 | memcpy(abuf, buf + 14 + buf[14 + 8] + 9 + 7, (((buf[18] << 8) | buf[19]) - buf[22] - 14));
|
---|
1359 | i = (((buf[18] << 8) | buf[19]) - buf[22] - 14);
|
---|
1360 | #else
|
---|
1361 | // byte swapping .. we become the wrong byteorder on lpcm on the 7025
|
---|
1362 | while (i < (((buf[18] << 8) | buf[19]) - buf[22] - 14)) {
|
---|
1363 | abuf[i + 0] = (buf[14 + buf[14 + 8] + 9 + 7 + i + 1]);
|
---|
1364 | abuf[i + 1] = (buf[14 + buf[14 + 8] + 9 + 7 + i + 0]);
|
---|
1365 | i += 2;
|
---|
1366 | }
|
---|
1367 | #endif
|
---|
1368 | // we will encode the raw lpcm data to mpeg audio and send them with pts
|
---|
1369 | // information to the decoder to get a sync. playing the pcm data via
|
---|
1370 | // oss will break the pic/sound sync. So believe it or not, this is the
|
---|
1371 | // smartest way to get a synced lpcm track ;-)
|
---|
1372 | if (ddvd_lpcm_count == 0) { // save mpeg header with pts
|
---|
1373 | memcpy(mpa_data, buf + 14, buf[14 + 8] + 9);
|
---|
1374 | mpa_header_length = buf[14 + 8] + 9;
|
---|
1375 | }
|
---|
1376 | if (ddvd_lpcm_count + i >= 4608) { //we have to send 4608 bytes to the encoder
|
---|
1377 | memcpy(lpcm_data + ddvd_lpcm_count, abuf, 4608 - ddvd_lpcm_count);
|
---|
1378 | //encode
|
---|
1379 | mpa_count = ddvd_mpa_encode_frame(mpa_data + mpa_header_length, 4608, lpcm_data);
|
---|
1380 | //patch pes__packet_length
|
---|
1381 | mpa_count = mpa_count + mpa_header_length - 6;
|
---|
1382 | mpa_data[4] = mpa_count >> 8;
|
---|
1383 | mpa_data[5] = mpa_count & 0xFF;
|
---|
1384 | //patch header type to mpeg
|
---|
1385 | mpa_data[3] = 0xC0;
|
---|
1386 | //write
|
---|
1387 | safe_write(ddvd_ac3_fd, mpa_data, mpa_count + mpa_header_length);
|
---|
1388 | memcpy(lpcm_data, abuf + (4608 - ddvd_lpcm_count), i - (4608 - ddvd_lpcm_count));
|
---|
1389 | ddvd_lpcm_count = i - (4608 - ddvd_lpcm_count);
|
---|
1390 | memcpy(mpa_data, buf + 14, buf[14 + 8] + 9);
|
---|
1391 | mpa_header_length = buf[14 + 8] + 9;
|
---|
1392 | } else {
|
---|
1393 | memcpy(lpcm_data + ddvd_lpcm_count, abuf, i);
|
---|
1394 | ddvd_lpcm_count += i;
|
---|
1395 | }
|
---|
1396 | #else
|
---|
1397 | safe_write(ddvd_ac3_fd, buf+14 , buf[19]+(buf[18]<<8)+6);
|
---|
1398 | #endif
|
---|
1399 | } else if ((buf[14 + 3]) == 0xBD && (buf[14 + buf[14 + 8] + 9]) == 0x88 + audio_id) { // dts audio
|
---|
1400 | if (audio_type != DDVD_DTS) {
|
---|
1401 | //printf("Switch to DTS Audio (thru)\n");
|
---|
1402 | #ifdef __sh__
|
---|
1403 | //stop audio bevor change encoding
|
---|
1404 | if (ioctl(ddvd_fdaudio, AUDIO_STOP) < 0)
|
---|
1405 | perror("AUDIO_STOP");
|
---|
1406 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
1407 | perror("AUDIO_CLEAR_BUFFER");
|
---|
1408 | #endif
|
---|
1409 | if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
|
---|
1410 | perror("AUDIO_SET_AV_SYNC");
|
---|
1411 | #ifdef CONVERT_TO_DVB_COMPLIANT_DTS
|
---|
1412 | if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 2) < 0) // DTS (dvb compliant)
|
---|
1413 | #else
|
---|
1414 | if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 5) < 0) // DTS VOB
|
---|
1415 | perror("AUDIO_SET_BYPASS_MODE");
|
---|
1416 | #endif
|
---|
1417 | #ifdef __sh__
|
---|
1418 | //start audio after encoding set
|
---|
1419 | if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
|
---|
1420 | perror("AUDIO_PLAY");
|
---|
1421 | #endif
|
---|
1422 | audio_type = DDVD_DTS;
|
---|
1423 | }
|
---|
1424 |
|
---|
1425 | if (buf[14 + 7] & 128) {
|
---|
1426 | /* damn gcc bug */
|
---|
1427 | apts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
|
---|
1428 | apts |= buf[14 + 10] << 22;
|
---|
1429 | apts |= (buf[14 + 11] >> 1) << 15;
|
---|
1430 | apts |= buf[14 + 12] << 7;
|
---|
1431 | apts |= (buf[14 + 14] >> 1);
|
---|
1432 | //printf("APTS? %X\n",(int)apts);
|
---|
1433 | }
|
---|
1434 |
|
---|
1435 | #ifdef CONVERT_TO_DVB_COMPLIANT_DTS
|
---|
1436 | unsigned short pes_len = (buf[14 + 4] << 8 | buf[14 + 5]);
|
---|
1437 | pes_len -= 4; // strip first 4 bytes of pes payload
|
---|
1438 | buf[14 + 4] = pes_len >> 8; // patch pes len
|
---|
1439 | buf[15 + 4] = pes_len & 0xFF;
|
---|
1440 |
|
---|
1441 | safe_write(ddvd_ac3_fd, buf + 14, 9 + buf[14 + 8]); // write pes_header
|
---|
1442 | safe_write(ddvd_ac3_fd, buf + 14 + 9 + buf[14 + 8] + 4, pes_len - (3 + buf[14 + 8])); // write pes_payload
|
---|
1443 | #else
|
---|
1444 | safe_write(ddvd_ac3_fd, buf + 14, buf[19] + (buf[18] << 8) + 6);
|
---|
1445 | #endif
|
---|
1446 | } else if ((buf[14 + 3]) == 0xBD && (buf[14 + buf[14 + 8] + 9]) == 0x80 + audio_id) { // ac3 audio
|
---|
1447 | if (audio_type != DDVD_AC3) {
|
---|
1448 | //printf("Switch to AC3 Audio\n");
|
---|
1449 | #if defined(__sh__)
|
---|
1450 | if (ac3thru) {
|
---|
1451 | #else
|
---|
1452 | if (ac3thru || !have_liba52) { // !have_liba52 and !ac3thru should never happen, but who knows ;)
|
---|
1453 | #endif
|
---|
1454 |
|
---|
1455 | #ifdef __sh__
|
---|
1456 | //stop audio bevor change encoding
|
---|
1457 | if (ioctl(ddvd_fdaudio, AUDIO_STOP) < 0)
|
---|
1458 | perror("AUDIO_STOP");
|
---|
1459 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
1460 | perror("AUDIO_CLEAR_BUFFER");
|
---|
1461 | #endif
|
---|
1462 | if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
|
---|
1463 | perror("AUDIO_SET_AV_SYNC");
|
---|
1464 | #ifdef CONVERT_TO_DVB_COMPLIANT_AC3
|
---|
1465 | if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 0) < 0) // AC3 (dvb compliant)
|
---|
1466 | #else
|
---|
1467 | if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 3) < 0) // AC3 VOB
|
---|
1468 | #endif
|
---|
1469 | perror("AUDIO_SET_BYPASS_MODE");
|
---|
1470 | #ifdef __sh__
|
---|
1471 | //start audio after encoding set
|
---|
1472 | if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
|
---|
1473 | perror("AUDIO_PLAY");
|
---|
1474 | #endif
|
---|
1475 | } else {
|
---|
1476 | #ifdef __sh__
|
---|
1477 | //stop audio bevor change encoding
|
---|
1478 | if (ioctl(ddvd_fdaudio, AUDIO_STOP) < 0)
|
---|
1479 | perror("AUDIO_STOP");
|
---|
1480 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
1481 | perror("AUDIO_CLEAR_BUFFER");
|
---|
1482 | #endif
|
---|
1483 | if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
|
---|
1484 | perror("AUDIO_SET_AV_SYNC");
|
---|
1485 | if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 1) < 0)
|
---|
1486 | perror("AUDIO_SET_BYPASS_MODE");
|
---|
1487 | #ifdef __sh__
|
---|
1488 | //start audio after encoding set
|
---|
1489 | if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
|
---|
1490 | perror("AUDIO_PLAY");
|
---|
1491 | #endif
|
---|
1492 | }
|
---|
1493 | audio_type = DDVD_AC3;
|
---|
1494 | }
|
---|
1495 |
|
---|
1496 | if (buf[14 + 7] & 128) {
|
---|
1497 | /* damn gcc bug */
|
---|
1498 | apts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
|
---|
1499 | apts |= buf[14 + 10] << 22;
|
---|
1500 | apts |= (buf[14 + 11] >> 1) << 15;
|
---|
1501 | apts |= buf[14 + 12] << 7;
|
---|
1502 | apts |= (buf[14 + 14] >> 1);
|
---|
1503 | //printf("APTS? %X\n",(int)apts);
|
---|
1504 | }
|
---|
1505 |
|
---|
1506 | #if defined(__sh__)
|
---|
1507 | if (ac3thru) {
|
---|
1508 | #else
|
---|
1509 | if (ac3thru || !have_liba52) { // !have_liba52 and !ac3thru should never happen, but who knows ;)
|
---|
1510 | #endif
|
---|
1511 | #if defined(__sh__)
|
---|
1512 | safe_write(ddvd_ac3_fd, buf + 14, buf[19] + (buf[18] << 8) + 6);
|
---|
1513 | #else
|
---|
1514 | #ifdef CONVERT_TO_DVB_COMPLIANT_AC3
|
---|
1515 | unsigned short pes_len = (buf[14 + 4] << 8 | buf[14 + 5]);
|
---|
1516 | pes_len -= 4; // strip first 4 bytes of pes payload
|
---|
1517 | buf[14 + 4] = pes_len >> 8; // patch pes len
|
---|
1518 | buf[15 + 4] = pes_len & 0xFF;
|
---|
1519 |
|
---|
1520 | safe_write(ddvd_ac3_fd, buf + 14, 9 + buf[14 + 8]); // write pes_header
|
---|
1521 | safe_write(ddvd_ac3_fd, buf + 14 + 9 + buf[14 + 8] + 4, pes_len - (3 + buf[14 + 8])); // write pes_payload
|
---|
1522 | #else
|
---|
1523 | safe_write(ddvd_ac3_fd, buf + 14, buf[19] + (buf[18] << 8) + 6);
|
---|
1524 | #endif
|
---|
1525 | #endif /* __sh__ */
|
---|
1526 | //fwrite(buf+buf[22]+27, 1, ((buf[18]<<8)|buf[19])-buf[22]-7, fac3); //debugwrite
|
---|
1527 | } else {
|
---|
1528 | // a bit more funny than lpcm sound, because we do a complete recoding here
|
---|
1529 | // we will decode the ac3 data to plain lpcm and will then encode to mpeg
|
---|
1530 | // audio and send them with pts information to the decoder to get a sync.
|
---|
1531 |
|
---|
1532 | // decode and convert ac3 to raw lpcm
|
---|
1533 | ac3_len = ddvd_ac3_decode(buf + buf[22] + 27, ((buf[18] << 8) | buf[19]) - buf[22] - 7, ac3_tmp);
|
---|
1534 |
|
---|
1535 | // save the pes header incl. PTS
|
---|
1536 | memcpy(mpa_data, buf + 14, buf[14 + 8] + 9);
|
---|
1537 | mpa_header_length = buf[14 + 8] + 9;
|
---|
1538 |
|
---|
1539 | //apts-=(((unsigned long long)(ddvd_lpcm_count)*90)/192);
|
---|
1540 |
|
---|
1541 | //mpa_data[14]=(int)((apts<<1)&0xFF);
|
---|
1542 | //mpa_data[12]=(int)((apts>>7)&0xFF);
|
---|
1543 | //mpa_data[11]=(int)(((apts<<1)>>15)&0xFF);
|
---|
1544 | //mpa_data[10]=(int)((apts>>22)&0xFF);
|
---|
1545 |
|
---|
1546 | // copy lpcm data into buffer for encoding
|
---|
1547 | memcpy(lpcm_data + ddvd_lpcm_count, ac3_tmp, ac3_len);
|
---|
1548 | ddvd_lpcm_count += ac3_len;
|
---|
1549 |
|
---|
1550 | // encode the whole packet to mpa
|
---|
1551 | mpa_count2 = mpa_count = 0;
|
---|
1552 | while (ddvd_lpcm_count >= 4608) {
|
---|
1553 | mpa_count = ddvd_mpa_encode_frame(mpa_data + mpa_header_length + mpa_count2, 4608, lpcm_data);
|
---|
1554 | mpa_count2 += mpa_count;
|
---|
1555 | ddvd_lpcm_count -= 4608;
|
---|
1556 | memcpy(lpcm_data, lpcm_data + 4608, ddvd_lpcm_count);
|
---|
1557 | }
|
---|
1558 |
|
---|
1559 | // patch pes__packet_length
|
---|
1560 | mpa_count = mpa_count2 + mpa_header_length - 6;
|
---|
1561 | mpa_data[4] = mpa_count >> 8;
|
---|
1562 | mpa_data[5] = mpa_count & 0xFF;
|
---|
1563 |
|
---|
1564 | // patch header type to mpeg
|
---|
1565 | mpa_data[3] = 0xC0;
|
---|
1566 |
|
---|
1567 | // write to decoder
|
---|
1568 | safe_write(ddvd_ac3_fd, mpa_data, mpa_count2 + mpa_header_length);
|
---|
1569 |
|
---|
1570 | }
|
---|
1571 | } else if ((buf[14 + 3]) == 0xBD && ((buf[14 + buf[14 + 8] + 9]) & 0xE0) == 0x20 && ((buf[14 + buf[14 + 8] + 9]) & 0x1F) == spu_active_id) { // SPU packet
|
---|
1572 | memcpy(spu_buffer + ddvd_spu_ptr, buf + buf[22] + 14 + 10, 2048 - (buf[22] + 14 + 10));
|
---|
1573 | ddvd_spu_ptr += 2048 - (buf[22] + 14 + 10);
|
---|
1574 |
|
---|
1575 | if (buf[14 + 7] & 128) {
|
---|
1576 | /* damn gcc bug */
|
---|
1577 | #if CONFIG_API_VERSION == 3
|
---|
1578 | spts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
|
---|
1579 | spts |= buf[14 + 10] << 22;
|
---|
1580 | spts |= (buf[14 + 11] >> 1) << 15;
|
---|
1581 | spts |= buf[14 + 12] << 7;
|
---|
1582 | spts |= (buf[14 + 14] >> 1);
|
---|
1583 | #else
|
---|
1584 | spts = (buf[14 + 9] >> 1) << 29; // need a corrected "spts" because vulcan/pallas will give us a 32bit pts instead of 33bit
|
---|
1585 | spts |= buf[14 + 10] << 21;
|
---|
1586 | spts |= (buf[14 + 11] >> 1) << 14;
|
---|
1587 | spts |= buf[14 + 12] << 6;
|
---|
1588 | spts |= buf[14 + 12] >> 2;
|
---|
1589 | #endif
|
---|
1590 | //printf("SPTS? %X\n",(int)spts);
|
---|
1591 | }
|
---|
1592 |
|
---|
1593 | if (ddvd_spu_ptr >= (spu_buffer[0] << 8 | spu_buffer[1])) // SPU packet complete ?
|
---|
1594 | {
|
---|
1595 | if (ddvd_spu_backnr == NUM_SPU_BACKBUFFER) // backbuffer already full ?
|
---|
1596 | {
|
---|
1597 | printf("dropped SPU frame\n");
|
---|
1598 | int tmplen = (spu_backbuffer[0] << 8 | spu_backbuffer[1]);
|
---|
1599 | memcpy(spu_backbuffer, spu_backbuffer + tmplen, ddvd_spu_backptr - tmplen); // delete oldest SPU packet
|
---|
1600 | int i;
|
---|
1601 | for (i = 0; i < NUM_SPU_BACKBUFFER - 1; ++i)
|
---|
1602 | spu_backpts[i] = spu_backpts[i + 1];
|
---|
1603 | ddvd_spu_backnr = NUM_SPU_BACKBUFFER - 1;
|
---|
1604 | ddvd_spu_backptr -= tmplen;
|
---|
1605 | }
|
---|
1606 |
|
---|
1607 | memcpy(spu_backbuffer + ddvd_spu_backptr, spu_buffer, (spu_buffer[0] << 8 | spu_buffer[1])); // copy into backbuffer
|
---|
1608 | spu_backpts[ddvd_spu_backnr++] = spts; // store pts
|
---|
1609 | ddvd_spu_backptr += (spu_buffer[0] << 8 | spu_buffer[1]); // increase ptr
|
---|
1610 |
|
---|
1611 | ddvd_spu_ptr = 0;
|
---|
1612 | }
|
---|
1613 | }
|
---|
1614 | }
|
---|
1615 | break;
|
---|
1616 |
|
---|
1617 | case DVDNAV_NOP:
|
---|
1618 | /* Nothing to do here. */
|
---|
1619 | break;
|
---|
1620 |
|
---|
1621 | case DVDNAV_STILL_FRAME:
|
---|
1622 | /* We have reached a still frame. So we start a timer to wait
|
---|
1623 | * the amount of time specified by the still's length while still handling
|
---|
1624 | * user input to make menus and other interactive stills work.
|
---|
1625 | * A length of 0xff means an indefinite still which has to be skipped
|
---|
1626 | * indirectly by some user interaction. */
|
---|
1627 | {
|
---|
1628 | if (ddvd_iframesend == 0 && ddvd_last_iframe_len)
|
---|
1629 | ddvd_iframesend = 1;
|
---|
1630 |
|
---|
1631 | dvdnav_still_event_t *still_event = (dvdnav_still_event_t *) buf;
|
---|
1632 | if (still_event->length < 0xff) {
|
---|
1633 | if (!ddvd_wait_timer_active) {
|
---|
1634 | ddvd_wait_timer_active = 1;
|
---|
1635 | ddvd_wait_timer_end = ddvd_get_time() + (still_event->length * 1000); //ms
|
---|
1636 | }
|
---|
1637 | } else
|
---|
1638 | ddvd_wait_for_user = 1;
|
---|
1639 | }
|
---|
1640 | break;
|
---|
1641 |
|
---|
1642 | case DVDNAV_WAIT:
|
---|
1643 | /* We have reached a point in DVD playback, where timing is critical.
|
---|
1644 | * We dont use readahead, so we can simply skip the wait state. */
|
---|
1645 | dvdnav_wait_skip(dvdnav);
|
---|
1646 | break;
|
---|
1647 |
|
---|
1648 | case DVDNAV_SPU_CLUT_CHANGE:
|
---|
1649 | /* We received a new color lookup table so we read and store
|
---|
1650 | * it */
|
---|
1651 | {
|
---|
1652 | int i = 0, i2 = 0;
|
---|
1653 | uint8_t pal[16 * 4];
|
---|
1654 | #if BYTE_ORDER == BIG_ENDIAN
|
---|
1655 | memcpy(pal, buf, 16 * sizeof(uint32_t));
|
---|
1656 | #else
|
---|
1657 | for (; i < 16; ++i)
|
---|
1658 | *(int *)(pal + i * 4) = htonl(*(int *)(buf + i * 4));
|
---|
1659 | i = 0;
|
---|
1660 | #endif
|
---|
1661 | while (i < 16 * 4) {
|
---|
1662 | int y = buf[i + 1];
|
---|
1663 | signed char cr = buf[i + 2]; //v
|
---|
1664 | signed char cb = buf[i + 3]; //u
|
---|
1665 | //printf("%d %d %d ->", y, cr, cb);
|
---|
1666 | y = pal[i + 1];
|
---|
1667 | cr = pal[i + 2]; //v
|
---|
1668 | cb = pal[i + 3]; //u
|
---|
1669 | //printf(" %d %d %d\n", y, cr, cb);
|
---|
1670 | i += 4;
|
---|
1671 | }
|
---|
1672 | i = 0;
|
---|
1673 |
|
---|
1674 | while (i < 16 * 4) {
|
---|
1675 | int y = pal[i + 1];
|
---|
1676 | signed char cr = pal[i + 2]; //v
|
---|
1677 | signed char cb = pal[i + 3]; //u
|
---|
1678 |
|
---|
1679 | y = 76310 * (y - 16); //yuv2rgb
|
---|
1680 | cr -= 128;
|
---|
1681 | cb -= 128;
|
---|
1682 | int r = CLAMP((y + 104635 * cr) >> 16);
|
---|
1683 | int g = CLAMP((y - 53294 * cr - 25690 * cb) >> 16);
|
---|
1684 | int b = CLAMP((y + 132278 * cb) >> 16);
|
---|
1685 |
|
---|
1686 | ddvd_bl[i2] = b << 8;
|
---|
1687 | ddvd_gn[i2] = g << 8;
|
---|
1688 | ddvd_rd[i2] = r << 8;
|
---|
1689 | i += 4;
|
---|
1690 | i2++;
|
---|
1691 | }
|
---|
1692 | //CHANGE COLORMAP
|
---|
1693 | }
|
---|
1694 | break;
|
---|
1695 |
|
---|
1696 | case DVDNAV_SPU_STREAM_CHANGE:
|
---|
1697 | /* We received a new SPU stream ID */
|
---|
1698 | if (spu_lock)
|
---|
1699 | break;
|
---|
1700 |
|
---|
1701 | dvdnav_spu_stream_change_event_t *ev = (dvdnav_spu_stream_change_event_t *) buf;
|
---|
1702 | switch (tv_scale) {
|
---|
1703 | case 0: //off
|
---|
1704 | spu_active_id = ev->physical_wide;
|
---|
1705 | break;
|
---|
1706 | case 1: //letterbox
|
---|
1707 | spu_active_id = ev->physical_letterbox;
|
---|
1708 | break;
|
---|
1709 | case 2: //panscan
|
---|
1710 | spu_active_id = ev->physical_pan_scan;
|
---|
1711 | break;
|
---|
1712 | default: // should not happen
|
---|
1713 | spu_active_id = ev->physical_wide;
|
---|
1714 | break;
|
---|
1715 | }
|
---|
1716 | uint16_t spu_lang = 0xFFFF;
|
---|
1717 | int spu_id_logical, count_tmp;
|
---|
1718 | spu_id_logical = -1;
|
---|
1719 | count_tmp = spu_active_id;
|
---|
1720 | while (count_tmp >= 0 && count_tmp < MAX_SPU)
|
---|
1721 | {
|
---|
1722 | spu_id_logical = playerconfig->spu_map[count_tmp];
|
---|
1723 | if (spu_id_logical >= 0)
|
---|
1724 | count_tmp = 0;
|
---|
1725 | count_tmp--;
|
---|
1726 | }
|
---|
1727 |
|
---|
1728 | spu_lang = dvdnav_spu_stream_to_lang(dvdnav, (spu_id_logical >= 0 ? spu_id_logical : spu_active_id) & 0x1F);
|
---|
1729 | if (spu_lang == 0xFFFF) {
|
---|
1730 | spu_lang = 0x2D2D; // SPU "off, unknown or maybe menuoverlays"
|
---|
1731 | spu_id_logical = -1;
|
---|
1732 | }
|
---|
1733 | msg = DDVD_SHOWOSD_SUBTITLE;
|
---|
1734 | int report_spu = spu_id_logical > 31 ? -1 : spu_id_logical;
|
---|
1735 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1736 | safe_write(message_pipe, &report_spu, sizeof(int));
|
---|
1737 | safe_write(message_pipe, &spu_lang, sizeof(uint16_t));
|
---|
1738 | //printf("SPU Stream change: w %X l: %X p: %X active: %X\n",ev->physical_wide,ev->physical_letterbox,ev->physical_pan_scan,spu_active_id);
|
---|
1739 | break;
|
---|
1740 |
|
---|
1741 | case DVDNAV_AUDIO_STREAM_CHANGE:
|
---|
1742 | /* We received a new Audio stream ID */
|
---|
1743 | if (!audio_lock)
|
---|
1744 | {
|
---|
1745 | audio_id = dvdnav_get_active_audio_stream(dvdnav);
|
---|
1746 | report_audio_info = 1;
|
---|
1747 | }
|
---|
1748 | break;
|
---|
1749 |
|
---|
1750 | case DVDNAV_HIGHLIGHT:
|
---|
1751 | /* Lets display some Buttons */
|
---|
1752 | if (ddvd_clear_buttons == 0) {
|
---|
1753 | dvdnav_highlight_event_t *highlight_event = (dvdnav_highlight_event_t *) buf;
|
---|
1754 |
|
---|
1755 | pci = dvdnav_get_current_nav_pci(dvdnav);
|
---|
1756 | dsi = dvdnav_get_current_nav_dsi(dvdnav);
|
---|
1757 | dvdnav_highlight_area_t hl;
|
---|
1758 |
|
---|
1759 | memcpy(&blit_area,&last_blit_area,sizeof(struct ddvd_resize_return));
|
---|
1760 | memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres); //clear backbuffer ..
|
---|
1761 | msg = DDVD_SCREEN_UPDATE; // wipe old highlight
|
---|
1762 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1763 | safe_write(message_pipe, &blit_area, sizeof(struct ddvd_resize_return));
|
---|
1764 | //printf("destination area to wipe: %d %d %d %d\n",blit_area.x_start,blit_area.x_end,blit_area.y_start,blit_area.y_end);
|
---|
1765 |
|
---|
1766 | //struct ddvd_resize_return blit_area;
|
---|
1767 | blit_area.x_start = blit_area.x_end = blit_area.y_start = blit_area.y_end = 0;
|
---|
1768 |
|
---|
1769 | int libdvdnav_workaround = 0;
|
---|
1770 |
|
---|
1771 | if (pci->hli.hl_gi.btngr_ns) {
|
---|
1772 | int btns_per_group = 36 / pci->hli.hl_gi.btngr_ns;
|
---|
1773 | btni_t *btni = NULL;
|
---|
1774 | int modeMask = 1 << tv_scale;
|
---|
1775 |
|
---|
1776 | if (!btni && pci->hli.hl_gi.btngr_ns >= 1 && (pci->hli.hl_gi.btngr1_dsp_ty & modeMask)) {
|
---|
1777 | btni = &pci->hli.btnit[0 * btns_per_group + highlight_event->buttonN - 1];
|
---|
1778 | }
|
---|
1779 | if (!btni && pci->hli.hl_gi.btngr_ns >= 2 && (pci->hli.hl_gi.btngr2_dsp_ty & modeMask)) {
|
---|
1780 | btni = &pci->hli.btnit[1 * btns_per_group + highlight_event->buttonN - 1];
|
---|
1781 | }
|
---|
1782 | if (!btni && pci->hli.hl_gi.btngr_ns >= 3 && (pci->hli.hl_gi.btngr3_dsp_ty & modeMask)) {
|
---|
1783 | btni = &pci->hli.btnit[2 * btns_per_group + highlight_event->buttonN - 1];
|
---|
1784 | }
|
---|
1785 |
|
---|
1786 | if (btni && btni->btn_coln != 0) {
|
---|
1787 | // get and set clut for actual button
|
---|
1788 | unsigned char tmp, tmp2;
|
---|
1789 | struct ddvd_color colneu;
|
---|
1790 | int i;
|
---|
1791 | msg = DDVD_COLORTABLE_UPDATE;
|
---|
1792 | if (ddvd_screeninfo_bypp == 1)
|
---|
1793 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1794 | for (i = 0; i < 4; i++) {
|
---|
1795 | tmp = ((pci->hli.btn_colit.btn_coli[btni->btn_coln - 1][0]) >> (16 + 4 * i)) & 0xf;
|
---|
1796 | tmp2 = ((pci->hli.btn_colit.btn_coli[btni->btn_coln - 1][0]) >> (4 * i)) & 0xf;
|
---|
1797 | colneu.blue = ddvd_bl[i + 252] = ddvd_bl[tmp];
|
---|
1798 | colneu.green = ddvd_gn[i + 252] = ddvd_gn[tmp];
|
---|
1799 | colneu.red = ddvd_rd[i + 252] = ddvd_rd[tmp];
|
---|
1800 | colneu.trans = ddvd_tr[i + 252] = (0xF - tmp2) * 0x1111;
|
---|
1801 | if (ddvd_screeninfo_bypp == 1)
|
---|
1802 | safe_write(message_pipe, &colneu, sizeof(struct ddvd_color));
|
---|
1803 | }
|
---|
1804 | msg = DDVD_NULL;
|
---|
1805 | //CHANGE COLORMAP
|
---|
1806 |
|
---|
1807 | memset(ddvd_lbb2, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres); //clear backbuffer ..
|
---|
1808 | //copy button into screen
|
---|
1809 | for (i = btni->y_start; i < btni->y_end; i++) {
|
---|
1810 | if (ddvd_screeninfo_bypp == 1)
|
---|
1811 | memcpy(ddvd_lbb2 + btni->x_start + 720 * (i),
|
---|
1812 | ddvd_lbb + btni->x_start + 720 * (i),
|
---|
1813 | btni->x_end - btni->x_start);
|
---|
1814 | else
|
---|
1815 | ddvd_blit_to_argb(ddvd_lbb2 + btni->x_start * ddvd_screeninfo_bypp +
|
---|
1816 | 720 * ddvd_screeninfo_bypp * i,
|
---|
1817 | ddvd_lbb + btni->x_start + 720 * (i),
|
---|
1818 | btni->x_end - btni->x_start);
|
---|
1819 | }
|
---|
1820 | blit_area.x_start = btni->x_start;
|
---|
1821 | blit_area.x_end = btni->x_end;
|
---|
1822 | blit_area.y_start = btni->y_start;
|
---|
1823 | blit_area.y_end = btni->y_end;
|
---|
1824 | libdvdnav_workaround = 1;
|
---|
1825 | }
|
---|
1826 | }
|
---|
1827 | if (!libdvdnav_workaround && dvdnav_get_highlight_area(pci, highlight_event->buttonN, 0, &hl) == DVDNAV_STATUS_OK) {
|
---|
1828 | // get and set clut for actual button
|
---|
1829 | unsigned char tmp, tmp2;
|
---|
1830 | struct ddvd_color colneu;
|
---|
1831 | int i;
|
---|
1832 | msg = DDVD_COLORTABLE_UPDATE;
|
---|
1833 | if (ddvd_screeninfo_bypp == 1)
|
---|
1834 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1835 | for (i = 0; i < 4; i++) {
|
---|
1836 | tmp = ((hl.palette) >> (16 + 4 * i)) & 0xf;
|
---|
1837 | tmp2 = ((hl.palette) >> (4 * i)) & 0xf;
|
---|
1838 | colneu.blue = ddvd_bl[i + 252] = ddvd_bl[tmp];
|
---|
1839 | colneu.green = ddvd_gn[i + 252] = ddvd_gn[tmp];
|
---|
1840 | colneu.red = ddvd_rd[i + 252] = ddvd_rd[tmp];
|
---|
1841 | colneu.trans = ddvd_tr[i + 252] = (0xF - tmp2) * 0x1111;
|
---|
1842 | if (ddvd_screeninfo_bypp == 1)
|
---|
1843 | safe_write(message_pipe, &colneu, sizeof(struct ddvd_color));
|
---|
1844 | }
|
---|
1845 | msg = DDVD_NULL;
|
---|
1846 | //CHANGE COLORMAP
|
---|
1847 |
|
---|
1848 | memset(ddvd_lbb2, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres); //clear backbuffer ..
|
---|
1849 | //copy button into screen
|
---|
1850 | for (i = hl.sy; i < hl.ey; i++) {
|
---|
1851 | if (ddvd_screeninfo_bypp == 1)
|
---|
1852 | memcpy(ddvd_lbb2 + hl.sx + 720 * (i),
|
---|
1853 | ddvd_lbb + hl.sx + 720 * (i), hl.ex - hl.sx);
|
---|
1854 | else
|
---|
1855 | ddvd_blit_to_argb(ddvd_lbb2 + hl.sx * ddvd_screeninfo_bypp + 720 * ddvd_screeninfo_bypp * i,
|
---|
1856 | ddvd_lbb + hl.sx + 720 * (i), hl.ex - hl.sx);
|
---|
1857 | }
|
---|
1858 | blit_area.x_start = hl.sx;
|
---|
1859 | blit_area.x_end = hl.ex;
|
---|
1860 | blit_area.y_start = hl.sy;
|
---|
1861 | blit_area.y_end = hl.ey;
|
---|
1862 | libdvdnav_workaround = 1;
|
---|
1863 | }
|
---|
1864 | if (!libdvdnav_workaround)
|
---|
1865 | memset(ddvd_lbb2, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres); //clear backbuffer ..
|
---|
1866 | else
|
---|
1867 | {
|
---|
1868 | int y_source = ddvd_have_ntsc ? 480 : 576; // correct ntsc overlay
|
---|
1869 | int x_offset = calc_x_scale_offset(dvd_aspect, tv_mode, tv_mode2, tv_aspect);
|
---|
1870 | int y_offset = calc_y_scale_offset(dvd_aspect, tv_mode, tv_mode2, tv_aspect);
|
---|
1871 |
|
---|
1872 | uint64_t start=ddvd_get_time();
|
---|
1873 | int resized = 0;
|
---|
1874 |
|
---|
1875 | if ((x_offset != 0 || y_offset != 0 || y_source != ddvd_screeninfo_yres || ddvd_screeninfo_xres != 720) && !playerconfig->canscale)
|
---|
1876 | {
|
---|
1877 | // printf("resizing\n");
|
---|
1878 | resized = 1;
|
---|
1879 | blit_area = ddvd_resize_pixmap(ddvd_lbb2, 720, y_source, ddvd_screeninfo_xres, ddvd_screeninfo_yres, x_offset, y_offset, blit_area.x_start, blit_area.x_end, blit_area.y_start, blit_area.y_end, ddvd_screeninfo_bypp); // resize
|
---|
1880 | }
|
---|
1881 |
|
---|
1882 | blit_area.width = ddvd_screeninfo_xres;
|
---|
1883 | blit_area.height = ddvd_screeninfo_yres;
|
---|
1884 |
|
---|
1885 | if (resized)
|
---|
1886 | {
|
---|
1887 | blit_area.x_offset = 0;
|
---|
1888 | blit_area.y_offset = 0;
|
---|
1889 | } else
|
---|
1890 | {
|
---|
1891 | blit_area.x_offset = x_offset;
|
---|
1892 | blit_area.y_offset = y_offset;
|
---|
1893 | }
|
---|
1894 | memcpy(p_lfb, ddvd_lbb2, ddvd_screeninfo_xres * ddvd_screeninfo_yres * ddvd_screeninfo_bypp); //copy backbuffer into screen
|
---|
1895 | //printf("needed time for resizing: %d ms\n",(int)(ddvd_get_time()-start));
|
---|
1896 | //printf("destination area to blit: %d %d %d %d\n",blit_area.x_start,blit_area.x_end,blit_area.y_start,blit_area.y_end);
|
---|
1897 | msg = DDVD_SCREEN_UPDATE;
|
---|
1898 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
1899 | safe_write(message_pipe, &blit_area, sizeof(struct ddvd_resize_return));
|
---|
1900 | memcpy(&last_blit_area,&blit_area,sizeof(struct ddvd_resize_return)); // safe blit area for next wipe
|
---|
1901 | }
|
---|
1902 | } else {
|
---|
1903 | ddvd_clear_buttons = 0;
|
---|
1904 | //printf("clear buttons\n");
|
---|
1905 | }
|
---|
1906 | break;
|
---|
1907 |
|
---|
1908 | case DVDNAV_VTS_CHANGE:
|
---|
1909 | {
|
---|
1910 | /* Some status information like video aspect and video scale permissions do
|
---|
1911 | * not change inside a VTS. Therefore we will set it new at this place */
|
---|
1912 | ddvd_play_empty(FALSE);
|
---|
1913 | audio_lock = 0; // reset audio & spu lock
|
---|
1914 | spu_lock = 0;
|
---|
1915 | for ( i = 0; i < MAX_AUDIO; i++)
|
---|
1916 | playerconfig->audio_format[i] = -1;
|
---|
1917 | // fill spu_map with data
|
---|
1918 | int count_tmp,spu_tmp;
|
---|
1919 | for (count_tmp = 0; count_tmp < MAX_SPU; count_tmp++)
|
---|
1920 | playerconfig->spu_map[count_tmp] = -1;
|
---|
1921 | for (count_tmp = 0; count_tmp < MAX_SPU; count_tmp++)
|
---|
1922 | {
|
---|
1923 | spu_tmp = dvdnav_get_spu_logical_stream(dvdnav, count_tmp);
|
---|
1924 | if (spu_tmp >= 0 && spu_tmp < MAX_SPU)
|
---|
1925 | playerconfig->spu_map[spu_tmp] = count_tmp;
|
---|
1926 | }
|
---|
1927 |
|
---|
1928 | dvd_aspect = dvdnav_get_video_aspect(dvdnav);
|
---|
1929 |
|
---|
1930 | //needed for titan
|
---|
1931 | #if defined(__sh__)
|
---|
1932 | playerconfig->dvd_aspect = dvd_aspect;
|
---|
1933 | #endif
|
---|
1934 |
|
---|
1935 | dvd_scale_perm = dvdnav_get_video_scale_permission(dvdnav);
|
---|
1936 | tv_scale = ddvd_check_aspect(dvd_aspect, dvd_scale_perm, tv_aspect, tv_mode);
|
---|
1937 | //printf("DVD Aspect: %d TV Aspect: %d Scale: %d Allowed: %d\n",dvd_aspect,tv_aspect,tv_scale,dvd_scale_perm);
|
---|
1938 |
|
---|
1939 | // resuming a dvd ?
|
---|
1940 | if (playerconfig->should_resume && first_vts_change) {
|
---|
1941 | first_vts_change = 0;
|
---|
1942 | int title_numbers,part_numbers;
|
---|
1943 | dvdnav_get_number_of_titles(dvdnav, &title_numbers);
|
---|
1944 | dvdnav_get_number_of_parts(dvdnav, playerconfig->resume_title, &part_numbers);
|
---|
1945 | if (playerconfig->resume_title <= title_numbers && playerconfig->resume_title > 0 && playerconfig->resume_chapter <= part_numbers && playerconfig->resume_chapter > 0) {
|
---|
1946 | dvdnav_part_play(dvdnav, playerconfig->resume_title, playerconfig->resume_chapter);
|
---|
1947 | next_cell_change = 1;
|
---|
1948 | } else {
|
---|
1949 | playerconfig->should_resume = 0;
|
---|
1950 | playerconfig->resume_title = 0;
|
---|
1951 | playerconfig->resume_chapter = 0;
|
---|
1952 | playerconfig->resume_block = 0;
|
---|
1953 | playerconfig->resume_audio_id = 0;
|
---|
1954 | playerconfig->resume_audio_lock = 0;
|
---|
1955 | playerconfig->resume_spu_id = 0;
|
---|
1956 | playerconfig->resume_spu_lock = 0;
|
---|
1957 | perror("DVD resuming failed");
|
---|
1958 | }
|
---|
1959 |
|
---|
1960 |
|
---|
1961 | }
|
---|
1962 | }
|
---|
1963 | break;
|
---|
1964 |
|
---|
1965 | case DVDNAV_CELL_CHANGE:
|
---|
1966 | {
|
---|
1967 | /* Store new cell information */
|
---|
1968 | memcpy(&ddvd_lastCellEventInfo, buf, sizeof(dvdnav_cell_change_event_t));
|
---|
1969 |
|
---|
1970 | if ((ddvd_still_frame & CELL_STILL) && ddvd_iframesend == 0 && ddvd_last_iframe_len)
|
---|
1971 | ddvd_iframesend = 1;
|
---|
1972 |
|
---|
1973 | ddvd_still_frame = (dvdnav_get_next_still_flag(dvdnav) != 0) ? CELL_STILL : 0;
|
---|
1974 |
|
---|
1975 | // resuming a dvd ?
|
---|
1976 | if (playerconfig->should_resume && next_cell_change) {
|
---|
1977 | next_cell_change = 0;
|
---|
1978 | playerconfig->should_resume = 0;
|
---|
1979 | if (dvdnav_sector_search(dvdnav, playerconfig->resume_block, SEEK_SET) != DVDNAV_STATUS_OK)
|
---|
1980 | {
|
---|
1981 | perror("DVD resuming failed");
|
---|
1982 | } else {
|
---|
1983 | audio_id = playerconfig->resume_audio_id;
|
---|
1984 | audio_lock = 1;//playerconfig->resume_audio_lock;
|
---|
1985 | spu_active_id = playerconfig->resume_spu_id;
|
---|
1986 | spu_lock = 1;//playerconfig->resume_spu_lock;
|
---|
1987 | report_audio_info = 1;
|
---|
1988 | uint16_t spu_lang = 0xFFFF;
|
---|
1989 | int spu_id_logical, count_tmp;
|
---|
1990 | count_tmp = spu_active_id;
|
---|
1991 | while (count_tmp >= 0)
|
---|
1992 | {
|
---|
1993 | spu_id_logical = playerconfig->spu_map[count_tmp];
|
---|
1994 | if (spu_id_logical >= 0)
|
---|
1995 | count_tmp = 0;
|
---|
1996 | count_tmp--;
|
---|
1997 | }
|
---|
1998 | spu_lang = dvdnav_spu_stream_to_lang(dvdnav, (spu_id_logical >= 0 ? spu_id_logical : spu_active_id) & 0x1F);
|
---|
1999 | if (spu_lang == 0xFFFF) {
|
---|
2000 | spu_lang = 0x2D2D; // SPU "off"
|
---|
2001 | spu_active_id = -1;
|
---|
2002 | spu_id_logical = -1;
|
---|
2003 | }
|
---|
2004 | msg = DDVD_SHOWOSD_SUBTITLE;
|
---|
2005 | int report_spu = spu_id_logical > 31 ? -1 : spu_id_logical;
|
---|
2006 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2007 | safe_write(message_pipe, &report_spu, sizeof(int));
|
---|
2008 | safe_write(message_pipe, &spu_lang, sizeof(uint16_t));
|
---|
2009 | msg = DDVD_SHOWOSD_TIME; // send new position to the frontend
|
---|
2010 | }
|
---|
2011 | playerconfig->resume_title = 0;
|
---|
2012 | playerconfig->resume_chapter = 0;
|
---|
2013 | playerconfig->resume_block = 0;
|
---|
2014 | playerconfig->resume_audio_id = 0;
|
---|
2015 | playerconfig->resume_audio_lock = 0;
|
---|
2016 | playerconfig->resume_spu_id = 0;
|
---|
2017 | playerconfig->resume_spu_lock = 0;
|
---|
2018 | }
|
---|
2019 | // multiple angels ?
|
---|
2020 | int num = 0, current = 0;
|
---|
2021 | dvdnav_get_angle_info(dvdnav, ¤t, &num);
|
---|
2022 | msg = DDVD_SHOWOSD_ANGLE;
|
---|
2023 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2024 | safe_write(message_pipe, ¤t, sizeof(int));
|
---|
2025 | safe_write(message_pipe, &num, sizeof(int));
|
---|
2026 | }
|
---|
2027 | break;
|
---|
2028 |
|
---|
2029 | case DVDNAV_NAV_PACKET:
|
---|
2030 | /* A NAV packet provides PTS discontinuity information, angle linking information and
|
---|
2031 | * button definitions for DVD menus. We have to handle some stilframes here */
|
---|
2032 | pci = dvdnav_get_current_nav_pci(dvdnav);
|
---|
2033 | dsi = dvdnav_get_current_nav_dsi(dvdnav);
|
---|
2034 |
|
---|
2035 | if ((ddvd_still_frame & NAV_STILL) && ddvd_iframesend == 0 && ddvd_last_iframe_len)
|
---|
2036 | ddvd_iframesend = 1;
|
---|
2037 |
|
---|
2038 | if (dsi->vobu_sri.next_video == 0xbfffffff)
|
---|
2039 | ddvd_still_frame |= NAV_STILL; //|= 1;
|
---|
2040 | else
|
---|
2041 | ddvd_still_frame &= ~NAV_STILL; //&= 1;
|
---|
2042 | break;
|
---|
2043 |
|
---|
2044 | case DVDNAV_HOP_CHANNEL:
|
---|
2045 | /* This event is issued whenever a non-seamless operation has been executed.
|
---|
2046 | * So we drop our buffers */
|
---|
2047 | ddvd_play_empty(TRUE);
|
---|
2048 | break;
|
---|
2049 |
|
---|
2050 | case DVDNAV_STOP:
|
---|
2051 | /* Playback should end here. */
|
---|
2052 | printf("DVDNAV_STOP\n");
|
---|
2053 | playerconfig->resume_title = 0;
|
---|
2054 | playerconfig->resume_chapter = 0;
|
---|
2055 | playerconfig->resume_block = 0;
|
---|
2056 | playerconfig->resume_audio_id = 0;
|
---|
2057 | playerconfig->resume_audio_lock = 0;
|
---|
2058 | playerconfig->resume_spu_id = 0;
|
---|
2059 | playerconfig->resume_spu_lock = 0;
|
---|
2060 | finished = 1;
|
---|
2061 | break;
|
---|
2062 |
|
---|
2063 | default:
|
---|
2064 | printf("Unknown event (%i)\n", event);
|
---|
2065 | finished = 1;
|
---|
2066 | break;
|
---|
2067 | }
|
---|
2068 | }
|
---|
2069 | // spu handling
|
---|
2070 | #if CONFIG_API_VERSION == 1
|
---|
2071 | unsigned int tpts;
|
---|
2072 | if (ioctl(ddvd_output_fd, VIDEO_GET_PTS, &tpts) < 0)
|
---|
2073 | perror("VIDEO_GET_PTS");
|
---|
2074 | pts = (unsigned long long)tpts;
|
---|
2075 | signed long long diff = spu_backpts[0] - pts;
|
---|
2076 | if (ddvd_spu_backnr > 0 && diff <= 0xFF) // we only have a 32bit pts on vulcan/pallas (instead of 33bit) so we need some tolerance on syncing SPU for menus
|
---|
2077 | // so on non animated menus the buttons will be displayed to soon, but we we have to accept it
|
---|
2078 | #else
|
---|
2079 |
|
---|
2080 | // nit: VIDEO_GET_EVENT blocks here
|
---|
2081 | // if dvd can't start VIDEO_GET_PTS overflows console with output
|
---|
2082 | #if defined(__sh__)
|
---|
2083 | ioctl(ddvd_fdvideo, VIDEO_GET_PTS, &pts);
|
---|
2084 | #else
|
---|
2085 | if (ioctl(ddvd_fdvideo, VIDEO_GET_PTS, &pts) < 0)
|
---|
2086 | perror("VIDEO_GET_PTS");
|
---|
2087 | // printf("pts %d, dvd_spu_backnr = %d, spu_backpts = %d\n",
|
---|
2088 | // (int)pts, (int)ddvd_spu_backnr, (int) spu_backpts[0]);
|
---|
2089 | struct video_event event;
|
---|
2090 | if (!ioctl(ddvd_fdvideo, VIDEO_GET_EVENT, &event))
|
---|
2091 | {
|
---|
2092 | switch(event.type)
|
---|
2093 | {
|
---|
2094 | case VIDEO_EVENT_SIZE_CHANGED:
|
---|
2095 | {
|
---|
2096 | struct ddvd_size_evt evt;
|
---|
2097 | int msg = DDVD_SIZE_CHANGED;
|
---|
2098 | evt.width = event.u.size.w;
|
---|
2099 | evt.height = event.u.size.h;
|
---|
2100 | evt.aspect = event.u.size.aspect_ratio;
|
---|
2101 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2102 | safe_write(message_pipe, &evt, sizeof(evt));
|
---|
2103 | break;
|
---|
2104 | }
|
---|
2105 | case VIDEO_EVENT_FRAME_RATE_CHANGED:
|
---|
2106 | {
|
---|
2107 | struct ddvd_framerate_evt evt;
|
---|
2108 | int msg = DDVD_FRAMERATE_CHANGED;
|
---|
2109 | evt.framerate = event.u.frame_rate;
|
---|
2110 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2111 | safe_write(message_pipe, &evt, sizeof(evt));
|
---|
2112 | break;
|
---|
2113 | }
|
---|
2114 | case 16: // VIDEO_EVENT_PROGRESSIVE_CHANEGD
|
---|
2115 | {
|
---|
2116 | struct ddvd_progressive_evt evt;
|
---|
2117 | int msg = DDVD_PROGRESSIVE_CHANGED;
|
---|
2118 | evt.progressive = event.u.frame_rate;
|
---|
2119 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2120 | safe_write(message_pipe, &evt, sizeof(evt));
|
---|
2121 | break;
|
---|
2122 | }
|
---|
2123 | }
|
---|
2124 | }
|
---|
2125 | #endif
|
---|
2126 | if (ddvd_spu_backnr > 0 && pts >= spu_backpts[0])
|
---|
2127 | #endif
|
---|
2128 | {
|
---|
2129 | int tmplen = (spu_backbuffer[0] << 8 | spu_backbuffer[1]);
|
---|
2130 |
|
---|
2131 | // we dont support overlapping spu timers yet, so we have to clear the screen if there is such a case
|
---|
2132 | int whole_screen = 0;
|
---|
2133 | if (ddvd_spu_timer_active || last_spu_return.display_time < 0)
|
---|
2134 | memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres); //clear screen ..
|
---|
2135 | /* the last subtitle's bbox is still in last_spu_return, so this subtitle will enlarge this bbox. */
|
---|
2136 |
|
---|
2137 | memset(ddvd_lbb, 0, 720 * 576); //clear backbuffer ..
|
---|
2138 | // printf("[SPU] previous bbox: %d %d %d %d\n",
|
---|
2139 | // last_spu_return.x_start, last_spu_return.x_end,
|
---|
2140 | // last_spu_return.y_start, last_spu_return.y_end);
|
---|
2141 | last_spu_return = merge(last_spu_return, ddvd_spu_decode_data(spu_backbuffer, tmplen)); // decode
|
---|
2142 | // printf("[SPU] merged bbox: %d %d %d %d\n",
|
---|
2143 | // last_spu_return.x_start, last_spu_return.x_end,
|
---|
2144 | // last_spu_return.y_start, last_spu_return.y_end);
|
---|
2145 | ddvd_display_time = last_spu_return.display_time;
|
---|
2146 | ddvd_lbb_changed = 1;
|
---|
2147 |
|
---|
2148 | struct ddvd_color colneu;
|
---|
2149 | int ctmp;
|
---|
2150 | msg = DDVD_COLORTABLE_UPDATE;
|
---|
2151 | if (ddvd_screeninfo_bypp == 1)
|
---|
2152 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2153 | for (ctmp = 0; ctmp < 4; ctmp++) {
|
---|
2154 | colneu.blue = ddvd_bl[ctmp + 252];
|
---|
2155 | colneu.green = ddvd_gn[ctmp + 252];
|
---|
2156 | colneu.red = ddvd_rd[ctmp + 252];
|
---|
2157 | colneu.trans = ddvd_tr[ctmp + 252];
|
---|
2158 | if (ddvd_screeninfo_bypp == 1)
|
---|
2159 | safe_write(message_pipe, &colneu, sizeof(struct ddvd_color));
|
---|
2160 | }
|
---|
2161 | msg = DDVD_NULL;
|
---|
2162 |
|
---|
2163 | memcpy(spu_backbuffer, spu_backbuffer + tmplen, ddvd_spu_backptr - tmplen); // delete SPU packet
|
---|
2164 | int i;
|
---|
2165 | for (i = 0; i < NUM_SPU_BACKBUFFER - 1; ++i)
|
---|
2166 | spu_backpts[i] = spu_backpts[i + 1];
|
---|
2167 |
|
---|
2168 | ddvd_spu_backnr--;
|
---|
2169 | ddvd_spu_backptr -= tmplen;
|
---|
2170 |
|
---|
2171 | // printf("[SPU] backnr = %d, backptr = %d\n", ddvd_spu_backnr, ddvd_spu_backptr);
|
---|
2172 |
|
---|
2173 | // set timer
|
---|
2174 | if (ddvd_display_time > 0) {
|
---|
2175 | ddvd_spu_timer_active = 1;
|
---|
2176 | ddvd_spu_timer_end = ddvd_get_time() + (ddvd_display_time * 10); //ms
|
---|
2177 | } else
|
---|
2178 | ddvd_spu_timer_active = 0;
|
---|
2179 |
|
---|
2180 | // dont display SPU if spu sets the HIDE command or the actual SPU track is marked as hide (bit 7) and the packet had no FORCE command
|
---|
2181 | if (last_spu_return.force_hide == SPU_HIDE || ((dvdnav_get_active_spu_stream(dvdnav) & 0x80) && last_spu_return.force_hide != SPU_FORCE && !spu_lock)) {
|
---|
2182 | ddvd_lbb_changed = 0;
|
---|
2183 | ddvd_spu_timer_active = 0;
|
---|
2184 | }
|
---|
2185 |
|
---|
2186 | pci = dvdnav_get_current_nav_pci(dvdnav); //update highlight buttons
|
---|
2187 | dsi = dvdnav_get_current_nav_dsi(dvdnav);
|
---|
2188 | if (pci->hli.hl_gi.btn_ns > 0) {
|
---|
2189 | dvdnav_get_current_highlight(dvdnav, &buttonN);
|
---|
2190 | if (buttonN == 0)
|
---|
2191 | buttonN = 1;
|
---|
2192 | if (buttonN > pci->hli.hl_gi.btn_ns)
|
---|
2193 | buttonN = pci->hli.hl_gi.btn_ns;
|
---|
2194 | dvdnav_button_select(dvdnav, pci, buttonN);
|
---|
2195 | ddvd_lbb_changed = 0;
|
---|
2196 | in_menu = 1;
|
---|
2197 | }
|
---|
2198 | }
|
---|
2199 |
|
---|
2200 | if (!in_menu) {
|
---|
2201 | if (!pci)
|
---|
2202 | pci = dvdnav_get_current_nav_pci(dvdnav);
|
---|
2203 |
|
---|
2204 | in_menu = pci && pci->hli.hl_gi.btn_ns > 0;
|
---|
2205 | }
|
---|
2206 |
|
---|
2207 | if ((dvdnav_is_domain_vmgm(dvdnav) || dvdnav_is_domain_vtsm(dvdnav) || in_menu) && !playerconfig->in_menu) {
|
---|
2208 | int bla = DDVD_MENU_OPENED;
|
---|
2209 | safe_write(message_pipe, &bla, sizeof(int));
|
---|
2210 | playerconfig->in_menu = 1;
|
---|
2211 | } else if (!(dvdnav_is_domain_vmgm(dvdnav) || dvdnav_is_domain_vtsm(dvdnav) || in_menu) && playerconfig->in_menu) {
|
---|
2212 | int bla = DDVD_MENU_CLOSED;
|
---|
2213 | safe_write(message_pipe, &bla, sizeof(int));
|
---|
2214 | playerconfig->in_menu = 0;
|
---|
2215 | }
|
---|
2216 |
|
---|
2217 | if (ddvd_wait_for_user) {
|
---|
2218 | struct pollfd pfd[1]; // make new pollfd array
|
---|
2219 | pfd[0].fd = key_pipe;
|
---|
2220 | pfd[0].events = POLLIN | POLLPRI | POLLERR;
|
---|
2221 | poll(pfd, 1, -1);
|
---|
2222 | }
|
---|
2223 | //Userinput
|
---|
2224 | if (ddvd_readpipe(key_pipe, &rccode, sizeof(int), 0) == sizeof(int)) {
|
---|
2225 | int keydone = 1;
|
---|
2226 |
|
---|
2227 | if (!dsi)
|
---|
2228 | dsi = dvdnav_get_current_nav_dsi(dvdnav);
|
---|
2229 |
|
---|
2230 | if (buttonN == -1)
|
---|
2231 | dvdnav_get_current_highlight(dvdnav, &buttonN);
|
---|
2232 |
|
---|
2233 | switch (rccode) // actions inside and outside of menu
|
---|
2234 | {
|
---|
2235 | case DDVD_SET_MUTE:
|
---|
2236 | ismute = 1;
|
---|
2237 | break;
|
---|
2238 | case DDVD_UNSET_MUTE:
|
---|
2239 | ismute = 0;
|
---|
2240 | break;
|
---|
2241 | default:
|
---|
2242 | keydone = 0;
|
---|
2243 | break;
|
---|
2244 | }
|
---|
2245 |
|
---|
2246 | if (!keydone && in_menu) {
|
---|
2247 | switch (rccode) //Actions inside a Menu
|
---|
2248 | {
|
---|
2249 | case DDVD_KEY_UP: //Up
|
---|
2250 | dvdnav_upper_button_select(dvdnav, pci);
|
---|
2251 | break;
|
---|
2252 | case DDVD_KEY_DOWN: //Down
|
---|
2253 | dvdnav_lower_button_select(dvdnav, pci);
|
---|
2254 | break;
|
---|
2255 | case DDVD_KEY_LEFT: //left
|
---|
2256 | dvdnav_left_button_select(dvdnav, pci);
|
---|
2257 | break;
|
---|
2258 | case DDVD_KEY_RIGHT: //right
|
---|
2259 | dvdnav_right_button_select(dvdnav, pci);
|
---|
2260 | break;
|
---|
2261 | case DDVD_KEY_OK: //OK
|
---|
2262 | ddvd_wait_for_user = 0;
|
---|
2263 | memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres); //clear screen ..
|
---|
2264 | memset(ddvd_lbb, 0, 720 * 576); //clear backbuffer
|
---|
2265 | memset(ddvd_lbb2, 0, 720 * 576 * ddvd_screeninfo_bypp); //clear 2nd backbuffer
|
---|
2266 | blit_area.x_start = blit_area.y_start = 0;
|
---|
2267 | blit_area.x_end = ddvd_screeninfo_xres - 1;
|
---|
2268 | blit_area.y_end = ddvd_screeninfo_yres - 1;
|
---|
2269 | blit_area.x_offset = 0;
|
---|
2270 | blit_area.y_offset = 0;
|
---|
2271 | blit_area.width = ddvd_screeninfo_xres;
|
---|
2272 | blit_area.height = ddvd_screeninfo_yres;
|
---|
2273 | msg = DDVD_SCREEN_UPDATE;
|
---|
2274 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2275 | safe_write(message_pipe, &blit_area, sizeof(struct ddvd_resize_return));
|
---|
2276 |
|
---|
2277 | ddvd_clear_buttons = 1;
|
---|
2278 | dvdnav_button_activate(dvdnav, pci);
|
---|
2279 | ddvd_play_empty(TRUE);
|
---|
2280 | if (ddvd_wait_timer_active)
|
---|
2281 | ddvd_wait_timer_active = 0;
|
---|
2282 | break;
|
---|
2283 | case DDVD_KEY_MENU: //Dream
|
---|
2284 | if (dvdnav_menu_call(dvdnav, DVD_MENU_Root) == DVDNAV_STATUS_OK)
|
---|
2285 | ddvd_play_empty(TRUE);
|
---|
2286 | break;
|
---|
2287 | case DDVD_KEY_AUDIOMENU: //Audio
|
---|
2288 | if (dvdnav_menu_call(dvdnav, DVD_MENU_Audio) == DVDNAV_STATUS_OK)
|
---|
2289 | ddvd_play_empty(TRUE);
|
---|
2290 | break;
|
---|
2291 | case DDVD_KEY_EXIT: //Exit
|
---|
2292 | {
|
---|
2293 | printf("DDVD_KEY_EXIT (menu)\n");
|
---|
2294 | playerconfig->resume_title = 0;
|
---|
2295 | playerconfig->resume_chapter = 0;
|
---|
2296 | playerconfig->resume_block = 0;
|
---|
2297 | playerconfig->resume_audio_id = 0;
|
---|
2298 | playerconfig->resume_audio_lock = 0;
|
---|
2299 | playerconfig->resume_spu_id = 0;
|
---|
2300 | playerconfig->resume_spu_lock = 0;
|
---|
2301 | finished = 1;
|
---|
2302 | }
|
---|
2303 | break;
|
---|
2304 | case DDVD_SKIP_FWD:
|
---|
2305 | case DDVD_SKIP_BWD:
|
---|
2306 | case DDVD_SET_TITLE:
|
---|
2307 | case DDVD_SET_CHAPTER:
|
---|
2308 | // we must empty the pipe here...
|
---|
2309 | ddvd_readpipe(key_pipe, &keydone, sizeof(int), 1);
|
---|
2310 | default:
|
---|
2311 | break;
|
---|
2312 | }
|
---|
2313 | } else if (!keydone) //Actions inside a Movie
|
---|
2314 | {
|
---|
2315 | switch (rccode) //Main Actions
|
---|
2316 | {
|
---|
2317 | case DDVD_KEY_PREV_CHAPTER: //left
|
---|
2318 | {
|
---|
2319 | int titleNo, chapterNumber, chapterNo;
|
---|
2320 | dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
|
---|
2321 | dvdnav_get_number_of_parts(dvdnav, titleNo, &chapterNumber);
|
---|
2322 | chapterNo--;
|
---|
2323 | if (chapterNo > chapterNumber)
|
---|
2324 | chapterNo = 1;
|
---|
2325 | if (chapterNo <= 0)
|
---|
2326 | chapterNo = chapterNumber;
|
---|
2327 | dvdnav_part_play(dvdnav, titleNo, chapterNo);
|
---|
2328 | ddvd_play_empty(TRUE);
|
---|
2329 | msg = DDVD_SHOWOSD_TIME;
|
---|
2330 | break;
|
---|
2331 | }
|
---|
2332 | case DDVD_KEY_NEXT_CHAPTER: //right
|
---|
2333 | {
|
---|
2334 | int titleNo, chapterNumber, chapterNo;
|
---|
2335 | dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
|
---|
2336 | dvdnav_get_number_of_parts(dvdnav, titleNo, &chapterNumber);
|
---|
2337 | chapterNo++;
|
---|
2338 | if (chapterNo > chapterNumber)
|
---|
2339 | chapterNo = 1;
|
---|
2340 | if (chapterNo <= 0)
|
---|
2341 | chapterNo = chapterNumber;
|
---|
2342 | dvdnav_part_play(dvdnav, titleNo, chapterNo);
|
---|
2343 | ddvd_play_empty(TRUE);
|
---|
2344 | msg = DDVD_SHOWOSD_TIME;
|
---|
2345 | break;
|
---|
2346 | }
|
---|
2347 | case DDVD_KEY_PREV_TITLE:
|
---|
2348 | {
|
---|
2349 | int titleNo, titleNumber, chapterNo;
|
---|
2350 | dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
|
---|
2351 | dvdnav_get_number_of_titles(dvdnav, &titleNumber);
|
---|
2352 | titleNo--;
|
---|
2353 | if (titleNo > titleNumber)
|
---|
2354 | titleNo = 1;
|
---|
2355 | if (titleNo <= 0)
|
---|
2356 | titleNo = titleNumber;
|
---|
2357 | dvdnav_part_play(dvdnav, titleNo, 1);
|
---|
2358 | ddvd_play_empty(TRUE);
|
---|
2359 | msg = DDVD_SHOWOSD_TIME;
|
---|
2360 | break;
|
---|
2361 | }
|
---|
2362 | case DDVD_KEY_NEXT_TITLE:
|
---|
2363 | {
|
---|
2364 | int titleNo, titleNumber, chapterNo;
|
---|
2365 | dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
|
---|
2366 | dvdnav_get_number_of_titles(dvdnav, &titleNumber);
|
---|
2367 | titleNo++;
|
---|
2368 | if (titleNo > titleNumber)
|
---|
2369 | titleNo = 1;
|
---|
2370 | if (titleNo <= 0)
|
---|
2371 | titleNo = titleNumber;
|
---|
2372 | dvdnav_part_play(dvdnav, titleNo, 1);
|
---|
2373 | ddvd_play_empty(TRUE);
|
---|
2374 | msg = DDVD_SHOWOSD_TIME;
|
---|
2375 | break;
|
---|
2376 | }
|
---|
2377 | case DDVD_KEY_PAUSE: // Pause
|
---|
2378 | {
|
---|
2379 | if (ddvd_playmode == PLAY) {
|
---|
2380 | ddvd_playmode = PAUSE;
|
---|
2381 | if (ioctl(ddvd_fdaudio, AUDIO_PAUSE) < 0)
|
---|
2382 | perror("AUDIO_PAUSE");
|
---|
2383 | if (ioctl(ddvd_fdvideo, VIDEO_FREEZE) < 0)
|
---|
2384 | perror("VIDEO_FREEZE");
|
---|
2385 | msg = DDVD_SHOWOSD_STATE_PAUSE;
|
---|
2386 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2387 | break;
|
---|
2388 | } else if (ddvd_playmode != PAUSE)
|
---|
2389 | break;
|
---|
2390 | // fall through to PLAY
|
---|
2391 | }
|
---|
2392 | case DDVD_KEY_PLAY: // Play
|
---|
2393 | {
|
---|
2394 | if (ddvd_playmode == PAUSE || ddvd_trickmode) {
|
---|
2395 | ddvd_playmode = PLAY;
|
---|
2396 | key_play:
|
---|
2397 | #if CONFIG_API_VERSION == 1
|
---|
2398 | ddvd_device_clear();
|
---|
2399 | #endif
|
---|
2400 | if (ddvd_trickmode && !ismute)
|
---|
2401 | if (ioctl(ddvd_fdaudio, AUDIO_SET_MUTE, 0) < 0)
|
---|
2402 | perror("AUDIO_SET_MUTE");
|
---|
2403 | ddvd_trickmode = TOFF;
|
---|
2404 | if (ddvd_playmode == PLAY) {
|
---|
2405 | if (ioctl(ddvd_fdaudio, AUDIO_CONTINUE) < 0)
|
---|
2406 | perror("AUDIO_CONTINUE");
|
---|
2407 | if (ioctl(ddvd_fdvideo, VIDEO_CONTINUE) < 0)
|
---|
2408 | perror("VIDEO_CONTINUE");
|
---|
2409 | msg = DDVD_SHOWOSD_STATE_PLAY;
|
---|
2410 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2411 | }
|
---|
2412 | msg = DDVD_SHOWOSD_TIME;
|
---|
2413 | }
|
---|
2414 | break;
|
---|
2415 | }
|
---|
2416 | case DDVD_KEY_MENU: //Dream
|
---|
2417 | if (dvdnav_menu_call(dvdnav, DVD_MENU_Root) == DVDNAV_STATUS_OK)
|
---|
2418 | ddvd_play_empty(TRUE);
|
---|
2419 | break;
|
---|
2420 | case DDVD_KEY_AUDIOMENU: //Audio
|
---|
2421 | if (dvdnav_menu_call(dvdnav, DVD_MENU_Audio) == DVDNAV_STATUS_OK)
|
---|
2422 | ddvd_play_empty(TRUE);
|
---|
2423 | break;
|
---|
2424 | case DDVD_KEY_EXIT: //Exit
|
---|
2425 | {
|
---|
2426 | printf("DDVD_KEY_EXIT (menu)\n");
|
---|
2427 | int resume_title, resume_chapter; //safe resume info
|
---|
2428 | uint32_t resume_block, total_block;
|
---|
2429 | if (dvdnav_current_title_info(dvdnav, &resume_title, &resume_chapter) && (0 != resume_title)) {
|
---|
2430 | if(dvdnav_get_position (dvdnav, &resume_block, &total_block) == DVDNAV_STATUS_OK) {
|
---|
2431 | playerconfig->resume_title = resume_title;
|
---|
2432 | playerconfig->resume_chapter = resume_chapter;
|
---|
2433 | playerconfig->resume_block = resume_block;
|
---|
2434 | playerconfig->resume_audio_id = audio_id;
|
---|
2435 | playerconfig->resume_audio_lock = audio_lock;
|
---|
2436 | playerconfig->resume_spu_id = spu_active_id;
|
---|
2437 | playerconfig->resume_spu_lock = spu_lock;
|
---|
2438 | } else perror("error getting resume position");
|
---|
2439 | } perror("error getting resume position");
|
---|
2440 | finished = 1;
|
---|
2441 | }
|
---|
2442 | break;
|
---|
2443 | case DDVD_KEY_FFWD: //FastForward
|
---|
2444 | case DDVD_KEY_FBWD: //FastBackward
|
---|
2445 | {
|
---|
2446 | if (ddvd_trickmode == TOFF) {
|
---|
2447 | if (ioctl(ddvd_fdaudio, AUDIO_SET_MUTE, 1) < 0)
|
---|
2448 | perror("AUDIO_SET_MUTE");
|
---|
2449 | ddvd_trickspeed = 2;
|
---|
2450 | ddvd_trickmode = (rccode == DDVD_KEY_FBWD ? FASTBW : FASTFW);
|
---|
2451 | } else if (ddvd_trickmode == (rccode == DDVD_KEY_FBWD ? FASTFW : FASTBW)) {
|
---|
2452 | ddvd_trickspeed /= 2;
|
---|
2453 | if (ddvd_trickspeed == 1) {
|
---|
2454 | ddvd_trickspeed = 0;
|
---|
2455 | goto key_play;
|
---|
2456 | }
|
---|
2457 | } else if (ddvd_trickspeed < 64)
|
---|
2458 | ddvd_trickspeed *= 2;
|
---|
2459 | break;
|
---|
2460 | }
|
---|
2461 | case DDVD_KEY_AUDIO: //jump to next audio track
|
---|
2462 | {
|
---|
2463 | int count = 0;
|
---|
2464 | audio_id = (audio_id == MAX_AUDIO-1 ? 0 : audio_id+1);
|
---|
2465 | while (playerconfig->audio_format[audio_id] == -1 && count++ < MAX_AUDIO-1)
|
---|
2466 | {
|
---|
2467 | audio_id = (audio_id == 7 ? 0 : audio_id+1);
|
---|
2468 | }
|
---|
2469 | report_audio_info = 1;
|
---|
2470 | ddvd_play_empty(TRUE);
|
---|
2471 | audio_lock = 1;
|
---|
2472 | ddvd_lpcm_count = 0;
|
---|
2473 | break;
|
---|
2474 | }
|
---|
2475 | case DDVD_SET_AUDIO: //change to given audio track
|
---|
2476 | {
|
---|
2477 | int set_audio_id;
|
---|
2478 | ddvd_readpipe(key_pipe, &set_audio_id, sizeof(int), 1);
|
---|
2479 | printf("DDVD_SET_AUDIO %i (prev %i)\n", set_audio_id, audio_id);
|
---|
2480 | if (set_audio_id < MAX_AUDIO && playerconfig->audio_format[audio_id] != -1)
|
---|
2481 | audio_id = set_audio_id;
|
---|
2482 | report_audio_info = 1;
|
---|
2483 | ddvd_play_empty(TRUE);
|
---|
2484 | audio_lock = 1;
|
---|
2485 | ddvd_lpcm_count = 0;
|
---|
2486 | break;
|
---|
2487 | }
|
---|
2488 | case DDVD_KEY_SUBTITLE: //jump to next spu track
|
---|
2489 | case DDVD_SET_SUBTITLE: //change to given spu track
|
---|
2490 | {
|
---|
2491 | uint16_t spu_lang = 0xFFFF;
|
---|
2492 | int spu_id_logical;
|
---|
2493 | if (rccode == DDVD_KEY_SUBTITLE)
|
---|
2494 | {
|
---|
2495 | int count_tmp;
|
---|
2496 | spu_id_logical = -1;
|
---|
2497 | count_tmp = spu_active_id;
|
---|
2498 | while (count_tmp >= 0)
|
---|
2499 | {
|
---|
2500 | spu_id_logical = playerconfig->spu_map[count_tmp];
|
---|
2501 | if (spu_id_logical >= 0)
|
---|
2502 | count_tmp = 0;
|
---|
2503 | count_tmp--;
|
---|
2504 | }
|
---|
2505 | spu_id_logical++;
|
---|
2506 | spu_active_id = dvdnav_get_spu_logical_stream(dvdnav, spu_id_logical);
|
---|
2507 | }
|
---|
2508 | else if (rccode == DDVD_SET_SUBTITLE)
|
---|
2509 | {
|
---|
2510 | ddvd_readpipe(key_pipe, &spu_id_logical, sizeof(int), 1);
|
---|
2511 | printf("DDVD_SET_SUBTITLE %i (prev %i)\n", spu_id_logical, spu_active_id);
|
---|
2512 | if (spu_id_logical < MAX_SPU && playerconfig->spu_map[spu_id_logical] > -1)
|
---|
2513 | spu_active_id = dvdnav_get_spu_logical_stream(dvdnav, spu_id_logical);
|
---|
2514 | }
|
---|
2515 | spu_lang = dvdnav_spu_stream_to_lang(dvdnav, (spu_id_logical >= 0 ? spu_id_logical : spu_active_id) & 0x1F);
|
---|
2516 | if (spu_lang == 0xFFFF) {
|
---|
2517 | spu_lang = 0x2D2D; // SPU "off"
|
---|
2518 | spu_active_id = -1;
|
---|
2519 | spu_id_logical = -1;
|
---|
2520 | }
|
---|
2521 | spu_lock = 1;
|
---|
2522 | msg = DDVD_SHOWOSD_SUBTITLE;
|
---|
2523 | int report_spu = spu_id_logical > 31 ? -1 : spu_id_logical;
|
---|
2524 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2525 | safe_write(message_pipe, &report_spu, sizeof(int));
|
---|
2526 | safe_write(message_pipe, &spu_lang, sizeof(uint16_t));
|
---|
2527 | break;
|
---|
2528 | }
|
---|
2529 | case DDVD_KEY_ANGLE: //change angle
|
---|
2530 | {
|
---|
2531 | int num = 0, current = 0;
|
---|
2532 | dvdnav_get_angle_info(dvdnav, ¤t, &num);
|
---|
2533 | if(num != 0) {
|
---|
2534 | current++;
|
---|
2535 | if(current > num)
|
---|
2536 | current = 1;
|
---|
2537 | }
|
---|
2538 | dvdnav_angle_change(dvdnav, current);
|
---|
2539 | msg = DDVD_SHOWOSD_ANGLE;
|
---|
2540 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2541 | safe_write(message_pipe, ¤t, sizeof(int));
|
---|
2542 | safe_write(message_pipe, &num, sizeof(int));
|
---|
2543 | break;
|
---|
2544 | }
|
---|
2545 | case DDVD_GET_ANGLE: //frontend wants angle info
|
---|
2546 | {
|
---|
2547 | int num = 0, current = 0;
|
---|
2548 | dvdnav_get_angle_info(dvdnav, ¤t, &num);
|
---|
2549 | msg = DDVD_SHOWOSD_ANGLE;
|
---|
2550 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2551 | safe_write(message_pipe, ¤t, sizeof(int));
|
---|
2552 | safe_write(message_pipe, &num, sizeof(int));
|
---|
2553 | break;
|
---|
2554 | }
|
---|
2555 | case DDVD_GET_TIME: // frontend wants actual time
|
---|
2556 | msg = DDVD_SHOWOSD_TIME;
|
---|
2557 | break;
|
---|
2558 | case DDVD_SKIP_FWD:
|
---|
2559 | case DDVD_SKIP_BWD:
|
---|
2560 | {
|
---|
2561 | int skip;
|
---|
2562 | ddvd_readpipe(key_pipe, &skip, sizeof(int), 1);
|
---|
2563 | if (ddvd_trickmode == TOFF) {
|
---|
2564 | uint32_t pos, len;
|
---|
2565 | dvdnav_get_position(dvdnav, &pos, &len);
|
---|
2566 | printf("DDVD_SKIP pos=%u len=%u \n", pos, len);
|
---|
2567 | //90000 = 1 Sek.
|
---|
2568 | if (!len)
|
---|
2569 | len = 1;
|
---|
2570 | long long int posneu = ((pos * ddvd_lastCellEventInfo.pgc_length) / len) + (90000 * skip);
|
---|
2571 | printf("DDVD_SKIP posneu1=%lld\n", posneu);
|
---|
2572 | long long int posneu2 = posneu <= 0 ? 0 : (posneu * len) / ddvd_lastCellEventInfo.pgc_length;
|
---|
2573 | printf("DDVD_SKIP posneu2=%lld\n", posneu2);
|
---|
2574 | if (len && posneu2 && posneu2 >= len) // reached end of movie
|
---|
2575 | {
|
---|
2576 | posneu2 = len - 250;
|
---|
2577 | reached_eof = 1;
|
---|
2578 | }
|
---|
2579 | dvdnav_sector_search(dvdnav, posneu2, SEEK_SET);
|
---|
2580 | ddvd_lpcm_count = 0;
|
---|
2581 | msg = DDVD_SHOWOSD_TIME;
|
---|
2582 | }
|
---|
2583 | break;
|
---|
2584 | }
|
---|
2585 | case DDVD_SET_TITLE:
|
---|
2586 | {
|
---|
2587 | int title, totalTitles;
|
---|
2588 | ddvd_readpipe(key_pipe, &title, sizeof(int), 1);
|
---|
2589 | dvdnav_get_number_of_titles(dvdnav, &totalTitles);
|
---|
2590 | printf("DDVD_SET_TITLE %d/%d\n", title, totalTitles);
|
---|
2591 | if (title <= totalTitles) {
|
---|
2592 | dvdnav_part_play(dvdnav, title, 0);
|
---|
2593 | ddvd_play_empty(TRUE);
|
---|
2594 | msg = DDVD_SHOWOSD_TIME;
|
---|
2595 | }
|
---|
2596 | break;
|
---|
2597 | }
|
---|
2598 | case DDVD_SET_CHAPTER:
|
---|
2599 | {
|
---|
2600 | int chapter, totalChapters, chapterNo, titleNo;
|
---|
2601 | ddvd_readpipe(key_pipe, &chapter, sizeof(int), 1);
|
---|
2602 | dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
|
---|
2603 | dvdnav_get_number_of_parts(dvdnav, titleNo, &totalChapters);
|
---|
2604 | printf("DDVD_SET_CHAPTER %d/%d in title %d\n", chapter, totalChapters, titleNo);
|
---|
2605 | if (chapter <= totalChapters) {
|
---|
2606 | dvdnav_part_play(dvdnav, titleNo, chapter);
|
---|
2607 | ddvd_play_empty(TRUE);
|
---|
2608 | msg = DDVD_SHOWOSD_TIME;
|
---|
2609 | }
|
---|
2610 | break;
|
---|
2611 | }
|
---|
2612 | default:
|
---|
2613 | break;
|
---|
2614 | }
|
---|
2615 | }
|
---|
2616 | }
|
---|
2617 | // spu handling
|
---|
2618 | if (ddvd_lbb_changed == 1) {
|
---|
2619 |
|
---|
2620 | if (ddvd_screeninfo_bypp == 1)
|
---|
2621 | memcpy(ddvd_lbb2, ddvd_lbb, 720 * 576);
|
---|
2622 | else {
|
---|
2623 | int i = 0;
|
---|
2624 | for (i = last_spu_return.y_start; i < last_spu_return.y_end; ++i)
|
---|
2625 | ddvd_blit_to_argb(ddvd_lbb2 + (i * 720 + last_spu_return.x_start) * ddvd_screeninfo_bypp, ddvd_lbb + i * 720 + last_spu_return.x_start, last_spu_return.x_end - last_spu_return.x_start);
|
---|
2626 | }
|
---|
2627 | //struct ddvd_resize_return blit_area;
|
---|
2628 | blit_area.x_start = last_spu_return.x_start;
|
---|
2629 | blit_area.x_end = last_spu_return.x_end;
|
---|
2630 | blit_area.y_start = last_spu_return.y_start;
|
---|
2631 | blit_area.y_end = last_spu_return.y_end;
|
---|
2632 | if (!ddvd_spu_timer_active)
|
---|
2633 | {
|
---|
2634 | /* in case this is the last action for this subtitle's bbox (i.e. no timer has been set), then we will clear the bbox.
|
---|
2635 | otherwise, we will leave it there, so it will be contained in the next update as well. */
|
---|
2636 | last_spu_return.x_start = last_spu_return.x_end = 0;
|
---|
2637 | last_spu_return.y_start = last_spu_return.y_end = 0;
|
---|
2638 | }
|
---|
2639 |
|
---|
2640 | int y_source = ddvd_have_ntsc ? 480 : 576; // correct ntsc overlay
|
---|
2641 | int x_offset = calc_x_scale_offset(dvd_aspect, tv_mode, tv_mode2, tv_aspect);
|
---|
2642 | int y_offset = calc_y_scale_offset(dvd_aspect, tv_mode, tv_mode2, tv_aspect);
|
---|
2643 |
|
---|
2644 | uint64_t start=ddvd_get_time();
|
---|
2645 | int resized = 0;
|
---|
2646 | if ((x_offset != 0 || y_offset != 0 || y_source != ddvd_screeninfo_yres || ddvd_screeninfo_xres != 720) && !playerconfig->canscale)
|
---|
2647 | {
|
---|
2648 | // printf("resizing.. (x=%d y=%d %d %d, %d)\n", x_offset, y_offset, y_source, ddvd_screeninfo_yres, ddvd_screeninfo_xres );
|
---|
2649 | blit_area = ddvd_resize_pixmap_spu(ddvd_lbb2, 720, y_source, ddvd_screeninfo_xres, ddvd_screeninfo_yres, x_offset, y_offset, blit_area.x_start, blit_area.x_end, blit_area.y_start, blit_area.y_end, ddvd_screeninfo_bypp); // resize
|
---|
2650 | resized = 1;
|
---|
2651 | }
|
---|
2652 | memcpy(p_lfb, ddvd_lbb2, ddvd_screeninfo_xres * ddvd_screeninfo_yres * ddvd_screeninfo_bypp); //copy backbuffer into screen
|
---|
2653 |
|
---|
2654 | if (resized)
|
---|
2655 | {
|
---|
2656 | blit_area.x_offset = 0;
|
---|
2657 | blit_area.y_offset = 0;
|
---|
2658 | blit_area.width = 720;
|
---|
2659 | blit_area.height = 576;
|
---|
2660 | } else
|
---|
2661 | {
|
---|
2662 | blit_area.x_offset = x_offset;
|
---|
2663 | blit_area.y_offset = y_offset;
|
---|
2664 | blit_area.width = ddvd_screeninfo_xres;
|
---|
2665 | blit_area.height = ddvd_screeninfo_yres;
|
---|
2666 | }
|
---|
2667 |
|
---|
2668 | //printf("needed time for resizing: %d ms\n",(int)(ddvd_get_time()-start));
|
---|
2669 | //printf("destination area to blit: %d %d %d %d Time: %d\n",blit_area.x_start,blit_area.x_end,blit_area.y_start,blit_area.y_end,last_spu_return.display_time);
|
---|
2670 | int msg_old = msg; // save and restore msg it may not be empty
|
---|
2671 | msg = DDVD_SCREEN_UPDATE;
|
---|
2672 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2673 | safe_write(message_pipe, &blit_area, sizeof(struct ddvd_resize_return));
|
---|
2674 |
|
---|
2675 | msg = msg_old;
|
---|
2676 | ddvd_lbb_changed = 0;
|
---|
2677 | }
|
---|
2678 | // report audio info
|
---|
2679 | if (report_audio_info) {
|
---|
2680 | if (playerconfig->audio_format[audio_id] > -1) {
|
---|
2681 | uint16_t audio_lang = 0xFFFF;
|
---|
2682 | int audio_id_logical;
|
---|
2683 | audio_id_logical = dvdnav_get_audio_logical_stream(dvdnav, audio_id);
|
---|
2684 | audio_lang = dvdnav_audio_stream_to_lang(dvdnav, audio_id_logical);
|
---|
2685 | if (audio_lang == 0xFFFF)
|
---|
2686 | audio_lang = 0x2D2D;
|
---|
2687 | int msg_old = msg; // save and restore msg it may not bee empty
|
---|
2688 | msg = DDVD_SHOWOSD_AUDIO;
|
---|
2689 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2690 | safe_write(message_pipe, &audio_id, sizeof(int));
|
---|
2691 | safe_write(message_pipe, &audio_lang, sizeof(uint16_t));
|
---|
2692 | safe_write(message_pipe, &playerconfig->audio_format[audio_id], sizeof(int));
|
---|
2693 | msg = msg_old;
|
---|
2694 | report_audio_info = 0;
|
---|
2695 | }
|
---|
2696 | }
|
---|
2697 | }
|
---|
2698 |
|
---|
2699 | err_dvdnav:
|
---|
2700 | /* destroy dvdnav handle */
|
---|
2701 | if (dvdnav_close(dvdnav) != DVDNAV_STATUS_OK)
|
---|
2702 | printf("Error on dvdnav_close: %s\n", dvdnav_err_to_string(dvdnav));
|
---|
2703 |
|
---|
2704 | err_dvdnav_open:
|
---|
2705 | if (ioctl(ddvd_fdvideo, VIDEO_CLEAR_BUFFER) < 0)
|
---|
2706 | perror("VIDEO_CLEAR_BUFFER");
|
---|
2707 | if (ioctl(ddvd_fdvideo, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
|
---|
2708 | perror("VIDEO_SELECT_SOURCE");
|
---|
2709 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
2710 | perror("AUDIO_CLEAR_BUFFER");
|
---|
2711 | if (ioctl(ddvd_fdaudio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX) < 0)
|
---|
2712 | perror("AUDIO_SELECT_SOURCE");
|
---|
2713 | if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0) // restore AudioDecoder State
|
---|
2714 | perror("AUDIO_SET_AV_SYNC");
|
---|
2715 | close(ddvd_ac3_fd);
|
---|
2716 | err_open_ac3_fd:
|
---|
2717 | close(ddvd_fdaudio);
|
---|
2718 | err_open_fdaudio:
|
---|
2719 | close(ddvd_fdvideo);
|
---|
2720 | err_open_fdvideo:
|
---|
2721 | close(ddvd_output_fd);
|
---|
2722 | err_open_output_fd:
|
---|
2723 |
|
---|
2724 | #if defined(__sh__)
|
---|
2725 | #else
|
---|
2726 | if (have_liba52) {
|
---|
2727 | a52_free(state);
|
---|
2728 | ddvd_close_liba52();
|
---|
2729 | }
|
---|
2730 | #endif
|
---|
2731 |
|
---|
2732 | //Clear Screen
|
---|
2733 | //struct ddvd_resize_return blit_area;
|
---|
2734 | blit_area.x_start = blit_area.y_start = 0;
|
---|
2735 | blit_area.x_end = ddvd_screeninfo_xres - 1;
|
---|
2736 | blit_area.y_end = ddvd_screeninfo_yres - 1;
|
---|
2737 | blit_area.x_offset = 0;
|
---|
2738 | blit_area.y_offset = 0;
|
---|
2739 | blit_area.width = ddvd_screeninfo_xres;
|
---|
2740 | blit_area.height = ddvd_screeninfo_yres;
|
---|
2741 | memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres);
|
---|
2742 | msg = DDVD_SCREEN_UPDATE;
|
---|
2743 | safe_write(message_pipe, &msg, sizeof(int));
|
---|
2744 | safe_write(message_pipe, &blit_area, sizeof(struct ddvd_resize_return));
|
---|
2745 |
|
---|
2746 | err_malloc:
|
---|
2747 | // clean up
|
---|
2748 | if (ddvd_lbb != NULL)
|
---|
2749 | free(ddvd_lbb);
|
---|
2750 | if (ddvd_lbb2 != NULL)
|
---|
2751 | free(ddvd_lbb2);
|
---|
2752 | if (last_iframe != NULL)
|
---|
2753 | free(last_iframe);
|
---|
2754 | if (spu_buffer != NULL)
|
---|
2755 | free(spu_buffer);
|
---|
2756 | if (spu_backbuffer != NULL)
|
---|
2757 | free(spu_backbuffer);
|
---|
2758 |
|
---|
2759 | #if CONFIG_API_VERSION == 3
|
---|
2760 | ddvd_unset_pcr_offset();
|
---|
2761 | #endif
|
---|
2762 | return res;
|
---|
2763 | }
|
---|
2764 |
|
---|
2765 | /*
|
---|
2766 | * internal functions
|
---|
2767 | */
|
---|
2768 |
|
---|
2769 | // reading from pipe
|
---|
2770 | static int ddvd_readpipe(int pipefd, void *dest, size_t bytes, int blocked_read)
|
---|
2771 | {
|
---|
2772 | size_t bytes_completed = 0;
|
---|
2773 |
|
---|
2774 | while (bytes_completed < bytes) {
|
---|
2775 | ssize_t rd = read(pipefd, dest + bytes_completed, bytes - bytes_completed);
|
---|
2776 | if (rd < 0) {
|
---|
2777 | if (errno == EAGAIN) {
|
---|
2778 | if (blocked_read || bytes_completed) {
|
---|
2779 | usleep(1);
|
---|
2780 | continue;
|
---|
2781 | }
|
---|
2782 | break; // leave while loop
|
---|
2783 | }
|
---|
2784 | /* else if (errno == ????) // hier sollte evtl noch geschaut werden welcher error code kommt wenn die pipe geschlossen wurde...
|
---|
2785 | break; */
|
---|
2786 | printf("unhandled read error %d(%m)\n", errno);
|
---|
2787 | }
|
---|
2788 |
|
---|
2789 | bytes_completed += rd;
|
---|
2790 | if (!blocked_read && !bytes_completed)
|
---|
2791 | break;
|
---|
2792 | }
|
---|
2793 |
|
---|
2794 | return bytes_completed;
|
---|
2795 | }
|
---|
2796 |
|
---|
2797 | // get actual playing time
|
---|
2798 | static struct ddvd_time ddvd_get_osd_time(struct ddvd *playerconfig)
|
---|
2799 | {
|
---|
2800 | int titleNo;
|
---|
2801 | struct ddvd_time info;
|
---|
2802 | uint32_t pos, len;
|
---|
2803 |
|
---|
2804 | info.pos_minutes = info.pos_hours = info.pos_seconds = info.pos_chapter = info.pos_title = 0;
|
---|
2805 | info.end_minutes = info.end_hours = info.end_seconds = info.end_chapter = 0;
|
---|
2806 |
|
---|
2807 | dvdnav_get_number_of_titles(dvdnav, &info.end_title);
|
---|
2808 | dvdnav_current_title_info(dvdnav, &titleNo, &info.pos_chapter);
|
---|
2809 |
|
---|
2810 | if (titleNo) {
|
---|
2811 | dvdnav_get_number_of_parts(dvdnav, titleNo, &info.end_chapter);
|
---|
2812 | dvdnav_get_position_in_title(dvdnav, &pos, &len);
|
---|
2813 |
|
---|
2814 | uint64_t len_s = ddvd_lastCellEventInfo.pgc_length / 90000;
|
---|
2815 | uint64_t pos_s = ((ddvd_lastCellEventInfo.pgc_length / len) * pos) / 90000;
|
---|
2816 |
|
---|
2817 | info.pos_minutes = pos_s / 60;
|
---|
2818 | info.pos_hours = info.pos_minutes / 60;
|
---|
2819 | info.pos_minutes = info.pos_minutes - (info.pos_hours * 60);
|
---|
2820 | info.pos_seconds = pos_s - ((info.pos_hours * 60) + info.pos_minutes) * 60;
|
---|
2821 | info.end_minutes = len_s / 60;
|
---|
2822 | info.end_hours = info.end_minutes / 60;
|
---|
2823 | info.end_minutes = info.end_minutes - (info.end_hours * 60);
|
---|
2824 | info.end_seconds = len_s - ((info.end_hours * 60) + info.end_minutes) * 60;
|
---|
2825 |
|
---|
2826 | info.pos_title = titleNo;
|
---|
2827 | }
|
---|
2828 |
|
---|
2829 | playerconfig->next_time_update = ddvd_get_time() + 1000;
|
---|
2830 |
|
---|
2831 | return info;
|
---|
2832 | }
|
---|
2833 |
|
---|
2834 | // video out aspect/scale
|
---|
2835 | static int ddvd_check_aspect(int dvd_aspect, int dvd_scale_perm, int tv_aspect, int tv_mode)
|
---|
2836 | {
|
---|
2837 | int tv_scale = 0; // widescreen spu
|
---|
2838 |
|
---|
2839 | if (dvd_aspect == 0) // dvd 4:3
|
---|
2840 | {
|
---|
2841 | if((tv_aspect == DDVD_16_9 || tv_aspect == DDVD_16_10) && (tv_mode == DDVD_PAN_SCAN || tv_mode == DDVD_LETTERBOX))
|
---|
2842 | tv_scale = 2; // pan_scan spu
|
---|
2843 | if (tv_aspect == DDVD_4_3 && tv_mode == DDVD_PAN_SCAN)
|
---|
2844 | tv_scale = 2; // pan_scan spu
|
---|
2845 | if (tv_aspect == DDVD_4_3 && tv_mode == DDVD_LETTERBOX)
|
---|
2846 | tv_scale = 1; // letterbox spu
|
---|
2847 | }
|
---|
2848 |
|
---|
2849 | return tv_scale;
|
---|
2850 | }
|
---|
2851 |
|
---|
2852 | // get timestamp
|
---|
2853 | static uint64_t ddvd_get_time(void)
|
---|
2854 | {
|
---|
2855 | static time_t t0 = 0;
|
---|
2856 | struct timeval t;
|
---|
2857 |
|
---|
2858 | if (gettimeofday(&t, NULL) == 0) {
|
---|
2859 | if (t0 == 0)
|
---|
2860 | t0 = t.tv_sec; // this avoids an overflow (we only work with deltas)
|
---|
2861 | return (uint64_t) (t.tv_sec - t0) * 1000 + (uint64_t) (t.tv_usec / 1000);
|
---|
2862 | }
|
---|
2863 |
|
---|
2864 | return 0;
|
---|
2865 | }
|
---|
2866 |
|
---|
2867 | // Empty all Buffers
|
---|
2868 | static void ddvd_play_empty(int device_clear)
|
---|
2869 | {
|
---|
2870 | ddvd_wait_for_user = 0;
|
---|
2871 | ddvd_clear_buttons = 0;
|
---|
2872 | ddvd_lpcm_count = 0;
|
---|
2873 | ddvd_iframerun = 0;
|
---|
2874 | ddvd_still_frame = 0;
|
---|
2875 | ddvd_iframesend = 0;
|
---|
2876 | ddvd_last_iframe_len = 0;
|
---|
2877 | ddvd_spu_ptr = 0;
|
---|
2878 | ddvd_spu_backnr = 0;
|
---|
2879 | ddvd_spu_backptr = 0;
|
---|
2880 |
|
---|
2881 | ddvd_wait_timer_active = 0;
|
---|
2882 | ddvd_wait_timer_end = 0;
|
---|
2883 |
|
---|
2884 | ddvd_spu_timer_active = 0;
|
---|
2885 | ddvd_spu_timer_end = 0;
|
---|
2886 |
|
---|
2887 | memset(ddvd_lbb, 0, 720 * 576); //clear backbuffer
|
---|
2888 | ddvd_lbb_changed = 1;
|
---|
2889 |
|
---|
2890 | if (device_clear)
|
---|
2891 | ddvd_device_clear();
|
---|
2892 | }
|
---|
2893 |
|
---|
2894 | // Empty Device Buffers
|
---|
2895 | static void ddvd_device_clear(void)
|
---|
2896 | {
|
---|
2897 | if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
|
---|
2898 | perror("AUDIO_CLEAR_BUFFER");
|
---|
2899 | if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
|
---|
2900 | perror("AUDIO_PLAY");
|
---|
2901 |
|
---|
2902 | if (ioctl(ddvd_fdvideo, VIDEO_CLEAR_BUFFER) < 0)
|
---|
2903 | perror("VIDEO_CLEAR_BUFFER");
|
---|
2904 | if (ioctl(ddvd_fdvideo, VIDEO_PLAY) < 0)
|
---|
2905 | perror("VIDEO_PLAY");
|
---|
2906 |
|
---|
2907 | if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
|
---|
2908 | perror("AUDIO_SET_AV_SYNC");
|
---|
2909 | }
|
---|
2910 |
|
---|
2911 | // SPU Decoder
|
---|
2912 | static struct ddvd_spu_return ddvd_spu_decode_data(const uint8_t * buffer, int len)
|
---|
2913 | {
|
---|
2914 | int x1spu, x2spu, y1spu, y2spu, xspu, yspu;
|
---|
2915 | int offset[2], param_len;
|
---|
2916 | int size, datasize, controlsize, aligned, id;
|
---|
2917 | int menubutton = 0;
|
---|
2918 | int display_time = -1;
|
---|
2919 | int force_hide = SPU_NOP;
|
---|
2920 |
|
---|
2921 | size = (buffer[0] << 8 | buffer[1]);
|
---|
2922 | datasize = (buffer[2] << 8 | buffer[3]);
|
---|
2923 | controlsize = (buffer[datasize + 2] << 8 | buffer[datasize + 3]);
|
---|
2924 |
|
---|
2925 | //printf("SPU_dec: Size: %X Datasize: %X Controlsize: %X\n",size,datasize,controlsize);
|
---|
2926 | // parse header
|
---|
2927 | int i = datasize + 4;
|
---|
2928 |
|
---|
2929 | while (i < size && buffer[i] != 0xFF) {
|
---|
2930 | switch (buffer[i]) {
|
---|
2931 | case 0x00: /* force */
|
---|
2932 | force_hide = SPU_FORCE;
|
---|
2933 | i++;
|
---|
2934 | break;
|
---|
2935 | case 0x01: /* show */
|
---|
2936 | force_hide = SPU_SHOW;
|
---|
2937 | i++;
|
---|
2938 | break;
|
---|
2939 | case 0x02: /* hide */
|
---|
2940 | force_hide = SPU_HIDE;
|
---|
2941 | i++;
|
---|
2942 | break;
|
---|
2943 | case 0x03: /* palette */
|
---|
2944 | {
|
---|
2945 | ddvd_spudec_clut_t *clut = (ddvd_spudec_clut_t *) (buffer + i + 1);
|
---|
2946 | //printf("update palette %d %d %d %d\n", clut->entry0, clut->entry1, clut->entry2, clut->entry3);
|
---|
2947 |
|
---|
2948 | ddvd_bl[3 + 252] = ddvd_bl[clut->entry0];
|
---|
2949 | ddvd_gn[3 + 252] = ddvd_gn[clut->entry0];
|
---|
2950 | ddvd_rd[3 + 252] = ddvd_rd[clut->entry0];
|
---|
2951 |
|
---|
2952 | ddvd_bl[2 + 252] = ddvd_bl[clut->entry1];
|
---|
2953 | ddvd_gn[2 + 252] = ddvd_gn[clut->entry1];
|
---|
2954 | ddvd_rd[2 + 252] = ddvd_rd[clut->entry1];
|
---|
2955 |
|
---|
2956 | ddvd_bl[1 + 252] = ddvd_bl[clut->entry2];
|
---|
2957 | ddvd_gn[1 + 252] = ddvd_gn[clut->entry2];
|
---|
2958 | ddvd_rd[1 + 252] = ddvd_rd[clut->entry2];
|
---|
2959 |
|
---|
2960 | ddvd_bl[0 + 252] = ddvd_bl[clut->entry3];
|
---|
2961 | ddvd_gn[0 + 252] = ddvd_gn[clut->entry3];
|
---|
2962 | ddvd_rd[0 + 252] = ddvd_rd[clut->entry3];
|
---|
2963 |
|
---|
2964 | //CHANGE COLORMAP
|
---|
2965 | i += 3;
|
---|
2966 | }
|
---|
2967 | break;
|
---|
2968 | case 0x04: /* transparency palette */
|
---|
2969 | {
|
---|
2970 | ddvd_spudec_clut_t *clut = (ddvd_spudec_clut_t *) (buffer + i + 1);
|
---|
2971 | //printf("update transp palette %d %d %d %d\n", clut->entry0, clut->entry1, clut->entry2, clut->entry3);
|
---|
2972 |
|
---|
2973 | ddvd_tr[0 + 252] = (0xF - clut->entry3) * 0x1111;
|
---|
2974 | ddvd_tr[1 + 252] = (0xF - clut->entry2) * 0x1111;
|
---|
2975 | ddvd_tr[2 + 252] = (0xF - clut->entry1) * 0x1111;
|
---|
2976 | ddvd_tr[3 + 252] = (0xF - clut->entry0) * 0x1111;
|
---|
2977 |
|
---|
2978 | //CHANGE COLORMAP
|
---|
2979 | i += 3;
|
---|
2980 | }
|
---|
2981 | break;
|
---|
2982 | case 0x05: /* image coordinates */
|
---|
2983 | //printf("image coords\n");
|
---|
2984 | xspu = x1spu = (((unsigned int)buffer[i + 1]) << 4) + (buffer[i + 2] >> 4);
|
---|
2985 | yspu = y1spu = (((unsigned int)buffer[i + 4]) << 4) + (buffer[i + 5] >> 4);
|
---|
2986 | x2spu = (((buffer[i + 2] & 0x0f) << 8) + buffer[i + 3]);
|
---|
2987 | y2spu = (((buffer[i + 5] & 0x0f) << 8) + buffer[i + 6]);
|
---|
2988 | //printf("%d %d %d %d\n", xspu, yspu, x2spu, y2spu);
|
---|
2989 | i += 7;
|
---|
2990 | break;
|
---|
2991 | case 0x06: /* image 1 / image 2 offsets */
|
---|
2992 | //printf("image offsets\n");
|
---|
2993 | offset[0] = (((unsigned int)buffer[i + 1]) << 8) + buffer[i + 2];
|
---|
2994 | offset[1] = (((unsigned int)buffer[i + 3]) << 8) + buffer[i + 4];
|
---|
2995 | //printf("%d %d\n", offset[0], offset[1]);
|
---|
2996 | i += 5;
|
---|
2997 | break;
|
---|
2998 | case 0x07: /* change color for a special area so overlays with more than 4 colors are possible - NOT IMPLEMENTET YET */
|
---|
2999 | //printf("change color packet\n");
|
---|
3000 | param_len = (buffer[i + 1] << 8 | buffer[i + 2]);
|
---|
3001 | i += param_len + 1;
|
---|
3002 | break;
|
---|
3003 | default:
|
---|
3004 | i++;
|
---|
3005 | break;
|
---|
3006 | }
|
---|
3007 | }
|
---|
3008 |
|
---|
3009 | //get display time
|
---|
3010 | if (i + 6 <= size) {
|
---|
3011 | if (buffer[i + 5] == 0x02 && buffer[i + 6] == 0xFF) {
|
---|
3012 | display_time = ((buffer[i + 1] << 8) + buffer[i + 2]);
|
---|
3013 | //printf("Display Time: %d\n",ddvd_display_time);
|
---|
3014 | }
|
---|
3015 | }
|
---|
3016 | //printf("SPU_dec: Image coords x1: %d y1: %d x2: %d y2: %d\n",x1spu,y1spu,x2spu,y2spu);
|
---|
3017 | //printf("Offset[0]: %X Offset[1]: %X\n",offset[0],offset[1]);
|
---|
3018 |
|
---|
3019 | // parse picture
|
---|
3020 |
|
---|
3021 | aligned = 1;
|
---|
3022 | id = 0;
|
---|
3023 |
|
---|
3024 | while (offset[1] < datasize + 2 && yspu <= 575) // there are some special cases the decoder tries to write more than 576 lines in our buffer and we dont want this ;)
|
---|
3025 | {
|
---|
3026 | u_int len;
|
---|
3027 | u_int code;
|
---|
3028 |
|
---|
3029 | code = (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
|
---|
3030 | aligned = aligned ? 0 : 1;
|
---|
3031 |
|
---|
3032 | if (code < 0x0004) {
|
---|
3033 | code = (code << 4) | (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
|
---|
3034 | aligned = aligned ? 0 : 1;
|
---|
3035 | if (code < 0x0010) {
|
---|
3036 | code = (code << 4) | (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
|
---|
3037 | aligned = aligned ? 0 : 1;
|
---|
3038 | if (code < 0x0040) {
|
---|
3039 | code = (code << 4) | (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
|
---|
3040 | aligned = aligned ? 0 : 1;
|
---|
3041 | }
|
---|
3042 | }
|
---|
3043 | }
|
---|
3044 |
|
---|
3045 | len = code >> 2;
|
---|
3046 |
|
---|
3047 | if (len == 0)
|
---|
3048 | len = (x2spu - xspu) + 1;
|
---|
3049 |
|
---|
3050 | memset(ddvd_lbb + xspu + 720 * (yspu), (code & 3) + 252, len); //drawpixel into backbuffer
|
---|
3051 | xspu += len;
|
---|
3052 | if (xspu > x2spu) {
|
---|
3053 | if (!aligned) {
|
---|
3054 | code = (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
|
---|
3055 | aligned = aligned ? 0 : 1;
|
---|
3056 | }
|
---|
3057 | xspu = x1spu; //next line
|
---|
3058 | yspu++;
|
---|
3059 | id = id ? 0 : 1;
|
---|
3060 | }
|
---|
3061 | }
|
---|
3062 | struct ddvd_spu_return return_code;
|
---|
3063 | return_code.display_time = display_time;
|
---|
3064 | return_code.x_start = x1spu;
|
---|
3065 | return_code.x_end = x2spu;
|
---|
3066 | return_code.y_start = y1spu;
|
---|
3067 | return_code.y_end = y2spu;
|
---|
3068 | return_code.force_hide = force_hide;
|
---|
3069 |
|
---|
3070 | return return_code;
|
---|
3071 | }
|
---|
3072 |
|
---|
3073 | // blit to argb in 32bit mode
|
---|
3074 | #ifdef __sh__
|
---|
3075 | #define alpha_composite(composite, fg, alpha, bg) { \
|
---|
3076 | unsigned short temp = ((unsigned short)(fg)*(unsigned short)(alpha) + \
|
---|
3077 | (unsigned short)(bg)*(unsigned short)(255 - (unsigned short)(alpha)) + \
|
---|
3078 | (unsigned short)128); \
|
---|
3079 | (composite) = (unsigned char)((temp + (temp >> 8)) >> 8); \
|
---|
3080 | }
|
---|
3081 | #endif
|
---|
3082 | static void ddvd_blit_to_argb(void *_dst, const void *_src, int pix)
|
---|
3083 | {
|
---|
3084 | unsigned long *dst = _dst;
|
---|
3085 | const unsigned char *src = _src;
|
---|
3086 | while (pix--) {
|
---|
3087 | int p = (*src++);
|
---|
3088 | int a, r, g, b;
|
---|
3089 | #ifdef __sh__
|
---|
3090 | int r1, g1, b1;
|
---|
3091 | #endif
|
---|
3092 | if (p == 0) {
|
---|
3093 | r = g = b = a = 0; //clear screen (transparency)
|
---|
3094 | } else {
|
---|
3095 | #ifdef __sh__
|
---|
3096 | a = 0xFF - (ddvd_tr[p] >> 8);
|
---|
3097 | r1 = ddvd_rd[p] >> 8;
|
---|
3098 | g1 = ddvd_gn[p] >> 8;
|
---|
3099 | b1 = ddvd_bl[p] >> 8;
|
---|
3100 | alpha_composite(r, r1, a, 0);
|
---|
3101 | alpha_composite(g, g1, a, 0);
|
---|
3102 | alpha_composite(b, b1, a, 0);
|
---|
3103 | #else
|
---|
3104 | a = 0xFF - (ddvd_tr[p] >> 8);
|
---|
3105 | r = ddvd_rd[p] >> 8;
|
---|
3106 | g = ddvd_gn[p] >> 8;
|
---|
3107 | b = ddvd_bl[p] >> 8;
|
---|
3108 | #endif
|
---|
3109 | }
|
---|
3110 | *dst++ = (a << 24) | (r << 16) | (g << 8) | (b << 0);
|
---|
3111 | }
|
---|
3112 | }
|
---|
3113 |
|
---|
3114 | #if CONFIG_API_VERSION == 3
|
---|
3115 |
|
---|
3116 | // set decoder buffer offsets to a minimum
|
---|
3117 | static void ddvd_set_pcr_offset(void)
|
---|
3118 | {
|
---|
3119 | write_string("/proc/stb/pcr/pcr_stc_offset", "200");
|
---|
3120 | write_string("/proc/stb/vmpeg/0/sync_offset", "200");
|
---|
3121 | }
|
---|
3122 |
|
---|
3123 | // reset decoder buffer offsets
|
---|
3124 | static void ddvd_unset_pcr_offset(void)
|
---|
3125 | {
|
---|
3126 | write_string("/proc/stb/pcr/pcr_stc_offset", "2710");
|
---|
3127 | write_string("/proc/stb/vmpeg/0/sync_offset", "2710");
|
---|
3128 | }
|
---|
3129 |
|
---|
3130 | #endif
|
---|
3131 |
|
---|
3132 |
|
---|
3133 | // "nearest neighbor" pixmap resizing
|
---|
3134 | struct ddvd_resize_return ddvd_resize_pixmap_xbpp(unsigned char *pixmap, int xsource, int ysource, int xdest, int ydest, int xoffset, int yoffset, int xstart, int xend, int ystart, int yend, int colors)
|
---|
3135 | {
|
---|
3136 | int x_ratio = (int)((xsource<<16)/(xdest-2*xoffset)) ;
|
---|
3137 | int y_ratio = (int)(((ysource-2*yoffset)<<16)/ydest) ;
|
---|
3138 | int yoffset2 = (yoffset<<16)/y_ratio;
|
---|
3139 |
|
---|
3140 | unsigned char *pixmap_tmp;
|
---|
3141 | pixmap_tmp = (unsigned char *)malloc(xsource*ysource*colors);
|
---|
3142 | memcpy(pixmap_tmp, pixmap, xsource*ysource*colors);
|
---|
3143 | memset(pixmap, 0, xdest * ydest * colors); //clear screen ..
|
---|
3144 | struct ddvd_resize_return return_code;
|
---|
3145 |
|
---|
3146 | return_code.x_start=(xstart<<16)/x_ratio; // transform input resize area to destination area
|
---|
3147 | return_code.x_end=(xend<<16)/x_ratio;
|
---|
3148 | return_code.y_start=((ystart<<16)/y_ratio)-yoffset2;
|
---|
3149 | return_code.y_end=((yend<<16)/y_ratio)-yoffset2;
|
---|
3150 | return_code.y_start = return_code.y_start < 0 ? 0 : return_code.y_start;
|
---|
3151 | return_code.y_end = return_code.y_end > ydest ? ydest : return_code.y_end;
|
---|
3152 |
|
---|
3153 | int x2, y2, c, i ,j;
|
---|
3154 | for (i=return_code.y_start;i<=return_code.y_end;i++) {
|
---|
3155 | for (j=return_code.x_start;j<=return_code.x_end;j++) {
|
---|
3156 | x2 = ((j*x_ratio)>>16) ;
|
---|
3157 | y2 = ((i*y_ratio)>>16)+yoffset ;
|
---|
3158 | for (c=0; c<colors; c++)
|
---|
3159 | pixmap[((i*xdest)+j)*colors + c + xoffset*colors] = pixmap_tmp[((y2*xsource)+x2)*colors + c] ;
|
---|
3160 | }
|
---|
3161 | }
|
---|
3162 | free(pixmap_tmp);
|
---|
3163 |
|
---|
3164 | return_code.x_start+=xoffset; // correct xoffset
|
---|
3165 | return_code.x_end+=xoffset;
|
---|
3166 |
|
---|
3167 | return return_code;
|
---|
3168 | }
|
---|
3169 |
|
---|
3170 | // bicubic picture resize
|
---|
3171 | struct ddvd_resize_return ddvd_resize_pixmap_xbpp_smooth(unsigned char *pixmap, int xsource, int ysource, int xdest, int ydest, int xoffset, int yoffset, int xstart, int xend, int ystart, int yend, int colors)
|
---|
3172 | {
|
---|
3173 | unsigned int xs,ys,xd,yd,dpixel,fx,fy;
|
---|
3174 | unsigned int c,tmp_i;
|
---|
3175 | int x,y,t,t1;
|
---|
3176 |
|
---|
3177 | xs=xsource; // x-resolution source
|
---|
3178 | ys=ysource-2*yoffset; // y-resolution source
|
---|
3179 | xd=xdest-2*xoffset; // x-resolution destination
|
---|
3180 | yd=ydest; // y-resolution destination
|
---|
3181 | unsigned char *pixmap_tmp;
|
---|
3182 | pixmap_tmp = (unsigned char *)malloc(xsource*ysource*colors);
|
---|
3183 | memcpy(pixmap_tmp, pixmap, xsource*ysource*colors);
|
---|
3184 | memset(pixmap, 0, xdest * ydest * colors); //clear screen ..
|
---|
3185 | struct ddvd_resize_return return_code;
|
---|
3186 |
|
---|
3187 | int yoffset2 = (yoffset<<16)/((ys<<16)/yd);
|
---|
3188 | return_code.x_start=(xstart<<16)/((xs<<16)/xd); // transform input resize area to destination area
|
---|
3189 | return_code.x_end=(xend<<16)/((xs<<16)/xd);
|
---|
3190 | return_code.y_start=((ystart<<16)/((ys<<16)/yd))-yoffset2;
|
---|
3191 | return_code.y_end=((yend<<16)/((ys<<16)/yd))-yoffset2;
|
---|
3192 | return_code.y_start = return_code.y_start < 0 ? 0 : return_code.y_start;
|
---|
3193 | return_code.y_end = return_code.y_end > ydest ? ydest : return_code.y_end;
|
---|
3194 |
|
---|
3195 | // get x scale factor, use bitshifting to get rid of floats
|
---|
3196 | fx=((xs-1)<<16)/xd;
|
---|
3197 |
|
---|
3198 | // get y scale factor, use bitshifting to get rid of floats
|
---|
3199 | fy=((ys-1)<<16)/yd;
|
---|
3200 |
|
---|
3201 | unsigned int sx1[xd],sx2[xd],sy1,sy2;
|
---|
3202 |
|
---|
3203 | // pre calculating sx1/sx2 for faster resizing
|
---|
3204 | for (x=return_code.x_start; x<=return_code.x_end; x++)
|
---|
3205 | {
|
---|
3206 | // first x source pixel for calculating destination pixel
|
---|
3207 | sx1[x]=(fx*x)>>16; //floor()
|
---|
3208 |
|
---|
3209 | // last x source pixel for calculating destination pixel
|
---|
3210 | sx2[x]=sx1[x]+(fx>>16);
|
---|
3211 | if (fx & 0x7FFF) //ceil()
|
---|
3212 | sx2[x]++;
|
---|
3213 | }
|
---|
3214 |
|
---|
3215 | // Scale
|
---|
3216 | for (y=return_code.y_start; y<=return_code.y_end; y++)
|
---|
3217 | {
|
---|
3218 |
|
---|
3219 | // first y source pixel for calculating destination pixel
|
---|
3220 | sy1=(fy*y)>>16; //floor()
|
---|
3221 |
|
---|
3222 | // last y source pixel for calculating destination pixel
|
---|
3223 | sy2=sy1+(fy>>16);
|
---|
3224 | if (fy & 0x7FFF) //ceil()
|
---|
3225 | sy2++;
|
---|
3226 |
|
---|
3227 | for (x=return_code.x_start; x<=return_code.x_end; x++)
|
---|
3228 | {
|
---|
3229 | // we do this for every color
|
---|
3230 | for (c=0; c<colors; c++)
|
---|
3231 | {
|
---|
3232 | // calculating destination pixel
|
---|
3233 | tmp_i=0;
|
---|
3234 | dpixel=0;
|
---|
3235 | for (t1=sy1; t1<sy2; t1++)
|
---|
3236 | {
|
---|
3237 | for (t=sx1[x]; t<=sx2[x]; t++)
|
---|
3238 | {
|
---|
3239 | tmp_i+=(int)pixmap_tmp[(t*colors)+c+((t1+yoffset)*xs*colors)];
|
---|
3240 | dpixel++;
|
---|
3241 | }
|
---|
3242 | }
|
---|
3243 | // writing calculated pixel into destination pixmap
|
---|
3244 | pixmap[((x+xoffset)*colors)+c+(y*(xd+2*xoffset)*colors)]=tmp_i/dpixel;
|
---|
3245 | }
|
---|
3246 | }
|
---|
3247 | }
|
---|
3248 | free(pixmap_tmp);
|
---|
3249 |
|
---|
3250 | return_code.x_start+=xoffset; // correct xoffset
|
---|
3251 | return_code.x_end+=xoffset;
|
---|
3252 |
|
---|
3253 | return return_code;
|
---|
3254 | }
|
---|
3255 |
|
---|
3256 | // very simple linear resize used for 1bypp mode
|
---|
3257 | struct ddvd_resize_return ddvd_resize_pixmap_1bpp(unsigned char *pixmap, int xsource, int ysource, int xdest, int ydest, int xoffset, int yoffset, int xstart, int xend, int ystart, int yend, int colors)
|
---|
3258 | {
|
---|
3259 | unsigned char *pixmap_tmp;
|
---|
3260 | pixmap_tmp = (unsigned char *)malloc(xsource * ysource * colors);
|
---|
3261 | memcpy(pixmap_tmp, pixmap, xsource * ysource * colors);
|
---|
3262 | memset(pixmap, 0, xdest * ydest * colors); //clear screen ..
|
---|
3263 | struct ddvd_resize_return return_code;
|
---|
3264 |
|
---|
3265 | int i, fx, fy, tmp;
|
---|
3266 |
|
---|
3267 | // precalculate scale factor, use factor 10 to get rid of floats
|
---|
3268 | fx=xsource*10/(xdest-2*xoffset);
|
---|
3269 | fy=(ysource-2*yoffset)*10/ydest;
|
---|
3270 | int yoffset2 = (yoffset*10)/fy;
|
---|
3271 |
|
---|
3272 | return_code.x_start=(xstart*10)/fx; // transform input resize area to destination area
|
---|
3273 | return_code.x_end=(xend*10)/fx;
|
---|
3274 | return_code.y_start=(ystart*10)/fy;
|
---|
3275 | return_code.y_end=(yend*10)/fy;
|
---|
3276 | return_code.y_start = return_code.y_start < 0 ? 0 : return_code.y_start;
|
---|
3277 | return_code.y_end = return_code.y_end > ydest ? ydest : return_code.y_end;
|
---|
3278 |
|
---|
3279 | // scale x
|
---|
3280 | for (i = return_code.x_start; i <= return_code.x_end; i++)
|
---|
3281 | pixmap[i+xoffset]=pixmap_tmp[((fx*i)/10)];
|
---|
3282 |
|
---|
3283 | // scale y
|
---|
3284 | for (i = return_code.y_start; i <= return_code.y_end; i++)
|
---|
3285 | {
|
---|
3286 | tmp=(fy*i)/10;
|
---|
3287 | if (tmp != i)
|
---|
3288 | memcpy(pixmap + (i*xdest), pixmap + (tmp + yoffset) * xdest, xdest);
|
---|
3289 | }
|
---|
3290 | free(pixmap_tmp);
|
---|
3291 |
|
---|
3292 | return_code.x_start+=xoffset; // correct xoffset
|
---|
3293 | return_code.x_end+=xoffset;
|
---|
3294 |
|
---|
3295 | return return_code;
|
---|
3296 | }
|
---|
3297 |
|
---|