source: titan/titan/player.h @ 32137

Last change on this file since 32137 was 32137, checked in by gost, 9 years ago

[titan] deactivate fr.. gstreamer

File size: 63.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 *pipeline = NULL;
32unsigned long long m_gst_startpts = 0;
33CustomData data;
34GstElement *video_sink = NULL;
35#endif
36
37//titan player
38
39//flag 0: from play
40//flag 1: from timeshift
41//flag 2: from playrcjumpr
42int playerstartts(char* file, int flag)
43{
44        int fd = -1, ret = 0, tssize = 188;
45        int16_t pmtpid = 0;
46        int serviceid = 0;
47        int supermagic = -1;
48        int lastpos = 0;
49        struct channel* chnode = NULL;
50        struct service* snode = NULL;
51        struct dvbdev* fenode = NULL;
52        struct dvbdev* dvrnode = NULL;
53        status.prefillbuffer = 0;
54
55        //supermagic = getsupermagic(file);
56
57        if(supermagic == NFS_SUPER_MAGIC || supermagic == SMB_SUPER_MAGIC)
58        {
59                debug(150, "use O_DIRECT to open file %s", file);
60                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK | O_DIRECT);
61        }
62        else
63                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK);
64
65        if(fd < 0)
66        {
67                perr("open player file");
68                return 1;
69        }
70
71        fenode = fegetdummy();
72        dvrnode = dvropen(fenode);
73        if(dvrnode == NULL)
74        {
75                err("find dvr dev");
76                close(fd);
77                return 1;
78        }
79
80        if(flag == 0 || flag == 2)
81        {
82                //TODO: funktion to get tssize from file content
83                if(cmpfilenameext(file, ".mts") == 0) tssize = 192;
84                if(cmpfilenameext(file, ".m2ts") == 0) tssize = 192;
85               
86                ret = dvbfindpmtpid(fd, &pmtpid, &serviceid, tssize);
87                if(ret == 1)
88                {
89                        err("find sid/pmt pid");
90                        close(fd);
91                        dvrclose(dvrnode, -1);
92                        return 1;
93                }
94               
95                lastpos = 0;
96                if(flag == 0 && getconfigint("showlastpos", NULL) == 1)
97                {
98                        char* fileseek = changefilenameext(file, ".se");
99                        FILE* fbseek = fopen(fileseek, "r");
100                        if(fbseek != NULL)
101                        {
102                                ret = textbox(_("Message"), _("Start at last position ?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 10, 0);
103                                if(ret == 0 || ret == 1)
104                                {
105                                        char* skip1 = calloc(1, 20);
106                                        if(skip1 != NULL)
107                                        {
108                                                fscanf(fbseek, "%s", skip1);
109                                                off64_t seekpos = atoll(skip1);
110                                                seekpos = seekpos - (seekpos % tssize);
111                                                lseek64(fd, atoll(skip1), SEEK_SET);
112                                                lastpos = 1;
113                                        }
114                                        free(skip1); skip1 = NULL;
115                                }
116                                fclose(fbseek);
117                        }
118                        free(fileseek); fileseek = NULL;
119                }       
120               
121                status.autoseek = 0;
122               
123                if(flag == 0)
124                {
125                        delmarkernode(-1);
126                        char* filemarker = changefilenameext(file, ".ma");
127                        getmarker(filemarker);
128                        free(filemarker); filemarker=NULL;
129                }
130               
131                if(status.playmarker != NULL)
132                {
133                        char* testfile = changefilenameext(file, ".as");
134                        FILE* testseek = fopen(testfile, "r");
135                        if(testseek != NULL)
136                        {
137                                if(lastpos == 0)
138                                        lseek64(fd, status.playmarker->pos, SEEK_SET);
139                                status.autoseek = 2;
140                                addtimer(&markerautoseek_thread, START, 10000, 1, NULL, NULL, NULL);
141                                fclose(testseek);
142                        }
143                        free(testfile); testfile = NULL;
144                }
145                               
146                delchannel(serviceid, 0, 1);
147                chnode = createchannel("player", 0, 0, serviceid, 99, 0, -1, -1, -1, -1, 0, -1);
148                if(chnode != NULL) chnode->pmtpid = pmtpid;
149        }
150        else
151                chnode = status.aktservice->channel;
152
153        if(chnode == NULL)
154        {
155                err("create channel");
156                close(fd);
157                dvrclose(dvrnode, -1);
158                return 1;
159        }
160
161        if(flag == 1)
162        {
163                ret = servicestart(chnode, NULL, NULL, 2);
164                if(ret != 0)
165                {
166                        err("start play");
167                        close(fd);
168                        dvrclose(dvrnode, -1);
169                        return 1;
170                }
171               
172                //on permanent timeshift seek to end, and a little back (eof problem)
173                if(status.timeshifttype == 1)
174                {
175                        if(status.timeshiftpos > 0)
176                                lseek64(fd, status.timeshiftpos, SEEK_SET);
177                        else
178                        {
179                                unsigned long long pos = lseek64(fd, 0, SEEK_END);
180                                pos -= 10000000;
181                                pos = pos - (pos & tssize);
182                                lseek64(fd, -pos, SEEK_END);
183                        }
184                }
185        }
186
187        ret = recordstartreal(NULL, fd, dvrnode->fd, RECPLAY, 0, NULL, tssize);
188        if(ret != 0)
189        {
190                err("start play thread");
191                close(fd);
192                dvrclose(dvrnode, -1);
193                return 1;
194        }
195
196        snode = getservice(RECORDPLAY, 0);
197        if(snode != NULL)
198        {
199                int dupfd = -1;
200                snode->recname = ostrcat(file, NULL, 0, 0);
201
202                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
203                if(dupfd > -1)
204                        gettsinfo(dupfd, &snode->lenpts, &snode->startpts, &snode->endpts, &snode->bitrate, snode->tssize);
205
206                if(flag == 1)
207                {
208                        snode->lenpts = 0;
209                        snode->endpts = 0;
210                }
211                else
212                {
213                        if(getservicebyrecname(file, 1, 0) != NULL) //playfile is recording, so len can change
214                        {
215                                snode->lenpts = 0;
216                                snode->endpts = 0;
217                        }
218                        else if(dupfd > -1)
219                                snode->endoffile = lseek64(dupfd , 0, SEEK_END);
220                }
221                close(dupfd);
222        }
223
224        if(flag == 0 || flag == 2)
225        {
226                ret = servicestart(chnode, NULL, NULL, 1);
227                if(ret != 0)
228                {
229                        err("start play");
230                        if(snode != NULL) snode->recendtime = 1;
231                        close(fd);
232                        dvrclose(dvrnode, -1);
233                        return 1;
234                }
235                //status.playercan = 0x7EFF;
236                status.playercan = 0xFFFF;     
237        }
238
239        return 0;
240}
241
242//flag 0: from play
243//flag 1: from timeshift
244//flag 2: from playrcjumpr/playerafterendts
245//flag1 0: stop from rcstop
246//flag1 1: stop from servicestop
247void playerstopts(int flag, int flag1)
248{
249        int ret = 0;
250        struct service* snode = NULL;
251        struct channel* node = NULL;
252
253        snode = getservice(RECORDPLAY, flag1);
254
255        if(snode != NULL && snode->recsrcfd >= 0 && flag == 0 && flag1 == 0)
256        {
257                char* fileseek = changefilenameext(snode->recname, ".se");
258                FILE* fbseek = fopen(fileseek, "w");
259                if(fbseek != NULL)
260                {
261                        off64_t pos = getcurrentpos(snode);
262                        if(pos <= 0)
263                                pos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
264                        fprintf(fbseek,"%lld", pos);
265                        fclose(fbseek);
266                }
267                free(fileseek); fileseek=NULL;
268                char* filemarker = changefilenameext(snode->recname, ".ma");
269                ret = putmarker(filemarker);
270                free(filemarker); filemarker=NULL;
271                delmarkernode(-1);
272        }
273       
274        if(snode != NULL) snode->recendtime = 1;
275       
276        if(flag == 0 || flag == 2)
277        {
278                playerslowts(0);
279                playerffts(0);
280
281                ret = servicestop(status.aktservice, 1, 1);
282                if(ret == 1)
283                {
284                        debug(150, "can't stop ts playback service");   
285                }
286                else
287                        status.aktservice->channel = NULL;
288
289                               
290                node = gettmpchannel();
291                if(node != NULL && ostrcmp(node->name, "player") == 0)
292                        delchannel(node->serviceid, node->transponderid, 1);
293        }
294}
295
296void playerresetts()
297{
298        audiostop(status.aktservice->audiodev);
299        videostop(status.aktservice->videodev, 0);
300#ifdef MIPSEL
301        videoclearbuffer(status.aktservice->videodev);
302        audioclearbuffer(status.aktservice->audiodev);
303#endif
304        videoplay(status.aktservice->videodev);
305        audioplay(status.aktservice->audiodev);
306}
307
308void playercontinuets()
309{
310        videocontinue(status.aktservice->videodev);
311        audioplay(status.aktservice->audiodev);
312}
313
314void playerpausets()
315{
316        videofreeze(status.aktservice->videodev);
317        audiopause(status.aktservice->audiodev);
318}
319
320//flag 0: with lock
321//flag 1: without lock
322int playerseekts(struct service* servicenode, int sekunden, int flag)
323{
324        off64_t offset = 0;
325        off64_t endoffile = 0;
326        off64_t currentpos = 0;
327        //off64_t fdptspos = 0;
328        //int ret = 0;
329        unsigned long long lenpts = 0;
330        unsigned long long startpts = 0;
331        unsigned long long endpts = 0;
332        unsigned long long bitrate = 0;
333        //unsigned long long aktpts = 0;
334        //unsigned long long fdpts = 0;
335        //int aktsekunden = 0;
336        int sekundenoff = 0;
337       
338        if(servicenode == NULL) return 1;
339
340        if(servicenode->recsrcfd < 0)
341        {
342                err("source fd not ok");
343                return 1;
344        }
345       
346        if(flag == 0) m_lock(&status.tsseekmutex, 15);
347
348/*
349        ret = videogetpts(status.aktservice->videodev, &aktpts);
350        if(ret == 0)
351        {
352                aktsekunden = aktpts / 90000;
353        }
354        else
355                aktsekunden = 0;
356        ret = getpts(servicenode->recsrcfd, 0, 0, 256 * 1024, &fdpts, &fdptspos, -1, servicenode->tssize);
357        if(ret == 0 && aktsekunden != 0)
358        {
359                sekundenoff = fdpts / 90000 - aktsekunden ;
360                //currentpos = lseek64(servicenode->recsrcfd, fdptspos, SEEK_SET);
361        }
362        else
363                sekundenoff = 0;
364*/
365       
366        currentpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);
367
368        lenpts = servicenode->lenpts;
369        startpts = servicenode->startpts;
370        endpts = servicenode->endpts;
371        bitrate = servicenode->bitrate;
372        if(gettsinfo(servicenode->recsrcfd, &lenpts, &startpts, &endpts, &bitrate, servicenode->tssize) != 0)
373        {
374                err("can't read ts info");
375                lseek64(servicenode->recsrcfd, currentpos, SEEK_SET);
376                if(flag == 0) m_unlock(&status.tsseekmutex, 15);
377                return 1;
378        }
379        if(servicenode->endoffile > 0)
380                endoffile = servicenode->endoffile - (servicenode->tssize * 2);
381        else
382                endoffile = lseek64(servicenode->recsrcfd , -servicenode->tssize * 2, SEEK_END);
383
384/*
385        ret = videoclearbuffer(status.aktservice->videodev);
386        ret = audioclearbuffer(status.aktservice->audiodev);
387        ret = videodiscontinuityskip(status.aktservice->videodev, 0);
388*/
389
390        if(sekunden >= 0)
391        {
392                if(sekundenoff != 0)
393                        offset = (bitrate / 8) * (sekunden - sekundenoff);
394                else
395                        offset = (bitrate / 8) * sekunden - 5000000;
396                offset = offset - (offset % servicenode->tssize);
397                if(currentpos + offset > endoffile)
398                {
399                        offset = endoffile - currentpos;
400                        offset = offset - (offset % servicenode->tssize);
401                }
402        }
403        else
404        {
405                sekunden = sekunden * -1;
406                if(sekundenoff != 0)
407                        offset = (bitrate / 8) * (sekunden + sekundenoff);
408                else
409                        offset = (bitrate / 8) * sekunden;
410                if(offset > 0) offset += 5000000;
411                offset = offset - (offset % servicenode->tssize);
412                if(currentpos - offset < 0)
413                        offset = currentpos;
414                offset = offset * -1;
415        }
416        offset += currentpos;
417        currentpos = lseek64(servicenode->recsrcfd, offset, SEEK_SET);
418
419        playerresetts();
420
421        if(flag == 0) m_unlock(&status.tsseekmutex, 15);
422        return 0;
423}
424
425void playerffts(int speed)
426{
427#ifdef MIPSEL
428        audiostop(status.aktservice->audiodev);
429        videoslowmotion(status.aktservice->videodev, 0);
430        videofastforward(status.aktservice->videodev, speed);
431        videocontinue(status.aktservice->videodev);
432#else   
433        videofastforward(status.aktservice->videodev, speed);
434#endif
435}
436
437void playerslowts(int speed)
438{
439#ifdef MIPSEL
440        audiostop(status.aktservice->audiodev);
441        videoslowmotion(status.aktservice->videodev, speed);
442        videofastforward(status.aktservice->videodev, 0);
443        videocontinue(status.aktservice->videodev);
444#else           
445        videoslowmotion(status.aktservice->videodev, speed);
446#endif
447}
448
449//flag = 0 --> recordplay
450//flag = 1 --> timeshift
451void playerfrts(int speed, int flag)
452{
453        if(flag == 1)
454                videocontinue(status.aktservice->videodev);
455        if(speed == -2)
456        {
457                videoclearbuffer(status.aktservice->videodev);
458                audioclearbuffer(status.aktservice->audiodev);
459        }
460        speed *= -1;
461#ifdef MIPSEL
462        audiostop(status.aktservice->audiodev);
463        videoslowmotion(status.aktservice->videodev, 0);
464        videofastforward(status.aktservice->videodev, speed);
465        videocontinue(status.aktservice->videodev);
466#else   
467        videofastforward(status.aktservice->videodev, speed);
468#endif
469}
470       
471
472//flag = 0 --> play ts
473//flag = 1 --> timeshift
474//flag = 2 --> timeshift, not in play mode (only recording)
475int playergetinfots(unsigned long long* lenpts, unsigned long long* startpts, unsigned long long* endpts, unsigned long long* aktpts, unsigned long long* bitrate, int flag)
476{
477        int ret = 0, dupfd = -1;
478        double ratio = 0;
479        struct service* snode = NULL;
480        unsigned long long lenpts1 = 0;
481        unsigned long long startpts1 = 0;
482        unsigned long long endpts1 = 0;
483        unsigned long long bitrate1 = 0;
484        unsigned long long endoffile1 = 0;
485        unsigned long long aktpos = 0;
486       
487        if(flag == 2)
488                snode = getservice(RECORDTIMESHIFT, 0);
489        else
490                snode = getservice(RECORDPLAY, 0);
491               
492        if(snode == NULL) return 1;
493
494        if(snode->lenpts > 0 && snode->startpts > 0 && snode->endpts > 0 && snode->bitrate > 0 && snode->endoffile > 0)
495        {
496                if(lenpts != NULL) *lenpts = snode->lenpts;
497                if(startpts != NULL) *startpts = snode->startpts;
498                if(endpts != NULL) *endpts = snode->endpts;
499                if(bitrate != NULL) *bitrate = snode->bitrate;
500
501                //ret = videogetpts(status.aktservice->videodev, aktpts);
502                if(aktpts != NULL)
503                {
504                        m_lock(&status.tsseekmutex, 15);
505                        if(flag == 2)
506                                aktpos = lseek64(snode->recdstfd , 0, SEEK_CUR);
507                        else
508                                aktpos = lseek64(snode->recsrcfd , 0, SEEK_CUR);
509                        m_unlock(&status.tsseekmutex, 15);
510
511                        ratio = (double)snode->endoffile / (double)(snode->endpts - snode->startpts);
512                        if(ratio == 0) ratio = 1;
513                        *aktpts = ((double)aktpos / ratio);
514                        *aktpts += snode->startpts;
515                }
516
517                return ret;
518        }
519       
520        dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
521        if(dupfd < 0)
522        {
523                err("copy source fd not ok");
524                return 1;
525        }
526
527        lenpts1 = snode->lenpts;
528        startpts1 = snode->startpts;
529        endpts1 = snode->endpts;
530        bitrate1 = snode->bitrate;
531        if(gettsinfo(dupfd, &lenpts1, &startpts1, &endpts1, &bitrate1, snode->tssize) != 0)
532        {
533                err("can't read ts info");
534                return 1;
535        }
536
537        if(lenpts != NULL) *lenpts = lenpts1;
538        if(startpts != NULL) *startpts = startpts1;
539        if(endpts != NULL) *endpts = endpts1;
540        if(bitrate != NULL) *bitrate = bitrate1;
541
542        //ret = videogetpts(status.aktservice->videodev, aktpts);
543        if(aktpts != NULL)
544        {
545                m_lock(&status.tsseekmutex, 15);
546                if(flag == 2)
547                        aktpos = lseek64(snode->recdstfd, 0, SEEK_CUR);
548                else
549                        aktpos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
550                m_unlock(&status.tsseekmutex, 15);
551
552                if(snode->endoffile <= 0)
553                        endoffile1 = lseek64(dupfd, 0, SEEK_END);
554                else
555                        endoffile1 = snode->endoffile;
556
557                if(endpts1 == 0)
558                        ratio = 1;
559                else
560                        ratio = (double)endoffile1 / (double)(endpts1 - startpts1);
561
562                if(ratio == 0) ratio = 1;
563                *aktpts = ((double)aktpos / ratio);
564                *aktpts += startpts1;
565        }
566
567        close(dupfd);
568        return ret;
569}
570
571void playerchangeaudiotrackts()
572{
573        screenaudiotrack();
574}
575
576void playerchangesubtitletrackts()
577{
578        screensubtitle();
579}
580
581int playerisplayingts()
582{
583        struct service* snode = getservice(RECORDPLAY, 0);
584
585        if(snode == NULL)
586                return 0;
587        return 1;
588}
589
590void playerafterendts()
591{
592        playerstopts(2, 0);
593}
594
595//extern player
596int playerstart(char* file)
597{
598        char * tmpfile = NULL;
599        status.prefillbuffer = 0;
600       
601        if(file != NULL)
602        {
603#ifdef EPLAYER3
604                //use eplayer
605
606                if(player != NULL)
607                {
608                        debug(150, "eplayer allready running");
609                        playerstop();
610                }
611
612                player = calloc(1, sizeof(Context_t));
613
614                if(player == NULL)
615                {
616                        err("no mem");
617                        return 1;
618                }
619
620                if(ostrstr(file, "://") == NULL)
621                        tmpfile = ostrcat("file://", file, 0, 0);
622                else
623                        tmpfile = ostrcat(file, NULL, 0, 0);
624
625                if(tmpfile == NULL)
626                {
627                        err("no mem");
628                        free(player); player = NULL;
629                        return 1;
630                }
631// move to mc
632//              set_player_sound(0);
633
634                if(ostrstr(tmpfile, "file://") == NULL)
635                        status.playercan = 0x4650;
636                else
637                        status.playercan = 0xFFFF;
638               
639                player->playback = &PlaybackHandler;
640                player->output = &OutputHandler;
641                player->container = &ContainerHandler;
642                player->manager = &ManagerHandler;
643               
644                //add container befor open, so we can set buffer size
645                char* ext = getfilenameext(tmpfile);
646                if(ext != NULL)
647                {
648                        player->container->Command(player, CONTAINER_ADD, ext);
649                        free(ext); ext = NULL;
650                }
651
652                //select container_ffmpeg, if we does not found a container with extensions
653                if(player->container->selectedContainer == NULL)
654                        player->container->Command(player, CONTAINER_ADD, "mp3");
655
656                if(player && player->container && player->container->selectedContainer)
657                {
658                        int size = getconfigint("playerbuffersize", NULL);
659                        int seektime = getconfigint("playerbufferseektime", NULL);
660                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SIZE, (void*)&size);
661                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SEEK_TIME, (void*)&seektime);
662                }
663               
664                debug(150, "eplayername = %s", player->output->Name);
665
666                //Registrating output devices
667                player->output->Command(player, OUTPUT_ADD, "audio");
668                player->output->Command(player, OUTPUT_ADD, "video");
669                player->output->Command(player, OUTPUT_ADD, "subtitle");
670               
671                //for subtitle
672                SubtitleOutputDef_t subout;
673
674                subout.screen_width = skinfb->width;
675                subout.screen_height = skinfb->height;
676                subout.framebufferFD = skinfb->fd;
677                subout.destination = (uint32_t *)skinfb->fb;
678                subout.destStride = skinfb->pitch;
679                subout.shareFramebuffer = 1;
680                subout.framebufferBlit = blitfb1;
681
682                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&subout);
683               
684                if(player->playback->Command(player, PLAYBACK_OPEN, tmpfile) < 0)
685                {
686                        free(player); player = NULL;
687                        free(tmpfile);
688                        return 1;
689                }
690
691                player->output->Command(player, OUTPUT_OPEN, NULL);
692                player->playback->Command(player, PLAYBACK_PLAY, NULL);
693
694                free(tmpfile);
695
696                return 0;
697#endif
698
699#ifdef EPLAYER4
700                int flags = 0x47; //(GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT);
701               
702                if(pipeline != NULL)
703                {
704                        debug(150, "eplayer allready running");
705                        playerstop();
706                }
707               
708                if(ostrstr(file, "://") == NULL)
709                        tmpfile = ostrcat("file://", file, 0, 0);
710                else
711                        tmpfile = ostrcat(file, NULL, 0, 0);
712
713                if(tmpfile == NULL)
714                {
715                        err("no mem");
716                        free(pipeline); pipeline = NULL;
717                        return 1;
718                }
719
720                if(ostrstr(tmpfile, "file://") == NULL)
721                        //status.playercan = 0x7E7F;
722                        status.playercan = 0x7EFF;
723                else
724                        //status.playercan = 0x7E7F;
725                        status.playercan = 0x7EFF;
726       
727                pipeline = gst_element_factory_make("playbin2", "playbin");
728
729// enable buffersize start
730                int size = getconfigint("playerbuffersize", NULL);
731                printf("size: %d\n",size);
732               
733                if(size > 0)
734                        status.prefillbuffer = 1;
735
736                g_object_set(G_OBJECT(pipeline), "buffer-duration", size * GST_SECOND, NULL);
737                g_object_set(G_OBJECT(pipeline), "buffer-size", size, NULL);
738// enable buffersizeend
739
740                g_object_set(G_OBJECT(pipeline), "uri", tmpfile, NULL);
741                g_object_set(G_OBJECT(pipeline), "flags", flags, NULL);
742                free(tmpfile); tmpfile = NULL;
743
744///////////////////
745// srt subs start
746                const char *filename = file;
747                const char *ext = strrchr(filename, '.');
748                if (!ext)
749                        ext = filename + strlen(filename);
750
751                GstElement *subsink = gst_element_factory_make("subsink", "subtitle_sink");
752                if (!subsink)
753                        printf("sorry, can't play: missing gst-plugin-subsink\n");
754                else
755                {
756//                      m_subs_to_pull_handler_id = g_signal_connect (subsink, "new-buffer", G_CALLBACK (gstCBsubtitleAvail), this);
757                        g_object_set (G_OBJECT (subsink), "caps", gst_caps_from_string("text/plain; text/x-plain; text/x-raw; text/x-pango-markup; video/x-dvd-subpicture; subpicture/x-pgs"), NULL);
758                        g_object_set (G_OBJECT (pipeline), "text-sink", subsink, NULL);
759                        g_object_set (G_OBJECT (pipeline), "current-text", -1, NULL);
760                }
761
762//gpointer this;
763//memset (&this, 0, sizeof (this));
764
765                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
766#if GST_VERSION_MAJOR < 1
767//              gst_bus_set_sync_handler(bus, gstBusSyncHandler, this);
768                gst_bus_set_sync_handler(bus, GST_BUS_DROP, NULL);
769#else
770//              gst_bus_set_sync_handler(bus, gstBusSyncHandler, this, NULL);
771                gst_bus_set_sync_handler(bus, GST_BUS_DROP, NULL, NULL);
772#endif
773
774                gst_object_unref(bus);
775                char srt_filename[ext - filename + 5];
776                strncpy(srt_filename,filename, ext - filename);
777                srt_filename[ext - filename] = '\0';
778                strcat(srt_filename, ".srt");
779
780                if(access(srt_filename, R_OK) >= 0)
781                {
782                        printf("found srt1: %s\n",srt_filename);
783                        printf("found srt2: %s\n",g_filename_to_uri(srt_filename, NULL, NULL));
784                        g_object_set(G_OBJECT (pipeline), "suburi", g_filename_to_uri(srt_filename, NULL, NULL), NULL);         
785                }
786// srt end     
787
788///////////////////
789//              CustomData data;
790                memset (&data, 0, sizeof (data));
791                data.pipeline = pipeline;
792//              GstBus *bus;
793//              bus = gst_element_get_bus (pipeline);
794               
795                // Start playing //
796                GstStateChangeReturn ret;
797                ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
798                if(ret == GST_STATE_CHANGE_FAILURE)
799                {
800                        g_printerr ("Unable to set the pipeline to the playing state.\n");
801                        gst_object_unref (pipeline);
802                        return -1;
803                }
804                else if(ret == GST_STATE_CHANGE_NO_PREROLL)
805                {
806                        data.is_live = TRUE;
807                }
808
809                data.loop = g_main_loop_new (NULL, FALSE);
810                data.pipeline = pipeline;
811                gst_bus_add_signal_watch (bus);
812//              g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data);
813//              status.prefillbuffer = 1;
814
815//analyze_streams(data);
816
817                int count = 0;
818                m_gst_startpts = 0;
819                while(m_gst_startpts == 0 && count < 5)
820                {
821                        count++;
822                        sleep(1);
823                        m_gst_startpts = playergetpts();
824                }
825
826                return 0;
827#endif
828        }
829       
830        return 1;
831}
832
833#ifdef EPLAYER4
834int setBufferSize(int size)
835{
836        int m_buffer_size = size;
837        g_object_set (G_OBJECT (pipeline), "buffer-size", m_buffer_size, NULL);
838        return 0;
839}
840#endif
841
842void playerinit(int argc, char* argv[])
843{
844#ifdef EPLAYER4
845//      GstBus *bus;
846//      GstStateChangeReturn ret;
847//      gint flags;
848        gst_init(&argc, &argv);
849#endif
850}
851
852#ifdef EPLAYER4
853int gstbuscall(GstBus *bus, GstMessage *msg, CustomData *data)
854{
855        int ret = 1;
856        if(!pipeline) return 0;
857        if(!msg) return ret;
858
859        gchar *sourceName = NULL;
860        GstObject *source = GST_MESSAGE_SRC(msg);
861
862        if(!GST_IS_OBJECT(source)) return ret;
863        sourceName = gst_object_get_name(source);
864
865        debug(150, "gst type: %s", GST_MESSAGE_TYPE_NAME(msg));
866
867        switch(GST_MESSAGE_TYPE(msg))
868        {
869                case GST_MESSAGE_EOS:
870                        debug(150, "gst player eof");
871                        ret = 0;
872                        break;
873                case GST_MESSAGE_STATE_CHANGED:
874                        debug(150, "gst message state changed");
875                        if(GST_MESSAGE_SRC(msg) != GST_OBJECT(pipeline))
876                                break;
877
878                        GstState old_state, new_state, pending_state;
879                        gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
880                        if(GST_MESSAGE_SRC(msg) == GST_OBJECT(pipeline))
881                        {
882                                if(new_state == GST_STATE_PLAYING)
883                                {
884                                        /* Once we are in the playing state, analyze the streams */
885                                        analyze_streams(data);
886                                }
887                        }
888
889                        if(old_state == new_state) break;
890       
891                        debug(150, "gst state change %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
892       
893                        GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
894       
895                        switch(transition)
896                        {
897                                case GST_STATE_CHANGE_NULL_TO_READY:
898                                        break;
899                                case GST_STATE_CHANGE_READY_TO_PAUSED:
900/*
901                                        GstElement *appsink = gst_bin_get_by_name(GST_BIN(pipeline), "subtitle_sink");
902                                        if(appsink)
903                                        {
904                                                g_object_set(G_OBJECT(appsink), "max-buffers", 2, NULL);
905                                                g_object_set(G_OBJECT(appsink), "sync", FALSE, NULL);
906                                                g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, NULL);
907                                                gst_object_unref(appsink);
908                                        }
909*/
910                                        break;
911                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
912                                        //if(m_sourceinfo.is_streaming && m_streamingsrc_timeout )
913                                                //m_streamingsrc_timeout->stop();
914                                        break;
915                                case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
916                                        break;
917                                case GST_STATE_CHANGE_PAUSED_TO_READY:
918                                        break;
919                                case GST_STATE_CHANGE_READY_TO_NULL:
920                                        ret = 0;
921                                        break;
922                        }
923                        break;
924                case GST_MESSAGE_ERROR:
925                        debug(150, "gst player error");
926
927                        gchar *gdebug1;
928                        GError *err;
929
930                        gst_message_parse_error(msg, &err, &gdebug1);
931                        g_free(gdebug1);
932
933                        debug(150, "gst error: %s (%i) from %s", err->message, err->code, sourceName);
934                        if(err->domain == GST_STREAM_ERROR)
935                        {
936                                if(err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
937                                {
938                                        //if(g_strrstr(sourceName, "videosink"))
939                                        //      m_event((iPlayableService*)this, evUser+11);
940                                        //else if ( g_strrstr(sourceName, "audiosink") )
941                                        //      m_event((iPlayableService*)this, evUser+10);
942                                }
943                        }
944                        g_error_free(err);
945                        break;
946                case GST_MESSAGE_INFO:
947                        debug(150, "gst player info");
948
949/*
950                        gchar *gdebug2;
951                        GError *inf;
952       
953                        gst_message_parse_info(msg, &inf, &gdebug2);
954                        g_free(gdebug2);
955                        if(inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
956                        {
957                                //if(g_strrstr(sourceName, "videosink"))
958                                //      m_event((iPlayableService*)this, evUser+14);
959                        }
960                        g_error_free(inf);
961*/
962                        break;
963                case GST_MESSAGE_TAG:
964                        debug(150, "gst player tag");
965                        break;
966                //case GST_MESSAGE_ASYNC_DONE:
967                //      debug(150, "gst player async done");
968                //      break;
969                case GST_MESSAGE_ELEMENT:
970                        debug(150, "gst player element");
971                        break;
972                case GST_MESSAGE_BUFFERING:
973                        debug(150, "gst player buffering");
974
975/*
976                        GstBufferingMode mode;
977                        gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
978                        gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
979                        //m_event((iPlayableService*)this, evBuffering);
980*/
981
982                        if (data->is_live) break;
983                        gst_message_parse_buffering (msg, &status.bufferpercent);
984
985                        if(status.prefillbuffer == 1)
986                        {
987//                              gint percent = 0;
988//                              if (data->is_live) break;
989//                              gst_message_parse_buffering (msg, &status.bufferpercent);
990                                g_print ("Buffering (%3d%%)\r", status.bufferpercent);
991
992                                if (status.bufferpercent < 100)
993                                {
994                                        gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
995                                        struct skin* waitmsgbar = getscreen("waitmsgbar");
996                                        struct skin* load = getscreen("loading");
997       
998                                        waitmsgbar->progresssize = status.bufferpercent;
999                                        char* tmpstr = NULL;
1000                                        tmpstr = ostrcat(_("Buffering Stream - Cancel with Exit"), " (", 0, 0);
1001                                        tmpstr = ostrcat(tmpstr, oitoa(waitmsgbar->progresssize), 1, 0);
1002                                        tmpstr = ostrcat(tmpstr, "%)", 1, 0);
1003                                        changetext(waitmsgbar, tmpstr);
1004                                        free(tmpstr); tmpstr = NULL;
1005       
1006                                        drawscreen(load, 0, 0);
1007                                        drawscreen(waitmsgbar, 0, 0);
1008                                        status.cleaninfobar = 0;
1009                                }
1010                                else
1011                                {
1012                                        drawscreen(skin, 0, 0);
1013                                        gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
1014                                        status.prefillbuffer = 0;
1015                                        status.cleaninfobar = 1;
1016                                }
1017       
1018                        }
1019                        else if(status.prefillbuffer == 2)
1020                        {
1021                                drawscreen(skin, 0, 0);
1022                                gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
1023                                status.prefillbuffer = 0;
1024                                status.cleaninfobar = 1;
1025                        }
1026                        else if(status.cleaninfobar == 1)
1027                        {
1028                                drawscreen(skin, 0, 0);
1029                                status.cleaninfobar = 0;
1030                        }
1031
1032                        break;
1033 
1034/*
1035                        GstBufferingMode mode;
1036                        gst_message_parse_buffering(msg, &(status.bufferpercent));
1037                        gst_message_parse_buffering_stats(msg, &mode, &(status.avgInRate), &(status.avgOutRate), &(status.bufferingLeft));
1038
1039//                      printf("#########################################################\n");
1040//                      printf("Buffering %u percent done\n", status.bufferpercent);
1041//                      printf("avgInRate %d\n", status.avgInRate);
1042//                      printf("avgOutRate %d\n", status.avgOutRate);
1043//                      printf("bufferingLeft %lld\n", status.bufferingLeft);
1044                                       
1045                        if(status.prefillbuffer == 1)
1046                        {
1047                                printf("status.prefillbuffer Buffering %u percent done\n", status.bufferpercent);
1048
1049                                if (status.bufferpercent == 100)
1050                                {
1051                                        GstState state;
1052                                        gst_element_get_state(pipeline, &state, NULL, 0LL);
1053                                        if (state != GST_STATE_PLAYING)
1054                                        {
1055                                                // eDebug("start playing");
1056                                                gst_element_set_state (pipeline, GST_STATE_PLAYING);
1057                                        }
1058//                                      m_ignore_buffering_messages = 5;
1059                                        status.prefillbuffer = 0;
1060                                }
1061                                else if (status.bufferpercent == 0)
1062                                {
1063                                        // eDebug("start pause");
1064                                        gst_element_set_state (pipeline, GST_STATE_PAUSED);
1065//                                      m_ignore_buffering_messages = 0;
1066                                }
1067                        }
1068*/
1069/*
1070                                GstBufferingMode mode;
1071                                printf("GST_STATE_PAUSED\n");
1072                                gst_element_set_state (pipeline, GST_STATE_PAUSED);
1073
1074
1075                                gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
1076                                // eDebug("Buffering %u percent done", m_bufferInfo.bufferPercent);
1077                                gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
1078                                m_event((iPlayableService*)this, evBuffering);
1079                                if (m_use_prefillbuffer && !m_is_live && --m_ignore_buffering_messages <= 0)
1080                                {
1081                                        if (m_bufferInfo.bufferPercent == 100)
1082                                        {
1083                                                GstState state;
1084                                                gst_element_get_state(pipeline, &state, NULL, 0LL);
1085                                                if (state != GST_STATE_PLAYING)
1086                                                {
1087                                                        // eDebug("start playing");
1088                                                        gst_element_set_state (pipeline, GST_STATE_PLAYING);
1089                                                }
1090                                                m_ignore_buffering_messages = 5;
1091                                        }
1092                                        else if (m_bufferInfo.bufferPercent == 0)
1093                                        {
1094                                                // eDebug("start pause");
1095                                                gst_element_set_state (pipeline, GST_STATE_PAUSED);
1096                                                m_ignore_buffering_messages = 0;
1097                                        }
1098                                        else
1099                                        {
1100                                                m_ignore_buffering_messages = 0;
1101                                        }
1102                                }
1103
1104*/
1105                        break;
1106                case GST_MESSAGE_STREAM_STATUS:
1107                        debug(150, "gst player stream status");
1108
1109/*
1110                        GstStreamStatusType type;
1111                        GstElement *owner;
1112
1113                        gst_message_parse_stream_status(msg, &type, &owner);
1114                        if(type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming)
1115                        {
1116                                if(GST_IS_PAD(source))
1117                                        owner = gst_pad_get_parent_element(GST_PAD(source));
1118                                else if(GST_IS_ELEMENT(source))
1119                                        owner = GST_ELEMENT(source);
1120                                else
1121                                        owner = NULL;
1122                                if(owner)
1123                                {
1124                                        GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
1125                                        const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
1126                                        if (!strcmp(name, "souphttpsrc"))
1127                                        {
1128                                                //m_streamingsrc_timeout->start(10 * 1000, true);
1129                                                g_object_set(G_OBJECT(owner), "timeout", 10, NULL);
1130                                        }
1131                                       
1132                                }
1133                                if(GST_IS_PAD(source))
1134                                        gst_object_unref(owner);
1135                        }
1136*/
1137                        break;
1138                default:
1139                        debug(150, "gst player unknown message");
1140                        break;
1141        }
1142        g_free(sourceName);
1143        return ret;
1144}
1145#endif
1146
1147int playergetbuffersize()
1148{
1149        int ret = 0;
1150
1151#ifdef EPLAYER3
1152        if(player && player->container && player->container->selectedContainer)
1153                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_SIZE, (void*)&ret);
1154#endif
1155
1156        return ret;
1157}
1158
1159int playergetbufferstatus()
1160{
1161        int ret = 0;
1162
1163#ifdef EPLAYER3
1164        if(player && player->container && player->container->selectedContainer)
1165                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_STATUS, (void*)&ret);
1166#endif
1167
1168        return ret;
1169}
1170
1171int playerstopbuffer()
1172{
1173        int ret = 0;
1174
1175#ifdef EPLAYER3
1176        if(player && player->container && player->container->selectedContainer)
1177                player->container->selectedContainer->Command(player, CONTAINER_STOP_BUFFER, NULL);
1178#endif
1179
1180        return ret;
1181}
1182
1183int playerisplaying()
1184{
1185#ifdef SIMULATE
1186        return 1;
1187#endif
1188
1189#ifdef EPLAYER3
1190        if(player != NULL && player->playback != NULL && player->playback->isPlaying)
1191                return 1;
1192#endif
1193
1194#ifdef EPLAYER4
1195        int ret = 1;
1196
1197        if(pipeline)
1198        {
1199                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
1200                GstMessage *message = NULL;
1201//use global variale, with static var crash
1202//              CustomData *data = NULL;
1203                while((message = gst_bus_pop(bus)))
1204                {
1205                        ret = gstbuscall(bus, message, &data);
1206                        gst_message_unref(message);
1207                }               
1208
1209// eof workaround for some mp4 files.
1210                gint64 pts = 0, len = 0, rest = 0;
1211                gint64 nanos_pts = 0, nanos_len = 0;
1212
1213                len = playergetlength();
1214                nanos_len = len * 1000000000;
1215                if(nanos_len < 0) nanos_len = 0;
1216
1217                pts = playergetpts();
1218                nanos_pts = pts * 11111;
1219
1220                rest = nanos_len - nanos_pts;
1221//              printf("rest: %lld\n", nanos_len - nanos_pts);
1222
1223                debug(150, "status.pause=%d status.playspeed=%d status.slowspeed=%d status.prefillbuffer=%d rest=%lld", status.pause, status.playspeed, status.slowspeed, status.prefillbuffer, rest);
1224                if(rest > 4000000000LL || status.pts != pts || pts == 0 || status.pause == 1 || status.playspeed != 0 || status.slowspeed != 0 /*|| status.prefillbuffer == 1*/)
1225                {
1226//                      debug(150, "status.pts=%llu / pts=%llu\n", status.pts, pts);
1227                        status.pts = pts;
1228                }
1229                else
1230                {
1231                        debug(150, "gst player eof - workaround (rest=%lld)", rest);
1232                        ret = 0;
1233                }
1234// eof workaround done
1235        }
1236        else
1237                ret = 0;
1238
1239        return ret;
1240#endif
1241        return 0;
1242}
1243
1244void playerplay()
1245{
1246#ifdef EPLAYER3
1247        if(player && player->playback)
1248                player->playback->Command(player, PLAYBACK_PLAY, NULL);
1249#endif
1250
1251#ifdef EPLAYER4
1252        if(pipeline)
1253                gst_element_set_state(pipeline, GST_STATE_PLAYING);
1254#endif
1255}
1256
1257int playerstop()
1258{
1259#ifdef EPLAYER3
1260        if(player && player->playback)
1261                player->playback->Command(player, PLAYBACK_STOP, NULL);
1262        if(player && player->container && player->container->selectedContainer)
1263                player->container->selectedContainer->Command(player, CONTAINER_STOP, NULL);
1264        if(player && player->output)
1265        {
1266                player->output->Command(player, OUTPUT_CLOSE, NULL);
1267                player->output->Command(player, OUTPUT_DEL, (void*)"audio");
1268                player->output->Command(player, OUTPUT_DEL, (void*)"video");
1269                player->output->Command(player, OUTPUT_DEL, (void*)"subtitle");
1270        }
1271        if(player && player->playback)
1272                player->playback->Command(player, PLAYBACK_CLOSE, NULL);
1273
1274        free(player);
1275        player = NULL;
1276// move to mc
1277//      set_player_sound(1);
1278#endif
1279
1280#ifdef EPLAYER4
1281        if(video_sink)
1282        {
1283                gst_object_unref (video_sink);
1284                video_sink = NULL;
1285        }
1286        if(pipeline)
1287        {
1288                gst_element_set_state(pipeline, GST_STATE_NULL);
1289                gst_object_unref(GST_OBJECT(pipeline));
1290                pipeline = NULL;
1291        }
1292#endif
1293
1294        writesysint("/proc/sys/vm/drop_caches", 3, 0);
1295        return 0;
1296}
1297
1298void playerafterend()
1299{
1300#ifdef EPLAYER3
1301        if(player != NULL && player->playback != NULL)
1302                playerstop();
1303#endif
1304
1305#ifdef EPLAYER4
1306        if(pipeline)
1307                playerstop();
1308#endif
1309}
1310
1311void playerpause()
1312{
1313#ifdef EPLAYER3
1314        if(player && player->playback)
1315                player->playback->Command(player, PLAYBACK_PAUSE, NULL);
1316#endif
1317
1318#ifdef EPLAYER4
1319        if(pipeline)
1320                gst_element_set_state(pipeline, GST_STATE_PAUSED);
1321#endif
1322}
1323
1324void playercontinue()
1325{
1326#ifdef EPLAYER3
1327        if(player && player->playback)
1328                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
1329#endif
1330
1331#ifdef EPLAYER4
1332        if(pipeline)
1333        {
1334                if(status.playspeed != 0)
1335                        playersend_ff_fr_event(1);
1336                gst_element_set_state(pipeline, GST_STATE_PLAYING);
1337        }
1338#endif
1339}
1340
1341void playerff(int speed)
1342{
1343#ifdef EPLAYER3
1344        int speedmap = 0;
1345
1346        if (speed < 1) speed = 1;
1347        if (speed > 7) speed = 7;
1348
1349        switch(speed)
1350        {
1351                case 1: speedmap = 1; break;
1352                case 2: speedmap = 3; break;
1353                case 3: speedmap = 7; break;
1354                case 4: speedmap = 15; break;
1355                case 5: speedmap = 31; break;
1356                case 6: speedmap = 63; break;
1357                case 7: speedmap = 127; break;
1358        }
1359
1360        if(player && player->playback)
1361                player->playback->Command(player, PLAYBACK_FASTFORWARD, &speedmap);
1362#endif
1363
1364#ifdef EPLAYER4
1365        gdouble rate = 0;
1366       
1367        if (speed < 1) speed = 1;
1368        if (speed > 7) speed = 7;
1369
1370        switch(speed)
1371        {
1372                case 1: rate = 2; break;
1373                case 2: rate = 4; break;
1374                case 3: rate = 8; break;
1375                case 4: rate = 16; break;
1376                case 5: rate = 32; break;
1377                case 6: rate = 64; break;
1378                case 7: rate = 128; break;
1379        }
1380        playersend_ff_fr_event(rate);
1381#endif
1382}
1383
1384void playerslow(int speed)
1385{
1386#ifdef EPLAYER3
1387        int speedmap = 0;
1388
1389        if (speed < 1) speed = 1;
1390        if (speed > 7) speed = 7;
1391
1392        switch(speed)
1393        {
1394                case 1: speedmap = 1; break;
1395                case 2: speedmap = 3; break;
1396                case 3: speedmap = 7; break;
1397                case 4: speedmap = 15; break;
1398                case 5: speedmap = 31; break;
1399                case 6: speedmap = 63; break;
1400                case 7: speedmap = 127; break;
1401        }
1402
1403        if(player && player->playback)
1404                player->playback->Command(player, PLAYBACK_SLOWMOTION, &speedmap);
1405#endif
1406}
1407
1408void playerfr(int speed)
1409{
1410#ifdef EPLAYER3
1411        int speedmap = 0;
1412
1413        if (speed > -1) speed = -1;
1414        if (speed < -7) speed = -7;
1415
1416        switch(speed)
1417        {
1418                case -1: speedmap = -5; break;
1419                case -2: speedmap = -10; break;
1420                case -3: speedmap = -20; break;
1421                case -4: speedmap = -40; break;
1422                case -5: speedmap = -80; break;
1423                case -6: speedmap = -160; break;
1424                case -7: speedmap = -320; break;
1425        }
1426
1427        if(player && player->playback)
1428                player->playback->Command(player, PLAYBACK_FASTBACKWARD, &speedmap);
1429#endif
1430
1431#ifdef EPLAYER4
1432        gdouble rate = 0;
1433       
1434        if (speed > -1) speed = -1;
1435        if (speed < -7) speed = -7;
1436
1437        switch(speed)
1438        {
1439                case -1: rate = -2; break;
1440                case -2: rate = -4; break;
1441                case -3: rate = -8; break;
1442                case -4: rate = -16; break;
1443                case -5: rate = -32; break;
1444                case -6: rate = -64; break;
1445                case -7: rate = -128; break;
1446        }
1447        playersend_ff_fr_event(rate);
1448#endif
1449}
1450
1451void playerseek(float sec)
1452{
1453#ifdef EPLAYER3
1454        if(player && player->playback)
1455                player->playback->Command(player, PLAYBACK_SEEK, (void*)&sec);
1456#endif
1457
1458#ifdef EPLAYER4
1459        gint64 nanos_pts = 0, nanos_len = 0;
1460        gint64 pts = 0, len = 0;
1461        //GstFormat fmt = GST_FORMAT_TIME;
1462               
1463        if(pipeline)
1464        {
1465                len = playergetlength();
1466                nanos_len = len * 1000000000;
1467                if(nanos_len < 0) nanos_len = 0;
1468
1469                pts = playergetpts();
1470                nanos_pts = pts * 11111;
1471                nanos_pts = nanos_pts + (sec * 1000000000);
1472                if(nanos_pts < 0) nanos_pts = 0;
1473
1474                if(nanos_pts >= nanos_len)
1475                {
1476                        debug(150, "gst skip seeking");
1477//                      playerstop();
1478                }
1479                else
1480                        gst_element_seek(pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, nanos_pts, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
1481        }
1482#endif
1483}
1484
1485#ifdef EPLAYER4
1486audiotype_t gstCheckAudioPad(GstStructure* structure)
1487{
1488        if(!structure)
1489                return atUnknown;
1490
1491        if(gst_structure_has_name(structure, "audio/mpeg"))
1492        {
1493                gint mpegversion, layer = -1;
1494                if(!gst_structure_get_int (structure, "mpegversion", &mpegversion))
1495                        return atUnknown;
1496
1497                switch(mpegversion)
1498                {
1499                        case 1:
1500                                {
1501                                        gst_structure_get_int(structure, "layer", &layer);
1502                                        if(layer == 3)
1503                                                return atMP3;
1504                                        else
1505                                                return atMPEG;
1506                                        break;
1507                                }
1508                        case 2:
1509                                return atAAC;
1510                        case 4:
1511                                return atAAC;
1512                        default:
1513                                return atUnknown;
1514                }
1515        }
1516
1517        else if(gst_structure_has_name(structure, "audio/x-ac3") || gst_structure_has_name(structure, "audio/ac3"))
1518                return atAC3;
1519        else if(gst_structure_has_name(structure, "audio/x-dts") || gst_structure_has_name(structure, "audio/dts"))
1520                return atDTS;
1521#if GST_VERSION_MAJOR < 1
1522        else if(gst_structure_has_name(structure, "audio/x-raw-int"))
1523#else
1524        else if(gst_structure_has_name(structure, "audio/x-raw"))
1525#endif
1526                return atPCM;
1527
1528        return atUnknown;
1529}
1530
1531
1532subtype_t getSubtitleType(GstPad* pad, gchar *g_codec)
1533{
1534g_codec = NULL;
1535        subtype_t type = stUnknown;
1536#if GST_VERSION_MAJOR < 1
1537        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
1538#else
1539        GstCaps* caps = gst_pad_get_current_caps(pad);
1540#endif
1541        if (!caps && !g_codec)
1542        {
1543                caps = gst_pad_get_allowed_caps(pad);
1544        }
1545
1546        if (caps && !gst_caps_is_empty(caps))
1547        {
1548                GstStructure* str = gst_caps_get_structure(caps, 0);
1549                if (str)
1550                {
1551                        const gchar *g_type = gst_structure_get_name(str);
1552                        // eDebug("getSubtitleType::subtitle probe caps type=%s", g_type ? g_type : "(null)");
1553                        if (g_type)
1554                        {
1555                                if ( !strcmp(g_type, "video/x-dvd-subpicture") )
1556                                        type = stVOB;
1557                                else if ( !strcmp(g_type, "text/x-pango-markup") )
1558                                        type = stSRT;
1559                                else if ( !strcmp(g_type, "text/plain") || !strcmp(g_type, "text/x-plain") || !strcmp(g_type, "text/x-raw") )
1560                                        type = stPlainText;
1561                                else if ( !strcmp(g_type, "subpicture/x-pgs") )
1562                                        type = stPGS;
1563                                else
1564                                        printf("getSubtitleType::unsupported subtitle caps %s (%s)\n", g_type, g_codec ? g_codec : "(null)");
1565//                                      eDebug("getSubtitleType::unsupported subtitle caps %s (%s)", g_type, g_codec ? g_codec : "(null)");
1566                        }
1567                }
1568        }
1569        else if ( g_codec )
1570        {
1571                // eDebug("getSubtitleType::subtitle probe codec tag=%s", g_codec);
1572                if ( !strcmp(g_codec, "VOB") )
1573                        type = stVOB;
1574                else if ( !strcmp(g_codec, "SubStation Alpha") || !strcmp(g_codec, "SSA") )
1575                        type = stSSA;
1576                else if ( !strcmp(g_codec, "ASS") )
1577                        type = stASS;
1578                else if ( !strcmp(g_codec, "SRT") )
1579                        type = stSRT;
1580                else if ( !strcmp(g_codec, "UTF-8 plain text") )
1581                        type = stPlainText;
1582                else
1583                        printf("getSubtitleType::unsupported subtitle codec %s\n", g_codec);
1584        }
1585        else
1586                printf("getSubtitleType::unidentifiable subtitle stream!\n");
1587
1588        return type;
1589}
1590
1591#endif
1592
1593void playerfreetracklist(char** TrackList)
1594{
1595        int i = 0;
1596
1597        if(TrackList != NULL)
1598        {
1599                while(TrackList[i] != NULL)
1600                {
1601                        free(TrackList[i]);
1602                        free(TrackList[i + 1]);
1603                        i += 2;
1604                }
1605        }
1606}
1607
1608char** playergettracklist(int type)
1609{
1610        char ** TrackList = NULL;
1611#ifdef EPLAYER3
1612        if(player && player->manager)
1613        {
1614                switch(type)
1615                {
1616                        case 1:
1617                                if(player->manager->audio)
1618                                {
1619                                        player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
1620                                        debug(150, "Audio Track List");
1621                                }
1622                                break;
1623                        case 2:
1624                                if(player->manager->subtitle)
1625                                {
1626                                        player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
1627                                        debug(150, "Subtitle Track List");
1628                                }
1629                                break;
1630                        default:
1631                                if(player->manager->video)
1632                                {
1633                                        player->manager->video->Command(player, MANAGER_LIST, &TrackList);
1634                                        debug(150, "Video Track List");
1635                                }
1636                }
1637               
1638                int i = 0;
1639                if(TrackList != NULL)
1640                {
1641                        while(TrackList[i] != NULL)
1642                        {
1643                                string_newline(TrackList[i]);
1644                                i += 2;
1645                        }
1646                       
1647                        debug(150, "Track List");
1648                        i = 0;
1649                        while(TrackList[i] != NULL)
1650                        {
1651                                debug(150, "%s - %s", TrackList[i], TrackList[i + 1]);
1652                                i += 2;
1653                        }
1654                }
1655        }
1656#endif
1657
1658//////////////////////////////NEUER CODE //////////////////////////////
1659#ifdef EPLAYER4
1660        TrackList = calloc(1, sizeof(char *) * ((100 * 2) + 1));
1661       
1662        if(pipeline != NULL)
1663        {
1664                gint i, n_video = 0, n_audio = 0, n_text = 0;
1665               
1666                g_object_get(pipeline, "n-video", &n_video, NULL);
1667                g_object_get(pipeline, "n-audio", &n_audio, NULL);
1668                g_object_get(pipeline, "n-text", &n_text, NULL);
1669
1670                switch(type)
1671                {
1672                        case 1:
1673                                for(i = 0; i < n_audio; i++)
1674                                {
1675                                        GstTagList *tags = NULL;
1676                                        gchar *g_codec = NULL, *g_lang = NULL;
1677                                        char* tmpstr = NULL;
1678                                        GstPad* pad = 0;
1679                                       
1680                                        g_signal_emit_by_name (pipeline, "get-audio-pad", i, &pad);
1681#if GST_VERSION_MAJOR < 1
1682                                        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
1683#else
1684                                        GstCaps* caps = gst_pad_get_current_caps(pad);
1685#endif
1686                                        if(!caps)
1687                                                continue;
1688                                       
1689                                        GstStructure* str = gst_caps_get_structure(caps, 0);
1690                                        const gchar *g_type = gst_structure_get_name(str);
1691
1692                                        g_signal_emit_by_name(pipeline, "get-audio-tags", i, &tags);
1693
1694#if GST_VERSION_MAJOR < 1
1695                                        if(tags && gst_is_tag_list(tags))
1696#else
1697                                        if(tags && GST_IS_TAG_LIST(tags))
1698#endif
1699                                        {
1700                                                if(gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_codec))
1701                                                {
1702                                                        printf("Audio Codec: %s\n", g_codec);
1703       
1704                                                        tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
1705                                                        tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
1706                                                        if(g_codec != NULL && g_type != NULL)
1707                                                                tmpstr = ostrcat(tmpstr, " (", 1, 0);
1708                                                        tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
1709                                                        if(g_codec != NULL && g_type != NULL)
1710                                                                tmpstr = ostrcat(tmpstr, ")", 1, 0);
1711
1712                                                        printf("Tracklist tmpstr: %s\n", tmpstr);
1713
1714                                                        TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
1715                                                        g_free(tmpstr); tmpstr = NULL;
1716                                                        g_free(g_codec); g_codec = NULL;
1717                                                }
1718                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
1719                                                {
1720                                                        printf("Audio Lang: %s\n", g_lang);
1721                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
1722                                                        g_free(g_lang); g_lang = NULL;
1723                                                }
1724                                                gst_tag_list_free(tags);
1725                                        }
1726                                        else
1727                                        {
1728                                                printf("Audio Codec: %s\n", g_codec);
1729                                               
1730                                                tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
1731                                                tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
1732                                                if(g_codec != NULL && g_type != NULL)
1733                                                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1734                                                tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
1735                                                if(g_codec != NULL && g_type != NULL)
1736                                                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1737
1738                                                printf("Tracklist tmpstr: %s\n", tmpstr);                               
1739                                                TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
1740
1741                                                g_free(tmpstr); tmpstr = NULL;
1742                                                g_free(g_codec); g_codec = NULL;
1743                                        }
1744                                }
1745                                break;
1746                        case 2:
1747                                for(i = 0; i < n_text; i++)
1748                                {
1749                                        GstTagList *tags = NULL;
1750                                        gchar *g_codec = NULL, *g_lang = NULL;
1751                                        GstPad* pad = 0;
1752                                        char* tmpstr = NULL;
1753
1754                                        g_signal_emit_by_name (pipeline, "get-text-pad", i, &pad);
1755                                        printf("SubTitle Type: %d\n", getSubtitleType(pad, g_codec));
1756
1757#if GST_VERSION_MAJOR < 1
1758                                        GstCaps* caps = gst_pad_get_negotiated_caps(pad);
1759#else
1760                                        GstCaps* caps = gst_pad_get_current_caps(pad);
1761#endif
1762                                        if (!caps && !g_codec)
1763                                        {
1764                                                caps = gst_pad_get_allowed_caps(pad);
1765                                        }
1766                                               
1767                                        GstStructure* str = gst_caps_get_structure(caps, 0);
1768                                        const gchar *g_type = gst_structure_get_name(str);
1769
1770                                        g_signal_emit_by_name(pipeline, "get-text-tags", i, &tags);
1771                                       
1772#if GST_VERSION_MAJOR < 1
1773                                        if (tags && gst_is_tag_list(tags))
1774#else
1775                                        if (tags && GST_IS_TAG_LIST(tags))
1776#endif
1777                                        {
1778                                                if(gst_tag_list_get_string(tags, GST_TAG_SUBTITLE_CODEC, &g_codec));
1779                                                {
1780                                                        printf("SubTitle Codec: %s\n", g_codec);
1781                                                        tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
1782                                                        tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
1783                                                        if(g_codec != NULL && g_type != NULL)
1784                                                                tmpstr = ostrcat(tmpstr, " (", 1, 0);
1785                                                        tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
1786                                                        if(g_codec != NULL && g_type != NULL)
1787                                                                tmpstr = ostrcat(tmpstr, ")", 1, 0);
1788
1789                                                        printf("Tracklist tmpstr: %s\n", tmpstr);
1790                                                        TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
1791                                                        g_free(g_codec); g_codec = NULL;
1792                                                }
1793                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
1794                                                {
1795                                                        printf("SubTitle Lang: %s\n", g_lang);
1796                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
1797                                                        g_free(g_lang); g_lang = NULL;
1798                                                }
1799                                                gst_tag_list_free(tags);
1800                                        }
1801                                        else
1802                                        {
1803                                                printf("SubTitle Codec: %s\n", g_codec);
1804                                               
1805                                                tmpstr = ostrcat(oitoa(i), ": ", 1, 0);
1806                                                tmpstr = ostrcat(tmpstr, g_codec, 1, 0);
1807                                                if(g_codec != NULL && g_type != NULL)
1808                                                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1809                                                tmpstr = ostrcat(tmpstr, (gchar*)g_type, 1, 0);
1810                                                if(g_codec != NULL && g_type != NULL)
1811                                                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1812
1813                                                printf("Tracklist tmpstr: %s\n", tmpstr);               
1814                                                TrackList[i * 2] = ostrcat(tmpstr, NULL, 0, 0);
1815
1816                                                g_free(tmpstr); tmpstr = NULL;
1817                                                g_free(g_codec); g_codec = NULL;                               
1818                                        }
1819                                }
1820                                break;
1821                        default:
1822                                for(i = 0; i < n_video; i++)
1823                                {
1824                                        GstTagList *tags = NULL;
1825                                        gchar *g_codec = NULL, *g_lang = NULL;
1826                                       
1827                                        g_signal_emit_by_name(pipeline, "get-video-tags", i, &tags);
1828                                       
1829#if GST_VERSION_MAJOR < 1
1830                                        if (tags && gst_is_tag_list(tags))
1831#else
1832                                        if (tags && GST_IS_TAG_LIST(tags))
1833#endif
1834                                        {
1835                                                if(gst_tag_list_get_string(tags, GST_TAG_VIDEO_CODEC, &g_codec));
1836                                                {
1837                                                        printf("Video Codec: %s\n", g_codec);
1838                                                        TrackList[i * 2] = ostrcat(g_codec, NULL, 0, 0);
1839                                                        g_free(g_codec); g_codec = NULL;
1840                                                }
1841                                                if(gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
1842                                                {
1843                                                        printf("Video Lang: %s\n", g_lang);
1844                                                        TrackList[(i * 2) + 1] = ostrcat(g_lang, NULL, 0, 0);
1845                                                        g_free(g_lang); g_lang = NULL;
1846                                                }
1847                                                gst_tag_list_free(tags);
1848                                        }
1849                                }
1850                }
1851        }
1852#endif
1853//////////////////////////////NEUER CODE //////////////////////////////
1854
1855        return TrackList;
1856}
1857
1858//*CurTrackEncoding and *CurTrackName be freed
1859void playergetcurtrac(int type, int *CurTrackId, char** CurTrackEncoding, char** CurTrackName)
1860{
1861#ifdef EPLAYER3
1862        if(player && player->manager)
1863        {
1864                switch(type)
1865                {
1866                        case 1:
1867                                if(player->manager->audio)
1868                                {
1869                                        player->manager->audio->Command(player, MANAGER_GET, CurTrackId);
1870                                        player->manager->audio->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1871                                        player->manager->audio->Command(player, MANAGER_GETNAME, CurTrackName);
1872                                }
1873                                break;
1874                        case 2:
1875                                if(player->manager->subtitle)
1876                                {
1877                                        player->manager->subtitle->Command(player, MANAGER_GET, CurTrackId);
1878                                        player->manager->subtitle->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1879                                        player->manager->subtitle->Command(player, MANAGER_GETNAME, CurTrackName);
1880                                }
1881                                break;
1882                        default:
1883                                if(player->manager->video)
1884                                {
1885                                        player->manager->video->Command(player, MANAGER_GET, CurTrackId);
1886                                        player->manager->video->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1887                                        player->manager->video->Command(player, MANAGER_GETNAME, CurTrackName);
1888                                }
1889                }
1890
1891                if(CurTrackId != NULL)
1892                        debug(150, "Current Track ID: %d", *CurTrackId);
1893                if(*CurTrackEncoding != NULL)
1894                        debug(150, "Current Track Enc: %s", *CurTrackEncoding);
1895                if(*CurTrackName != NULL)
1896                        debug(150, "Current Track Name: %s", *CurTrackName);
1897        }
1898#endif
1899
1900#ifdef EPLAYER4
1901        if(pipeline != NULL)
1902        {
1903                switch(type)
1904                {
1905                        case 1:
1906                                g_object_get(G_OBJECT(pipeline), "current-audio", CurTrackId, NULL);
1907                                break;
1908                }
1909                if(CurTrackId != NULL) {
1910                        debug(150, "Current Track ID: %d", *CurTrackId);
1911                }
1912        }
1913#endif
1914}
1915
1916unsigned long long playergetpts()
1917{
1918        unsigned long long pts = 0;
1919        unsigned long long sec = 0;
1920
1921#ifdef EPLAYER3
1922        if(player && player->playback)
1923        {
1924                player->playback->Command(player, PLAYBACK_PTS, &pts);
1925                sec = pts / 90000;
1926                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
1927        }
1928#endif
1929
1930#ifdef EPLAYER4
1931        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1932       
1933/*
1934        if(pipeline)
1935        {
1936                gst_element_query_position(pipeline, &fmt, (gint64*)&pts);
1937                sec = pts / 1000000000;
1938                pts = sec * 90000;
1939                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
1940        }
1941*/
1942
1943        if(pipeline)
1944        {
1945                gint64 pos;
1946                GstElement *sink;
1947                pts = 0;
1948
1949                g_object_get(G_OBJECT (pipeline), "audio-sink", &sink, NULL);
1950
1951                if(!sink) g_object_get (G_OBJECT (pipeline), "video-sink", &sink, NULL);
1952                if(!sink) return 0;
1953
1954                gchar *name = gst_element_get_name(sink);
1955                gboolean use_get_decoder_time = ostrstr(name, "dvbaudiosink") || ostrstr(name, "dvbvideosink");
1956                g_free(name);
1957
1958                if(use_get_decoder_time) g_signal_emit_by_name(sink, "get-decoder-time", &pos);
1959
1960                gst_object_unref(sink);
1961
1962                if(!use_get_decoder_time && !gst_element_query_position(pipeline, &fmt, &pos))
1963                        return 0;
1964
1965                /* pos is in nanoseconds. we have 90 000 pts per second. */
1966                pts = pos / 11111;
1967                pts = pts - m_gst_startpts;
1968                sec = pts / 90000;
1969                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);
1970        }
1971#endif
1972
1973        if(pts < 0) pts = 0;
1974        return pts;
1975}
1976
1977double playergetlength()
1978{
1979        double length = 0;
1980
1981#ifdef EPLAYER3
1982        if(player && player->playback)
1983        {
1984                player->playback->Command(player, PLAYBACK_LENGTH, &length);
1985                if(length < 0) length = 0;
1986                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
1987        }
1988#endif
1989
1990#ifdef EPLAYER4
1991        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1992        gint64 len;
1993
1994        if(pipeline)
1995        {
1996                gst_element_query_duration(pipeline, &fmt, &len);
1997                length = len / 1000000000;
1998                if(length < 0) length = 0;
1999                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
2000        }
2001#endif
2002
2003        return length;
2004}
2005
2006char* playergetinfo(char* tag)
2007{
2008        char* ret = NULL;
2009
2010#ifdef EPLAYER3
2011        char *tags[] = {"Title", "Artist", "Album", "Year", "Genre", "Comment", "Track", "Copyright", "TestLibEplayer", NULL};
2012        int i = 0;
2013
2014        if(player && player->playback)
2015        {
2016                while(tags[i] != NULL)
2017                {
2018                        ret = tags[i];
2019                        if(ostrcmp(tag, ret) == 0)
2020                        {
2021                                player->playback->Command(player, PLAYBACK_INFO, &ret);
2022                                break;
2023                        }
2024
2025                        i++;
2026                }
2027        }
2028#endif
2029        return ret;
2030}
2031
2032void playerchangeaudiotrack(int num)
2033{
2034#ifdef EPLAYER3
2035        if(player && player->playback)
2036                player->playback->Command(player, PLAYBACK_SWITCH_AUDIO, (void*)&num);
2037#endif
2038
2039#ifdef EPLAYER4
2040        if(pipeline != NULL)
2041                g_object_set(G_OBJECT(pipeline), "current-audio", num, NULL);   
2042#endif
2043}
2044
2045void playerchangesubtitletrack(int num)
2046{
2047#ifdef EPLAYER3
2048        if(player && player->playback)
2049                player->playback->Command(player, PLAYBACK_SWITCH_SUBTITLE, (void*)&num);
2050#endif
2051
2052#ifdef EPLAYER4
2053        if(pipeline != NULL)
2054                g_object_set(G_OBJECT(pipeline), "current-text", num, NULL);   
2055#endif
2056}
2057
2058void playerstopsubtitletrack()
2059{
2060#ifdef EPLAYER3
2061        if(player && player->output && player->output->subtitle)
2062                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_STOP, NULL);
2063        if(player && player->container && player->container->assContainer)
2064        {
2065                player->container->assContainer->Command(player, CONTAINER_STOP, NULL);
2066                player->container->assContainer->Command(player, CONTAINER_INIT, NULL);
2067        }
2068        if(player && player->manager && player->manager->subtitle)
2069        {
2070                int onlycurrent = 1;
2071                player->manager->subtitle->Command(player, MANAGER_DEL, (void*)&onlycurrent);
2072        }
2073#endif
2074
2075#ifdef EPLAYER4
2076        if(pipeline != NULL)
2077                g_object_set(G_OBJECT(pipeline), "current-text", -1, NULL);
2078#endif
2079}
2080
2081int playerjumpts(struct service* servicenode, int sekunden, int *startpts, off64_t *poslastpts, off64_t *bitrate, int vpid, int tssize)
2082{
2083        int adaptation = 0;
2084        int payload = 0;
2085        int pes = 0;
2086        int tspid = 0;
2087       
2088        off64_t pts  = 0;
2089        uint64_t aktpts = 0;
2090        long long unsigned int lenpts = 0;
2091        long long unsigned int startpts1 = 0;
2092        long long unsigned int endpts = 0;
2093        long long unsigned int aktbitrate = 0;
2094        off64_t ziehlpts = 0;
2095
2096        off64_t curpos = 0;
2097        off64_t newpos = 0;
2098        off64_t jump = 0;
2099
2100        int kleiner = 0;
2101        int groesser = 0;
2102        int gleich = 0;
2103        int len = 0;
2104        int i = 0;
2105        int ret = 0;
2106
2107        if(servicenode == NULL) return -1;
2108
2109        int buflen = tssize * 15000;
2110        char *buf = malloc(buflen);
2111        if(buf == NULL)
2112                return -1;
2113       
2114        curpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);   
2115        int dupfd = open(servicenode->recname, O_RDONLY | O_LARGEFILE);
2116        newpos = lseek64(dupfd, curpos, SEEK_SET);
2117       
2118        if (*startpts == 0)
2119        {
2120                if(videogetpts(status.aktservice->videodev, &aktpts) == 0)
2121                {
2122                                ziehlpts = (aktpts / 90000) + sekunden;
2123                }
2124                else
2125                        return 1;
2126        }
2127        else
2128        {
2129                ziehlpts = *startpts + sekunden;
2130        }
2131        *startpts = ziehlpts;
2132
2133        if(*bitrate == 0)
2134        {
2135                lenpts = servicenode->lenpts;
2136                startpts1 = servicenode->startpts;
2137                endpts = servicenode->endpts;
2138                aktbitrate = servicenode->bitrate;
2139                ret = gettsinfo(dupfd, &lenpts, &startpts1, &endpts, &aktbitrate, servicenode->tssize);
2140                if(ret != 0)
2141                {
2142                        err("can't read ts info");
2143                }
2144                else
2145                        *bitrate = aktbitrate;
2146                newpos = lseek64(dupfd, curpos, SEEK_SET);
2147        }
2148        else
2149                aktbitrate = *bitrate;
2150               
2151        if(*poslastpts == 0)
2152                *poslastpts = curpos;
2153       
2154        if(sekunden > 0)
2155        {
2156                err("not implemented");
2157                return 1;
2158        }       
2159        else if(sekunden < 0)
2160        {
2161                sekunden = sekunden * -1;
2162                if(aktbitrate != 0)
2163                {
2164                        jump = (aktbitrate / 8) * sekunden;
2165                        jump = jump + (curpos - *poslastpts);
2166                        jump = jump + (jump % servicenode->tssize);
2167                        newpos = lseek64(dupfd, -jump, SEEK_CUR);
2168                }
2169                else
2170                        newpos = lseek64(dupfd, - buflen, SEEK_CUR);
2171                if(newpos < 0)
2172                        newpos = lseek64(dupfd, tssize, SEEK_SET);
2173        }
2174        len = read(dupfd, buf, buflen);
2175        for(i = 0; i < len; i = i + 1)
2176        {
2177                if (buf[i] == 0x47 && buf[i+tssize] == 0x47)
2178                {
2179                        newpos = lseek64(dupfd, newpos + i, SEEK_SET);
2180                        break;
2181                }
2182        }
2183        if(i >= len)
2184        {
2185                newpos = lseek64(dupfd, curpos, SEEK_SET);     
2186                return 1;
2187        }
2188        while(1)
2189        {
2190        len = read(dupfd, buf, buflen);
2191
2192                if(len > 0)
2193                {
2194                        for(i = 0; i <= len-tssize; i = i + tssize)
2195                        {
2196                                payload = 0;
2197
2198                                tspid = (buf[i+1] & 0x1F) << 8;
2199                                tspid = tspid + (buf[i+2] & 0xFF);
2200                                pes = buf[i+1] & 0x40;
2201
2202                                if(tspid == vpid)
2203                                {       
2204                                        adaptation = buf[i+3] & 0x30;
2205                                        if(adaptation == 16)
2206                                        {
2207                                                payload = 4;
2208                                        }
2209                                        if(adaptation == 32)
2210                                        {
2211                                                //printf("adaptation field only\n");
2212                                        }
2213                                        if(adaptation == 48)
2214                                        {
2215                                                payload = buf[i+4] & 0xFF;
2216                                                payload = payload + 5;
2217                                        }
2218                                        if(payload != 0)
2219                                        {
2220                                                if(pes == 64)
2221                                                {
2222                                                        if(buf[i+payload+7] & 0x80) //PTS
2223                                                        {
2224                                                                pts = ((unsigned long long)(buf[i+payload+9] & 0xE)) << 29;
2225                                                                pts |= ((unsigned long long)(buf[i+payload+10] & 0xFF)) << 22;
2226                                                                pts |= ((unsigned long long)(buf[i+payload+11] & 0xFE)) << 14;
2227                                                                pts |= ((unsigned long long)(buf[i+payload+12] & 0xFF)) << 7;
2228                                                                pts |= ((unsigned long long)(buf[i+payload+13] & 0xFE)) >> 1;
2229                                                               
2230                                                                if(pts / 90000 == ziehlpts)
2231                                                                {
2232                                                                        gleich = newpos + i;
2233                                                                        break;
2234                                                                }
2235                                                                else if(pts / 90000 > ziehlpts)
2236                                                                {                                                                       
2237                                                                        groesser = newpos + i;
2238                                                                        break;
2239                                                                }
2240                                                                else
2241                                                                {
2242                                                                        kleiner = newpos + i;
2243                                                                }
2244                                                        }
2245                                                }
2246                                        }
2247                                }
2248                        }
2249                        if(gleich != 0)
2250                        {
2251                                close(dupfd);
2252                                free(buf);buf = NULL;
2253                                *poslastpts = lseek64(servicenode->recsrcfd, gleich, SEEK_SET);
2254                                return 0;
2255                        }
2256                        else if(groesser != 0 && kleiner != 0)
2257                        {
2258                                close(dupfd);
2259                                free(buf);buf = NULL;
2260                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
2261                                return 0;
2262                        }
2263                        else if(groesser != 0)
2264                        {
2265                                if((newpos - buflen)  < 0)
2266                                {
2267                                        close(dupfd);
2268                                        free(buf);buf = NULL;
2269                                        *poslastpts = 0;
2270                                        return -1       ;
2271                                }
2272                                else
2273                                {
2274                                        newpos = lseek64(dupfd, -(buflen * 2), SEEK_CUR);
2275                                }
2276                        }
2277                }
2278                else
2279                {
2280                        if(kleiner == 0)
2281                        {
2282                                close(dupfd);
2283                                free(buf);buf = NULL;
2284                                newpos = lseek64(servicenode->recsrcfd, curpos, SEEK_SET);
2285                                *poslastpts = 0;
2286                                return -1;
2287                        }
2288                        else
2289                        {
2290                                close(dupfd);
2291                                free(buf);buf = NULL;
2292                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
2293                                return 0;
2294                        }
2295                }
2296        }
2297}
2298
2299//praez = 1 .... sekunden
2300//                      =       2 .... zehntel
2301//                      = 3 .... hundertstel
2302//                      = 4 .... volle Uebereinstimmung
2303//
2304//type  = 0 .... alle
2305//                      = 1 .... nur PCR
2306//                      = 2 .... nur Video
2307//                      = 3 .... nur Audio
2308//
2309//flag = 0 --> play ts
2310//flag = 1 --> timeshift
2311//flag = 2 --> timeshift, not in play mode (only recording)
2312//flag = 9 --> dataset mode
2313//
2314off64_t playergetptspos(unsigned long long fpts, off64_t pos, int dir, int praez, int type, int flag, char* dsn)
2315{
2316        unsigned long long pts;
2317        int ret = 0, dupfd = -1, left = 0, tssize = 0, recbsize = 0;
2318        unsigned char* buf = NULL;
2319        unsigned char *payload;
2320        int pid = 0, pusi = 0;
2321        unsigned char* packet;
2322        struct service* snode;
2323       
2324        if(type > 3)
2325        {
2326                printf("type %i nicht unterstützt\n", type);
2327                return -1;
2328        }
2329       
2330        if(flag == 2)
2331                snode = getservice(RECORDTIMESHIFT, 0);
2332        else if(flag != 9)
2333                snode = getservice(RECORDPLAY, 0);
2334               
2335        if(flag == 9)
2336        {
2337                tssize = 188;
2338                recbsize = tssize * 1024 * 10;
2339                dupfd = open(dsn, O_RDONLY | O_LARGEFILE );
2340        }
2341        else
2342        {
2343                tssize = snode->tssize;
2344                recbsize = snode->tssize * 1024 * 10;
2345                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
2346        }
2347
2348        if(dupfd < 0)
2349        {
2350                err("copy source fd not ok");
2351                return -1;
2352        }
2353
2354        buf = malloc(recbsize);
2355        if(buf == NULL)
2356        {
2357                err("no mem");
2358                return -1;
2359        }
2360        packet = buf;
2361        if(dir > 0) 
2362                pos = lseek64(dupfd, pos, SEEK_SET);
2363        else
2364                pos = lseek64(dupfd, pos - recbsize, SEEK_SET);
2365       
2366        ret = read(dupfd,  buf, recbsize);
2367        close(dupfd);
2368        left = 0;
2369       
2370        if(buf[0] != 0x47)
2371        {
2372                while(left < tssize)
2373                {
2374                        if(buf[left] == 0x47) break;
2375                        left++;
2376                }
2377                if(left >= tssize)
2378                {
2379                        free(buf);
2380                        return -1;
2381                }       
2382        }
2383        pts = 0;
2384        while(left <= recbsize - tssize)
2385        {
2386                if(pts != 0)
2387                {
2388                        switch( praez )
2389          {
2390        case 1 :        if(fpts / 90000 != pts / 90000)
2391                                                        pts = 0;
2392                                                break;
2393        case 2 :        if(fpts / 9000 != pts / 9000)
2394                                                        pts = 0;
2395                                                break;
2396        case 3 :        if(fpts / 900 != pts / 900)
2397                                                        pts = 0;
2398                                                break;         
2399        case 4 :        if(fpts != pts )
2400                                                        pts = 0;
2401                                                break;
2402                                default :       free(buf); return -1; break;
2403                        }
2404                        if(pts != 0)
2405                        {       
2406                                pos = pos + left - tssize;
2407                                free(buf);
2408                                return pos;
2409                        }
2410                }
2411                packet = buf + left;
2412                left = left + tssize;
2413                                               
2414                pid = ((packet[1] << 8) | packet[2]) & 0x1FFF;
2415                pusi = !!(packet[1] & 0x40);
2416                //check for adaption field
2417                if(packet[3] & 0x20)
2418                {
2419                        if(type > 1)continue;
2420                        if(packet[4] >= 183) continue;
2421                        if(packet[4])
2422                        {
2423                                if(packet[5] & 0x10) //PCR present
2424                                {
2425                                        pts = ((unsigned long long)(packet[6] & 0xFF)) << 25;
2426                                        pts |= ((unsigned long long)(packet[7] & 0xFF)) << 17;
2427                                        pts |= ((unsigned long long)(packet[8] & 0xFE)) << 9;
2428                                        pts |= ((unsigned long long)(packet[9] & 0xFF)) << 1;
2429                                        pts |= ((unsigned long long)(packet[10] & 0x80)) >> 7;
2430                                        continue;
2431                                }
2432                        }
2433                        payload = packet + packet[4] + 4 + 1;
2434                } else
2435                        payload = packet + 4;
2436               
2437                if(type == 1) continue;
2438                if(!pusi) continue;
2439               
2440                if (payload[0] || payload[1] || (payload[2] != 1))
2441                        continue;
2442               
2443                        //stream use extension mechanism def in ISO 13818-1 Amendment 2
2444                if(payload[3] == 0xFD)
2445                {
2446                        if(payload[7] & 1) //PES extension flag
2447                        {
2448                                int offs = 0;
2449                                if(payload[7] & 0x80) offs += 5; //pts avail
2450                                if(payload[7] & 0x40) offs += 5; //dts avail
2451                                if(payload[7] & 0x20) offs += 6; //escr avail
2452                                if(payload[7] & 0x10) offs += 3; //es rate
2453                                if(payload[7] & 0x8) offs += 1; //dsm trickmode
2454                                if(payload[7] & 0x4) offs += 1; //additional copy info
2455                                if(payload[7] & 0x2) offs += 2; //crc
2456                                if(payload[8] < offs) continue;
2457
2458                                uint8_t pef = payload[9 + offs++]; //pes extension field
2459                                if(pef & 1) //pes extension flag 2
2460                                {
2461                                        if(pef & 0x80) offs += 16; //private data flag
2462                                        if(pef & 0x40) offs += 1; //pack header field flag
2463                                        if(pef & 0x20) offs += 2; //program packet sequence counter flag
2464                                        if(pef & 0x10) offs += 2; //P-STD buffer flag
2465                                        if(payload[8] < offs) continue;
2466
2467                                        uint8_t stream_id_extension_len = payload[9 + offs++] & 0x7F;
2468                                        if(stream_id_extension_len >= 1)
2469                                        {
2470                                                if(payload[8] < (offs + stream_id_extension_len)) continue;
2471                                                //stream_id_extension_bit (should not set)
2472                                                if(payload[9 + offs] & 0x80) continue;
2473                                                switch(payload[9 + offs])
2474                                                {
2475                                                        case 0x55 ... 0x5f: break; //VC-1
2476                                                        case 0x71: break; //AC3 / DTS
2477                                                        case 0x72: break; //DTS - HD
2478                                                        default:
2479                                                                printf("skip unknwn stream_id_extension %02x\n", payload[9 + offs]);
2480                                                                continue;
2481                                                }
2482                                        }
2483                                        else
2484                                                continue;
2485                                }
2486                                else
2487                                        continue;
2488                        }
2489                        else
2490                                continue;
2491                }
2492                //drop non-audio, non-video packets because other streams
2493                //can be non-compliant.
2494                //0xC0 = audio, 0xE0 = video
2495                else if(((payload[3] & 0xE0) != 0xC0) && ((payload[3] & 0xF0) != 0xE0))
2496                        continue;
2497
2498                if((payload[7] & 0x80) && ((payload[3] & 0xF0) != 0xE0) && (type == 0 || type == 2)) //PTS video
2499                {
2500                        pts = ((unsigned long long)(payload[9] & 0xE)) << 29;
2501                        pts |= ((unsigned long long)(payload[10] & 0xFF)) << 22;
2502                        pts |= ((unsigned long long)(payload[11] & 0xFE)) << 14;
2503                        pts |= ((unsigned long long)(payload[12] & 0xFF)) << 7;
2504                        pts |= ((unsigned long long)(payload[13] & 0xFE)) >> 1;
2505                        continue;
2506                }
2507                if((payload[7] & 0x80) && ((payload[3] & 0xE0) != 0xC0) && (type == 0 || type == 3)) //PTS audio
2508                {
2509                        pts = ((unsigned long long)(payload[9] & 0xE)) << 29;
2510                        pts |= ((unsigned long long)(payload[10] & 0xFF)) << 22;
2511                        pts |= ((unsigned long long)(payload[11] & 0xFE)) << 14;
2512                        pts |= ((unsigned long long)(payload[12] & 0xFF)) << 7;
2513                        pts |= ((unsigned long long)(payload[13] & 0xFE)) >> 1;
2514                        continue;
2515                }
2516        }
2517        free(buf);
2518        return recbsize * -1;
2519}
2520
2521#ifdef EPLAYER4
2522/* Extract some metadata from the streams and print it on the screen */
2523static void analyze_streams(CustomData *data)
2524{
2525        gint i;
2526        GstTagList *tags;
2527        gchar *str;
2528        guint rate;
2529
2530        /* Read some properties */
2531        g_object_get(pipeline, "n-video", &data->n_video, NULL);
2532        g_object_get(pipeline, "n-audio", &data->n_audio, NULL);
2533        g_object_get(pipeline, "n-text", &data->n_text, NULL);
2534
2535        g_print("%d video stream(s), %d audio stream(s), %d text stream(s)\n", data->n_video, data->n_audio, data->n_text);
2536
2537        g_print ("\n");
2538        for(i = 0; i < data->n_video; i++)
2539        {
2540                tags = NULL;
2541                /* Retrieve the stream's video tags */
2542                g_signal_emit_by_name(pipeline, "get-video-tags", i, &tags);
2543                if(tags)
2544                {
2545                        g_print("video stream %d:\n", i);
2546                        gst_tag_list_get_string(tags, GST_TAG_VIDEO_CODEC, &str);
2547                        g_print("  codec: %s\n", str ? str : "unknown");
2548                        g_free(str);
2549                        gst_tag_list_free(tags);
2550                }
2551        }
2552
2553        g_print("\n");
2554        for(i = 0; i < data->n_audio; i++)
2555        {
2556                tags = NULL;
2557                g_signal_emit_by_name(pipeline, "get-audio-tags", i, &tags);
2558                if(tags)
2559                {
2560                        /* Retrieve the stream's audio tags */
2561                        g_print("audio stream %d:\n", i);
2562                        if(gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str))
2563                        {
2564                                g_print("  codec: %s\n", str);
2565                                g_free(str);
2566                        }
2567                        if(gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str))
2568                        {
2569                                g_print("  language: %s\n", str);
2570                                g_free(str);
2571                        }
2572                        if(gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate))
2573                        {
2574                                g_print("  bitrate: %d\n", rate);
2575                        }
2576                        gst_tag_list_free(tags);
2577                }
2578        }
2579
2580        g_print("\n");
2581        for(i = 0; i < data->n_text; i++)
2582        {
2583                tags = NULL;
2584                /* Retrieve the stream's subtitle tags */
2585                g_print("subtitle stream %d:\n", i);
2586                g_signal_emit_by_name(pipeline, "get-text-tags", i, &tags);
2587                if(tags)
2588                {
2589                        if(gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str))
2590                        {
2591                                g_print("  language: %s\n", str);
2592                                g_free(str);
2593                        }
2594                        gst_tag_list_free(tags);
2595                }
2596                else
2597                {
2598                        g_print("  no tags found\n");
2599                }
2600        }
2601
2602        g_object_get(pipeline, "current-video", &data->current_video, NULL);
2603        g_object_get(pipeline, "current-audio", &data->current_audio, NULL);
2604        g_object_get(pipeline, "current-text", &data->current_text, NULL);
2605
2606        g_print("\n");
2607        g_print("Currently playing video stream %d, audio stream %d and subtitle stream %d\n", data->current_video, data->current_audio, data->current_text);
2608        g_print("Type any number and hit ENTER to select a different subtitle stream\n");
2609}
2610#endif
2611
2612#ifdef EPLAYER4
2613void playersend_ff_fr_event(gdouble rate) {
2614        gint64 position;
2615        GstFormat format = GST_FORMAT_TIME;
2616        GstEvent *seek_event;
2617   
2618        /* Obtain the current position, needed for the seek event */
2619        if (!gst_element_query_position (pipeline, &format, &position)) {
2620                g_printerr ("Unable to retrieve current position.\n");
2621                return;
2622        }
2623   
2624        /* Create the seek event */
2625        if (rate > 0)
2626        {       
2627                seek_event = gst_event_new_seek (rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_NONE, 0);
2628  }
2629        else
2630        {
2631                seek_event = gst_event_new_seek (rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, position);
2632        }
2633   
2634        if (video_sink == NULL) {
2635                /* If we have not done so, obtain the sink through which we will send the seek events */
2636                g_object_get (pipeline, "video-sink", &video_sink, NULL);
2637        }
2638   
2639        /* Send the event */
2640        gst_element_send_event (video_sink, seek_event);
2641   
2642        g_print ("Current rate: %g\n", rate);
2643}
2644#endif
2645
2646#endif
Note: See TracBrowser for help on using the repository browser.