source: titan/titan/player.h @ 29991

Last change on this file since 29991 was 29991, checked in by obi, 9 years ago

[mipsel] disable playergettracklist for release 1.55

File size: 45.8 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        int lastpos = 0;
47        struct channel* chnode = NULL;
48        struct service* snode = NULL;
49        struct dvbdev* fenode = NULL;
50        struct dvbdev* dvrnode = NULL;
51
52        //supermagic = getsupermagic(file);
53
54        if(supermagic == NFS_SUPER_MAGIC || supermagic == SMB_SUPER_MAGIC)
55        {
56                debug(150, "use O_DIRECT to open file %s", file);
57                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK | O_DIRECT);
58        }
59        else
60                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK);
61
62        if(fd < 0)
63        {
64                perr("open player file");
65                return 1;
66        }
67
68        fenode = fegetdummy();
69        dvrnode = dvropen(fenode);
70        if(dvrnode == NULL)
71        {
72                err("find dvr dev");
73                close(fd);
74                return 1;
75        }
76
77        if(flag == 0 || flag == 2)
78        {
79                //TODO: funktion to get tssize from file content
80                if(cmpfilenameext(file, ".mts") == 0) tssize = 192;
81                if(cmpfilenameext(file, ".m2ts") == 0) tssize = 192;
82               
83                ret = dvbfindpmtpid(fd, &pmtpid, &serviceid, tssize);
84                if(ret == 1)
85                {
86                        err("find sid/pmt pid");
87                        close(fd);
88                        dvrclose(dvrnode, -1);
89                        return 1;
90                }
91               
92                lastpos = 0;
93                if(flag == 0 && getconfigint("showlastpos", NULL) == 1)
94                {
95                        char* fileseek = changefilenameext(file, ".se");
96                        FILE* fbseek = fopen(fileseek, "r");
97                        if(fbseek != NULL)
98                        {
99                                ret = textbox(_("Message"), _("Start at last position ?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 10, 0);
100                                if(ret == 0 || ret == 1)
101                                {
102                                        char* skip1 = calloc(1, 20);
103                                        if(skip1 != NULL)
104                                        {
105                                                fscanf(fbseek, "%s", skip1);
106                                                off64_t seekpos = atoll(skip1);
107                                                seekpos = seekpos - (seekpos % tssize);
108                                                lseek64(fd, atoll(skip1), SEEK_SET);
109                                                lastpos = 1;
110                                        }
111                                        free(skip1); skip1 = NULL;
112                                }
113                                fclose(fbseek);
114                        }
115                        free(fileseek); fileseek = NULL;
116                }       
117               
118                status.autoseek = 0;
119               
120                if(flag == 0)
121                {
122                        delmarkernode(-1);
123                        char* filemarker = changefilenameext(file, ".ma");
124                        getmarker(filemarker);
125                        free(filemarker); filemarker=NULL;
126                }
127               
128                if(status.playmarker != NULL)
129                {
130                        char* testfile = changefilenameext(file, ".as");
131                        FILE* testseek = fopen(testfile, "r");
132                        if(testseek != NULL)
133                        {
134                                if(lastpos == 0)
135                                        lseek64(fd, status.playmarker->pos, SEEK_SET);
136                                status.autoseek = 2;
137                                addtimer(&markerautoseek_thread, START, 10000, 1, NULL, NULL, NULL);
138                                fclose(testseek);
139                        }
140                        free(testfile); testfile = NULL;
141                }
142                               
143                delchannel(serviceid, 0, 1);
144                chnode = createchannel("player", 0, 0, serviceid, 99, 0, -1, -1, -1, -1, 0, -1);
145                if(chnode != NULL) chnode->pmtpid = pmtpid;
146        }
147        else
148                chnode = status.aktservice->channel;
149
150        if(chnode == NULL)
151        {
152                err("create channel");
153                close(fd);
154                dvrclose(dvrnode, -1);
155                return 1;
156        }
157
158        if(flag == 1)
159        {
160                ret = servicestart(chnode, NULL, NULL, 2);
161                if(ret != 0)
162                {
163                        err("start play");
164                        close(fd);
165                        dvrclose(dvrnode, -1);
166                        return 1;
167                }
168               
169                //on permanent timeshift seek to end, and a little back (eof problem)
170                if(status.timeshifttype == 1)
171                {
172                        if(status.timeshiftpos > 0)
173                                lseek64(fd, status.timeshiftpos, SEEK_SET);
174                        else
175                        {
176                                unsigned long long pos = lseek64(fd, 0, SEEK_END);
177                                pos -= 10000000;
178                                pos = pos - (pos & tssize);
179                                lseek64(fd, -pos, SEEK_END);
180                        }
181                }
182        }
183
184        ret = recordstartreal(NULL, fd, dvrnode->fd, RECPLAY, 0, NULL, tssize);
185        if(ret != 0)
186        {
187                err("start play thread");
188                close(fd);
189                dvrclose(dvrnode, -1);
190                return 1;
191        }
192
193        snode = getservice(RECORDPLAY, 0);
194        if(snode != NULL)
195        {
196                int dupfd = -1;
197                snode->recname = ostrcat(file, NULL, 0, 0);
198
199                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
200                if(dupfd > -1)
201                        gettsinfo(dupfd, &snode->lenpts, &snode->startpts, &snode->endpts, &snode->bitrate, snode->tssize);
202
203                if(flag == 1)
204                {
205                        snode->lenpts = 0;
206                        snode->endpts = 0;
207                }
208                else
209                {
210                        if(getservicebyrecname(file, 1, 0) != NULL) //playfile is recording, so len can change
211                        {
212                                snode->lenpts = 0;
213                                snode->endpts = 0;
214                        }
215                        else if(dupfd > -1)
216                                snode->endoffile = lseek64(dupfd , 0, SEEK_END);
217                }
218                close(dupfd);
219        }
220
221        if(flag == 0 || flag == 2)
222        {
223                ret = servicestart(chnode, NULL, NULL, 1);
224                if(ret != 0)
225                {
226                        err("start play");
227                        if(snode != NULL) snode->recendtime = 1;
228                        close(fd);
229                        dvrclose(dvrnode, -1);
230                        return 1;
231                }
232                //status.playercan = 0x7EFF;
233                status.playercan = 0xFFFF;     
234        }
235
236        return 0;
237}
238
239//flag 0: from play
240//flag 1: from timeshift
241//flag 2: from playrcjumpr/playerafterendts
242//flag1 0: stop from rcstop
243//flag1 1: stop from servicestop
244void playerstopts(int flag, int flag1)
245{
246        int ret = 0;
247        struct service* snode = NULL;
248        struct channel* node = NULL;
249
250        snode = getservice(RECORDPLAY, flag1);
251
252        if(snode != NULL && snode->recsrcfd >= 0 && flag == 0 && flag1 == 0)
253        {
254                char* fileseek = changefilenameext(snode->recname, ".se");
255                FILE* fbseek = fopen(fileseek, "w");
256                if(fbseek != NULL)
257                {
258                        off64_t pos = getcurrentpos(snode);
259                        if(pos <= 0)
260                                pos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
261                        fprintf(fbseek,"%lld", pos);
262                        fclose(fbseek);
263                }
264                free(fileseek); fileseek=NULL;
265                char* filemarker = changefilenameext(snode->recname, ".ma");
266                ret = putmarker(filemarker);
267                free(filemarker); filemarker=NULL;
268                delmarkernode(-1);
269        }
270       
271        if(snode != NULL) snode->recendtime = 1;
272       
273        if(flag == 0 || flag == 2)
274        {
275                playerslowts(0);
276                playerffts(0);
277
278                ret = servicestop(status.aktservice, 1, 1);
279                if(ret == 1)
280                {
281                        debug(150, "can't stop ts playback service");   
282                }
283                else
284                        status.aktservice->channel = NULL;
285
286                               
287                node = gettmpchannel();
288                if(node != NULL && ostrcmp(node->name, "player") == 0)
289                        delchannel(node->serviceid, node->transponderid, 1);
290        }
291}
292
293void playerresetts()
294{
295        audiostop(status.aktservice->audiodev);
296        videostop(status.aktservice->videodev, 0);
297        videoplay(status.aktservice->videodev);
298        audioplay(status.aktservice->audiodev);
299}
300
301void playercontinuets()
302{
303        videocontinue(status.aktservice->videodev);
304        audioplay(status.aktservice->audiodev);
305}
306
307void playerpausets()
308{
309        videofreeze(status.aktservice->videodev);
310        audiopause(status.aktservice->audiodev);
311}
312
313//flag 0: with lock
314//flag 1: without lock
315int playerseekts(struct service* servicenode, int sekunden, int flag)
316{
317        off64_t offset = 0;
318        off64_t endoffile = 0;
319        off64_t currentpos = 0;
320        //off64_t fdptspos = 0;
321        //int ret = 0;
322        unsigned long long lenpts = 0;
323        unsigned long long startpts = 0;
324        unsigned long long endpts = 0;
325        unsigned long long bitrate = 0;
326        //unsigned long long aktpts = 0;
327        //unsigned long long fdpts = 0;
328        //int aktsekunden = 0;
329        int sekundenoff = 0;
330       
331        if(servicenode == NULL) return 1;
332
333        if(servicenode->recsrcfd < 0)
334        {
335                err("source fd not ok");
336                return 1;
337        }
338       
339        if(flag == 0) m_lock(&status.tsseekmutex, 15);
340
341/*
342        ret = videogetpts(status.aktservice->videodev, &aktpts);
343        if(ret == 0)
344        {
345                aktsekunden = aktpts / 90000;
346        }
347        else
348                aktsekunden = 0;
349        ret = getpts(servicenode->recsrcfd, 0, 0, 256 * 1024, &fdpts, &fdptspos, -1, servicenode->tssize);
350        if(ret == 0 && aktsekunden != 0)
351        {
352                sekundenoff = fdpts / 90000 - aktsekunden ;
353                //currentpos = lseek64(servicenode->recsrcfd, fdptspos, SEEK_SET);
354        }
355        else
356                sekundenoff = 0;
357*/
358       
359        currentpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);
360
361        lenpts = servicenode->lenpts;
362        startpts = servicenode->startpts;
363        endpts = servicenode->endpts;
364        bitrate = servicenode->bitrate;
365        if(gettsinfo(servicenode->recsrcfd, &lenpts, &startpts, &endpts, &bitrate, servicenode->tssize) != 0)
366        {
367                err("can't read ts info");
368                lseek64(servicenode->recsrcfd, currentpos, SEEK_SET);
369                if(flag == 0) m_unlock(&status.tsseekmutex, 15);
370                return 1;
371        }
372        if(servicenode->endoffile > 0)
373                endoffile = servicenode->endoffile - (servicenode->tssize * 2);
374        else
375                endoffile = lseek64(servicenode->recsrcfd , -servicenode->tssize * 2, SEEK_END);
376
377/*
378        ret = videoclearbuffer(status.aktservice->videodev);
379        ret = audioclearbuffer(status.aktservice->audiodev);
380        ret = videodiscontinuityskip(status.aktservice->videodev, 0);
381*/
382
383        if(sekunden >= 0)
384        {
385                if(sekundenoff != 0)
386                        offset = (bitrate / 8) * (sekunden - sekundenoff);
387                else
388                        offset = (bitrate / 8) * sekunden - 5000000;
389                offset = offset - (offset % servicenode->tssize);
390                if(currentpos + offset > endoffile)
391                {
392                        offset = endoffile - currentpos;
393                        offset = offset - (offset % servicenode->tssize);
394                }
395        }
396        else
397        {
398                sekunden = sekunden * -1;
399                if(sekundenoff != 0)
400                        offset = (bitrate / 8) * (sekunden + sekundenoff);
401                else
402                        offset = (bitrate / 8) * sekunden;
403                if(offset > 0) offset += 5000000;
404                offset = offset - (offset % servicenode->tssize);
405                if(currentpos - offset < 0)
406                        offset = currentpos;
407                offset = offset * -1;
408        }
409        offset += currentpos;
410        currentpos = lseek64(servicenode->recsrcfd, offset, SEEK_SET);
411
412        playerresetts();
413
414        if(flag == 0) m_unlock(&status.tsseekmutex, 15);
415        return 0;
416}
417
418void playerffts(int speed)
419{
420#ifdef MIPSEL
421        audiostop(status.aktservice->audiodev);
422        videoslowmotion(status.aktservice->videodev, 0);
423        videofastforward(status.aktservice->videodev, speed);
424        videocontinue(status.aktservice->videodev);
425#else   
426        videofastforward(status.aktservice->videodev, speed);
427#endif
428}
429
430void playerslowts(int speed)
431{
432#ifdef MIPSEL
433        audiostop(status.aktservice->audiodev);
434        videoslowmotion(status.aktservice->videodev, speed);
435        videofastforward(status.aktservice->videodev, 0);
436        videocontinue(status.aktservice->videodev);
437#else           
438        videoslowmotion(status.aktservice->videodev, speed);
439#endif
440}
441
442//flag = 0 --> recordplay
443//flag = 1 --> timeshift
444void playerfrts(int speed, int flag)
445{
446        if(flag == 1)
447                videocontinue(status.aktservice->videodev);
448        if(speed == -2)
449        {
450                videoclearbuffer(status.aktservice->videodev);
451                audioclearbuffer(status.aktservice->audiodev);
452        }
453        speed *= -1;
454#ifdef MIPSEL
455        audiostop(status.aktservice->audiodev);
456        videoslowmotion(status.aktservice->videodev, 0);
457        videofastforward(status.aktservice->videodev, speed);
458        videocontinue(status.aktservice->videodev);
459#else   
460        videofastforward(status.aktservice->videodev, speed);
461#endif
462}
463       
464
465//flag = 0 --> play ts
466//flag = 1 --> timeshift
467//flag = 2 --> timeshift, not in play mode (only recording)
468int playergetinfots(unsigned long long* lenpts, unsigned long long* startpts, unsigned long long* endpts, unsigned long long* aktpts, unsigned long long* bitrate, int flag)
469{
470        int ret = 0, dupfd = -1;
471        double ratio = 0;
472        struct service* snode = NULL;
473        unsigned long long lenpts1 = 0;
474        unsigned long long startpts1 = 0;
475        unsigned long long endpts1 = 0;
476        unsigned long long bitrate1 = 0;
477        unsigned long long endoffile1 = 0;
478        unsigned long long aktpos = 0;
479       
480        if(flag == 2)
481                snode = getservice(RECORDTIMESHIFT, 0);
482        else
483                snode = getservice(RECORDPLAY, 0);
484               
485        if(snode == NULL) return 1;
486
487        if(snode->lenpts > 0 && snode->startpts > 0 && snode->endpts > 0 && snode->bitrate > 0 && snode->endoffile > 0)
488        {
489                if(lenpts != NULL) *lenpts = snode->lenpts;
490                if(startpts != NULL) *startpts = snode->startpts;
491                if(endpts != NULL) *endpts = snode->endpts;
492                if(bitrate != NULL) *bitrate = snode->bitrate;
493
494                //ret = videogetpts(status.aktservice->videodev, aktpts);
495                if(aktpts != NULL)
496                {
497                        m_lock(&status.tsseekmutex, 15);
498                        if(flag == 2)
499                                aktpos = lseek64(snode->recdstfd , 0, SEEK_CUR);
500                        else
501                                aktpos = lseek64(snode->recsrcfd , 0, SEEK_CUR);
502                        m_unlock(&status.tsseekmutex, 15);
503
504                        ratio = (double)snode->endoffile / (double)(snode->endpts - snode->startpts);
505                        if(ratio == 0) ratio = 1;
506                        *aktpts = ((double)aktpos / ratio);
507                        *aktpts += snode->startpts;
508                }
509
510                return ret;
511        }
512       
513        dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
514        if(dupfd < 0)
515        {
516                err("copy source fd not ok");
517                return 1;
518        }
519
520        lenpts1 = snode->lenpts;
521        startpts1 = snode->startpts;
522        endpts1 = snode->endpts;
523        bitrate1 = snode->bitrate;
524        if(gettsinfo(dupfd, &lenpts1, &startpts1, &endpts1, &bitrate1, snode->tssize) != 0)
525        {
526                err("can't read ts info");
527                return 1;
528        }
529
530        if(lenpts != NULL) *lenpts = lenpts1;
531        if(startpts != NULL) *startpts = startpts1;
532        if(endpts != NULL) *endpts = endpts1;
533        if(bitrate != NULL) *bitrate = bitrate1;
534
535        //ret = videogetpts(status.aktservice->videodev, aktpts);
536        if(aktpts != NULL)
537        {
538                m_lock(&status.tsseekmutex, 15);
539                if(flag == 2)
540                        aktpos = lseek64(snode->recdstfd, 0, SEEK_CUR);
541                else
542                        aktpos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
543                m_unlock(&status.tsseekmutex, 15);
544
545                if(snode->endoffile <= 0)
546                        endoffile1 = lseek64(dupfd, 0, SEEK_END);
547                else
548                        endoffile1 = snode->endoffile;
549
550                if(endpts1 == 0)
551                        ratio = 1;
552                else
553                        ratio = (double)endoffile1 / (double)(endpts1 - startpts1);
554
555                if(ratio == 0) ratio = 1;
556                *aktpts = ((double)aktpos / ratio);
557                *aktpts += startpts1;
558        }
559
560        close(dupfd);
561        return ret;
562}
563
564void playerchangeaudiotrackts()
565{
566        screenaudiotrack();
567}
568
569void playerchangesubtitletrackts()
570{
571        screensubtitle();
572}
573
574int playerisplayingts()
575{
576        struct service* snode = getservice(RECORDPLAY, 0);
577
578        if(snode == NULL)
579                return 0;
580        return 1;
581}
582
583void playerafterendts()
584{
585        playerstopts(2, 0);
586}
587
588//extern player
589
590int playerstart(char* file)
591{
592        char * tmpfile = NULL;
593       
594        if(file != NULL)
595        {
596#ifdef EPLAYER3
597                //use eplayer
598
599                if(player != NULL)
600                {
601                        debug(150, "eplayer allready running");
602                        playerstop();
603                }
604
605                player = calloc(1, sizeof(Context_t));
606
607                if(player == NULL)
608                {
609                        err("no mem");
610                        return 1;
611                }
612
613                if(ostrstr(file, "://") == NULL)
614                        tmpfile = ostrcat("file://", file, 0, 0);
615                else
616                        tmpfile = ostrcat(file, NULL, 0, 0);
617
618                if(tmpfile == NULL)
619                {
620                        err("no mem");
621                        free(player); player = NULL;
622                        return 1;
623                }
624// move to mc
625//              set_player_sound(0);
626
627                if(ostrstr(tmpfile, "file://") == NULL)
628                        status.playercan = 0x4650;
629                else
630                        status.playercan = 0xFFFF;
631               
632                player->playback = &PlaybackHandler;
633                player->output = &OutputHandler;
634                player->container = &ContainerHandler;
635                player->manager = &ManagerHandler;
636               
637                //add container befor open, so we can set buffer size
638                char* ext = getfilenameext(tmpfile);
639                if(ext != NULL)
640                {
641                        player->container->Command(player, CONTAINER_ADD, ext);
642                        free(ext); ext = NULL;
643                }
644
645                //select container_ffmpeg, if we does not found a container with extensions
646                if(player->container->selectedContainer == NULL)
647                        player->container->Command(player, CONTAINER_ADD, "mp3");
648
649                if(player && player->container && player->container->selectedContainer)
650                {
651                        int size = getconfigint("playerbuffersize", NULL);
652                        int seektime = getconfigint("playerbufferseektime", NULL);
653                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SIZE, (void*)&size);
654                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SEEK_TIME, (void*)&seektime);
655                }
656               
657                debug(150, "eplayername = %s", player->output->Name);
658
659                //Registrating output devices
660                player->output->Command(player, OUTPUT_ADD, "audio");
661                player->output->Command(player, OUTPUT_ADD, "video");
662                player->output->Command(player, OUTPUT_ADD, "subtitle");
663               
664                //for subtitle
665                SubtitleOutputDef_t subout;
666
667                subout.screen_width = skinfb->width;
668                subout.screen_height = skinfb->height;
669                subout.framebufferFD = skinfb->fd;
670                subout.destination = (uint32_t *)skinfb->fb;
671                subout.destStride = skinfb->pitch;
672                subout.shareFramebuffer = 1;
673                subout.framebufferBlit = blitfb1;
674
675                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&subout);
676               
677                if(player->playback->Command(player, PLAYBACK_OPEN, tmpfile) < 0)
678                {
679                        free(player); player = NULL;
680                        free(tmpfile);
681                        return 1;
682                }
683
684                player->output->Command(player, OUTPUT_OPEN, NULL);
685                player->playback->Command(player, PLAYBACK_PLAY, NULL);
686
687                free(tmpfile);
688
689                return 0;
690#endif
691
692#ifdef EPLAYER4
693                int flags = 0x47; //(GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT);
694               
695                if(m_gst_playbin != NULL)
696                {
697                        debug(150, "eplayer allready running");
698                        playerstop();
699                }
700               
701                if(ostrstr(file, "://") == NULL)
702                        tmpfile = ostrcat("file://", file, 0, 0);
703                else
704                        tmpfile = ostrcat(file, NULL, 0, 0);
705
706                if(tmpfile == NULL)
707                {
708                        err("no mem");
709                        free(m_gst_playbin); m_gst_playbin = NULL;
710                        return 1;
711                }
712
713                if(ostrstr(tmpfile, "file://") == NULL)
714                        status.playercan = 0x7E7F;
715                else
716                        status.playercan = 0x7E7F;
717               
718                m_gst_playbin = gst_element_factory_make("playbin2", "playbin");
719                g_object_set(G_OBJECT (m_gst_playbin), "uri", tmpfile, NULL);
720                g_object_set(G_OBJECT (m_gst_playbin), "flags", flags, NULL);
721                free(tmpfile); tmpfile = NULL;
722               
723                if(m_gst_playbin)
724                        gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
725               
726                int count = 0;
727                m_gst_startpts = 0;
728                while(m_gst_startpts == 0 && count < 5)
729                {
730                        count++;
731                        sleep(1);
732                        m_gst_startpts = playergetpts();
733                }
734                return 0;
735#endif
736        }
737       
738        return 1;
739}
740
741void playerinit(int argc, char* argv[])
742{
743#ifdef EPLAYER4
744        gst_init(&argc, &argv);
745#endif
746}
747
748#ifdef EPLAYER4
749int gstbuscall(GstBus *bus, GstMessage *msg)
750{
751        int ret = 1;
752        if(!m_gst_playbin) return 0;
753        if(!msg) return ret;
754
755        gchar *sourceName = NULL;
756        GstObject *source = GST_MESSAGE_SRC(msg);
757
758        if(!GST_IS_OBJECT(source)) return ret;
759        sourceName = gst_object_get_name(source);
760
761        switch(GST_MESSAGE_TYPE(msg))
762        {
763                case GST_MESSAGE_EOS:
764                        debug(150, "gst player eof");
765                        ret = 0;
766                        break;
767                case GST_MESSAGE_STATE_CHANGED:
768                        if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
769                                break;
770
771                        GstState old_state, new_state;
772                        gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
773               
774                        if(old_state == new_state) break;
775       
776                        debug(150, "gst state change %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
777       
778                        GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
779       
780                        switch(transition)
781                        {
782                                case GST_STATE_CHANGE_NULL_TO_READY:
783                                        break;
784                                case GST_STATE_CHANGE_READY_TO_PAUSED:
785/*
786                                        GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
787                                        if(appsink)
788                                        {
789                                                g_object_set(G_OBJECT(appsink), "max-buffers", 2, NULL);
790                                                g_object_set(G_OBJECT(appsink), "sync", FALSE, NULL);
791                                                g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, NULL);
792                                                gst_object_unref(appsink);
793                                        }
794*/
795                                        break;
796                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
797                                        //if(m_sourceinfo.is_streaming && m_streamingsrc_timeout )
798                                                //m_streamingsrc_timeout->stop();
799                                        break;
800                                case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
801                                        break;
802                                case GST_STATE_CHANGE_PAUSED_TO_READY:
803                                        break;
804                                case GST_STATE_CHANGE_READY_TO_NULL:
805                                        ret = 0;
806                                        break;
807                        }
808                        break;
809                case GST_MESSAGE_ERROR:
810                        debug(150, "gst player error");
811
812                        gchar *gdebug1;
813                        GError *err;
814
815                        gst_message_parse_error(msg, &err, &gdebug1);
816                        g_free(gdebug1);
817
818                        debug(150, "gst error: %s (%i) from %s", err->message, err->code, sourceName);
819                        if(err->domain == GST_STREAM_ERROR)
820                        {
821                                if(err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
822                                {
823                                        //if(g_strrstr(sourceName, "videosink"))
824                                        //      m_event((iPlayableService*)this, evUser+11);
825                                        //else if ( g_strrstr(sourceName, "audiosink") )
826                                        //      m_event((iPlayableService*)this, evUser+10);
827                                }
828                        }
829                        g_error_free(err);
830                        break;
831                case GST_MESSAGE_INFO:
832                        debug(150, "gst player info");
833
834/*
835                        gchar *gdebug2;
836                        GError *inf;
837       
838                        gst_message_parse_info(msg, &inf, &gdebug2);
839                        g_free(gdebug2);
840                        if(inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
841                        {
842                                //if(g_strrstr(sourceName, "videosink"))
843                                //      m_event((iPlayableService*)this, evUser+14);
844                        }
845                        g_error_free(inf);
846*/
847                        break;
848                case GST_MESSAGE_TAG:
849                        debug(150, "gst player tag");
850                        break;
851                //case GST_MESSAGE_ASYNC_DONE:
852                //      debug(150, "gst player async done");
853                //      break;
854                case GST_MESSAGE_ELEMENT:
855                        debug(150, "gst player element");
856                        break;
857                case GST_MESSAGE_BUFFERING:
858                        debug(150, "gst player buffering");
859
860/*
861                        GstBufferingMode mode;
862                        gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
863                        gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
864                        //m_event((iPlayableService*)this, evBuffering);
865*/
866                        break;
867                case GST_MESSAGE_STREAM_STATUS:
868                        debug(150, "gst player stream status");
869
870/*
871                        GstStreamStatusType type;
872                        GstElement *owner;
873
874                        gst_message_parse_stream_status(msg, &type, &owner);
875                        if(type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming)
876                        {
877                                if(GST_IS_PAD(source))
878                                        owner = gst_pad_get_parent_element(GST_PAD(source));
879                                else if(GST_IS_ELEMENT(source))
880                                        owner = GST_ELEMENT(source);
881                                else
882                                        owner = NULL;
883                                if(owner)
884                                {
885                                        GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
886                                        const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
887                                        if (!strcmp(name, "souphttpsrc"))
888                                        {
889                                                //m_streamingsrc_timeout->start(10 * 1000, true);
890                                                g_object_set(G_OBJECT(owner), "timeout", 10, NULL);
891                                        }
892                                       
893                                }
894                                if(GST_IS_PAD(source))
895                                        gst_object_unref(owner);
896                        }
897*/
898                        break;
899                default:
900                        debug(150, "gst player unknown message");
901                        break;
902        }
903        g_free(sourceName);
904        return ret;
905}
906#endif
907
908int playergetbuffersize()
909{
910        int ret = 0;
911
912#ifdef EPLAYER3
913        if(player && player->container && player->container->selectedContainer)
914                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_SIZE, (void*)&ret);
915#endif
916
917        return ret;
918}
919
920int playergetbufferstatus()
921{
922        int ret = 0;
923
924#ifdef EPLAYER3
925        if(player && player->container && player->container->selectedContainer)
926                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_STATUS, (void*)&ret);
927#endif
928
929        return ret;
930}
931
932int playerstopbuffer()
933{
934        int ret = 0;
935
936#ifdef EPLAYER3
937        if(player && player->container && player->container->selectedContainer)
938                player->container->selectedContainer->Command(player, CONTAINER_STOP_BUFFER, NULL);
939#endif
940
941        return ret;
942}
943
944int playerisplaying()
945{
946#ifdef SIMULATE
947        return 1;
948#endif
949
950#ifdef EPLAYER3
951        if(player != NULL && player->playback != NULL && player->playback->isPlaying)
952                return 1;
953#endif
954
955#ifdef EPLAYER4
956        int ret = 1;
957
958        if(m_gst_playbin)
959        {
960                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(m_gst_playbin));
961                GstMessage *message = NULL;
962                while((message = gst_bus_pop(bus)))
963                {
964                        ret = gstbuscall(bus, message);
965                        gst_message_unref(message);
966                }
967        }
968        else
969                ret = 0;
970
971        return ret;
972#endif
973        return 0;
974}
975
976void playerplay()
977{
978#ifdef EPLAYER3
979        if(player && player->playback)
980                player->playback->Command(player, PLAYBACK_PLAY, NULL);
981#endif
982
983#ifdef EPLAYER4
984        if(m_gst_playbin)
985                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
986#endif
987}
988
989int playerstop()
990{
991#ifdef EPLAYER3
992        if(player && player->playback)
993                player->playback->Command(player, PLAYBACK_STOP, NULL);
994        if(player && player->container && player->container->selectedContainer)
995                player->container->selectedContainer->Command(player, CONTAINER_STOP, NULL);
996        if(player && player->output)
997        {
998                player->output->Command(player, OUTPUT_CLOSE, NULL);
999                player->output->Command(player, OUTPUT_DEL, (void*)"audio");
1000                player->output->Command(player, OUTPUT_DEL, (void*)"video");
1001                player->output->Command(player, OUTPUT_DEL, (void*)"subtitle");
1002        }
1003        if(player && player->playback)
1004                player->playback->Command(player, PLAYBACK_CLOSE, NULL);
1005
1006        free(player);
1007        player = NULL;
1008// move to mc
1009//      set_player_sound(1);
1010#endif
1011
1012#ifdef EPLAYER4
1013        if(m_gst_playbin)
1014        {
1015                gst_element_set_state(m_gst_playbin, GST_STATE_NULL);
1016                gst_object_unref(GST_OBJECT(m_gst_playbin));
1017                m_gst_playbin = NULL;
1018        }
1019#endif
1020
1021        writesysint("/proc/sys/vm/drop_caches", 3, 0);
1022        return 0;
1023}
1024
1025void playerafterend()
1026{
1027#ifdef EPLAYER3
1028        if(player != NULL && player->playback != NULL)
1029                playerstop();
1030#endif
1031
1032#ifdef EPLAYER4
1033        if(m_gst_playbin)
1034                playerstop();
1035#endif
1036}
1037
1038void playerpause()
1039{
1040#ifdef EPLAYER3
1041        if(player && player->playback)
1042                player->playback->Command(player, PLAYBACK_PAUSE, NULL);
1043#endif
1044
1045#ifdef EPLAYER4
1046        if(m_gst_playbin)
1047                gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED);
1048#endif
1049}
1050
1051void playercontinue()
1052{
1053#ifdef EPLAYER3
1054        if(player && player->playback)
1055                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
1056#endif
1057
1058#ifdef EPLAYER4
1059        if(m_gst_playbin)
1060                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
1061#endif
1062}
1063
1064void playerff(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 = 1; break;
1075                case 2: speedmap = 3; break;
1076                case 3: speedmap = 7; break;
1077                case 4: speedmap = 15; break;
1078                case 5: speedmap = 31; break;
1079                case 6: speedmap = 63; break;
1080                case 7: speedmap = 127; break;
1081        }
1082
1083        if(player && player->playback)
1084                player->playback->Command(player, PLAYBACK_FASTFORWARD, &speedmap);
1085#endif
1086}
1087
1088void playerslow(int speed)
1089{
1090#ifdef EPLAYER3
1091        int speedmap = 0;
1092
1093        if (speed < 1) speed = 1;
1094        if (speed > 7) speed = 7;
1095
1096        switch(speed)
1097        {
1098                case 1: speedmap = 1; break;
1099                case 2: speedmap = 3; break;
1100                case 3: speedmap = 7; break;
1101                case 4: speedmap = 15; break;
1102                case 5: speedmap = 31; break;
1103                case 6: speedmap = 63; break;
1104                case 7: speedmap = 127; break;
1105        }
1106
1107        if(player && player->playback)
1108                player->playback->Command(player, PLAYBACK_SLOWMOTION, &speedmap);
1109#endif
1110}
1111
1112void playerfr(int speed)
1113{
1114#ifdef EPLAYER3
1115        int speedmap = 0;
1116
1117        if (speed > -1) speed = -1;
1118        if (speed < -7) speed = -7;
1119
1120        switch(speed)
1121        {
1122                case -1: speedmap = -5; break;
1123                case -2: speedmap = -10; break;
1124                case -3: speedmap = -20; break;
1125                case -4: speedmap = -40; break;
1126                case -5: speedmap = -80; break;
1127                case -6: speedmap = -160; break;
1128                case -7: speedmap = -320; break;
1129        }
1130
1131        if(player && player->playback)
1132                player->playback->Command(player, PLAYBACK_FASTBACKWARD, &speedmap);
1133#endif
1134}
1135
1136void playerseek(float sec)
1137{
1138#ifdef EPLAYER3
1139        if(player && player->playback)
1140                player->playback->Command(player, PLAYBACK_SEEK, (void*)&sec);
1141#endif
1142
1143#ifdef EPLAYER4
1144        gint64 nanos_pts = 0, nanos_len = 0;
1145        gint64 pts = 0, len = 0;
1146        //GstFormat fmt = GST_FORMAT_TIME;
1147               
1148        if(m_gst_playbin)
1149        {
1150                len = playergetlength();
1151                nanos_len = len * 1000000000;
1152                if(nanos_len < 0) nanos_len = 0;
1153
1154                pts = playergetpts();
1155                nanos_pts = pts * 11111;
1156                nanos_pts = nanos_pts + (sec * 1000000000);
1157                if(nanos_pts < 0) nanos_pts = 0;
1158
1159                if(nanos_pts >= nanos_len)
1160                        playerstop();
1161                else
1162                        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);
1163        }
1164#endif
1165}
1166
1167void playerfreetracklist(char** TrackList)
1168{
1169        int i = 0;
1170
1171        if(TrackList != NULL)
1172        {
1173                while(TrackList[i] != NULL)
1174                {
1175                        free(TrackList[i]);
1176                        free(TrackList[i + 1]);
1177                        i += 2;
1178                }
1179        }
1180}
1181
1182char** playergettracklist(int type)
1183{
1184        char ** TrackList = NULL;
1185#ifdef EPLAYER3
1186        if(player && player->manager)
1187        {
1188                switch(type)
1189                {
1190                        case 1:
1191                                if(player->manager->audio)
1192                                {
1193                                        player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
1194                                        debug(150, "Audio Track List");
1195                                }
1196                                break;
1197                        case 2:
1198                                if(player->manager->subtitle)
1199                                {
1200                                        player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
1201                                        debug(150, "Subtitle Track List");
1202                                }
1203                                break;
1204                        default:
1205                                if(player->manager->video)
1206                                {
1207                                        player->manager->video->Command(player, MANAGER_LIST, &TrackList);
1208                                        debug(150, "Video Track List");
1209                                }
1210                }
1211               
1212                int i = 0;
1213                if(TrackList != NULL)
1214                {
1215                        while(TrackList[i] != NULL)
1216                        {
1217                                string_newline(TrackList[i]);
1218                                i += 2;
1219                        }
1220                       
1221                        debug(150, "Track List");
1222                        i = 0;
1223                        while(TrackList[i] != NULL)
1224                        {
1225                                debug(150, "%s - %s", TrackList[i], TrackList[i + 1]);
1226                                i += 2;
1227                        }
1228                }
1229        }
1230#endif
1231/*
1232//////////////////////////////NEUER CODE //////////////////////////////
1233#ifdef EPLAYER4
1234        char ** tmpTrackList[2][100];
1235        TrackList = tmpTrackList;
1236       
1237        if(m_gst_playbin != NULL) {
1238                gint i, n_video = 0, n_audio = 0, n_text = 0;
1239               
1240                g_object_get(m_gst_playbin, "n-video", &n_video, NULL);
1241                g_object_get(m_gst_playbin, "n-audio", &n_audio, NULL);
1242                g_object_get(m_gst_playbin, "n-text", &n_text, NULL);
1243               
1244                switch(type)
1245                {
1246                        case 1:
1247                                for(i = 0; i < n_audio; i++)
1248                                {
1249                                        GstTagList *tags = NULL;
1250                                        gchar *g_codec = NULL, *g_lang = NULL;
1251                                       
1252                                        g_signal_emit_by_name(m_gst_playbin, "get-audio-tags", i, &tags);
1253                                       
1254#if GST_VERSION_MAJOR < 1
1255                                        if(tags && gst_is_tag_list(tags))
1256#else
1257                                        if(tags && GST_IS_TAG_LIST(tags))
1258#endif
1259                                        {
1260                                                if(gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_codec))
1261                                                {
1262                                                        printf("Audio Codec: %s", g_codec);
1263                                                        TrackList[i * 2] = ostrcat(g_codec, NULL, 0, 0);
1264                                                        g_free(g_codec);
1265                                                }
1266                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
1267                                                {
1268                                                        printf("Audio Lang: %s", g_lang);
1269                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
1270                                                        g_free(g_lang);
1271                                                }
1272                                                gst_tag_list_free(tags);
1273                                        }
1274                                }
1275                                break;
1276                        case 2:
1277                                for(i = 0; i < n_text; i++)
1278                                {
1279                                        GstTagList *tags = NULL;
1280                                        gchar *g_codec = NULL, *g_lang = NULL;
1281                                       
1282                                        g_signal_emit_by_name(m_gst_playbin, "get-text-tags", i, &tags);
1283                                       
1284#if GST_VERSION_MAJOR < 1
1285                                        if (tags && gst_is_tag_list(tags))
1286#else
1287                                        if (tags && GST_IS_TAG_LIST(tags))
1288#endif
1289                                        {
1290                                                if(gst_tag_list_get_string(tags, GST_TAG_SUBTITLE_CODEC, &g_codec));
1291                                                {
1292                                                        printf("SubTitle Codec: %s", g_codec);
1293                                                        TrackList[i * 2] = ostrcat(g_codec, NULL, 0, 0);
1294                                                        g_free(g_codec);
1295                                                }
1296                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
1297                                                {
1298                                                        printf("SubTitle Lang: %s", g_lang);
1299                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
1300                                                        g_free(g_lang);
1301                                                }
1302                                                gst_tag_list_free(tags);
1303                                        }
1304                                }
1305                                break;
1306                        default:
1307                                for(i = 0; i < n_video; i++)
1308                                {
1309                                        GstTagList *tags = NULL;
1310                                        gchar *g_codec = NULL, *g_lang = NULL;
1311                                       
1312                                        g_signal_emit_by_name(m_gst_playbin, "get-video-tags", i, &tags);
1313                                       
1314#if GST_VERSION_MAJOR < 1
1315                                        if (tags && gst_is_tag_list(tags))
1316#else
1317                                        if (tags && GST_IS_TAG_LIST(tags))
1318#endif
1319                                        {
1320                                                if(gst_tag_list_get_string(tags, GST_TAG_VIDEO_CODEC, &g_codec));
1321                                                {
1322                                                        printf("Video Codec: %s", g_codec);
1323                                                        TrackList[i * 2] = ostrcat(g_codec, NULL, 0, 0);
1324                                                        g_free(g_codec);
1325                                                }
1326                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
1327                                                {
1328                                                        printf("Video Lang: %s", g_lang);
1329                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
1330                                                        g_free(g_lang);
1331                                                }
1332                                                gst_tag_list_free(tags);
1333                                        }
1334                                }
1335                }
1336        }
1337#endif
1338//////////////////////////////NEUER CODE //////////////////////////////
1339*/
1340        return TrackList;
1341}
1342
1343//*CurTrackEncoding and *CurTrackName be freed
1344void playergetcurtrac(int type, int *CurTrackId, char** CurTrackEncoding, char** CurTrackName)
1345{
1346#ifdef EPLAYER3
1347        if(player && player->manager)
1348        {
1349                switch(type)
1350                {
1351                        case 1:
1352                                if(player->manager->audio)
1353                                {
1354                                        player->manager->audio->Command(player, MANAGER_GET, CurTrackId);
1355                                        player->manager->audio->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1356                                        player->manager->audio->Command(player, MANAGER_GETNAME, CurTrackName);
1357                                }
1358                                break;
1359                        case 2:
1360                                if(player->manager->subtitle)
1361                                {
1362                                        player->manager->subtitle->Command(player, MANAGER_GET, CurTrackId);
1363                                        player->manager->subtitle->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1364                                        player->manager->subtitle->Command(player, MANAGER_GETNAME, CurTrackName);
1365                                }
1366                                break;
1367                        default:
1368                                if(player->manager->video)
1369                                {
1370                                        player->manager->video->Command(player, MANAGER_GET, CurTrackId);
1371                                        player->manager->video->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1372                                        player->manager->video->Command(player, MANAGER_GETNAME, CurTrackName);
1373                                }
1374                }
1375
1376                if(CurTrackId != NULL)
1377                        debug(150, "Current Track ID: %d", *CurTrackId);
1378                if(*CurTrackEncoding != NULL)
1379                        debug(150, "Current Track Enc: %s", *CurTrackEncoding);
1380                if(*CurTrackName != NULL)
1381                        debug(150, "Current Track Name: %s", *CurTrackName);
1382        }
1383#endif
1384
1385#ifdef EPLAYER4
1386        if(m_gst_playbin != NULL)
1387        {
1388                switch(type)
1389                {
1390                        case 1:
1391                                g_object_get(G_OBJECT(m_gst_playbin), "current-audio", CurTrackId, NULL);
1392                                break;
1393                }
1394               
1395                if(CurTrackId != NULL)
1396                        debug(150, "Current Track ID: %d", *CurTrackId);
1397        }
1398#endif
1399}
1400
1401unsigned long long playergetpts()
1402{
1403        unsigned long long pts = 0;
1404        unsigned long long sec = 0;
1405
1406#ifdef EPLAYER3
1407        if(player && player->playback)
1408        {
1409                player->playback->Command(player, PLAYBACK_PTS, &pts);
1410                sec = pts / 90000;
1411                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
1412        }
1413#endif
1414
1415#ifdef EPLAYER4
1416        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1417       
1418/*
1419        if(m_gst_playbin)
1420        {
1421                gst_element_query_position(m_gst_playbin, &fmt, (gint64*)&pts);
1422                sec = pts / 1000000000;
1423                pts = sec * 90000;
1424                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
1425        }
1426*/
1427
1428        if(m_gst_playbin)
1429        {
1430                gint64 pos;
1431                GstElement *sink;
1432                pts = 0;
1433
1434                g_object_get(G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
1435
1436                if(!sink) g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
1437                if(!sink) return 0;
1438
1439                gchar *name = gst_element_get_name(sink);
1440                gboolean use_get_decoder_time = ostrstr(name, "dvbaudiosink") || ostrstr(name, "dvbvideosink");
1441                g_free(name);
1442
1443                if(use_get_decoder_time) g_signal_emit_by_name(sink, "get-decoder-time", &pos);
1444
1445                gst_object_unref(sink);
1446
1447                if(!use_get_decoder_time && !gst_element_query_position(m_gst_playbin, &fmt, &pos))
1448                        return 0;
1449
1450                /* pos is in nanoseconds. we have 90 000 pts per second. */
1451                pts = pos / 11111;
1452                pts = pts - m_gst_startpts;
1453                sec = pts / 90000;
1454                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);
1455        }
1456#endif
1457
1458        if(pts < 0) pts = 0;
1459        return pts;
1460}
1461
1462double playergetlength()
1463{
1464        double length = 0;
1465
1466#ifdef EPLAYER3
1467        if(player && player->playback)
1468        {
1469                player->playback->Command(player, PLAYBACK_LENGTH, &length);
1470                if(length < 0) length = 0;
1471                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
1472        }
1473#endif
1474
1475#ifdef EPLAYER4
1476        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1477        gint64 len;
1478
1479        if(m_gst_playbin)
1480        {
1481                gst_element_query_duration(m_gst_playbin, &fmt, &len);
1482                length = len / 1000000000;
1483                if(length < 0) length = 0;
1484                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
1485        }
1486#endif
1487
1488        return length;
1489}
1490
1491char* playergetinfo(char* tag)
1492{
1493        char* ret = NULL;
1494
1495#ifdef EPLAYER3
1496        char *tags[] = {"Title", "Artist", "Album", "Year", "Genre", "Comment", "Track", "Copyright", "TestLibEplayer", NULL};
1497        int i = 0;
1498
1499        if(player && player->playback)
1500        {
1501                while(tags[i] != NULL)
1502                {
1503                        ret = tags[i];
1504                        if(ostrcmp(tag, ret) == 0)
1505                        {
1506                                player->playback->Command(player, PLAYBACK_INFO, &ret);
1507                                break;
1508                        }
1509
1510                        i++;
1511                }
1512        }
1513#endif
1514        return ret;
1515}
1516
1517void playerchangeaudiotrack(int num)
1518{
1519#ifdef EPLAYER3
1520        if(player && player->playback)
1521                player->playback->Command(player, PLAYBACK_SWITCH_AUDIO, (void*)&num);
1522#endif
1523
1524#ifdef EPLAYER4
1525        if(m_gst_playbin != NULL)
1526                g_object_set(G_OBJECT(m_gst_playbin), "current-audio", num, NULL);     
1527#endif
1528}
1529
1530void playerchangesubtitletrack(int num)
1531{
1532#ifdef EPLAYER3
1533        if(player && player->playback)
1534                player->playback->Command(player, PLAYBACK_SWITCH_SUBTITLE, (void*)&num);
1535#endif
1536}
1537
1538void playerstopsubtitletrack()
1539{
1540#ifdef EPLAYER3
1541        if(player && player->output && player->output->subtitle)
1542                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_STOP, NULL);
1543        if(player && player->container && player->container->assContainer)
1544        {
1545                player->container->assContainer->Command(player, CONTAINER_STOP, NULL);
1546                player->container->assContainer->Command(player, CONTAINER_INIT, NULL);
1547        }
1548        if(player && player->manager && player->manager->subtitle)
1549        {
1550                int onlycurrent = 1;
1551                player->manager->subtitle->Command(player, MANAGER_DEL, (void*)&onlycurrent);
1552        }
1553#endif
1554}
1555
1556int playerjumpts(struct service* servicenode, int sekunden, int *startpts, off64_t *poslastpts, off64_t *bitrate, int vpid, int tssize)
1557{
1558        int adaptation = 0;
1559        int payload = 0;
1560        int pes = 0;
1561        int tspid = 0;
1562       
1563        off64_t pts  = 0;
1564        uint64_t aktpts = 0;
1565        long long unsigned int lenpts = 0;
1566        long long unsigned int startpts1 = 0;
1567        long long unsigned int endpts = 0;
1568        long long unsigned int aktbitrate = 0;
1569        off64_t ziehlpts = 0;
1570
1571        off64_t curpos = 0;
1572        off64_t newpos = 0;
1573        off64_t jump = 0;
1574
1575        int kleiner = 0;
1576        int groesser = 0;
1577        int gleich = 0;
1578        int len = 0;
1579        int i = 0;
1580        int ret = 0;
1581
1582        if(servicenode == NULL) return -1;
1583
1584        int buflen = tssize * 15000;
1585        char *buf = malloc(buflen);
1586        if(buf == NULL)
1587                return -1;
1588       
1589        curpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);   
1590        int dupfd = open(servicenode->recname, O_RDONLY | O_LARGEFILE);
1591        newpos = lseek64(dupfd, curpos, SEEK_SET);
1592       
1593        if (*startpts == 0)
1594        {
1595                if(videogetpts(status.aktservice->videodev, &aktpts) == 0)
1596                {
1597                                ziehlpts = (aktpts / 90000) + sekunden;
1598                }
1599                else
1600                        return 1;
1601        }
1602        else
1603        {
1604                ziehlpts = *startpts + sekunden;
1605        }
1606        *startpts = ziehlpts;
1607
1608        if(*bitrate == 0)
1609        {
1610                lenpts = servicenode->lenpts;
1611                startpts1 = servicenode->startpts;
1612                endpts = servicenode->endpts;
1613                aktbitrate = servicenode->bitrate;
1614                ret = gettsinfo(dupfd, &lenpts, &startpts1, &endpts, &aktbitrate, servicenode->tssize);
1615                if(ret != 0)
1616                {
1617                        err("can't read ts info");
1618                }
1619                else
1620                        *bitrate = aktbitrate;
1621                newpos = lseek64(dupfd, curpos, SEEK_SET);
1622        }
1623        else
1624                aktbitrate = *bitrate;
1625               
1626        if(*poslastpts == 0)
1627                *poslastpts = curpos;
1628       
1629        if(sekunden > 0)
1630        {
1631                err("not implemented");
1632                return 1;
1633        }       
1634        else if(sekunden < 0)
1635        {
1636                sekunden = sekunden * -1;
1637                if(aktbitrate != 0)
1638                {
1639                        jump = (aktbitrate / 8) * sekunden;
1640                        jump = jump + (curpos - *poslastpts);
1641                        jump = jump + (jump % servicenode->tssize);
1642                        newpos = lseek64(dupfd, -jump, SEEK_CUR);
1643                }
1644                else
1645                        newpos = lseek64(dupfd, - buflen, SEEK_CUR);
1646                if(newpos < 0)
1647                        newpos = lseek64(dupfd, tssize, SEEK_SET);
1648        }
1649        len = read(dupfd, buf, buflen);
1650        for(i = 0; i < len; i = i + 1)
1651        {
1652                if (buf[i] == 0x47 && buf[i+tssize] == 0x47)
1653                {
1654                        newpos = lseek64(dupfd, newpos + i, SEEK_SET);
1655                        break;
1656                }
1657        }
1658        if(i >= len)
1659        {
1660                newpos = lseek64(dupfd, curpos, SEEK_SET);     
1661                return 1;
1662        }
1663        while(1)
1664        {
1665        len = read(dupfd, buf, buflen);
1666
1667                if(len > 0)
1668                {
1669                        for(i = 0; i <= len-tssize; i = i + tssize)
1670                        {
1671                                payload = 0;
1672
1673                                tspid = (buf[i+1] & 0x1F) << 8;
1674                                tspid = tspid + (buf[i+2] & 0xFF);
1675                                pes = buf[i+1] & 0x40;
1676
1677                                if(tspid == vpid)
1678                                {       
1679                                        adaptation = buf[i+3] & 0x30;
1680                                        if(adaptation == 16)
1681                                        {
1682                                                payload = 4;
1683                                        }
1684                                        if(adaptation == 32)
1685                                        {
1686                                                //printf("adaptation field only\n");
1687                                        }
1688                                        if(adaptation == 48)
1689                                        {
1690                                                payload = buf[i+4] & 0xFF;
1691                                                payload = payload + 5;
1692                                        }
1693                                        if(payload != 0)
1694                                        {
1695                                                if(pes == 64)
1696                                                {
1697                                                        if(buf[i+payload+7] & 0x80) //PTS
1698                                                        {
1699                                                                pts = ((unsigned long long)(buf[i+payload+9] & 0xE)) << 29;
1700                                                                pts |= ((unsigned long long)(buf[i+payload+10] & 0xFF)) << 22;
1701                                                                pts |= ((unsigned long long)(buf[i+payload+11] & 0xFE)) << 14;
1702                                                                pts |= ((unsigned long long)(buf[i+payload+12] & 0xFF)) << 7;
1703                                                                pts |= ((unsigned long long)(buf[i+payload+13] & 0xFE)) >> 1;
1704                                                               
1705                                                                if(pts / 90000 == ziehlpts)
1706                                                                {
1707                                                                        gleich = newpos + i;
1708                                                                        break;
1709                                                                }
1710                                                                else if(pts / 90000 > ziehlpts)
1711                                                                {                                                                       
1712                                                                        groesser = newpos + i;
1713                                                                        break;
1714                                                                }
1715                                                                else
1716                                                                {
1717                                                                        kleiner = newpos + i;
1718                                                                }
1719                                                        }
1720                                                }
1721                                        }
1722                                }
1723                        }
1724                        if(gleich != 0)
1725                        {
1726                                close(dupfd);
1727                                free(buf);buf = NULL;
1728                                *poslastpts = lseek64(servicenode->recsrcfd, gleich, SEEK_SET);
1729                                return 0;
1730                        }
1731                        else if(groesser != 0 && kleiner != 0)
1732                        {
1733                                close(dupfd);
1734                                free(buf);buf = NULL;
1735                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
1736                                return 0;
1737                        }
1738                        else if(groesser != 0)
1739                        {
1740                                if((newpos - buflen)  < 0)
1741                                {
1742                                        close(dupfd);
1743                                        free(buf);buf = NULL;
1744                                        *poslastpts = 0;
1745                                        return -1       ;
1746                                }
1747                                else
1748                                {
1749                                        newpos = lseek64(dupfd, -(buflen * 2), SEEK_CUR);
1750                                }
1751                        }
1752                }
1753                else
1754                {
1755                        if(kleiner == 0)
1756                        {
1757                                close(dupfd);
1758                                free(buf);buf = NULL;
1759                                newpos = lseek64(servicenode->recsrcfd, curpos, SEEK_SET);
1760                                *poslastpts = 0;
1761                                return -1;
1762                        }
1763                        else
1764                        {
1765                                close(dupfd);
1766                                free(buf);buf = NULL;
1767                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
1768                                return 0;
1769                        }
1770                }
1771        }
1772}
1773
1774//praez = 1 .... sekunden
1775//                      =       2 .... zehntel
1776//                      = 3 .... hundertstel
1777//                      = 4 .... volle Uebereinstimmung
1778//
1779//type  = 0 .... alle
1780//                      = 1 .... nur PCR
1781//                      = 2 .... nur Video
1782//                      = 3 .... nur Audio
1783//
1784//flag = 0 --> play ts
1785//flag = 1 --> timeshift
1786//flag = 2 --> timeshift, not in play mode (only recording)
1787//flag = 9 --> dataset mode
1788//
1789off64_t playergetptspos(unsigned long long fpts, off64_t pos, int dir, int praez, int type, int flag, char* dsn)
1790{
1791        unsigned long long pts;
1792        int ret = 0, dupfd = -1, left = 0, tssize = 0, recbsize = 0;
1793        unsigned char* buf = NULL;
1794        unsigned char *payload;
1795        int pid = 0, pusi = 0;
1796        unsigned char* packet;
1797        struct service* snode;
1798       
1799        if(type > 3)
1800        {
1801                printf("type %i nicht unterstützt\n", type);
1802                return -1;
1803        }
1804       
1805        if(flag == 2)
1806                snode = getservice(RECORDTIMESHIFT, 0);
1807        else if(flag != 9)
1808                snode = getservice(RECORDPLAY, 0);
1809               
1810        if(flag == 9)
1811        {
1812                tssize = 188;
1813                recbsize = tssize * 1024 * 10;
1814                dupfd = open(dsn, O_RDONLY | O_LARGEFILE );
1815        }
1816        else
1817        {
1818                tssize = snode->tssize;
1819                recbsize = snode->tssize * 1024 * 10;
1820                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
1821        }
1822
1823        if(dupfd < 0)
1824        {
1825                err("copy source fd not ok");
1826                return -1;
1827        }
1828
1829        buf = malloc(recbsize);
1830        if(buf == NULL)
1831        {
1832                err("no mem");
1833                return -1;
1834        }
1835        packet = buf;
1836        if(dir > 0) 
1837                pos = lseek64(dupfd, pos, SEEK_SET);
1838        else
1839                pos = lseek64(dupfd, pos - recbsize, SEEK_SET);
1840       
1841        ret = read(dupfd,  buf, recbsize);
1842        close(dupfd);
1843        left = 0;
1844       
1845        if(buf[0] != 0x47)
1846        {
1847                while(left < tssize)
1848                {
1849                        if(buf[left] == 0x47) break;
1850                        left++;
1851                }
1852                if(left >= tssize)
1853                {
1854                        free(buf);
1855                        return -1;
1856                }       
1857        }
1858        pts = 0;
1859        while(left <= recbsize - tssize)
1860        {
1861                if(pts != 0)
1862                {
1863                        switch( praez )
1864          {
1865        case 1 :        if(fpts / 90000 != pts / 90000)
1866                                                        pts = 0;
1867                                                break;
1868        case 2 :        if(fpts / 9000 != pts / 9000)
1869                                                        pts = 0;
1870                                                break;
1871        case 3 :        if(fpts / 900 != pts / 900)
1872                                                        pts = 0;
1873                                                break;         
1874        case 4 :        if(fpts != pts )
1875                                                        pts = 0;
1876                                                break;
1877                                default :       free(buf); return -1; break;
1878                        }
1879                        if(pts != 0)
1880                        {       
1881                                pos = pos + left - tssize;
1882                                free(buf);
1883                                return pos;
1884                        }
1885                }
1886                packet = buf + left;
1887                left = left + tssize;
1888                                               
1889                pid = ((packet[1] << 8) | packet[2]) & 0x1FFF;
1890                pusi = !!(packet[1] & 0x40);
1891                //check for adaption field
1892                if(packet[3] & 0x20)
1893                {
1894                        if(type > 1)continue;
1895                        if(packet[4] >= 183) continue;
1896                        if(packet[4])
1897                        {
1898                                if(packet[5] & 0x10) //PCR present
1899                                {
1900                                        pts = ((unsigned long long)(packet[6] & 0xFF)) << 25;
1901                                        pts |= ((unsigned long long)(packet[7] & 0xFF)) << 17;
1902                                        pts |= ((unsigned long long)(packet[8] & 0xFE)) << 9;
1903                                        pts |= ((unsigned long long)(packet[9] & 0xFF)) << 1;
1904                                        pts |= ((unsigned long long)(packet[10] & 0x80)) >> 7;
1905                                        continue;
1906                                }
1907                        }
1908                        payload = packet + packet[4] + 4 + 1;
1909                } else
1910                        payload = packet + 4;
1911               
1912                if(type == 1) continue;
1913                if(!pusi) continue;
1914               
1915                if (payload[0] || payload[1] || (payload[2] != 1))
1916                        continue;
1917               
1918                        //stream use extension mechanism def in ISO 13818-1 Amendment 2
1919                if(payload[3] == 0xFD)
1920                {
1921                        if(payload[7] & 1) //PES extension flag
1922                        {
1923                                int offs = 0;
1924                                if(payload[7] & 0x80) offs += 5; //pts avail
1925                                if(payload[7] & 0x40) offs += 5; //dts avail
1926                                if(payload[7] & 0x20) offs += 6; //escr avail
1927                                if(payload[7] & 0x10) offs += 3; //es rate
1928                                if(payload[7] & 0x8) offs += 1; //dsm trickmode
1929                                if(payload[7] & 0x4) offs += 1; //additional copy info
1930                                if(payload[7] & 0x2) offs += 2; //crc
1931                                if(payload[8] < offs) continue;
1932
1933                                uint8_t pef = payload[9 + offs++]; //pes extension field
1934                                if(pef & 1) //pes extension flag 2
1935                                {
1936                                        if(pef & 0x80) offs += 16; //private data flag
1937                                        if(pef & 0x40) offs += 1; //pack header field flag
1938                                        if(pef & 0x20) offs += 2; //program packet sequence counter flag
1939                                        if(pef & 0x10) offs += 2; //P-STD buffer flag
1940                                        if(payload[8] < offs) continue;
1941
1942                                        uint8_t stream_id_extension_len = payload[9 + offs++] & 0x7F;
1943                                        if(stream_id_extension_len >= 1)
1944                                        {
1945                                                if(payload[8] < (offs + stream_id_extension_len)) continue;
1946                                                //stream_id_extension_bit (should not set)
1947                                                if(payload[9 + offs] & 0x80) continue;
1948                                                switch(payload[9 + offs])
1949                                                {
1950                                                        case 0x55 ... 0x5f: break; //VC-1
1951                                                        case 0x71: break; //AC3 / DTS
1952                                                        case 0x72: break; //DTS - HD
1953                                                        default:
1954                                                                printf("skip unknwn stream_id_extension %02x\n", payload[9 + offs]);
1955                                                                continue;
1956                                                }
1957                                        }
1958                                        else
1959                                                continue;
1960                                }
1961                                else
1962                                        continue;
1963                        }
1964                        else
1965                                continue;
1966                }
1967                //drop non-audio, non-video packets because other streams
1968                //can be non-compliant.
1969                //0xC0 = audio, 0xE0 = video
1970                else if(((payload[3] & 0xE0) != 0xC0) && ((payload[3] & 0xF0) != 0xE0))
1971                        continue;
1972
1973                if((payload[7] & 0x80) && ((payload[3] & 0xF0) != 0xE0) && (type == 0 || type == 2)) //PTS video
1974                {
1975                        pts = ((unsigned long long)(payload[9] & 0xE)) << 29;
1976                        pts |= ((unsigned long long)(payload[10] & 0xFF)) << 22;
1977                        pts |= ((unsigned long long)(payload[11] & 0xFE)) << 14;
1978                        pts |= ((unsigned long long)(payload[12] & 0xFF)) << 7;
1979                        pts |= ((unsigned long long)(payload[13] & 0xFE)) >> 1;
1980                        continue;
1981                }
1982                if((payload[7] & 0x80) && ((payload[3] & 0xE0) != 0xC0) && (type == 0 || type == 3)) //PTS audio
1983                {
1984                        pts = ((unsigned long long)(payload[9] & 0xE)) << 29;
1985                        pts |= ((unsigned long long)(payload[10] & 0xFF)) << 22;
1986                        pts |= ((unsigned long long)(payload[11] & 0xFE)) << 14;
1987                        pts |= ((unsigned long long)(payload[12] & 0xFF)) << 7;
1988                        pts |= ((unsigned long long)(payload[13] & 0xFE)) >> 1;
1989                        continue;
1990                }
1991        }
1992        free(buf);
1993        return recbsize * -1;
1994}
1995
1996#endif
Note: See TracBrowser for help on using the repository browser.