source: titan/titan/player.h @ 30933

Last change on this file since 30933 was 30933, checked in by obi, 8 years ago

mipsel add gst eof work

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