source: titan/titan/player.h @ 39988

Last change on this file since 39988 was 39878, checked in by obi, 7 years ago

disable sh4 subs update server

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