source: titan/titan/player.h @ 24223

Last change on this file since 24223 was 24101, checked in by nit, 10 years ago

fix

File size: 36.1 KB
Line 
1#ifndef PLAYER_H
2#define PLAYER_H
3
4// playercan bits:
5// 0 policy
6// 1 auditraklist
7// 2 subtitle
8// 3 videomode
9// 4 powerofftimer
10// 5 videosettings
11// 6 stop
12// 7 ff
13// 8 fr
14// 9 pause
15// 10 play
16// 11 jump/seek reverse
17// 12 jump/seek forward
18// 13 changecodec
19// 14 infobar
20// 15 slowmotion
21
22#ifdef EPLAYER3
23Context_t * player = NULL;
24extern OutputHandler_t OutputHandler;
25extern PlaybackHandler_t PlaybackHandler;
26extern ContainerHandler_t ContainerHandler;
27extern ManagerHandler_t ManagerHandler;
28#endif
29
30#ifdef EPLAYER4
31GstElement *m_gst_playbin = NULL;
32unsigned long long m_gst_startpts = 0;
33#endif
34
35//titan player
36
37//flag 0: from play
38//flag 1: from timeshift
39//flag 2: from playrcjumpr
40int playerstartts(char* file, int flag)
41{
42        int fd = -1, ret = 0, tssize = 188;
43        int16_t pmtpid = 0;
44        int serviceid = 0;
45        int supermagic = -1;
46        struct channel* chnode = NULL;
47        struct service* snode = NULL;
48        struct dvbdev* fenode = NULL;
49        struct dvbdev* dvrnode = NULL;
50
51        //supermagic = getsupermagic(file);
52
53        if(supermagic == NFS_SUPER_MAGIC || supermagic == SMB_SUPER_MAGIC)
54        {
55                debug(150, "use O_DIRECT to open file %s", file);
56                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK | O_DIRECT);
57        }
58        else
59                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK);
60
61        if(fd < 0)
62        {
63                perr("open player file");
64                return 1;
65        }
66
67        fenode = fegetdummy();
68        dvrnode = dvropen(fenode);
69        if(dvrnode == NULL)
70        {
71                err("find dvr dev");
72                close(fd);
73                return 1;
74        }
75
76        if(flag == 0 || flag == 2)
77        {
78                //TODO: funktion to get tssize from file content
79                if(cmpfilenameext(file, ".mts") == 0) tssize = 192;
80                if(cmpfilenameext(file, ".m2ts") == 0) tssize = 192;
81               
82                ret = dvbfindpmtpid(fd, &pmtpid, &serviceid, tssize);
83                if(ret == 1)
84                {
85                        err("find sid/pmt pid");
86                        close(fd);
87                        dvrclose(dvrnode, -1);
88                        return 1;
89                }
90               
91                if(flag == 0 && getconfigint("showlastpos", NULL) == 1)
92                {
93                        char* fileseek = changefilenameext(file, ".se");
94                        FILE* fbseek = fopen(fileseek, "r");
95                        if(fbseek != NULL)
96                        {
97                                ret = textbox(_("Message"), _("Start at last position ?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 10, 0);
98                                if(ret == 0 || ret == 1)
99                                {
100                                        char* skip1 = calloc(1, 20);
101                                        if(skip1 != NULL)
102                                        {
103                                                fscanf(fbseek, "%s", skip1);
104                                                off64_t seekpos = atoll(skip1);
105                                                seekpos = seekpos - (seekpos % tssize);
106                                                lseek64(fd, atoll(skip1), SEEK_SET);
107                                        }
108                                        free(skip1); skip1 = NULL;
109                                }
110                                fclose(fbseek);
111                        }
112                        free(fileseek); fileseek = NULL;
113                }       
114               
115                if(flag == 0)
116                {
117                        delmarkernode(-1);
118                        char* filemarker = changefilenameext(file, ".ma");
119                        getmarker(filemarker);
120                        free(filemarker); filemarker=NULL;
121                }
122               
123                delchannel(serviceid, 0, 1);
124                chnode = createchannel("player", 0, 0, serviceid, 99, 0, -1, -1, -1, -1, 0);
125                if(chnode != NULL) chnode->pmtpid = pmtpid;
126        }
127        else
128                chnode = status.aktservice->channel;
129
130        if(chnode == NULL)
131        {
132                err("create channel");
133                close(fd);
134                dvrclose(dvrnode, -1);
135                return 1;
136        }
137
138        if(flag == 1)
139        {
140                ret = servicestart(chnode, NULL, NULL, 2);
141                if(ret != 0)
142                {
143                        err("start play");
144                        close(fd);
145                        dvrclose(dvrnode, -1);
146                        return 1;
147                }
148               
149                //on permanent timeshift seek to end, and a little back (eof problem)
150                if(status.timeshifttype == 1)
151                {
152                        if(status.timeshiftpos > 0)
153                                lseek64(fd, status.timeshiftpos, SEEK_SET);
154                        else
155                        {
156                                unsigned long long pos = lseek64(fd, 0, SEEK_END);
157                                pos -= 10000000;
158                                pos = pos - (pos & tssize);
159                                lseek64(fd, -pos, SEEK_END);
160                        }
161                }
162        }
163
164        ret = recordstartreal(NULL, fd, dvrnode->fd, RECPLAY, 0, NULL, tssize);
165        if(ret != 0)
166        {
167                err("start play thread");
168                close(fd);
169                dvrclose(dvrnode, -1);
170                return 1;
171        }
172
173        snode = getservice(RECORDPLAY, 0);
174        if(snode != NULL)
175        {
176                int dupfd = -1;
177                snode->recname = ostrcat(file, NULL, 0, 0);
178
179                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
180                if(dupfd > -1)
181                        gettsinfo(dupfd, &snode->lenpts, &snode->startpts, &snode->endpts, &snode->bitrate, snode->tssize);
182
183                if(flag == 1)
184                {
185                        snode->lenpts = 0;
186                        snode->endpts = 0;
187                }
188                else
189                {
190                        if(getservicebyrecname(file, 1, 0) != NULL) //playfile is recording, so len can change
191                        {
192                                snode->lenpts = 0;
193                                snode->endpts = 0;
194                        }
195                        else if(dupfd > -1)
196                                snode->endoffile = lseek64(dupfd , 0, SEEK_END);
197                }
198                close(dupfd);
199        }
200
201        if(flag == 0 || flag == 2)
202        {
203                ret = servicestart(chnode, NULL, NULL, 1);
204                if(ret != 0)
205                {
206                        err("start play");
207                        if(snode != NULL) snode->recendtime = 1;
208                        close(fd);
209                        dvrclose(dvrnode, -1);
210                        return 1;
211                }
212                //status.playercan = 0x7EFF;
213                status.playercan = 0xFFFF;     
214        }
215
216        return 0;
217}
218
219//flag 0: from play
220//flag 1: from timeshift
221//flag 2: from playrcjumpr/playerafterendts
222//flag1 0: stop from rcstop
223//flag1 1: stop from servicestop
224void playerstopts(int flag, int flag1)
225{
226        int ret = 0;
227        struct service* snode = NULL;
228        struct channel* node = NULL;
229
230        snode = getservice(RECORDPLAY, flag1);
231        if(snode != NULL) snode->recendtime = 1;
232
233        if(flag == 0 || flag == 2)
234        {
235                playerslowts(0);
236                playerffts(0);
237
238                if(snode != NULL && snode->recsrcfd >= 0 && flag == 0)
239                {
240                        char* fileseek = changefilenameext(snode->recname, ".se");
241                        FILE* fbseek = fopen(fileseek, "w");
242                        if(fbseek != NULL)
243                        {
244                                off64_t pos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
245                                fprintf(fbseek,"%lld", pos);
246                                fclose(fbseek);
247                        }
248                        free(fileseek); fileseek=NULL;
249                        char* filemarker = changefilenameext(snode->recname, ".ma");
250                        ret = putmarker(filemarker);
251                        free(filemarker); filemarker=NULL;
252                        delmarkernode(-1);
253                }
254               
255                ret = servicestop(status.aktservice, 1, 1);
256                if(ret == 1)
257                {
258                        debug(150, "can't stop ts playback service");   
259                }
260                else
261                        status.aktservice->channel = NULL;
262
263                               
264                node = gettmpchannel();
265                if(node != NULL && ostrcmp(node->name, "player") == 0)
266                        delchannel(node->serviceid, node->transponderid, 1);
267        }
268}
269
270void playerresetts()
271{
272        audiostop(status.aktservice->audiodev);
273        videostop(status.aktservice->videodev, 0);
274        videoplay(status.aktservice->videodev);
275        audioplay(status.aktservice->audiodev);
276}
277
278void playercontinuets()
279{
280        videocontinue(status.aktservice->videodev);
281        audioplay(status.aktservice->audiodev);
282}
283
284void playerpausets()
285{
286        videofreeze(status.aktservice->videodev);
287        audiopause(status.aktservice->audiodev);
288}
289
290//flag 0: with lock
291//flag 1: without lock
292int playerseekts(struct service* servicenode, int sekunden, int flag)
293{
294        off64_t offset = 0;
295        off64_t endoffile = 0;
296        off64_t currentpos = 0;
297        //off64_t fdptspos = 0;
298        //int ret = 0;
299        unsigned long long lenpts = 0;
300        unsigned long long startpts = 0;
301        unsigned long long endpts = 0;
302        unsigned long long bitrate = 0;
303        //unsigned long long aktpts = 0;
304        //unsigned long long fdpts = 0;
305        //int aktsekunden = 0;
306        int sekundenoff = 0;
307       
308        if(servicenode == NULL) return 1;
309
310        if(servicenode->recsrcfd < 0)
311        {
312                err("source fd not ok");
313                return 1;
314        }
315       
316        if(flag == 0) m_lock(&status.tsseekmutex, 15);
317
318/*
319        ret = videogetpts(status.aktservice->videodev, &aktpts);
320        if(ret == 0)
321        {
322                aktsekunden = aktpts / 90000;
323        }
324        else
325                aktsekunden = 0;
326        ret = getpts(servicenode->recsrcfd, 0, 0, 256 * 1024, &fdpts, &fdptspos, -1, servicenode->tssize);
327        if(ret == 0 && aktsekunden != 0)
328        {
329                sekundenoff = fdpts / 90000 - aktsekunden ;
330                //currentpos = lseek64(servicenode->recsrcfd, fdptspos, SEEK_SET);
331        }
332        else
333                sekundenoff = 0;
334*/
335       
336        currentpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);
337
338        lenpts = servicenode->lenpts;
339        startpts = servicenode->startpts;
340        endpts = servicenode->endpts;
341        bitrate = servicenode->bitrate;
342        if(gettsinfo(servicenode->recsrcfd, &lenpts, &startpts, &endpts, &bitrate, servicenode->tssize) != 0)
343        {
344                err("can't read ts info");
345                lseek64(servicenode->recsrcfd, currentpos, SEEK_SET);
346                if(flag == 0) m_unlock(&status.tsseekmutex, 15);
347                return 1;
348        }
349        if(servicenode->endoffile > 0)
350                endoffile = servicenode->endoffile - (servicenode->tssize * 2);
351        else
352                endoffile = lseek64(servicenode->recsrcfd , -servicenode->tssize * 2, SEEK_END);
353
354/*
355        ret = videoclearbuffer(status.aktservice->videodev);
356        ret = audioclearbuffer(status.aktservice->audiodev);
357        ret = videodiscontinuityskip(status.aktservice->videodev, 0);
358*/
359
360        if(sekunden >= 0)
361        {
362                if(sekundenoff != 0)
363                        offset = (bitrate / 8) * (sekunden - sekundenoff);
364                else
365                        offset = (bitrate / 8) * sekunden - 5000000;
366                offset = offset - (offset % servicenode->tssize);
367                if(currentpos + offset > endoffile)
368                {
369                        offset = endoffile - currentpos;
370                        offset = offset - (offset % servicenode->tssize);
371                }
372        }
373        else
374        {
375                sekunden = sekunden * -1;
376                if(sekundenoff != 0)
377                        offset = (bitrate / 8) * (sekunden + sekundenoff);
378                else
379                        offset = (bitrate / 8) * sekunden;
380                if(offset > 0) offset += 5000000;
381                offset = offset - (offset % servicenode->tssize);
382                if(currentpos - offset < 0)
383                        offset = currentpos;
384                offset = offset * -1;
385        }
386        offset += currentpos;
387        currentpos = lseek64(servicenode->recsrcfd, offset, SEEK_SET);
388
389        playerresetts();
390
391        if(flag == 0) m_unlock(&status.tsseekmutex, 15);
392        return 0;
393}
394
395void playerffts(int speed)
396{
397        videofastforward(status.aktservice->videodev, speed);
398}
399
400void playerslowts(int speed)
401{
402        videoslowmotion(status.aktservice->videodev, speed);
403}
404
405//flag = 0 --> recordplay
406//flag = 1 --> timeshift
407void playerfrts(int speed, int flag)
408{
409        if(flag == 1)
410                videocontinue(status.aktservice->videodev);
411        if(speed == -2)
412        {
413                videoclearbuffer(status.aktservice->videodev);
414                audioclearbuffer(status.aktservice->audiodev);
415        }
416        speed *= -1;
417        videofastforward(status.aktservice->videodev, speed);
418}
419       
420
421//flag = 0 --> play ts
422//flag = 1 --> timeshift
423//flag = 2 --> timeshift, not in play mode (only recording)
424int playergetinfots(unsigned long long* lenpts, unsigned long long* startpts, unsigned long long* endpts, unsigned long long* aktpts, unsigned long long* bitrate, int flag)
425{
426        int ret = 0, dupfd = -1;
427        double ratio = 0;
428        struct service* snode = NULL;
429        unsigned long long lenpts1 = 0;
430        unsigned long long startpts1 = 0;
431        unsigned long long endpts1 = 0;
432        unsigned long long bitrate1 = 0;
433        unsigned long long endoffile1 = 0;
434        unsigned long long aktpos = 0;
435       
436        if(flag == 2)
437                snode = getservice(RECORDTIMESHIFT, 0);
438        else
439                snode = getservice(RECORDPLAY, 0);
440               
441        if(snode == NULL) return 1;
442
443        if(snode->lenpts > 0 && snode->startpts > 0 && snode->endpts > 0 && snode->bitrate > 0 && snode->endoffile > 0)
444        {
445                if(lenpts != NULL) *lenpts = snode->lenpts;
446                if(startpts != NULL) *startpts = snode->startpts;
447                if(endpts != NULL) *endpts = snode->endpts;
448                if(bitrate != NULL) *bitrate = snode->bitrate;
449
450                //ret = videogetpts(status.aktservice->videodev, aktpts);
451                if(aktpts != NULL)
452                {
453                        m_lock(&status.tsseekmutex, 15);
454                        if(flag == 2)
455                                aktpos = lseek64(snode->recdstfd , 0, SEEK_CUR);
456                        else
457                                aktpos = lseek64(snode->recsrcfd , 0, SEEK_CUR);
458                        m_unlock(&status.tsseekmutex, 15);
459
460                        ratio = (double)snode->endoffile / (double)(snode->endpts - snode->startpts);
461                        if(ratio == 0) ratio = 1;
462                        *aktpts = ((double)aktpos / ratio);
463                        *aktpts += snode->startpts;
464                }
465
466                return ret;
467        }
468       
469        dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
470        if(dupfd < 0)
471        {
472                err("copy source fd not ok");
473                return 1;
474        }
475
476        lenpts1 = snode->lenpts;
477        startpts1 = snode->startpts;
478        endpts1 = snode->endpts;
479        bitrate1 = snode->bitrate;
480        if(gettsinfo(dupfd, &lenpts1, &startpts1, &endpts1, &bitrate1, snode->tssize) != 0)
481        {
482                err("can't read ts info");
483                return 1;
484        }
485
486        if(lenpts != NULL) *lenpts = lenpts1;
487        if(startpts != NULL) *startpts = startpts1;
488        if(endpts != NULL) *endpts = endpts1;
489        if(bitrate != NULL) *bitrate = bitrate1;
490
491        //ret = videogetpts(status.aktservice->videodev, aktpts);
492        if(aktpts != NULL)
493        {
494                m_lock(&status.tsseekmutex, 15);
495                if(flag == 2)
496                        aktpos = lseek64(snode->recdstfd, 0, SEEK_CUR);
497                else
498                        aktpos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
499                m_unlock(&status.tsseekmutex, 15);
500
501                if(snode->endoffile <= 0)
502                        endoffile1 = lseek64(dupfd, 0, SEEK_END);
503                else
504                        endoffile1 = snode->endoffile;
505
506                if(endpts1 == 0)
507                        ratio = 1;
508                else
509                        ratio = (double)endoffile1 / (double)(endpts1 - startpts1);
510
511                if(ratio == 0) ratio = 1;
512                *aktpts = ((double)aktpos / ratio);
513                *aktpts += startpts1;
514        }
515
516        close(dupfd);
517        return ret;
518}
519
520void playerchangeaudiotrackts()
521{
522        screenaudiotrack();
523}
524
525void playerchangesubtitletrackts()
526{
527        screensubtitle();
528}
529
530int playerisplayingts()
531{
532        struct service* snode = getservice(RECORDPLAY, 0);
533
534        if(snode == NULL)
535                return 0;
536        return 1;
537}
538
539void playerafterendts()
540{
541        playerstopts(2, 0);
542}
543
544//extern player
545
546int playerstart(char* file)
547{
548        char * tmpfile = NULL;
549       
550        if(file != NULL)
551        {
552#ifdef EPLAYER3
553                //use eplayer
554
555                if(player != NULL)
556                {
557                        debug(150, "eplayer allready running");
558                        playerstop();
559                }
560
561                player = calloc(1, sizeof(Context_t));
562
563                if(player == NULL)
564                {
565                        err("no mem");
566                        return 1;
567                }
568
569                if(ostrstr(file, "://") == NULL)
570                        tmpfile = ostrcat("file://", file, 0, 0);
571                else
572                        tmpfile = ostrcat(file, NULL, 0, 0);
573
574                if(tmpfile == NULL)
575                {
576                        err("no mem");
577                        free(player); player = NULL;
578                        return 1;
579                }
580
581                if(ostrstr(tmpfile, "file://") == NULL)
582                        status.playercan = 0x4650;
583                else
584                        status.playercan = 0xFFFF;
585               
586                player->playback = &PlaybackHandler;
587                player->output = &OutputHandler;
588                player->container = &ContainerHandler;
589                player->manager = &ManagerHandler;
590               
591                //add container befor open, so we can set buffer size
592                char* ext = getfilenameext(tmpfile);
593                if(ext != NULL)
594                {
595                        player->container->Command(player, CONTAINER_ADD, ext);
596                        free(ext); ext = NULL;
597                }
598
599                //select container_ffmpeg, if we does not found a container with extensions
600                if(player->container->selectedContainer == NULL)
601                        player->container->Command(player, CONTAINER_ADD, "mp3");
602
603                if(player && player->container && player->container->selectedContainer)
604                {
605                        int size = getconfigint("playerbuffersize", NULL);
606                        int seektime = getconfigint("playerbufferseektime", NULL);
607                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SIZE, (void*)&size);
608                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SEEK_TIME, (void*)&seektime);
609                }
610               
611                debug(150, "eplayername = %s", player->output->Name);
612
613                //Registrating output devices
614                player->output->Command(player, OUTPUT_ADD, "audio");
615                player->output->Command(player, OUTPUT_ADD, "video");
616                player->output->Command(player, OUTPUT_ADD, "subtitle");
617               
618                //for subtitle
619                SubtitleOutputDef_t subout;
620
621                subout.screen_width = skinfb->width;
622                subout.screen_height = skinfb->height;
623                subout.framebufferFD = skinfb->fd;
624                subout.destination = (uint32_t *)skinfb->fb;
625                subout.destStride = skinfb->pitch;
626                subout.shareFramebuffer = 1;
627                subout.framebufferBlit = blitfb1;
628
629                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&subout);
630               
631                if(player->playback->Command(player, PLAYBACK_OPEN, tmpfile) < 0)
632                {
633                        free(player); player = NULL;
634                        free(tmpfile);
635                        return 1;
636                }
637
638                player->output->Command(player, OUTPUT_OPEN, NULL);
639                player->playback->Command(player, PLAYBACK_PLAY, NULL);
640
641                free(tmpfile);
642
643                return 0;
644#endif
645
646#ifdef EPLAYER4
647                int flags = 0x47; //(GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT);
648               
649                if(m_gst_playbin != NULL)
650                {
651                        debug(150, "eplayer allready running");
652                        playerstop();
653                }
654               
655                if(ostrstr(file, "://") == NULL)
656                        tmpfile = ostrcat("file://", file, 0, 0);
657                else
658                        tmpfile = ostrcat(file, NULL, 0, 0);
659
660                if(tmpfile == NULL)
661                {
662                        err("no mem");
663                        free(m_gst_playbin); m_gst_playbin = NULL;
664                        return 1;
665                }
666
667                if(ostrstr(tmpfile, "file://") == NULL)
668                        status.playercan = 0x7E7F;
669                else
670                        status.playercan = 0x7E7F;
671               
672                m_gst_playbin = gst_element_factory_make("playbin2", "playbin");
673                g_object_set(G_OBJECT (m_gst_playbin), "uri", tmpfile, NULL);
674                g_object_set(G_OBJECT (m_gst_playbin), "flags", flags, NULL);
675                free(tmpfile); tmpfile = NULL;
676               
677                if(m_gst_playbin)
678                        gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
679               
680                int count = 0;
681                m_gst_startpts = 0;
682                while(m_gst_startpts == 0 && count < 5)
683                {
684                        count++;
685                        sleep(1);
686                        m_gst_startpts = playergetpts();
687                }
688                return 0;
689#endif
690        }
691       
692        return 1;
693}
694
695void playerinit(int argc, char* argv[])
696{
697#ifdef EPLAYER4
698        gst_init(&argc, &argv);
699#endif
700}
701
702#ifdef EPLAYER4
703int gstbuscall(GstBus *bus, GstMessage *msg)
704{
705        int ret = 1;
706        if(!m_gst_playbin) return 0;
707        if(!msg) return ret;
708
709        gchar *sourceName = NULL;
710        GstObject *source = GST_MESSAGE_SRC(msg);
711
712        if(!GST_IS_OBJECT(source)) return ret;
713        sourceName = gst_object_get_name(source);
714
715        switch(GST_MESSAGE_TYPE(msg))
716        {
717                case GST_MESSAGE_EOS:
718                        debug(150, "gst player eof");
719                        ret = 0;
720                        break;
721                case GST_MESSAGE_STATE_CHANGED:
722                        if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
723                                break;
724
725                        GstState old_state, new_state;
726                        gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
727               
728                        if(old_state == new_state) break;
729       
730                        debug(150, "gst state change %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
731       
732                        GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
733       
734                        switch(transition)
735                        {
736                                case GST_STATE_CHANGE_NULL_TO_READY:
737                                        break;
738                                case GST_STATE_CHANGE_READY_TO_PAUSED:
739/*
740                                        GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
741                                        if(appsink)
742                                        {
743                                                g_object_set(G_OBJECT(appsink), "max-buffers", 2, NULL);
744                                                g_object_set(G_OBJECT(appsink), "sync", FALSE, NULL);
745                                                g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, NULL);
746                                                gst_object_unref(appsink);
747                                        }
748*/
749                                        break;
750                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
751                                        //if(m_sourceinfo.is_streaming && m_streamingsrc_timeout )
752                                                //m_streamingsrc_timeout->stop();
753                                        break;
754                                case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
755                                        break;
756                                case GST_STATE_CHANGE_PAUSED_TO_READY:
757                                        break;
758                                case GST_STATE_CHANGE_READY_TO_NULL:
759                                        ret = 0;
760                                        break;
761                        }
762                        break;
763                case GST_MESSAGE_ERROR:
764                        debug(150, "gst player error");
765
766                        gchar *gdebug1;
767                        GError *err;
768
769                        gst_message_parse_error(msg, &err, &gdebug1);
770                        g_free(gdebug1);
771
772                        debug(150, "gst error: %s (%i) from %s", err->message, err->code, sourceName);
773                        if(err->domain == GST_STREAM_ERROR)
774                        {
775                                if(err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
776                                {
777                                        //if(g_strrstr(sourceName, "videosink"))
778                                        //      m_event((iPlayableService*)this, evUser+11);
779                                        //else if ( g_strrstr(sourceName, "audiosink") )
780                                        //      m_event((iPlayableService*)this, evUser+10);
781                                }
782                        }
783                        g_error_free(err);
784                        break;
785                case GST_MESSAGE_INFO:
786                        debug(150, "gst player info");
787
788/*
789                        gchar *gdebug2;
790                        GError *inf;
791       
792                        gst_message_parse_info(msg, &inf, &gdebug2);
793                        g_free(gdebug2);
794                        if(inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
795                        {
796                                //if(g_strrstr(sourceName, "videosink"))
797                                //      m_event((iPlayableService*)this, evUser+14);
798                        }
799                        g_error_free(inf);
800*/
801                        break;
802                case GST_MESSAGE_TAG:
803                        debug(150, "gst player tag");
804                        break;
805                //case GST_MESSAGE_ASYNC_DONE:
806                //      debug(150, "gst player async done");
807                //      break;
808                case GST_MESSAGE_ELEMENT:
809                        debug(150, "gst player element");
810                        break;
811                case GST_MESSAGE_BUFFERING:
812                        debug(150, "gst player buffering");
813
814/*
815                        GstBufferingMode mode;
816                        gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
817                        gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
818                        //m_event((iPlayableService*)this, evBuffering);
819*/
820                        break;
821                case GST_MESSAGE_STREAM_STATUS:
822                        debug(150, "gst player stream status");
823
824/*
825                        GstStreamStatusType type;
826                        GstElement *owner;
827
828                        gst_message_parse_stream_status(msg, &type, &owner);
829                        if(type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming)
830                        {
831                                if(GST_IS_PAD(source))
832                                        owner = gst_pad_get_parent_element(GST_PAD(source));
833                                else if(GST_IS_ELEMENT(source))
834                                        owner = GST_ELEMENT(source);
835                                else
836                                        owner = NULL;
837                                if(owner)
838                                {
839                                        GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
840                                        const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
841                                        if (!strcmp(name, "souphttpsrc"))
842                                        {
843                                                //m_streamingsrc_timeout->start(10 * 1000, true);
844                                                g_object_set(G_OBJECT(owner), "timeout", 10, NULL);
845                                        }
846                                       
847                                }
848                                if(GST_IS_PAD(source))
849                                        gst_object_unref(owner);
850                        }
851*/
852                        break;
853                default:
854                        debug(150, "gst player unknown message");
855                        break;
856        }
857        g_free(sourceName);
858        return ret;
859}
860#endif
861
862int playergetbuffersize()
863{
864        int ret = 0;
865
866#ifdef EPLAYER3
867        if(player && player->container && player->container->selectedContainer)
868                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_SIZE, (void*)&ret);
869#endif
870
871        return ret;
872}
873
874int playergetbufferstatus()
875{
876        int ret = 0;
877
878#ifdef EPLAYER3
879        if(player && player->container && player->container->selectedContainer)
880                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_STATUS, (void*)&ret);
881#endif
882
883        return ret;
884}
885
886int playerstopbuffer()
887{
888        int ret = 0;
889
890#ifdef EPLAYER3
891        if(player && player->container && player->container->selectedContainer)
892                player->container->selectedContainer->Command(player, CONTAINER_STOP_BUFFER, NULL);
893#endif
894
895        return ret;
896}
897
898int playerisplaying()
899{
900#ifdef SIMULATE
901        return 1;
902#endif
903
904#ifdef EPLAYER3
905        if(player != NULL && player->playback != NULL && player->playback->isPlaying)
906                return 1;
907#endif
908
909#ifdef EPLAYER4
910        int ret = 1;
911
912        if(m_gst_playbin)
913        {
914                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(m_gst_playbin));
915                GstMessage *message = NULL;
916                while((message = gst_bus_pop(bus)))
917                {
918                        ret = gstbuscall(bus, message);
919                        gst_message_unref(message);
920                }
921        }
922        else
923                ret = 0;
924
925        return ret;
926#endif
927        return 0;
928}
929
930void playerplay()
931{
932#ifdef EPLAYER3
933        if(player && player->playback)
934                player->playback->Command(player, PLAYBACK_PLAY, NULL);
935#endif
936
937#ifdef EPLAYER4
938        if(m_gst_playbin)
939                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
940#endif
941}
942
943int playerstop()
944{
945#ifdef EPLAYER3
946        if(player && player->playback)
947                player->playback->Command(player, PLAYBACK_STOP, NULL);
948        if(player && player->container && player->container->selectedContainer)
949                player->container->selectedContainer->Command(player, CONTAINER_STOP, NULL);
950        if(player && player->output)
951        {
952                player->output->Command(player, OUTPUT_CLOSE, NULL);
953                player->output->Command(player, OUTPUT_DEL, (void*)"audio");
954                player->output->Command(player, OUTPUT_DEL, (void*)"video");
955                player->output->Command(player, OUTPUT_DEL, (void*)"subtitle");
956        }
957        if(player && player->playback)
958                player->playback->Command(player, PLAYBACK_CLOSE, NULL);
959
960        free(player);
961        player = NULL;
962#endif
963
964#ifdef EPLAYER4
965        if(m_gst_playbin)
966        {
967                gst_element_set_state(m_gst_playbin, GST_STATE_NULL);
968                gst_object_unref(GST_OBJECT(m_gst_playbin));
969                m_gst_playbin = NULL;
970        }
971#endif
972
973        writesysint("/proc/sys/vm/drop_caches", 3, 0);
974        return 0;
975}
976
977void playerafterend()
978{
979#ifdef EPLAYER3
980        if(player != NULL && player->playback != NULL)
981                playerstop();
982#endif
983
984#ifdef EPLAYER4
985        if(m_gst_playbin)
986                playerstop();
987#endif
988}
989
990void playerpause()
991{
992#ifdef EPLAYER3
993        if(player && player->playback)
994                player->playback->Command(player, PLAYBACK_PAUSE, NULL);
995#endif
996
997#ifdef EPLAYER4
998        if(m_gst_playbin)
999                gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED);
1000#endif
1001}
1002
1003void playercontinue()
1004{
1005#ifdef EPLAYER3
1006        if(player && player->playback)
1007                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
1008#endif
1009
1010#ifdef EPLAYER4
1011        if(m_gst_playbin)
1012                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
1013#endif
1014}
1015
1016void playerff(int speed)
1017{
1018#ifdef EPLAYER3
1019        int speedmap = 0;
1020
1021        if (speed < 1) speed = 1;
1022        if (speed > 7) speed = 7;
1023
1024        switch(speed)
1025        {
1026                case 1: speedmap = 1; break;
1027                case 2: speedmap = 3; break;
1028                case 3: speedmap = 7; break;
1029                case 4: speedmap = 15; break;
1030                case 5: speedmap = 31; break;
1031                case 6: speedmap = 63; break;
1032                case 7: speedmap = 127; break;
1033        }
1034
1035        if(player && player->playback)
1036                player->playback->Command(player, PLAYBACK_FASTFORWARD, &speedmap);
1037#endif
1038}
1039
1040void playerslow(int speed)
1041{
1042#ifdef EPLAYER3
1043        int speedmap = 0;
1044
1045        if (speed < 1) speed = 1;
1046        if (speed > 7) speed = 7;
1047
1048        switch(speed)
1049        {
1050                case 1: speedmap = 1; break;
1051                case 2: speedmap = 3; break;
1052                case 3: speedmap = 7; break;
1053                case 4: speedmap = 15; break;
1054                case 5: speedmap = 31; break;
1055                case 6: speedmap = 63; break;
1056                case 7: speedmap = 127; break;
1057        }
1058
1059        if(player && player->playback)
1060                player->playback->Command(player, PLAYBACK_SLOWMOTION, &speedmap);
1061#endif
1062}
1063
1064void playerfr(int speed)
1065{
1066#ifdef EPLAYER3
1067        int speedmap = 0;
1068
1069        if (speed > -1) speed = -1;
1070        if (speed < -7) speed = -7;
1071
1072        switch(speed)
1073        {
1074                case -1: speedmap = -5; break;
1075                case -2: speedmap = -10; break;
1076                case -3: speedmap = -20; break;
1077                case -4: speedmap = -40; break;
1078                case -5: speedmap = -80; break;
1079                case -6: speedmap = -160; break;
1080                case -7: speedmap = -320; break;
1081        }
1082
1083        if(player && player->playback)
1084                player->playback->Command(player, PLAYBACK_FASTBACKWARD, &speedmap);
1085#endif
1086}
1087
1088void playerseek(float sec)
1089{
1090#ifdef EPLAYER3
1091        if(player && player->playback)
1092                player->playback->Command(player, PLAYBACK_SEEK, (void*)&sec);
1093#endif
1094
1095#ifdef EPLAYER4
1096        gint64 nanos_pts = 0, nanos_len = 0;
1097        gint64 pts = 0, len = 0;
1098        //GstFormat fmt = GST_FORMAT_TIME;
1099               
1100        if(m_gst_playbin)
1101        {
1102                len = playergetlength();
1103                nanos_len = len * 1000000000;
1104                if(nanos_len < 0) nanos_len = 0;
1105
1106                pts = playergetpts();
1107                nanos_pts = pts * 11111;
1108                nanos_pts = nanos_pts + (sec * 1000000000);
1109                if(nanos_pts < 0) nanos_pts = 0;
1110
1111                if(nanos_pts >= nanos_len)
1112                        playerstop();
1113                else
1114                        gst_element_seek(m_gst_playbin, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, nanos_pts, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
1115        }
1116#endif
1117}
1118
1119void playerfreetracklist(char** TrackList)
1120{
1121        int i = 0;
1122
1123        if(TrackList != NULL)
1124        {
1125                while(TrackList[i] != NULL)
1126                {
1127                        free(TrackList[i]);
1128                        free(TrackList[i + 1]);
1129                        i += 2;
1130                }
1131        }
1132}
1133
1134char** playergettracklist(int type)
1135{
1136        char ** TrackList = NULL;
1137#ifdef EPLAYER3
1138        if(player && player->manager)
1139        {
1140                switch(type)
1141                {
1142                        case 1:
1143                                if(player->manager->audio)
1144                                {
1145                                        player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
1146                                        debug(150, "Audio Track List");
1147                                }
1148                                break;
1149                        case 2:
1150                                if(player->manager->subtitle)
1151                                {
1152                                        player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
1153                                        debug(150, "Subtitle Track List");
1154                                }
1155                                break;
1156                        default:
1157                                if(player->manager->video)
1158                                {
1159                                        player->manager->video->Command(player, MANAGER_LIST, &TrackList);
1160                                        debug(150, "Video Track List");
1161                                }
1162                }
1163               
1164                int i = 0;
1165                if(TrackList != NULL)
1166                {
1167                        while(TrackList[i] != NULL)
1168                        {
1169                                string_newline(TrackList[i]);
1170                                i += 2;
1171                        }
1172                       
1173                        debug(150, "Track List");
1174                        i = 0;
1175                        while(TrackList[i] != NULL)
1176                        {
1177                                debug(150, "%s - %s", TrackList[i], TrackList[i + 1]);
1178                                i += 2;
1179                        }
1180                }
1181        }
1182#endif
1183        return TrackList;
1184}
1185
1186//*CurTrackEncoding and *CurTrackName be freed
1187void playergetcurtrac(int type, int *CurTrackId, char** CurTrackEncoding, char** CurTrackName)
1188{
1189#ifdef EPLAYER3
1190        if(player && player->manager)
1191        {
1192                switch(type)
1193                {
1194                        case 1:
1195                                if(player->manager->audio)
1196                                {
1197                                        player->manager->audio->Command(player, MANAGER_GET, CurTrackId);
1198                                        player->manager->audio->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1199                                        player->manager->audio->Command(player, MANAGER_GETNAME, CurTrackName);
1200                                }
1201                                break;
1202                        case 2:
1203                                if(player->manager->subtitle)
1204                                {
1205                                        player->manager->subtitle->Command(player, MANAGER_GET, CurTrackId);
1206                                        player->manager->subtitle->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1207                                        player->manager->subtitle->Command(player, MANAGER_GETNAME, CurTrackName);
1208                                }
1209                                break;
1210                        default:
1211                                if(player->manager->video)
1212                                {
1213                                        player->manager->video->Command(player, MANAGER_GET, CurTrackId);
1214                                        player->manager->video->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1215                                        player->manager->video->Command(player, MANAGER_GETNAME, CurTrackName);
1216                                }
1217                }
1218
1219                if(CurTrackId != NULL)
1220                        debug(150, "Current Track ID: %d", *CurTrackId);
1221                if(*CurTrackEncoding != NULL)
1222                        debug(150, "Current Track Enc: %s", *CurTrackEncoding);
1223                if(*CurTrackName != NULL)
1224                        debug(150, "Current Track Name: %s", *CurTrackName);
1225        }
1226#endif
1227
1228#ifdef EPLAYER4
1229        if(m_gst_playbin != NULL)
1230        {
1231                switch(type)
1232                {
1233                        case 1:
1234                                g_object_get(G_OBJECT(m_gst_playbin), "current-audio", CurTrackId, NULL);
1235                                break;
1236                }
1237               
1238                if(CurTrackId != NULL)
1239                        debug(150, "Current Track ID: %d", *CurTrackId);
1240        }
1241#endif
1242}
1243
1244unsigned long long playergetpts()
1245{
1246        unsigned long long pts = 0;
1247        unsigned long long sec = 0;
1248
1249#ifdef EPLAYER3
1250        if(player && player->playback)
1251        {
1252                player->playback->Command(player, PLAYBACK_PTS, &pts);
1253                sec = pts / 90000;
1254                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
1255        }
1256#endif
1257
1258#ifdef EPLAYER4
1259        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1260       
1261/*
1262        if(m_gst_playbin)
1263        {
1264                gst_element_query_position(m_gst_playbin, &fmt, (gint64*)&pts);
1265                sec = pts / 1000000000;
1266                pts = sec * 90000;
1267                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
1268        }
1269*/
1270
1271        if(m_gst_playbin)
1272        {
1273                gint64 pos;
1274                GstElement *sink;
1275                pts = 0;
1276
1277                g_object_get(G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
1278
1279                if(!sink) g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
1280                if(!sink) return 0;
1281
1282                gchar *name = gst_element_get_name(sink);
1283                gboolean use_get_decoder_time = ostrstr(name, "dvbaudiosink") || ostrstr(name, "dvbvideosink");
1284                g_free(name);
1285
1286                if(use_get_decoder_time) g_signal_emit_by_name(sink, "get-decoder-time", &pos);
1287
1288                gst_object_unref(sink);
1289
1290                if(!use_get_decoder_time && !gst_element_query_position(m_gst_playbin, &fmt, &pos))
1291                        return 0;
1292
1293                /* pos is in nanoseconds. we have 90 000 pts per second. */
1294                pts = pos / 11111;
1295                pts = pts - m_gst_startpts;
1296                sec = pts / 90000;
1297                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);
1298        }
1299#endif
1300
1301        if(pts < 0) pts = 0;
1302        return pts;
1303}
1304
1305double playergetlength()
1306{
1307        double length = 0;
1308
1309#ifdef EPLAYER3
1310        if(player && player->playback)
1311        {
1312                player->playback->Command(player, PLAYBACK_LENGTH, &length);
1313                if(length < 0) length = 0;
1314                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
1315        }
1316#endif
1317
1318#ifdef EPLAYER4
1319        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1320        gint64 len;
1321
1322        if(m_gst_playbin)
1323        {
1324                gst_element_query_duration(m_gst_playbin, &fmt, &len);
1325                length = len / 1000000000;
1326                if(length < 0) length = 0;
1327                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
1328        }
1329#endif
1330
1331        return length;
1332}
1333
1334char* playergetinfo(char* tag)
1335{
1336        char* ret = NULL;
1337
1338#ifdef EPLAYER3
1339        char *tags[] = {"Title", "Artist", "Album", "Year", "Genre", "Comment", "Track", "Copyright", "TestLibEplayer", NULL};
1340        int i = 0;
1341
1342        if(player && player->playback)
1343        {
1344                while(tags[i] != NULL)
1345                {
1346                        ret = tags[i];
1347                        if(ostrcmp(tag, ret) == 0)
1348                        {
1349                                player->playback->Command(player, PLAYBACK_INFO, &ret);
1350                                break;
1351                        }
1352
1353                        i++;
1354                }
1355        }
1356#endif
1357        return ret;
1358}
1359
1360void playerchangeaudiotrack(int num)
1361{
1362#ifdef EPLAYER3
1363        if(player && player->playback)
1364                player->playback->Command(player, PLAYBACK_SWITCH_AUDIO, (void*)&num);
1365#endif
1366
1367#ifdef EPLAYER4
1368        if(m_gst_playbin != NULL)
1369                g_object_set(G_OBJECT(m_gst_playbin), "current-audio", num, NULL);     
1370#endif
1371}
1372
1373void playerchangesubtitletrack(int num)
1374{
1375#ifdef EPLAYER3
1376        if(player && player->playback)
1377                player->playback->Command(player, PLAYBACK_SWITCH_SUBTITLE, (void*)&num);
1378#endif
1379}
1380
1381void playerstopsubtitletrack()
1382{
1383#ifdef EPLAYER3
1384        if(player && player->output && player->output->subtitle)
1385                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_STOP, NULL);
1386        if(player && player->container && player->container->assContainer)
1387        {
1388                player->container->assContainer->Command(player, CONTAINER_STOP, NULL);
1389                player->container->assContainer->Command(player, CONTAINER_INIT, NULL);
1390        }
1391        if(player && player->manager && player->manager->subtitle)
1392        {
1393                int onlycurrent = 1;
1394                player->manager->subtitle->Command(player, MANAGER_DEL, (void*)&onlycurrent);
1395        }
1396#endif
1397}
1398
1399int playerjumpts(struct service* servicenode, int sekunden, int *startpts, off64_t *poslastpts, off64_t *bitrate, int vpid, int tssize)
1400{
1401        int adaptation = 0;
1402        int payload = 0;
1403        int pes = 0;
1404        int tspid = 0;
1405       
1406        off64_t pts  = 0;
1407        uint64_t aktpts = 0;
1408        long long unsigned int lenpts = 0;
1409        long long unsigned int startpts1 = 0;
1410        long long unsigned int endpts = 0;
1411        long long unsigned int aktbitrate = 0;
1412        off64_t ziehlpts = 0;
1413
1414        off64_t curpos = 0;
1415        off64_t newpos = 0;
1416        off64_t jump = 0;
1417
1418        int kleiner = 0;
1419        int groesser = 0;
1420        int gleich = 0;
1421        int len = 0;
1422        int i = 0;
1423        int ret = 0;
1424
1425        if(servicenode == NULL) return -1;
1426
1427        int buflen = tssize * 15000;
1428        char *buf = malloc(buflen);
1429        if(buf == NULL)
1430                return -1;
1431       
1432        curpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);   
1433        int dupfd = open(servicenode->recname, O_RDONLY | O_LARGEFILE);
1434        newpos = lseek64(dupfd, curpos, SEEK_SET);
1435       
1436        if (*startpts == 0)
1437        {
1438                if(videogetpts(status.aktservice->videodev, &aktpts) == 0)
1439                {
1440                                ziehlpts = (aktpts / 90000) + sekunden;
1441                }
1442                else
1443                        return 1;
1444        }
1445        else
1446        {
1447                ziehlpts = *startpts + sekunden;
1448        }
1449        *startpts = ziehlpts;
1450
1451        if(*bitrate == 0)
1452        {
1453                lenpts = servicenode->lenpts;
1454                startpts1 = servicenode->startpts;
1455                endpts = servicenode->endpts;
1456                aktbitrate = servicenode->bitrate;
1457                ret = gettsinfo(dupfd, &lenpts, &startpts1, &endpts, &aktbitrate, servicenode->tssize);
1458                if(ret != 0)
1459                {
1460                        err("can't read ts info");
1461                }
1462                else
1463                        *bitrate = aktbitrate;
1464                newpos = lseek64(dupfd, curpos, SEEK_SET);
1465        }
1466        else
1467                aktbitrate = *bitrate;
1468               
1469        if(*poslastpts == 0)
1470                *poslastpts = curpos;
1471       
1472        if(sekunden > 0)
1473        {
1474                err("not implemented");
1475                return 1;
1476        }       
1477        else if(sekunden < 0)
1478        {
1479                sekunden = sekunden * -1;
1480                if(aktbitrate != 0)
1481                {
1482                        jump = (aktbitrate / 8) * sekunden;
1483                        jump = jump + (curpos - *poslastpts);
1484                        jump = jump + (jump % servicenode->tssize);
1485                        newpos = lseek64(dupfd, -jump, SEEK_CUR);
1486                }
1487                else
1488                        newpos = lseek64(dupfd, - buflen, SEEK_CUR);
1489                if(newpos < 0)
1490                        newpos = lseek64(dupfd, tssize, SEEK_SET);
1491        }
1492        len = read(dupfd, buf, buflen);
1493        for(i = 0; i < len; i = i + 1)
1494        {
1495                if (buf[i] == 0x47 && buf[i+tssize] == 0x47)
1496                {
1497                        newpos = lseek64(dupfd, newpos + i, SEEK_SET);
1498                        break;
1499                }
1500        }
1501        if(i >= len)
1502        {
1503                newpos = lseek64(dupfd, curpos, SEEK_SET);     
1504                return 1;
1505        }
1506        while(1)
1507        {
1508        len = read(dupfd, buf, buflen);
1509
1510                if(len > 0)
1511                {
1512                        for(i = 0; i <= len-tssize; i = i + tssize)
1513                        {
1514                                payload = 0;
1515
1516                                tspid = (buf[i+1] & 0x1F) << 8;
1517                                tspid = tspid + (buf[i+2] & 0xFF);
1518                                pes = buf[i+1] & 0x40;
1519
1520                                if(tspid == vpid)
1521                                {       
1522                                        adaptation = buf[i+3] & 0x30;
1523                                        if(adaptation == 16)
1524                                        {
1525                                                payload = 4;
1526                                        }
1527                                        if(adaptation == 32)
1528                                        {
1529                                                //printf("adaptation field only\n");
1530                                        }
1531                                        if(adaptation == 48)
1532                                        {
1533                                                payload = buf[i+4] & 0xFF;
1534                                                payload = payload + 5;
1535                                        }
1536                                        if(payload != 0)
1537                                        {
1538                                                if(pes == 64)
1539                                                {
1540                                                        if(buf[i+payload+7] & 0x80) //PTS
1541                                                        {
1542                                                                pts = ((unsigned long long)(buf[i+payload+9] & 0xE)) << 29;
1543                                                                pts |= ((unsigned long long)(buf[i+payload+10] & 0xFF)) << 22;
1544                                                                pts |= ((unsigned long long)(buf[i+payload+11] & 0xFE)) << 14;
1545                                                                pts |= ((unsigned long long)(buf[i+payload+12] & 0xFF)) << 7;
1546                                                                pts |= ((unsigned long long)(buf[i+payload+13] & 0xFE)) >> 1;
1547                                                               
1548                                                                if(pts / 90000 == ziehlpts)
1549                                                                {
1550                                                                        gleich = newpos + i;
1551                                                                        break;
1552                                                                }
1553                                                                else if(pts / 90000 > ziehlpts)
1554                                                                {                                                                       
1555                                                                        groesser = newpos + i;
1556                                                                        break;
1557                                                                }
1558                                                                else
1559                                                                {
1560                                                                        kleiner = newpos + i;
1561                                                                }
1562                                                        }
1563                                                }
1564                                        }
1565                                }
1566                        }
1567                        if(gleich != 0)
1568                        {
1569                                close(dupfd);
1570                                free(buf);buf = NULL;
1571                                *poslastpts = lseek64(servicenode->recsrcfd, gleich, SEEK_SET);
1572                                return 0;
1573                        }
1574                        else if(groesser != 0 && kleiner != 0)
1575                        {
1576                                close(dupfd);
1577                                free(buf);buf = NULL;
1578                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
1579                                return 0;
1580                        }
1581                        else if(groesser != 0)
1582                        {
1583                                if((newpos - buflen)  < 0)
1584                                {
1585                                        close(dupfd);
1586                                        free(buf);buf = NULL;
1587                                        *poslastpts = 0;
1588                                        return -1       ;
1589                                }
1590                                else
1591                                {
1592                                        newpos = lseek64(dupfd, -(buflen * 2), SEEK_CUR);
1593                                }
1594                        }
1595                }
1596                else
1597                {
1598                        if(kleiner == 0)
1599                        {
1600                                close(dupfd);
1601                                free(buf);buf = NULL;
1602                                newpos = lseek64(servicenode->recsrcfd, curpos, SEEK_SET);
1603                                *poslastpts = 0;
1604                                return -1;
1605                        }
1606                        else
1607                        {
1608                                close(dupfd);
1609                                free(buf);buf = NULL;
1610                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
1611                                return 0;
1612                        }
1613                }
1614        }
1615}
1616
1617
1618#endif
Note: See TracBrowser for help on using the repository browser.