source: titan/titan/player.h @ 35064

Last change on this file since 35064 was 35064, checked in by gost, 7 years ago

[titan] mipsel.. fix play ts after pause (audio delay)

File size: 72.3 KB
Line 
1#ifndef PLAYER_H
2#define PLAYER_H
3
4// playercan bits:
5// 0 policy
6// 1 auditraklist
7// 2 subtitle
8// 3 videomode
9// 4 powerofftimer
10// 5 videosettings
11// 6 stop
12// 7 ff
13// 8 fr
14// 9 pause
15// 10 play
16// 11 jump/seek reverse
17// 12 jump/seek forward
18// 13 changecodec
19// 14 infobar
20// 15 slowmotion
21
22#ifdef EPLAYER3
23Context_t * player = NULL;
24extern OutputHandler_t OutputHandler;
25extern PlaybackHandler_t PlaybackHandler;
26extern ContainerHandler_t ContainerHandler;
27extern ManagerHandler_t ManagerHandler;
28#endif
29
30#ifdef EPLAYER4
31//#define GST_VERSION_MAJOR (0)
32GstElement *pipeline = NULL;
33gint m_framerate;
34unsigned long long m_gst_startpts = 0;
35CustomData data;
36GstElement *video_sink = NULL;
37struct stimerthread* subtitlethread = NULL;
38uint32_t buf_pos_ms = 0;
39uint32_t duration_ms = 0;
40int subtitleflag = 0;
41char *subtext = NULL;
42#endif
43
44//titan player
45
46//flag 0: from play
47//flag 1: from timeshift
48//flag 2: from playrcjumpr
49int playerstartts(char* file, int flag)
50{
51        int fd = -1, ret = 0, tssize = 188;
52        int16_t pmtpid = 0;
53        int serviceid = 0;
54        int supermagic = -1;
55        int lastpos = 0;
56        struct channel* chnode = NULL;
57        struct service* snode = NULL;
58        struct dvbdev* fenode = NULL;
59        struct dvbdev* dvrnode = NULL;
60        status.prefillbuffer = 0;
61
62        //supermagic = getsupermagic(file);
63
64        if(supermagic == NFS_SUPER_MAGIC || supermagic == SMB_SUPER_MAGIC)
65        {
66                debug(150, "use O_DIRECT to open file %s", file);
67                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK | O_DIRECT);
68        }
69        else
70                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK);
71
72        if(fd < 0)
73        {
74                perr("open player file");
75                return 1;
76        }
77
78        fenode = fegetdummy();
79        dvrnode = dvropen(fenode);
80        if(dvrnode == NULL)
81        {
82                err("find dvr dev");
83                close(fd);
84                return 1;
85        }
86
87        if(flag == 0 || flag == 2)
88        {
89                //TODO: funktion to get tssize from file content
90                if(cmpfilenameext(file, ".mts") == 0) tssize = 192;
91                if(cmpfilenameext(file, ".m2ts") == 0) tssize = 192;
92               
93                ret = dvbfindpmtpid(fd, &pmtpid, &serviceid, tssize);
94                if(ret == 1)
95                {
96                        err("find sid/pmt pid");
97                        close(fd);
98                        dvrclose(dvrnode, -1);
99                        return 1;
100                }
101               
102                lastpos = 0;
103                if(flag == 0 && getconfigint("showlastpos", NULL) == 1)
104                {
105                        char* fileseek = changefilenameext(file, ".se");
106                        FILE* fbseek = fopen(fileseek, "r");
107                        if(fbseek != NULL)
108                        {
109                                ret = textbox(_("Message"), _("Start at last position ?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 10, 0);
110                                if(ret == 0 || ret == 1)
111                                {
112                                        char* skip1 = calloc(1, 20);
113                                        if(skip1 != NULL)
114                                        {
115                                                fscanf(fbseek, "%s", skip1);
116                                                off64_t seekpos = atoll(skip1);
117                                                seekpos = seekpos - (seekpos % tssize);
118                                                lseek64(fd, atoll(skip1), SEEK_SET);
119                                                lastpos = 1;
120                                        }
121                                        free(skip1); skip1 = NULL;
122                                }
123                                fclose(fbseek);
124                        }
125                        free(fileseek); fileseek = NULL;
126                }       
127               
128                status.autoseek = 0;
129               
130                if(flag == 0)
131                {
132                        delmarkernode(-1);
133                        char* filemarker = changefilenameext(file, ".ma");
134                        getmarker(filemarker);
135                        free(filemarker); filemarker=NULL;
136                }
137               
138                if(status.playmarker != NULL)
139                {
140                        char* testfile = changefilenameext(file, ".as");
141                        FILE* testseek = fopen(testfile, "r");
142                        if(testseek != NULL)
143                        {
144                                if(lastpos == 0)
145                                        lseek64(fd, status.playmarker->pos, SEEK_SET);
146                                status.autoseek = 2;
147                                addtimer(&markerautoseek_thread, START, 10000, 1, NULL, NULL, NULL);
148                                fclose(testseek);
149                        }
150                        free(testfile); testfile = NULL;
151                }
152                               
153                delchannel(serviceid, 0, 1);
154                chnode = createchannel("player", 0, 0, serviceid, 99, 0, -1, -1, -1, -1, 0, -1);
155                if(chnode != NULL) chnode->pmtpid = pmtpid;
156        }
157        else
158                chnode = status.aktservice->channel;
159
160        if(chnode == NULL)
161        {
162                err("create channel");
163                close(fd);
164                dvrclose(dvrnode, -1);
165                return 1;
166        }
167
168        if(flag == 1)
169        {
170                ret = servicestart(chnode, NULL, NULL, 2);
171                if(ret != 0)
172                {
173                        err("start play");
174                        close(fd);
175                        dvrclose(dvrnode, -1);
176                        return 1;
177                }
178               
179                //on permanent timeshift seek to end, and a little back (eof problem)
180                if(status.timeshifttype == 1)
181                {
182                        if(status.timeshiftpos > 0)
183                                lseek64(fd, status.timeshiftpos, SEEK_SET);
184                        else
185                        {
186                                unsigned long long pos = lseek64(fd, 0, SEEK_END);
187                                pos -= 10000000;
188                                pos = pos - (pos & tssize);
189                                lseek64(fd, -pos, SEEK_END);
190                        }
191                }
192        }
193
194        ret = recordstartreal(NULL, fd, dvrnode->fd, RECPLAY, 0, NULL, tssize);
195        if(ret != 0)
196        {
197                err("start play thread");
198                close(fd);
199                dvrclose(dvrnode, -1);
200                return 1;
201        }
202
203        snode = getservice(RECORDPLAY, 0);
204        if(snode != NULL)
205        {
206                int dupfd = -1;
207                snode->recname = ostrcat(file, NULL, 0, 0);
208
209                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
210                if(dupfd > -1)
211                        gettsinfo(dupfd, &snode->lenpts, &snode->startpts, &snode->endpts, &snode->bitrate, snode->tssize);
212
213                if(flag == 1)
214                {
215                        snode->lenpts = 0;
216                        snode->endpts = 0;
217                }
218                else
219                {
220                        if(getservicebyrecname(file, 1, 0) != NULL) //playfile is recording, so len can change
221                        {
222                                snode->lenpts = 0;
223                                snode->endpts = 0;
224                        }
225                        else if(dupfd > -1)
226                                snode->endoffile = lseek64(dupfd , 0, SEEK_END);
227                }
228                close(dupfd);
229        }
230
231        if(flag == 0 || flag == 2)
232        {
233                ret = servicestart(chnode, NULL, NULL, 1);
234                if(ret != 0)
235                {
236                        err("start play");
237                        if(snode != NULL) snode->recendtime = 1;
238                        close(fd);
239                        dvrclose(dvrnode, -1);
240                        return 1;
241                }
242                //status.playercan = 0x7EFF;
243                status.playercan = 0xFFFF;     
244        }
245
246        return 0;
247}
248
249//flag 0: from play
250//flag 1: from timeshift
251//flag 2: from playrcjumpr/playerafterendts
252//flag1 0: stop from rcstop
253//flag1 1: stop from servicestop
254void playerstopts(int flag, int flag1)
255{
256        int ret = 0;
257        struct service* snode = NULL;
258        struct channel* node = NULL;
259
260        snode = getservice(RECORDPLAY, flag1);
261
262        if(snode != NULL && snode->recsrcfd >= 0 && flag == 0 && flag1 == 0)
263        {
264                char* fileseek = changefilenameext(snode->recname, ".se");
265                FILE* fbseek = fopen(fileseek, "w");
266                if(fbseek != NULL)
267                {
268                        off64_t pos = getcurrentpos(snode);
269                        if(pos <= 0)
270                                pos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
271                        fprintf(fbseek,"%lld", pos);
272                        fclose(fbseek);
273                }
274                free(fileseek); fileseek=NULL;
275                char* filemarker = changefilenameext(snode->recname, ".ma");
276                ret = putmarker(filemarker);
277                free(filemarker); filemarker=NULL;
278                delmarkernode(-1);
279        }
280       
281        if(snode != NULL) snode->recendtime = 1;
282       
283        if(flag == 0 || flag == 2)
284        {
285                playerslowts(0);
286                playerffts(0);
287
288                ret = servicestop(status.aktservice, 1, 1);
289                if(ret == 1)
290                {
291                        debug(150, "can't stop ts playback service");   
292                }
293                else
294                        status.aktservice->channel = NULL;
295
296                               
297                node = gettmpchannel();
298                if(node != NULL && ostrcmp(node->name, "player") == 0)
299                        delchannel(node->serviceid, node->transponderid, 1);
300        }
301}
302
303void playerresetts()
304{
305        audiostop(status.aktservice->audiodev);
306        videostop(status.aktservice->videodev, 0);
307#ifdef MIPSEL
308        videoclearbuffer(status.aktservice->videodev);
309        audioclearbuffer(status.aktservice->audiodev);
310#endif
311        videoplay(status.aktservice->videodev);
312        audioplay(status.aktservice->audiodev);
313}
314
315void playercontinuets()
316{
317        videocontinue(status.aktservice->videodev);
318#ifdef MIPSEL
319        audiocontinue(status.aktservice->audiodev);
320#else
321        audioplay(status.aktservice->audiodev);
322#endif
323}
324
325void playerpausets()
326{
327        videofreeze(status.aktservice->videodev);
328        audiopause(status.aktservice->audiodev);
329}
330
331//flag 0: with lock
332//flag 1: without lock
333int playerseekts(struct service* servicenode, int sekunden, int flag)
334{
335        off64_t offset = 0;
336        off64_t endoffile = 0;
337        off64_t currentpos = 0;
338        //off64_t fdptspos = 0;
339        //int ret = 0;
340        unsigned long long lenpts = 0;
341        unsigned long long startpts = 0;
342        unsigned long long endpts = 0;
343        unsigned long long bitrate = 0;
344        //unsigned long long aktpts = 0;
345        //unsigned long long fdpts = 0;
346        //int aktsekunden = 0;
347        int sekundenoff = 0;
348       
349        if(servicenode == NULL) return 1;
350
351        if(servicenode->recsrcfd < 0)
352        {
353                err("source fd not ok");
354                return 1;
355        }
356       
357        if(flag == 0) m_lock(&status.tsseekmutex, 15);
358
359/*
360        ret = videogetpts(status.aktservice->videodev, &aktpts);
361        if(ret == 0)
362        {
363                aktsekunden = aktpts / 90000;
364        }
365        else
366                aktsekunden = 0;
367        ret = getpts(servicenode->recsrcfd, 0, 0, 256 * 1024, &fdpts, &fdptspos, -1, servicenode->tssize);
368        if(ret == 0 && aktsekunden != 0)
369        {
370                sekundenoff = fdpts / 90000 - aktsekunden ;
371                //currentpos = lseek64(servicenode->recsrcfd, fdptspos, SEEK_SET);
372        }
373        else
374                sekundenoff = 0;
375*/
376       
377        currentpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);
378
379        lenpts = servicenode->lenpts;
380        startpts = servicenode->startpts;
381        endpts = servicenode->endpts;
382        bitrate = servicenode->bitrate;
383        if(gettsinfo(servicenode->recsrcfd, &lenpts, &startpts, &endpts, &bitrate, servicenode->tssize) != 0)
384        {
385                err("can't read ts info");
386                lseek64(servicenode->recsrcfd, currentpos, SEEK_SET);
387                if(flag == 0) m_unlock(&status.tsseekmutex, 15);
388                return 1;
389        }
390        if(servicenode->endoffile > 0)
391                endoffile = servicenode->endoffile - (servicenode->tssize * 2);
392        else
393                endoffile = lseek64(servicenode->recsrcfd , -servicenode->tssize * 2, SEEK_END);
394
395/*
396        ret = videoclearbuffer(status.aktservice->videodev);
397        ret = audioclearbuffer(status.aktservice->audiodev);
398        ret = videodiscontinuityskip(status.aktservice->videodev, 0);
399*/
400
401        if(sekunden >= 0)
402        {
403                if(sekundenoff != 0)
404                        offset = (bitrate / 8) * (sekunden - sekundenoff);
405                else
406                        offset = (bitrate / 8) * sekunden - 5000000;
407                offset = offset - (offset % servicenode->tssize);
408                if(currentpos + offset > endoffile)
409                {
410                        offset = endoffile - currentpos;
411                        offset = offset - (offset % servicenode->tssize);
412                }
413        }
414        else
415        {
416                sekunden = sekunden * -1;
417                if(sekundenoff != 0)
418                        offset = (bitrate / 8) * (sekunden + sekundenoff);
419                else
420                        offset = (bitrate / 8) * sekunden;
421                if(offset > 0) offset += 5000000;
422                offset = offset - (offset % servicenode->tssize);
423                if(currentpos - offset < 0)
424                        offset = currentpos;
425                offset = offset * -1;
426        }
427        offset += currentpos;
428        currentpos = lseek64(servicenode->recsrcfd, offset, SEEK_SET);
429
430        playerresetts();
431
432        if(flag == 0) m_unlock(&status.tsseekmutex, 15);
433        return 0;
434}
435
436void playerffts(int speed)
437{
438#ifdef MIPSEL
439        audiostop(status.aktservice->audiodev);
440        videoslowmotion(status.aktservice->videodev, 0);
441        videofastforward(status.aktservice->videodev, speed);
442        videocontinue(status.aktservice->videodev);
443#else   
444        videofastforward(status.aktservice->videodev, speed);
445#endif
446}
447
448void playerslowts(int speed)
449{
450#ifdef MIPSEL
451        audiostop(status.aktservice->audiodev);
452        videoslowmotion(status.aktservice->videodev, speed);
453        videofastforward(status.aktservice->videodev, 0);
454        videocontinue(status.aktservice->videodev);
455#else           
456        videoslowmotion(status.aktservice->videodev, speed);
457#endif
458}
459
460//flag = 0 --> recordplay
461//flag = 1 --> timeshift
462void playerfrts(int speed, int flag)
463{
464        if(flag == 1)
465                videocontinue(status.aktservice->videodev);
466        if(speed == -2)
467        {
468                videoclearbuffer(status.aktservice->videodev);
469                audioclearbuffer(status.aktservice->audiodev);
470        }
471        speed *= -1;
472#ifdef MIPSEL
473        audiostop(status.aktservice->audiodev);
474        videoslowmotion(status.aktservice->videodev, 0);
475        videofastforward(status.aktservice->videodev, speed);
476        videocontinue(status.aktservice->videodev);
477#else   
478        videofastforward(status.aktservice->videodev, speed);
479#endif
480}
481       
482
483//flag = 0 --> play ts
484//flag = 1 --> timeshift
485//flag = 2 --> timeshift, not in play mode (only recording)
486int playergetinfots(unsigned long long* lenpts, unsigned long long* startpts, unsigned long long* endpts, unsigned long long* aktpts, unsigned long long* bitrate, int flag)
487{
488        int ret = 0, dupfd = -1;
489        double ratio = 0;
490        struct service* snode = NULL;
491        unsigned long long lenpts1 = 0;
492        unsigned long long startpts1 = 0;
493        unsigned long long endpts1 = 0;
494        unsigned long long bitrate1 = 0;
495        unsigned long long endoffile1 = 0;
496        unsigned long long aktpos = 0;
497       
498        if(flag == 2)
499                snode = getservice(RECORDTIMESHIFT, 0);
500        else
501                snode = getservice(RECORDPLAY, 0);
502               
503        if(snode == NULL) return 1;
504
505        if(snode->lenpts > 0 && snode->startpts > 0 && snode->endpts > 0 && snode->bitrate > 0 && snode->endoffile > 0)
506        {
507                if(lenpts != NULL) *lenpts = snode->lenpts;
508                if(startpts != NULL) *startpts = snode->startpts;
509                if(endpts != NULL) *endpts = snode->endpts;
510                if(bitrate != NULL) *bitrate = snode->bitrate;
511
512                //ret = videogetpts(status.aktservice->videodev, aktpts);
513                if(aktpts != NULL)
514                {
515                        m_lock(&status.tsseekmutex, 15);
516                        if(flag == 2)
517                                aktpos = lseek64(snode->recdstfd , 0, SEEK_CUR);
518                        else
519                                aktpos = lseek64(snode->recsrcfd , 0, SEEK_CUR);
520                        m_unlock(&status.tsseekmutex, 15);
521
522                        ratio = (double)snode->endoffile / (double)(snode->endpts - snode->startpts);
523                        if(ratio == 0) ratio = 1;
524                        *aktpts = ((double)aktpos / ratio);
525                        *aktpts += snode->startpts;
526                }
527
528                return ret;
529        }
530       
531        dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
532        if(dupfd < 0)
533        {
534                err("copy source fd not ok");
535                return 1;
536        }
537
538        lenpts1 = snode->lenpts;
539        startpts1 = snode->startpts;
540        endpts1 = snode->endpts;
541        bitrate1 = snode->bitrate;
542        if(gettsinfo(dupfd, &lenpts1, &startpts1, &endpts1, &bitrate1, snode->tssize) != 0)
543        {
544                err("can't read ts info");
545                return 1;
546        }
547
548        if(lenpts != NULL) *lenpts = lenpts1;
549        if(startpts != NULL) *startpts = startpts1;
550        if(endpts != NULL) *endpts = endpts1;
551        if(bitrate != NULL) *bitrate = bitrate1;
552
553        //ret = videogetpts(status.aktservice->videodev, aktpts);
554        if(aktpts != NULL)
555        {
556                m_lock(&status.tsseekmutex, 15);
557                if(flag == 2)
558                        aktpos = lseek64(snode->recdstfd, 0, SEEK_CUR);
559                else
560                        aktpos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
561                m_unlock(&status.tsseekmutex, 15);
562
563                if(snode->endoffile <= 0)
564                        endoffile1 = lseek64(dupfd, 0, SEEK_END);
565                else
566                        endoffile1 = snode->endoffile;
567
568                if(endpts1 == 0)
569                        ratio = 1;
570                else
571                        ratio = (double)endoffile1 / (double)(endpts1 - startpts1);
572
573                if(ratio == 0) ratio = 1;
574                *aktpts = ((double)aktpos / ratio);
575                *aktpts += startpts1;
576        }
577
578        close(dupfd);
579        return ret;
580}
581
582void playerchangeaudiotrackts()
583{
584        screenaudiotrack();
585}
586
587void playerchangesubtitletrackts()
588{
589        screensubtitle();
590}
591
592int playerisplayingts()
593{
594        struct service* snode = getservice(RECORDPLAY, 0);
595
596        if(snode == NULL)
597                return 0;
598        return 1;
599}
600
601void playerafterendts()
602{
603        playerstopts(2, 0);
604}
605
606#ifdef EPLAYER4
607void playersubtitleclean(char* data, int len)
608{
609        char* zeichen = NULL;
610        int found = 1;
611       
612        while(found == 1)
613        {
614                found = 0;
615                zeichen = NULL;
616                zeichen = strstr(data, "&apos;");
617                if(zeichen != NULL)
618                {
619                        zeichen[0] = '\'';
620                        memcpy(zeichen+1, zeichen+6, len - (zeichen - data + 1));
621                        found = 1;
622                }
623                zeichen = NULL;
624                zeichen = strstr(data, "&amp;");
625                if(zeichen != NULL)
626                {
627                        zeichen[0] = '&';
628                        memcpy(zeichen+1, zeichen+5, len - (zeichen - data + 1));
629                        found = 1;
630                }
631                zeichen = NULL;
632                zeichen = strstr(data, "&quot;");
633                if(zeichen != NULL)
634                {
635                        zeichen[0] = '"';
636                        memcpy(zeichen+1, zeichen+6, len - (zeichen - data + 1));
637                        found = 1;
638                }
639                zeichen = NULL;
640                zeichen = strstr(data, "&lt;");
641                if(zeichen != NULL)
642                {
643                        zeichen[0] = '<';
644                        memcpy(zeichen+1, zeichen+4, len - (zeichen - data + 1));
645                        found = 1;
646                }
647                zeichen = NULL;
648                zeichen = strstr(data, "&gt;");
649                if(zeichen != NULL)
650                {
651                        zeichen[0] = '<';
652                        memcpy(zeichen+1, zeichen+4, len - (zeichen - data + 1));
653                        found = 1;
654                }
655                //workaround da keine Aufbereitung
656                zeichen = NULL;
657                zeichen = strstr(data, "<i>");
658                if(zeichen != NULL)
659                {
660                        memcpy(zeichen, zeichen+3, len - (zeichen - data + 1));
661                        found = 1;
662                }
663                zeichen = NULL;
664                zeichen = strstr(data, "</i>");
665                if(zeichen != NULL)
666                {
667                        memcpy(zeichen, zeichen+4, len - (zeichen - data + 1));
668                        found = 1;
669                }
670        }
671}
672#endif
673
674#ifdef EPLAYER4
675void playersubtitle_thread()
676{
677        struct skin* framebuffer = getscreen("framebuffer");
678        struct skin* subtitle = getscreen("gstsubtitle");
679        char* bg = NULL;
680        int count = 0;
681       
682        subtitle->bgcol = -1;
683       
684        setnodeattr(subtitle, framebuffer, 0);
685        bg = savescreen(subtitle);
686       
687        while(subtitlethread->aktion != STOP)
688        {
689                if(duration_ms != 0)
690                {
691                        count = 0;
692                        changetext(subtitle, subtext);
693                        count = duration_ms / 100;
694                        drawscreen(subtitle, 0, 0);
695                        while(count > 0 && subtitlethread->aktion != STOP)
696                        {
697                                usleep(100000);
698                                count = count - 1;
699                        }
700                        changetext(subtitle, " ");
701                        drawscreen(subtitle, 0, 0);
702                        duration_ms = 0;
703                }
704                else
705                        usleep(100000);
706        }
707        free(subtext); subtext = NULL;
708        restorescreen(bg, subtitle);
709        blitfb(0);
710        subtitlethread = NULL;
711}
712#endif
713
714#ifdef EPLAYER4
715void playersubtitleAvail(GstElement *subsink, GstBuffer *buffer, gpointer user_data)
716{
717        //printf("++++++ subtitelflag: %i\n", subtitleflag);
718        if(subtitleflag == 0 || subtitleflag == 2) return;
719
720#if GST_VERSION_MAJOR < 1
721        gint64 buf_pos = GST_BUFFER_TIMESTAMP(buffer);
722        gint64 duration_ns = GST_BUFFER_DURATION(buffer);
723#endif 
724        time_t running_pts = 0;
725        gint64 pos = 0;
726        int32_t decoder_ms;
727        GstFormat fmt = GST_FORMAT_TIME;
728       
729#if GST_VERSION_MAJOR < 1
730        if (!gst_element_query_position(pipeline, &fmt, &pos))
731#else
732        if (!gst_element_query_position(pipeline, fmt, &pos))
733#endif
734        {
735                err("gst_element_query_position failed");
736                return;
737        }
738        running_pts = pos / 11111LL;
739        decoder_ms = running_pts / 90;
740               
741        if(subtitlethread == NULL)
742                subtitlethread = addtimer(&playersubtitle_thread, START, 10000, 1, NULL, NULL, NULL);
743       
744#if GST_VERSION_MAJOR < 1
745        size_t len = GST_BUFFER_SIZE(buffer);
746#else
747//      size_t len = gst_buffer_get_size(buffer);
748        GstMapInfo map;
749        if(!gst_buffer_map(buffer, &map, GST_MAP_READ))
750        {
751                printf("eServiceMP3::pullSubtitle gst_buffer_map failed\n");
752                return;
753        }
754        gint64 buf_pos = GST_BUFFER_PTS(buffer);
755        size_t len = map.size;
756#if GST_VERSION_MAJOR < 1
757        printf("gst_buffer_get_size %zu map.size %zu\n", gst_buffer_get_size(buffer), len);
758#endif
759        gint64 duration_ns = GST_BUFFER_DURATION(buffer);
760#endif
761                       
762        //printf("BUFFER_TIMESTAMP: %lld - BUFFER_DURATION: %lld in ns\n", buf_pos, duration_ns);
763        //printf("BUFFER_SIZE: %d\n", len);
764        //printf("BUFFER_DATA: %s\n", GST_BUFFER_DATA(buffer));
765       
766        while(duration_ms != 0 && subtitlethread != NULL)
767        {
768                usleep(100000);
769        }
770        if(subtext != NULL)
771                free(subtext);
772        subtext = malloc(len+10);
773        if(subtext == NULL)
774        {
775                err("no mem");
776                return;
777        }
778#if GST_VERSION_MAJOR > 1
779        guint8 *data;
780//      gsize size;
781        GstMapInfo map;
782        gst_buffer_map(buffer, &map, GST_MAP_READ);
783        data = map.data;
784        sprintf(subtext, "%s", data);
785//      sprintf(subtext, "%s", GST_BUFFER_DATA(buffer));
786#endif
787        playersubtitleclean(subtext, len+10);
788       
789        double convert_fps = 1.0;
790        buf_pos_ms  = (buf_pos / 1000000ULL) * convert_fps;
791        duration_ms = duration_ns / 1000000ULL;
792
793        //printf("++++++ buff_pos  : %u\n", buf_pos_ms);
794        //printf("++++++ decoder_ms: %i\n", decoder_ms);
795}
796#endif
797
798//extern player
799int playerstart(char* file)
800{
801        char * tmpfile = NULL;
802        status.prefillbuffer = 0;
803       
804        if(file != NULL)
805        {
806#ifdef EPLAYER3
807                //use eplayer
808
809                if(player != NULL)
810                {
811                        debug(150, "eplayer allready running");
812                        playerstop();
813                }
814
815                player = calloc(1, sizeof(Context_t));
816
817                if(player == NULL)
818                {
819                        err("no mem");
820                        return 1;
821                }
822
823                if(ostrstr(file, "://") == NULL)
824                        tmpfile = ostrcat("file://", file, 0, 0);
825                else
826                        tmpfile = ostrcat(file, NULL, 0, 0);
827
828                if(tmpfile == NULL)
829                {
830                        err("no mem");
831                        free(player); player = NULL;
832                        return 1;
833                }
834// move to mc
835//              set_player_sound(0);
836
837                if(ostrstr(tmpfile, "file://") == NULL)
838                        status.playercan = 0x4650;
839                else
840                        status.playercan = 0xFFFF;
841               
842                player->playback = &PlaybackHandler;
843                player->output = &OutputHandler;
844                player->container = &ContainerHandler;
845                player->manager = &ManagerHandler;
846               
847                //add container befor open, so we can set buffer size
848                char* ext = getfilenameext(tmpfile);
849                if(ext != NULL)
850                {
851                        player->container->Command(player, CONTAINER_ADD, ext);
852                        free(ext); ext = NULL;
853                }
854
855                //select container_ffmpeg, if we does not found a container with extensions
856                if(player->container->selectedContainer == NULL)
857                        player->container->Command(player, CONTAINER_ADD, "mp3");
858
859                if(player && player->container && player->container->selectedContainer)
860                {
861                        int size = getconfigint("playerbuffersize", NULL);
862                        int seektime = getconfigint("playerbufferseektime", NULL);
863                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SIZE, (void*)&size);
864                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SEEK_TIME, (void*)&seektime);
865                }
866               
867                debug(150, "eplayername = %s", player->output->Name);
868
869                //Registrating output devices
870                player->output->Command(player, OUTPUT_ADD, "audio");
871                player->output->Command(player, OUTPUT_ADD, "video");
872                player->output->Command(player, OUTPUT_ADD, "subtitle");
873               
874                //for subtitle
875                SubtitleOutputDef_t subout;
876
877                subout.screen_width = skinfb->width;
878                subout.screen_height = skinfb->height;
879                subout.framebufferFD = skinfb->fd;
880                subout.destination = (uint32_t *)skinfb->fb;
881                subout.destStride = skinfb->pitch;
882                subout.shareFramebuffer = 1;
883                subout.framebufferBlit = blitfb1;
884
885                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&subout);
886               
887                if(player->playback->Command(player, PLAYBACK_OPEN, tmpfile) < 0)
888                {
889                        free(player); player = NULL;
890                        free(tmpfile);
891                        return 1;
892                }
893
894                player->output->Command(player, OUTPUT_OPEN, NULL);
895                player->playback->Command(player, PLAYBACK_PLAY, NULL);
896
897                free(tmpfile);
898
899                return 0;
900#endif
901
902#ifdef EPLAYER4
903                int flags = 0x47; //(GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT);
904               
905                if(pipeline != NULL)
906                {
907                        debug(150, "eplayer allready running");
908                        playerstop();
909                }
910               
911                if(ostrstr(file, "://") == NULL)
912                        tmpfile = ostrcat("file://", file, 0, 0);
913                else
914                        tmpfile = ostrcat(file, NULL, 0, 0);
915
916                if(tmpfile == NULL)
917                {
918                        err("no mem");
919                        free(pipeline); pipeline = NULL;
920                        return 1;
921                }
922
923                if(ostrstr(tmpfile, "file://") == NULL)
924                        //status.playercan = 0x7E7F;
925                        //status.playercan = 0x7EFF;
926                        status.playercan = 0xFEFF;
927                else
928                        //status.playercan = 0x7E7F;
929                        //status.playercan = 0x7EFF;
930                        status.playercan = 0xFEFF;
931               
932                m_framerate = -1;
933#if GST_VERSION_MAJOR < 1
934                pipeline = gst_element_factory_make("playbin2", "playbin");
935#else
936                pipeline = gst_element_factory_make("playbin", "playbin");
937#endif
938
939// enable buffersize start
940                int size = getconfigint("playerbuffersize", NULL);
941                printf("size: %d\n",size);
942               
943                if(size > 0 && ostrstr(tmpfile, "file://") == NULL)
944                        status.prefillbuffer = 1;
945
946                if(ostrstr(file, "|User-Agent=") != NULL)
947                {
948                        char* tmpstr = NULL;
949                        tmpstr = ostrcat(file, NULL, 0, 0);
950                        tmpstr = string_replace("|User-Agent=", "|", tmpstr, 1);
951                        int count1 = 0;
952                        struct splitstr* ret1 = NULL;
953                        ret1 = strsplit(tmpstr, "|", &count1);
954                        if(ret1 != NULL && count1 >= 2)
955                        {
956                                printf("[player.h] set user-agent: %s\n",ret1[1].part);
957                                g_object_set(G_OBJECT(pipeline), "user-agent", ret1[1].part, NULL);
958                        }
959                        free(ret1), ret1 = NULL;
960                        free(tmpstr), tmpstr = NULL;
961//                      g_object_set(G_OBJECT(pipeline), "user-agent", "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:30.0) Gecko/20100101 Firefox/30.0", NULL);
962                        stringreplacechar(tmpfile, '|', '\0');
963                        printf("tmpfile changed: %s\n", tmpfile);
964                }
965
966                g_object_set(G_OBJECT(pipeline), "buffer-duration", size * GST_SECOND, NULL);
967                g_object_set(G_OBJECT(pipeline), "buffer-size", size, NULL);
968// enable buffersizeend
969
970                g_object_set(G_OBJECT(pipeline), "uri", tmpfile, NULL);
971                g_object_set(G_OBJECT(pipeline), "flags", flags, NULL);
972                free(tmpfile); tmpfile = NULL;
973
974///////////////////
975// srt subs start
976                const char *filename = file;
977                const char *ext = strrchr(filename, '.');
978                if (!ext)
979                        ext = filename + strlen(filename);
980
981                GstElement *subsink = gst_element_factory_make("subsink", "subtitle_sink");
982                if (!subsink)
983                        printf("sorry, can't play: missing gst-plugin-subsink\n");
984                else
985                {
986//                      m_subs_to_pull_handler_id = g_signal_connect (subsink, "new-buffer", G_CALLBACK (gstCBsubtitleAvail), this);
987                        g_signal_connect (subsink, "new-buffer", G_CALLBACK (playersubtitleAvail), NULL);
988                        g_object_set (G_OBJECT (subsink), "caps", gst_caps_from_string("text/plain; text/x-plain; text/x-raw; text/x-pango-markup; video/x-dvd-subpicture; subpicture/x-pgs"), NULL);
989
990#if GST_VERSION_MAJOR < 1
991                        g_object_set (G_OBJECT (subsink), "caps", gst_caps_from_string("text/plain; text/x-plain; text/x-raw; text/x-pango-markup; video/x-dvd-subpicture; subpicture/x-pgs"), NULL);
992#else
993                        g_object_set (G_OBJECT (subsink), "caps", gst_caps_from_string("text/plain; text/x-plain; text/x-raw; text/x-pango-markup; subpicture/x-dvd; subpicture/x-pgs"), NULL);
994#endif
995
996                        g_object_set (G_OBJECT (pipeline), "text-sink", subsink, NULL);
997                        subtitleflag = 1;
998                        //g_object_set (G_OBJECT (pipeline), "current-text", -1, NULL);
999                }
1000
1001//gpointer this;
1002//memset (&this, 0, sizeof (this));
1003
1004                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
1005#if GST_VERSION_MAJOR < 1
1006//              gst_bus_set_sync_handler(bus, gstBusSyncHandler, this);
1007                gst_bus_set_sync_handler(bus, GST_BUS_DROP, NULL);
1008#else
1009//              gst_bus_set_sync_handler(bus, gstBusSyncHandler, this, NULL);
1010                gst_bus_set_sync_handler(bus, GST_BUS_DROP, NULL, NULL);
1011#endif
1012
1013                gst_object_unref(bus);
1014                char srt_filename[ext - filename + 5];
1015                strncpy(srt_filename,filename, ext - filename);
1016                srt_filename[ext - filename] = '\0';
1017                strcat(srt_filename, ".srt");
1018
1019                if(access(srt_filename, R_OK) >= 0)
1020                {
1021                        printf("found srt1: %s\n",srt_filename);
1022                        printf("found srt2: %s\n",g_filename_to_uri(srt_filename, NULL, NULL));
1023                        g_object_set(G_OBJECT (pipeline), "suburi", g_filename_to_uri(srt_filename, NULL, NULL), NULL);
1024                }
1025// srt end     
1026
1027///////////////////
1028//              CustomData data;
1029                memset (&data, 0, sizeof (data));
1030                data.pipeline = pipeline;
1031//              GstBus *bus;
1032//              bus = gst_element_get_bus (pipeline);
1033               
1034                // Start playing //
1035
1036                GstStateChangeReturn ret;
1037                ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
1038                g_object_set (G_OBJECT (pipeline), "current-text", 0, NULL);
1039                if(ret == GST_STATE_CHANGE_FAILURE)
1040                {
1041                        g_printerr ("Unable to set the pipeline to the playing state.\n");
1042                        gst_object_unref (pipeline);
1043                        return -1;
1044                }
1045                else if(ret == GST_STATE_CHANGE_NO_PREROLL)
1046                {
1047                        data.is_live = TRUE;
1048                }
1049
1050                data.loop = g_main_loop_new (NULL, FALSE);
1051                data.pipeline = pipeline;
1052                gst_bus_add_signal_watch (bus);
1053//              g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data);
1054//              status.prefillbuffer = 1;
1055
1056//analyze_streams(data);
1057
1058                int count = 0;
1059                m_gst_startpts = 0;
1060                while(m_gst_startpts == 0 && count < 5)
1061                {
1062                        count++;
1063                        sleep(1);
1064                        m_gst_startpts = playergetpts();
1065                }
1066
1067                return 0;
1068#endif
1069        }
1070       
1071        return 1;
1072}
1073
1074#ifdef EPLAYER4
1075int setBufferSize(int size)
1076{
1077        int m_buffer_size = size;
1078        g_object_set (G_OBJECT (pipeline), "buffer-size", m_buffer_size, NULL);
1079        return 0;
1080}
1081#endif
1082
1083void playerinit(int argc, char* argv[])
1084{
1085#ifdef EPLAYER4
1086//      GstBus *bus;
1087//      GstStateChangeReturn ret;
1088//      gint flags;
1089        gst_init(&argc, &argv);
1090#endif
1091}
1092
1093#ifdef EPLAYER4
1094int gstbuscall(GstBus *bus, GstMessage *msg, CustomData *data)
1095{
1096        int ret = 1;
1097        if(!pipeline) return 0;
1098        if(!msg) return ret;
1099
1100        gchar *sourceName = NULL;
1101        GstObject *source = GST_MESSAGE_SRC(msg);
1102
1103        if(!GST_IS_OBJECT(source)) return ret;
1104        sourceName = gst_object_get_name(source);
1105
1106        debug(150, "gst type: %s", GST_MESSAGE_TYPE_NAME(msg));
1107
1108        switch(GST_MESSAGE_TYPE(msg))
1109        {
1110                case GST_MESSAGE_EOS:
1111                        debug(150, "gst player eof");
1112                        ret = 0;
1113                        break;
1114                case GST_MESSAGE_STATE_CHANGED:
1115                        debug(150, "gst message state changed");
1116                        if(GST_MESSAGE_SRC(msg) != GST_OBJECT(pipeline))
1117                                break;
1118
1119                        GstState old_state, new_state, pending_state;
1120                        gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
1121                        if(GST_MESSAGE_SRC(msg) == GST_OBJECT(pipeline))
1122                        {
1123                                if(new_state == GST_STATE_PLAYING)
1124                                {
1125                                        /* Once we are in the playing state, analyze the streams */
1126                                        analyze_streams(data);
1127                                }
1128                        }
1129
1130                        if(old_state == new_state) break;
1131       
1132                        debug(150, "gst state change %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
1133       
1134                        GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
1135       
1136                        switch(transition)
1137                        {
1138                                case GST_STATE_CHANGE_NULL_TO_READY:
1139                                        break;
1140                                case GST_STATE_CHANGE_READY_TO_PAUSED:
1141/*
1142                                        GstElement *appsink = gst_bin_get_by_name(GST_BIN(pipeline), "subtitle_sink");
1143                                        if(appsink)
1144                                        {
1145                                                g_object_set(G_OBJECT(appsink), "max-buffers", 2, NULL);
1146                                                g_object_set(G_OBJECT(appsink), "sync", FALSE, NULL);
1147                                                g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, NULL);
1148                                                gst_object_unref(appsink);
1149                                        }
1150*/
1151                                        break;
1152                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1153                                        //if(m_sourceinfo.is_streaming && m_streamingsrc_timeout )
1154                                                //m_streamingsrc_timeout->stop();
1155                                        break;
1156                                case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1157                                        break;
1158                                case GST_STATE_CHANGE_PAUSED_TO_READY:
1159                                        break;
1160                                case GST_STATE_CHANGE_READY_TO_NULL:
1161                                        ret = 0;
1162                                        break;
1163                        }
1164                        break;
1165                case GST_MESSAGE_ERROR:
1166                        debug(150, "gst player error");
1167
1168                        gchar *gdebug1;
1169                        GError *err;
1170
1171                        gst_message_parse_error(msg, &err, &gdebug1);
1172                        g_free(gdebug1);
1173
1174                        debug(150, "gst error: %s (%i) from %s", err->message, err->code, sourceName);
1175                        if(err->domain == GST_STREAM_ERROR)
1176                        {
1177                                if(err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
1178                                {
1179                                        //if(g_strrstr(sourceName, "videosink"))
1180                                        //      m_event((iPlayableService*)this, evUser+11);
1181                                        //else if ( g_strrstr(sourceName, "audiosink") )
1182                                        //      m_event((iPlayableService*)this, evUser+10);
1183                                }
1184                        }
1185                        g_error_free(err);
1186                        break;
1187                case GST_MESSAGE_INFO:
1188                        debug(150, "gst player info");
1189
1190/*
1191                        gchar *gdebug2;
1192                        GError *inf;
1193       
1194                        gst_message_parse_info(msg, &inf, &gdebug2);
1195                        g_free(gdebug2);
1196                        if(inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
1197                        {
1198                                //if(g_strrstr(sourceName, "videosink"))
1199                                //      m_event((iPlayableService*)this, evUser+14);
1200                        }
1201                        g_error_free(inf);
1202*/
1203                        break;
1204                case GST_MESSAGE_TAG:
1205                        debug(150, "gst player tag");
1206                        break;
1207                //case GST_MESSAGE_ASYNC_DONE:
1208                //      debug(150, "gst player async done");
1209                //      break;
1210                case GST_MESSAGE_ELEMENT:
1211                        debug(150, "GST_MESSAGE_ELEMENT");
1212                        const GstStructure *msgstruct = gst_message_get_structure(msg);
1213                        if (msgstruct)
1214                        {
1215                                const gchar *eventname = gst_structure_get_name(msgstruct);
1216                                if (!strcmp(eventname, "eventFrameRateChanged") || !strcmp(eventname, "eventFrameRateAvail"))
1217                                {
1218                                        gst_structure_get_int (msgstruct, "frame_rate", &m_framerate);
1219                                }
1220                        }
1221                        debug(150, "gst player element");
1222                        break;
1223                case GST_MESSAGE_BUFFERING:
1224                        debug(150, "gst player buffering");
1225
1226/*
1227                        GstBufferingMode mode;
1228                        gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
1229                        gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
1230                        //m_event((iPlayableService*)this, evBuffering);
1231*/
1232
1233// playback stream jerky on start
1234//                      if (data->is_live) break;
1235//                      gst_message_parse_buffering (msg, &status.bufferpercent);
1236
1237                        if(status.prefillbuffer == 1)
1238                        {
1239//                              gint percent = 0;
1240                                if (data->is_live) break;
1241                                gst_message_parse_buffering (msg, &status.bufferpercent);
1242                                g_print ("Buffering (%3d%%)\r", status.bufferpercent);
1243
1244                                if (status.bufferpercent < 100)
1245                                {
1246                                        gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
1247                                        struct skin* waitmsgbar = getscreen("waitmsgbar");
1248                                        struct skin* load = getscreen("loading");
1249       
1250                                        waitmsgbar->progresssize = status.bufferpercent;
1251                                        char* tmpstr = NULL;
1252                                        tmpstr = ostrcat(_("Buffering Stream - Cancel with Exit"), " (", 0, 0);
1253                                        tmpstr = ostrcat(tmpstr, oitoa(waitmsgbar->progresssize), 1, 0);
1254                                        tmpstr = ostrcat(tmpstr, "%)", 1, 0);
1255                                        changetext(waitmsgbar, tmpstr);
1256                                        free(tmpstr); tmpstr = NULL;
1257       
1258                                        drawscreen(load, 0, 0);
1259                                        drawscreen(waitmsgbar, 0, 0);
1260                                        status.cleaninfobar = 0;
1261                                }
1262                                else
1263                                {
1264                                        drawscreen(skin, 0, 0);
1265                                        gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
1266                                        status.prefillbuffer = 0;
1267                                        status.cleaninfobar = 1;
1268                                }
1269       
1270                        }
1271                        else if(status.prefillbuffer == 2)
1272                        {
1273                                drawscreen(skin, 0, 0);
1274                                gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
1275                                status.prefillbuffer = 0;
1276                                status.cleaninfobar = 1;
1277                        }
1278                        else if(status.cleaninfobar == 1)
1279                        {
1280                                drawscreen(skin, 0, 0);
1281                                status.cleaninfobar = 0;
1282                        }
1283
1284                        break;
1285 
1286/*
1287                        GstBufferingMode mode;
1288                        gst_message_parse_buffering(msg, &(status.bufferpercent));
1289                        gst_message_parse_buffering_stats(msg, &mode, &(status.avgInRate), &(status.avgOutRate), &(status.bufferingLeft));
1290
1291//                      printf("#########################################################\n");
1292//                      printf("Buffering %u percent done\n", status.bufferpercent);
1293//                      printf("avgInRate %d\n", status.avgInRate);
1294//                      printf("avgOutRate %d\n", status.avgOutRate);
1295//                      printf("bufferingLeft %lld\n", status.bufferingLeft);
1296                                       
1297                        if(status.prefillbuffer == 1)
1298                        {
1299                                printf("status.prefillbuffer Buffering %u percent done\n", status.bufferpercent);
1300
1301                                if (status.bufferpercent == 100)
1302                                {
1303                                        GstState state;
1304                                        gst_element_get_state(pipeline, &state, NULL, 0LL);
1305                                        if (state != GST_STATE_PLAYING)
1306                                        {
1307                                                // eDebug("start playing");
1308                                                gst_element_set_state (pipeline, GST_STATE_PLAYING);
1309                                        }
1310//                                      m_ignore_buffering_messages = 5;
1311                                        status.prefillbuffer = 0;
1312                                }
1313                                else if (status.bufferpercent == 0)
1314                                {
1315                                        // eDebug("start pause");
1316                                        gst_element_set_state (pipeline, GST_STATE_PAUSED);
1317//                                      m_ignore_buffering_messages = 0;
1318                                }
1319                        }
1320*/
1321/*
1322                                GstBufferingMode mode;
1323                                printf("GST_STATE_PAUSED\n");
1324                                gst_element_set_state (pipeline, GST_STATE_PAUSED);
1325
1326
1327                                gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
1328                                // eDebug("Buffering %u percent done", m_bufferInfo.bufferPercent);
1329                                gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
1330                                m_event((iPlayableService*)this, evBuffering);
1331                                if (m_use_prefillbuffer && !m_is_live && --m_ignore_buffering_messages <= 0)
1332                                {
1333                                        if (m_bufferInfo.bufferPercent == 100)
1334                                        {
1335                                                GstState state;
1336                                                gst_element_get_state(pipeline, &state, NULL, 0LL);
1337                                                if (state != GST_STATE_PLAYING)
1338                                                {
1339                                                        // eDebug("start playing");
1340                                                        gst_element_set_state (pipeline, GST_STATE_PLAYING);
1341                                                }
1342                                                m_ignore_buffering_messages = 5;
1343                                        }
1344                                        else if (m_bufferInfo.bufferPercent == 0)
1345                                        {
1346                                                // eDebug("start pause");
1347                                                gst_element_set_state (pipeline, GST_STATE_PAUSED);
1348                                                m_ignore_buffering_messages = 0;
1349                                        }
1350                                        else
1351                                        {
1352                                                m_ignore_buffering_messages = 0;
1353                                        }
1354                                }
1355
1356*/
1357                        break;
1358                case GST_MESSAGE_STREAM_STATUS:
1359                        debug(150, "gst player stream status");
1360
1361/*
1362                        GstStreamStatusType type;
1363                        GstElement *owner;
1364
1365                        gst_message_parse_stream_status(msg, &type, &owner);
1366                        if(type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming)
1367                        {
1368                                if(GST_IS_PAD(source))
1369                                        owner = gst_pad_get_parent_element(GST_PAD(source));
1370                                else if(GST_IS_ELEMENT(source))
1371                                        owner = GST_ELEMENT(source);
1372                                else
1373                                        owner = NULL;
1374                                if(owner)
1375                                {
1376                                        GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
1377                                        const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
1378                                        if (!strcmp(name, "souphttpsrc"))
1379                                        {
1380                                                //m_streamingsrc_timeout->start(10 * 1000, true);
1381                                                g_object_set(G_OBJECT(owner), "timeout", 10, NULL);
1382                                        }
1383                                       
1384                                }
1385                                if(GST_IS_PAD(source))
1386                                        gst_object_unref(owner);
1387                        }
1388*/
1389                        break;
1390                default:
1391                        debug(150, "gst player unknown message");
1392                        break;
1393        }
1394        g_free(sourceName);
1395        return ret;
1396}
1397#endif
1398
1399int playergetbuffersize()
1400{
1401        int ret = 0;
1402
1403#ifdef EPLAYER3
1404        if(player && player->container && player->container->selectedContainer)
1405                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_SIZE, (void*)&ret);
1406#endif
1407
1408        return ret;
1409}
1410
1411int playergetbufferstatus()
1412{
1413        int ret = 0;
1414
1415#ifdef EPLAYER3
1416        if(player && player->container && player->container->selectedContainer)
1417                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_STATUS, (void*)&ret);
1418#endif
1419
1420        return ret;
1421}
1422
1423int playerstopbuffer()
1424{
1425        int ret = 0;
1426
1427#ifdef EPLAYER3
1428        if(player && player->container && player->container->selectedContainer)
1429                player->container->selectedContainer->Command(player, CONTAINER_STOP_BUFFER, NULL);
1430#endif
1431
1432        return ret;
1433}
1434
1435int playerisplaying()
1436{
1437#ifdef SIMULATE
1438        return 1;
1439#endif
1440
1441#ifdef EPLAYER3
1442        if(player != NULL && player->playback != NULL && player->playback->isPlaying)
1443                return 1;
1444#endif
1445
1446#ifdef EPLAYER4
1447        int ret = 1;
1448
1449        if(pipeline)
1450        {
1451                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
1452                GstMessage *message = NULL;
1453//use global variale, with static var crash
1454//              CustomData *data = NULL;
1455                while((message = gst_bus_pop(bus)))
1456                {
1457                        ret = gstbuscall(bus, message, &data);
1458                        gst_message_unref(message);
1459                }               
1460
1461// eof workaround for some mp4 files.
1462                gint64 pts = 0, len = 0, rest = 0;
1463                gint64 nanos_pts = 0, nanos_len = 0;
1464
1465                len = playergetlength();
1466                nanos_len = len * 1000000000;
1467                if(nanos_len < 0) nanos_len = 0;
1468
1469                pts = playergetpts();
1470                nanos_pts = pts * 11111;
1471
1472                rest = nanos_len - nanos_pts;
1473//              printf("rest: %lld\n", nanos_len - nanos_pts);
1474
1475                debug(150, "status.pause=%d status.playspeed=%d status.slowspeed=%d status.prefillbuffer=%d rest=%lld", status.pause, status.playspeed, status.slowspeed, status.prefillbuffer, rest);
1476                if(rest > 4000000000LL || status.pts != pts || pts == 0 || status.pause == 1 || status.playspeed != 0 || status.slowspeed != 0 /*|| status.prefillbuffer == 1*/)
1477                {
1478//                      debug(150, "status.pts=%llu / pts=%llu\n", status.pts, pts);
1479                        status.pts = pts;
1480                }
1481                else
1482                {
1483                        debug(150, "gst player eof - workaround (rest=%lld)", rest);
1484                        ret = 0;
1485                }
1486// eof workaround done
1487        }
1488        else
1489                ret = 0;
1490
1491        return ret;
1492#endif
1493        return 0;
1494}
1495
1496void playerplay()
1497{
1498#ifdef EPLAYER3
1499        if(player && player->playback)
1500                player->playback->Command(player, PLAYBACK_PLAY, NULL);
1501#endif
1502
1503#ifdef EPLAYER4
1504        if(pipeline)
1505                gst_element_set_state(pipeline, GST_STATE_PLAYING);
1506        if(subtitleflag == 2)
1507                subtitleflag = 1;
1508#endif
1509}
1510
1511int playerstop()
1512{
1513#ifdef EPLAYER3
1514        if(player && player->playback)
1515                player->playback->Command(player, PLAYBACK_STOP, NULL);
1516        if(player && player->container && player->container->selectedContainer)
1517                player->container->selectedContainer->Command(player, CONTAINER_STOP, NULL);
1518        if(player && player->output)
1519        {
1520                player->output->Command(player, OUTPUT_CLOSE, NULL);
1521                player->output->Command(player, OUTPUT_DEL, (void*)"audio");
1522                player->output->Command(player, OUTPUT_DEL, (void*)"video");
1523                player->output->Command(player, OUTPUT_DEL, (void*)"subtitle");
1524        }
1525        if(player && player->playback)
1526                player->playback->Command(player, PLAYBACK_CLOSE, NULL);
1527
1528        free(player);
1529        player = NULL;
1530// move to mc
1531//      set_player_sound(1);
1532#endif
1533
1534#ifdef EPLAYER4
1535        subtitleflag = 0;
1536        if(subtitlethread != 0)
1537                subtitlethread->aktion = STOP;
1538        if(video_sink)
1539        {
1540                gst_object_unref (video_sink);
1541                video_sink = NULL;
1542        }
1543        if(pipeline)
1544        {
1545                gst_element_set_state(pipeline, GST_STATE_NULL);
1546                gst_object_unref(GST_OBJECT(pipeline));
1547                pipeline = NULL;
1548        }
1549#endif
1550
1551        writesysint("/proc/sys/vm/drop_caches", 3, 0);
1552        return 0;
1553}
1554
1555void playerafterend()
1556{
1557#ifdef EPLAYER3
1558        if(player != NULL && player->playback != NULL)
1559                playerstop();
1560#endif
1561
1562#ifdef EPLAYER4
1563        if(pipeline)
1564                playerstop();
1565#endif
1566}
1567
1568void playerpause()
1569{
1570#ifdef EPLAYER3
1571        if(player && player->playback)
1572                player->playback->Command(player, PLAYBACK_PAUSE, NULL);
1573#endif
1574
1575#ifdef EPLAYER4
1576        if(pipeline)
1577                gst_element_set_state(pipeline, GST_STATE_PAUSED);
1578#endif
1579}
1580
1581void playercontinue()
1582{
1583#ifdef EPLAYER3
1584        if(player && player->playback)
1585                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
1586#endif
1587
1588#ifdef EPLAYER4
1589        if(pipeline)
1590        {
1591                if(status.playspeed != 0 || status.slowspeed != 0)
1592                {
1593                        //subtitle sync bug... start
1594                        gint64 time_nanoseconds = 0;
1595                        GstFormat fmt = GST_FORMAT_TIME;
1596#if GST_VERSION_MAJOR < 1
1597                        if (!gst_element_query_position(pipeline, &fmt, &time_nanoseconds))
1598#else
1599                        if (!gst_element_query_position(pipeline, fmt, &time_nanoseconds))
1600#endif
1601                        {
1602                                err("gst_element_query_position failed");
1603                                return;
1604                        }
1605                        time_nanoseconds = time_nanoseconds - 90000;
1606                        if (!gst_element_seek (pipeline, 1, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT),GST_SEEK_TYPE_SET, time_nanoseconds,GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
1607                                printf("seekTo failed");
1608                        //subtitle sync bug... end
1609
1610                        //playersend_ff_fr_event(1);
1611                }               
1612                gst_element_set_state(pipeline, GST_STATE_PLAYING);
1613                if(subtitleflag == 2)
1614                        subtitleflag = 1;
1615        }
1616#endif
1617}
1618
1619void playerff(int speed)
1620{
1621#ifdef EPLAYER3
1622        int speedmap = 0;
1623
1624        if (speed < 1) speed = 1;
1625        if (speed > 7) speed = 7;
1626
1627        switch(speed)
1628        {
1629                case 1: speedmap = 1; break;
1630                case 2: speedmap = 3; break;
1631                case 3: speedmap = 7; break;
1632                case 4: speedmap = 15; break;
1633                case 5: speedmap = 31; break;
1634                case 6: speedmap = 63; break;
1635                case 7: speedmap = 127; break;
1636        }
1637
1638        if(player && player->playback)
1639                player->playback->Command(player, PLAYBACK_FASTFORWARD, &speedmap);
1640#endif
1641
1642#ifdef EPLAYER4
1643        gdouble rate = 0;
1644        subtitleflag = 2;
1645        if (speed < 1) speed = 1;
1646        if (speed > 7) speed = 7;
1647
1648        switch(speed)
1649        {
1650                case 1: rate = 2; break;
1651                case 2: rate = 4; break;
1652                case 3: rate = 8; break;
1653                case 4: rate = 16; break;
1654                case 5: rate = 32; break;
1655                case 6: rate = 64; break;
1656                case 7: rate = 128; break;
1657        }
1658        playersend_ff_fr_event(rate);
1659#endif
1660}
1661
1662void playerslow(int speed)
1663{
1664#ifdef EPLAYER3
1665        int speedmap = 0;
1666
1667        if (speed < 1) speed = 1;
1668        if (speed > 7) speed = 7;
1669
1670        switch(speed)
1671        {
1672                case 1: speedmap = 1; break;
1673                case 2: speedmap = 3; break;
1674                case 3: speedmap = 7; break;
1675                case 4: speedmap = 15; break;
1676                case 5: speedmap = 31; break;
1677                case 6: speedmap = 63; break;
1678                case 7: speedmap = 127; break;
1679        }
1680
1681        if(player && player->playback)
1682                player->playback->Command(player, PLAYBACK_SLOWMOTION, &speedmap);
1683#endif
1684
1685#ifdef EPLAYER4
1686        gdouble rate = 0;
1687        if (speed < 1) speed = 1;
1688        if (speed > 7) speed = 7;
1689               
1690        switch(speed)
1691        {
1692                case 1: rate = 0.8; break;
1693                case 2: rate = 0.7; break;
1694                case 3: rate = 0.6; break;
1695                case 4: rate = 0.5; break;
1696                case 5: rate = 0.3; break;
1697                case 6: rate = 0.2; break;
1698                case 7: rate = 0.1; break;
1699        }
1700        gst_element_set_state(pipeline, GST_STATE_PLAYING);
1701        playersend_ff_fr_event(rate);
1702       
1703#endif
1704
1705}
1706
1707void playerfr(int speed)
1708{
1709#ifdef EPLAYER3
1710        int speedmap = 0;
1711
1712        if (speed > -1) speed = -1;
1713        if (speed < -7) speed = -7;
1714
1715        switch(speed)
1716        {
1717                case -1: speedmap = -5; break;
1718                case -2: speedmap = -10; break;
1719                case -3: speedmap = -20; break;
1720                case -4: speedmap = -40; break;
1721                case -5: speedmap = -80; break;
1722                case -6: speedmap = -160; break;
1723                case -7: speedmap = -320; break;
1724        }
1725
1726        if(player && player->playback)
1727                player->playback->Command(player, PLAYBACK_FASTBACKWARD, &speedmap);
1728#endif
1729
1730#ifdef EPLAYER4
1731        gdouble rate = 0;
1732       
1733        if (speed > -1) speed = -1;
1734        if (speed < -7) speed = -7;
1735
1736        switch(speed)
1737        {
1738                case -1: rate = -2; break;
1739                case -2: rate = -4; break;
1740                case -3: rate = -8; break;
1741                case -4: rate = -16; break;
1742                case -5: rate = -32; break;
1743                case -6: rate = -64; break;
1744                case -7: rate = -128; break;
1745        }
1746        playersend_ff_fr_event(rate);
1747#endif
1748}
1749
1750void playerseek(float sec)
1751{
1752#ifdef EPLAYER3
1753        if(player && player->playback)
1754                player->playback->Command(player, PLAYBACK_SEEK, (void*)&sec);
1755#endif
1756
1757#ifdef EPLAYER4
1758        gint64 nanos_pts = 0, nanos_len = 0;
1759        gint64 pts = 0, len = 0;
1760        //GstFormat fmt = GST_FORMAT_TIME;
1761               
1762        if(pipeline)
1763        {
1764                len = playergetlength();
1765                nanos_len = len * 1000000000;
1766                if(nanos_len < 0) nanos_len = 0;
1767
1768                pts = playergetpts();
1769                nanos_pts = pts * 11111;
1770                nanos_pts = nanos_pts + (sec * 1000000000);
1771                if(nanos_pts < 0) nanos_pts = 0;
1772
1773                if(nanos_pts >= nanos_len)
1774                {
1775                        debug(150, "gst skip seeking");
1776//                      playerstop();
1777                }
1778                else
1779                        gst_element_seek(pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, nanos_pts, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
1780        }
1781#endif
1782}
1783
1784#ifdef EPLAYER4
1785audiotype_t gstCheckAudioPad(GstStructure* structure)
1786{
1787        if(!structure)
1788                return atUnknown;
1789
1790        if(gst_structure_has_name(structure, "audio/mpeg"))
1791        {
1792                gint mpegversion, layer = -1;
1793                if(!gst_structure_get_int (structure, "mpegversion", &mpegversion))
1794                        return atUnknown;
1795
1796                switch(mpegversion)
1797                {
1798                        case 1:
1799                                {
1800                                        gst_structure_get_int(structure, "layer", &layer);
1801                                        if(layer == 3)
1802                                                return atMP3;
1803                                        else
1804                                                return atMPEG;
1805                                        break;
1806                                }
1807                        case 2:
1808                                return atAAC;
1809                        case 4:
1810                                return atAAC;
1811                        default:
1812                                return atUnknown;
1813                }
1814        }
1815
1816        else if(gst_structure_has_name(structure, "audio/x-ac3") || gst_structure_has_name(structure, "audio/ac3"))
1817                return atAC3;
1818        else if(gst_structure_has_name(structure, "audio/x-dts") || gst_structure_has_name(structure, "audio/dts"))
1819                return atDTS;
1820#if GST_VERSION_MAJOR < 1
1821        else if(gst_structure_has_name(structure, "audio/x-raw-int"))
1822#else
1823        else if(gst_structure_has_name(structure, "audio/x-raw"))
1824#endif
1825                return atPCM;
1826
1827        return atUnknown;
1828}
1829
1830
1831subtype_t getSubtitleType(GstPad* pad, gchar *g_codec)
1832{
1833g_codec = NULL;
1834        subtype_t type = stUnknown;
1835#if GST_VERSION_MAJOR < 1
1836        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
1837#else
1838        GstCaps* caps = gst_pad_get_current_caps(pad);
1839#endif
1840        if (!caps && !g_codec)
1841        {
1842                caps = gst_pad_get_allowed_caps(pad);
1843        }
1844
1845        if (caps && !gst_caps_is_empty(caps))
1846        {
1847                GstStructure* str = gst_caps_get_structure(caps, 0);
1848                if (str)
1849                {
1850                        const gchar *g_type = gst_structure_get_name(str);
1851                        // eDebug("getSubtitleType::subtitle probe caps type=%s", g_type ? g_type : "(null)");
1852                        if (g_type)
1853                        {
1854#if GST_VERSION_MAJOR < 1
1855                                if ( !strcmp(g_type, "video/x-dvd-subpicture") )
1856#else
1857                                if ( !strcmp(g_type, "subpicture/x-dvd") )
1858#endif
1859                                        type = stVOB;
1860                                else if ( !strcmp(g_type, "text/x-pango-markup") )
1861                                        type = stSRT;
1862                                else if ( !strcmp(g_type, "text/plain") || !strcmp(g_type, "text/x-plain") || !strcmp(g_type, "text/x-raw") )
1863                                        type = stPlainText;
1864                                else if ( !strcmp(g_type, "subpicture/x-pgs") )
1865                                        type = stPGS;
1866                                else
1867                                        printf("getSubtitleType::unsupported subtitle caps %s (%s)\n", g_type, g_codec ? g_codec : "(null)");
1868//                                      eDebug("getSubtitleType::unsupported subtitle caps %s (%s)", g_type, g_codec ? g_codec : "(null)");
1869                        }
1870                }
1871        }
1872        else if ( g_codec )
1873        {
1874                // eDebug("getSubtitleType::subtitle probe codec tag=%s", g_codec);
1875                if ( !strcmp(g_codec, "VOB") )
1876                        type = stVOB;
1877                else if ( !strcmp(g_codec, "SubStation Alpha") || !strcmp(g_codec, "SSA") )
1878                        type = stSSA;
1879                else if ( !strcmp(g_codec, "ASS") )
1880                        type = stASS;
1881                else if ( !strcmp(g_codec, "SRT") )
1882                        type = stSRT;
1883                else if ( !strcmp(g_codec, "UTF-8 plain text") )
1884                        type = stPlainText;
1885                else
1886                        printf("getSubtitleType::unsupported subtitle codec %s\n", g_codec);
1887        }
1888        else
1889                printf("getSubtitleType::unidentifiable subtitle stream!\n");
1890
1891        return type;
1892}
1893
1894#endif
1895
1896void playerfreetracklist(char** TrackList)
1897{
1898        int i = 0;
1899
1900        if(TrackList != NULL)
1901        {
1902                while(TrackList[i] != NULL)
1903                {
1904                        free(TrackList[i]);
1905                        free(TrackList[i + 1]);
1906                        i += 2;
1907                }
1908        }
1909}
1910
1911char** playergettracklist(int type)
1912{
1913        char ** TrackList = NULL;
1914#ifdef EPLAYER3
1915        if(player && player->manager)
1916        {
1917                switch(type)
1918                {
1919                        case 1:
1920                                if(player->manager->audio)
1921                                {
1922                                        player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
1923                                        debug(150, "Audio Track List");
1924                                }
1925                                break;
1926                        case 2:
1927                                if(player->manager->subtitle)
1928                                {
1929                                        player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
1930                                        debug(150, "Subtitle Track List");
1931                                }
1932                                break;
1933                        default:
1934                                if(player->manager->video)
1935                                {
1936                                        player->manager->video->Command(player, MANAGER_LIST, &TrackList);
1937                                        debug(150, "Video Track List");
1938                                }
1939                }
1940               
1941                int i = 0;
1942                if(TrackList != NULL)
1943                {
1944                        while(TrackList[i] != NULL)
1945                        {
1946                                string_newline(TrackList[i]);
1947                                i += 2;
1948                        }
1949                       
1950                        debug(150, "Track List");
1951                        i = 0;
1952                        while(TrackList[i] != NULL)
1953                        {
1954                                debug(150, "%s - %s", TrackList[i], TrackList[i + 1]);
1955                                i += 2;
1956                        }
1957                }
1958        }
1959#endif
1960
1961//////////////////////////////NEUER CODE //////////////////////////////
1962#ifdef EPLAYER4
1963        TrackList = calloc(1, sizeof(char *) * ((100 * 2) + 1));
1964       
1965        if(pipeline != NULL)
1966        {
1967                gint i, n_video = 0, n_audio = 0, n_text = 0;
1968               
1969                g_object_get(pipeline, "n-video", &n_video, NULL);
1970                g_object_get(pipeline, "n-audio", &n_audio, NULL);
1971                g_object_get(pipeline, "n-text", &n_text, NULL);
1972
1973                switch(type)
1974                {
1975                        case 1:
1976                                for(i = 0; i < n_audio; i++)
1977                                {
1978                                        GstTagList *tags = NULL;
1979                                        gchar *g_codec = NULL, *g_lang = NULL;
1980                                        char* tmpstr = NULL;
1981                                        GstPad* pad = 0;
1982                                       
1983                                        g_signal_emit_by_name (pipeline, "get-audio-pad", i, &pad);
1984#if GST_VERSION_MAJOR < 1
1985                                        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
1986#else
1987                                        GstCaps* caps = gst_pad_get_current_caps(pad);
1988#endif
1989                                        if(!caps)
1990                                                continue;
1991                                       
1992                                        GstStructure* str = gst_caps_get_structure(caps, 0);
1993                                        const gchar *g_type = gst_structure_get_name(str);
1994
1995                                        g_signal_emit_by_name(pipeline, "get-audio-tags", i, &tags);
1996
1997#if GST_VERSION_MAJOR < 1
1998                                        if(tags && gst_is_tag_list(tags))
1999#else
2000                                        if(tags && GST_IS_TAG_LIST(tags))
2001#endif
2002                                        {
2003                                                if(gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_codec))
2004                                                {
2005                                                        printf("Audio Codec: %s\n", g_codec);
2006       
2007                                                        tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
2008                                                        tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
2009                                                        if(g_codec != NULL && g_type != NULL)
2010                                                                tmpstr = ostrcat(tmpstr, " (", 1, 0);
2011                                                        tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
2012                                                        if(g_codec != NULL && g_type != NULL)
2013                                                                tmpstr = ostrcat(tmpstr, ")", 1, 0);
2014
2015                                                        printf("Tracklist tmpstr: %s\n", tmpstr);
2016
2017                                                        TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2018                                                        g_free(tmpstr); tmpstr = NULL;
2019                                                        g_free(g_codec); g_codec = NULL;
2020                                                }
2021                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
2022                                                {
2023                                                        printf("Audio Lang: %s\n", g_lang);
2024                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
2025                                                        g_free(g_lang); g_lang = NULL;
2026                                                }
2027                                                gst_tag_list_free(tags);
2028                                        }
2029                                        else
2030                                        {
2031                                                printf("Audio Codec: %s\n", g_codec);
2032                                               
2033                                                tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
2034                                                tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
2035                                                if(g_codec != NULL && g_type != NULL)
2036                                                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
2037                                                tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
2038                                                if(g_codec != NULL && g_type != NULL)
2039                                                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
2040
2041                                                printf("Tracklist tmpstr: %s\n", tmpstr);                               
2042                                                TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2043
2044                                                g_free(tmpstr); tmpstr = NULL;
2045                                                g_free(g_codec); g_codec = NULL;
2046                                        }
2047                                }
2048                                break;
2049                        case 2:
2050                                for(i = 0; i < n_text; i++)
2051                                {
2052                                        GstTagList *tags = NULL;
2053                                        gchar *g_codec = NULL, *g_lang = NULL;
2054                                        GstPad* pad = 0;
2055                                        char* tmpstr = NULL;
2056
2057                                        g_signal_emit_by_name (pipeline, "get-text-pad", i, &pad);
2058                                        printf("SubTitle Type: %d\n", getSubtitleType(pad, g_codec));
2059
2060#if GST_VERSION_MAJOR < 1
2061                                        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
2062#else
2063                                        GstCaps* caps = gst_pad_get_current_caps(pad);
2064#endif
2065                                        if (!caps && !g_codec)
2066                                        {
2067                                                caps = gst_pad_get_allowed_caps(pad);
2068                                        }
2069                                               
2070                                        GstStructure* str = gst_caps_get_structure(caps, 0);
2071                                        const gchar *g_type = gst_structure_get_name(str);
2072
2073                                        g_signal_emit_by_name(pipeline, "get-text-tags", i, &tags);
2074                                       
2075#if GST_VERSION_MAJOR < 1
2076                                        if (tags && gst_is_tag_list(tags))
2077#else
2078                                        if (tags && GST_IS_TAG_LIST(tags))
2079#endif
2080                                        {
2081                                                if(gst_tag_list_get_string(tags, GST_TAG_SUBTITLE_CODEC, &g_codec));
2082                                                {
2083                                                        printf("SubTitle Codec: %s\n", g_codec);
2084                                                        tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
2085                                                        tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
2086                                                        if(g_codec != NULL && g_type != NULL)
2087                                                                tmpstr = ostrcat(tmpstr, " (", 1, 0);
2088                                                        tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
2089                                                        if(g_codec != NULL && g_type != NULL)
2090                                                                tmpstr = ostrcat(tmpstr, ")", 1, 0);
2091
2092                                                        printf("Tracklist tmpstr: %s\n", tmpstr);
2093                                                        TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2094                                                        g_free(g_codec); g_codec = NULL;
2095                                                }
2096                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
2097                                                {
2098                                                        printf("SubTitle Lang: %s\n", g_lang);
2099                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
2100                                                        g_free(g_lang); g_lang = NULL;
2101                                                }
2102                                                gst_tag_list_free(tags);
2103                                        }
2104                                        else
2105                                        {
2106                                                printf("SubTitle Codec: %s\n", g_codec);
2107                                               
2108                                                tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
2109                                                tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
2110                                                if(g_codec != NULL && g_type != NULL)
2111                                                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
2112                                                tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
2113                                                if(g_codec != NULL && g_type != NULL)
2114                                                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
2115
2116                                                printf("Tracklist tmpstr: %s\n", tmpstr);               
2117                                                TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2118
2119                                                g_free(tmpstr); tmpstr = NULL;
2120                                                g_free(g_codec); g_codec = NULL;                               
2121                                        }
2122                                }
2123                                break;
2124                        default:
2125                                for(i = 0; i < n_video; i++)
2126                                {
2127                                        GstTagList *tags = NULL;
2128                                        gchar *g_codec = NULL, *g_lang = NULL;
2129                                       
2130                                        g_signal_emit_by_name(pipeline, "get-video-tags", i, &tags);
2131                                       
2132#if GST_VERSION_MAJOR < 1
2133                                        if (tags && gst_is_tag_list(tags))
2134#else
2135                                        if (tags && GST_IS_TAG_LIST(tags))
2136#endif
2137                                        {
2138                                                if(gst_tag_list_get_string(tags, GST_TAG_VIDEO_CODEC, &g_codec));
2139                                                {
2140                                                        printf("Video Codec: %s\n", g_codec);
2141                                                        TrackList[i * 2] = ostrcat(g_codec, NULL, 0, 0);
2142                                                        g_free(g_codec); g_codec = NULL;
2143                                                }
2144                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
2145                                                {
2146                                                        printf("Video Lang: %s\n", g_lang);
2147                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
2148                                                        g_free(g_lang); g_lang = NULL;
2149                                                }
2150                                                gst_tag_list_free(tags);
2151                                        }
2152                                }
2153                }
2154        }
2155#endif
2156//////////////////////////////NEUER CODE //////////////////////////////
2157
2158        return TrackList;
2159}
2160
2161//*CurTrackEncoding and *CurTrackName be freed
2162void playergetcurtrac(int type, int *CurTrackId, char** CurTrackEncoding, char** CurTrackName)
2163{
2164#ifdef EPLAYER3
2165        if(player && player->manager)
2166        {
2167                switch(type)
2168                {
2169                        case 1:
2170                                if(player->manager->audio)
2171                                {
2172                                        player->manager->audio->Command(player, MANAGER_GET, CurTrackId);
2173                                        player->manager->audio->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
2174                                        player->manager->audio->Command(player, MANAGER_GETNAME, CurTrackName);
2175                                }
2176                                break;
2177                        case 2:
2178                                if(player->manager->subtitle)
2179                                {
2180                                        player->manager->subtitle->Command(player, MANAGER_GET, CurTrackId);
2181                                        player->manager->subtitle->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
2182                                        player->manager->subtitle->Command(player, MANAGER_GETNAME, CurTrackName);
2183                                }
2184                                break;
2185                        default:
2186                                if(player->manager->video)
2187                                {
2188                                        player->manager->video->Command(player, MANAGER_GET, CurTrackId);
2189                                        player->manager->video->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
2190                                        player->manager->video->Command(player, MANAGER_GETNAME, CurTrackName);
2191                                }
2192                }
2193
2194                if(CurTrackId != NULL)
2195                        debug(150, "Current Track ID: %d", *CurTrackId);
2196                if(*CurTrackEncoding != NULL)
2197                        debug(150, "Current Track Enc: %s", *CurTrackEncoding);
2198                if(*CurTrackName != NULL)
2199                        debug(150, "Current Track Name: %s", *CurTrackName);
2200        }
2201#endif
2202
2203#ifdef EPLAYER4
2204        if(pipeline != NULL)
2205        {
2206                switch(type)
2207                {
2208                        case 1:
2209                                g_object_get(G_OBJECT(pipeline), "current-audio", CurTrackId, NULL);
2210                                break;
2211                        case 2:
2212                                if(subtitleflag == 0)
2213                                        *CurTrackId = -1;
2214                                else
2215                                        g_object_get(G_OBJECT(pipeline), "current-text", CurTrackId, NULL);
2216                                break;
2217                }
2218                if(CurTrackId != NULL) {
2219                        debug(150, "Current Track ID: %d", *CurTrackId);
2220                }
2221        }
2222#endif
2223}
2224
2225unsigned long long playergetpts()
2226{
2227        unsigned long long pts = 0;
2228        unsigned long long sec = 0;
2229
2230#ifdef EPLAYER3
2231        if(player && player->playback)
2232        {
2233                player->playback->Command(player, PLAYBACK_PTS, &pts);
2234                sec = pts / 90000;
2235                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
2236        }
2237#endif
2238
2239#ifdef EPLAYER4
2240        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
2241       
2242/*
2243        if(pipeline)
2244        {
2245#if GST_VERSION_MAJOR < 1
2246                gst_element_query_position(pipeline, &fmt, (gint64*)&pts);
2247#else
2248                gst_element_query_position(pipeline, fmt, (gint64*)&pts);
2249#endif
2250                sec = pts / 1000000000;
2251                pts = sec * 90000;
2252                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
2253        }
2254*/
2255
2256        if(pipeline)
2257        {
2258                gint64 pos;
2259                GstElement *sink;
2260                pts = 0;
2261
2262                g_object_get(G_OBJECT (pipeline), "audio-sink", &sink, NULL);
2263
2264                if(!sink) g_object_get (G_OBJECT (pipeline), "video-sink", &sink, NULL);
2265                if(!sink) return 0;
2266
2267                gchar *name = gst_element_get_name(sink);
2268                gboolean use_get_decoder_time = ostrstr(name, "dvbaudiosink") || ostrstr(name, "dvbvideosink");
2269                g_free(name);
2270
2271                if(use_get_decoder_time) g_signal_emit_by_name(sink, "get-decoder-time", &pos);
2272
2273                gst_object_unref(sink);
2274
2275#if GST_VERSION_MAJOR < 1
2276                if(!use_get_decoder_time && !gst_element_query_position(pipeline, &fmt, &pos))
2277#else
2278                if(!use_get_decoder_time && !gst_element_query_position(pipeline, fmt, &pos))
2279#endif
2280                        return 0;
2281
2282                /* pos is in nanoseconds. we have 90 000 pts per second. */
2283                pts = pos / 11111;
2284                pts = pts - m_gst_startpts;
2285                sec = pts / 90000;
2286                debug(150, "StartPTS = %llu Pts = %02d:%02d:%02d (%llu.0000 sec)", m_gst_startpts, (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
2287        }
2288#endif
2289
2290        if(pts < 0) pts = 0;
2291        return pts;
2292}
2293
2294double playergetlength()
2295{
2296        double length = 0;
2297
2298#ifdef EPLAYER3
2299        if(player && player->playback)
2300        {
2301                player->playback->Command(player, PLAYBACK_LENGTH, &length);
2302                if(length < 0) length = 0;
2303                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
2304        }
2305#endif
2306
2307#ifdef EPLAYER4
2308        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
2309        gint64 len;
2310
2311        if(pipeline)
2312        {
2313#if GST_VERSION_MAJOR < 1
2314                gst_element_query_duration(pipeline, &fmt, &len);
2315#else
2316                gst_element_query_duration(pipeline, fmt, &len);
2317#endif
2318                length = len / 1000000000;
2319                if(length < 0) length = 0;
2320                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
2321        }
2322#endif
2323
2324        return length;
2325}
2326
2327char* playergetinfo(char* tag)
2328{
2329        char* ret = NULL;
2330
2331#ifdef EPLAYER3
2332        char *tags[] = {"Title", "Artist", "Album", "Year", "Genre", "Comment", "Track", "Copyright", "TestLibEplayer", NULL};
2333        int i = 0;
2334
2335        if(player && player->playback)
2336        {
2337                while(tags[i] != NULL)
2338                {
2339                        ret = tags[i];
2340                        if(ostrcmp(tag, ret) == 0)
2341                        {
2342                                player->playback->Command(player, PLAYBACK_INFO, &ret);
2343                                break;
2344                        }
2345
2346                        i++;
2347                }
2348        }
2349#endif
2350        return ret;
2351}
2352
2353void playerchangeaudiotrack(int num)
2354{
2355#ifdef EPLAYER3
2356        if(player && player->playback)
2357                player->playback->Command(player, PLAYBACK_SWITCH_AUDIO, (void*)&num);
2358#endif
2359
2360#ifdef EPLAYER4
2361        if(pipeline != NULL)
2362                g_object_set(G_OBJECT(pipeline), "current-audio", num, NULL);   
2363#endif
2364}
2365
2366void playerchangesubtitletrack(int num)
2367{
2368#ifdef EPLAYER3
2369        if(player && player->playback)
2370                player->playback->Command(player, PLAYBACK_SWITCH_SUBTITLE, (void*)&num);
2371#endif
2372
2373#ifdef EPLAYER4
2374        printf("player: set subtitle: %d\n", num);
2375        if(pipeline != NULL)
2376                g_object_set(G_OBJECT(pipeline), "current-text", num, NULL);
2377        subtitleflag = 1;       
2378#endif
2379}
2380
2381void playerstopsubtitletrack()
2382{
2383#ifdef EPLAYER3
2384        if(player && player->output && player->output->subtitle)
2385                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_STOP, NULL);
2386        if(player && player->container && player->container->assContainer)
2387        {
2388                player->container->assContainer->Command(player, CONTAINER_STOP, NULL);
2389                player->container->assContainer->Command(player, CONTAINER_INIT, NULL);
2390        }
2391        if(player && player->manager && player->manager->subtitle)
2392        {
2393                int onlycurrent = 1;
2394                player->manager->subtitle->Command(player, MANAGER_DEL, (void*)&onlycurrent);
2395        }
2396#endif
2397
2398#ifdef EPLAYER4
2399        printf("player: stop subtitle\n");
2400        subtitleflag = 0;
2401        //if(pipeline != NULL)
2402        //      g_object_set(G_OBJECT(pipeline), "current-text", -1, NULL);
2403        if(subtitlethread != NULL)
2404                subtitlethread->aktion = STOP;
2405#endif
2406}
2407
2408int playerjumpts(struct service* servicenode, int sekunden, int *startpts, off64_t *poslastpts, off64_t *bitrate, int vpid, int tssize)
2409{
2410        int adaptation = 0;
2411        int payload = 0;
2412        int pes = 0;
2413        int tspid = 0;
2414       
2415        off64_t pts  = 0;
2416        uint64_t aktpts = 0;
2417        long long unsigned int lenpts = 0;
2418        long long unsigned int startpts1 = 0;
2419        long long unsigned int endpts = 0;
2420        long long unsigned int aktbitrate = 0;
2421        off64_t ziehlpts = 0;
2422
2423        off64_t curpos = 0;
2424        off64_t newpos = 0;
2425        off64_t jump = 0;
2426
2427        int kleiner = 0;
2428        int groesser = 0;
2429        int gleich = 0;
2430        int len = 0;
2431        int i = 0;
2432        int ret = 0;
2433
2434        if(servicenode == NULL) return -1;
2435
2436        int buflen = tssize * 15000;
2437        char *buf = malloc(buflen);
2438        if(buf == NULL)
2439                return -1;
2440       
2441        curpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);   
2442        int dupfd = open(servicenode->recname, O_RDONLY | O_LARGEFILE);
2443        newpos = lseek64(dupfd, curpos, SEEK_SET);
2444       
2445        if (*startpts == 0)
2446        {
2447                if(videogetpts(status.aktservice->videodev, &aktpts) == 0)
2448                {
2449                                ziehlpts = (aktpts / 90000) + sekunden;
2450                }
2451                else
2452                        return 1;
2453        }
2454        else
2455        {
2456                ziehlpts = *startpts + sekunden;
2457        }
2458        *startpts = ziehlpts;
2459
2460        if(*bitrate == 0)
2461        {
2462                lenpts = servicenode->lenpts;
2463                startpts1 = servicenode->startpts;
2464                endpts = servicenode->endpts;
2465                aktbitrate = servicenode->bitrate;
2466                ret = gettsinfo(dupfd, &lenpts, &startpts1, &endpts, &aktbitrate, servicenode->tssize);
2467                if(ret != 0)
2468                {
2469                        err("can't read ts info");
2470                }
2471                else
2472                        *bitrate = aktbitrate;
2473                newpos = lseek64(dupfd, curpos, SEEK_SET);
2474        }
2475        else
2476                aktbitrate = *bitrate;
2477               
2478        if(*poslastpts == 0)
2479                *poslastpts = curpos;
2480       
2481        if(sekunden > 0)
2482        {
2483                err("not implemented");
2484                return 1;
2485        }       
2486        else if(sekunden < 0)
2487        {
2488                sekunden = sekunden * -1;
2489                if(aktbitrate != 0)
2490                {
2491                        jump = (aktbitrate / 8) * sekunden;
2492                        jump = jump + (curpos - *poslastpts);
2493                        jump = jump + (jump % servicenode->tssize);
2494                        newpos = lseek64(dupfd, -jump, SEEK_CUR);
2495                }
2496                else
2497                        newpos = lseek64(dupfd, - buflen, SEEK_CUR);
2498                if(newpos < 0)
2499                        newpos = lseek64(dupfd, tssize, SEEK_SET);
2500        }
2501        len = read(dupfd, buf, buflen);
2502        for(i = 0; i < len; i = i + 1)
2503        {
2504                if (buf[i] == 0x47 && buf[i+tssize] == 0x47)
2505                {
2506                        newpos = lseek64(dupfd, newpos + i, SEEK_SET);
2507                        break;
2508                }
2509        }
2510        if(i >= len)
2511        {
2512                newpos = lseek64(dupfd, curpos, SEEK_SET);     
2513                return 1;
2514        }
2515        while(1)
2516        {
2517        len = read(dupfd, buf, buflen);
2518
2519                if(len > 0)
2520                {
2521                        for(i = 0; i <= len-tssize; i = i + tssize)
2522                        {
2523                                payload = 0;
2524
2525                                tspid = (buf[i+1] & 0x1F) << 8;
2526                                tspid = tspid + (buf[i+2] & 0xFF);
2527                                pes = buf[i+1] & 0x40;
2528
2529                                if(tspid == vpid)
2530                                {       
2531                                        adaptation = buf[i+3] & 0x30;
2532                                        if(adaptation == 16)
2533                                        {
2534                                                payload = 4;
2535                                        }
2536                                        if(adaptation == 32)
2537                                        {
2538                                                //printf("adaptation field only\n");
2539                                        }
2540                                        if(adaptation == 48)
2541                                        {
2542                                                payload = buf[i+4] & 0xFF;
2543                                                payload = payload + 5;
2544                                        }
2545                                        if(payload != 0)
2546                                        {
2547                                                if(pes == 64)
2548                                                {
2549                                                        if(buf[i+payload+7] & 0x80) //PTS
2550                                                        {
2551                                                                pts = ((unsigned long long)(buf[i+payload+9] & 0xE)) << 29;
2552                                                                pts |= ((unsigned long long)(buf[i+payload+10] & 0xFF)) << 22;
2553                                                                pts |= ((unsigned long long)(buf[i+payload+11] & 0xFE)) << 14;
2554                                                                pts |= ((unsigned long long)(buf[i+payload+12] & 0xFF)) << 7;
2555                                                                pts |= ((unsigned long long)(buf[i+payload+13] & 0xFE)) >> 1;
2556                                                               
2557                                                                if(pts / 90000 == ziehlpts)
2558                                                                {
2559                                                                        gleich = newpos + i;
2560                                                                        break;
2561                                                                }
2562                                                                else if(pts / 90000 > ziehlpts)
2563                                                                {                                                                       
2564                                                                        groesser = newpos + i;
2565                                                                        break;
2566                                                                }
2567                                                                else
2568                                                                {
2569                                                                        kleiner = newpos + i;
2570                                                                }
2571                                                        }
2572                                                }
2573                                        }
2574                                }
2575                        }
2576                        if(gleich != 0)
2577                        {
2578                                close(dupfd);
2579                                free(buf);buf = NULL;
2580                                *poslastpts = lseek64(servicenode->recsrcfd, gleich, SEEK_SET);
2581                                return 0;
2582                        }
2583                        else if(groesser != 0 && kleiner != 0)
2584                        {
2585                                close(dupfd);
2586                                free(buf);buf = NULL;
2587                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
2588                                return 0;
2589                        }
2590                        else if(groesser != 0)
2591                        {
2592                                if((newpos - buflen)  < 0)
2593                                {
2594                                        close(dupfd);
2595                                        free(buf);buf = NULL;
2596                                        *poslastpts = 0;
2597                                        return -1       ;
2598                                }
2599                                else
2600                                {
2601                                        newpos = lseek64(dupfd, -(buflen * 2), SEEK_CUR);
2602                                }
2603                        }
2604                }
2605                else
2606                {
2607                        if(kleiner == 0)
2608                        {
2609                                close(dupfd);
2610                                free(buf);buf = NULL;
2611                                newpos = lseek64(servicenode->recsrcfd, curpos, SEEK_SET);
2612                                *poslastpts = 0;
2613                                return -1;
2614                        }
2615                        else
2616                        {
2617                                close(dupfd);
2618                                free(buf);buf = NULL;
2619                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
2620                                return 0;
2621                        }
2622                }
2623        }
2624}
2625
2626//praez = 1 .... sekunden
2627//                      =       2 .... zehntel
2628//                      = 3 .... hundertstel
2629//                      = 4 .... volle Uebereinstimmung
2630//
2631//type  = 0 .... alle
2632//                      = 1 .... nur PCR
2633//                      = 2 .... nur Video
2634//                      = 3 .... nur Audio
2635//
2636//flag = 0 --> play ts
2637//flag = 1 --> timeshift
2638//flag = 2 --> timeshift, not in play mode (only recording)
2639//flag = 9 --> dataset mode
2640//
2641off64_t playergetptspos(unsigned long long fpts, off64_t pos, int dir, int praez, int type, int flag, char* dsn)
2642{
2643        unsigned long long pts;
2644        int ret = 0, dupfd = -1, left = 0, tssize = 0, recbsize = 0;
2645        unsigned char* buf = NULL;
2646        unsigned char *payload;
2647        int pid = 0, pusi = 0;
2648        unsigned char* packet;
2649        struct service* snode;
2650       
2651        if(type > 3)
2652        {
2653                printf("type %i nicht unterstützt\n", type);
2654                return -1;
2655        }
2656       
2657        if(flag == 2)
2658                snode = getservice(RECORDTIMESHIFT, 0);
2659        else if(flag != 9)
2660                snode = getservice(RECORDPLAY, 0);
2661               
2662        if(flag == 9)
2663        {
2664                tssize = 188;
2665                recbsize = tssize * 1024 * 10;
2666                dupfd = open(dsn, O_RDONLY | O_LARGEFILE );
2667        }
2668        else
2669        {
2670                tssize = snode->tssize;
2671                recbsize = snode->tssize * 1024 * 10;
2672                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
2673        }
2674
2675        if(dupfd < 0)
2676        {
2677                err("copy source fd not ok");
2678                return -1;
2679        }
2680
2681        buf = malloc(recbsize);
2682        if(buf == NULL)
2683        {
2684                err("no mem");
2685                return -1;
2686        }
2687        packet = buf;
2688        if(dir > 0) 
2689                pos = lseek64(dupfd, pos, SEEK_SET);
2690        else
2691                pos = lseek64(dupfd, pos - recbsize, SEEK_SET);
2692       
2693        ret = read(dupfd,  buf, recbsize);
2694        close(dupfd);
2695        left = 0;
2696       
2697        if(buf[0] != 0x47)
2698        {
2699                while(left < tssize)
2700                {
2701                        if(buf[left] == 0x47) break;
2702                        left++;
2703                }
2704                if(left >= tssize)
2705                {
2706                        free(buf);
2707                        return -1;
2708                }       
2709        }
2710        pts = 0;
2711        while(left <= recbsize - tssize)
2712        {
2713                if(pts != 0)
2714                {
2715                        switch( praez )
2716          {
2717        case 1 :        if(fpts / 90000 != pts / 90000)
2718                                                        pts = 0;
2719                                                break;
2720        case 2 :        if(fpts / 9000 != pts / 9000)
2721                                                        pts = 0;
2722                                                break;
2723        case 3 :        if(fpts / 900 != pts / 900)
2724                                                        pts = 0;
2725                                                break;         
2726        case 4 :        if(fpts != pts )
2727                                                        pts = 0;
2728                                                break;
2729                                default :       free(buf); return -1; break;
2730                        }
2731                        if(pts != 0)
2732                        {       
2733                                pos = pos + left - tssize;
2734                                free(buf);
2735                                return pos;
2736                        }
2737                }
2738                packet = buf + left;
2739                left = left + tssize;
2740                                               
2741                pid = ((packet[1] << 8) | packet[2]) & 0x1FFF;
2742                pusi = !!(packet[1] & 0x40);
2743                //check for adaption field
2744                if(packet[3] & 0x20)
2745                {
2746                        if(type > 1)continue;
2747                        if(packet[4] >= 183) continue;
2748                        if(packet[4])
2749                        {
2750                                if(packet[5] & 0x10) //PCR present
2751                                {
2752                                        pts = ((unsigned long long)(packet[6] & 0xFF)) << 25;
2753                                        pts |= ((unsigned long long)(packet[7] & 0xFF)) << 17;
2754                                        pts |= ((unsigned long long)(packet[8] & 0xFE)) << 9;
2755                                        pts |= ((unsigned long long)(packet[9] & 0xFF)) << 1;
2756                                        pts |= ((unsigned long long)(packet[10] & 0x80)) >> 7;
2757                                        continue;
2758                                }
2759                        }
2760                        payload = packet + packet[4] + 4 + 1;
2761                } else
2762                        payload = packet + 4;
2763               
2764                if(type == 1) continue;
2765                if(!pusi) continue;
2766               
2767                if (payload[0] || payload[1] || (payload[2] != 1))
2768                        continue;
2769               
2770                        //stream use extension mechanism def in ISO 13818-1 Amendment 2
2771                if(payload[3] == 0xFD)
2772                {
2773                        if(payload[7] & 1) //PES extension flag
2774                        {
2775                                int offs = 0;
2776                                if(payload[7] & 0x80) offs += 5; //pts avail
2777                                if(payload[7] & 0x40) offs += 5; //dts avail
2778                                if(payload[7] & 0x20) offs += 6; //escr avail
2779                                if(payload[7] & 0x10) offs += 3; //es rate
2780                                if(payload[7] & 0x8) offs += 1; //dsm trickmode
2781                                if(payload[7] & 0x4) offs += 1; //additional copy info
2782                                if(payload[7] & 0x2) offs += 2; //crc
2783                                if(payload[8] < offs) continue;
2784
2785                                uint8_t pef = payload[9 + offs++]; //pes extension field
2786                                if(pef & 1) //pes extension flag 2
2787                                {
2788                                        if(pef & 0x80) offs += 16; //private data flag
2789                                        if(pef & 0x40) offs += 1; //pack header field flag
2790                                        if(pef & 0x20) offs += 2; //program packet sequence counter flag
2791                                        if(pef & 0x10) offs += 2; //P-STD buffer flag
2792                                        if(payload[8] < offs) continue;
2793
2794                                        uint8_t stream_id_extension_len = payload[9 + offs++] & 0x7F;
2795                                        if(stream_id_extension_len >= 1)
2796                                        {
2797                                                if(payload[8] < (offs + stream_id_extension_len)) continue;
2798                                                //stream_id_extension_bit (should not set)
2799                                                if(payload[9 + offs] & 0x80) continue;
2800                                                switch(payload[9 + offs])
2801                                                {
2802                                                        case 0x55 ... 0x5f: break; //VC-1
2803                                                        case 0x71: break; //AC3 / DTS
2804                                                        case 0x72: break; //DTS - HD
2805                                                        default:
2806                                                                printf("skip unknwn stream_id_extension %02x\n", payload[9 + offs]);
2807                                                                continue;
2808                                                }
2809                                        }
2810                                        else
2811                                                continue;
2812                                }
2813                                else
2814                                        continue;
2815                        }
2816                        else
2817                                continue;
2818                }
2819                //drop non-audio, non-video packets because other streams
2820                //can be non-compliant.
2821                //0xC0 = audio, 0xE0 = video
2822                else if(((payload[3] & 0xE0) != 0xC0) && ((payload[3] & 0xF0) != 0xE0))
2823                        continue;
2824
2825                if((payload[7] & 0x80) && ((payload[3] & 0xF0) != 0xE0) && (type == 0 || type == 2)) //PTS video
2826                {
2827                        pts = ((unsigned long long)(payload[9] & 0xE)) << 29;
2828                        pts |= ((unsigned long long)(payload[10] & 0xFF)) << 22;
2829                        pts |= ((unsigned long long)(payload[11] & 0xFE)) << 14;
2830                        pts |= ((unsigned long long)(payload[12] & 0xFF)) << 7;
2831                        pts |= ((unsigned long long)(payload[13] & 0xFE)) >> 1;
2832                        continue;
2833                }
2834                if((payload[7] & 0x80) && ((payload[3] & 0xE0) != 0xC0) && (type == 0 || type == 3)) //PTS audio
2835                {
2836                        pts = ((unsigned long long)(payload[9] & 0xE)) << 29;
2837                        pts |= ((unsigned long long)(payload[10] & 0xFF)) << 22;
2838                        pts |= ((unsigned long long)(payload[11] & 0xFE)) << 14;
2839                        pts |= ((unsigned long long)(payload[12] & 0xFF)) << 7;
2840                        pts |= ((unsigned long long)(payload[13] & 0xFE)) >> 1;
2841                        continue;
2842                }
2843        }
2844        free(buf);
2845        return recbsize * -1;
2846}
2847
2848#ifdef EPLAYER4
2849/* Extract some metadata from the streams and print it on the screen */
2850static void analyze_streams(CustomData *data)
2851{
2852        gint i;
2853        GstTagList *tags;
2854        gchar *str;
2855        guint rate;
2856
2857        /* Read some properties */
2858        g_object_get(pipeline, "n-video", &data->n_video, NULL);
2859        g_object_get(pipeline, "n-audio", &data->n_audio, NULL);
2860        g_object_get(pipeline, "n-text", &data->n_text, NULL);
2861
2862        g_print("%d video stream(s), %d audio stream(s), %d text stream(s)\n", data->n_video, data->n_audio, data->n_text);
2863
2864        g_print ("\n");
2865        for(i = 0; i < data->n_video; i++)
2866        {
2867                tags = NULL;
2868                /* Retrieve the stream's video tags */
2869                g_signal_emit_by_name(pipeline, "get-video-tags", i, &tags);
2870                if(tags)
2871                {
2872                        g_print("video stream %d:\n", i);
2873                        gst_tag_list_get_string(tags, GST_TAG_VIDEO_CODEC, &str);
2874                        g_print("  codec: %s\n", str ? str : "unknown");
2875                        g_free(str);
2876                        gst_tag_list_free(tags);
2877                }
2878        }
2879
2880        g_print("\n");
2881        for(i = 0; i < data->n_audio; i++)
2882        {
2883                tags = NULL;
2884                g_signal_emit_by_name(pipeline, "get-audio-tags", i, &tags);
2885                if(tags)
2886                {
2887                        /* Retrieve the stream's audio tags */
2888                        g_print("audio stream %d:\n", i);
2889                        if(gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str))
2890                        {
2891                                g_print("  codec: %s\n", str);
2892                                g_free(str);
2893                        }
2894                        if(gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str))
2895                        {
2896                                g_print("  language: %s\n", str);
2897                                g_free(str);
2898                        }
2899                        if(gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate))
2900                        {
2901                                g_print("  bitrate: %d\n", rate);
2902                        }
2903                        gst_tag_list_free(tags);
2904                }
2905        }
2906
2907        g_print("\n");
2908        for(i = 0; i < data->n_text; i++)
2909        {
2910                tags = NULL;
2911                /* Retrieve the stream's subtitle tags */
2912                g_print("subtitle stream %d:\n", i);
2913                g_signal_emit_by_name(pipeline, "get-text-tags", i, &tags);
2914                if(tags)
2915                {
2916                        if(gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str))
2917                        {
2918                                g_print("  language: %s\n", str);
2919                                g_free(str);
2920                        }
2921                        gst_tag_list_free(tags);
2922                }
2923                else
2924                {
2925                        g_print("  no tags found\n");
2926                }
2927        }
2928
2929        g_object_get(pipeline, "current-video", &data->current_video, NULL);
2930        g_object_get(pipeline, "current-audio", &data->current_audio, NULL);
2931        g_object_get(pipeline, "current-text", &data->current_text, NULL);
2932
2933        g_print("\n");
2934        g_print("Currently playing video stream %d, audio stream %d and subtitle stream %d\n", data->current_video, data->current_audio, data->current_text);
2935        g_print("Type any number and hit ENTER to select a different subtitle stream\n");
2936}
2937#endif
2938
2939#ifdef EPLAYER4
2940void playersend_ff_fr_event(gdouble rate) {
2941        gint64 position;
2942        GstFormat format = GST_FORMAT_TIME;
2943        GstEvent *seek_event;
2944   
2945        /* Obtain the current position, needed for the seek event */
2946#if GST_VERSION_MAJOR < 1
2947        if (!gst_element_query_position (pipeline, &format, &position)) {
2948#else
2949        if (!gst_element_query_position (pipeline, format, &position)) {
2950#endif
2951                g_printerr ("Unable to retrieve current position.\n");
2952                return;
2953        }
2954   
2955        /* Create the seek event */
2956        if (rate > 0)
2957        {       
2958                seek_event = gst_event_new_seek (rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_NONE, 0);
2959  }
2960        else
2961        {
2962                seek_event = gst_event_new_seek (rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, position);
2963        }
2964   
2965        if (video_sink == NULL) {
2966                /* If we have not done so, obtain the sink through which we will send the seek events */
2967                g_object_get (pipeline, "video-sink", &video_sink, NULL);
2968        }
2969   
2970        /* Send the event */
2971        gst_element_send_event (video_sink, seek_event);
2972   
2973        g_print ("Current rate: %g\n", rate);
2974}
2975#endif
2976
2977#endif
Note: See TracBrowser for help on using the repository browser.