source: titan/titan/player.h @ 24075

Last change on this file since 24075 was 24075, checked in by nit, 10 years ago

fix

File size: 35.8 KB
RevLine 
[7557]1#ifndef PLAYER_H
2#define PLAYER_H
3
[20105]4// playercan bits:
[13962]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
[20105]20// 15 slowmotion
[13962]21
[10626]22#ifdef EPLAYER3
[7557]23Context_t * player = NULL;
24extern OutputHandler_t OutputHandler;
25extern PlaybackHandler_t PlaybackHandler;
26extern ContainerHandler_t ContainerHandler;
27extern ManagerHandler_t ManagerHandler;
28#endif
29
[10626]30#ifdef EPLAYER4
[13959]31GstElement *m_gst_playbin = NULL;
[18429]32unsigned long long m_gst_startpts = 0;
[10626]33#endif
34
35//titan player
36
[9713]37//flag 0: from play
38//flag 1: from timeshift
[17464]39//flag 2: from playrcjumpr
[9713]40int playerstartts(char* file, int flag)
41{
[14357]42        int fd = -1, ret = 0, tssize = 188;
[9713]43        int16_t pmtpid = 0;
44        int serviceid = 0;
[18262]45        int supermagic = -1;
[9713]46        struct channel* chnode = NULL;
47        struct service* snode = NULL;
48        struct dvbdev* fenode = NULL;
49        struct dvbdev* dvrnode = NULL;
50
[18262]51        //supermagic = getsupermagic(file);
[17007]52
53        if(supermagic == NFS_SUPER_MAGIC || supermagic == SMB_SUPER_MAGIC)
54        {
55                debug(150, "use O_DIRECT to open file %s", file);
[17310]56                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK | O_DIRECT);
[17007]57        }
58        else
[17310]59                fd = open(file, O_RDONLY | O_LARGEFILE | O_NONBLOCK);
[17007]60
[9713]61        if(fd < 0)
62        {
63                perr("open player file");
64                return 1;
65        }
66
67        fenode = fegetdummy();
68        dvrnode = dvropen(fenode);
69        if(dvrnode == NULL)
70        {
71                err("find dvr dev");
72                close(fd);
73                return 1;
74        }
75
[17464]76        if(flag == 0 || flag == 2)
[9746]77        {
[14357]78                //TODO: funktion to get tssize from file content
79                if(cmpfilenameext(file, ".mts") == 0) tssize = 192;
80                if(cmpfilenameext(file, ".m2ts") == 0) tssize = 192;
[17463]81               
[14357]82                ret = dvbfindpmtpid(fd, &pmtpid, &serviceid, tssize);
[9746]83                if(ret == 1)
84                {
85                        err("find sid/pmt pid");
86                        close(fd);
87                        dvrclose(dvrnode, -1);
88                        return 1;
89                }
[20312]90               
91                if(flag == 0 && getconfigint("showlastpos", NULL) == 1)
92                {
93                        char* fileseek = changefilenameext(file, ".se");
94                        FILE* fbseek = fopen(fileseek, "r");
95                        if(fbseek != NULL)
96                        {
97                                ret = textbox(_("Message"), _("Start at last position ?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 10, 0);
98                                if(ret == 0 || ret == 1)
99                                {
100                                        char* skip1 = calloc(1, 20);
101                                        if(skip1 != NULL)
102                                        {
103                                                fscanf(fbseek, "%s", skip1);
[20314]104                                                off64_t seekpos = atoll(skip1);
[20409]105                                                seekpos = seekpos - (seekpos % tssize);
[20314]106                                                lseek64(fd, atoll(skip1), SEEK_SET);
[20312]107                                        }
108                                        free(skip1); skip1 = NULL;
109                                }
110                                fclose(fbseek);
111                        }
112                        free(fileseek); fileseek = NULL;
113                }       
114               
[19679]115                if(flag == 0)
116                {
117                        delmarkernode(-1);
118                        char* filemarker = changefilenameext(file, ".ma");
119                        getmarker(filemarker);
120                        free(filemarker); filemarker=NULL;
121                }
[20308]122               
[19236]123                delchannel(serviceid, 0, 1);
[9713]124                chnode = createchannel("player", 0, 0, serviceid, 99, 0, -1, -1, -1, -1, 0);
[13641]125                if(chnode != NULL) chnode->pmtpid = pmtpid;
[9746]126        }
[9713]127        else
128                chnode = status.aktservice->channel;
129
130        if(chnode == NULL)
131        {
132                err("create channel");
133                close(fd);
134                dvrclose(dvrnode, -1);
135                return 1;
136        }
137
[9746]138        if(flag == 1)
[9713]139        {
[10849]140                ret = servicestart(chnode, NULL, NULL, 2);
[9746]141                if(ret != 0)
[9713]142                {
[9746]143                        err("start play");
[9713]144                        close(fd);
145                        dvrclose(dvrnode, -1);
146                        return 1;
147                }
[20413]148               
149                //on permanent timeshift seek to end, and a little back (eof problem)
150                if(status.timeshifttype == 1)
[20477]151                {
152                        if(status.timeshiftpos > 0)
153                                lseek64(fd, status.timeshiftpos, SEEK_SET);
154                        else
[20542]155                        {
156                                unsigned long long pos = lseek64(fd, 0, SEEK_END);
157                                pos -= 10000000;
158                                pos = pos - (pos & tssize);
159                                lseek64(fd, -pos, SEEK_END);
160                        }
[20477]161                }
[9713]162        }
163
[14357]164        ret = recordstartreal(NULL, fd, dvrnode->fd, RECPLAY, 0, NULL, tssize);
[9713]165        if(ret != 0)
166        {
167                err("start play thread");
168                close(fd);
169                dvrclose(dvrnode, -1);
170                return 1;
171        }
172
[20276]173        snode = getservice(RECORDPLAY, 0);
174        if(snode != NULL)
175        {
[20301]176                int dupfd = -1;
177                snode->recname = ostrcat(file, NULL, 0, 0);
178
179                dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
180                if(dupfd > -1)
181                        gettsinfo(dupfd, &snode->lenpts, &snode->startpts, &snode->endpts, &snode->bitrate, snode->tssize);
182
[20276]183                if(flag == 1)
184                {
185                        snode->lenpts = 0;
186                        snode->endpts = 0;
187                }
188                else
189                {
[20510]190                        if(getservicebyrecname(file, 1, 0) != NULL) //playfile is recording, so len can change
191                        {
192                                snode->lenpts = 0;
193                                snode->endpts = 0;
194                        }
195                        else if(dupfd > -1)
[20301]196                                snode->endoffile = lseek64(dupfd , 0, SEEK_END);
[20276]197                }
[20301]198                close(dupfd);
[20276]199        }
200
[18270]201        if(flag == 0 || flag == 2)
[9713]202        {
[10849]203                ret = servicestart(chnode, NULL, NULL, 1);
[9746]204                if(ret != 0)
205                {
206                        err("start play");
207                        if(snode != NULL) snode->recendtime = 1;
208                        close(fd);
209                        dvrclose(dvrnode, -1);
210                        return 1;
211                }
[17552]212                //status.playercan = 0x7EFF;
[19762]213                status.playercan = 0xFFFF;     
[9713]214        }
[20314]215
[9713]216        return 0;
217}
218
219//flag 0: from play
220//flag 1: from timeshift
[17464]221//flag 2: from playrcjumpr/playerafterendts
[10007]222//flag1 0: stop from rcstop
223//flag1 1: stop from servicestop
224void playerstopts(int flag, int flag1)
[9713]225{
226        int ret = 0;
227        struct service* snode = NULL;
[13692]228        struct channel* node = NULL;
[9713]229
[10007]230        snode = getservice(RECORDPLAY, flag1);
[9713]231        if(snode != NULL) snode->recendtime = 1;
232
[17464]233        if(flag == 0 || flag == 2)
[9713]234        {
[20298]235                playerslowts(0);
[13692]236                playerffts(0);
237
[17614]238                if(snode != NULL && snode->recsrcfd >= 0 && flag == 0)
[17464]239                {
240                        char* fileseek = changefilenameext(snode->recname, ".se");
241                        FILE* fbseek = fopen(fileseek, "w");
242                        if(fbseek != NULL)
243                        {
244                                off64_t pos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
[17699]245                                fprintf(fbseek,"%lld", pos);
[17464]246                                fclose(fbseek);
247                        }
248                        free(fileseek); fileseek=NULL;
[19695]249                        char* filemarker = changefilenameext(snode->recname, ".ma");
250                        ret = putmarker(filemarker);
251                        free(filemarker); filemarker=NULL;
[19679]252                        delmarkernode(-1);
[17464]253                }
254               
[9713]255                ret = servicestop(status.aktservice, 1, 1);
256                if(ret == 1)
257                {
258                        debug(150, "can't stop ts playback service");   
259                }
[13692]260                else
261                        status.aktservice->channel = NULL;
[13696]262
[17464]263                               
[13692]264                node = gettmpchannel();
265                if(node != NULL && ostrcmp(node->name, "player") == 0)
266                        delchannel(node->serviceid, node->transponderid, 1);
[9713]267        }
268}
269
[20337]270void playerresetts()
271{
272        audiostop(status.aktservice->audiodev);
273        videostop(status.aktservice->videodev, 0);
274        videoplay(status.aktservice->videodev);
275        audioplay(status.aktservice->audiodev);
276}
277
[9713]278void playercontinuets()
279{
[17689]280        videocontinue(status.aktservice->videodev);
281        audioplay(status.aktservice->audiodev);
[9713]282}
283
284void playerpausets()
285{
286        videofreeze(status.aktservice->videodev);
287        audiopause(status.aktservice->audiodev);
288}
289
[20413]290//flag 0: with lock
291//flag 1: without lock
[13654]292int playerseekts(struct service* servicenode, int sekunden, int flag)
[13636]293{
[20276]294        off64_t offset = 0;
295        off64_t endoffile = 0;
296        off64_t currentpos = 0;
297        //off64_t fdptspos = 0;
[20312]298        //int ret = 0;
[17552]299        unsigned long long lenpts = 0;
[20276]300        unsigned long long startpts = 0;
301        unsigned long long endpts = 0;
302        unsigned long long bitrate = 0;
[18330]303        //unsigned long long aktpts = 0;
304        //unsigned long long fdpts = 0;
305        //int aktsekunden = 0;
[17552]306        int sekundenoff = 0;
[13636]307       
308        if(servicenode == NULL) return 1;
309
310        if(servicenode->recsrcfd < 0)
311        {
312                err("source fd not ok");
313                return 1;
314        }
315       
[20413]316        if(flag == 0) m_lock(&status.tsseekmutex, 15);
[20284]317
[18270]318/*
[17552]319        ret = videogetpts(status.aktservice->videodev, &aktpts);
320        if(ret == 0)
[13636]321        {
[17552]322                aktsekunden = aktpts / 90000;
323        }
324        else
325                aktsekunden = 0;
[17574]326        ret = getpts(servicenode->recsrcfd, 0, 0, 256 * 1024, &fdpts, &fdptspos, -1, servicenode->tssize);
[17552]327        if(ret == 0 && aktsekunden != 0)
328        {
329                sekundenoff = fdpts / 90000 - aktsekunden ;
[17575]330                //currentpos = lseek64(servicenode->recsrcfd, fdptspos, SEEK_SET);
[17552]331        }
332        else
333                sekundenoff = 0;
[18270]334*/
[17552]335       
[20284]336        currentpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);
337
[20276]338        lenpts = servicenode->lenpts;
339        startpts = servicenode->startpts;
340        endpts = servicenode->endpts;
341        bitrate = servicenode->bitrate;
[20284]342        if(gettsinfo(servicenode->recsrcfd, &lenpts, &startpts, &endpts, &bitrate, servicenode->tssize) != 0)
[17552]343        {
[20443]344                err("can't read ts info");
[20444]345                lseek64(servicenode->recsrcfd, currentpos, SEEK_SET);
[20413]346                if(flag == 0) m_unlock(&status.tsseekmutex, 15);
[13636]347                return 1;
348        }
[20276]349        if(servicenode->endoffile > 0)
350                endoffile = servicenode->endoffile - (servicenode->tssize * 2);
351        else
[20284]352                endoffile = lseek64(servicenode->recsrcfd , -servicenode->tssize * 2, SEEK_END);
[17552]353
[20284]354/*
355        ret = videoclearbuffer(status.aktservice->videodev);
356        ret = audioclearbuffer(status.aktservice->audiodev);
357        ret = videodiscontinuityskip(status.aktservice->videodev, 0);
358*/
[18222]359
[13636]360        if(sekunden >= 0)
361        {
[17552]362                if(sekundenoff != 0)
363                        offset = (bitrate / 8) * (sekunden - sekundenoff);
364                else
365                        offset = (bitrate / 8) * sekunden - 5000000;
[14355]366                offset = offset - (offset % servicenode->tssize);
[13636]367                if(currentpos + offset > endoffile)
368                {
369                        offset = endoffile - currentpos;
[14355]370                        offset = offset - (offset % servicenode->tssize);
[13636]371                }
372        }
373        else
374        {
375                sekunden = sekunden * -1;
[17552]376                if(sekundenoff != 0)
377                        offset = (bitrate / 8) * (sekunden + sekundenoff);
378                else
[20302]379                        offset = (bitrate / 8) * sekunden;
380                if(offset > 0) offset += 5000000;
[14355]381                offset = offset - (offset % servicenode->tssize);
[13636]382                if(currentpos - offset < 0)
[20302]383                        offset = currentpos;
[13636]384                offset = offset * -1;
385        }
[20302]386        offset += currentpos;
387        currentpos = lseek64(servicenode->recsrcfd, offset, SEEK_SET);
[18222]388
[20337]389        playerresetts();
[20282]390
[20413]391        if(flag == 0) m_unlock(&status.tsseekmutex, 15);
[13636]392        return 0;
393}
394
[13638]395void playerffts(int speed)
[13636]396{
[18493]397        videofastforward(status.aktservice->videodev, speed);
[13636]398}
399
[19762]400void playerslowts(int speed)
401{
402        videoslowmotion(status.aktservice->videodev, speed);
403}
404
[17576]405//flag = 0 --> recordplay
406//flag = 1 --> timeshift
407void playerfrts(int speed, int flag)
[13638]408{
[18281]409        if(flag == 1)
410                videocontinue(status.aktservice->videodev);
411        if(speed == -2)
[17552]412        {
[18231]413                videoclearbuffer(status.aktservice->videodev);
414                audioclearbuffer(status.aktservice->audiodev);
[17552]415        }
[18231]416        speed *= -1;
[18495]417        videofastforward(status.aktservice->videodev, speed);
[13638]418}
[17552]419       
[13638]420
[17572]421//flag = 0 --> play ts
422//flag = 1 --> timeshift
[20542]423//flag = 2 --> timeshift, not in play mode (only recording)
[17572]424int playergetinfots(unsigned long long* lenpts, unsigned long long* startpts, unsigned long long* endpts, unsigned long long* aktpts, unsigned long long* bitrate, int flag)
[13638]425{
[20292]426        int ret = 0, dupfd = -1;
[20441]427        double ratio = 0;
[17572]428        struct service* snode = NULL;
[20276]429        unsigned long long lenpts1 = 0;
430        unsigned long long startpts1 = 0;
431        unsigned long long endpts1 = 0;
432        unsigned long long bitrate1 = 0;
[20441]433        unsigned long long endoffile1 = 0;
434        unsigned long long aktpos = 0;
[13654]435       
[20542]436        if(flag == 2)
437                snode = getservice(RECORDTIMESHIFT, 0);
438        else
439                snode = getservice(RECORDPLAY, 0);
[17572]440               
[13696]441        if(snode == NULL) return 1;
[20292]442
[20441]443        if(snode->lenpts > 0 && snode->startpts > 0 && snode->endpts > 0 && snode->bitrate > 0 && snode->endoffile > 0)
[20292]444        {
445                if(lenpts != NULL) *lenpts = snode->lenpts;
446                if(startpts != NULL) *startpts = snode->startpts;
447                if(endpts != NULL) *endpts = snode->endpts;
448                if(bitrate != NULL) *bitrate = snode->bitrate;
449
[20441]450                //ret = videogetpts(status.aktservice->videodev, aktpts);
451                if(aktpts != NULL)
452                {
453                        m_lock(&status.tsseekmutex, 15);
[20542]454                        if(flag == 2)
455                                aktpos = lseek64(snode->recdstfd , 0, SEEK_CUR);
456                        else
457                                aktpos = lseek64(snode->recsrcfd , 0, SEEK_CUR);
[20441]458                        m_unlock(&status.tsseekmutex, 15);
459
[20443]460                        ratio = (double)snode->endoffile / (double)(snode->endpts - snode->startpts);
[20441]461                        if(ratio == 0) ratio = 1;
462                        *aktpts = ((double)aktpos / ratio);
463                        *aktpts += snode->startpts;
464                }
465
[20292]466                return ret;
467        }
[13654]468       
469        dupfd = open(snode->recname, O_RDONLY | O_LARGEFILE);
470        if(dupfd < 0)
471        {
472                err("copy source fd not ok");
[13696]473                return 1;
[13654]474        }
475
[20276]476        lenpts1 = snode->lenpts;
477        startpts1 = snode->startpts;
478        endpts1 = snode->endpts;
479        bitrate1 = snode->bitrate;
480        if(gettsinfo(dupfd, &lenpts1, &startpts1, &endpts1, &bitrate1, snode->tssize) != 0)
[13654]481        {
[20443]482                err("can't read ts info");
[13696]483                return 1;
[13654]484        }
[20276]485
486        if(lenpts != NULL) *lenpts = lenpts1;
487        if(startpts != NULL) *startpts = startpts1;
488        if(endpts != NULL) *endpts = endpts1;
489        if(bitrate != NULL) *bitrate = bitrate1;
[20441]490
491        //ret = videogetpts(status.aktservice->videodev, aktpts);
492        if(aktpts != NULL)
493        {
494                m_lock(&status.tsseekmutex, 15);
[20542]495                if(flag == 2)
496                        aktpos = lseek64(snode->recdstfd, 0, SEEK_CUR);
497                else
498                        aktpos = lseek64(snode->recsrcfd, 0, SEEK_CUR);
[20441]499                m_unlock(&status.tsseekmutex, 15);
500
501                if(snode->endoffile <= 0)
502                        endoffile1 = lseek64(dupfd, 0, SEEK_END);
503                else
504                        endoffile1 = snode->endoffile;
505
506                if(endpts1 == 0)
507                        ratio = 1;
508                else
[20443]509                        ratio = (double)endoffile1 / (double)(endpts1 - startpts1);
[20441]510
511                if(ratio == 0) ratio = 1;
512                *aktpts = ((double)aktpos / ratio);
513                *aktpts += startpts1;
514        }
515
[13654]516        close(dupfd);
[20292]517        return ret;
[13638]518}
519
520void playerchangeaudiotrackts()
521{
[13698]522        screenaudiotrack();
[13638]523}
524
525void playerchangesubtitletrackts()
526{
[13698]527        screensubtitle();
[13638]528}
529
530int playerisplayingts()
531{
[13662]532        struct service* snode = getservice(RECORDPLAY, 0);
[13692]533
[13662]534        if(snode == NULL)
535                return 0;
[13638]536        return 1;
537}
538
539void playerafterendts()
540{
[17464]541        playerstopts(2, 0);
[13638]542}
543
[10626]544//extern player
545
[7557]546int playerstart(char* file)
547{
[13959]548        char * tmpfile = NULL;
549       
[7557]550        if(file != NULL)
551        {
[10626]552#ifdef EPLAYER3
[7557]553                //use eplayer
554
555                if(player != NULL)
[10742]556                {
[7557]557                        debug(150, "eplayer allready running");
[10742]558                        playerstop();
559                }
[7557]560
[20105]561                player = calloc(1, sizeof(Context_t));
[7557]562
563                if(player == NULL)
564                {
565                        err("no mem");
566                        return 1;
567                }
568
[16471]569                if(ostrstr(file, "://") == NULL)
[7557]570                        tmpfile = ostrcat("file://", file, 0, 0);
571                else
[16286]572                        tmpfile = ostrcat(file, NULL, 0, 0);
[7557]573
574                if(tmpfile == NULL)
575                {
576                        err("no mem");
577                        free(player); player = NULL;
578                        return 1;
579                }
580
[16471]581                if(ostrstr(tmpfile, "file://") == NULL)
[13962]582                        status.playercan = 0x4650;
583                else
[19762]584                        status.playercan = 0xFFFF;
[13962]585               
[7557]586                player->playback = &PlaybackHandler;
587                player->output = &OutputHandler;
588                player->container = &ContainerHandler;
589                player->manager = &ManagerHandler;
[19736]590               
591                //add container befor open, so we can set buffer size
592                char* ext = getfilenameext(tmpfile);
593                if(ext != NULL)
594                {
595                        player->container->Command(player, CONTAINER_ADD, ext);
596                        free(ext); ext = NULL;
597                }
[19780]598
599                //select container_ffmpeg, if we does not found a container with extensions
600                if(player->container->selectedContainer == NULL)
601                        player->container->Command(player, CONTAINER_ADD, "mp3");
[24075]602
[19736]603                if(player && player->container && player->container->selectedContainer)
604                {
605                        int size = getconfigint("playerbuffersize", NULL);
606                        int seektime = getconfigint("playerbufferseektime", NULL);
607                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SIZE, (void*)&size);
608                        player->container->selectedContainer->Command(player, CONTAINER_SET_BUFFER_SEEK_TIME, (void*)&seektime);
609                }
610               
[7557]611                debug(150, "eplayername = %s", player->output->Name);
612
613                //Registrating output devices
[7586]614                player->output->Command(player, OUTPUT_ADD, "audio");
615                player->output->Command(player, OUTPUT_ADD, "video");
616                player->output->Command(player, OUTPUT_ADD, "subtitle");
[19736]617               
[14229]618                //for subtitle
619                SubtitleOutputDef_t subout;
620
621                subout.screen_width = fb->width;
622                subout.screen_height = fb->height;
623                subout.framebufferFD = fb->fd;
[24023]624                subout.destination = (uint32_t *)fb->fb;
[14230]625                subout.destStride = fb->pitch;
[14229]626                subout.shareFramebuffer = 1;
627
628                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&subout);
[19736]629               
[7557]630                if(player->playback->Command(player, PLAYBACK_OPEN, tmpfile) < 0)
631                {
632                        free(player); player = NULL;
633                        free(tmpfile);
634                        return 1;
635                }
636
637                player->output->Command(player, OUTPUT_OPEN, NULL);
638                player->playback->Command(player, PLAYBACK_PLAY, NULL);
639
640                free(tmpfile);
641
642                return 0;
643#endif
[10626]644
645#ifdef EPLAYER4
646                int flags = 0x47; //(GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT);
647               
[10742]648                if(m_gst_playbin != NULL)
649                {
650                        debug(150, "eplayer allready running");
651                        playerstop();
652                }
653               
[16471]654                if(ostrstr(file, "://") == NULL)
[13959]655                        tmpfile = ostrcat("file://", file, 0, 0);
656                else
[16286]657                        tmpfile = ostrcat(file, NULL, 0, 0);
[13959]658
659                if(tmpfile == NULL)
660                {
661                        err("no mem");
662                        free(m_gst_playbin); m_gst_playbin = NULL;
663                        return 1;
664                }
[13962]665
[16471]666                if(ostrstr(tmpfile, "file://") == NULL)
[13982]667                        status.playercan = 0x7E7F;
[13962]668                else
[13982]669                        status.playercan = 0x7E7F;
[13959]670               
[10626]671                m_gst_playbin = gst_element_factory_make("playbin2", "playbin");
[13959]672                g_object_set(G_OBJECT (m_gst_playbin), "uri", tmpfile, NULL);
[10626]673                g_object_set(G_OBJECT (m_gst_playbin), "flags", flags, NULL);
[13959]674                free(tmpfile); tmpfile = NULL;
[10626]675               
[13917]676                if(m_gst_playbin)
677                        gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
678               
[13982]679                int count = 0;
680                m_gst_startpts = 0;
681                while(m_gst_startpts == 0 && count < 5)
682                {
683                        count++;
684                        sleep(1);
685                        m_gst_startpts = playergetpts();
686                }
[10626]687                return 0;
688#endif
[7557]689        }
[9746]690       
[7557]691        return 1;
692}
693
[10702]694void playerinit(int argc, char* argv[])
695{
696#ifdef EPLAYER4
697        gst_init(&argc, &argv);
698#endif
699}
700
[11089]701#ifdef EPLAYER4
702int gstbuscall(GstBus *bus, GstMessage *msg)
703{
704        int ret = 1;
[13982]705        if(!m_gst_playbin) return 0;
[13591]706        if(!msg) return ret;
[11089]707
708        gchar *sourceName = NULL;
709        GstObject *source = GST_MESSAGE_SRC(msg);
710
[13591]711        if(!GST_IS_OBJECT(source)) return ret;
[11089]712        sourceName = gst_object_get_name(source);
713
714        switch(GST_MESSAGE_TYPE(msg))
715        {
716                case GST_MESSAGE_EOS:
717                        debug(150, "gst player eof");
718                        ret = 0;
719                        break;
720                case GST_MESSAGE_STATE_CHANGED:
[13982]721                        if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
722                                break;
723
724                        GstState old_state, new_state;
725                        gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
726               
727                        if(old_state == new_state) break;
728       
729                        debug(150, "gst state change %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
730       
731                        GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
732       
733                        switch(transition)
734                        {
735                                case GST_STATE_CHANGE_NULL_TO_READY:
736                                        break;
737                                case GST_STATE_CHANGE_READY_TO_PAUSED:
738/*
739                                        GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
740                                        if(appsink)
741                                        {
742                                                g_object_set(G_OBJECT(appsink), "max-buffers", 2, NULL);
743                                                g_object_set(G_OBJECT(appsink), "sync", FALSE, NULL);
744                                                g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, NULL);
745                                                gst_object_unref(appsink);
746                                        }
747*/
748                                        break;
749                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
750                                        //if(m_sourceinfo.is_streaming && m_streamingsrc_timeout )
751                                                //m_streamingsrc_timeout->stop();
752                                        break;
753                                case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
754                                        break;
755                                case GST_STATE_CHANGE_PAUSED_TO_READY:
756                                        break;
757                                case GST_STATE_CHANGE_READY_TO_NULL:
758                                        ret = 0;
759                                        break;
760                        }
[11089]761                        break;
762                case GST_MESSAGE_ERROR:
763                        debug(150, "gst player error");
[13982]764
765                        gchar *gdebug1;
766                        GError *err;
767
768                        gst_message_parse_error(msg, &err, &gdebug1);
769                        g_free(gdebug1);
770
771                        debug(150, "gst error: %s (%i) from %s", err->message, err->code, sourceName);
772                        if(err->domain == GST_STREAM_ERROR)
773                        {
774                                if(err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
775                                {
776                                        //if(g_strrstr(sourceName, "videosink"))
777                                        //      m_event((iPlayableService*)this, evUser+11);
778                                        //else if ( g_strrstr(sourceName, "audiosink") )
779                                        //      m_event((iPlayableService*)this, evUser+10);
780                                }
781                        }
782                        g_error_free(err);
[11089]783                        break;
784                case GST_MESSAGE_INFO:
785                        debug(150, "gst player info");
[13982]786
787/*
788                        gchar *gdebug2;
789                        GError *inf;
790       
791                        gst_message_parse_info(msg, &inf, &gdebug2);
792                        g_free(gdebug2);
793                        if(inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
794                        {
795                                //if(g_strrstr(sourceName, "videosink"))
796                                //      m_event((iPlayableService*)this, evUser+14);
797                        }
798                        g_error_free(inf);
799*/
[11089]800                        break;
801                case GST_MESSAGE_TAG:
802                        debug(150, "gst player tag");
803                        break;
[13591]804                //case GST_MESSAGE_ASYNC_DONE:
805                //      debug(150, "gst player async done");
806                //      break;
[11089]807                case GST_MESSAGE_ELEMENT:
808                        debug(150, "gst player element");
809                        break;
810                case GST_MESSAGE_BUFFERING:
811                        debug(150, "gst player buffering");
[13982]812
813/*
814                        GstBufferingMode mode;
815                        gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
816                        gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
817                        //m_event((iPlayableService*)this, evBuffering);
818*/
[11089]819                        break;
820                case GST_MESSAGE_STREAM_STATUS:
821                        debug(150, "gst player stream status");
[13982]822
823/*
824                        GstStreamStatusType type;
825                        GstElement *owner;
826
827                        gst_message_parse_stream_status(msg, &type, &owner);
828                        if(type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming)
829                        {
830                                if(GST_IS_PAD(source))
831                                        owner = gst_pad_get_parent_element(GST_PAD(source));
832                                else if(GST_IS_ELEMENT(source))
833                                        owner = GST_ELEMENT(source);
834                                else
835                                        owner = NULL;
836                                if(owner)
837                                {
838                                        GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
839                                        const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
840                                        if (!strcmp(name, "souphttpsrc"))
841                                        {
842                                                //m_streamingsrc_timeout->start(10 * 1000, true);
843                                                g_object_set(G_OBJECT(owner), "timeout", 10, NULL);
844                                        }
845                                       
846                                }
847                                if(GST_IS_PAD(source))
848                                        gst_object_unref(owner);
849                        }
850*/
[11089]851                        break;
852                default:
853                        debug(150, "gst player unknown message");
854                        break;
855        }
856        g_free(sourceName);
857        return ret;
858}
859#endif
860
[19736]861int playergetbuffersize()
862{
863        int ret = 0;
[20284]864
[19736]865#ifdef EPLAYER3
866        if(player && player->container && player->container->selectedContainer)
867                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_SIZE, (void*)&ret);
868#endif
869
870        return ret;
871}
872
873int playergetbufferstatus()
874{
875        int ret = 0;
[20284]876
[19736]877#ifdef EPLAYER3
878        if(player && player->container && player->container->selectedContainer)
879                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_STATUS, (void*)&ret);
880#endif
881
882        return ret;
883}
884
[19810]885int playerstopbuffer()
886{
887        int ret = 0;
888
889#ifdef EPLAYER3
[19875]890        if(player && player->container && player->container->selectedContainer)
891                player->container->selectedContainer->Command(player, CONTAINER_STOP_BUFFER, NULL);
[19810]892#endif
893
894        return ret;
895}
896
[10626]897int playerisplaying()
898{
899#ifdef SIMULATE
900        return 1;
901#endif
902
903#ifdef EPLAYER3
904        if(player != NULL && player->playback != NULL && player->playback->isPlaying)
905                return 1;
906#endif
907
[11089]908#ifdef EPLAYER4
909        int ret = 1;
910
911        if(m_gst_playbin)
912        {
913                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(m_gst_playbin));
914                GstMessage *message = NULL;
915                while((message = gst_bus_pop(bus)))
916                {
[13591]917                        ret = gstbuscall(bus, message);
[11089]918                        gst_message_unref(message);
919                }
920        }
[13982]921        else
922                ret = 0;
923
[11089]924        return ret;
925#endif
[10626]926        return 0;
927}
928
[8451]929void playerplay()
930{
[10626]931#ifdef EPLAYER3
[8451]932        if(player && player->playback)
933                player->playback->Command(player, PLAYBACK_PLAY, NULL);
934#endif
[13982]935
936#ifdef EPLAYER4
937        if(m_gst_playbin)
938                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
939#endif
[8451]940}
941
[7557]942int playerstop()
943{
[10626]944#ifdef EPLAYER3
[9665]945        if(player && player->playback)
[7557]946                player->playback->Command(player, PLAYBACK_STOP, NULL);
[9665]947        if(player && player->container && player->container->selectedContainer)
948                player->container->selectedContainer->Command(player, CONTAINER_STOP, NULL);
[7976]949        if(player && player->output)
950        {
[9665]951                player->output->Command(player, OUTPUT_CLOSE, NULL);
[8451]952                player->output->Command(player, OUTPUT_DEL, (void*)"audio");
953                player->output->Command(player, OUTPUT_DEL, (void*)"video");
954                player->output->Command(player, OUTPUT_DEL, (void*)"subtitle");
[7976]955        }
956        if(player && player->playback)
[8451]957                player->playback->Command(player, PLAYBACK_CLOSE, NULL);
[7557]958
[7586]959        free(player);
960        player = NULL;
[7557]961#endif
[10626]962
963#ifdef EPLAYER4
964        if(m_gst_playbin)
965        {
966                gst_element_set_state(m_gst_playbin, GST_STATE_NULL);
[13591]967                gst_object_unref(GST_OBJECT(m_gst_playbin));
[13959]968                m_gst_playbin = NULL;
[10626]969        }
970#endif
971
[9593]972        writesysint("/proc/sys/vm/drop_caches", 3, 0);
[7586]973        return 0;
[7557]974}
975
[10626]976void playerafterend()
977{
978#ifdef EPLAYER3
979        if(player != NULL && player->playback != NULL)
980                playerstop();
981#endif
[13980]982
983#ifdef EPLAYER4
984        if(m_gst_playbin)
985                playerstop();
986#endif
[10626]987}
988
[7557]989void playerpause()
990{
[10626]991#ifdef EPLAYER3
[7586]992        if(player && player->playback)
[7557]993                player->playback->Command(player, PLAYBACK_PAUSE, NULL);
994#endif
[10626]995
996#ifdef EPLAYER4
997        if(m_gst_playbin)
998                gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED);
999#endif
[7557]1000}
1001
1002void playercontinue()
1003{
[10626]1004#ifdef EPLAYER3
[7586]1005        if(player && player->playback)
[7557]1006                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
1007#endif
[10626]1008
1009#ifdef EPLAYER4
1010        if(m_gst_playbin)
1011                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
1012#endif
[7557]1013}
1014
1015void playerff(int speed)
1016{
[10626]1017#ifdef EPLAYER3
[7557]1018        int speedmap = 0;
1019
[8267]1020        if (speed < 1) speed = 1;
[7557]1021        if (speed > 7) speed = 7;
1022
1023        switch(speed)
1024        {
1025                case 1: speedmap = 1; break;
1026                case 2: speedmap = 3; break;
1027                case 3: speedmap = 7; break;
1028                case 4: speedmap = 15; break;
1029                case 5: speedmap = 31; break;
1030                case 6: speedmap = 63; break;
1031                case 7: speedmap = 127; break;
1032        }
1033
[7586]1034        if(player && player->playback)
[8267]1035                player->playback->Command(player, PLAYBACK_FASTFORWARD, &speedmap);
[7557]1036#endif
1037}
1038
[19762]1039void playerslow(int speed)
1040{
1041#ifdef EPLAYER3
1042        int speedmap = 0;
1043
1044        if (speed < 1) speed = 1;
1045        if (speed > 7) speed = 7;
1046
1047        switch(speed)
1048        {
1049                case 1: speedmap = 1; break;
1050                case 2: speedmap = 3; break;
1051                case 3: speedmap = 7; break;
1052                case 4: speedmap = 15; break;
1053                case 5: speedmap = 31; break;
1054                case 6: speedmap = 63; break;
1055                case 7: speedmap = 127; break;
1056        }
1057
1058        if(player && player->playback)
1059                player->playback->Command(player, PLAYBACK_SLOWMOTION, &speedmap);
1060#endif
1061}
1062
[7557]1063void playerfr(int speed)
1064{
[10626]1065#ifdef EPLAYER3
[7557]1066        int speedmap = 0;
1067
[8267]1068        if (speed > -1) speed = -1;
[7557]1069        if (speed < -7) speed = -7;
1070
1071        switch(speed)
1072        {
1073                case -1: speedmap = -5; break;
1074                case -2: speedmap = -10; break;
1075                case -3: speedmap = -20; break;
1076                case -4: speedmap = -40; break;
1077                case -5: speedmap = -80; break;
1078                case -6: speedmap = -160; break;
1079                case -7: speedmap = -320; break;
1080        }
1081
[7586]1082        if(player && player->playback)
[8267]1083                player->playback->Command(player, PLAYBACK_FASTBACKWARD, &speedmap);
[7557]1084#endif
1085}
1086
1087void playerseek(float sec)
1088{
[10626]1089#ifdef EPLAYER3
[7586]1090        if(player && player->playback)
[7557]1091                player->playback->Command(player, PLAYBACK_SEEK, (void*)&sec);
1092#endif
[10626]1093
1094#ifdef EPLAYER4
[13982]1095        gint64 nanos_pts = 0, nanos_len = 0;
1096        gint64 pts = 0, len = 0;
[15831]1097        //GstFormat fmt = GST_FORMAT_TIME;
[10626]1098               
1099        if(m_gst_playbin)
1100        {
[13982]1101                len = playergetlength();
1102                nanos_len = len * 1000000000;
1103                if(nanos_len < 0) nanos_len = 0;
1104
1105                pts = playergetpts();
1106                nanos_pts = pts * 11111;
1107                nanos_pts = nanos_pts + (sec * 1000000000);
1108                if(nanos_pts < 0) nanos_pts = 0;
1109
1110                if(nanos_pts >= nanos_len)
1111                        playerstop();
1112                else
1113                        gst_element_seek(m_gst_playbin, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, nanos_pts, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
[10626]1114        }
1115#endif
[7557]1116}
1117
1118void playerfreetracklist(char** TrackList)
1119{
1120        int i = 0;
1121
[7586]1122        if(TrackList != NULL)
[7557]1123        {
[7586]1124                while(TrackList[i] != NULL)
1125                {
1126                        free(TrackList[i]);
[8418]1127                        free(TrackList[i + 1]);
1128                        i += 2;
[7586]1129                }
[7557]1130        }
1131}
1132
1133char** playergettracklist(int type)
1134{
1135        char ** TrackList = NULL;
[10626]1136#ifdef EPLAYER3
[7586]1137        if(player && player->manager)
[7557]1138        {
1139                switch(type)
1140                {
1141                        case 1:
[7586]1142                                if(player->manager->audio)
1143                                {
1144                                        player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
1145                                        debug(150, "Audio Track List");
1146                                }
[7557]1147                                break;
1148                        case 2:
[7586]1149                                if(player->manager->subtitle)
1150                                {
1151                                        player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
1152                                        debug(150, "Subtitle Track List");
1153                                }
[7557]1154                                break;
1155                        default:
[7586]1156                                if(player->manager->video)
1157                                {
1158                                        player->manager->video->Command(player, MANAGER_LIST, &TrackList);
1159                                        debug(150, "Video Track List");
1160                                }
[7557]1161                }
[24058]1162               
1163                int i = 0;
1164                while(TrackList[i] != NULL)
1165                {
1166                        string_newline(TrackList[i]);
1167                        i += 2;
1168                }
[7557]1169       
1170                if(TrackList != NULL)
1171                {
[8451]1172                        debug(150, "Track List");
[24058]1173                        i = 0;
[7557]1174                        while(TrackList[i] != NULL)
1175                        {
[8418]1176                                debug(150, "%s - %s", TrackList[i], TrackList[i + 1]);
1177                                i += 2;
[7557]1178                        }
1179                }
1180        }
1181#endif
1182        return TrackList;
1183}
1184
[8451]1185//*CurTrackEncoding and *CurTrackName be freed
[7557]1186void playergetcurtrac(int type, int *CurTrackId, char** CurTrackEncoding, char** CurTrackName)
1187{
[10626]1188#ifdef EPLAYER3
[7586]1189        if(player && player->manager)
[7557]1190        {
1191                switch(type)
1192                {
1193                        case 1:
[7586]1194                                if(player->manager->audio)
1195                                {
1196                                        player->manager->audio->Command(player, MANAGER_GET, CurTrackId);
1197                                        player->manager->audio->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1198                                        player->manager->audio->Command(player, MANAGER_GETNAME, CurTrackName);
1199                                }
[7557]1200                                break;
1201                        case 2:
[7586]1202                                if(player->manager->subtitle)
1203                                {
1204                                        player->manager->subtitle->Command(player, MANAGER_GET, CurTrackId);
1205                                        player->manager->subtitle->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1206                                        player->manager->subtitle->Command(player, MANAGER_GETNAME, CurTrackName);
1207                                }
[7557]1208                                break;
1209                        default:
[7586]1210                                if(player->manager->video)
1211                                {
1212                                        player->manager->video->Command(player, MANAGER_GET, CurTrackId);
1213                                        player->manager->video->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1214                                        player->manager->video->Command(player, MANAGER_GETNAME, CurTrackName);
1215                                }
[7557]1216                }
1217
1218                if(CurTrackId != NULL)
1219                        debug(150, "Current Track ID: %d", *CurTrackId);
1220                if(*CurTrackEncoding != NULL)
1221                        debug(150, "Current Track Enc: %s", *CurTrackEncoding);
1222                if(*CurTrackName != NULL)
1223                        debug(150, "Current Track Name: %s", *CurTrackName);
1224        }
1225#endif
[10742]1226
1227#ifdef EPLAYER4
1228        if(m_gst_playbin != NULL)
1229        {
1230                switch(type)
1231                {
1232                        case 1:
1233                                g_object_get(G_OBJECT(m_gst_playbin), "current-audio", CurTrackId, NULL);
1234                                break;
1235                }
1236               
1237                if(CurTrackId != NULL)
1238                        debug(150, "Current Track ID: %d", *CurTrackId);
1239        }
1240#endif
[7557]1241}
1242
[18429]1243unsigned long long playergetpts()
[7557]1244{
[18429]1245        unsigned long long pts = 0;
1246        unsigned long long sec = 0;
[7557]1247
[10626]1248#ifdef EPLAYER3
[7586]1249        if(player && player->playback)
[7557]1250        {
1251                player->playback->Command(player, PLAYBACK_PTS, &pts);
1252                sec = pts / 90000;
[8418]1253                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
[7557]1254        }
1255#endif
1256
[10626]1257#ifdef EPLAYER4
1258        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1259       
[13982]1260/*
[10626]1261        if(m_gst_playbin)
1262        {
[13604]1263                gst_element_query_position(m_gst_playbin, &fmt, (gint64*)&pts);
[13977]1264                sec = pts / 1000000000;
1265                pts = sec * 90000;
1266                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
[10626]1267        }
[13982]1268*/
1269
1270        if(m_gst_playbin)
1271        {
1272                gint64 pos;
1273                GstElement *sink;
1274                pts = 0;
1275
1276                g_object_get(G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
1277
1278                if(!sink) g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
1279                if(!sink) return 0;
1280
1281                gchar *name = gst_element_get_name(sink);
[16471]1282                gboolean use_get_decoder_time = ostrstr(name, "dvbaudiosink") || ostrstr(name, "dvbvideosink");
[13982]1283                g_free(name);
1284
1285                if(use_get_decoder_time) g_signal_emit_by_name(sink, "get-decoder-time", &pos);
1286
1287                gst_object_unref(sink);
1288
1289                if(!use_get_decoder_time && !gst_element_query_position(m_gst_playbin, &fmt, &pos))
1290                        return 0;
1291
1292                /* pos is in nanoseconds. we have 90 000 pts per second. */
1293                pts = pos / 11111;
1294                pts = pts - m_gst_startpts;
1295                sec = pts / 90000;
1296                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);
1297        }
[10626]1298#endif
1299
[13977]1300        if(pts < 0) pts = 0;
[7557]1301        return pts;
1302}
1303
1304double playergetlength()
1305{
1306        double length = 0;
1307
[10626]1308#ifdef EPLAYER3
[9625]1309        if(player && player->playback)
[7557]1310        {
[10626]1311                player->playback->Command(player, PLAYBACK_LENGTH, &length);
1312                if(length < 0) length = 0;
1313                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
1314        }
1315#endif
[9625]1316
[10626]1317#ifdef EPLAYER4
1318        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1319        gint64 len;
1320
1321        if(m_gst_playbin)
1322        {
1323                gst_element_query_duration(m_gst_playbin, &fmt, &len);
[13982]1324                length = len / 1000000000;
[9625]1325                if(length < 0) length = 0;
[8418]1326                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
[7557]1327        }
1328#endif
1329
1330        return length;
1331}
1332
1333char* playergetinfo(char* tag)
1334{
[18711]1335        char* ret = NULL;
[7557]1336
[10626]1337#ifdef EPLAYER3
[18711]1338        char *tags[] = {"Title", "Artist", "Album", "Year", "Genre", "Comment", "Track", "Copyright", "TestLibEplayer", NULL};
1339        int i = 0;
[7557]1340
[7586]1341        if(player && player->playback)
[7557]1342        {
[18711]1343                while(tags[i] != NULL)
1344                {
1345                        ret = tags[i];
1346                        if(ostrcmp(tag, ret) == 0)
[18812]1347                        {
[18711]1348                                player->playback->Command(player, PLAYBACK_INFO, &ret);
[18812]1349                                break;
1350                        }
[7557]1351
[18711]1352                        i++;
1353                }
[7557]1354        }
1355#endif
1356        return ret;
1357}
1358
1359void playerchangeaudiotrack(int num)
1360{
[10626]1361#ifdef EPLAYER3
[7586]1362        if(player && player->playback)
[7557]1363        {
[24075]1364                //if(num >= 0 && num <= 9)
[7557]1365                        player->playback->Command(player, PLAYBACK_SWITCH_AUDIO, (void*)&num);
1366        }
1367#endif
[10742]1368
1369#ifdef EPLAYER4
1370        if(m_gst_playbin != NULL)
1371                g_object_set(G_OBJECT(m_gst_playbin), "current-audio", num, NULL);     
1372#endif
[7557]1373}
1374
1375void playerchangesubtitletrack(int num)
1376{
[10626]1377#ifdef EPLAYER3
[7586]1378        if(player && player->playback)
[7557]1379        {
[24065]1380                //if(num >= 0 && num <= 9)
[7557]1381                        player->playback->Command(player, PLAYBACK_SWITCH_SUBTITLE, (void*)&num);
1382        }
1383#endif
1384}
1385
[14261]1386void playerstopsubtitletrack()
1387{
1388#ifdef EPLAYER3
1389        if(player && player->output && player->output->subtitle)
1390                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_STOP, NULL);
1391
[7557]1392#endif
[14261]1393}
1394
[17698]1395int playerjumpts(struct service* servicenode, int sekunden, int *startpts, off64_t *poslastpts, off64_t *bitrate, int vpid, int tssize)
[17689]1396{
1397        int adaptation = 0;
1398        int payload = 0;
1399        int pes = 0;
[20276]1400        int tspid = 0;
[17689]1401       
1402        off64_t pts  = 0;
[18403]1403        uint64_t aktpts = 0;
1404        long long unsigned int lenpts = 0;
[20276]1405        long long unsigned int startpts1 = 0;
1406        long long unsigned int endpts = 0;
[18403]1407        long long unsigned int aktbitrate = 0;
[17689]1408        off64_t ziehlpts = 0;
1409
1410        off64_t curpos = 0;
1411        off64_t newpos = 0;
[17698]1412        off64_t jump = 0;
[17689]1413
1414        int kleiner = 0;
1415        int groesser = 0;
1416        int gleich = 0;
1417        int len = 0;
1418        int i = 0;
[17698]1419        int ret = 0;
[17689]1420
[20276]1421        if(servicenode == NULL) return -1;
1422
[17689]1423        int buflen = tssize * 15000;
1424        char *buf = malloc(buflen);
1425        if(buf == NULL)
1426                return -1;
1427       
1428        curpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);   
1429        int dupfd = open(servicenode->recname, O_RDONLY | O_LARGEFILE);
[17698]1430        newpos = lseek64(dupfd, curpos, SEEK_SET);
1431       
[17689]1432        if (*startpts == 0)
1433        {
1434                if(videogetpts(status.aktservice->videodev, &aktpts) == 0)
1435                {
1436                                ziehlpts = (aktpts / 90000) + sekunden;
1437                }
1438                else
[17698]1439                        return 1;
[17689]1440        }
1441        else
1442        {
1443                ziehlpts = *startpts + sekunden;
1444        }
[17698]1445        *startpts = ziehlpts;
[17689]1446
[17698]1447        if(*bitrate == 0)
1448        {
[20276]1449                lenpts = servicenode->lenpts;
1450                startpts1 = servicenode->startpts;
1451                endpts = servicenode->endpts;
1452                aktbitrate = servicenode->bitrate;
1453                ret = gettsinfo(dupfd, &lenpts, &startpts1, &endpts, &aktbitrate, servicenode->tssize);
[17698]1454                if(ret != 0)
1455                {
[20443]1456                        err("can't read ts info");
[17698]1457                }
1458                else
1459                        *bitrate = aktbitrate;
1460                newpos = lseek64(dupfd, curpos, SEEK_SET);
1461        }
1462        else
1463                aktbitrate = *bitrate;
1464               
1465        if(*poslastpts == 0)
1466                *poslastpts = curpos;
1467       
[17689]1468        if(sekunden > 0)
1469        {
[19736]1470                err("not implemented");
[17698]1471                return 1;
[17689]1472        }       
1473        else if(sekunden < 0)
1474        {
[17698]1475                sekunden = sekunden * -1;
1476                if(aktbitrate != 0)
1477                {
1478                        jump = (aktbitrate / 8) * sekunden;
1479                        jump = jump + (curpos - *poslastpts);
1480                        jump = jump + (jump % servicenode->tssize);
1481                        newpos = lseek64(dupfd, -jump, SEEK_CUR);
1482                }
1483                else
1484                        newpos = lseek64(dupfd, - buflen, SEEK_CUR);
[17689]1485                if(newpos < 0)
1486                        newpos = lseek64(dupfd, tssize, SEEK_SET);
1487        }
1488        len = read(dupfd, buf, buflen);
1489        for(i = 0; i < len; i = i + 1)
1490        {
1491                if (buf[i] == 0x47 && buf[i+tssize] == 0x47)
1492                {
1493                        newpos = lseek64(dupfd, newpos + i, SEEK_SET);
1494                        break;
1495                }
1496        }
1497        if(i >= len)
1498        {
1499                newpos = lseek64(dupfd, curpos, SEEK_SET);     
[17698]1500                return 1;
[17689]1501        }
1502        while(1)
1503        {
1504        len = read(dupfd, buf, buflen);
1505
1506                if(len > 0)
1507                {
1508                        for(i = 0; i <= len-tssize; i = i + tssize)
1509                        {
1510                                payload = 0;
1511
1512                                tspid = (buf[i+1] & 0x1F) << 8;
1513                                tspid = tspid + (buf[i+2] & 0xFF);
1514                                pes = buf[i+1] & 0x40;
1515
1516                                if(tspid == vpid)
1517                                {       
1518                                        adaptation = buf[i+3] & 0x30;
1519                                        if(adaptation == 16)
1520                                        {
1521                                                payload = 4;
1522                                        }
1523                                        if(adaptation == 32)
1524                                        {
1525                                                //printf("adaptation field only\n");
1526                                        }
[20284]1527                                        if(adaptation == 48)
1528                                        {
[17689]1529                                                payload = buf[i+4] & 0xFF;
1530                                                payload = payload + 5;
1531                                        }
1532                                        if(payload != 0)
1533                                        {
1534                                                if(pes == 64)
1535                                                {
1536                                                        if(buf[i+payload+7] & 0x80) //PTS
1537                                                        {
1538                                                                pts = ((unsigned long long)(buf[i+payload+9] & 0xE)) << 29;
1539                                                                pts |= ((unsigned long long)(buf[i+payload+10] & 0xFF)) << 22;
1540                                                                pts |= ((unsigned long long)(buf[i+payload+11] & 0xFE)) << 14;
1541                                                                pts |= ((unsigned long long)(buf[i+payload+12] & 0xFF)) << 7;
1542                                                                pts |= ((unsigned long long)(buf[i+payload+13] & 0xFE)) >> 1;
1543                                                               
1544                                                                if(pts / 90000 == ziehlpts)
1545                                                                {
1546                                                                        gleich = newpos + i;
1547                                                                        break;
1548                                                                }
1549                                                                else if(pts / 90000 > ziehlpts)
1550                                                                {                                                                       
1551                                                                        groesser = newpos + i;
1552                                                                        break;
1553                                                                }
1554                                                                else
1555                                                                {
1556                                                                        kleiner = newpos + i;
1557                                                                }
1558                                                        }
1559                                                }
1560                                        }
1561                                }
1562                        }
1563                        if(gleich != 0)
1564                        {
1565                                close(dupfd);
1566                                free(buf);buf = NULL;
[17698]1567                                *poslastpts = lseek64(servicenode->recsrcfd, gleich, SEEK_SET);
1568                                return 0;
[17689]1569                        }
1570                        else if(groesser != 0 && kleiner != 0)
1571                        {
1572                                close(dupfd);
1573                                free(buf);buf = NULL;
[17698]1574                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
1575                                return 0;
[17689]1576                        }
1577                        else if(groesser != 0)
1578                        {
1579                                if((newpos - buflen)  < 0)
1580                                {
1581                                        close(dupfd);
1582                                        free(buf);buf = NULL;
[17698]1583                                        *poslastpts = 0;
[17689]1584                                        return -1       ;
1585                                }
1586                                else
[17698]1587                                {
[17689]1588                                        newpos = lseek64(dupfd, -(buflen * 2), SEEK_CUR);
[17698]1589                                }
[17689]1590                        }
1591                }
1592                else
1593                {
1594                        if(kleiner == 0)
1595                        {
1596                                close(dupfd);
1597                                free(buf);buf = NULL;
1598                                newpos = lseek64(servicenode->recsrcfd, curpos, SEEK_SET);
[17698]1599                                *poslastpts = 0;
[17689]1600                                return -1;
1601                        }
1602                        else
1603                        {
1604                                close(dupfd);
1605                                free(buf);buf = NULL;
[17698]1606                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
1607                                return 0;
[17689]1608                        }
1609                }
1610        }
1611}
1612
1613
[14261]1614#endif
Note: See TracBrowser for help on using the repository browser.