source: titan/titan/player.h @ 41345

Last change on this file since 41345 was 41345, checked in by obi, 6 years ago

libeplayer3 / titan add internal subs support and srt listing

File size: 96.1 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
29#ifdef EXTEPLAYER3
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33#include <fcntl.h>
34#include <unistd.h>
35#include <sched.h>
36#include <signal.h>
37
38#include <sys/ioctl.h>
39#include <sys/prctl.h>
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <sys/time.h>
43#include <sys/resource.h>
44#include <sys/mman.h>
45
46#include "common.h"
47
48extern int ffmpeg_av_dict_set(const char *key, const char *value, int flags);
49extern void       aac_software_decoder_set(const int32_t val);
50extern void  aac_latm_software_decoder_set(const int32_t val);
51extern void       dts_software_decoder_set(const int32_t val);
52extern void       wma_software_decoder_set(const int32_t val);
53extern void       ac3_software_decoder_set(const int32_t val);
54extern void      eac3_software_decoder_set(const int32_t val);
55extern void       mp3_software_decoder_set(const int32_t val);
56extern void            rtmp_proto_impl_set(const int32_t val);
57extern void        flv2mpeg4_converter_set(const int32_t val);
58
59extern void pcm_resampling_set(int32_t val);
60extern void stereo_software_decoder_set(int32_t val);
61extern void insert_pcm_as_lpcm_set(int32_t val);
62extern void progressive_playback_set(int32_t val);
63
64static void SetBuffering()
65{
66    static char buff[2048];
67    memset( buff, '\0', sizeof(buff));
68    if( setvbuf(stderr, buff, _IOLBF, sizeof(buff)) )
69    {
70        printf("SetBuffering: failed to change the buffer of stderr\n");
71    }
72   
73    // make fgets not blocking
74    int flags = fcntl(stdin->_fileno, F_GETFL, 0);
75    fcntl(stdin->_fileno, F_SETFL, flags | O_NONBLOCK);
76}
77
78/*
79static void SetNice(int prio)
80{
81#if 0
82    setpriority(PRIO_PROCESS, 0, -8);
83   
84    int prio = sched_get_priority_max(SCHED_RR) / 2;
85    struct sched_param param = {
86        .sched_priority = prio
87    };
88    sched_setscheduler(0, SCHED_RR, &param);
89#else
90    int prevPrio = getpriority(PRIO_PROCESS, 0);
91    if (-1 == setpriority(PRIO_PROCESS, 0, prio))
92    {
93        printf("setpriority - failed\n");
94    }
95#endif
96}
97*/
98
99static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff)
100{
101    int commandRetVal = 0;
102   
103    if (NULL == ptrManager || NULL == argvBuff || 2 != strnlen(argvBuff, 2))
104    {
105        return -1;
106    }
107   
108    switch (argvBuff[1])
109    {
110        case 'l':
111        {
112            TrackDescription_t *TrackList = NULL;
113            ptrManager->Command(player, MANAGER_LIST, &TrackList);
114            if( NULL != TrackList)
115            {
116                int i = 0;
117                fprintf(stderr, "{\"%c_%c\": [", argvBuff[0], argvBuff[1]);
118                for (i = 0; TrackList[i].Id >= 0; ++i)
119                {
120                    if(0 < i)
121                    {
122                        fprintf(stderr, ", ");
123                    }
124                    fprintf(stderr, "{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", TrackList[i].Id , TrackList[i].Encoding, TrackList[i].Name);
125                    free(TrackList[i].Encoding);
126                    free(TrackList[i].Name);
127                }
128                fprintf(stderr, "]}\n");
129                free(TrackList);
130            }
131            else
132            {
133                // not tracks
134                fprintf(stderr, "{\"%c_%c\": []}\n", argvBuff[0], argvBuff[1]);
135            }
136            break;
137        }
138        case 'c':
139        {
140           
141            TrackDescription_t *track = NULL;
142            ptrManager->Command(player, MANAGER_GET_TRACK_DESC, &track);
143            if (NULL != track)
144            {
145                if ('a' == argvBuff[0] || 's' == argvBuff[0])
146                {
147                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], track->Id , track->Encoding, track->Name);
148                }
149                else // video
150                {
151                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \
152                    argvBuff[0], argvBuff[1], track->Id , track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den);
153                }
154                free(track->Encoding);
155                free(track->Name);
156                free(track);
157            }
158            else
159            {
160                // no tracks
161                if ('a' == argvBuff[0] || 's' == argvBuff[0])
162                {
163                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], -1, "", "");
164                }
165                else // video
166                {
167                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d}}\n", argvBuff[0], argvBuff[1], -1, "", "", -1, -1, 0, -1);
168                }
169            }
170            break;
171        }
172        default:
173        {
174            /* switch command available only for audio and subtitle tracks */
175            if ('a' == argvBuff[0] || 's' == argvBuff[0])
176            {
177                int ok = 0;
178                int id = -1;
179                if ('i' == argvBuff[1])
180                {
181                    int idx = -1;
182                    ok = sscanf(argvBuff+2, "%d", &idx);
183                    if (idx >= 0)
184                    {
185                        TrackDescription_t *TrackList = NULL;
186                        ptrManager->Command(player, MANAGER_LIST, &TrackList);
187                        if( NULL != TrackList)
188                        {
189                            int i = 0;
190                            for (i = 0; TrackList[i].Id >= 0; ++i)
191                            {
192                                if (idx == i)
193                                {
194                                    id = TrackList[i].Id;
195                                }
196                                free(TrackList[i].Encoding);
197                                free(TrackList[i].Name);
198                            }
199                            free(TrackList);
200                        }
201                    }
202                    else
203                    {
204                        id = idx;
205                    }
206                }
207                else
208                {
209                    ok = sscanf(argvBuff+1, "%d", &id);
210                }
211               
212                if(id >= 0 || (1 == ok && id == -1))
213                {
214                    commandRetVal = player->playback->Command(player, playbackSwitchCmd, (void*)&id);
215                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"sts\":%d}}\n", argvBuff[0], 's', id, commandRetVal);
216                }
217            }
218            break;
219        }
220    }
221   
222    return commandRetVal;
223}
224
225static void UpdateVideoTrack()
226{
227    HandleTracks(player->manager->video, (PlaybackCmd_t)-1, "vc");
228}
229#endif
230#endif
231
232#ifdef EPLAYER4
233//#define GST_VERSION_MAJOR (0)
234GstElement *pipeline = NULL;
235gint m_framerate;
236unsigned long long m_gst_startpts = 0;
237CustomData data;
238GstElement *video_sink = NULL;
239struct stimerthread* subtitlethread = NULL;
240uint32_t buf_pos_ms = 0;
241uint32_t duration_ms = 0;
242int subtitleflag = 0;
243char *subtext = NULL;
244#else
245struct stimerthread* subtitlethread = NULL;
246uint32_t buf_pos_ms = 0;
247uint32_t duration_ms = 0;
248int subtitleflag = 0;
249char *subtext = NULL;
250#endif
251
252//titan player
253
254//flag 0: from play
255//flag 1: from timeshift
256//flag 2: from playrcjumpr
257int playerstartts(char* file, int flag)
258{
259        int fd = -1, ret = 0, tssize = 188;
260        int16_t pmtpid = 0;
261        int serviceid = 0;
262        int supermagic = -1;
263        int lastpos = 0;
264        struct channel* chnode = NULL;
265        struct service* snode = NULL;
266        struct dvbdev* fenode = NULL;
267        struct dvbdev* dvrnode = NULL;
268        status.prefillbuffer = 0;
269#ifdef EPLAYER4
270        status.bufferpercent = 0;
271#endif
272        //supermagic = getsupermagic(file);
273
274        if(supermagic == NFS_SUPER_MAGIC || supermagic == SMB_SUPER_MAGIC)
275        {
276                debug(150, "use O_DIRECT to open file %s", file);
277                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK | O_DIRECT);
278        }
279        else
280                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK);
281
282        if(fd < 0)
283        {
284                perr("open player file");
285                return 1;
286        }
287
288        fenode = fegetdummy();
289        dvrnode = dvropen(fenode);
290        if(dvrnode == NULL)
291        {
292                err("find dvr dev");
293                close(fd);
294                return 1;
295        }
296
297        if(flag == 0 || flag == 2)
298        {
299                //TODO: funktion to get tssize from file content
300                if(cmpfilenameext(file, ".mts") == 0) tssize = 192;
301                if(cmpfilenameext(file, ".m2ts") == 0) tssize = 192;
302               
303                ret = dvbfindpmtpid(fd, &pmtpid, &serviceid, tssize);
304                if(ret == 1)
305                {
306                        err("find sid/pmt pid");
307                        close(fd);
308                        dvrclose(dvrnode, -1);
309                        return 1;
310                }
311               
312                lastpos = 0;
313                if(flag == 0 && getconfigint("showlastpos", NULL) == 1)
314                {
315                        char* fileseek = changefilenameext(file, ".se");
316                        FILE* fbseek = fopen(fileseek, "r");
317                        if(fbseek != NULL)
318                        {
319                                ret = textbox(_("Message"), _("Start at last position ?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 1000, 200, 10, 0);
320                                if(ret == 0 || ret == 1)
321                                {
322                                        char* skip1 = calloc(1, 20);
323                                        if(skip1 != NULL)
324                                        {
325                                                fscanf(fbseek, "%s", skip1);
326                                                off64_t seekpos = atoll(skip1);
327                                                seekpos = seekpos - (seekpos % tssize);
328                                                lseek64(fd, atoll(skip1), SEEK_SET);
329                                                lastpos = 1;
330                                        }
331                                        free(skip1); skip1 = NULL;
332                                }
333                                fclose(fbseek);
334                        }
335                        free(fileseek); fileseek = NULL;
336                }       
337               
338                status.autoseek = 0;
339               
340                if(flag == 0)
341                {
342                        delmarkernode(-1);
343                        char* filemarker = changefilenameext(file, ".ma");
344                        getmarker(filemarker);
345                        free(filemarker); filemarker=NULL;
346                }
347               
348                if(status.playmarker != NULL)
349                {
350                        char* testfile = changefilenameext(file, ".as");
351                        FILE* testseek = fopen(testfile, "r");
352                        if(testseek != NULL)
353                        {
354                                if(lastpos == 0)
355                                        lseek64(fd, status.playmarker->pos, SEEK_SET);
356                                status.autoseek = 2;
357                                addtimer(&markerautoseek_thread, START, 10000, 1, NULL, NULL, NULL);
358                                fclose(testseek);
359                        }
360                        free(testfile); testfile = NULL;
361                }
362                               
363                delchannel(serviceid, 0, 1);
364                chnode = createchannel("player", 0, 0, serviceid, 99, 0, -1, -1, -1, -1, 0, -1);
365                if(chnode != NULL) chnode->pmtpid = pmtpid;
366        }
367        else
368                chnode = status.aktservice->channel;
369
370        if(chnode == NULL)
371        {
372                err("create channel");
373                close(fd);
374                dvrclose(dvrnode, -1);
375                return 1;
376        }
377
378        if(flag == 1)
379        {
380                ret = servicestart(chnode, NULL, NULL, 2);
381                if(ret != 0)
382                {
383                        err("start play");
384                        close(fd);
385                        dvrclose(dvrnode, -1);
386                        return 1;
387                }
388               
389                //on permanent timeshift seek to end, and a little back (eof problem)
390                if(status.timeshifttype == 1)
391                {
392                        if(status.timeshiftpos > 0)
393                                lseek64(fd, status.timeshiftpos, SEEK_SET);
394                        else
395                        {
396                                unsigned long long pos = lseek64(fd, 0, SEEK_END);
397                                pos -= 10000000;
398                                pos = pos - (pos & tssize);
399                                lseek64(fd, -pos, SEEK_END);
400                        }
401                }
402        }
403
404        ret = recordstartreal(NULL, fd, dvrnode->fd, RECPLAY, 0, NULL, tssize);
405        if(ret != 0)
406        {
407                err("start play thread");
408                close(fd);
409                dvrclose(dvrnode, -1);
410                return 1;
411        }
412
413        snode = getservice(RECORDPLAY, 0);
414        if(snode != NULL)
415        {
416                int dupfd = -1;
417                snode->recname = ostrcat(file, NULL, 0, 0);
418
419                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
420                if(dupfd > -1)
421                        gettsinfo(dupfd, &snode->lenpts, &snode->startpts, &snode->endpts, &snode->bitrate, snode->tssize);
422
423                if(flag == 1)
424                {
425                        snode->lenpts = 0;
426                        snode->endpts = 0;
427                }
428                else
429                {
430                        if(getservicebyrecname(file, 1, 0) != NULL) //playfile is recording, so len can change
431                        {
432                                snode->lenpts = 0;
433                                snode->endpts = 0;
434                        }
435                        else if(dupfd > -1)
436                                snode->endoffile = lseek64(dupfd , 0, SEEK_END);
437                }
438                close(dupfd);
439        }
440
441        if(flag == 0 || flag == 2)
442        {
443                ret = servicestart(chnode, NULL, NULL, 1);
444                if(ret != 0)
445                {
446                        err("start play");
447                        if(snode != NULL) snode->recendtime = 1;
448                        close(fd);
449                        dvrclose(dvrnode, -1);
450                        return 1;
451                }
452                //status.playercan = 0x7EFF;
453                status.playercan = 0xFFFF;     
454        }
455
456        return 0;
457}
458
459//flag 0: from play
460//flag 1: from timeshift
461//flag 2: from playrcjumpr/playerafterendts
462//flag1 0: stop from rcstop
463//flag1 1: stop from servicestop
464void playerstopts(int flag, int flag1)
465{
466        int ret = 0;
467        struct service* snode = NULL;
468        struct channel* node = NULL;
469
470        snode = getservice(RECORDPLAY, flag1);
471
472        if(snode != NULL && snode->recsrcfd >= 0 && flag == 0 && flag1 == 0)
473        {
474                char* fileseek = changefilenameext(snode->recname, ".se");
475                FILE* fbseek = fopen(fileseek, "w");
476                if(fbseek != NULL)
477                {
478                        off64_t pos = getcurrentpos(snode);
479                        if(pos <= 0)
480                                pos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
481                        fprintf(fbseek,"%lld", pos);
482                        fclose(fbseek);
483                }
484                free(fileseek); fileseek=NULL;
485                char* filemarker = changefilenameext(snode->recname, ".ma");
486                ret = putmarker(filemarker);
487                free(filemarker); filemarker=NULL;
488                delmarkernode(-1);
489        }
490       
491        if(snode != NULL) snode->recendtime = 1;
492       
493        if(flag == 0 || flag == 2)
494        {
495                playerslowts(0);
496                playerffts(0);
497
498                ret = servicestop(status.aktservice, 1, 1);
499                if(ret == 1)
500                {
501                        debug(150, "can't stop ts playback service");   
502                }
503                else
504                        status.aktservice->channel = NULL;
505
506                               
507                node = gettmpchannel();
508                if(node != NULL && ostrcmp(node->name, "player") == 0)
509                        delchannel(node->serviceid, node->transponderid, 1);
510        }
511}
512
513void playerresetts()
514{
515#ifdef DREAMBOX
516        videofreeze(status.aktservice->videodev);
517        dmxstart(status.aktservice->dmxaudiodev);
518        audioplay(status.aktservice->audiodev);
519        audiopause(status.aktservice->audiodev);
520#else
521        audiostop(status.aktservice->audiodev);
522        videostop(status.aktservice->videodev, 0);
523#endif
524
525#ifdef MIPSEL
526        videoclearbuffer(status.aktservice->videodev);
527        audioclearbuffer(status.aktservice->audiodev);
528#endif
529
530#ifdef DREAMBOX
531        videoslowmotion(status.aktservice->videodev, 0);
532        videofastforward(status.aktservice->videodev, 0);
533        videocontinue(status.aktservice->videodev);
534        audiocontinue(status.aktservice->audiodev);
535#else
536        videoplay(status.aktservice->videodev);
537        audioplay(status.aktservice->audiodev);
538#endif
539}
540
541void playercontinuets()
542{
543        videocontinue(status.aktservice->videodev);
544#ifdef MIPSEL
545        audiocontinue(status.aktservice->audiodev);
546#else
547        audioplay(status.aktservice->audiodev);
548#endif
549}
550
551void playerpausets()
552{
553        videofreeze(status.aktservice->videodev);
554        audiopause(status.aktservice->audiodev);
555}
556
557//flag 0: with lock
558//flag 1: without lock
559int playerseekts(struct service* servicenode, int sekunden, int flag)
560{
561        off64_t offset = 0;
562        off64_t endoffile = 0;
563        off64_t currentpos = 0;
564        //off64_t fdptspos = 0;
565        //int ret = 0;
566        unsigned long long lenpts = 0;
567        unsigned long long startpts = 0;
568        unsigned long long endpts = 0;
569        unsigned long long bitrate = 0;
570        //unsigned long long aktpts = 0;
571        //unsigned long long fdpts = 0;
572        //int aktsekunden = 0;
573        int sekundenoff = 0;
574       
575        if(servicenode == NULL) return 1;
576
577        if(servicenode->recsrcfd < 0)
578        {
579                err("source fd not ok");
580                return 1;
581        }
582       
583        if(flag == 0) m_lock(&status.tsseekmutex, 15);
584
585/*
586        ret = videogetpts(status.aktservice->videodev, &aktpts);
587        if(ret == 0)
588        {
589                aktsekunden = aktpts / 90000;
590        }
591        else
592                aktsekunden = 0;
593        ret = getpts(servicenode->recsrcfd, 0, 0, 256 * 1024, &fdpts, &fdptspos, -1, servicenode->tssize);
594        if(ret == 0 && aktsekunden != 0)
595        {
596                sekundenoff = fdpts / 90000 - aktsekunden ;
597                //currentpos = lseek64(servicenode->recsrcfd, fdptspos, SEEK_SET);
598        }
599        else
600                sekundenoff = 0;
601*/
602       
603        currentpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);
604
605        lenpts = servicenode->lenpts;
606        startpts = servicenode->startpts;
607        endpts = servicenode->endpts;
608        bitrate = servicenode->bitrate;
609        if(gettsinfo(servicenode->recsrcfd, &lenpts, &startpts, &endpts, &bitrate, servicenode->tssize) != 0)
610        {
611                err("can't read ts info");
612                lseek64(servicenode->recsrcfd, currentpos, SEEK_SET);
613                if(flag == 0) m_unlock(&status.tsseekmutex, 15);
614                return 1;
615        }
616        if(servicenode->endoffile > 0)
617                endoffile = servicenode->endoffile - (servicenode->tssize * 2);
618        else
619                endoffile = lseek64(servicenode->recsrcfd , -servicenode->tssize * 2, SEEK_END);
620
621/*
622        ret = videoclearbuffer(status.aktservice->videodev);
623        ret = audioclearbuffer(status.aktservice->audiodev);
624        ret = videodiscontinuityskip(status.aktservice->videodev, 0);
625*/
626
627        if(sekunden >= 0)
628        {
629                if(sekundenoff != 0)
630                        offset = (bitrate / 8) * (sekunden - sekundenoff);
631                else
632                        offset = (bitrate / 8) * sekunden - 5000000;
633                offset = offset - (offset % servicenode->tssize);
634                if(currentpos + offset > endoffile)
635                {
636                        offset = endoffile - currentpos;
637                        offset = offset - (offset % servicenode->tssize);
638                }
639        }
640        else
641        {
642                sekunden = sekunden * -1;
643                if(sekundenoff != 0)
644                        offset = (bitrate / 8) * (sekunden + sekundenoff);
645                else
646                        offset = (bitrate / 8) * sekunden;
647                if(offset > 0) offset += 5000000;
648                offset = offset - (offset % servicenode->tssize);
649                if(currentpos - offset < 0)
650                        offset = currentpos;
651                offset = offset * -1;
652        }
653        offset += currentpos;
654        currentpos = lseek64(servicenode->recsrcfd, offset, SEEK_SET);
655
656        playerresetts();
657
658        if(flag == 0) m_unlock(&status.tsseekmutex, 15);
659        return 0;
660}
661
662void playerffts(int speed)
663{
664#ifdef MIPSEL
665        audiostop(status.aktservice->audiodev);
666
667#ifdef DREAMBOX
668        dmxstop(status.aktservice->dmxaudiodev);
669#endif
670
671        videoslowmotion(status.aktservice->videodev, 0);
672        videofastforward(status.aktservice->videodev, speed);
673        videocontinue(status.aktservice->videodev);
674#else   
675        videofastforward(status.aktservice->videodev, speed);
676#endif
677}
678
679void playerslowts(int speed)
680{
681#ifdef MIPSEL
682        audiostop(status.aktservice->audiodev);
683       
684#ifdef DREAMBOX
685        dmxstop(status.aktservice->dmxaudiodev);
686#endif 
687
688        videoslowmotion(status.aktservice->videodev, speed);
689        videofastforward(status.aktservice->videodev, 0);
690        videocontinue(status.aktservice->videodev);
691#else           
692        videoslowmotion(status.aktservice->videodev, speed);
693#endif
694}
695
696//flag = 0 --> recordplay
697//flag = 1 --> timeshift
698void playerfrts(int speed, int flag)
699{
700        if(flag == 1)
701                videocontinue(status.aktservice->videodev);
702        if(speed == -2)
703        {
704                videoclearbuffer(status.aktservice->videodev);
705                audioclearbuffer(status.aktservice->audiodev);
706        }
707        speed *= -1;
708#ifdef MIPSEL
709        audiostop(status.aktservice->audiodev);
710#ifdef DREAMBOX
711        dmxstop(status.aktservice->dmxaudiodev);
712#endif
713        videoslowmotion(status.aktservice->videodev, 0);
714        videofastforward(status.aktservice->videodev, speed);
715        videocontinue(status.aktservice->videodev);
716#else   
717        videofastforward(status.aktservice->videodev, speed);
718#endif
719}
720       
721
722//flag = 0 --> play ts
723//flag = 1 --> timeshift
724//flag = 2 --> timeshift, not in play mode (only recording)
725int playergetinfots(unsigned long long* lenpts, unsigned long long* startpts, unsigned long long* endpts, unsigned long long* aktpts, unsigned long long* bitrate, int flag)
726{
727        int ret = 0, dupfd = -1;
728        double ratio = 0;
729        struct service* snode = NULL;
730        unsigned long long lenpts1 = 0;
731        unsigned long long startpts1 = 0;
732        unsigned long long endpts1 = 0;
733        unsigned long long bitrate1 = 0;
734        unsigned long long endoffile1 = 0;
735        unsigned long long aktpos = 0;
736       
737        if(flag == 2)
738                snode = getservice(RECORDTIMESHIFT, 0);
739        else
740                snode = getservice(RECORDPLAY, 0);
741               
742        if(snode == NULL) return 1;
743
744        if(snode->lenpts > 0 && snode->startpts > 0 && snode->endpts > 0 && snode->bitrate > 0 && snode->endoffile > 0)
745        {
746                if(lenpts != NULL) *lenpts = snode->lenpts;
747                if(startpts != NULL) *startpts = snode->startpts;
748                if(endpts != NULL) *endpts = snode->endpts;
749                if(bitrate != NULL) *bitrate = snode->bitrate;
750
751                //ret = videogetpts(status.aktservice->videodev, aktpts);
752                if(aktpts != NULL)
753                {
754                        m_lock(&status.tsseekmutex, 15);
755                        if(flag == 2)
756                                aktpos = lseek64(snode->recdstfd , 0, SEEK_CUR);
757                        else
758                                aktpos = lseek64(snode->recsrcfd , 0, SEEK_CUR);
759                        m_unlock(&status.tsseekmutex, 15);
760
761                        ratio = (double)snode->endoffile / (double)(snode->endpts - snode->startpts);
762                        if(ratio == 0) ratio = 1;
763                        *aktpts = ((double)aktpos / ratio);
764                        *aktpts += snode->startpts;
765                }
766
767                return ret;
768        }
769       
770        dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
771        if(dupfd < 0)
772        {
773                err("copy source fd not ok");
774                return 1;
775        }
776
777        lenpts1 = snode->lenpts;
778        startpts1 = snode->startpts;
779        endpts1 = snode->endpts;
780        bitrate1 = snode->bitrate;
781        if(gettsinfo(dupfd, &lenpts1, &startpts1, &endpts1, &bitrate1, snode->tssize) != 0)
782        {
783                err("can't read ts info");
784                return 1;
785        }
786
787        if(lenpts != NULL) *lenpts = lenpts1;
788        if(startpts != NULL) *startpts = startpts1;
789        if(endpts != NULL) *endpts = endpts1;
790        if(bitrate != NULL) *bitrate = bitrate1;
791
792        //ret = videogetpts(status.aktservice->videodev, aktpts);
793        if(aktpts != NULL)
794        {
795                m_lock(&status.tsseekmutex, 15);
796                if(flag == 2)
797                        aktpos = lseek64(snode->recdstfd, 0, SEEK_CUR);
798                else
799                        aktpos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
800                m_unlock(&status.tsseekmutex, 15);
801
802                if(snode->endoffile <= 0)
803                        endoffile1 = lseek64(dupfd, 0, SEEK_END);
804                else
805                        endoffile1 = snode->endoffile;
806
807                if(endpts1 == 0)
808                        ratio = 1;
809                else
810                        ratio = (double)endoffile1 / (double)(endpts1 - startpts1);
811
812                if(ratio == 0) ratio = 1;
813                *aktpts = ((double)aktpos / ratio);
814                *aktpts += startpts1;
815        }
816
817        close(dupfd);
818        return ret;
819}
820
821void playerchangeaudiotrackts()
822{
823        screenaudiotrack();
824}
825
826void playerchangesubtitletrackts()
827{
828        screensubtitle();
829}
830
831int playerisplayingts()
832{
833        struct service* snode = getservice(RECORDPLAY, 0);
834
835        if(snode == NULL)
836                return 0;
837        return 1;
838}
839
840void playerafterendts()
841{
842        playerstopts(2, 0);
843}
844
845#ifdef EPLAYER4
846void playersubtitleclean(char* data, int len)
847{
848        char* zeichen = NULL;
849        int found = 1;
850       
851        while(found == 1)
852        {
853                found = 0;
854                zeichen = NULL;
855                zeichen = strstr(data, "&apos;");
856                if(zeichen != NULL)
857                {
858                        zeichen[0] = '\'';
859                        memcpy(zeichen+1, zeichen+6, len - (zeichen - data + 1));
860                        found = 1;
861                }
862                zeichen = NULL;
863                zeichen = strstr(data, "&amp;");
864                if(zeichen != NULL)
865                {
866                        zeichen[0] = '&';
867                        memcpy(zeichen+1, zeichen+5, len - (zeichen - data + 1));
868                        found = 1;
869                }
870                zeichen = NULL;
871                zeichen = strstr(data, "&quot;");
872                if(zeichen != NULL)
873                {
874                        zeichen[0] = '"';
875                        memcpy(zeichen+1, zeichen+6, len - (zeichen - data + 1));
876                        found = 1;
877                }
878                zeichen = NULL;
879                zeichen = strstr(data, "&lt;");
880                if(zeichen != NULL)
881                {
882                        zeichen[0] = '<';
883                        memcpy(zeichen+1, zeichen+4, len - (zeichen - data + 1));
884                        found = 1;
885                }
886                zeichen = NULL;
887                zeichen = strstr(data, "&gt;");
888                if(zeichen != NULL)
889                {
890                        zeichen[0] = '<';
891                        memcpy(zeichen+1, zeichen+4, len - (zeichen - data + 1));
892                        found = 1;
893                }
894                //workaround da keine Aufbereitung
895                zeichen = NULL;
896                zeichen = strstr(data, "<i>");
897                if(zeichen != NULL)
898                {
899                        memcpy(zeichen, zeichen+3, len - (zeichen - data + 1));
900                        found = 1;
901                }
902                zeichen = NULL;
903                zeichen = strstr(data, "</i>");
904                if(zeichen != NULL)
905                {
906                        memcpy(zeichen, zeichen+4, len - (zeichen - data + 1));
907                        found = 1;
908                }
909        }
910}
911#endif
912
913#ifdef EPLAYER4
914void playersubtitle_thread()
915{
916        struct skin* framebuffer = getscreen("framebuffer");
917        struct skin* subtitle = getscreen("gstsubtitle");
918        char* bg = NULL;
919        int count = 0;
920       
921        subtitle->bgcol = -1;
922       
923        setnodeattr(subtitle, framebuffer, 0);
924        bg = savescreen(subtitle);
925       
926        while(subtitlethread->aktion != STOP)
927        {
928                if(duration_ms != 0)
929                {
930                        count = 0;
931                        changetext(subtitle, subtext);
932                        count = duration_ms / 100;
933                        drawscreen(subtitle, 0, 0);
934                        while(count > 0 && subtitlethread->aktion != STOP)
935                        {
936                                usleep(100000);
937                                count = count - 1;
938                        }
939                        changetext(subtitle, " ");
940                        drawscreen(subtitle, 0, 0);
941                        duration_ms = 0;
942                }
943                else
944                        usleep(100000);
945        }
946        free(subtext); subtext = NULL;
947        restorescreen(bg, subtitle);
948        blitfb(0);
949        subtitlethread = NULL;
950}
951#else
952void playersubtitle_thread()
953{
954        struct skin* framebuffer = getscreen("framebuffer");
955        struct skin* subtitle = getscreen("gstsubtitle");
956        char* bg = NULL;
957        int count = 0;
958       
959        subtitle->bgcol = -1;
960       
961        setnodeattr(subtitle, framebuffer, 0);
962        bg = savescreen(subtitle);
963       
964        while(subtitlethread->aktion != STOP)
965        {
966                if(duration_ms != 0)
967                {
968                        count = 0;
969                        changetext(subtitle, subtext);
970                        count = duration_ms / 100;
971                        drawscreen(subtitle, 0, 0);
972                        while(count > 0 && subtitlethread->aktion != STOP)
973                        {
974                                usleep(100000);
975                                count = count - 1;
976                        }
977                        changetext(subtitle, " ");
978                        drawscreen(subtitle, 0, 0);
979                        duration_ms = 0;
980                }
981                else
982                        usleep(100000);
983        }
984        free(subtext); subtext = NULL;
985        restorescreen(bg, subtitle);
986        blitfb(0);
987        subtitlethread = NULL;
988}
989#endif
990
991#ifdef EPLAYER4
992void playersubtitleAvail(GstElement *subsink, GstBuffer *buffer, gpointer user_data)
993{
994        //printf("++++++ subtitelflag: %i\n", subtitleflag);
995        if(subtitleflag == 0 || subtitleflag == 2) return;
996
997#if GST_VERSION_MAJOR < 1
998        gint64 buf_pos = GST_BUFFER_TIMESTAMP(buffer);
999        gint64 duration_ns = GST_BUFFER_DURATION(buffer);
1000#endif 
1001        time_t running_pts = 0;
1002        gint64 pos = 0;
1003        int32_t decoder_ms;
1004        GstFormat fmt = GST_FORMAT_TIME;
1005       
1006#if GST_VERSION_MAJOR < 1
1007        if (!gst_element_query_position(pipeline, &fmt, &pos))
1008#else
1009        if (!gst_element_query_position(pipeline, fmt, &pos))
1010#endif
1011        {
1012                err("gst_element_query_position failed");
1013                return;
1014        }
1015        running_pts = pos / 11111LL;
1016        decoder_ms = running_pts / 90;
1017               
1018        if(subtitlethread == NULL)
1019                subtitlethread = addtimer(&playersubtitle_thread, START, 10000, 1, NULL, NULL, NULL);
1020       
1021#if GST_VERSION_MAJOR < 1
1022        size_t len = GST_BUFFER_SIZE(buffer);
1023#else
1024//      size_t len = gst_buffer_get_size(buffer);
1025        GstMapInfo map;
1026        if(!gst_buffer_map(buffer, &map, GST_MAP_READ))
1027        {
1028                printf("eServiceMP3::pullSubtitle gst_buffer_map failed\n");
1029                return;
1030        }
1031        gint64 buf_pos = GST_BUFFER_PTS(buffer);
1032        size_t len = map.size;
1033#if GST_VERSION_MAJOR < 1
1034        printf("gst_buffer_get_size %zu map.size %zu\n", gst_buffer_get_size(buffer), len);
1035#endif
1036        gint64 duration_ns = GST_BUFFER_DURATION(buffer);
1037#endif
1038                       
1039        //printf("BUFFER_TIMESTAMP: %lld - BUFFER_DURATION: %lld in ns\n", buf_pos, duration_ns);
1040        //printf("BUFFER_SIZE: %d\n", len);
1041        //printf("BUFFER_DATA: %s\n", GST_BUFFER_DATA(buffer));
1042       
1043        while(duration_ms != 0 && subtitlethread != NULL)
1044        {
1045                usleep(100000);
1046        }
1047        if(subtext != NULL)
1048                free(subtext);
1049        subtext = malloc(len+10);
1050        if(subtext == NULL)
1051        {
1052                err("no mem");
1053                return;
1054        }
1055#if GST_VERSION_MAJOR > 1
1056        guint8 *data;
1057//      gsize size;
1058        GstMapInfo map;
1059        gst_buffer_map(buffer, &map, GST_MAP_READ);
1060        data = map.data;
1061        sprintf(subtext, "%s", data);
1062//      sprintf(subtext, "%s", GST_BUFFER_DATA(buffer));
1063#endif
1064        playersubtitleclean(subtext, len+10);
1065       
1066        double convert_fps = 1.0;
1067        buf_pos_ms  = (buf_pos / 1000000ULL) * convert_fps;
1068        duration_ms = duration_ns / 1000000ULL;
1069
1070        //printf("++++++ buff_pos  : %u\n", buf_pos_ms);
1071        //printf("++++++ decoder_ms: %i\n", decoder_ms);
1072}
1073#endif
1074
1075#ifdef EPLAYER4
1076// set http extra-header and user-agent
1077void playbinNotifySource(GObject *object, GParamSpec *unused, char* file)
1078{
1079        printf("[player.h] playbinNotifySource: %s\n", file);
1080        GstElement *source = NULL;
1081        g_object_get(object, "source", &source, NULL);
1082        if (source)
1083        {
1084                if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "cookiejar-file-name") != 0)
1085                {
1086                        printf("[player.h] set cookiejar-file-name: /mnt/network/cookies\n");
1087                        g_object_set(G_OBJECT(source), "cookiejar-file-name", "/mnt/network/cookies", NULL);
1088                }
1089
1090                if(ostrstr(file, "|") != NULL)
1091                {
1092                        if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "extra-headers") != 0)
1093                        {
1094        #if GST_VERSION_MAJOR < 1
1095                                GstStructure *extras = gst_structure_empty_new("extras");
1096        #else
1097                                GstStructure *extras = gst_structure_new_empty("extras");
1098        #endif
1099                                char* tmpstr1 = NULL, *tmpstr2 = NULL, *tmpstr3 = NULL, *tmpstr4 = NULL;
1100                                tmpstr1 = ostrcat(file, NULL, 0, 0);
1101                                int count1 = 0, i = 0;
1102                                struct splitstr* ret1 = NULL;
1103                                ret1 = strsplit(tmpstr1, "|", &count1);
1104       
1105                                for(i = 0; i < count1; i++)
1106                                {
1107                                        if(i == 0)
1108                                        {
1109                                                printf("[player.h] playbinNotifySource: skip url string: %s\n", ret1[i].part);
1110                                                continue;
1111                                        }
1112                                        tmpstr2 = ostrcat(ret1[i].part, NULL, 0, 0);
1113       
1114                                        int count2 = 0, i2 = 0;
1115                                        struct splitstr* ret2 = NULL;
1116                                        ret2 = strsplit(tmpstr2, "&", &count2);
1117
1118                                        if(ret2 != NULL)
1119                                        {
1120                                                for(i2 = 0; i2 < count2; i2++)
1121                                                {
1122                                                        int count3 = 0, i3 = 0;
1123                                                        struct splitstr* ret3 = NULL;
1124                                                        tmpstr3 = ostrcat(ret2[i2].part, NULL, 0, 0);
1125                                                        ret3 = strsplit(tmpstr3, "=", &count3);
1126                                       
1127                                                        if(ret3 != NULL)
1128                                                        {
1129                                                                int max = count3 - 1;
1130                                                                for(i3 = 0; i3 < max; i3++)
1131                                                                {
1132                                                                        if(ostrstr(ret3[i3].part, "User-Agent") != NULL)
1133                                                                        {
1134                        //                                                      printf("[player.h] skip set user-agent: %s\n", ret2[1].part);
1135                                                                                printf("[player.h] set user-agent: %s\n", ret3[i3 + 1].part);
1136                                                                                g_object_set(G_OBJECT(source), "user-agent", ret3[i3 + 1].part, NULL);
1137                                                                        }
1138                                                                        else
1139                                                                        {
1140                                                                                if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "extra-headers") != 0)
1141                                                                                {                                       
1142                                                                                        GValue header;
1143                                                                                        // eDebug("setting extra-header '%s:%s'", name.c_str(), value.c_str());
1144                                                                                        printf("[player.h] set extra-header %s: %s\n", ret3[i3].part, ret3[i3 + 1].part);
1145                                                                                       
1146                                                                                        tmpstr4 = ostrcat(ret3[i3 + 1].part, NULL, 0, 0);
1147                                                                                        htmldecode(tmpstr4, tmpstr4);
1148                                                                                        printf("[player.h] set extra-header decode %s: %s\n", ret3[i3].part, tmpstr4);
1149                       
1150                                                                                        memset(&header, 0, sizeof(GValue));
1151                                                                                        g_value_init(&header, G_TYPE_STRING);
1152                                                                                        //value
1153                                                                                        g_value_set_string(&header, tmpstr4);
1154                                                                                        //name
1155                                                                                        gst_structure_set_value(extras, ret3[i3].part, &header);
1156                                                                                        free(tmpstr4), tmpstr4 = NULL;
1157                                                                                }
1158                                                                        }
1159                                                                }
1160                                                        }
1161                                                        free(ret3), ret3 = NULL;
1162                                                        free(tmpstr3), tmpstr3 = NULL;
1163                                                }
1164                                        }
1165                                        free(ret2), ret2 = NULL;
1166                                        free(tmpstr2), tmpstr2 = NULL;
1167                                }
1168
1169                                free(ret1), ret1 = NULL;
1170                                free(tmpstr1), tmpstr1 = NULL;
1171
1172                                if (gst_structure_n_fields(extras) > 0)
1173                                {
1174                                        g_object_set(G_OBJECT(source), "extra-headers", extras, NULL);
1175                                }
1176                                gst_structure_free(extras);
1177                        }
1178                }
1179
1180                if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "ssl-strict") != 0)
1181                {
1182                        printf("[player.h] set ssl-strict\n");
1183                        g_object_set(G_OBJECT(source), "ssl-strict", FALSE, NULL);
1184                }
1185        }
1186        gst_object_unref(source);
1187}
1188#endif
1189
1190//extern player
1191int playerstart(char* file)
1192{
1193        char * tmpfile = NULL;
1194        status.prefillbuffer = 0;
1195#ifdef EPLAYER4
1196        status.prefillbuffercount = 0;
1197        status.bufferpercent = 0;
1198#endif 
1199        if(file != NULL)
1200        {
1201#ifdef EPLAYER3
1202                //use eplayer
1203
1204                if(player != NULL)
1205                {
1206                        debug(150, "eplayer allready running");
1207                        playerstop();
1208                }
1209
1210                player = calloc(1, sizeof(Context_t));
1211
1212                if(player == NULL)
1213                {
1214                        err("no mem");
1215                        return 1;
1216                }
1217
1218                if(ostrstr(file, "://") == NULL)
1219                        tmpfile = ostrcat("file://", file, 0, 0);
1220                else
1221                        tmpfile = ostrcat(file, NULL, 0, 0);
1222
1223                if(tmpfile == NULL)
1224                {
1225                        err("no mem");
1226                        free(player); player = NULL;
1227                        return 1;
1228                }
1229// move to mc
1230//              set_player_sound(0);
1231
1232                if(ostrstr(tmpfile, "file://") == NULL)
1233                        status.playercan = 0x4650;
1234                else
1235                        status.playercan = 0xFFFF;
1236
1237                player->playback = &PlaybackHandler;
1238                player->output = &OutputHandler;
1239                player->container = &ContainerHandler;
1240                player->manager = &ManagerHandler;
1241
1242//#ifndef EXTEPLAYER3           
1243                //add container befor open, so we can set buffer size
1244                char* extffm = getfilenameext(tmpfile);
1245                if(extffm != NULL)
1246                {
1247                        player->container->Command(player, CONTAINER_ADD, extffm);
1248                        free(extffm); extffm = NULL;
1249                }
1250
1251                //select container_ffmpeg, if we does not found a container with extensions
1252                if(player->container->selectedContainer == NULL)
1253                        player->container->Command(player, CONTAINER_ADD, "mp3");
1254//#endif
1255
1256                if(player && player->container && player->container->selectedContainer)
1257                {
1258#ifndef EXTEPLAYER3
1259                        int32_t size = getconfigint("playerbuffersize", NULL);
1260                        int32_t seektime = getconfigint("playerbufferseektime", NULL);
1261#else
1262                        int32_t* size = (int32_t*)getconfigint("playerbuffersize", NULL);
1263                        int32_t* seektime = (int32_t*)getconfigint("playerbufferseektime", NULL);
1264
1265                        if(strstr(tmpfile, "http://") == tmpfile || strstr(tmpfile, "https://") == tmpfile)
1266                                progressive_playback_set(1);
1267
1268//                      if(ostrcmp(getconfig("av_ac3mode", NULL), "downmix") == 0)
1269#ifndef MIPSEL
1270                        printf("status.downmix; %d\n", status.downmix);
1271
1272
1273                        char* downmix = readfiletomem(getconfig("ac3dev", NULL), 1);
1274printf("ac3dev: %s\n",getconfig("ac3dev", NULL));
1275printf("downmix: %s\n",downmix);
1276                        if(ostrcmp(downmix, "passthrough") == 0)
1277                                status.downmix = 0;
1278                        else
1279                                status.downmix = 1;
1280
1281printf("status.downmix: %d\n",status.downmix);
1282sleep(5);
1283                        if(status.downmix == 1)
1284                        {
1285                                dts_software_decoder_set(1);
1286                                stereo_software_decoder_set(1);
1287                        }
1288#endif
1289//                      container_set_ffmpeg_buf_size(size);
1290#endif
1291
1292                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SIZE, (void*)&size);
1293                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SEEK_TIME, (void*)&seektime);
1294                }
1295               
1296                debug(150, "eplayername = %s", player->output->Name);
1297#ifdef EXTEPLAYER3
1298            // make sure to kill myself when parent dies
1299            prctl(PR_SET_PDEATHSIG, SIGKILL);
1300
1301            SetBuffering();
1302#endif
1303                //Registrating output devices
1304                player->output->Command(player, OUTPUT_ADD, "audio");
1305                player->output->Command(player, OUTPUT_ADD, "video");
1306                player->output->Command(player, OUTPUT_ADD, "subtitle");
1307#ifndef EXTEPLAYER3
1308                //for subtitle
1309//              SubtitleOutputDef_t subout;
1310
1311//              subout.screen_width = skinfb->width;
1312//              subout.screen_height = skinfb->height;
1313//              subout.framebufferFD = skinfb->fd;
1314//              subout.destination = (uint32_t *)skinfb->fb;
1315//              subout.destStride = skinfb->pitch;
1316//              subout.shareFramebuffer = 1;
1317//              subout.framebufferBlit = blitfb1;
1318
1319//              player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&subout);
1320
1321                if(player->playback->Command(player, PLAYBACK_OPEN, tmpfile) < 0)
1322                {
1323                        free(player); player = NULL;
1324                        free(tmpfile);
1325                        return 1;
1326                }
1327#else
1328            player->manager->video->Command(player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack);
1329            if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4))
1330            {
1331                player->playback->noprobe = 1;
1332            }
1333       
1334                char* audioFile = NULL;
1335            PlayFiles_t playbackFiles = {tmpfile, NULL};
1336            if('\0' != audioFile[0])
1337            {
1338                playbackFiles.szSecondFile = audioFile;
1339            }
1340
1341                //for subtitle
1342//              SubtitleOutputDef_t subout;
1343
1344//              subout.screen_width = skinfb->width;
1345//              subout.screen_height = skinfb->height;
1346//              subout.framebufferFD = skinfb->fd;
1347//              subout.destination = (uint32_t *)skinfb->fb;
1348//              subout.destStride = skinfb->pitch;
1349//              subout.shareFramebuffer = 1;
1350//              subout.framebufferBlit = blitfb1;
1351
1352//              player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&subout);
1353
1354                if(player->playback->Command(player, PLAYBACK_OPEN, &playbackFiles) < 0)
1355                {
1356                        free(player); player = NULL;
1357                        free(tmpfile);
1358                        return 1;
1359                }
1360#endif         
1361
1362
1363                player->output->Command(player, OUTPUT_OPEN, NULL);
1364                player->playback->Command(player, PLAYBACK_PLAY, NULL);
1365
1366                free(tmpfile);
1367
1368                return 0;
1369#endif
1370
1371#ifdef EPLAYER4
1372                int flags = 0x47; //(GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT);
1373               
1374                if(pipeline != NULL)
1375                {
1376                        debug(150, "eplayer allready running");
1377                        playerstop();
1378                }
1379               
1380                if(ostrstr(file, "://") == NULL)
1381                        tmpfile = ostrcat("file://", file, 0, 0);
1382                else
1383                        tmpfile = ostrcat(file, NULL, 0, 0);
1384
1385                printf("[player.h] file: %s\n", file);
1386
1387                if(tmpfile == NULL)
1388                {
1389                        err("no mem");
1390                        free(pipeline); pipeline = NULL;
1391                        return 1;
1392                }
1393
1394                if(ostrstr(tmpfile, "file://") == NULL)
1395                        //status.playercan = 0x7E7F;
1396                        //status.playercan = 0x7EFF;
1397                        status.playercan = 0xFEFF;
1398                else
1399                        //status.playercan = 0x7E7F;
1400                        //status.playercan = 0x7EFF;
1401                        status.playercan = 0xFEFF;
1402               
1403                m_framerate = -1;
1404#if GST_VERSION_MAJOR < 1
1405                pipeline = gst_element_factory_make("playbin2", "playbin");
1406#else
1407                pipeline = gst_element_factory_make("playbin", "playbin");
1408#endif
1409
1410// enable buffersize start
1411                int size = getconfigint("playerbuffersize", NULL);
1412                printf("size: %d\n",size);
1413               
1414                if(size > 0 && ostrstr(tmpfile, "file://") == NULL)
1415                        status.prefillbuffer = 1;
1416
1417/*
1418        if (g_object_class_find_property(G_OBJECT_GET_CLASS(pipeline), "user-agent") != 0)
1419                        printf("11111111111111\n");
1420        if (g_object_class_find_property(G_OBJECT_GET_CLASS(pipeline), "cookie") != 0)
1421                        printf("22222222222222\n");
1422        if (g_object_class_find_property(G_OBJECT_GET_CLASS(pipeline), "extra-headers") != 0)
1423                        printf("33333333333333\n");
1424
1425                if(ostrstr(file, "|User-Agent=") != NULL || ostrstr(file, "|Cookie=") != NULL || ostrstr(file, "|Referer=") != NULL)
1426                {
1427                        char* tmpstr = NULL, *tmpstr1 = NULL;
1428                        tmpstr = ostrcat(file, NULL, 0, 0);
1429//                      tmpstr = string_replace("|User-Agent=", "|", tmpstr, 1);
1430                        int count1 = 0, i = 0;
1431                        struct splitstr* ret1 = NULL;
1432                        ret1 = strsplit(tmpstr, "|", &count1);
1433
1434                        int max = count1;
1435                        for(i = 0; i < max; i++)
1436                        {
1437                                if(ostrstr(ret1[i].part, "User-Agent=") != NULL)
1438                                {
1439                                        tmpstr1 = ostrcat(ret1[i].part, NULL, 0, 0);
1440                                        tmpstr1 = string_replace("User-Agent=", "", tmpstr1, 1);
1441                                        printf("[player.h] set user-agent: %s\n", tmpstr1);
1442                                        g_object_set(G_OBJECT(pipeline), "user-agent", tmpstr1, NULL);
1443                                        free(tmpstr1), tmpstr1 = NULL;
1444                                }
1445                                if(ostrstr(ret1[i].part, "Cookie=") != NULL)
1446                                {
1447                                        tmpstr1 = ostrcat(ret1[i].part, NULL, 0, 0);
1448                                        tmpstr1 = string_replace("Cookie=", "", tmpstr1, 1);
1449                                        printf("[player.h] set cookie: %s\n", tmpstr1);
1450
1451                                        gchar **cookie;
1452//                                      cookie = g_strsplit ("foo=1234,bar=9871615348162523726337x99FB", ",", -1);
1453                                        cookie = g_strsplit (tmpstr1, ",", -1);
1454                                        g_object_set (G_OBJECT(pipeline), "http-headers", cookie, NULL);
1455                                        g_strfreev (cookie);
1456                                        free(tmpstr1), tmpstr1 = NULL;
1457                                }
1458                                if(ostrstr(ret1[i].part, "Referer=") != NULL)
1459                                {
1460                                        tmpstr1 = ostrcat(ret1[i].part, NULL, 0, 0);
1461                                        tmpstr1 = string_replace("Referer=", "", tmpstr1, 1);
1462                                        printf("[player.h] set referer dummy: %s\n", tmpstr1);
1463                                        free(tmpstr1), tmpstr1 = NULL;
1464                                }
1465                        }
1466                        free(ret1), ret1 = NULL;
1467                        free(tmpstr), tmpstr = NULL;
1468//                      g_object_set(G_OBJECT(pipeline), "user-agent", "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:30.0) Gecko/20100101 Firefox/30.0", NULL);
1469                        stringreplacechar(tmpfile, '|', '\0');
1470                        printf("tmpfile changed: %s\n", tmpfile);
1471                }
1472*/
1473
1474// strip url
1475                stringreplacechar(tmpfile, '|', '\0');
1476
1477                g_object_set(G_OBJECT(pipeline), "buffer-duration", size * GST_SECOND, NULL);
1478                g_object_set(G_OBJECT(pipeline), "buffer-size", size, NULL);
1479// enable buffersizeend
1480
1481                g_object_set(G_OBJECT(pipeline), "uri", tmpfile, NULL);
1482                g_object_set(G_OBJECT(pipeline), "flags", flags, NULL);
1483                free(tmpfile); tmpfile = NULL;
1484
1485///////////////////
1486// srt subs start
1487                const char *filename = file;
1488                const char *ext = strrchr(filename, '.');
1489                if (!ext)
1490                        ext = filename + strlen(filename);
1491
1492                GstElement *subsink = gst_element_factory_make("subsink", "subtitle_sink");
1493                if (!subsink)
1494                        printf("sorry, can't play: missing gst-plugin-subsink\n");
1495                else
1496                {
1497//                      m_subs_to_pull_handler_id = g_signal_connect (subsink, "new-buffer", G_CALLBACK (gstCBsubtitleAvail), this);
1498                        g_signal_connect (subsink, "new-buffer", G_CALLBACK (playersubtitleAvail), NULL);
1499
1500                        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);
1501
1502#if GST_VERSION_MAJOR < 1
1503                        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);
1504#else
1505                        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);
1506#endif
1507
1508                        g_object_set (G_OBJECT (pipeline), "text-sink", subsink, NULL);
1509                        subtitleflag = 1;
1510                        //g_object_set (G_OBJECT (pipeline), "current-text", -1, NULL);
1511                }
1512
1513//////////////////////////
1514// enable soup user-agent / extra-headers
1515                g_signal_connect(G_OBJECT(pipeline), "notify::source", G_CALLBACK(playbinNotifySource), file);
1516//////////////////////////
1517
1518                printf("[player.h] file changed: %s\n", file);
1519
1520//gpointer this;
1521//memset (&this, 0, sizeof (this));
1522
1523                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
1524#if GST_VERSION_MAJOR < 1
1525//              gst_bus_set_sync_handler(bus, gstBusSyncHandler, this);
1526                gst_bus_set_sync_handler(bus, GST_BUS_DROP, NULL);
1527#else
1528//              gst_bus_set_sync_handler(bus, gstBusSyncHandler, this, NULL);
1529                gst_bus_set_sync_handler(bus, GST_BUS_DROP, NULL, NULL);
1530#endif
1531
1532                gst_object_unref(bus);
1533                char srt_filename[ext - filename + 5];
1534                strncpy(srt_filename,filename, ext - filename);
1535                srt_filename[ext - filename] = '\0';
1536                strcat(srt_filename, ".srt");
1537
1538                if(access(srt_filename, R_OK) >= 0)
1539                {
1540                        printf("found srt1: %s\n",srt_filename);
1541                        printf("found srt2: %s\n",g_filename_to_uri(srt_filename, NULL, NULL));
1542                        g_object_set(G_OBJECT (pipeline), "suburi", g_filename_to_uri(srt_filename, NULL, NULL), NULL);
1543                }
1544// srt end     
1545
1546///////////////////
1547//              CustomData data;
1548                memset (&data, 0, sizeof (data));
1549                data.pipeline = pipeline;
1550//              GstBus *bus;
1551//              bus = gst_element_get_bus (pipeline);
1552               
1553                // Start playing //
1554
1555                GstStateChangeReturn ret;
1556                ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
1557                g_object_set (G_OBJECT (pipeline), "current-text", 0, NULL);
1558                if(ret == GST_STATE_CHANGE_FAILURE)
1559                {
1560                        g_printerr ("Unable to set the pipeline to the playing state.\n");
1561                        gst_object_unref (pipeline);
1562                        return -1;
1563                }
1564                else if(ret == GST_STATE_CHANGE_NO_PREROLL)
1565                {
1566                        data.is_live = TRUE;
1567                }
1568
1569                data.loop = g_main_loop_new (NULL, FALSE);
1570                data.pipeline = pipeline;
1571                gst_bus_add_signal_watch (bus);
1572//              g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data);
1573//              status.prefillbuffer = 1;
1574
1575//analyze_streams(data);
1576
1577                int count = 0;
1578                m_gst_startpts = 0;
1579                while(m_gst_startpts == 0 && count < 5)
1580                {
1581                        count++;
1582                        sleep(1);
1583                        m_gst_startpts = playergetpts();
1584                }
1585
1586                return 0;
1587#endif
1588        }
1589       
1590        return 1;
1591}
1592
1593#ifdef EPLAYER4
1594int setBufferSize(int size)
1595{
1596        int m_buffer_size = size;
1597        g_object_set (G_OBJECT (pipeline), "buffer-size", m_buffer_size, NULL);
1598        return 0;
1599}
1600#endif
1601
1602void playerinit(int argc, char* argv[])
1603{
1604#ifdef EPLAYER4
1605//      GstBus *bus;
1606//      GstStateChangeReturn ret;
1607//      gint flags;
1608        gst_init(&argc, &argv);
1609#endif
1610}
1611
1612#ifdef EPLAYER4
1613int gstbuscall(GstBus *bus, GstMessage *msg, CustomData *data)
1614{
1615        int ret = 1;
1616        if(!pipeline) return 0;
1617        if(!msg) return ret;
1618
1619        gchar *sourceName = NULL;
1620        GstObject *source = GST_MESSAGE_SRC(msg);
1621
1622        if(!GST_IS_OBJECT(source)) return ret;
1623        sourceName = gst_object_get_name(source);
1624
1625        debug(150, "gst type: %s", GST_MESSAGE_TYPE_NAME(msg));
1626
1627        switch(GST_MESSAGE_TYPE(msg))
1628        {
1629                case GST_MESSAGE_EOS:
1630                        debug(150, "gst player eof");
1631                        ret = 0;
1632                        break;
1633                case GST_MESSAGE_STATE_CHANGED:
1634                        debug(150, "gst message state changed");
1635                        if(GST_MESSAGE_SRC(msg) != GST_OBJECT(pipeline))
1636                                break;
1637
1638                        GstState old_state, new_state, pending_state;
1639                        gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
1640                        if(GST_MESSAGE_SRC(msg) == GST_OBJECT(pipeline))
1641                        {
1642                                if(new_state == GST_STATE_PLAYING)
1643                                {
1644                                        /* Once we are in the playing state, analyze the streams */
1645                                        analyze_streams(data);
1646                                }
1647                        }
1648
1649                        if(old_state == new_state) break;
1650       
1651                        debug(150, "gst state change %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
1652       
1653                        GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
1654       
1655                        switch(transition)
1656                        {
1657                                case GST_STATE_CHANGE_NULL_TO_READY:
1658                                        break;
1659                                case GST_STATE_CHANGE_READY_TO_PAUSED:
1660/*
1661                                        GstElement *appsink = gst_bin_get_by_name(GST_BIN(pipeline), "subtitle_sink");
1662                                        if(appsink)
1663                                        {
1664                                                g_object_set(G_OBJECT(appsink), "max-buffers", 2, NULL);
1665                                                g_object_set(G_OBJECT(appsink), "sync", FALSE, NULL);
1666                                                g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, NULL);
1667                                                gst_object_unref(appsink);
1668                                        }
1669*/
1670                                        break;
1671                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1672                                        //if(m_sourceinfo.is_streaming && m_streamingsrc_timeout )
1673                                                //m_streamingsrc_timeout->stop();
1674                                        break;
1675                                case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1676                                        break;
1677                                case GST_STATE_CHANGE_PAUSED_TO_READY:
1678                                        break;
1679                                case GST_STATE_CHANGE_READY_TO_NULL:
1680                                        ret = 0;
1681                                        break;
1682                        }
1683                        break;
1684                case GST_MESSAGE_ERROR:
1685                        debug(150, "gst player error");
1686
1687                        gchar *gdebug1;
1688                        GError *err;
1689
1690                        gst_message_parse_error(msg, &err, &gdebug1);
1691                        g_free(gdebug1);
1692
1693                        debug(150, "gst error: %s (%i) from %s", err->message, err->code, sourceName);
1694                        if(err->domain == GST_STREAM_ERROR)
1695                        {
1696                                if(err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
1697                                {
1698                                        //if(g_strrstr(sourceName, "videosink"))
1699                                        //      m_event((iPlayableService*)this, evUser+11);
1700                                        //else if ( g_strrstr(sourceName, "audiosink") )
1701                                        //      m_event((iPlayableService*)this, evUser+10);
1702                                }
1703                        }
1704                        g_error_free(err);
1705                        break;
1706                case GST_MESSAGE_INFO:
1707                        debug(150, "gst player info");
1708
1709/*
1710                        gchar *gdebug2;
1711                        GError *inf;
1712       
1713                        gst_message_parse_info(msg, &inf, &gdebug2);
1714                        g_free(gdebug2);
1715                        if(inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
1716                        {
1717                                //if(g_strrstr(sourceName, "videosink"))
1718                                //      m_event((iPlayableService*)this, evUser+14);
1719                        }
1720                        g_error_free(inf);
1721*/
1722                        break;
1723                case GST_MESSAGE_TAG:
1724                        debug(150, "gst player tag");
1725                        break;
1726                //case GST_MESSAGE_ASYNC_DONE:
1727                //      debug(150, "gst player async done");
1728                //      break;
1729                case GST_MESSAGE_ELEMENT:
1730                        debug(150, "GST_MESSAGE_ELEMENT");
1731                        const GstStructure *msgstruct = gst_message_get_structure(msg);
1732                        if (msgstruct)
1733                        {
1734                                const gchar *eventname = gst_structure_get_name(msgstruct);
1735                                if (!strcmp(eventname, "eventFrameRateChanged") || !strcmp(eventname, "eventFrameRateAvail"))
1736                                {
1737                                        gst_structure_get_int (msgstruct, "frame_rate", &m_framerate);
1738                                }
1739                        }
1740                        debug(150, "gst player element");
1741                        break;
1742                case GST_MESSAGE_BUFFERING:
1743                        debug(150, "gst player buffering");
1744
1745/*
1746                        GstBufferingMode mode;
1747                        gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
1748                        gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
1749                        //m_event((iPlayableService*)this, evBuffering);
1750*/
1751
1752// playback stream jerky on start
1753//                      if (data->is_live) break;
1754//                      gst_message_parse_buffering (msg, &status.bufferpercent);
1755
1756                        if(status.prefillbuffer == 1)
1757                        {
1758                                status.prefillbuffercount++;
1759                                if(status.prefillbuffercount >= 200 && status.bufferpercent < 2)
1760                                {
1761                                        printf("status.prefillbuffercount >= 200 set status.prefillbuffer=2\n");
1762                                        status.prefillbuffer = 2;
1763                                }
1764                        }
1765                        debug(150, "status.prefillbuffercount=%d status.cleaninfobar=%d status.prefillbuffer=%d status.bufferpercent=%d",status.prefillbuffercount , status.cleaninfobar, status.prefillbuffer, status.bufferpercent);
1766                       
1767                        if(status.prefillbuffer == 1)
1768                        {
1769//                              gint percent = 0;
1770                                if (data->is_live)
1771                                {
1772                                        printf("data->is_live break: status.cleaninfobar=%d status.prefillbuffer=%d status.bufferpercent=%d\n", status.cleaninfobar, status.prefillbuffer, status.bufferpercent);
1773                                        break;
1774                                }
1775
1776                                gst_message_parse_buffering (msg, &status.bufferpercent);
1777                                g_print ("Buffering (%3d%%)\r", status.bufferpercent);
1778
1779                                if (status.bufferpercent < 100)
1780                                {
1781                                        gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
1782                                        struct skin* waitmsgbar = getscreen("waitmsgbar");
1783                                        struct skin* load = getscreen("loading");
1784       
1785                                        waitmsgbar->progresssize = status.bufferpercent;
1786                                        char* tmpstr = NULL;
1787                                        tmpstr = ostrcat(_("Buffering Stream - Cancel with Exit"), " (", 0, 0);
1788                                        tmpstr = ostrcat(tmpstr, oitoa(waitmsgbar->progresssize), 1, 0);
1789                                        tmpstr = ostrcat(tmpstr, "%)", 1, 0);
1790                                        changetext(waitmsgbar, tmpstr);
1791                                        free(tmpstr); tmpstr = NULL;
1792       
1793                                        drawscreen(load, 0, 0);
1794                                        drawscreen(waitmsgbar, 0, 0);
1795                                        status.cleaninfobar = 0;
1796                                }
1797                                else
1798                                {
1799                                        drawscreen(skin, 0, 0);
1800                                        gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
1801                                        status.prefillbuffer = 0;
1802                                        status.cleaninfobar = 1;
1803                                }
1804       
1805                        }
1806                        else if(status.prefillbuffer == 2)
1807                        {
1808                                drawscreen(skin, 0, 0);
1809                                gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
1810                                status.prefillbuffer = 0;
1811                                status.cleaninfobar = 1;
1812                        }
1813                        else if(status.cleaninfobar == 1)
1814                        {
1815                                drawscreen(skin, 0, 0);
1816                                status.cleaninfobar = 0;
1817                        }
1818                        else
1819                        {
1820//                      printf("else\n");
1821                                gst_message_parse_buffering (msg, &status.bufferpercent);
1822                                g_print ("Buffering (%3d%%)\r", status.bufferpercent);
1823//                              drawscreen(skin, 0, 0);
1824//                              status.cleaninfobar = 0;
1825                        }
1826                        break;
1827 
1828/*
1829                        GstBufferingMode mode;
1830                        gst_message_parse_buffering(msg, &(status.bufferpercent));
1831                        gst_message_parse_buffering_stats(msg, &mode, &(status.avgInRate), &(status.avgOutRate), &(status.bufferingLeft));
1832
1833//                      printf("#########################################################\n");
1834//                      printf("Buffering %u percent done\n", status.bufferpercent);
1835//                      printf("avgInRate %d\n", status.avgInRate);
1836//                      printf("avgOutRate %d\n", status.avgOutRate);
1837//                      printf("bufferingLeft %lld\n", status.bufferingLeft);
1838                                       
1839                        if(status.prefillbuffer == 1)
1840                        {
1841                                printf("status.prefillbuffer Buffering %u percent done\n", status.bufferpercent);
1842
1843                                if (status.bufferpercent == 100)
1844                                {
1845                                        GstState state;
1846                                        gst_element_get_state(pipeline, &state, NULL, 0LL);
1847                                        if (state != GST_STATE_PLAYING)
1848                                        {
1849                                                // eDebug("start playing");
1850                                                gst_element_set_state (pipeline, GST_STATE_PLAYING);
1851                                        }
1852//                                      m_ignore_buffering_messages = 5;
1853                                        status.prefillbuffer = 0;
1854                                }
1855                                else if (status.bufferpercent == 0)
1856                                {
1857                                        // eDebug("start pause");
1858                                        gst_element_set_state (pipeline, GST_STATE_PAUSED);
1859//                                      m_ignore_buffering_messages = 0;
1860                                }
1861                        }
1862*/
1863/*
1864                                GstBufferingMode mode;
1865                                printf("GST_STATE_PAUSED\n");
1866                                gst_element_set_state (pipeline, GST_STATE_PAUSED);
1867
1868
1869                                gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
1870                                // eDebug("Buffering %u percent done", m_bufferInfo.bufferPercent);
1871                                gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
1872                                m_event((iPlayableService*)this, evBuffering);
1873                                if (m_use_prefillbuffer && !m_is_live && --m_ignore_buffering_messages <= 0)
1874                                {
1875                                        if (m_bufferInfo.bufferPercent == 100)
1876                                        {
1877                                                GstState state;
1878                                                gst_element_get_state(pipeline, &state, NULL, 0LL);
1879                                                if (state != GST_STATE_PLAYING)
1880                                                {
1881                                                        // eDebug("start playing");
1882                                                        gst_element_set_state (pipeline, GST_STATE_PLAYING);
1883                                                }
1884                                                m_ignore_buffering_messages = 5;
1885                                        }
1886                                        else if (m_bufferInfo.bufferPercent == 0)
1887                                        {
1888                                                // eDebug("start pause");
1889                                                gst_element_set_state (pipeline, GST_STATE_PAUSED);
1890                                                m_ignore_buffering_messages = 0;
1891                                        }
1892                                        else
1893                                        {
1894                                                m_ignore_buffering_messages = 0;
1895                                        }
1896                                }
1897
1898*/
1899                        break;
1900                case GST_MESSAGE_STREAM_STATUS:
1901                        debug(150, "gst player stream status");
1902
1903/*
1904                        GstStreamStatusType type;
1905                        GstElement *owner;
1906
1907                        gst_message_parse_stream_status(msg, &type, &owner);
1908                        if(type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming)
1909                        {
1910                                if(GST_IS_PAD(source))
1911                                        owner = gst_pad_get_parent_element(GST_PAD(source));
1912                                else if(GST_IS_ELEMENT(source))
1913                                        owner = GST_ELEMENT(source);
1914                                else
1915                                        owner = NULL;
1916                                if(owner)
1917                                {
1918                                        GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
1919                                        const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
1920                                        if (!strcmp(name, "souphttpsrc"))
1921                                        {
1922                                                //m_streamingsrc_timeout->start(10 * 1000, true);
1923                                                g_object_set(G_OBJECT(owner), "timeout", 10, NULL);
1924                                        }
1925                                       
1926                                }
1927                                if(GST_IS_PAD(source))
1928                                        gst_object_unref(owner);
1929                        }
1930*/
1931                        break;
1932                default:
1933                        debug(150, "gst player unknown message");
1934                        break;
1935        }
1936        g_free(sourceName);
1937        return ret;
1938}
1939#endif
1940
1941int playergetbuffersize()
1942{
1943        int ret = 0;
1944
1945#ifdef EPLAYER3
1946        if(player && player->container && player->container->selectedContainer)
1947                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_SIZE, (void*)&ret);
1948#endif
1949
1950        return ret;
1951}
1952
1953int playergetbufferstatus()
1954{
1955        int ret = 0;
1956
1957#ifdef EPLAYER3
1958        if(player && player->container && player->container->selectedContainer)
1959                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_STATUS, (void*)&ret);
1960#endif
1961
1962        return ret;
1963}
1964
1965int playerstopbuffer()
1966{
1967        int ret = 0;
1968
1969#ifdef EPLAYER3
1970        if(player && player->container && player->container->selectedContainer)
1971                player->container->selectedContainer->Command(player, CONTAINER_STOP_BUFFER, NULL);
1972#endif
1973
1974        return ret;
1975}
1976
1977int playerisplaying()
1978{
1979#ifdef SIMULATE
1980        return 1;
1981#endif
1982
1983#ifdef EPLAYER3
1984        if(player != NULL && player->playback != NULL && player->playback->isPlaying)
1985                return 1;
1986#endif
1987
1988#ifdef EPLAYER4
1989        int ret = 1;
1990
1991        if(pipeline)
1992        {
1993                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
1994                GstMessage *message = NULL;
1995//use global variale, with static var crash
1996//              CustomData *data = NULL;
1997                while((message = gst_bus_pop(bus)))
1998                {
1999                        ret = gstbuscall(bus, message, &data);
2000                        gst_message_unref(message);
2001
2002                }               
2003// fix buffering on filenuke
2004                if(status.cleaninfobar == 0 && status.prefillbuffer == 1 && status.bufferpercent == 0)
2005                        gst_element_set_state (pipeline, GST_STATE_PAUSED);
2006                       
2007// eof workaround for some mp4 files.
2008                gint64 pts = 0, len = 0, rest = 0;
2009                gint64 nanos_pts = 0, nanos_len = 0;
2010
2011                len = playergetlength();
2012                nanos_len = len * 1000000000;
2013                if(nanos_len < 0) nanos_len = 0;
2014
2015                pts = playergetpts();
2016                nanos_pts = pts * 11111;
2017
2018                rest = nanos_len - nanos_pts;
2019//              printf("rest: %lld\n", nanos_len - nanos_pts);
2020
2021                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);
2022                if(rest > 4000000000LL || status.pts != pts || pts == 0 || status.pause == 1 || status.playspeed != 0 || status.slowspeed != 0 /*|| status.prefillbuffer == 1*/)
2023                {
2024//                      debug(150, "status.pts=%llu / pts=%llu\n", status.pts, pts);
2025                        status.pts = pts;
2026                }
2027                else
2028                {
2029                        debug(150, "gst player eof - workaround (rest=%lld)", rest);
2030                        ret = 0;
2031                }
2032// eof workaround done
2033        }
2034        else
2035                ret = 0;
2036
2037        return ret;
2038#endif
2039        return 0;
2040}
2041
2042void playerplay()
2043{
2044#ifdef EPLAYER3
2045        if(player && player->playback)
2046                player->playback->Command(player, PLAYBACK_PLAY, NULL);
2047#endif
2048
2049#ifdef EPLAYER4
2050        if(pipeline)
2051                gst_element_set_state(pipeline, GST_STATE_PLAYING);
2052        if(subtitleflag == 2)
2053                subtitleflag = 1;
2054#endif
2055}
2056
2057int playerstop()
2058{
2059#ifdef EPLAYER3
2060        if(player && player->playback)
2061                player->playback->Command(player, PLAYBACK_STOP, NULL);
2062        if(player && player->container && player->container->selectedContainer)
2063                player->container->selectedContainer->Command(player, CONTAINER_STOP, NULL);
2064        if(player && player->output)
2065        {
2066                player->output->Command(player, OUTPUT_CLOSE, NULL);
2067                player->output->Command(player, OUTPUT_DEL, (void*)"audio");
2068                player->output->Command(player, OUTPUT_DEL, (void*)"video");
2069                player->output->Command(player, OUTPUT_DEL, (void*)"subtitle");
2070        }
2071        if(player && player->playback)
2072                player->playback->Command(player, PLAYBACK_CLOSE, NULL);
2073
2074        free(player);
2075        player = NULL;
2076// move to mc
2077//      set_player_sound(1);
2078#endif
2079
2080#ifdef EPLAYER4
2081        subtitleflag = 0;
2082        if(subtitlethread != 0)
2083                subtitlethread->aktion = STOP;
2084        if(video_sink)
2085        {
2086                gst_object_unref (video_sink);
2087                video_sink = NULL;
2088        }
2089        if(pipeline)
2090        {
2091                gst_element_set_state(pipeline, GST_STATE_NULL);
2092                gst_object_unref(GST_OBJECT(pipeline));
2093                pipeline = NULL;
2094        }
2095#endif
2096
2097        writesysint("/proc/sys/vm/drop_caches", 3, 0);
2098        return 0;
2099}
2100
2101void playerafterend()
2102{
2103#ifdef EPLAYER3
2104        if(player != NULL && player->playback != NULL)
2105                playerstop();
2106#endif
2107
2108#ifdef EPLAYER4
2109        if(pipeline)
2110                playerstop();
2111#endif
2112}
2113
2114void playerpause()
2115{
2116#ifdef EPLAYER3
2117        if(player && player->playback)
2118                player->playback->Command(player, PLAYBACK_PAUSE, NULL);
2119#endif
2120
2121#ifdef EPLAYER4
2122        if(pipeline)
2123                gst_element_set_state(pipeline, GST_STATE_PAUSED);
2124#endif
2125}
2126
2127void playercontinue()
2128{
2129#ifdef EPLAYER3
2130        if(player && player->playback)
2131                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
2132#endif
2133
2134#ifdef EPLAYER4
2135        if(pipeline)
2136        {
2137                if(status.playspeed != 0 || status.slowspeed != 0)
2138                {
2139                        //subtitle sync bug... start
2140                        gint64 time_nanoseconds = 0;
2141                        GstFormat fmt = GST_FORMAT_TIME;
2142#if GST_VERSION_MAJOR < 1
2143                        if (!gst_element_query_position(pipeline, &fmt, &time_nanoseconds))
2144#else
2145                        if (!gst_element_query_position(pipeline, fmt, &time_nanoseconds))
2146#endif
2147                        {
2148                                err("gst_element_query_position failed");
2149                                return;
2150                        }
2151                        time_nanoseconds = time_nanoseconds - 90000;
2152                        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))
2153                                printf("seekTo failed");
2154                        //subtitle sync bug... end
2155
2156                        //playersend_ff_fr_event(1);
2157                }               
2158                gst_element_set_state(pipeline, GST_STATE_PLAYING);
2159                if(subtitleflag == 2)
2160                        subtitleflag = 1;
2161        }
2162#endif
2163}
2164
2165void playerff(int speed)
2166{
2167#ifdef EPLAYER3
2168        int speedmap = 0;
2169
2170        if (speed < 1) speed = 1;
2171        if (speed > 7) speed = 7;
2172
2173        switch(speed)
2174        {
2175                case 1: speedmap = 1; break;
2176                case 2: speedmap = 3; break;
2177                case 3: speedmap = 7; break;
2178                case 4: speedmap = 15; break;
2179                case 5: speedmap = 31; break;
2180                case 6: speedmap = 63; break;
2181                case 7: speedmap = 127; break;
2182        }
2183
2184        if(player && player->playback)
2185                player->playback->Command(player, PLAYBACK_FASTFORWARD, &speedmap);
2186#ifdef MIPSEL
2187        if(player && player->playback)
2188                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
2189#endif
2190#endif
2191
2192#ifdef EPLAYER4
2193        gdouble rate = 0;
2194        subtitleflag = 2;
2195        if (speed < 1) speed = 1;
2196        if (speed > 7) speed = 7;
2197
2198        switch(speed)
2199        {
2200                case 1: rate = 2; break;
2201                case 2: rate = 4; break;
2202                case 3: rate = 8; break;
2203                case 4: rate = 16; break;
2204                case 5: rate = 32; break;
2205                case 6: rate = 64; break;
2206                case 7: rate = 128; break;
2207        }
2208        playersend_ff_fr_event(rate);
2209#endif
2210}
2211
2212void playerslow(int speed)
2213{
2214#ifdef EPLAYER3
2215        int speedmap = 0;
2216#ifdef EXTEPLAYER3
2217        if (speed < 2) speed = 2;
2218        if (speed > 8) speed = 8;
2219
2220        switch(speed)
2221        {
2222                case 2: speedmap = 2; break;
2223                case 4: speedmap = 4; break;
2224                case 8: speedmap = 8; break;
2225        }
2226#else
2227        if (speed < 1) speed = 1;
2228        if (speed > 7) speed = 7;
2229
2230        switch(speed)
2231        {
2232                case 1: speedmap = 1; break;
2233                case 2: speedmap = 3; break;
2234                case 3: speedmap = 7; break;
2235                case 4: speedmap = 15; break;
2236                case 5: speedmap = 31; break;
2237                case 6: speedmap = 63; break;
2238                case 7: speedmap = 127; break;
2239        }
2240#endif
2241        if(player && player->playback)
2242                player->playback->Command(player, PLAYBACK_SLOWMOTION, &speedmap);
2243
2244#ifdef MIPSEL
2245        if(player && player->playback)
2246                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
2247#endif
2248#endif
2249
2250#ifdef EPLAYER4
2251        gdouble rate = 0;
2252        if (speed < 1) speed = 1;
2253        if (speed > 7) speed = 7;
2254               
2255        switch(speed)
2256        {
2257                case 1: rate = 0.8; break;
2258                case 2: rate = 0.7; break;
2259                case 3: rate = 0.6; break;
2260                case 4: rate = 0.5; break;
2261                case 5: rate = 0.3; break;
2262                case 6: rate = 0.2; break;
2263                case 7: rate = 0.1; break;
2264        }
2265        gst_element_set_state(pipeline, GST_STATE_PLAYING);
2266        playersend_ff_fr_event(rate);
2267       
2268#endif
2269
2270}
2271
2272void playerfr(int speed)
2273{
2274#ifdef EPLAYER3
2275        int speedmap = 0;
2276
2277        if (speed > -1) speed = -1;
2278        if (speed < -7) speed = -7;
2279
2280        switch(speed)
2281        {
2282                case -1: speedmap = -5; break;
2283                case -2: speedmap = -10; break;
2284                case -3: speedmap = -20; break;
2285                case -4: speedmap = -40; break;
2286                case -5: speedmap = -80; break;
2287                case -6: speedmap = -160; break;
2288                case -7: speedmap = -320; break;
2289        }
2290
2291        if(player && player->playback)
2292                player->playback->Command(player, PLAYBACK_FASTBACKWARD, &speedmap);
2293
2294#ifdef MIPSEL
2295        if(player && player->playback)
2296                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
2297#endif
2298#endif
2299
2300#ifdef EPLAYER4
2301        gdouble rate = 0;
2302       
2303        if (speed > -1) speed = -1;
2304        if (speed < -7) speed = -7;
2305
2306        switch(speed)
2307        {
2308                case -1: rate = -2; break;
2309                case -2: rate = -4; break;
2310                case -3: rate = -8; break;
2311                case -4: rate = -16; break;
2312                case -5: rate = -32; break;
2313                case -6: rate = -64; break;
2314                case -7: rate = -128; break;
2315        }
2316        playersend_ff_fr_event(rate);
2317#endif
2318}
2319
2320void playerseek(float sec)
2321{
2322#ifdef EPLAYER3
2323#ifdef EXTEPLAYER3
2324        int64_t sectmp = (int64_t)sec;
2325        if(player && player->playback) 
2326                player->playback->Command(player, PLAYBACK_SEEK, (void*)&sectmp);
2327#else
2328        if(player && player->playback)
2329                player->playback->Command(player, PLAYBACK_SEEK, (void*)&sec);
2330#endif
2331#endif
2332
2333#ifdef EPLAYER4
2334        gint64 nanos_pts = 0, nanos_len = 0;
2335        gint64 pts = 0, len = 0;
2336        //GstFormat fmt = GST_FORMAT_TIME;
2337               
2338        if(pipeline)
2339        {
2340                len = playergetlength();
2341                nanos_len = len * 1000000000;
2342                if(nanos_len < 0) nanos_len = 0;
2343
2344                pts = playergetpts();
2345                nanos_pts = pts * 11111;
2346                nanos_pts = nanos_pts + (sec * 1000000000);
2347                if(nanos_pts < 0) nanos_pts = 0;
2348
2349                if(nanos_pts >= nanos_len)
2350                {
2351                        debug(150, "gst skip seeking");
2352//                      playerstop();
2353                }
2354                else
2355                        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);
2356        }
2357#endif
2358}
2359
2360#ifdef EPLAYER4
2361audiotype_t gstCheckAudioPad(GstStructure* structure)
2362{
2363        if(!structure)
2364                return atUnknown;
2365
2366        if(gst_structure_has_name(structure, "audio/mpeg"))
2367        {
2368                gint mpegversion, layer = -1;
2369                if(!gst_structure_get_int (structure, "mpegversion", &mpegversion))
2370                        return atUnknown;
2371
2372                switch(mpegversion)
2373                {
2374                        case 1:
2375                                {
2376                                        gst_structure_get_int(structure, "layer", &layer);
2377                                        if(layer == 3)
2378                                                return atMP3;
2379                                        else
2380                                                return atMPEG;
2381                                        break;
2382                                }
2383                        case 2:
2384                                return atAAC;
2385                        case 4:
2386                                return atAAC;
2387                        default:
2388                                return atUnknown;
2389                }
2390        }
2391
2392        else if(gst_structure_has_name(structure, "audio/x-ac3") || gst_structure_has_name(structure, "audio/ac3"))
2393                return atAC3;
2394        else if(gst_structure_has_name(structure, "audio/x-dts") || gst_structure_has_name(structure, "audio/dts"))
2395                return atDTS;
2396#if GST_VERSION_MAJOR < 1
2397        else if(gst_structure_has_name(structure, "audio/x-raw-int"))
2398#else
2399        else if(gst_structure_has_name(structure, "audio/x-raw"))
2400#endif
2401                return atPCM;
2402
2403        return atUnknown;
2404}
2405
2406
2407subtype_t getSubtitleType(GstPad* pad, gchar *g_codec)
2408{
2409g_codec = NULL;
2410        subtype_t type = stUnknown;
2411#if GST_VERSION_MAJOR < 1
2412        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
2413#else
2414        GstCaps* caps = gst_pad_get_current_caps(pad);
2415#endif
2416        if (!caps && !g_codec)
2417        {
2418                caps = gst_pad_get_allowed_caps(pad);
2419        }
2420
2421        if (caps && !gst_caps_is_empty(caps))
2422        {
2423                GstStructure* str = gst_caps_get_structure(caps, 0);
2424                if (str)
2425                {
2426                        const gchar *g_type = gst_structure_get_name(str);
2427                        // eDebug("getSubtitleType::subtitle probe caps type=%s", g_type ? g_type : "(null)");
2428                        if (g_type)
2429                        {
2430#if GST_VERSION_MAJOR < 1
2431                                if ( !strcmp(g_type, "video/x-dvd-subpicture") )
2432#else
2433                                if ( !strcmp(g_type, "subpicture/x-dvd") )
2434#endif
2435                                        type = stVOB;
2436                                else if ( !strcmp(g_type, "text/x-pango-markup") )
2437                                        type = stSRT;
2438                                else if ( !strcmp(g_type, "text/plain") || !strcmp(g_type, "text/x-plain") || !strcmp(g_type, "text/x-raw") )
2439                                        type = stPlainText;
2440                                else if ( !strcmp(g_type, "subpicture/x-pgs") )
2441                                        type = stPGS;
2442                                else
2443                                        printf("getSubtitleType::unsupported subtitle caps %s (%s)\n", g_type, g_codec ? g_codec : "(null)");
2444//                                      eDebug("getSubtitleType::unsupported subtitle caps %s (%s)", g_type, g_codec ? g_codec : "(null)");
2445                        }
2446                }
2447        }
2448        else if ( g_codec )
2449        {
2450                // eDebug("getSubtitleType::subtitle probe codec tag=%s", g_codec);
2451                if ( !strcmp(g_codec, "VOB") )
2452                        type = stVOB;
2453                else if ( !strcmp(g_codec, "SubStation Alpha") || !strcmp(g_codec, "SSA") )
2454                        type = stSSA;
2455                else if ( !strcmp(g_codec, "ASS") )
2456                        type = stASS;
2457                else if ( !strcmp(g_codec, "SRT") )
2458                        type = stSRT;
2459                else if ( !strcmp(g_codec, "UTF-8 plain text") )
2460                        type = stPlainText;
2461                else
2462                        printf("getSubtitleType::unsupported subtitle codec %s\n", g_codec);
2463        }
2464        else
2465                printf("getSubtitleType::unidentifiable subtitle stream!\n");
2466
2467        return type;
2468}
2469
2470#endif
2471
2472void playerfreetracklist(char** TrackList)
2473{
2474        int i = 0;
2475
2476        if(TrackList != NULL)
2477        {
2478                while(TrackList[i] != NULL)
2479                {
2480                        free(TrackList[i]);
2481                        free(TrackList[i + 1]);
2482                        i += 2;
2483                }
2484        }
2485}
2486
2487char** playergettracklist(int type)
2488{
2489#ifdef EXTEPLAYER3
2490#ifdef EPLAYER3
2491        TrackDescription_t *TrackList = NULL;
2492        char ** TrackList2 = NULL;
2493#else
2494        char ** TrackList = NULL;
2495#endif
2496#else
2497        char ** TrackList = NULL;
2498#endif
2499
2500#ifdef EPLAYER3
2501        if(player && player->manager)
2502        {
2503                switch(type)
2504                {
2505                        case 1:
2506                                if(player->manager->audio)
2507                                {
2508                                        player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
2509                                        debug(150, "Audio Track List");
2510                                }
2511                                break;
2512                        case 2:
2513                                if(player->manager->subtitle)
2514                                {
2515                                        player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
2516                                        debug(150, "Subtitle Track List");
2517                                }
2518                                break;
2519                        default:
2520                                if(player->manager->video)
2521                                {
2522                                        player->manager->video->Command(player, MANAGER_LIST, &TrackList);
2523                                        debug(150, "Video Track List");
2524                                }
2525                }
2526
2527#ifdef EXTEPLAYER3
2528                TrackList2 = calloc(1, sizeof(char *) * ((100 * 2) + 1));
2529
2530                char* tmpstr = NULL;
2531        if( NULL != TrackList)
2532        {
2533                        debug(150, "Track List");
2534
2535            int i = 0;
2536            for (i = 0; TrackList[i].Id >= 0; ++i)
2537            {
2538                                tmpstr = ostrcat(oitoa(TrackList[i].Id), ": ", 1, 0);
2539                                tmpstr = ostrcat(tmpstr, TrackList[i].Name, 1, 0);
2540                                TrackList2[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2541                                TrackList2[(i * 2) + 1] = strdup(TrackList[i].Encoding);
2542                free(TrackList[i].Encoding);
2543                free(TrackList[i].Name);
2544                                debug(150, "%s - %s", TrackList2[i * 2], TrackList2[i * 2 + 1]);
2545            }
2546            free(TrackList);
2547        }
2548        free(tmpstr), tmpstr = NULL;
2549#else
2550                int i = 0;
2551                if(TrackList != NULL)
2552                {
2553                        while(TrackList[i] != NULL)
2554                        {
2555                                string_newline(TrackList[i]);
2556                                i += 2;
2557                        }
2558                       
2559                        debug(150, "Track List");
2560                        i = 0;
2561                        while(TrackList[i] != NULL)
2562                        {
2563                                debug(150, "%s - %s", TrackList[i], TrackList[i + 1]);
2564                                i += 2;
2565                        }
2566                }
2567#endif
2568        }
2569#endif
2570
2571//////////////////////////////NEUER CODE //////////////////////////////
2572#ifdef EPLAYER4
2573        TrackList = calloc(1, sizeof(char *) * ((100 * 2) + 1));
2574       
2575        if(pipeline != NULL)
2576        {
2577                gint i, n_video = 0, n_audio = 0, n_text = 0;
2578               
2579                g_object_get(pipeline, "n-video", &n_video, NULL);
2580                g_object_get(pipeline, "n-audio", &n_audio, NULL);
2581                g_object_get(pipeline, "n-text", &n_text, NULL);
2582
2583                switch(type)
2584                {
2585                        case 1:
2586                                for(i = 0; i < n_audio; i++)
2587                                {
2588                                        GstTagList *tags = NULL;
2589                                        gchar *g_codec = NULL, *g_lang = NULL;
2590                                        char* tmpstr = NULL;
2591                                        GstPad* pad = 0;
2592                                       
2593                                        g_signal_emit_by_name (pipeline, "get-audio-pad", i, &pad);
2594#if GST_VERSION_MAJOR < 1
2595                                        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
2596#else
2597                                        GstCaps* caps = gst_pad_get_current_caps(pad);
2598#endif
2599                                        if(!caps)
2600                                                continue;
2601                                       
2602                                        GstStructure* str = gst_caps_get_structure(caps, 0);
2603                                        const gchar *g_type = gst_structure_get_name(str);
2604
2605                                        g_signal_emit_by_name(pipeline, "get-audio-tags", i, &tags);
2606
2607#if GST_VERSION_MAJOR < 1
2608                                        if(tags && gst_is_tag_list(tags))
2609#else
2610                                        if(tags && GST_IS_TAG_LIST(tags))
2611#endif
2612                                        {
2613                                                if(gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_codec))
2614                                                {
2615                                                        printf("Audio Codec: %s\n", g_codec);
2616       
2617                                                        tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
2618                                                        tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
2619                                                        if(g_codec != NULL && g_type != NULL)
2620                                                                tmpstr = ostrcat(tmpstr, " (", 1, 0);
2621                                                        tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
2622                                                        if(g_codec != NULL && g_type != NULL)
2623                                                                tmpstr = ostrcat(tmpstr, ")", 1, 0);
2624
2625                                                        printf("Tracklist tmpstr: %s\n", tmpstr);
2626
2627                                                        TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2628                                                        g_free(tmpstr); tmpstr = NULL;
2629                                                        g_free(g_codec); g_codec = NULL;
2630                                                }
2631                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
2632                                                {
2633                                                        printf("Audio Lang: %s\n", g_lang);
2634                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
2635                                                        g_free(g_lang); g_lang = NULL;
2636                                                }
2637                                                gst_tag_list_free(tags);
2638                                        }
2639                                        else
2640                                        {
2641                                                printf("Audio Codec: %s\n", g_codec);
2642                                               
2643                                                tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
2644                                                tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
2645                                                if(g_codec != NULL && g_type != NULL)
2646                                                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
2647                                                tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
2648                                                if(g_codec != NULL && g_type != NULL)
2649                                                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
2650
2651                                                printf("Tracklist tmpstr: %s\n", tmpstr);                               
2652                                                TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2653
2654                                                g_free(tmpstr); tmpstr = NULL;
2655                                                g_free(g_codec); g_codec = NULL;
2656                                        }
2657                                }
2658                                break;
2659                        case 2:
2660                                for(i = 0; i < n_text; i++)
2661                                {
2662                                        GstTagList *tags = NULL;
2663                                        gchar *g_codec = NULL, *g_lang = NULL;
2664                                        GstPad* pad = 0;
2665                                        char* tmpstr = NULL;
2666
2667                                        g_signal_emit_by_name (pipeline, "get-text-pad", i, &pad);
2668                                        printf("SubTitle Type: %d\n", getSubtitleType(pad, g_codec));
2669
2670#if GST_VERSION_MAJOR < 1
2671                                        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
2672#else
2673                                        GstCaps* caps = gst_pad_get_current_caps(pad);
2674#endif
2675                                        if (!caps && !g_codec)
2676                                        {
2677                                                caps = gst_pad_get_allowed_caps(pad);
2678                                        }
2679                                               
2680                                        GstStructure* str = gst_caps_get_structure(caps, 0);
2681                                        const gchar *g_type = gst_structure_get_name(str);
2682
2683                                        g_signal_emit_by_name(pipeline, "get-text-tags", i, &tags);
2684                                       
2685#if GST_VERSION_MAJOR < 1
2686                                        if (tags && gst_is_tag_list(tags))
2687#else
2688                                        if (tags && GST_IS_TAG_LIST(tags))
2689#endif
2690                                        {
2691                                                if(gst_tag_list_get_string(tags, GST_TAG_SUBTITLE_CODEC, &g_codec))
2692                                                {
2693                                                        printf("SubTitle Codec: %s\n", g_codec);
2694                                                        tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
2695                                                        tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
2696                                                        if(g_codec != NULL && g_type != NULL)
2697                                                                tmpstr = ostrcat(tmpstr, " (", 1, 0);
2698                                                        tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
2699                                                        if(g_codec != NULL && g_type != NULL)
2700                                                                tmpstr = ostrcat(tmpstr, ")", 1, 0);
2701
2702                                                        printf("Tracklist tmpstr: %s\n", tmpstr);
2703                                                        TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2704                                                        g_free(g_codec); g_codec = NULL;
2705                                                }
2706                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
2707                                                {
2708                                                        printf("SubTitle Lang: %s\n", g_lang);
2709                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
2710                                                        g_free(g_lang); g_lang = NULL;
2711                                                }
2712                                                gst_tag_list_free(tags);
2713                                        }
2714                                        else
2715                                        {
2716                                                printf("SubTitle Codec: %s\n", g_codec);
2717                                               
2718                                                tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
2719                                                tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
2720                                                if(g_codec != NULL && g_type != NULL)
2721                                                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
2722                                                tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
2723                                                if(g_codec != NULL && g_type != NULL)
2724                                                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
2725
2726                                                printf("Tracklist tmpstr: %s\n", tmpstr);               
2727                                                TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
2728
2729                                                g_free(tmpstr); tmpstr = NULL;
2730                                                g_free(g_codec); g_codec = NULL;                               
2731                                        }
2732                                }
2733                                break;
2734                        default:
2735                                for(i = 0; i < n_video; i++)
2736                                {
2737                                        GstTagList *tags = NULL;
2738                                        gchar *g_codec = NULL, *g_lang = NULL;
2739                                       
2740                                        g_signal_emit_by_name(pipeline, "get-video-tags", i, &tags);
2741                                       
2742#if GST_VERSION_MAJOR < 1
2743                                        if (tags && gst_is_tag_list(tags))
2744#else
2745                                        if (tags && GST_IS_TAG_LIST(tags))
2746#endif
2747                                        {
2748                                                if(gst_tag_list_get_string(tags, GST_TAG_VIDEO_CODEC, &g_codec))
2749                                                {
2750                                                        printf("Video Codec: %s\n", g_codec);
2751                                                        TrackList[i * 2] = ostrcat(g_codec, NULL, 0, 0);
2752                                                        g_free(g_codec); g_codec = NULL;
2753                                                }
2754                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
2755                                                {
2756                                                        printf("Video Lang: %s\n", g_lang);
2757                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
2758                                                        g_free(g_lang); g_lang = NULL;
2759                                                }
2760                                                gst_tag_list_free(tags);
2761                                        }
2762                                }
2763                }
2764        }
2765#endif
2766//////////////////////////////NEUER CODE //////////////////////////////
2767
2768#ifdef EXTEPLAYER3
2769#ifdef EPLAYER3
2770        return TrackList2;
2771#else
2772        return TrackList;
2773#endif
2774#else
2775        return TrackList;
2776#endif
2777}
2778
2779//*CurTrackEncoding and *CurTrackName be freed
2780void playergetcurtrac(int type, int *CurTrackId, char** CurTrackEncoding, char** CurTrackName)
2781{
2782#ifdef EPLAYER3
2783        if(player && player->manager)
2784        {
2785                switch(type)
2786                {
2787                        case 1:
2788                                if(player->manager->audio)
2789                                {
2790                                        player->manager->audio->Command(player, MANAGER_GET, CurTrackId);
2791                                        player->manager->audio->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
2792                                        player->manager->audio->Command(player, MANAGER_GETNAME, CurTrackName);
2793                                }
2794                                break;
2795                        case 2:
2796                                if(player->manager->subtitle)
2797                                {
2798                                        player->manager->subtitle->Command(player, MANAGER_GET, CurTrackId);
2799                                        player->manager->subtitle->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
2800                                        player->manager->subtitle->Command(player, MANAGER_GETNAME, CurTrackName);
2801                                }
2802                                break;
2803                        default:
2804                                if(player->manager->video)
2805                                {
2806                                        player->manager->video->Command(player, MANAGER_GET, CurTrackId);
2807                                        player->manager->video->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
2808                                        player->manager->video->Command(player, MANAGER_GETNAME, CurTrackName);
2809                                }
2810                }
2811
2812                if(CurTrackId != NULL)
2813                        debug(150, "Current Track ID: %d", *CurTrackId);
2814                if(*CurTrackEncoding != NULL)
2815                        debug(150, "Current Track Enc: %s", *CurTrackEncoding);
2816                if(*CurTrackName != NULL)
2817                        debug(150, "Current Track Name: %s", *CurTrackName);
2818        }
2819#endif
2820
2821#ifdef EPLAYER4
2822        if(pipeline != NULL)
2823        {
2824                switch(type)
2825                {
2826                        case 1:
2827                                g_object_get(G_OBJECT(pipeline), "current-audio", CurTrackId, NULL);
2828                                break;
2829                        case 2:
2830                                if(subtitleflag == 0)
2831                                        *CurTrackId = -1;
2832                                else
2833                                        g_object_get(G_OBJECT(pipeline), "current-text", CurTrackId, NULL);
2834                                break;
2835                }
2836                if(CurTrackId != NULL) {
2837                        debug(150, "Current Track ID: %d", *CurTrackId);
2838                }
2839        }
2840#endif
2841}
2842
2843unsigned long long playergetpts2()
2844{
2845        int64_t pts = 0;
2846        int64_t sec = 0;
2847        sec = 0;
2848
2849#ifdef EPLAYER3
2850        if(player && player->playback)
2851        {
2852                player->playback->Command(player, PLAYBACK_PTS, &pts);
2853                sec = pts / 90000;
2854                fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90);
2855
2856                debug(150, "Pts = %02d:%02d:%02d (%lld sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
2857
2858        }
2859#endif
2860
2861        if(pts < 0) pts = 0;
2862        return pts;
2863}
2864
2865unsigned long long playergetpts()
2866{
2867#ifdef EXTEPLAYER3
2868#ifdef EPLAYER3
2869        int64_t pts = 0;
2870        int64_t sec = 0;
2871#else
2872        unsigned long long pts = 0;
2873        unsigned long long sec = 0;
2874#endif
2875#else
2876        unsigned long long pts = 0;
2877        unsigned long long sec = 0;
2878#endif
2879
2880#ifdef EPLAYER3
2881        if(player && player->playback)
2882        {
2883                player->playback->Command(player, PLAYBACK_PTS, &pts);
2884                sec = pts / 90000;
2885#ifdef EXTEPLAYER3
2886                debug(150, "Pts = %02d:%02d:%02d (%lld sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
2887#else
2888                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
2889#endif
2890        }
2891#endif
2892
2893#ifdef EPLAYER4
2894        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
2895       
2896/*
2897        if(pipeline)
2898        {
2899#if GST_VERSION_MAJOR < 1
2900                gst_element_query_position(pipeline, &fmt, (gint64*)&pts);
2901#else
2902                gst_element_query_position(pipeline, fmt, (gint64*)&pts);
2903#endif
2904                sec = pts / 1000000000;
2905                pts = sec * 90000;
2906                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
2907        }
2908*/
2909
2910        if(pipeline)
2911        {
2912                gint64 pos;
2913                GstElement *sink;
2914                pts = 0;
2915
2916                g_object_get(G_OBJECT (pipeline), "audio-sink", &sink, NULL);
2917
2918                if(!sink) g_object_get (G_OBJECT (pipeline), "video-sink", &sink, NULL);
2919                if(!sink) return 0;
2920
2921                gchar *name = gst_element_get_name(sink);
2922                gboolean use_get_decoder_time = ostrstr(name, "dvbaudiosink") || ostrstr(name, "dvbvideosink");
2923                g_free(name);
2924
2925                if(use_get_decoder_time) g_signal_emit_by_name(sink, "get-decoder-time", &pos);
2926
2927                gst_object_unref(sink);
2928
2929#if GST_VERSION_MAJOR < 1
2930                if(!use_get_decoder_time && !gst_element_query_position(pipeline, &fmt, &pos))
2931#else
2932                if(!use_get_decoder_time && !gst_element_query_position(pipeline, fmt, &pos))
2933#endif
2934                        return 0;
2935
2936                /* pos is in nanoseconds. we have 90 000 pts per second. */
2937                pts = pos / 11111;
2938                pts = pts - m_gst_startpts;
2939                sec = pts / 90000;
2940                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);
2941        }
2942#endif
2943
2944        if(pts < 0) pts = 0;
2945        return pts;
2946}
2947
2948double playergetlength2()
2949{
2950        int64_t length = 0;
2951
2952#ifdef EPLAYER3
2953        if(player && player->playback)
2954        {
2955                player->playback->Command(player, PLAYBACK_LENGTH, (void*)&length);
2956                if(length < 0) length = 0;
2957                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
2958                debug(150, "Length2 = %02d:%02d:%02d (%lld sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
2959
2960                fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld}}\n", length);
2961
2962        }
2963#endif
2964
2965        return length;
2966}
2967
2968double playergetlength()
2969{
2970#ifdef EXTEPLAYER3
2971#ifdef EPLAYER3
2972        int64_t length = 0;
2973#else
2974        double length = 0;
2975#endif
2976#else
2977        double length = 0;
2978#endif
2979
2980#ifdef EPLAYER3
2981        if(player && player->playback)
2982        {
2983                player->playback->Command(player, PLAYBACK_LENGTH, &length);
2984                if(length < 0) length = 0;
2985#ifdef EXTEPLAYER3
2986                debug(150, "Length = %02d:%02d:%02d (%lld sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
2987#else
2988                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
2989#endif
2990        }
2991#endif
2992
2993#ifdef EPLAYER4
2994        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
2995        gint64 len;
2996
2997        if(pipeline)
2998        {
2999#if GST_VERSION_MAJOR < 1
3000                gst_element_query_duration(pipeline, &fmt, &len);
3001#else
3002                gst_element_query_duration(pipeline, fmt, &len);
3003#endif
3004                length = len / 1000000000;
3005                if(length < 0) length = 0;
3006                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
3007        }
3008#endif
3009
3010        return length;
3011}
3012
3013char* playergetinfo(char* tag)
3014{
3015        char* ret = NULL;
3016
3017#ifdef EPLAYER3
3018        char *tags[] = {"Title", "Artist", "Album", "Year", "Genre", "Comment", "Track", "Copyright", "TestLibEplayer", NULL};
3019        int i = 0;
3020
3021        if(player && player->playback)
3022        {
3023                while(tags[i] != NULL)
3024                {
3025                        ret = tags[i];
3026                        if(ostrcmp(tag, ret) == 0)
3027                        {
3028                                player->playback->Command(player, PLAYBACK_INFO, &ret);
3029                                break;
3030                        }
3031
3032                        i++;
3033                }
3034        }
3035#endif
3036        return ret;
3037}
3038
3039void playerchangeaudiotrack(int num)
3040{
3041        debug(150, "change audiotrac to %d\n", num);
3042
3043#ifdef EPLAYER3
3044        if(player && player->playback)
3045                player->playback->Command(player, PLAYBACK_SWITCH_AUDIO, (void*)&num);
3046#endif
3047
3048#ifdef EPLAYER4
3049        if(pipeline != NULL)
3050                g_object_set(G_OBJECT(pipeline), "current-audio", num, NULL);   
3051#endif
3052}
3053
3054void playerchangesubtitletrack(int num)
3055{
3056#ifdef EPLAYER3
3057        if(player && player->playback)
3058                player->playback->Command(player, PLAYBACK_SWITCH_SUBTITLE, (void*)&num);
3059#endif
3060
3061#ifdef EPLAYER4
3062        printf("player: set subtitle: %d\n", num);
3063        if(pipeline != NULL)
3064                g_object_set(G_OBJECT(pipeline), "current-text", num, NULL);
3065        subtitleflag = 1;       
3066#endif
3067}
3068
3069void playerstopsubtitletrack()
3070{
3071#ifdef EPLAYER3
3072        if(player && player->output && player->output->subtitle)
3073                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_STOP, NULL);
3074#ifndef EXTEPLAYER3
3075        if(player && player->container && player->container->assContainer)
3076        {
3077                player->container->assContainer->Command(player, CONTAINER_STOP, NULL);
3078                player->container->assContainer->Command(player, CONTAINER_INIT, NULL);
3079        }
3080        if(player && player->manager && player->manager->subtitle)
3081        {
3082                int onlycurrent = 1;
3083                player->manager->subtitle->Command(player, MANAGER_DEL, (void*)&onlycurrent);
3084        }
3085#endif
3086#endif
3087
3088#ifdef EPLAYER4
3089        printf("player: stop subtitle\n");
3090        subtitleflag = 0;
3091        //if(pipeline != NULL)
3092        //      g_object_set(G_OBJECT(pipeline), "current-text", -1, NULL);
3093        if(subtitlethread != NULL)
3094                subtitlethread->aktion = STOP;
3095#endif
3096}
3097
3098int playerjumpts(struct service* servicenode, int sekunden, int *startpts, off64_t *poslastpts, off64_t *bitrate, int vpid, int tssize)
3099{
3100        int adaptation = 0;
3101        int payload = 0;
3102        int pes = 0;
3103        int tspid = 0;
3104       
3105        off64_t pts  = 0;
3106        uint64_t aktpts = 0;
3107        long long unsigned int lenpts = 0;
3108        long long unsigned int startpts1 = 0;
3109        long long unsigned int endpts = 0;
3110        long long unsigned int aktbitrate = 0;
3111        off64_t ziehlpts = 0;
3112
3113        off64_t curpos = 0;
3114        off64_t newpos = 0;
3115        off64_t jump = 0;
3116
3117        int kleiner = 0;
3118        int groesser = 0;
3119        int gleich = 0;
3120        int len = 0;
3121        int i = 0;
3122        int ret = 0;
3123
3124        if(servicenode == NULL) return -1;
3125
3126        int buflen = tssize * 15000;
3127        char *buf = malloc(buflen);
3128        if(buf == NULL)
3129                return -1;
3130       
3131        curpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);   
3132        int dupfd = open(servicenode->recname, O_RDONLY | O_LARGEFILE);
3133        newpos = lseek64(dupfd, curpos, SEEK_SET);
3134       
3135        if (*startpts == 0)
3136        {
3137                if(videogetpts(status.aktservice->videodev, &aktpts) == 0)
3138                {
3139                                ziehlpts = (aktpts / 90000) + sekunden;
3140                }
3141                else
3142                        return 1;
3143        }
3144        else
3145        {
3146                ziehlpts = *startpts + sekunden;
3147        }
3148        *startpts = ziehlpts;
3149
3150        if(*bitrate == 0)
3151        {
3152                lenpts = servicenode->lenpts;
3153                startpts1 = servicenode->startpts;
3154                endpts = servicenode->endpts;
3155                aktbitrate = servicenode->bitrate;
3156                ret = gettsinfo(dupfd, &lenpts, &startpts1, &endpts, &aktbitrate, servicenode->tssize);
3157                if(ret != 0)
3158                {
3159                        err("can't read ts info");
3160                }
3161                else
3162                        *bitrate = aktbitrate;
3163                newpos = lseek64(dupfd, curpos, SEEK_SET);
3164        }
3165        else
3166                aktbitrate = *bitrate;
3167               
3168        if(*poslastpts == 0)
3169                *poslastpts = curpos;
3170       
3171        if(sekunden > 0)
3172        {
3173                err("not implemented");
3174                return 1;
3175        }       
3176        else if(sekunden < 0)
3177        {
3178                sekunden = sekunden * -1;
3179                if(aktbitrate != 0)
3180                {
3181                        jump = (aktbitrate / 8) * sekunden;
3182                        jump = jump + (curpos - *poslastpts);
3183                        jump = jump + (jump % servicenode->tssize);
3184                        newpos = lseek64(dupfd, -jump, SEEK_CUR);
3185                }
3186                else
3187                        newpos = lseek64(dupfd, - buflen, SEEK_CUR);
3188                if(newpos < 0)
3189                        newpos = lseek64(dupfd, tssize, SEEK_SET);
3190        }
3191        len = read(dupfd, buf, buflen);
3192        for(i = 0; i < len; i = i + 1)
3193        {
3194                if (buf[i] == 0x47 && buf[i+tssize] == 0x47)
3195                {
3196                        newpos = lseek64(dupfd, newpos + i, SEEK_SET);
3197                        break;
3198                }
3199        }
3200        if(i >= len)
3201        {
3202                newpos = lseek64(dupfd, curpos, SEEK_SET);     
3203                return 1;
3204        }
3205        while(1)
3206        {
3207        len = read(dupfd, buf, buflen);
3208
3209                if(len > 0)
3210                {
3211                        for(i = 0; i <= len-tssize; i = i + tssize)
3212                        {
3213                                payload = 0;
3214
3215                                tspid = (buf[i+1] & 0x1F) << 8;
3216                                tspid = tspid + (buf[i+2] & 0xFF);
3217                                pes = buf[i+1] & 0x40;
3218
3219                                if(tspid == vpid)
3220                                {       
3221                                        adaptation = buf[i+3] & 0x30;
3222                                        if(adaptation == 16)
3223                                        {
3224                                                payload = 4;
3225                                        }
3226                                        if(adaptation == 32)
3227                                        {
3228                                                //printf("adaptation field only\n");
3229                                        }
3230                                        if(adaptation == 48)
3231                                        {
3232                                                payload = buf[i+4] & 0xFF;
3233                                                payload = payload + 5;
3234                                        }
3235                                        if(payload != 0)
3236                                        {
3237                                                if(pes == 64)
3238                                                {
3239                                                        if(buf[i+payload+7] & 0x80) //PTS
3240                                                        {
3241                                                                pts = ((unsigned long long)(buf[i+payload+9] & 0xE)) << 29;
3242                                                                pts |= ((unsigned long long)(buf[i+payload+10] & 0xFF)) << 22;
3243                                                                pts |= ((unsigned long long)(buf[i+payload+11] & 0xFE)) << 14;
3244                                                                pts |= ((unsigned long long)(buf[i+payload+12] & 0xFF)) << 7;
3245                                                                pts |= ((unsigned long long)(buf[i+payload+13] & 0xFE)) >> 1;
3246                                                               
3247                                                                if(pts / 90000 == ziehlpts)
3248                                                                {
3249                                                                        gleich = newpos + i;
3250                                                                        break;
3251                                                                }
3252                                                                else if(pts / 90000 > ziehlpts)
3253                                                                {                                                                       
3254                                                                        groesser = newpos + i;
3255                                                                        break;
3256                                                                }
3257                                                                else
3258                                                                {
3259                                                                        kleiner = newpos + i;
3260                                                                }
3261                                                        }
3262                                                }
3263                                        }
3264                                }
3265                        }
3266                        if(gleich != 0)
3267                        {
3268                                close(dupfd);
3269                                free(buf);buf = NULL;
3270                                *poslastpts = lseek64(servicenode->recsrcfd, gleich, SEEK_SET);
3271                                return 0;
3272                        }
3273                        else if(groesser != 0 && kleiner != 0)
3274                        {
3275                                close(dupfd);
3276                                free(buf);buf = NULL;
3277                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
3278                                return 0;
3279                        }
3280                        else if(groesser != 0)
3281                        {
3282                                if((newpos - buflen)  < 0)
3283                                {
3284                                        close(dupfd);
3285                                        free(buf);buf = NULL;
3286                                        *poslastpts = 0;
3287                                        return -1       ;
3288                                }
3289                                else
3290                                {
3291                                        newpos = lseek64(dupfd, -(buflen * 2), SEEK_CUR);
3292                                }
3293                        }
3294                }
3295                else
3296                {
3297                        if(kleiner == 0)
3298                        {
3299                                close(dupfd);
3300                                free(buf);buf = NULL;
3301                                newpos = lseek64(servicenode->recsrcfd, curpos, SEEK_SET);
3302                                *poslastpts = 0;
3303                                return -1;
3304                        }
3305                        else
3306                        {
3307                                close(dupfd);
3308                                free(buf);buf = NULL;
3309                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
3310                                return 0;
3311                        }
3312                }
3313        }
3314}
3315
3316//praez = 1 .... sekunden
3317//                      =       2 .... zehntel
3318//                      = 3 .... hundertstel
3319//                      = 4 .... volle Uebereinstimmung
3320//
3321//type  = 0 .... alle
3322//                      = 1 .... nur PCR
3323//                      = 2 .... nur Video
3324//                      = 3 .... nur Audio
3325//
3326//flag = 0 --> play ts
3327//flag = 1 --> timeshift
3328//flag = 2 --> timeshift, not in play mode (only recording)
3329//flag = 9 --> dataset mode
3330//
3331off64_t playergetptspos(unsigned long long fpts, off64_t pos, int dir, int praez, int type, int flag, char* dsn)
3332{
3333        unsigned long long pts;
3334        int ret = 0, dupfd = -1, left = 0, tssize = 0, recbsize = 0;
3335        unsigned char* buf = NULL;
3336        unsigned char *payload;
3337        int pid = 0, pusi = 0;
3338        unsigned char* packet;
3339        struct service* snode;
3340       
3341        if(type > 3)
3342        {
3343                printf("type %i nicht unterstützt\n", type);
3344                return -1;
3345        }
3346       
3347        if(flag == 2)
3348                snode = getservice(RECORDTIMESHIFT, 0);
3349        else if(flag != 9)
3350                snode = getservice(RECORDPLAY, 0);
3351               
3352        if(flag == 9)
3353        {
3354                tssize = 188;
3355                recbsize = tssize * 1024 * 10;
3356                dupfd = open(dsn, O_RDONLY | O_LARGEFILE );
3357        }
3358        else
3359        {
3360                tssize = snode->tssize;
3361                recbsize = snode->tssize * 1024 * 10;
3362                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
3363        }
3364
3365        if(dupfd < 0)
3366        {
3367                err("copy source fd not ok");
3368                return -1;
3369        }
3370
3371        buf = malloc(recbsize);
3372        if(buf == NULL)
3373        {
3374                err("no mem");
3375                return -1;
3376        }
3377        packet = buf;
3378        if(dir > 0) 
3379                pos = lseek64(dupfd, pos, SEEK_SET);
3380        else
3381                pos = lseek64(dupfd, pos - recbsize, SEEK_SET);
3382       
3383        ret = read(dupfd,  buf, recbsize);
3384        close(dupfd);
3385        left = 0;
3386       
3387        if(buf[0] != 0x47)
3388        {
3389                while(left < tssize)
3390                {
3391                        if(buf[left] == 0x47) break;
3392                        left++;
3393                }
3394                if(left >= tssize)
3395                {
3396                        free(buf);
3397                        return -1;
3398                }       
3399        }
3400        pts = 0;
3401        while(left <= recbsize - tssize)
3402        {
3403                if(pts != 0)
3404                {
3405                        switch( praez )
3406          {
3407        case 1 :        if(fpts / 90000 != pts / 90000)
3408                                                        pts = 0;
3409                                                break;
3410        case 2 :        if(fpts / 9000 != pts / 9000)
3411                                                        pts = 0;
3412                                                break;
3413        case 3 :        if(fpts / 900 != pts / 900)
3414                                                        pts = 0;
3415                                                break;         
3416        case 4 :        if(fpts != pts )
3417                                                        pts = 0;
3418                                                break;
3419                                default :       free(buf); return -1; break;
3420                        }
3421                        if(pts != 0)
3422                        {       
3423                                pos = pos + left - tssize;
3424                                free(buf);
3425                                return pos;
3426                        }
3427                }
3428                packet = buf + left;
3429                left = left + tssize;
3430                                               
3431                pid = ((packet[1] << 8) | packet[2]) & 0x1FFF;
3432                pusi = !!(packet[1] & 0x40);
3433                //check for adaption field
3434                if(packet[3] & 0x20)
3435                {
3436                        if(type > 1)continue;
3437                        if(packet[4] >= 183) continue;
3438                        if(packet[4])
3439                        {
3440                                if(packet[5] & 0x10) //PCR present
3441                                {
3442                                        pts = ((unsigned long long)(packet[6] & 0xFF)) << 25;
3443                                        pts |= ((unsigned long long)(packet[7] & 0xFF)) << 17;
3444                                        pts |= ((unsigned long long)(packet[8] & 0xFE)) << 9;
3445                                        pts |= ((unsigned long long)(packet[9] & 0xFF)) << 1;
3446                                        pts |= ((unsigned long long)(packet[10] & 0x80)) >> 7;
3447                                        continue;
3448                                }
3449                        }
3450                        payload = packet + packet[4] + 4 + 1;
3451                } else
3452                        payload = packet + 4;
3453               
3454                if(type == 1) continue;
3455                if(!pusi) continue;
3456               
3457                if (payload[0] || payload[1] || (payload[2] != 1))
3458                        continue;
3459               
3460                        //stream use extension mechanism def in ISO 13818-1 Amendment 2
3461                if(payload[3] == 0xFD)
3462                {
3463                        if(payload[7] & 1) //PES extension flag
3464                        {
3465                                int offs = 0;
3466                                if(payload[7] & 0x80) offs += 5; //pts avail
3467                                if(payload[7] & 0x40) offs += 5; //dts avail
3468                                if(payload[7] & 0x20) offs += 6; //escr avail
3469                                if(payload[7] & 0x10) offs += 3; //es rate
3470                                if(payload[7] & 0x8) offs += 1; //dsm trickmode
3471                                if(payload[7] & 0x4) offs += 1; //additional copy info
3472                                if(payload[7] & 0x2) offs += 2; //crc
3473                                if(payload[8] < offs) continue;
3474
3475                                uint8_t pef = payload[9 + offs++]; //pes extension field
3476                                if(pef & 1) //pes extension flag 2
3477                                {
3478                                        if(pef & 0x80) offs += 16; //private data flag
3479                                        if(pef & 0x40) offs += 1; //pack header field flag
3480                                        if(pef & 0x20) offs += 2; //program packet sequence counter flag
3481                                        if(pef & 0x10) offs += 2; //P-STD buffer flag
3482                                        if(payload[8] < offs) continue;
3483
3484                                        uint8_t stream_id_extension_len = payload[9 + offs++] & 0x7F;
3485                                        if(stream_id_extension_len >= 1)
3486                                        {
3487                                                if(payload[8] < (offs + stream_id_extension_len)) continue;
3488                                                //stream_id_extension_bit (should not set)
3489                                                if(payload[9 + offs] & 0x80) continue;
3490                                                switch(payload[9 + offs])
3491                                                {
3492                                                        case 0x55 ... 0x5f: break; //VC-1
3493                                                        case 0x71: break; //AC3 / DTS
3494                                                        case 0x72: break; //DTS - HD
3495                                                        default:
3496                                                                printf("skip unknwn stream_id_extension %02x\n", payload[9 + offs]);
3497                                                                continue;
3498                                                }
3499                                        }
3500                                        else
3501                                                continue;
3502                                }
3503                                else
3504                                        continue;
3505                        }
3506                        else
3507                                continue;
3508                }
3509                //drop non-audio, non-video packets because other streams
3510                //can be non-compliant.
3511                //0xC0 = audio, 0xE0 = video
3512                else if(((payload[3] & 0xE0) != 0xC0) && ((payload[3] & 0xF0) != 0xE0))
3513                        continue;
3514
3515                if((payload[7] & 0x80) && ((payload[3] & 0xF0) != 0xE0) && (type == 0 || type == 2)) //PTS video
3516                {
3517                        pts = ((unsigned long long)(payload[9] & 0xE)) << 29;
3518                        pts |= ((unsigned long long)(payload[10] & 0xFF)) << 22;
3519                        pts |= ((unsigned long long)(payload[11] & 0xFE)) << 14;
3520                        pts |= ((unsigned long long)(payload[12] & 0xFF)) << 7;
3521                        pts |= ((unsigned long long)(payload[13] & 0xFE)) >> 1;
3522                        continue;
3523                }
3524                if((payload[7] & 0x80) && ((payload[3] & 0xE0) != 0xC0) && (type == 0 || type == 3)) //PTS audio
3525                {
3526                        pts = ((unsigned long long)(payload[9] & 0xE)) << 29;
3527                        pts |= ((unsigned long long)(payload[10] & 0xFF)) << 22;
3528                        pts |= ((unsigned long long)(payload[11] & 0xFE)) << 14;
3529                        pts |= ((unsigned long long)(payload[12] & 0xFF)) << 7;
3530                        pts |= ((unsigned long long)(payload[13] & 0xFE)) >> 1;
3531                        continue;
3532                }
3533        }
3534        free(buf);
3535        return recbsize * -1;
3536}
3537
3538#ifdef EPLAYER4
3539/* Extract some metadata from the streams and print it on the screen */
3540static void analyze_streams(CustomData *data)
3541{
3542        gint i;
3543        GstTagList *tags;
3544        gchar *str;
3545        guint rate;
3546
3547        /* Read some properties */
3548        g_object_get(pipeline, "n-video", &data->n_video, NULL);
3549        g_object_get(pipeline, "n-audio", &data->n_audio, NULL);
3550        g_object_get(pipeline, "n-text", &data->n_text, NULL);
3551
3552        g_print("%d video stream(s), %d audio stream(s), %d text stream(s)\n", data->n_video, data->n_audio, data->n_text);
3553
3554        g_print ("\n");
3555        for(i = 0; i < data->n_video; i++)
3556        {
3557                tags = NULL;
3558                /* Retrieve the stream's video tags */
3559                g_signal_emit_by_name(pipeline, "get-video-tags", i, &tags);
3560                if(tags)
3561                {
3562                        g_print("video stream %d:\n", i);
3563                        gst_tag_list_get_string(tags, GST_TAG_VIDEO_CODEC, &str);
3564                        g_print("  codec: %s\n", str ? str : "unknown");
3565                        g_free(str);
3566                        gst_tag_list_free(tags);
3567                }
3568        }
3569
3570        g_print("\n");
3571        for(i = 0; i < data->n_audio; i++)
3572        {
3573                tags = NULL;
3574                g_signal_emit_by_name(pipeline, "get-audio-tags", i, &tags);
3575                if(tags)
3576                {
3577                        /* Retrieve the stream's audio tags */
3578                        g_print("audio stream %d:\n", i);
3579                        if(gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str))
3580                        {
3581                                g_print("  codec: %s\n", str);
3582                                g_free(str);
3583                        }
3584                        if(gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str))
3585                        {
3586                                g_print("  language: %s\n", str);
3587                                g_free(str);
3588                        }
3589                        if(gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate))
3590                        {
3591                                g_print("  bitrate: %d\n", rate);
3592                        }
3593                        gst_tag_list_free(tags);
3594                }
3595        }
3596
3597        g_print("\n");
3598        for(i = 0; i < data->n_text; i++)
3599        {
3600                tags = NULL;
3601                /* Retrieve the stream's subtitle tags */
3602                g_print("subtitle stream %d:\n", i);
3603                g_signal_emit_by_name(pipeline, "get-text-tags", i, &tags);
3604                if(tags)
3605                {
3606                        if(gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str))
3607                        {
3608                                g_print("  language: %s\n", str);
3609                                g_free(str);
3610                        }
3611                        gst_tag_list_free(tags);
3612                }
3613                else
3614                {
3615                        g_print("  no tags found\n");
3616                }
3617        }
3618
3619        g_object_get(pipeline, "current-video", &data->current_video, NULL);
3620        g_object_get(pipeline, "current-audio", &data->current_audio, NULL);
3621        g_object_get(pipeline, "current-text", &data->current_text, NULL);
3622
3623        g_print("\n");
3624        g_print("Currently playing video stream %d, audio stream %d and subtitle stream %d\n", data->current_video, data->current_audio, data->current_text);
3625        g_print("Type any number and hit ENTER to select a different subtitle stream\n");
3626}
3627#endif
3628
3629#ifdef EPLAYER4
3630void playersend_ff_fr_event(gdouble rate) {
3631        gint64 position;
3632        GstFormat format = GST_FORMAT_TIME;
3633        GstEvent *seek_event;
3634   
3635        /* Obtain the current position, needed for the seek event */
3636#if GST_VERSION_MAJOR < 1
3637        if (!gst_element_query_position (pipeline, &format, &position)) {
3638#else
3639        if (!gst_element_query_position (pipeline, format, &position)) {
3640#endif
3641                g_printerr ("Unable to retrieve current position.\n");
3642                return;
3643        }
3644   
3645        /* Create the seek event */
3646        if (rate > 0)
3647        {       
3648                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);
3649  }
3650        else
3651        {
3652                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);
3653        }
3654   
3655        if (video_sink == NULL) {
3656                /* If we have not done so, obtain the sink through which we will send the seek events */
3657                g_object_get (pipeline, "video-sink", &video_sink, NULL);
3658        }
3659   
3660        /* Send the event */
3661        gst_element_send_event (video_sink, seek_event);
3662   
3663        g_print ("Current rate: %g\n", rate);
3664}
3665#endif
3666
3667char* getsubtext()
3668{
3669        char* tmpstr = NULL;
3670        if(player && player->container && player->container->selectedContainer)
3671                player->container->selectedContainer->Command(player, CONTAINER_GET_SUBTEXT, (void*)&tmpstr);
3672
3673
3674//duration = oregex(".*([0-9]{8,8}.*[0-9]{4,4}).*", subtext);
3675//duration = oregex(".*duration=(.*);.*", subtext);
3676
3677char* duration = oregex(".*duration=(.*);pts=.*", tmpstr);
3678printf("[TITAN/getsubtext] duration %s\n", duration);
3679if(duration != NULL)
3680{
3681        printf("[TITAN/getsubtext] duration %d\n", atoi(duration));
3682        duration_ms = atoi(duration);
3683}
3684
3685char* pts = oregex(".*;pts=(.*);trackid=.*", tmpstr);
3686printf("[TITAN/getsubtext] pts %s\n", pts);
3687if(pts != NULL)
3688        printf("[TITAN/getsubtext] pts %d\n", atoi(pts));
3689
3690char* trackid = oregex(".*;trackid=(.*);trackid=.*", tmpstr);
3691printf("[TITAN/getsubtext] trackid %s\n", trackid);
3692if(trackid != NULL)
3693        printf("[TITAN/getsubtext] trackid %d\n", atoi(trackid));
3694
3695subtext = oregex(".*;subtext=(.*).*", tmpstr);
3696printf("[TITAN/getsubtext] subtext %s\n", subtext);
3697
3698        if(subtitlethread == NULL)
3699                subtitlethread = addtimer(&playersubtitle_thread, START, 10000, 1, NULL, NULL, NULL);
3700
3701
3702/*
3703duration=
3704duration=", ollutoa(tmpduration), 0, 1);
3705tmpstr = ostrcat(tmpstr, ";pts=", 1, 0);;
3706tmpstr = ostrcat(tmpstr, ollutoa(tmppts), 1, 0);;
3707tmpstr = ostrcat(tmpstr, ";trackid=", 1, 0);;
3708tmpstr = ostrcat(tmpstr, ollutoa(tmptrackId), 1, 0);
3709tmpstr = ostrcat(tmpstr, ";subtext=", 1, 0);;
3710tmpstr = ostrcat(tmpstr, subtext, 1, 0);
3711
3712        running_pts = pos / 11111LL;
3713        decoder_ms = running_pts / 90;
3714               
3715        if(subtitlethread == NULL)
3716                subtitlethread = addtimer(&playersubtitle_thread, START, 10000, 1, NULL, NULL, NULL);
3717
3718*/
3719/*
3720        SubtitleOut_t *data;
3721printf("[TITAN/getsubtext start]\n");
3722        if(player && player->container && player->container->selectedContainer)
3723//              player->container->selectedContainer->Command(player, CONTAINER_GET_SUBTEXT, (void*)&data);
3724                player->container->selectedContainer->Command(player, CONTAINER_GET_SUBTEXT, (void*)data);
3725
3726   if (data == NULL)
3727        return NULL;
3728printf("[TITAN/getsubtext] 2\n");
3729
3730printf("data.data: %s\n", &data->data);
3731
3732printf("data.data: %s\n", data->data);
3733printf("data.pts: %lld\n", data->pts);
3734printf("data.duration: %lld\n", data->durationMS);
3735
3736SubtitleOut_t *data;
3737printf("111111111111111\n");
3738
3739
3740        if(player && player->container && player->container->selectedContainer)
3741                player->container->selectedContainer->Command(player, CONTAINER_GET_SUBTEXT, (void*)data);
3742//              player->container->selectedContainer->Command(player, CONTAINER_GET_SUBTEXT, (void*)data);
3743
3744printf("222222222222222\n");
3745
3746   if (data == NULL)
3747        return NULL;
3748printf("-------------------------------------\n");
3749
3750printf("titan &data.data %s\n", (char*)&data->data);
3751
3752SubtitleOut_t *out  = NULL;
3753printf("333333333333333\n");
3754
3755out = (SubtitleOut_t*) data;
3756printf("444444444444444\n");
3757
3758printf("out.duration: %lld\n", out->durationMS);
3759printf("555555555555555\n");
3760*/
3761/*
3762printf(out->pts);
3763printf("444444444444444\n");
3764
3765printf(out->data);
3766printf("444444444444444\n");
3767
3768
3769printf("out.pts: %u\n", out->pts);
3770printf("out1.data: %u\n", out->data);
3771printf("out2.data: %d\n", out->data);
3772
3773
3774char *Encoding      = NULL;
3775printf("Encoding:%s Text:%s Len:%d\n", Encoding, (char*) out->data, out->len);
3776printf("555555555555555\n");
3777printf("-------------------------------------\n");
3778
3779printf("data.pts: %lld\n", data->pts);
3780printf("data.durationMS: %lld\n", data->durationMS);
3781printf("data1: %lld\n", data->data);
3782printf("data2: %d\n", data->data);
3783printf("data3: %s\n", data->data);
3784printf("data4: %s\n", (char*)data->data);
3785printf("data5: %s\n", (char*)data->data);
3786printf("-------------------------------------\n");
3787
3788*/
3789/*
3790        struct skin* framebuffer = getscreen("framebuffer");
3791        struct skin* subtitle = getscreen("gstsubtitle");
3792
3793//      changetext(subtitle, (char*) data->data);
3794        changetext(subtitle, subtext);
3795        drawscreen(subtitle, 0, 0);
3796*/
3797        return subtext;
3798}
3799
Note: See TracBrowser for help on using the repository browser.