source: titan/titan/player.h @ 44978

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

exteplayer3 enable fast forward

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