make menu buttons work again ... killed them with the last commit ;)
[libdreamdvd.git] / main.c
1 /*
2  * DreamDVD V0.9 - DVD-Player for Dreambox
3  * Copyright (C) 2007 by Seddi
4  *
5  * This DVD Player is based upon the great work from the libdvdnav project,
6  * a52dec library, ffmpeg and the knowledge from all the people who made
7  * watching DVD within linux possible.
8  *
9  * DreamDVD is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * DreamDVD is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
22  *
23  * part of libdreamdvd
24  */
25
26 #include "main.h"
27 #include "mpegaudioenc.h"
28 #include "a52dec.h"
29
30 #include <poll.h>
31
32 /*
33  * local helper functions
34  */
35 static ssize_t safe_write(int fd, const void *buf, size_t count)
36 {
37         const uint8_t *ptr = buf;
38         size_t written = 0;
39         ssize_t n;
40
41         while (written < count) {
42                 n = write(fd, &ptr[written], count - written);
43                 if (n < 0) {
44                         if (errno != EINTR) {
45                                 perror("write");
46                                 return written ? written : -1;
47                         }
48                 } else {
49                         written += n;
50                 }
51         }
52
53         return written;
54 }
55
56 static void write_string(const char *filename, const char *string)
57 {
58         FILE *f;
59
60         f = fopen(filename, "w");
61         if (f == NULL) {
62                 perror(filename);
63                 return;
64         }
65
66         fputs(string, f);
67         fclose(f);
68 }
69
70 static int open_pipe(int fd[2])
71 {
72         int flags;
73
74         fd[0] = fd[1] = -1;
75
76         if (pipe(fd) < 0) {
77                 perror("pipe");
78                 goto err;
79         }
80
81         flags = fcntl(fd[0], F_GETFL);
82         if (flags < 0) {
83                 perror("F_GETFL");
84                 goto err;
85         }
86         if (fcntl(fd[0], F_SETFL, flags | O_NONBLOCK) < 0) {
87                 perror("F_SETFL");
88                 goto err;
89         }
90
91         return 0;
92
93 err:
94         if (fd[0] != -1) {
95                 close(fd[0]);
96                 fd[0] = -1;
97         }
98         if (fd[1] != -1) {
99                 close(fd[1]);
100                 fd[1] = -1;
101         }
102
103         return -1;
104 }
105
106 /*
107  * external functions
108  */
109
110 // create ddvd handle and set defaults
111 struct ddvd *ddvd_create(void)
112 {
113         struct ddvd *pconfig;
114
115         pconfig = malloc(sizeof(struct ddvd));
116         if (pconfig == NULL) {
117                 perror("malloc");
118                 return NULL;
119         }
120
121         memset(pconfig, 0, sizeof(struct ddvd));
122
123         // defaults
124         ddvd_set_ac3thru(pconfig, 0);
125         ddvd_set_language(pconfig, "en");
126         ddvd_set_dvd_path(pconfig, "/dev/cdroms/cdrom0");
127         ddvd_set_video(pconfig, DDVD_4_3_LETTERBOX, DDVD_PAL);
128         ddvd_set_lfb(pconfig, NULL, 720, 576, 1, 720);
129         struct ddvd_resume resume_info;
130         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;
131         ddvd_set_resume_pos(pconfig, resume_info);
132         pconfig->should_resume = 0;
133         pconfig->next_time_update = 0;
134         strcpy(pconfig->title_string, "");
135
136         // open pipes
137         if (open_pipe(pconfig->key_pipe) < 0) {
138                 ddvd_close(pconfig);
139                 return NULL;
140         }
141         if (open_pipe(pconfig->message_pipe) < 0) {
142                 ddvd_close(pconfig);
143                 return NULL;
144         }
145
146         return pconfig;
147 }
148
149 // destroy ddvd handle
150 void ddvd_close(struct ddvd *pconfig)
151 {
152         if (pconfig->message_pipe[0] != -1)
153                 close(pconfig->message_pipe[0]);
154         if (pconfig->message_pipe[1] != -1)
155                 close(pconfig->message_pipe[1]);
156         if (pconfig->key_pipe[0] != -1)
157                 close(pconfig->key_pipe[0]);
158         if (pconfig->key_pipe[1] != -1)
159                 close(pconfig->key_pipe[1]);
160         if (pconfig->dvd_path != NULL)
161                 free(pconfig->dvd_path);
162
163         free(pconfig);
164 }
165
166 // get message_pipe fd for polling functions in the host app
167 int ddvd_get_messagepipe_fd(struct ddvd *pconfig)
168 {
169         return pconfig->message_pipe[0];
170 }
171
172 // set resume postion
173 void ddvd_set_resume_pos(struct ddvd *pconfig, struct ddvd_resume resume_info)
174 {
175         pconfig->resume_title = resume_info.title;
176         pconfig->resume_chapter = resume_info.chapter;
177         pconfig->resume_block = resume_info.block;
178         pconfig->should_resume = 1;
179         pconfig->resume_audio_id = resume_info.audio_id;
180         pconfig->resume_audio_lock = resume_info.audio_lock;
181         pconfig->resume_spu_id = resume_info.spu_id;
182         pconfig->resume_spu_lock = resume_info.spu_lock;
183 }
184
185 // set framebuffer options
186 void ddvd_set_lfb(struct ddvd *pconfig, unsigned char *lfb, int xres, int yres, int bypp, int stride)
187 {
188         pconfig->lfb = lfb;
189         pconfig->xres = xres;
190         pconfig->yres = yres;
191         pconfig->stride = stride;
192         pconfig->bypp = bypp;
193 }
194
195 // set path to dvd block device or file structure/iso
196 void ddvd_set_dvd_path(struct ddvd *pconfig, const char *path)
197 {
198         if (pconfig->dvd_path != NULL)
199                 free(pconfig->dvd_path);
200
201         pconfig->dvd_path = strdup(path);
202 }
203
204 // set language
205 void ddvd_set_language(struct ddvd *pconfig, const char lang[2])
206 {
207         memcpy(pconfig->language, lang, 2);
208 }
209
210 // set internal ac3 decoding (needs liba52 which will be dynamically loaded)
211 void ddvd_set_ac3thru(struct ddvd *pconfig, int ac3thru)
212 {
213         pconfig->ac3thru = ac3thru;
214 }
215
216 // set video options
217 void ddvd_set_video(struct ddvd *pconfig, int aspect, int tv_system)
218 {
219         pconfig->aspect = aspect;
220         pconfig->tv_system = tv_system;
221 }
222
223 // send commands/keys to the main player
224 void ddvd_send_key(struct ddvd *pconfig, int key)
225 {
226         safe_write(pconfig->key_pipe[1], &key, sizeof(int));
227 }
228
229 // skip n seconds in playing n>0 forward - n<0 backward
230 void ddvd_skip_seconds(struct ddvd *pconfig, int seconds)
231 {
232         if (seconds < 0)
233                 ddvd_send_key(pconfig, DDVD_SKIP_BWD);
234         else
235                 ddvd_send_key(pconfig, DDVD_SKIP_FWD);
236
237         ddvd_send_key(pconfig, seconds);
238 }
239
240 // jump to beginning of given title
241 void ddvd_set_title(struct ddvd *pconfig, int title)
242 {
243         ddvd_send_key(pconfig, DDVD_SET_TITLE);
244         ddvd_send_key(pconfig, title);
245 }
246
247 // jump to beginning of given chapter
248 void ddvd_set_chapter(struct ddvd *pconfig, int chapter)
249 {
250         ddvd_send_key(pconfig, DDVD_SET_CHAPTER);
251         ddvd_send_key(pconfig, chapter);
252 }
253
254 // get and process the next message from the main player
255 int ddvd_get_next_message(struct ddvd *pconfig, int blocked)
256 {
257         int res;
258         int i;
259
260         if (ddvd_readpipe(pconfig->message_pipe[0], &res, sizeof(int), blocked) != sizeof(int))
261                 res = DDVD_NULL;
262
263         switch (res)            // more data to process ?
264         {
265         case DDVD_COLORTABLE_UPDATE:
266                 for (i = 0; i < 4; i++)
267                         ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_col[i], sizeof(struct ddvd_color), 1);
268                 break;
269         case DDVD_SHOWOSD_TIME:
270                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_time, sizeof(pconfig->last_time), 1);
271                 break;
272         case DDVD_SHOWOSD_STATE_FFWD:
273                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_trickspeed, sizeof(pconfig->last_trickspeed), 1);
274                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_time, sizeof(pconfig->last_time), 1);
275                 break;
276         case DDVD_SHOWOSD_STATE_FBWD:
277                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_trickspeed, sizeof(pconfig->last_trickspeed), 1);
278                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_time, sizeof(pconfig->last_time), 1);
279                 break;
280         case DDVD_SHOWOSD_STRING:
281                 ddvd_readpipe(pconfig->message_pipe[0], pconfig->last_string, sizeof(pconfig->last_string), 1);
282                 break;
283         case DDVD_SHOWOSD_AUDIO:
284                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_audio_id, sizeof(int), 1);
285                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_audio_lang, sizeof(uint16_t), 1);
286                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_audio_type, sizeof(int), 1);
287                 break;
288         case DDVD_SHOWOSD_SUBTITLE:
289                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_spu_id, sizeof(int), 1);
290                 ddvd_readpipe(pconfig->message_pipe[0], &pconfig->last_spu_lang, sizeof(uint16_t), 1);
291                 break;
292         default:
293                 break;
294         }
295
296         return res;
297 }
298
299 // get last colortable for 8bit mode (4 colors)
300 void ddvd_get_last_colortable(struct ddvd *pconfig, void *colortable)
301 {
302         memcpy(colortable, pconfig->last_col, sizeof(pconfig->last_col));
303 }
304
305 // get last received playing time as struct ddvd_time
306 void ddvd_get_last_time(struct ddvd *pconfig, void *timestamp)
307 {
308         memcpy(timestamp, &pconfig->last_time, sizeof(pconfig->last_time));
309 }
310
311 // get the actual trickspeed (2-64x) when in trickmode
312 void ddvd_get_last_trickspeed(struct ddvd *pconfig, void *trickspeed)
313 {
314         memcpy(trickspeed, &pconfig->last_trickspeed, sizeof(pconfig->last_trickspeed));
315 }
316
317 // get last text message from player
318 void ddvd_get_last_string(struct ddvd *pconfig, void *text)
319 {
320         memcpy(text, pconfig->last_string, sizeof(pconfig->last_string));
321 }
322
323 // get the active audio track
324 void ddvd_get_last_audio(struct ddvd *pconfig, void *id, void *lang, void *type)
325 {
326         memcpy(id, &pconfig->last_audio_id, sizeof(pconfig->last_audio_id));
327         memcpy(lang, &pconfig->last_audio_lang, sizeof(pconfig->last_audio_lang));
328         memcpy(type, &pconfig->last_audio_type, sizeof(pconfig->last_audio_type));
329 }
330
331 // get the active SPU track
332 void ddvd_get_last_spu(struct ddvd *pconfig, void *id, void *lang)
333 {
334         memcpy(id, &pconfig->last_spu_id, sizeof(pconfig->last_spu_id));
335         memcpy(lang, &pconfig->last_spu_lang, sizeof(pconfig->last_spu_lang));
336 }
337
338 // get dvd title string
339 void ddvd_get_title_string(struct ddvd *pconfig, char *title_string)
340 {
341         memcpy(title_string, pconfig->title_string, sizeof(pconfig->title_string));
342 }
343
344 // get actual position for resuming
345 void ddvd_get_resume_pos(struct ddvd *pconfig, struct ddvd_resume *resume_info)
346 {
347         memcpy(&resume_info->title, &pconfig->resume_title, sizeof(pconfig->resume_title));
348         memcpy(&resume_info->chapter, &pconfig->resume_chapter, sizeof(pconfig->resume_chapter));
349         memcpy(&resume_info->block, &pconfig->resume_block, sizeof(pconfig->resume_block));
350         memcpy(&resume_info->audio_id, &pconfig->resume_audio_id, sizeof(pconfig->resume_audio_id));
351         memcpy(&resume_info->audio_lock, &pconfig->resume_audio_lock, sizeof(pconfig->resume_audio_lock));
352         memcpy(&resume_info->spu_id, &pconfig->resume_spu_id, sizeof(pconfig->resume_spu_id));
353         memcpy(&resume_info->spu_lock, &pconfig->resume_spu_lock, sizeof(pconfig->resume_spu_lock));
354 }
355
356 // the main player loop
357 enum ddvd_result ddvd_run(struct ddvd *playerconfig)
358 {
359         if (playerconfig->lfb == NULL) {
360                 printf("Frame/backbuffer not given to libdreamdvd. Will not start the player !\n");
361                 return DDVD_INVAL;
362         }
363
364         // we need to know the first vts_change and the next cell change for resuming a dvd
365         int first_vts_change = 1;
366         int next_cell_change = 0;
367         int ddvd_have_ntsc = -1;
368         
369         ddvd_screeninfo_xres = playerconfig->xres;
370         ddvd_screeninfo_yres = playerconfig->yres;
371         ddvd_screeninfo_stride = playerconfig->stride;
372         int ddvd_screeninfo_bypp = playerconfig->bypp;
373         int message_pipe = playerconfig->message_pipe[1];
374         int key_pipe = playerconfig->key_pipe[0];
375         unsigned char *p_lfb = playerconfig->lfb;
376         enum ddvd_result res = DDVD_OK;
377         int msg;
378         // try to load liba52.so.0 for softdecoding
379         int have_liba52 = ddvd_load_liba52();
380
381         uint8_t *last_iframe = NULL;
382         uint8_t *spu_buffer = NULL;
383         uint8_t *spu_backbuffer = NULL;
384
385         // init backbuffer (SPU)
386         ddvd_lbb = malloc(720 * 576);   // the spu backbuffer is always max DVD PAL 720x576 pixel (NTSC 720x480)
387         if (ddvd_lbb == NULL) {
388                 perror("SPU-Backbuffer <mem allocation failed>");
389                 res = DDVD_NOMEM;
390                 goto err_malloc;
391         }
392
393         last_iframe = malloc(320 * 1024);
394         if (last_iframe == NULL) {
395                 perror("malloc");
396                 res = DDVD_NOMEM;
397                 goto err_malloc;
398         }
399
400         spu_buffer = malloc(2 * (128 * 1024));
401         if (spu_buffer == NULL) {
402                 perror("malloc");
403                 res = DDVD_NOMEM;
404                 goto err_malloc;
405         }
406
407         spu_backbuffer = malloc(3 * 2 * (128 * 1024));
408         if (spu_backbuffer == NULL) {
409                 perror("malloc");
410                 res = DDVD_NOMEM;
411                 goto err_malloc;
412         }
413
414         memset(ddvd_lbb, 0, ddvd_screeninfo_xres * ddvd_screeninfo_yres);
415         memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres);        //clear screen
416
417         msg = DDVD_SCREEN_UPDATE;
418         safe_write(message_pipe, &msg, sizeof(int));
419
420         printf("Opening output...\n");
421
422 #if CONFIG_API_VERSION == 1
423         ddvd_output_fd = open("/dev/video", O_WRONLY);
424         if (ddvd_output_fd == -1) {
425                 perror("/dev/video");
426                 res = DDVD_BUSY;
427                 goto err_open_output_fd;
428         }
429
430         ddvd_fdvideo = open("/dev/dvb/card0/video0", O_RDWR);
431         if (ddvd_fdvideo == -1) {
432                 perror("/dev/dvb/card0/video0");
433                 res = DDVD_BUSY;
434                 goto err_open_fdvideo;
435         }
436
437         ddvd_fdaudio = open("/dev/dvb/card0/audio0", O_RDWR);
438         if (ddvd_fdaudio == -1) {
439                 perror("/dev/dvb/card0/audio0");
440                 res = DDVD_BUSY;
441                 goto err_open_fdaudio;
442         }
443
444         ddvd_ac3_fd = open("/dev/sound/dsp1", O_RDWR);
445         if (ddvd_ac3_fd == -1) {
446                 perror("/dev/sound/dsp1");
447                 res = DDVD_BUSY;
448                 goto err_open_ac3_fd;
449         }
450
451         if (ioctl(ddvd_fdvideo, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
452                 perror("VIDEO_SELECT_SOURCE");
453         if (ioctl(ddvd_fdvideo, VIDEO_CLEAR_BUFFER) < 0)
454                 perror("VIDEO_CLEAR_BUFFER");
455         if (ioctl(ddvd_fdvideo, VIDEO_PLAY) < 0)
456                 perror("VIDEO_PLAY");
457
458         if (ioctl(ddvd_fdaudio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) < 0)
459                 perror("AUDIO_SELECT_SOURCE");
460         if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
461                 perror("AUDIO_CLEAR_BUFFER");
462         if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
463                 perror("AUDIO_PLAY");
464
465 #elif CONFIG_API_VERSION == 3
466         ddvd_output_fd = ddvd_fdvideo = open("/dev/dvb/adapter0/video0", O_RDWR);
467         if (ddvd_fdvideo == -1) {
468                 perror("/dev/dvb/adapter0/video0");
469                 res = DDVD_BUSY;
470                 goto err_open_fdvideo;
471         }
472
473         ddvd_ac3_fd = ddvd_fdaudio = open("/dev/dvb/adapter0/audio0", O_RDWR);
474         if (ddvd_fdaudio == -1) {
475                 perror("/dev/dvb/adapter0/audio0");
476                 res = DDVD_BUSY;
477                 goto err_open_ac3_fd;
478         }
479
480         if (ioctl(ddvd_fdvideo, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
481                 perror("VIDEO_SELECT_SOURCE");
482         if (ioctl(ddvd_fdvideo, VIDEO_CLEAR_BUFFER) < 0)
483                 perror("VIDEO_CLEAR_BUFFER");
484         if (ioctl(ddvd_fdvideo, VIDEO_SET_STREAMTYPE, 0) < 0)   // set mpeg2
485                 perror("VIDEO_SET_STREAMTYPE");
486         if (ioctl(ddvd_fdvideo, VIDEO_PLAY) < 0)
487                 perror("VIDEO_PLAY");
488
489         if (ioctl(ddvd_fdaudio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) < 0)
490                 perror("AUDIO_SELECT_SOURCE");
491         if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
492                 perror("AUDIO_CLEAR_BUFFER");
493         if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
494                 perror("AUDIO_PLAY");
495 #else
496 #error please define CONFIG_API_VERSION to be 1 or 3
497 #endif
498
499 // show startup screen
500 #if SHOW_START_SCREEN == 1
501 #if CONFIG_API_VERSION == 1
502         int i;
503         //that really sucks but there is no other way
504         for (i = 0; i < 10; i++)
505                 safe_write(ddvd_output_fd, ddvd_startup_logo, sizeof(ddvd_startup_logo));
506 #else
507         unsigned char pes_header[] = { 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x00, 0x00 };
508         safe_write(ddvd_output_fd, pes_header, sizeof(pes_header));
509         safe_write(ddvd_output_fd, ddvd_startup_logo, sizeof(ddvd_startup_logo));
510         safe_write(ddvd_output_fd, ddvd_startup_logo, sizeof(ddvd_startup_logo));
511 #endif
512 #endif
513
514         int audio_type = DDVD_AC3;
515
516 #if CONFIG_API_VERSION == 3
517         ddvd_set_pcr_offset();
518 #endif
519
520         uint8_t mem[DVD_VIDEO_LB_LEN];
521         uint8_t *buf = mem;
522         int result, event, len;
523
524         unsigned char lpcm_data[2048 * 6 * 6 /*4608 */ ];
525         int mpa_header_length;
526         int mpa_count, mpa_count2;
527         uint8_t mpa_data[2048 * 4];
528         int ac3_len;
529         int16_t ac3_tmp[2048 * 6 * 6];
530
531         ddvd_mpa_init(48000, 192000);   //init MPA Encoder with 48kHz and 192k Bitrate
532
533         int ac3thru = 1;
534         if (have_liba52) {
535                 state = a52_init(0);    //init AC3 Decoder 
536                 ac3thru = playerconfig->ac3thru;
537         }
538
539         char osdtext[512];
540         strcpy(osdtext, "");
541
542         int tv_aspect = playerconfig->aspect;   //0-> 4:3 lb 1-> 4:3 ps 2-> 16:9 3-> always 16:9
543         int dvd_aspect = 0;     //0-> 4:3 2-> 16:9
544         int dvd_scale_perm = 0;
545         int tv_scale = 0;       //0-> off 1-> letterbox 2-> panscan
546         int spu_active_id = -1;
547         int finished = 0;
548         int audio_id;
549         int report_audio_info = 0;
550
551         ddvd_trickmode = TOFF;
552         ddvd_trickspeed = 0;
553
554         int rccode;
555         int ismute = 0;
556
557         if (ac3thru) {
558                 if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
559                         perror("AUDIO_SET_AV_SYNC");
560 #ifdef CONVERT_TO_DVB_COMPLIANT_AC3
561                 if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 0) < 0)  // AC3 (dvb compliant)
562 #else
563                 if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 3) < 0)  // AC3 VOB
564 #endif
565                         perror("AUDIO_SET_BYPASS_MODE");
566         } else {
567                 if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
568                         perror("AUDIO_SET_AV_SYNC");
569                 if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 1) < 0)
570                         perror("AUDIO_SET_BYPASS_MODE");
571         }
572
573         // set video system
574         int pal_ntsc = playerconfig->tv_system;
575         int saa;
576         if (pal_ntsc == 1)
577                 saa = SAA_NTSC;
578         else
579                 saa = SAA_PAL;
580         int saafd = open("/dev/dbox/saa0", O_RDWR);
581         if (saafd >= 0) {
582                 if (ioctl(saafd, SAAIOSENC, &saa) < 0)
583                         perror("SAAIOSENC");
584                 close(saafd);
585         }
586
587         /* open dvdnav handle */
588         printf("Opening DVD...%s\n", playerconfig->dvd_path);
589         if (dvdnav_open(&dvdnav, playerconfig->dvd_path) != DVDNAV_STATUS_OK) {
590                 printf("Error on dvdnav_open\n");
591                 sprintf(osdtext, "Error: Cant open DVD Source: %s", playerconfig->dvd_path);
592                 msg = DDVD_SHOWOSD_STRING;
593                 safe_write(message_pipe, &msg, sizeof(int));
594                 safe_write(message_pipe, &osdtext, sizeof(osdtext));
595                 res = DDVD_FAIL_OPEN;
596                 goto err_dvdnav_open;
597         }
598
599         /* set read ahead cache usage to no */
600         if (dvdnav_set_readahead_flag(dvdnav, 0) != DVDNAV_STATUS_OK) {
601                 printf("Error on dvdnav_set_readahead_flag: %s\n", dvdnav_err_to_string(dvdnav));
602                 res = DDVD_FAIL_PREFS;
603                 goto err_dvdnav;
604         }
605
606         /* set the language */
607         if (dvdnav_menu_language_select(dvdnav, playerconfig->language) != DVDNAV_STATUS_OK ||
608             dvdnav_audio_language_select(dvdnav, playerconfig->language) != DVDNAV_STATUS_OK ||
609             dvdnav_spu_language_select(dvdnav, playerconfig->language) != DVDNAV_STATUS_OK) {
610                 printf("Error on setting languages: %s\n", dvdnav_err_to_string(dvdnav));
611                 res = DDVD_FAIL_PREFS;
612                 goto err_dvdnav;
613         }
614
615         /* set the PGC positioning flag to have position information relatively to the
616          * whole feature instead of just relatively to the current chapter */
617         if (dvdnav_set_PGC_positioning_flag(dvdnav, 1) != DVDNAV_STATUS_OK) {
618                 printf("Error on dvdnav_set_PGC_positioning_flag: %s\n", dvdnav_err_to_string(dvdnav));
619                 res = DDVD_FAIL_PREFS;
620                 goto err_dvdnav;
621         }
622
623         int audio_lock = 0;
624         int spu_lock = 0;
625         int audio_format[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
626         unsigned long long vpts, apts, spts, pts;
627
628         audio_id = dvdnav_get_active_audio_stream(dvdnav);
629         ddvd_playmode = PLAY;
630
631         ddvd_lbb_changed = 0;
632
633         unsigned long long spu_backpts[3];
634
635         ddvd_play_empty(FALSE);
636         ddvd_get_time();        //set timestamp
637
638         playerconfig->in_menu = 0;
639
640         const char *dvd_titlestring;
641         if (dvdnav_get_title_string(dvdnav, &dvd_titlestring) == DVDNAV_STATUS_OK)
642                 strcpy(playerconfig->title_string, dvd_titlestring);
643
644         msg = DDVD_SHOWOSD_TITLESTRING;
645         safe_write(message_pipe, &msg, sizeof(int));
646
647         /* the read loop which regularly calls dvdnav_get_next_block
648          * and handles the returned events */
649         int reached_eof = 0;
650         int reached_sof = 0;
651         while (!finished) {
652                 pci_t *pci = 0;
653                 dsi_t *dsi = 0;
654                 int buttonN = -1;
655                 int in_menu = 0;
656
657                 /* the main reading function */
658                 if (ddvd_playmode == PLAY) {    //skip when not in play mode
659                         // trickmode
660                         if (ddvd_trickmode) {
661                                 if (ddvd_trick_timer_end <= ddvd_get_time()) {
662                                         if (ddvd_trickmode == FASTBW) { //jump back ?
663                                                 uint32_t pos, len;
664                                                 dvdnav_get_position(dvdnav, &pos, &len);
665                                                 //90000 = 1 Sek. -> 45000 = 0.5 Sek. -> Speed Faktor=2
666                                                 int64_t posneu = ((pos * ddvd_lastCellEventInfo.pgc_length) / len) - (45000 * 2 * ddvd_trickspeed);
667                                                 int64_t posneu2 = posneu <= 0 ? 0 : (posneu * len) / ddvd_lastCellEventInfo.pgc_length;
668                                                 dvdnav_sector_search(dvdnav, posneu2, SEEK_SET);
669                                                 if (posneu < 0) {       // reached begin of movie
670                                                         reached_sof = 1;
671                                                         msg = DDVD_SHOWOSD_TIME;
672                                                 } else {
673                                                         msg = DDVD_SHOWOSD_STATE_FBWD;
674                                                 }
675                                         } else if (ddvd_trickmode == FASTFW) {  //jump forward ?
676                                                 uint32_t pos, len;
677                                                 dvdnav_get_position(dvdnav, &pos, &len);
678                                                 //90000 = 1 Sek. -> 22500 = 0.25 Sek. -> Speed Faktor=2
679                                                 int64_t posneu = ((pos * ddvd_lastCellEventInfo.pgc_length) / len) + (22500 * 2 * ddvd_trickspeed);
680                                                 int64_t posneu2 = (posneu * len) / ddvd_lastCellEventInfo.pgc_length;
681                                                 if (posneu2 && len && posneu2 >= len) { // reached end of movie
682                                                         posneu2 = len - 250;
683                                                         reached_eof = 1;
684                                                         msg = DDVD_SHOWOSD_TIME;
685                                                 } else {
686                                                         msg = DDVD_SHOWOSD_STATE_FFWD;
687                                                 }
688                                                 dvdnav_sector_search(dvdnav, posneu2, SEEK_SET);
689                                         }
690                                         ddvd_trick_timer_end = ddvd_get_time() + 300;
691                                         ddvd_lpcm_count = 0;
692                                 }
693                         }
694
695                         result = dvdnav_get_next_block(dvdnav, buf, &event, &len);
696                         if (result == DVDNAV_STATUS_ERR) {
697                                 printf("Error getting next block: %s\n", dvdnav_err_to_string(dvdnav));
698                                 sprintf(osdtext, "Error: Getting next block: %s", dvdnav_err_to_string(dvdnav));
699                                 msg = DDVD_SHOWOSD_STRING;
700                                 safe_write(message_pipe, &msg, sizeof(int));
701                                 safe_write(message_pipe, &osdtext, sizeof(osdtext));
702                                 res = DDVD_FAIL_READ;
703                                 goto err_dvdnav;
704                         }
705
706 send_message:
707                         // send OSD Data
708                         if (msg > 0) {
709                                 struct ddvd_time info;
710                                 switch (msg) {
711                                 case DDVD_SHOWOSD_TIME:
712                                         info = ddvd_get_osd_time(playerconfig);
713                                         safe_write(message_pipe, &msg, sizeof(int));
714                                         safe_write(message_pipe, &info, sizeof(struct ddvd_time));
715                                         break;
716                                 case DDVD_SHOWOSD_STATE_FFWD:
717                                         info = ddvd_get_osd_time(playerconfig);
718                                         safe_write(message_pipe, &msg, sizeof(int));
719                                         safe_write(message_pipe, &ddvd_trickspeed, sizeof(int));
720                                         safe_write(message_pipe, &info, sizeof(struct ddvd_time));
721                                         break;
722                                 case DDVD_SHOWOSD_STATE_FBWD:
723                                         info = ddvd_get_osd_time(playerconfig);
724                                         safe_write(message_pipe, &msg, sizeof(int));
725                                         safe_write(message_pipe, &ddvd_trickspeed, sizeof(int));
726                                         safe_write(message_pipe, &info, sizeof(struct ddvd_time));
727                                         break;
728                                 default:
729                                         break;
730                                 }
731                                 msg = 0;
732                         }
733
734                         if (reached_eof) {
735                                 msg = DDVD_EOF_REACHED;
736                                 safe_write(message_pipe, &msg, sizeof(int));
737                                 reached_eof = 0;
738                         }
739
740                         if (reached_sof) {
741                                 msg = DDVD_SOF_REACHED;
742                                 safe_write(message_pipe, &msg, sizeof(int));
743                                 reached_sof = 0;
744                         }
745
746                         if (ddvd_get_time() > playerconfig->next_time_update) {
747                                 msg = DDVD_SHOWOSD_TIME;
748                                 goto send_message;
749                         }
750                         // send iFrame
751                         if (ddvd_iframesend < 0) {
752 #if CONFIG_API_VERSION == 1
753                                 ddvd_device_clear();
754 #endif
755                                 ddvd_iframesend = 0;
756                         }
757
758                         if (ddvd_iframesend > 0) {
759 #if CONFIG_API_VERSION == 1
760                                 ddvd_device_clear();
761 #endif
762                                 if (ddvd_still_frame && ddvd_last_iframe_len) {
763 #if 0
764                                         static int ifnum = 0;
765                                         static char ifname[255];
766                                         snprintf(ifname, 255, "/tmp/dvd.iframe.%3.3d.asm.pes", ifnum++);
767                                         FILE *f = fopen(ifname, "wb");
768                                         fwrite(last_iframe, 1, ddvd_last_iframe_len, f);
769                                         fclose(f);
770 #endif
771
772 #if CONFIG_API_VERSION == 1
773                                         //that really sucks but there is no other way
774                                         int i;
775                                         for (i = 0; i < 10; i++)
776                                                 safe_write(ddvd_output_fd, last_iframe, ddvd_last_iframe_len);
777 #else
778                                         safe_write(ddvd_output_fd, last_iframe, ddvd_last_iframe_len);
779 #endif
780                                         //printf("Show iframe with size: %d\n",ddvd_last_iframe_len);
781                                         ddvd_last_iframe_len = 0;
782                                 }
783
784                                 ddvd_iframesend = -1;
785                         }
786                         // wait timer
787                         if (ddvd_wait_timer_active) {
788                                 if (ddvd_wait_timer_end <= ddvd_get_time()) {
789                                         ddvd_wait_timer_active = 0;
790                                         dvdnav_still_skip(dvdnav);
791                                         //printf("wait timer done\n");
792                                 }
793                         }
794                         // SPU timer
795                         if (ddvd_spu_timer_active) {
796                                 if (ddvd_spu_timer_end <= ddvd_get_time()) {
797                                         ddvd_spu_timer_active = 0;
798                                         memset(ddvd_lbb, 0, ddvd_screeninfo_xres * ddvd_screeninfo_yres);       //clear SPU backbuffer
799                                         ddvd_lbb_changed = 1;
800                                         //printf("spu timer done\n");
801                                 }
802                         }
803
804                         switch (event) {
805                         case DVDNAV_BLOCK_OK:
806                                 /* We have received a regular block of the currently playing MPEG stream.
807                                  * So we do some demuxing and decoding. */
808
809                                 // collect audio data
810                                 if (((buf[14 + 3]) & 0xF0) == 0xC0)
811                                         audio_format[(buf[14 + 3]) - 0xC0] = DDVD_MPEG;
812                                 if ((buf[14 + 3]) == 0xBD && ((buf[14 + buf[14 + 8] + 9]) & 0xF8) == 0x80)
813                                         audio_format[(buf[14 + buf[14 + 8] + 9]) - 0x80] = DDVD_AC3;
814                                 if ((buf[14 + 3]) == 0xBD && ((buf[14 + buf[14 + 8] + 9]) & 0xF8) == 0x88)
815                                         audio_format[(buf[14 + buf[14 + 8] + 9]) - 0x88] = DDVD_DTS;
816                                 if ((buf[14 + 3]) == 0xBD && ((buf[14 + buf[14 + 8] + 9]) & 0xF8) == 0xA0)
817                                         audio_format[(buf[14 + buf[14 + 8] + 9]) - 0xA0] = DDVD_LPCM;
818
819                                 if ((buf[14 + 3] & 0xF0) == 0xE0) {     // video
820                                         if (buf[14 + 7] & 128) {
821                                                 /* damn gcc bug */
822                                                 vpts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
823                                                 vpts |= buf[14 + 10] << 22;
824                                                 vpts |= (buf[14 + 11] >> 1) << 15;
825                                                 vpts |= buf[14 + 12] << 7;
826                                                 vpts |= (buf[14 + 14] >> 1);
827                                                 //printf("VPTS? %X\n",(int)vpts);
828                                         }
829 #if CONFIG_API_VERSION == 1
830                                         // Eliminate 00 00 01 B4 sequence error packet because it breaks the pallas mpeg decoder
831                                         // This is very strange because the 00 00 01 B4 is partly inside the header extension ...
832                                         if (buf[21] == 0x00 && buf[22] == 0x00 && buf[23] == 0x01 && buf[24] == 0xB4) {
833                                                 buf[21] = 0x01;
834                                         }
835                                         if (buf[22] == 0x00 && buf[23] == 0x00 && buf[24] == 0x01 && buf[25] == 0xB4) {
836                                                 buf[22] = 0x01;
837                                         }
838 #endif
839                                         // If DVD Aspect is 16:9 Zoom (3) and TV is 16:9 then patch the mpeg stream
840                                         // up to 16:9 anamorph because the decoder dont support the 16:9 zoom mode
841                                         if (dvd_aspect == 3 && tv_aspect >= 2) {
842                                                 if (buf[33] == 0 && buf[33 + 1] == 0 && buf[33 + 2] == 1 && buf[33 + 3] == 0xB3) {
843                                                         buf[33 + 7] = (buf[33 + 7] & 0xF) + 0x30;
844                                                 }
845                                                 if (buf[36] == 0 && buf[36 + 1] == 0 && buf[36 + 2] == 1 && buf[36 + 3] == 0xB3) {
846                                                         buf[36 + 7] = (buf[36 + 7] & 0xF) + 0x30;
847                                                 }
848                                         }
849                                         
850                                         // check yres for detecting ntsc/pal
851                                         if (ddvd_have_ntsc == -1) {
852                                                 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) 
853                                                         || (buf[36] == 0 && buf[36 + 1] == 0 && buf[36 + 2] == 1 && buf[36 + 3] == 0xB3 && ((buf[36+5] & 0xF) << 8) + buf[36+6] == 0x1E0))
854                                                         ddvd_have_ntsc = 1;
855                                                 else
856                                                         ddvd_have_ntsc = 0;
857                                         }
858
859                                         safe_write(ddvd_output_fd, buf + 14, 2048 - 14);
860
861                                         // 14+8 header_length
862                                         // 14+(header_length)+3  -> start mpeg header
863                                         // buf[14+buf[14+8]+3] start mpeg header
864
865                                         int datalen = (buf[19] + (buf[18] << 8) + 6) - buf[14 + 8];     // length mpeg packet
866                                         int data = buf[14 + buf[14 + 8] + 3];   // start mpeg packet(header)
867
868                                         int do_copy = (ddvd_iframerun == 0x01) && !(buf[data] == 0 && buf[data + 1] == 0 && buf[data + 2] == 1) ? 1 : 0;
869                                         int have_pictureheader = 0;
870                                         int haveslice = 0;
871                                         int setrun = 0;
872
873                                         while (datalen > 6) {
874                                                 if (buf[data] == 0 && buf[data + 1] == 0 && buf[data + 2] == 1) {
875                                                         if (buf[data + 3] == 0x00)      //picture
876                                                         {
877                                                                 if (!setrun) {
878                                                                         ddvd_iframerun = ((buf[data + 5] >> 3) & 0x07);
879                                                                         setrun = 1;
880                                                                 }
881
882                                                                 if (ddvd_iframerun < 0x01 || 0x03 < ddvd_iframerun) {
883                                                                         data++;
884                                                                         datalen--;
885                                                                         continue;
886                                                                 }
887                                                                 have_pictureheader = 1;
888                                                                 data += 5;
889                                                                 datalen -= 5;
890                                                                 datalen = 6;
891                                                         } else if (buf[data + 3] == 0xB3 && datalen >= 8)       //sequence header
892                                                         {
893                                                                 ddvd_last_iframe_len = 0;       // clear iframe buffer
894                                                                 data += 7;
895                                                                 datalen -= 7;
896                                                         } else if (buf[data + 3] == 0xBE)       //padding stream
897                                                         {
898                                                                 break;
899                                                         } else if (0x01 <= buf[data + 3] && buf[data + 3] <= 0xaf)      //slice ?
900                                                         {
901                                                                 if (!have_pictureheader && ddvd_last_iframe_len == 0)
902                                                                         haveslice = 1;
903                                                         }
904                                                 }
905                                                 data++;
906                                                 datalen--;
907                                         }
908                                         if ((ddvd_iframerun <= 0x01 || do_copy) && ddvd_still_frame) {
909                                                 if (haveslice)
910                                                         ddvd_iframerun = 0xFF;
911                                                 else if (ddvd_last_iframe_len < (320 * 1024) - (buf[19] + (buf[18] << 8) + 6)) {
912                                                         memcpy(last_iframe + ddvd_last_iframe_len, buf + 14, buf[19] + (buf[18] << 8) + 6);
913                                                         ddvd_last_iframe_len += buf[19] + (buf[18] << 8) + 6;
914                                                 }
915                                         }
916                                 } else if ((buf[14 + 3]) == 0xC0 + audio_id)    // mpeg audio
917                                 {
918                                         if (audio_type != DDVD_MPEG) {
919                                                 //printf("Switch to MPEG Audio\n");
920                                                 if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
921                                                         perror("AUDIO_SET_AV_SYNC");
922                                                 if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 1) < 0)
923                                                         perror("AUDIO_SET_BYPASS_MODE");
924                                                 audio_type = DDVD_MPEG;
925                                         }
926
927                                         if (buf[14 + 7] & 128) {
928                                                 /* damn gcc bug */
929                                                 apts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
930                                                 apts |= buf[14 + 10] << 22;
931                                                 apts |= (buf[14 + 11] >> 1) << 15;
932                                                 apts |= buf[14 + 12] << 7;
933                                                 apts |= (buf[14 + 14] >> 1);
934                                                 //printf("APTS? %X\n",(int)apts);
935                                         }
936
937                                         safe_write(ddvd_ac3_fd, buf + 14, buf[19] + (buf[18] << 8) + 6);
938                                 } else if ((buf[14 + 3]) == 0xBD && (buf[14 + buf[14 + 8] + 9]) == 0xA0 + audio_id)     // lpcm audio
939                                 {
940                                         if (audio_type != DDVD_LPCM) {
941                                                 //printf("Switch to LPCM Audio\n");
942                                                 if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
943                                                         perror("AUDIO_SET_AV_SYNC");
944                                                 if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 1) < 0)
945                                                         perror("AUDIO_SET_BYPASS_MODE");
946                                                 audio_type = DDVD_LPCM;
947                                                 ddvd_lpcm_count = 0;
948                                         }
949                                         if (buf[14 + 7] & 128) {
950                                                 /* damn gcc bug */
951                                                 apts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
952                                                 apts |= buf[14 + 10] << 22;
953                                                 apts |= (buf[14 + 11] >> 1) << 15;
954                                                 apts |= buf[14 + 12] << 7;
955                                                 apts |= (buf[14 + 14] >> 1);
956                                                 //printf("APTS? %X\n",(int)apts);
957                                         }
958                                         int i = 0;
959                                         char abuf[(((buf[18] << 8) | buf[19]) - buf[22] - 14)];
960 #if BYTE_ORDER == BIG_ENDIAN
961                                         // just copy, byte order is correct on ppc machines
962                                         memcpy(abuf, buf + 14 + buf[14 + 8] + 9 + 7, (((buf[18] << 8) | buf[19]) - buf[22] - 14));
963                                         i = (((buf[18] << 8) | buf[19]) - buf[22] - 14);
964 #else
965                                         // byte swapping .. we become the wrong byteorder on lpcm on the 7025
966                                         while (i < (((buf[18] << 8) | buf[19]) - buf[22] - 14)) {
967                                                 abuf[i + 0] = (buf[14 + buf[14 + 8] + 9 + 7 + i + 1]);
968                                                 abuf[i + 1] = (buf[14 + buf[14 + 8] + 9 + 7 + i + 0]);
969                                                 i += 2;
970                                         }
971 #endif
972                                         // we will encode the raw lpcm data to mpeg audio and send them with pts
973                                         // information to the decoder to get a sync. playing the pcm data via
974                                         // oss will break the pic/sound sync. So believe it or not, this is the 
975                                         // smartest way to get a synced lpcm track ;-)
976                                         if (ddvd_lpcm_count == 0) {     // save mpeg header with pts
977                                                 memcpy(mpa_data, buf + 14, buf[14 + 8] + 9);
978                                                 mpa_header_length = buf[14 + 8] + 9;
979                                         }
980                                         if (ddvd_lpcm_count + i >= 4608) {      //we have to send 4608 bytes to the encoder
981                                                 memcpy(lpcm_data + ddvd_lpcm_count, abuf, 4608 - ddvd_lpcm_count);
982                                                 //encode
983                                                 mpa_count = ddvd_mpa_encode_frame(mpa_data + mpa_header_length, 4608, lpcm_data);
984                                                 //patch pes__packet_length
985                                                 mpa_count = mpa_count + mpa_header_length - 6;
986                                                 mpa_data[4] = mpa_count >> 8;
987                                                 mpa_data[5] = mpa_count & 0xFF;
988                                                 //patch header type to mpeg
989                                                 mpa_data[3] = 0xC0;
990                                                 //write
991                                                 safe_write(ddvd_ac3_fd, mpa_data, mpa_count + mpa_header_length);
992                                                 memcpy(lpcm_data, abuf + (4608 - ddvd_lpcm_count), i - (4608 - ddvd_lpcm_count));
993                                                 ddvd_lpcm_count = i - (4608 - ddvd_lpcm_count);
994                                                 memcpy(mpa_data, buf + 14, buf[14 + 8] + 9);
995                                                 mpa_header_length = buf[14 + 8] + 9;
996                                         } else {
997                                                 memcpy(lpcm_data + ddvd_lpcm_count, abuf, i);
998                                                 ddvd_lpcm_count += i;
999                                         }
1000
1001                                         //safe_write(ddvd_ac3_fd, buf+14 , buf[19]+(buf[18]<<8)+6);
1002                                 } else if ((buf[14 + 3]) == 0xBD && (buf[14 + buf[14 + 8] + 9]) == 0x88 + audio_id) {   // dts audio
1003                                         if (audio_type != DDVD_DTS) {
1004                                                 //printf("Switch to DTS Audio (thru)\n");
1005                                                 if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
1006                                                         perror("AUDIO_SET_AV_SYNC");
1007                                                 if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 5) < 0)
1008                                                         perror("AUDIO_SET_BYPASS_MODE");
1009                                                 audio_type = DDVD_DTS;
1010                                         }
1011
1012                                         if (buf[14 + 7] & 128) {
1013                                                 /* damn gcc bug */
1014                                                 apts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
1015                                                 apts |= buf[14 + 10] << 22;
1016                                                 apts |= (buf[14 + 11] >> 1) << 15;
1017                                                 apts |= buf[14 + 12] << 7;
1018                                                 apts |= (buf[14 + 14] >> 1);
1019                                                 //printf("APTS? %X\n",(int)apts);
1020                                         }
1021
1022                                         safe_write(ddvd_ac3_fd, buf + 14, buf[19] + (buf[18] << 8) + 6);        // not working yet ....
1023                                 } else if ((buf[14 + 3]) == 0xBD && (buf[14 + buf[14 + 8] + 9]) == 0x80 + audio_id) {   // ac3 audio
1024                                         if (audio_type != DDVD_AC3) {
1025                                                 //printf("Switch to AC3 Audio\n");
1026                                                 if (ac3thru || !have_liba52) {  // !have_liba52 and !ac3thru should never happen, but who knows ;)
1027                                                         if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
1028                                                                 perror("AUDIO_SET_AV_SYNC");
1029 #ifdef CONVERT_TO_DVB_COMPLIANT_AC3
1030                                                         if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 0) < 0)  // AC3 (dvb compliant)
1031 #else
1032                                                         if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 3) < 0)  // AC3 VOB
1033 #endif
1034                                                                 perror("AUDIO_SET_BYPASS_MODE");
1035                                                 } else {
1036                                                         if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
1037                                                                 perror("AUDIO_SET_AV_SYNC");
1038                                                         if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 1) < 0)
1039                                                                 perror("AUDIO_SET_BYPASS_MODE");
1040                                                 }
1041                                                 audio_type = DDVD_AC3;
1042                                         }
1043
1044                                         if (buf[14 + 7] & 128) {
1045                                                 /* damn gcc bug */
1046                                                 apts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
1047                                                 apts |= buf[14 + 10] << 22;
1048                                                 apts |= (buf[14 + 11] >> 1) << 15;
1049                                                 apts |= buf[14 + 12] << 7;
1050                                                 apts |= (buf[14 + 14] >> 1);
1051                                                 //printf("APTS? %X\n",(int)apts);
1052                                         }
1053
1054                                         if (ac3thru || !have_liba52) {  // !have_liba52 and !ac3thru should never happen, but who knows ;)
1055 #ifdef CONVERT_TO_DVB_COMPLIANT_AC3
1056                                                 unsigned short pes_len = (buf[14 + 4] << 8 | buf[14 + 5]);
1057                                                 pes_len -= 4;   // strip first 4 bytes of pes payload
1058                                                 buf[14 + 4] = pes_len >> 8;     // patch pes len
1059                                                 buf[15 + 4] = pes_len & 0xFF;
1060
1061                                                 safe_write(ddvd_ac3_fd, buf + 14, 9 + buf[14 + 8]);     // write pes_header
1062                                                 safe_write(ddvd_ac3_fd, buf + 14 + 9 + buf[14 + 8] + 4, pes_len - (3 + buf[14 + 8]));   // write pes_payload
1063 #else
1064                                                 safe_write(ddvd_ac3_fd, buf + 14, buf[19] + (buf[18] << 8) + 6);
1065 #endif
1066                                                 //fwrite(buf+buf[22]+27, 1, ((buf[18]<<8)|buf[19])-buf[22]-7, fac3); //debugwrite
1067                                         } else {
1068                                                 // a bit more funny than lpcm sound, because we do a complete recoding here
1069                                                 // we will decode the ac3 data to plain lpcm and will then encode to mpeg
1070                                                 // audio and send them with pts information to the decoder to get a sync.
1071
1072                                                 // decode and convert ac3 to raw lpcm
1073                                                 ac3_len = ddvd_ac3_decode(buf + buf[22] + 27, ((buf[18] << 8) | buf[19]) - buf[22] - 7, ac3_tmp);
1074
1075                                                 // save the pes header incl. PTS
1076                                                 memcpy(mpa_data, buf + 14, buf[14 + 8] + 9);
1077                                                 mpa_header_length = buf[14 + 8] + 9;
1078
1079                                                 //apts-=(((unsigned long long)(ddvd_lpcm_count)*90)/192);
1080
1081                                                 //mpa_data[14]=(int)((apts<<1)&0xFF);
1082                                                 //mpa_data[12]=(int)((apts>>7)&0xFF);
1083                                                 //mpa_data[11]=(int)(((apts<<1)>>15)&0xFF);
1084                                                 //mpa_data[10]=(int)((apts>>22)&0xFF);
1085
1086                                                 // copy lpcm data into buffer for encoding
1087                                                 memcpy(lpcm_data + ddvd_lpcm_count, ac3_tmp, ac3_len);
1088                                                 ddvd_lpcm_count += ac3_len;
1089
1090                                                 // encode the whole packet to mpa
1091                                                 mpa_count2 = mpa_count = 0;
1092                                                 while (ddvd_lpcm_count >= 4608) {
1093                                                         mpa_count = ddvd_mpa_encode_frame(mpa_data + mpa_header_length + mpa_count2, 4608, lpcm_data);
1094                                                         mpa_count2 += mpa_count;
1095                                                         ddvd_lpcm_count -= 4608;
1096                                                         memcpy(lpcm_data, lpcm_data + 4608, ddvd_lpcm_count);
1097                                                 }
1098
1099                                                 // patch pes__packet_length
1100                                                 mpa_count = mpa_count2 + mpa_header_length - 6;
1101                                                 mpa_data[4] = mpa_count >> 8;
1102                                                 mpa_data[5] = mpa_count & 0xFF;
1103
1104                                                 // patch header type to mpeg
1105                                                 mpa_data[3] = 0xC0;
1106
1107                                                 // write to decoder
1108                                                 safe_write(ddvd_ac3_fd, mpa_data, mpa_count2 + mpa_header_length);
1109
1110                                         }
1111                                 } 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
1112                                         memcpy(spu_buffer + ddvd_spu_ptr, buf + buf[22] + 14 + 10, 2048 - (buf[22] + 14 + 10));
1113                                         ddvd_spu_ptr += 2048 - (buf[22] + 14 + 10);
1114
1115                                         if (buf[14 + 7] & 128) {
1116                                                 /* damn gcc bug */
1117 #if CONFIG_API_VERSION == 3
1118                                                 spts = ((unsigned long long)(((buf[14 + 9] >> 1) & 7))) << 30;
1119                                                 spts |= buf[14 + 10] << 22;
1120                                                 spts |= (buf[14 + 11] >> 1) << 15;
1121                                                 spts |= buf[14 + 12] << 7;
1122                                                 spts |= (buf[14 + 14] >> 1);
1123 #else
1124                                                 spts = (buf[14 + 9] >> 1) << 29;        // need a corrected "spts" because vulcan/pallas will give us a 32bit pts instead of 33bit
1125                                                 spts |= buf[14 + 10] << 21;
1126                                                 spts |= (buf[14 + 11] >> 1) << 14;
1127                                                 spts |= buf[14 + 12] << 6;
1128                                                 spts |= buf[14 + 12] >> 2;
1129 #endif
1130                                                 //printf("SPTS? %X\n",(int)spts);
1131                                         }
1132
1133                                         if (ddvd_spu_ptr >= (spu_buffer[0] << 8 | spu_buffer[1]))       // SPU packet complete ?
1134                                         {
1135                                                 if (ddvd_spu_backnr == 3)       // backbuffer already full ?
1136                                                 {
1137                                                         int tmplen = (spu_backbuffer[0] << 8 | spu_backbuffer[1]);
1138                                                         memcpy(spu_backbuffer, spu_backbuffer + tmplen, ddvd_spu_backptr - tmplen);     // delete oldest SPU packet
1139                                                         spu_backpts[0] = spu_backpts[1];
1140                                                         spu_backpts[1] = spu_backpts[2];
1141                                                         ddvd_spu_backnr = 2;
1142                                                         ddvd_spu_backptr -= tmplen;
1143                                                 }
1144
1145                                                 memcpy(spu_backbuffer + ddvd_spu_backptr, spu_buffer, (spu_buffer[0] << 8 | spu_buffer[1]));    // copy into backbuffer
1146                                                 spu_backpts[ddvd_spu_backnr++] = spts;  // store pts
1147                                                 ddvd_spu_backptr += (spu_buffer[0] << 8 | spu_buffer[1]);       // increase ptr
1148
1149                                                 ddvd_spu_ptr = 0;
1150                                         }
1151                                 }
1152                                 break;
1153
1154                         case DVDNAV_NOP:
1155                                 /* Nothing to do here. */
1156                                 break;
1157
1158                         case DVDNAV_STILL_FRAME:
1159                                 /* We have reached a still frame. So we start a timer to wait
1160                                  * the amount of time specified by the still's length while still handling
1161                                  * user input to make menus and other interactive stills work.
1162                                  * A length of 0xff means an indefinite still which has to be skipped
1163                                  * indirectly by some user interaction. */
1164                                 {
1165                                         if (ddvd_iframesend == 0 && ddvd_last_iframe_len)
1166                                                 ddvd_iframesend = 1;
1167
1168                                         dvdnav_still_event_t *still_event = (dvdnav_still_event_t *) buf;
1169                                         if (still_event->length < 0xff) {
1170                                                 if (!ddvd_wait_timer_active) {
1171                                                         ddvd_wait_timer_active = 1;
1172                                                         ddvd_wait_timer_end = ddvd_get_time() + (still_event->length * 1000);   //ms
1173                                                 }
1174                                         } else
1175                                                 ddvd_wait_for_user = 1;
1176                                 }
1177                                 break;
1178
1179                         case DVDNAV_WAIT:
1180                                 /* We have reached a point in DVD playback, where timing is critical.
1181                                  * We dont use readahead, so we can simply skip the wait state. */
1182                                 dvdnav_wait_skip(dvdnav);
1183                                 break;
1184
1185                         case DVDNAV_SPU_CLUT_CHANGE:
1186                                 /* We received a new color lookup table so we read and store
1187                                  * it */
1188                                 {
1189                                         int i = 0, i2 = 0;
1190                                         uint8_t pal[16 * 4];
1191 #if BYTE_ORDER == BIG_ENDIAN
1192                                         memcpy(pal, buf, 16 * sizeof(uint32_t));
1193 #else
1194                                         for (; i < 16; ++i)
1195                                                 *(int *)(pal + i * 4) = htonl(*(int *)(buf + i * 4));
1196                                         i = 0;
1197 #endif
1198                                         while (i < 16 * 4) {
1199                                                 int y = buf[i + 1];
1200                                                 signed char cr = buf[i + 2];    //v
1201                                                 signed char cb = buf[i + 3];    //u
1202                                                 //printf("%d %d %d ->", y, cr, cb);
1203                                                 y = pal[i + 1];
1204                                                 cr = pal[i + 2];        //v
1205                                                 cb = pal[i + 3];        //u
1206                                                 //printf(" %d %d %d\n", y, cr, cb);
1207                                                 i += 4;
1208                                         }
1209                                         i = 0;
1210
1211                                         while (i < 16 * 4) {
1212                                                 int y = pal[i + 1];
1213                                                 signed char cr = pal[i + 2];    //v
1214                                                 signed char cb = pal[i + 3];    //u
1215
1216                                                 y = 76310 * (y - 16);   //yuv2rgb
1217                                                 cr -= 128;
1218                                                 cb -= 128;
1219                                                 int r = CLAMP((y + 104635 * cr) >> 16);
1220                                                 int g = CLAMP((y - 53294 * cr - 25690 * cb) >> 16);
1221                                                 int b = CLAMP((y + 132278 * cb) >> 16);
1222
1223                                                 ddvd_bl[i2] = b << 8;
1224                                                 ddvd_gn[i2] = g << 8;
1225                                                 ddvd_rd[i2] = r << 8;
1226                                                 i += 4;
1227                                                 i2++;
1228                                         }
1229                                         //CHANGE COLORMAP
1230                                 }
1231                                 break;
1232
1233                         case DVDNAV_SPU_STREAM_CHANGE:
1234                                 /* We received a new SPU stream ID */
1235                                 if (spu_lock)
1236                                         break;
1237
1238                                 dvdnav_spu_stream_change_event_t *ev = (dvdnav_spu_stream_change_event_t *) buf;
1239                                 switch (tv_scale) {
1240                                 case 0: //off
1241                                         spu_active_id = ev->physical_wide;
1242                                         break;
1243                                 case 1: //letterbox
1244                                         spu_active_id = ev->physical_letterbox;
1245                                         break;
1246                                 case 2: //panscan
1247                                         spu_active_id = ev->physical_pan_scan;
1248                                         break;
1249                                 default:        // should not happen
1250                                         spu_active_id = ev->physical_wide;
1251                                         break;
1252                                 }       
1253                                 uint16_t spu_lang = 0xFFFF;
1254                                 int spu_id_logical;
1255                                 spu_id_logical = dvdnav_get_spu_logical_stream(dvdnav, spu_active_id);
1256                                 spu_lang = dvdnav_spu_stream_to_lang(dvdnav, (spu_id_logical >= 0 ? spu_id_logical : spu_active_id) & 0x1F);
1257                                 if (spu_lang == 0xFFFF) {
1258                                         spu_lang = 0x2D2D;      // SPU "off, unknown or maybe menuoverlays" 
1259                                 }                                                       
1260                                 msg = DDVD_SHOWOSD_SUBTITLE;
1261                                 safe_write(message_pipe, &msg, sizeof(int));
1262                                 safe_write(message_pipe, &spu_active_id, sizeof(int));
1263                                 safe_write(message_pipe, &spu_lang, sizeof(uint16_t));
1264                                 //printf("SPU Stream change: w %X l: %X p: %X active: %X\n",ev->physical_wide,ev->physical_letterbox,ev->physical_pan_scan,spu_active_id);
1265                                 break;
1266
1267                         case DVDNAV_AUDIO_STREAM_CHANGE:
1268                                 /* We received a new Audio stream ID  */
1269                                 if (!audio_lock)
1270                                 {
1271                                         audio_id = dvdnav_get_active_audio_stream(dvdnav);
1272                                         report_audio_info = 1;
1273                                 }
1274                                 break;
1275
1276                         case DVDNAV_HIGHLIGHT:
1277                                 /* Lets display some Buttons */
1278                                 if (ddvd_clear_buttons == 0) {
1279                                         dvdnav_highlight_event_t *highlight_event = (dvdnav_highlight_event_t *) buf;
1280
1281                                         pci = dvdnav_get_current_nav_pci(dvdnav);
1282                                         dsi = dvdnav_get_current_nav_dsi(dvdnav);
1283                                         dvdnav_highlight_area_t hl;
1284
1285                                         int libdvdnav_workaround = 0;
1286
1287                                         if (pci->hli.hl_gi.btngr_ns) {
1288                                                 int btns_per_group = 36 / pci->hli.hl_gi.btngr_ns;
1289                                                 btni_t *btni = NULL;
1290                                                 int modeMask = 1 << tv_scale;
1291
1292                                                 if (!btni && pci->hli.hl_gi.btngr_ns >= 1 && (pci->hli.hl_gi.btngr1_dsp_ty & modeMask)) {
1293                                                         btni = &pci->hli.btnit[0 * btns_per_group + highlight_event->buttonN - 1];
1294                                                 }
1295                                                 if (!btni && pci->hli.hl_gi.btngr_ns >= 2 && (pci->hli.hl_gi.btngr2_dsp_ty & modeMask)) {
1296                                                         btni = &pci->hli.btnit[1 * btns_per_group + highlight_event->buttonN - 1];
1297                                                 }
1298                                                 if (!btni && pci->hli.hl_gi.btngr_ns >= 3 && (pci->hli.hl_gi.btngr3_dsp_ty & modeMask)) {
1299                                                         btni = &pci->hli.btnit[2 * btns_per_group + highlight_event->buttonN - 1];
1300                                                 }
1301
1302                                                 if (btni && btni->btn_coln != 0) {
1303                                                         // get and set clut for actual button
1304                                                         unsigned char tmp, tmp2;
1305                                                         struct ddvd_color colneu;
1306                                                         int i;
1307                                                         msg = DDVD_COLORTABLE_UPDATE;
1308                                                         if (ddvd_screeninfo_bypp == 1)
1309                                                                 safe_write(message_pipe, &msg, sizeof(int));
1310                                                         for (i = 0; i < 4; i++) {
1311                                                                 tmp = ((pci->hli.btn_colit.btn_coli[btni->btn_coln - 1][0]) >> (16 + 4 * i)) & 0xf;
1312                                                                 tmp2 = ((pci->hli.btn_colit.btn_coli[btni->btn_coln - 1][0]) >> (4 * i)) & 0xf;
1313                                                                 colneu.blue = ddvd_bl[i + 252] = ddvd_bl[tmp];
1314                                                                 colneu.green = ddvd_gn[i + 252] = ddvd_gn[tmp];
1315                                                                 colneu.red = ddvd_rd[i + 252] = ddvd_rd[tmp];
1316                                                                 colneu.trans = ddvd_tr[i + 252] = (0xF - tmp2) * 0x1111;
1317                                                                 if (ddvd_screeninfo_bypp == 1)
1318                                                                         safe_write(message_pipe, &colneu, sizeof(struct ddvd_color));
1319                                                         }
1320                                                         msg = DDVD_NULL;
1321                                                         //CHANGE COLORMAP
1322
1323                                                         memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres);        //clear screen ..
1324                                                         //copy button into screen
1325                                                         for (i = btni->y_start; i < btni->y_end; i++) {
1326                                                                 if (ddvd_screeninfo_bypp == 1)
1327                                                                         memcpy(p_lfb + btni->x_start + ddvd_screeninfo_xres * (i),
1328                                                                                ddvd_lbb + btni->x_start + ddvd_screeninfo_xres * (i),
1329                                                                                btni->x_end - btni->x_start);
1330                                                                 else
1331                                                                         ddvd_blit_to_argb(p_lfb + btni->x_start * ddvd_screeninfo_bypp +
1332                                                                                           ddvd_screeninfo_stride * i,
1333                                                                                           ddvd_lbb + btni->x_start + ddvd_screeninfo_xres * (i),
1334                                                                                           btni->x_end - btni->x_start);
1335                                                         }
1336
1337                                                         libdvdnav_workaround = 1;
1338                                                 }
1339                                         }
1340                                         if (!libdvdnav_workaround && dvdnav_get_highlight_area(pci, highlight_event->buttonN, 0, &hl) == DVDNAV_STATUS_OK) {
1341                                                 // get and set clut for actual button
1342                                                 unsigned char tmp, tmp2;
1343                                                 struct ddvd_color colneu;
1344                                                 int i;
1345                                                 msg = DDVD_COLORTABLE_UPDATE;
1346                                                 if (ddvd_screeninfo_bypp == 1)
1347                                                         safe_write(message_pipe, &msg, sizeof(int));
1348                                                 for (i = 0; i < 4; i++) {
1349                                                         tmp = ((hl.palette) >> (16 + 4 * i)) & 0xf;
1350                                                         tmp2 = ((hl.palette) >> (4 * i)) & 0xf;
1351                                                         colneu.blue = ddvd_bl[i + 252] = ddvd_bl[tmp];
1352                                                         colneu.green = ddvd_gn[i + 252] = ddvd_gn[tmp];
1353                                                         colneu.red = ddvd_rd[i + 252] = ddvd_rd[tmp];
1354                                                         colneu.trans = ddvd_tr[i + 252] = (0xF - tmp2) * 0x1111;
1355                                                         if (ddvd_screeninfo_bypp == 1)
1356                                                                 safe_write(message_pipe, &colneu, sizeof(struct ddvd_color));
1357                                                 }
1358                                                 msg = DDVD_NULL;
1359                                                 //CHANGE COLORMAP
1360
1361                                                 memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres);        //clear screen ..
1362                                                 //copy button into screen
1363                                                 for (i = hl.sy; i < hl.ey; i++) {
1364                                                         if (ddvd_screeninfo_bypp == 1)
1365                                                                 memcpy(p_lfb + hl.sx + ddvd_screeninfo_xres * (i),
1366                                                                        ddvd_lbb + hl.sx + ddvd_screeninfo_xres * (i), hl.ex - hl.sx);
1367                                                         else
1368                                                                 ddvd_blit_to_argb(p_lfb + hl.sx * ddvd_screeninfo_bypp + ddvd_screeninfo_stride * i,
1369                                                                                   ddvd_lbb + hl.sx + ddvd_screeninfo_xres * (i), hl.ex - hl.sx);
1370                                                 }
1371                                                 libdvdnav_workaround = 1;
1372                                         }
1373                                         if (!libdvdnav_workaround)
1374                                                 memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres);        //clear screen .. 
1375
1376                                         if (ddvd_have_ntsc == 1)
1377                                                 ddvd_resize_pixmap(p_lfb, 720, 480, 720, 576, ddvd_screeninfo_bypp);
1378                                         msg = DDVD_SCREEN_UPDATE;
1379                                         safe_write(message_pipe, &msg, sizeof(int));
1380                                 } else {
1381                                         ddvd_clear_buttons = 0;
1382                                         //printf("clear buttons\n");
1383                                 }
1384                                 break;
1385
1386                         case DVDNAV_VTS_CHANGE:
1387                                 {
1388                                         /* Some status information like video aspect and video scale permissions do
1389                                          * not change inside a VTS. Therefore we will set it new at this place */
1390                                         ddvd_play_empty(FALSE);//ddvd_play_empty(TRUE);
1391                                         audio_lock = 0; // reset audio & spu lock
1392                                         spu_lock = 0;
1393                                         audio_format[0] = audio_format[1] = audio_format[2] = audio_format[4] = audio_format[4] = audio_format[5] = audio_format[6] = audio_format[7] = -1;
1394
1395                                         dvd_aspect = dvdnav_get_video_aspect(dvdnav);
1396                                         dvd_scale_perm = dvdnav_get_video_scale_permission(dvdnav);
1397                                         tv_scale = ddvd_check_aspect(dvd_aspect, dvd_scale_perm, tv_aspect);
1398                                         //printf("DVD Aspect: %d TV Aspect: %d Scale: %d Allowed: %d\n",dvd_aspect,tv_aspect,tv_scale,dvd_scale_perm);
1399                                         
1400                                         // resuming a dvd ?
1401                                         if (playerconfig->should_resume && first_vts_change) {
1402                                                 first_vts_change = 0;
1403                                                 int title_numbers,part_numbers;
1404                                                 dvdnav_get_number_of_titles(dvdnav, &title_numbers);
1405                                                 dvdnav_get_number_of_parts(dvdnav, playerconfig->resume_title, &part_numbers);
1406                                                 if (playerconfig->resume_title <= title_numbers && playerconfig->resume_title > 0 && playerconfig->resume_chapter <= part_numbers && playerconfig->resume_chapter > 0) {
1407                                                         dvdnav_part_play(dvdnav, playerconfig->resume_title, playerconfig->resume_chapter);
1408                                                         next_cell_change = 1;
1409                                                 } else {
1410                                                         playerconfig->should_resume = 0;
1411                                                         playerconfig->resume_title = 0;
1412                                                         playerconfig->resume_chapter = 0;
1413                                                         playerconfig->resume_block = 0;
1414                                                         playerconfig->resume_audio_id = 0;
1415                                                         playerconfig->resume_audio_lock = 0;
1416                                                         playerconfig->resume_spu_id = 0;
1417                                                         playerconfig->resume_spu_lock = 0;                                                      
1418                                                         perror("DVD resuming failed");
1419                                                 }
1420                                                 
1421                                                 
1422                                         }
1423                                 }
1424                                 break;
1425
1426                         case DVDNAV_CELL_CHANGE:
1427                                 {
1428                                         /* Store new cell information */
1429                                         memcpy(&ddvd_lastCellEventInfo, buf, sizeof(dvdnav_cell_change_event_t));
1430
1431                                         if ((ddvd_still_frame & CELL_STILL) && ddvd_iframesend == 0 && ddvd_last_iframe_len)
1432                                                 ddvd_iframesend = 1;
1433
1434                                         ddvd_still_frame = (dvdnav_get_next_still_flag(dvdnav) != 0) ? CELL_STILL : 0;
1435                                         
1436                                         // resuming a dvd ?
1437                                         if (playerconfig->should_resume && next_cell_change) {
1438                                                 next_cell_change = 0;
1439                                                 playerconfig->should_resume = 0;
1440                                                 if (dvdnav_sector_search(dvdnav, playerconfig->resume_block, SEEK_SET) != DVDNAV_STATUS_OK)
1441                                                 {
1442                                                         perror("DVD resuming failed");
1443                                                 } else {
1444                                                         audio_id = playerconfig->resume_audio_id;
1445                                                         audio_lock = 1;//playerconfig->resume_audio_lock;
1446                                                         spu_active_id = playerconfig->resume_spu_id & 0x1F;
1447                                                         spu_lock = 1;//playerconfig->resume_spu_lock;
1448                                                         report_audio_info = 1;
1449                                                         uint16_t spu_lang = 0xFFFF;
1450                                                         int spu_id_logical;
1451                                                         spu_id_logical = dvdnav_get_spu_logical_stream(dvdnav, spu_active_id);
1452                                                         spu_lang = dvdnav_spu_stream_to_lang(dvdnav, (spu_id_logical >= 0 ? spu_id_logical : spu_active_id) & 0x1F);
1453                                                         if (spu_lang == 0xFFFF) {
1454                                                                 spu_lang = 0x2D2D;      // SPU "off" 
1455                                                                 spu_active_id = -1;
1456                                                         }
1457                                                         msg = DDVD_SHOWOSD_SUBTITLE;
1458                                                         safe_write(message_pipe, &msg, sizeof(int));
1459                                                         safe_write(message_pipe, &spu_active_id, sizeof(int));
1460                                                         safe_write(message_pipe, &spu_lang, sizeof(uint16_t));
1461                                                         msg = DDVD_SHOWOSD_TIME; // send new position to the frontend
1462                                                 }
1463                                                 playerconfig->resume_title = 0;
1464                                                 playerconfig->resume_chapter = 0;
1465                                                 playerconfig->resume_block = 0;
1466                                                 playerconfig->resume_audio_id = 0;
1467                                                 playerconfig->resume_audio_lock = 0;
1468                                                 playerconfig->resume_spu_id = 0;
1469                                                 playerconfig->resume_spu_lock = 0;
1470                                         }
1471                                 }
1472                                 break;
1473
1474                         case DVDNAV_NAV_PACKET:
1475                                 /* A NAV packet provides PTS discontinuity information, angle linking information and
1476                                  * button definitions for DVD menus. We have to handle some stilframes here */
1477                                 pci = dvdnav_get_current_nav_pci(dvdnav);
1478                                 dsi = dvdnav_get_current_nav_dsi(dvdnav);
1479
1480                                 if ((ddvd_still_frame & NAV_STILL) && ddvd_iframesend == 0 && ddvd_last_iframe_len)
1481                                         ddvd_iframesend = 1;
1482
1483                                 if (dsi->vobu_sri.next_video == 0xbfffffff)
1484                                         ddvd_still_frame |= NAV_STILL;  //|= 1;
1485                                 else
1486                                         ddvd_still_frame &= ~NAV_STILL; //&= 1;
1487                                 break;
1488
1489                         case DVDNAV_HOP_CHANNEL:
1490                                 /* This event is issued whenever a non-seamless operation has been executed.
1491                                  * So we drop our buffers */
1492                                 ddvd_play_empty(TRUE);
1493                                 break;
1494
1495                         case DVDNAV_STOP:
1496                                 /* Playback should end here. */
1497                                 printf("DVDNAV_STOP\n");
1498                                 playerconfig->resume_title = 0;
1499                                 playerconfig->resume_chapter = 0;
1500                                 playerconfig->resume_block = 0;
1501                                 playerconfig->resume_audio_id = 0;
1502                                 playerconfig->resume_audio_lock = 0;
1503                                 playerconfig->resume_spu_id = 0;
1504                                 playerconfig->resume_spu_lock = 0;
1505                                 finished = 1;
1506                                 break;
1507
1508                         default:
1509                                 printf("Unknown event (%i)\n", event);
1510                                 finished = 1;
1511                                 break;
1512                         }
1513                 }
1514                 // spu handling
1515 #if CONFIG_API_VERSION == 1
1516                 unsigned int tpts;
1517                 if (ioctl(ddvd_output_fd, VIDEO_GET_PTS, &tpts) < 0)
1518                         perror("VIDEO_GET_PTS");
1519                 pts = (unsigned long long)tpts;
1520                 signed long long diff = spts - pts;
1521                 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
1522                                                                                                         // so on non animated menus the buttons will be displayed to soon, but we we have to accept it
1523 #else
1524                 if (ioctl(ddvd_fdvideo, VIDEO_GET_PTS, &pts) < 0)
1525                         perror("VIDEO_GET_PTS");
1526                 if (ddvd_spu_backnr > 0 && pts >= spu_backpts[0])
1527 #endif
1528                 {
1529                         int tmplen = (spu_backbuffer[0] << 8 | spu_backbuffer[1]);
1530
1531                         memset(ddvd_lbb, 0, ddvd_screeninfo_xres * ddvd_screeninfo_yres);       //clear backbuffer .. 
1532                         ddvd_display_time = ddvd_spu_decode_data(spu_backbuffer, tmplen);       // decode
1533                         ddvd_lbb_changed = 1;
1534
1535                         struct ddvd_color colneu;
1536                         int ctmp;
1537                         msg = DDVD_COLORTABLE_UPDATE;
1538                         if (ddvd_screeninfo_bypp == 1)
1539                                 safe_write(message_pipe, &msg, sizeof(int));
1540                         for (ctmp = 0; ctmp < 4; ctmp++) {
1541                                 colneu.blue = ddvd_bl[ctmp + 252];
1542                                 colneu.green = ddvd_gn[ctmp + 252];
1543                                 colneu.red = ddvd_rd[ctmp + 252];
1544                                 colneu.trans = ddvd_tr[ctmp + 252];
1545                                 if (ddvd_screeninfo_bypp == 1)
1546                                         safe_write(message_pipe, &colneu, sizeof(struct ddvd_color));
1547                         }
1548                         msg = DDVD_NULL;
1549
1550                         memcpy(spu_backbuffer, spu_backbuffer + tmplen, ddvd_spu_backptr - tmplen);     // delete SPU packet
1551                         spu_backpts[0] = spu_backpts[1];
1552                         spu_backpts[1] = spu_backpts[2];
1553                         ddvd_spu_backnr--;
1554                         ddvd_spu_backptr -= tmplen;
1555
1556                         // set timer
1557                         if (ddvd_display_time > 0) {
1558                                 ddvd_spu_timer_active = 1;
1559                                 ddvd_spu_timer_end = ddvd_get_time() + (ddvd_display_time * 10);        //ms
1560                         } else
1561                                 ddvd_spu_timer_active = 0;
1562
1563                         pci = dvdnav_get_current_nav_pci(dvdnav);       //update highlight buttons
1564                         dsi = dvdnav_get_current_nav_dsi(dvdnav);
1565                         if (pci->hli.hl_gi.btn_ns > 0) {
1566                                 dvdnav_get_current_highlight(dvdnav, &buttonN);
1567                                 dvdnav_button_select(dvdnav, pci, buttonN);
1568                                 ddvd_lbb_changed = 0;
1569                                 in_menu = 1;
1570                         }
1571                 }
1572
1573                 if (!in_menu) {
1574                         if (!pci)
1575                                 pci = dvdnav_get_current_nav_pci(dvdnav);
1576
1577                         in_menu = pci && pci->hli.hl_gi.btn_ns > 0;
1578                 }
1579
1580                 if (in_menu && !playerconfig->in_menu) {
1581                         int bla = DDVD_MENU_OPENED;
1582                         safe_write(message_pipe, &bla, sizeof(int));
1583                         playerconfig->in_menu = 1;
1584                 } else if (!in_menu && playerconfig->in_menu) {
1585                         int bla = DDVD_MENU_CLOSED;
1586                         safe_write(message_pipe, &bla, sizeof(int));
1587                         playerconfig->in_menu = 0;
1588                 }
1589
1590                 if (ddvd_wait_for_user) {
1591                         struct pollfd pfd[1];   // make new pollfd array
1592                         pfd[0].fd = key_pipe;
1593                         pfd[0].events = POLLIN | POLLPRI | POLLERR;
1594                         poll(pfd, 1, -1);
1595                 }
1596                 //Userinput
1597                 if (ddvd_readpipe(key_pipe, &rccode, sizeof(int), 0) == sizeof(int)) {
1598                         int keydone = 1;
1599
1600                         if (!dsi)
1601                                 dsi = dvdnav_get_current_nav_dsi(dvdnav);
1602
1603                         if (buttonN == -1)
1604                                 dvdnav_get_current_highlight(dvdnav, &buttonN);
1605
1606                         switch (rccode) // actions inside and outside of menu
1607                         {
1608                                 case DDVD_SET_MUTE:
1609                                         ismute = 1;
1610                                         break;
1611                                 case DDVD_UNSET_MUTE:
1612                                         ismute = 0;
1613                                         break;
1614                                 default:
1615                                         keydone = 0;
1616                                         break;
1617                         }
1618
1619                         if (!keydone && in_menu) {
1620                                 switch (rccode) //Actions inside a Menu
1621                                 {
1622                                 case DDVD_KEY_UP:       //Up
1623                                         dvdnav_upper_button_select(dvdnav, pci);
1624                                         break;
1625                                 case DDVD_KEY_DOWN:     //Down
1626                                         dvdnav_lower_button_select(dvdnav, pci);
1627                                         break;
1628                                 case DDVD_KEY_LEFT:     //left
1629                                         dvdnav_left_button_select(dvdnav, pci);
1630                                         break;
1631                                 case DDVD_KEY_RIGHT:    //right
1632                                         dvdnav_right_button_select(dvdnav, pci);
1633                                         break;
1634                                 case DDVD_KEY_OK:       //OK
1635                                         ddvd_wait_for_user = 0;
1636                                         memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres);        //clear screen ..
1637                                         memset(ddvd_lbb, 0, ddvd_screeninfo_xres * ddvd_screeninfo_yres);       //clear backbuffer
1638                                         msg = DDVD_SCREEN_UPDATE;
1639                                         safe_write(message_pipe, &msg, sizeof(int));
1640                                         ddvd_clear_buttons = 1;
1641                                         dvdnav_button_activate(dvdnav, pci);
1642                                         ddvd_play_empty(TRUE);
1643                                         if (ddvd_wait_timer_active)
1644                                                 ddvd_wait_timer_active = 0;
1645                                         break;
1646                                 case DDVD_KEY_MENU:     //Dream
1647                                         if (dvdnav_menu_call(dvdnav, DVD_MENU_Root) == DVDNAV_STATUS_OK)
1648                                                 ddvd_play_empty(TRUE);
1649                                         break;
1650                                 case DDVD_KEY_AUDIOMENU:        //Audio
1651                                         if (dvdnav_menu_call(dvdnav, DVD_MENU_Audio) == DVDNAV_STATUS_OK)
1652                                                 ddvd_play_empty(TRUE);
1653                                         break;
1654                                 case DDVD_KEY_EXIT:     //Exit
1655                                         {
1656                                                 printf("DDVD_KEY_EXIT (menu)\n");
1657                                                 playerconfig->resume_title = 0;
1658                                                 playerconfig->resume_chapter = 0;
1659                                                 playerconfig->resume_block = 0;
1660                                                 playerconfig->resume_audio_id = 0;
1661                                                 playerconfig->resume_audio_lock = 0;
1662                                                 playerconfig->resume_spu_id = 0;
1663                                                 playerconfig->resume_spu_lock = 0;
1664                                                 finished = 1;
1665                                         }
1666                                         break;                                          
1667                                 case DDVD_SKIP_FWD:
1668                                 case DDVD_SKIP_BWD:
1669                                 case DDVD_SET_TITLE:
1670                                 case DDVD_SET_CHAPTER:
1671                                         // we must empty the pipe here...
1672                                         ddvd_readpipe(key_pipe, &keydone, sizeof(int), 1);
1673                                 default:
1674                                         break;
1675                                 }
1676                         } else if (!keydone)    //Actions inside a Movie
1677                         {
1678                                 switch (rccode) //Main Actions
1679                                 {
1680                                 case DDVD_KEY_PREV_CHAPTER:     //left
1681                                         {
1682                                                 int titleNo, chapterNumber, chapterNo;
1683                                                 dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
1684                                                 dvdnav_get_number_of_parts(dvdnav, titleNo, &chapterNumber);
1685                                                 chapterNo--;
1686                                                 if (chapterNo > chapterNumber)
1687                                                         chapterNo = 1;
1688                                                 if (chapterNo <= 0)
1689                                                         chapterNo = chapterNumber;
1690                                                 dvdnav_part_play(dvdnav, titleNo, chapterNo);
1691                                                 ddvd_play_empty(TRUE);
1692                                                 msg = DDVD_SHOWOSD_TIME;
1693                                                 break;
1694                                         }
1695                                 case DDVD_KEY_NEXT_CHAPTER:     //right
1696                                         {
1697                                                 int titleNo, chapterNumber, chapterNo;
1698                                                 dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
1699                                                 dvdnav_get_number_of_parts(dvdnav, titleNo, &chapterNumber);
1700                                                 chapterNo++;
1701                                                 if (chapterNo > chapterNumber)
1702                                                         chapterNo = 1;
1703                                                 if (chapterNo <= 0)
1704                                                         chapterNo = chapterNumber;
1705                                                 dvdnav_part_play(dvdnav, titleNo, chapterNo);
1706                                                 ddvd_play_empty(TRUE);
1707                                                 msg = DDVD_SHOWOSD_TIME;
1708                                                 break;
1709                                         }
1710                                 case DDVD_KEY_PREV_TITLE:
1711                                         {
1712                                                 int titleNo, titleNumber, chapterNo;
1713                                                 dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
1714                                                 dvdnav_get_number_of_titles(dvdnav, &titleNumber);
1715                                                 titleNo--;
1716                                                 if (titleNo > titleNumber)
1717                                                         titleNo = 1;
1718                                                 if (titleNo <= 0)
1719                                                         titleNo = titleNumber;
1720                                                 dvdnav_part_play(dvdnav, titleNo, 1);
1721                                                 ddvd_play_empty(TRUE);
1722                                                 msg = DDVD_SHOWOSD_TIME;
1723                                                 break;
1724                                         }
1725                                 case DDVD_KEY_NEXT_TITLE:
1726                                         {
1727                                                 int titleNo, titleNumber, chapterNo;
1728                                                 dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
1729                                                 dvdnav_get_number_of_titles(dvdnav, &titleNumber);
1730                                                 titleNo++;
1731                                                 if (titleNo > titleNumber)
1732                                                         titleNo = 1;
1733                                                 if (titleNo <= 0)
1734                                                         titleNo = titleNumber;
1735                                                 dvdnav_part_play(dvdnav, titleNo, 1);
1736                                                 ddvd_play_empty(TRUE);
1737                                                 msg = DDVD_SHOWOSD_TIME;
1738                                                 break;
1739                                         }
1740                                 case DDVD_KEY_PAUSE:    // Pause
1741                                         {
1742                                                 if (ddvd_playmode == PLAY) {
1743                                                         ddvd_playmode = PAUSE;
1744                                                         if (ioctl(ddvd_fdaudio, AUDIO_PAUSE) < 0)
1745                                                                 perror("AUDIO_PAUSE");
1746                                                         if (ioctl(ddvd_fdvideo, VIDEO_FREEZE) < 0)
1747                                                                 perror("VIDEO_FREEZE");
1748                                                         msg = DDVD_SHOWOSD_STATE_PAUSE;
1749                                                         safe_write(message_pipe, &msg, sizeof(int));
1750                                                         break;
1751                                                 } else if (ddvd_playmode != PAUSE)
1752                                                         break;
1753                                                 // fall through to PLAY
1754                                         }
1755                                 case DDVD_KEY_PLAY:     // Play
1756                                         {
1757                                                 if (ddvd_playmode == PAUSE || ddvd_trickmode) {
1758                                                         ddvd_playmode = PLAY;
1759 key_play:
1760 #if CONFIG_API_VERSION == 1
1761                                                         ddvd_device_clear();
1762 #endif
1763                                                         if (ddvd_trickmode && !ismute)
1764                                                                 if (ioctl(ddvd_fdaudio, AUDIO_SET_MUTE, 0) < 0)
1765                                                                         perror("AUDIO_SET_MUTE");
1766                                                         ddvd_trickmode = TOFF;
1767                                                         if (ddvd_playmode == PLAY) {
1768                                                                 if (ioctl(ddvd_fdaudio, AUDIO_CONTINUE) < 0)
1769                                                                         perror("AUDIO_CONTINUE");
1770                                                                 if (ioctl(ddvd_fdvideo, VIDEO_CONTINUE) < 0)
1771                                                                         perror("VIDEO_CONTINUE");
1772                                                                 msg = DDVD_SHOWOSD_STATE_PLAY;
1773                                                                 safe_write(message_pipe, &msg, sizeof(int));
1774                                                         }
1775                                                         msg = DDVD_SHOWOSD_TIME;
1776                                                 }
1777                                                 break;
1778                                         }
1779                                 case DDVD_KEY_MENU:     //Dream
1780                                         if (dvdnav_menu_call(dvdnav, DVD_MENU_Root) == DVDNAV_STATUS_OK)
1781                                                 ddvd_play_empty(TRUE);
1782                                         break;
1783                                 case DDVD_KEY_AUDIOMENU:        //Audio
1784                                         if (dvdnav_menu_call(dvdnav, DVD_MENU_Audio) == DVDNAV_STATUS_OK)
1785                                                 ddvd_play_empty(TRUE);
1786                                         break;
1787                                 case DDVD_KEY_EXIT:     //Exit
1788                                         {
1789                                                 printf("DDVD_KEY_EXIT (menu)\n");
1790                                                 int resume_title, resume_chapter; //safe resume info
1791                                                 uint32_t resume_block, total_block;
1792                                                 if (dvdnav_current_title_info(dvdnav, &resume_title, &resume_chapter) && (0 != resume_title)) {
1793                                                         if(dvdnav_get_position (dvdnav, &resume_block, &total_block) == DVDNAV_STATUS_OK) {
1794                                                                 playerconfig->resume_title = resume_title;
1795                                                                 playerconfig->resume_chapter = resume_chapter;
1796                                                                 playerconfig->resume_block = resume_block;
1797                                                                 playerconfig->resume_audio_id = audio_id;
1798                                                                 playerconfig->resume_audio_lock = audio_lock;
1799                                                                 playerconfig->resume_spu_id = spu_active_id;
1800                                                                 playerconfig->resume_spu_lock = spu_lock;
1801                                                         } else perror("error getting resume position");
1802                                                 } perror("error getting resume position");                                      
1803                                                 finished = 1;
1804                                         }
1805                                         break;                                          
1806                                 case DDVD_KEY_FFWD:     //FastForward
1807                                 case DDVD_KEY_FBWD:     //FastBackward
1808                                         {
1809                                                 if (ddvd_trickmode == TOFF) {
1810                                                         if (ioctl(ddvd_fdaudio, AUDIO_SET_MUTE, 1) < 0)
1811                                                                 perror("AUDIO_SET_MUTE");
1812                                                         ddvd_trickspeed = 2;
1813                                                         ddvd_trickmode = (rccode == DDVD_KEY_FBWD ? FASTBW : FASTFW);
1814                                                 } else if (ddvd_trickmode == (rccode == DDVD_KEY_FBWD ? FASTFW : FASTBW)) {
1815                                                         ddvd_trickspeed /= 2;
1816                                                         if (ddvd_trickspeed == 1) {
1817                                                                 ddvd_trickspeed = 0;
1818                                                                 goto key_play;
1819                                                         }
1820                                                 } else if (ddvd_trickspeed < 64)
1821                                                         ddvd_trickspeed *= 2;
1822                                                 break;
1823                                         }
1824                                 case DDVD_KEY_AUDIO:    //change audio track 
1825                                         {
1826                                                 int count = 0;
1827                                                 audio_id = (audio_id == 7 ? 0 : audio_id+1);
1828                                                 while (audio_format[audio_id] == -1 && count++ < 7)
1829                                                 {
1830                                                         audio_id = (audio_id == 7 ? 0 : audio_id+1);
1831                                                 }
1832                                                 report_audio_info = 1;
1833                                                 ddvd_play_empty(TRUE);
1834                                                 audio_lock = 1;
1835                                                 ddvd_lpcm_count = 0;
1836                                                 break;
1837                                         }
1838                                 case DDVD_KEY_SUBTITLE: //change spu track 
1839                                         {
1840                                                 uint16_t spu_lang = 0xFFFF;
1841                                                 int spu_id_logical;
1842                                                 spu_active_id++;
1843                                                 spu_id_logical = dvdnav_get_spu_logical_stream(dvdnav, spu_active_id);
1844                                                 spu_lang = dvdnav_spu_stream_to_lang(dvdnav, (spu_id_logical >= 0 ? spu_id_logical : spu_active_id) & 0x1F);
1845                                                 if (spu_lang == 0xFFFF) {
1846                                                         spu_lang = 0x2D2D;      // SPU "off" 
1847                                                         spu_active_id = -1;
1848                                                 }
1849                                                 spu_lock = 1;
1850                                                 msg = DDVD_SHOWOSD_SUBTITLE;
1851                                                 safe_write(message_pipe, &msg, sizeof(int));
1852                                                 safe_write(message_pipe, &spu_active_id, sizeof(int));
1853                                                 safe_write(message_pipe, &spu_lang, sizeof(uint16_t));
1854                                                 break;
1855                                         }
1856                                 case DDVD_GET_TIME:     // frontend wants actual time
1857                                         msg = DDVD_SHOWOSD_TIME;
1858                                         break;
1859                                 case DDVD_SKIP_FWD:
1860                                 case DDVD_SKIP_BWD:
1861                                         {
1862                                                 int skip;
1863                                                 ddvd_readpipe(key_pipe, &skip, sizeof(int), 1);
1864                                                 if (ddvd_trickmode == TOFF) {
1865                                                         uint32_t pos, len;
1866                                                         dvdnav_get_position(dvdnav, &pos, &len);
1867                                                         printf("DDVD_SKIP pos=%u len=%u \n", pos, len);
1868                                                         //90000 = 1 Sek.
1869                                                         if (!len)
1870                                                                 len = 1;
1871                                                         long long int posneu = ((pos * ddvd_lastCellEventInfo.pgc_length) / len) + (90000 * skip);
1872                                                         printf("DDVD_SKIP posneu1=%lld\n", posneu);
1873                                                         long long int posneu2 = posneu <= 0 ? 0 : (posneu * len) / ddvd_lastCellEventInfo.pgc_length;
1874                                                         printf("DDVD_SKIP posneu2=%lld\n", posneu2);
1875                                                         if (len && posneu2 && posneu2 >= len)   // reached end of movie
1876                                                         {
1877                                                                 posneu2 = len - 250;
1878                                                                 reached_eof = 1;
1879                                                         }
1880                                                         dvdnav_sector_search(dvdnav, posneu2, SEEK_SET);
1881                                                         ddvd_lpcm_count = 0;
1882                                                         msg = DDVD_SHOWOSD_TIME;
1883                                                 }
1884                                                 break;
1885                                         }
1886                                 case DDVD_SET_TITLE:
1887                                         {
1888                                                 int title, totalTitles;
1889                                                 ddvd_readpipe(key_pipe, &title, sizeof(int), 1);
1890                                                 dvdnav_get_number_of_titles(dvdnav, &totalTitles);
1891                                                 printf("DDVD_SET_TITLE %d/%d\n", title, totalTitles);
1892                                                 if (title <= totalTitles) {
1893                                                         dvdnav_part_play(dvdnav, title, 0);
1894                                                         ddvd_play_empty(TRUE);
1895                                                         msg = DDVD_SHOWOSD_TIME;
1896                                                 }
1897                                                 break;
1898                                         }
1899                                 case DDVD_SET_CHAPTER:
1900                                         {
1901                                                 int chapter, totalChapters, chapterNo, titleNo;
1902                                                 ddvd_readpipe(key_pipe, &chapter, sizeof(int), 1);
1903                                                 dvdnav_current_title_info(dvdnav, &titleNo, &chapterNo);
1904                                                 dvdnav_get_number_of_parts(dvdnav, titleNo, &totalChapters);
1905                                                 printf("DDVD_SET_CHAPTER %d/%d in title %d\n", chapter, totalChapters, titleNo);
1906                                                 if (chapter <= totalChapters) {
1907                                                         dvdnav_part_play(dvdnav, titleNo, chapter);
1908                                                         ddvd_play_empty(TRUE);
1909                                                         msg = DDVD_SHOWOSD_TIME;
1910                                                 }
1911                                                 break;
1912                                         }
1913                                 default:
1914                                         break;
1915                                 }
1916                         }
1917                 }
1918                 // spu handling
1919                 if (ddvd_lbb_changed == 1) {
1920                         if (ddvd_screeninfo_bypp == 1)
1921                                 memcpy(p_lfb, ddvd_lbb, ddvd_screeninfo_xres * ddvd_screeninfo_yres);   //copy SPU backbuffer into screen
1922                         else {
1923                                 int i = 0;
1924                                 for (; i < ddvd_screeninfo_yres; ++i)
1925                                         ddvd_blit_to_argb(p_lfb + i * ddvd_screeninfo_stride, ddvd_lbb + i * ddvd_screeninfo_xres, ddvd_screeninfo_xres);
1926                         }
1927                         if (ddvd_have_ntsc == 1)
1928                                 ddvd_resize_pixmap(p_lfb, 720, 480, 720, 576, ddvd_screeninfo_bypp);
1929                         int msg_old = msg;      // save and restore msg it may not bee empty
1930                         msg = DDVD_SCREEN_UPDATE;
1931                         safe_write(message_pipe, &msg, sizeof(int));
1932                         msg = msg_old;
1933                         ddvd_lbb_changed = 0;
1934                 }
1935                 // report audio info
1936                 if (report_audio_info) { 
1937                         if (audio_format[audio_id] > -1) {
1938                                 uint16_t audio_lang = 0xFFFF;
1939                                 int audio_id_logical;
1940                                 audio_id_logical = dvdnav_get_audio_logical_stream(dvdnav, audio_id);
1941                                 audio_lang = dvdnav_audio_stream_to_lang(dvdnav, audio_id_logical);
1942                                 if (audio_lang == 0xFFFF)
1943                                         audio_lang = 0x2D2D;    
1944                                 msg = DDVD_SHOWOSD_AUDIO;
1945                                 safe_write(message_pipe, &msg, sizeof(int));
1946                                 safe_write(message_pipe, &audio_id, sizeof(int));
1947                                 safe_write(message_pipe, &audio_lang, sizeof(uint16_t));
1948                                 safe_write(message_pipe, &audio_format[audio_id], sizeof(int));
1949                                 report_audio_info = 0;
1950                         }
1951                 }
1952
1953         }
1954
1955 err_dvdnav:
1956         /* destroy dvdnav handle */
1957         if (dvdnav_close(dvdnav) != DVDNAV_STATUS_OK)
1958                 printf("Error on dvdnav_close: %s\n", dvdnav_err_to_string(dvdnav));
1959
1960 err_dvdnav_open:
1961         if (ioctl(ddvd_fdvideo, VIDEO_CLEAR_BUFFER) < 0)
1962                 perror("VIDEO_CLEAR_BUFFER");
1963         if (ioctl(ddvd_fdvideo, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
1964                 perror("VIDEO_SELECT_SOURCE");
1965         if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
1966                 perror("AUDIO_CLEAR_BUFFER");
1967         if (ioctl(ddvd_fdaudio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX) < 0)
1968                 perror("AUDIO_SELECT_SOURCE");
1969
1970         if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)      // restore AudioDecoder State
1971                 perror("AUDIO_SET_AV_SYNC");
1972         if (ioctl(ddvd_fdaudio, AUDIO_SET_BYPASS_MODE, 1) < 0)
1973                 perror("AUDIO_SET_BYPASS_MODE");
1974
1975         close(ddvd_ac3_fd);
1976 err_open_ac3_fd:
1977         close(ddvd_fdaudio);
1978 err_open_fdaudio:
1979         close(ddvd_fdvideo);
1980 err_open_fdvideo:
1981         close(ddvd_output_fd);
1982 err_open_output_fd:
1983
1984         if (have_liba52) {
1985                 a52_free(state);
1986                 ddvd_close_liba52();
1987         }
1988
1989         //Clear Screen
1990         memset(p_lfb, 0, ddvd_screeninfo_stride * ddvd_screeninfo_yres);
1991         msg = DDVD_SCREEN_UPDATE;
1992         safe_write(message_pipe, &msg, sizeof(int));
1993
1994 err_malloc:
1995         // clean up
1996         if (ddvd_lbb != NULL)
1997                 free(ddvd_lbb);
1998         if (last_iframe != NULL)
1999                 free(last_iframe);
2000         if (spu_buffer != NULL)
2001                 free(spu_buffer);
2002         if (spu_backbuffer != NULL)
2003                 free(spu_backbuffer);
2004
2005 #if CONFIG_API_VERSION == 3
2006         ddvd_unset_pcr_offset();
2007 #endif
2008         return res;
2009 }
2010
2011 /*
2012  * internal functions
2013  */
2014
2015 // reading from pipe
2016 static int ddvd_readpipe(int pipefd, void *dest, size_t bytes, int blocked_read)
2017 {
2018         size_t bytes_completed = 0;
2019
2020         while (bytes_completed < bytes) {
2021                 ssize_t rd = read(pipefd, dest + bytes_completed, bytes - bytes_completed);
2022                 if (rd < 0) {
2023                         if (errno == EAGAIN) {
2024                                 if (blocked_read || bytes_completed) {
2025                                         usleep(1);
2026                                         continue;
2027                                 }
2028                                 break;  // leave while loop
2029                         }
2030                         /* else if (errno == ????) // hier sollte evtl noch geschaut werden welcher error code kommt wenn die pipe geschlossen wurde... 
2031                            break; */
2032                         printf("unhandled read error %d(%m)\n", errno);
2033                 }
2034
2035                 bytes_completed += rd;
2036                 if (!blocked_read && !bytes_completed)
2037                         break;
2038         }
2039
2040         return bytes_completed;
2041 }
2042
2043 // get actual playing time
2044 static struct ddvd_time ddvd_get_osd_time(struct ddvd *playerconfig)
2045 {
2046         int titleNo;
2047         struct ddvd_time info;
2048         uint32_t pos, len;
2049
2050         info.pos_minutes = info.pos_hours = info.pos_seconds = info.pos_chapter = info.pos_title = 0;
2051         info.end_minutes = info.end_hours = info.end_seconds = info.end_chapter = 0;
2052
2053         dvdnav_get_number_of_titles(dvdnav, &info.end_title);
2054         dvdnav_current_title_info(dvdnav, &titleNo, &info.pos_chapter);
2055
2056         if (titleNo) {
2057                 dvdnav_get_number_of_parts(dvdnav, titleNo, &info.end_chapter);
2058                 dvdnav_get_position_in_title(dvdnav, &pos, &len);
2059
2060                 uint64_t len_s = ddvd_lastCellEventInfo.pgc_length / 90000;
2061                 uint64_t pos_s = ((ddvd_lastCellEventInfo.pgc_length / len) * pos) / 90000;
2062
2063                 info.pos_minutes = pos_s / 60;
2064                 info.pos_hours = info.pos_minutes / 60;
2065                 info.pos_minutes = info.pos_minutes - (info.pos_hours * 60);
2066                 info.pos_seconds = pos_s - ((info.pos_hours * 60) + info.pos_minutes) * 60;
2067                 info.end_minutes = len_s / 60;
2068                 info.end_hours = info.end_minutes / 60;
2069                 info.end_minutes = info.end_minutes - (info.end_hours * 60);
2070                 info.end_seconds = len_s - ((info.end_hours * 60) + info.end_minutes) * 60;
2071
2072                 info.pos_title = titleNo;
2073         }
2074
2075         playerconfig->next_time_update = ddvd_get_time() + 1000;
2076
2077         return info;
2078 }
2079
2080 // video out aspect/scale
2081 static int ddvd_check_aspect(int dvd_aspect, int dvd_scale_perm, int tv_aspect)
2082 {
2083         const char *aspect = NULL, *policy = NULL, *policy2 = NULL, *saa2 = NULL;
2084         int tv_scale = 0;
2085         int saa;
2086
2087         if (tv_aspect == 2)     // tv 16:9
2088         {
2089                 if (dvd_aspect == 0) {
2090                         aspect = "4:3";
2091                         policy = "VIDEO_PAN_SCAN";      //no scaling needed
2092                         policy2 = "panscan";
2093                         tv_scale = 0;   //off
2094                         saa = SAA_WSS_43F;
2095                         saa2 = "4:3_full_format";
2096                 } else {
2097                         aspect = "16:9";
2098                         policy = "VIDEO_CENTER_CUT_OUT";        //no scaling needed
2099                         policy2 = "bestfit";
2100                         tv_scale = 0;   //off
2101                         saa = SAA_WSS_169F;
2102                         saa2 = "16:9_full_format";
2103                 }
2104         } else if (tv_aspect == 3)      // tv always 16:9
2105         {
2106                 aspect = "16:9";
2107                 policy = "VIDEO_CENTER_CUT_OUT";        //no scaling needed
2108                 policy2 = "panscan";
2109                 tv_scale = 0;   //off
2110                 saa = SAA_WSS_169F;
2111                 saa2 = "16:9_full_format";
2112         } else                  // tv 4:3
2113         {
2114                 aspect = "4:3";
2115                 saa = SAA_WSS_43F;
2116                 saa2 = "4:3_full_format";
2117                 if (dvd_aspect == 0)    // dvd 4:3 ...
2118                 {
2119                         policy = "VIDEO_PAN_SCAN";      //no scaling needed
2120                         policy2 = "panscan";
2121                         tv_scale = 0;   //off
2122                 } else          // dvd 16:9 ... need scaling prefer letterbox (tv_aspect 0)
2123                 {
2124                         if (!(dvd_scale_perm & 1))      // letterbox allowed
2125                         {
2126                                 policy = "VIDEO_LETTER_BOX";
2127                                 policy2 = "letterbox";
2128                                 tv_scale = 1;   //letterbox
2129                         } else if (!(dvd_scale_perm & 2))       // panscan allowed
2130                         {
2131                                 policy = "VIDEO_PAN_SCAN";
2132                                 policy2 = "panscan";
2133                                 tv_scale = 2;   //panscan
2134                         } else  // should not happen
2135                         {
2136                                 policy = "VIDEO_LETTER_BOX";
2137                                 policy2 = "letterbox";
2138                                 tv_scale = 1;   //off
2139                         }
2140                 }
2141                 if (tv_aspect == 1 && tv_scale == 1 && !(dvd_scale_perm & 2))   // prefer panscan if allowed (tv_aspect 1)
2142                 {
2143                         policy = "VIDEO_PAN_SCAN";
2144                         policy2 = "panscan";
2145                         tv_scale = 2;   //panscan
2146                 }
2147         }
2148
2149         if (ioctl(ddvd_fdvideo, VIDEO_SET_DISPLAY_FORMAT, policy) < 0)
2150                 perror("VIDEO_SET_DISPLAY_FORMAT");
2151
2152         int saafd = open("/dev/dbox/saa0", O_RDWR);
2153         if (saafd >= 0) {
2154                 if (ioctl(saafd, SAAIOSWSS, &saa) < 0)
2155                         perror("SAAIOSWSS");
2156                 close(saafd);
2157         }
2158
2159         // switch video aspect
2160         write_string("/proc/stb/video/aspect", aspect);
2161         // switch video scaling
2162         write_string("/proc/stb/video/policy", policy2);
2163         // switch wss
2164         write_string("/proc/stb/denc/0/wss", saa2);
2165
2166         return tv_scale;
2167 }
2168
2169 // get timestamp
2170 static uint64_t ddvd_get_time(void)
2171 {
2172         static time_t t0 = 0;
2173         struct timeval t;
2174
2175         if (gettimeofday(&t, NULL) == 0) {
2176                 if (t0 == 0)
2177                         t0 = t.tv_sec;  // this avoids an overflow (we only work with deltas)
2178                 return (uint64_t) (t.tv_sec - t0) * 1000 + (uint64_t) (t.tv_usec / 1000);
2179         }
2180
2181         return 0;
2182 }
2183
2184 // Empty all Buffers
2185 static void ddvd_play_empty(int device_clear)
2186 {
2187         ddvd_wait_for_user = 0;
2188         ddvd_clear_buttons = 0;
2189         ddvd_lpcm_count = 0;
2190         ddvd_iframerun = 0;
2191         ddvd_still_frame = 0;
2192         ddvd_iframesend = 0;
2193         ddvd_last_iframe_len = 0;
2194         ddvd_spu_ptr = 0;
2195         ddvd_spu_backnr = 0;
2196         ddvd_spu_backptr = 0;
2197
2198         ddvd_wait_timer_active = 0;
2199         ddvd_wait_timer_end = 0;
2200
2201         ddvd_spu_timer_active = 0;
2202         ddvd_spu_timer_end = 0;
2203
2204         //memset(ddvd_lbb, 0, ddvd_screeninfo_xres*ddvd_screeninfo_yres); //clear SPU backbuffer
2205         //ddvd_lbb_changed=1;
2206
2207         if (device_clear)
2208                 ddvd_device_clear();
2209 }
2210
2211 // Empty Device Buffers
2212 static void ddvd_device_clear(void)
2213 {
2214         if (ioctl(ddvd_fdaudio, AUDIO_STOP) < 0)
2215                 perror("AUDIO_STOP");
2216         if (ioctl(ddvd_fdaudio, AUDIO_CLEAR_BUFFER) < 0)
2217                 perror("AUDIO_CLEAR_BUFFER");
2218         if (ioctl(ddvd_fdaudio, AUDIO_PLAY) < 0)
2219                 perror("AUDIO_PLAY");
2220
2221         if (ioctl(ddvd_fdvideo, VIDEO_CLEAR_BUFFER) < 0)
2222                 perror("VIDEO_CLEAR_BUFFER");
2223         if (ioctl(ddvd_fdvideo, VIDEO_PLAY) < 0)
2224                 perror("VIDEO_PLAY");
2225
2226         if (ioctl(ddvd_fdaudio, AUDIO_SET_AV_SYNC, 1) < 0)
2227                 perror("AUDIO_SET_AV_SYNC");
2228 }
2229
2230 // SPU Decoder
2231 static int ddvd_spu_decode_data(const uint8_t * buffer, int len)
2232 {
2233         int x1spu, x2spu, y1spu, y2spu, xspu, yspu;
2234         int offset[2];
2235         int size, datasize, controlsize, aligned, id;
2236         int menubutton = 0;
2237         int display_time = -1;
2238
2239         size = (buffer[0] << 8 | buffer[1]);
2240         datasize = (buffer[2] << 8 | buffer[3]);
2241         controlsize = (buffer[datasize + 2] << 8 | buffer[datasize + 3]);
2242
2243         //printf("SPU_dec: Size: %X Datasize: %X Controlsize: %X\n",size,datasize,controlsize);
2244         // parse header
2245         int i = datasize + 4;
2246
2247         while (i < size && buffer[i] != 0xFF) {
2248                 switch (buffer[i]) {
2249                 case 0x00:      /* menu button special color handling */
2250                         menubutton = 1;
2251                         memset(ddvd_lbb, 0, ddvd_screeninfo_xres * ddvd_screeninfo_yres);       //clear backbuffer
2252                         i++;
2253                         break;
2254                 case 0x01:      /* show */
2255                         i++;
2256                         break;
2257                 case 0x02:      /* hide */
2258                         i++;
2259                         break;
2260                 case 0x03:      /* palette */
2261                         {
2262                                 ddvd_spudec_clut_t *clut = (ddvd_spudec_clut_t *) (buffer + i + 1);
2263                                 //printf("update palette %d %d %d %d\n", clut->entry0, clut->entry1, clut->entry2, clut->entry3);
2264
2265                                 ddvd_bl[3 + 252] = ddvd_bl[clut->entry0];
2266                                 ddvd_gn[3 + 252] = ddvd_gn[clut->entry0];
2267                                 ddvd_rd[3 + 252] = ddvd_rd[clut->entry0];
2268
2269                                 ddvd_bl[2 + 252] = ddvd_bl[clut->entry1];
2270                                 ddvd_gn[2 + 252] = ddvd_gn[clut->entry1];
2271                                 ddvd_rd[2 + 252] = ddvd_rd[clut->entry1];
2272
2273                                 ddvd_bl[1 + 252] = ddvd_bl[clut->entry2];
2274                                 ddvd_gn[1 + 252] = ddvd_gn[clut->entry2];
2275                                 ddvd_rd[1 + 252] = ddvd_rd[clut->entry2];
2276
2277                                 ddvd_bl[0 + 252] = ddvd_bl[clut->entry3];
2278                                 ddvd_gn[0 + 252] = ddvd_gn[clut->entry3];
2279                                 ddvd_rd[0 + 252] = ddvd_rd[clut->entry3];
2280
2281                                 //CHANGE COLORMAP
2282                                 i += 3;
2283                         }
2284                         break;
2285                 case 0x04:      /* transparency palette */
2286                         {
2287                                 ddvd_spudec_clut_t *clut = (ddvd_spudec_clut_t *) (buffer + i + 1);
2288                                 //printf("update transp palette %d %d %d %d\n", clut->entry0, clut->entry1, clut->entry2, clut->entry3);
2289
2290                                 ddvd_tr[0 + 252] = (0xF - clut->entry3) * 0x1111;
2291                                 ddvd_tr[1 + 252] = (0xF - clut->entry2) * 0x1111;
2292                                 ddvd_tr[2 + 252] = (0xF - clut->entry1) * 0x1111;
2293                                 ddvd_tr[3 + 252] = (0xF - clut->entry0) * 0x1111;
2294
2295                                 //CHANGE COLORMAP
2296                                 i += 3;
2297                         }
2298                         break;
2299                 case 0x05:      /* image coordinates */
2300                         //printf("image coords\n");
2301                         xspu = x1spu = (((unsigned int)buffer[i + 1]) << 4) + (buffer[i + 2] >> 4);
2302                         yspu = y1spu = (((unsigned int)buffer[i + 4]) << 4) + (buffer[i + 5] >> 4);
2303                         x2spu = (((buffer[i + 2] & 0x0f) << 8) + buffer[i + 3]);
2304                         y2spu = (((buffer[i + 5] & 0x0f) << 8) + buffer[i + 6]);
2305                         //printf("%d %d %d %d\n", xspu, yspu, x2spu, y2spu);
2306                         i += 7;
2307                         break;
2308                 case 0x06:      /* image 1 / image 2 offsets */
2309                         //printf("image offsets\n");
2310                         offset[0] = (((unsigned int)buffer[i + 1]) << 8) + buffer[i + 2];
2311                         offset[1] = (((unsigned int)buffer[i + 3]) << 8) + buffer[i + 4];
2312                         //printf("%d %d\n", offset[0], offset[1]);
2313                         i += 5;
2314                         break;
2315                 default:
2316                         i++;
2317                         break;
2318                 }
2319         }
2320
2321         //get display time
2322         if (i + 6 <= size) {
2323                 if (buffer[i + 5] == 0x02 && buffer[i + 6] == 0xFF) {
2324                         display_time = ((buffer[i + 1] << 8) + buffer[i + 2]);
2325                         //printf("Display Time: %d\n",ddvd_display_time);
2326                 }
2327         }
2328         //printf("SPU_dec: Image coords x1: %d y1: %d x2: %d y2: %d\n",x1spu,y1spu,x2spu,y2spu);
2329         //printf("Offset[0]: %X Offset[1]: %X\n",offset[0],offset[1]);
2330
2331         // parse picture
2332
2333         aligned = 1;
2334         id = 0;
2335
2336         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 ;)
2337         {
2338                 u_int len;
2339                 u_int code;
2340
2341                 code = (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
2342                 aligned = aligned ? 0 : 1;
2343
2344                 if (code < 0x0004) {
2345                         code = (code << 4) | (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
2346                         aligned = aligned ? 0 : 1;
2347                         if (code < 0x0010) {
2348                                 code = (code << 4) | (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
2349                                 aligned = aligned ? 0 : 1;
2350                                 if (code < 0x0040) {
2351                                         code = (code << 4) | (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
2352                                         aligned = aligned ? 0 : 1;
2353                                 }
2354                         }
2355                 }
2356
2357                 len = code >> 2;
2358
2359                 if (len == 0)
2360                         len = x2spu - xspu;
2361
2362                 memset(ddvd_lbb + xspu + ddvd_screeninfo_xres * (yspu), (code & 3) + 252, len); //drawpixel into backbuffer
2363                 xspu += len;
2364                 if (xspu >= x2spu) {
2365                         if (!aligned) {
2366                                 code = (aligned ? (buffer[offset[id]++] >> 4) : (buffer[offset[id] - 1] & 0xF));
2367                                 aligned = aligned ? 0 : 1;
2368                         }
2369                         xspu = x1spu;   //next line
2370                         yspu++;
2371                         id = id ? 0 : 1;
2372                 }
2373         }
2374
2375         return display_time;
2376 }
2377
2378 // blit to argb in 32bit mode
2379 static void ddvd_blit_to_argb(void *_dst, const void *_src, int pix)
2380 {
2381         unsigned long *dst = _dst;
2382         const unsigned char *src = _src;
2383         while (pix--) {
2384                 int p = (*src++);
2385                 int a, r, g, b;
2386                 if (p == 0) {
2387                         r = g = b = a = 0;      //clear screen (transparency)
2388                 } else {
2389                         a = 0xFF - (ddvd_tr[p] >> 8);
2390                         r = ddvd_rd[p] >> 8;
2391                         g = ddvd_gn[p] >> 8;
2392                         b = ddvd_bl[p] >> 8;
2393                 }
2394                 *dst++ = (a << 24) | (r << 16) | (g << 8) | (b << 0);
2395         }
2396 }
2397
2398 #if CONFIG_API_VERSION == 3
2399
2400 // set decoder buffer offsets to a minimum
2401 static void ddvd_set_pcr_offset(void)
2402 {
2403         write_string("/proc/stb/pcr/pcr_stc_offset", "200");
2404         write_string("/proc/stb/vmpeg/0/sync_offset", "200");
2405 }
2406
2407 // reset decoder buffer offsets
2408 static void ddvd_unset_pcr_offset(void)
2409 {
2410         write_string("/proc/stb/pcr/pcr_stc_offset", "2710");
2411         write_string("/proc/stb/vmpeg/0/sync_offset", "2710");
2412 }
2413
2414 #endif
2415
2416 void ddvd_resize_pixmap(unsigned char *pixmap, int xsource, int ysource, int xdest, int ydest, int colors)
2417 {
2418         
2419         float fx,fy,tmp_f/*,dpixel*/;
2420         unsigned int xs,ys,xd,yd,dpixel;
2421         unsigned int c,tmp_i;
2422         int x,y,t,t1;
2423         xs=xsource; // x-resolution source
2424         ys=ysource; // y-resolution source
2425         xd=xdest; // x-resolution destination
2426         yd=ydest; // y-resolution destination
2427         unsigned char *pixmap_tmp;
2428         pixmap_tmp = (unsigned char *)malloc(xsource*ysource*colors);
2429         memcpy(pixmap_tmp, pixmap, xsource*ysource*colors);
2430         
2431         // get x scale factor
2432         fx=(float)(xs-1)/(float)xd;
2433
2434         // get y scale factor
2435         fy=(float)(ys-1)/(float)yd;
2436
2437         unsigned int sx1[xd],sx2[xd],sy1,sy2;
2438         
2439         // pre calculating sx1/sx2 for faster resizing
2440         for (x=0; x<xd; x++) 
2441         {
2442                 // first x source pixel for calculating destination pixel
2443                 tmp_f=fx*(float)x;
2444                 sx1[x]=(int)tmp_f; //floor()
2445
2446                 // last x source pixel for calculating destination pixel
2447                 tmp_f=(float)sx1[x]+fx;
2448                 sx2[x]=(int)tmp_f;
2449                 if ((float)sx2[x] < tmp_f) {sx2[x]+=1;} //ceil()                
2450         }
2451         
2452         // Scale
2453         for (y=0; y<yd; y++) 
2454         {
2455
2456                 // first y source pixel for calculating destination pixel
2457                 tmp_f=fy*(float)y;
2458                 sy1=(int)tmp_f; //floor()
2459
2460                 // last y source pixel for calculating destination pixel
2461                 tmp_f=(float)sy1+fy;
2462                 sy2=(int)tmp_f;
2463                 if ((float)sy2 < tmp_f) {sy2+=1;} //ceil()      
2464
2465                 for (x=0; x<xd; x++) 
2466                 {
2467                         // we do this for every color
2468                         for (c=0; c<colors; c++) 
2469                         {
2470                                 // calculationg destination pixel
2471                                 tmp_i=0;
2472                                 dpixel=0;
2473                 
2474                                 for (t1=sy1; t1<sy2; t1++) 
2475                                 {
2476                                         for (t=sx1[x]; t<=sx2[x]; t++) 
2477                                         {
2478                                                 tmp_i+=(int)pixmap_tmp[(t*colors)+c+(t1*xs*colors)];
2479                                                 dpixel++;               
2480                                         }
2481                                 }
2482                 
2483                                 //tmp_f=(float)tmp_i/dpixel;
2484                                 //tmp_i=(int)tmp_f;
2485                                 //if ((float)tmp_i+0.5 <= tmp_f) {tmp_i+=1;} //round()
2486                                 tmp_i=tmp_i/dpixel; // working with integers is not correct, but much faster and +-1 inside the color values doesnt really matter
2487                                 
2488                                 // writing calculated pixel into destination pixmap
2489                                 pixmap[(x*colors)+c+(y*xd*colors)]=tmp_i;
2490                         }
2491                 }
2492         }
2493         free(pixmap_tmp);
2494 }