source: titan/titan/player.h @ 44947

Last change on this file since 44947 was 44947, checked in by obi, 2 years ago

cleanup

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