source: titan/titan/player.h @ 38153

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

[mipsel] add gst191 pre buffer work

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