source: titan/titan/player.h @ 44525

Last change on this file since 44525 was 44525, checked in by gost, 3 years ago

test seek

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