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