source: titan/titan/player.h @ 40368

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

mipsel test fix eplayer3 slowm ff fr

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