source: titan/titan/player.h @ 40896

Last change on this file since 40896 was 40896, checked in by obi, 4 years ago

disable dtsdownmix only on ARM

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