source: titan/titan/player.h @ 44520

Last change on this file since 44520 was 44520, checked in by obi, 3 years ago

fix building

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