source: titan/titan/player.h @ 44554

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

test old player

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