source: titan/titan/player.h @ 44398

Last change on this file since 44398 was 44398, checked in by gost, 4 years ago

next test ff multibox

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