source: titan/titan/player.h @ 44558

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

fix seek

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