source: titan/titan/player.h @ 24090

Last change on this file since 24090 was 24090, 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
[24081]621                subout.screen_width = skinfb->width;
622                subout.screen_height = skinfb->height;
623                subout.framebufferFD = skinfb->fd;
624                subout.destination = (uint32_t *)skinfb->fb;
625                subout.destStride = skinfb->pitch;
[14229]626                subout.shareFramebuffer = 1;
[24090]627                subout.framebufferBlit = blitfb1;
[14229]628
629                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&subout);
[19736]630               
[7557]631                if(player->playback->Command(player, PLAYBACK_OPEN, tmpfile) < 0)
632                {
633                        free(player); player = NULL;
634                        free(tmpfile);
635                        return 1;
636                }
637
638                player->output->Command(player, OUTPUT_OPEN, NULL);
639                player->playback->Command(player, PLAYBACK_PLAY, NULL);
640
641                free(tmpfile);
642
643                return 0;
644#endif
[10626]645
646#ifdef EPLAYER4
647                int flags = 0x47; //(GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT);
648               
[10742]649                if(m_gst_playbin != NULL)
650                {
651                        debug(150, "eplayer allready running");
652                        playerstop();
653                }
654               
[16471]655                if(ostrstr(file, "://") == NULL)
[13959]656                        tmpfile = ostrcat("file://", file, 0, 0);
657                else
[16286]658                        tmpfile = ostrcat(file, NULL, 0, 0);
[13959]659
660                if(tmpfile == NULL)
661                {
662                        err("no mem");
663                        free(m_gst_playbin); m_gst_playbin = NULL;
664                        return 1;
665                }
[13962]666
[16471]667                if(ostrstr(tmpfile, "file://") == NULL)
[13982]668                        status.playercan = 0x7E7F;
[13962]669                else
[13982]670                        status.playercan = 0x7E7F;
[13959]671               
[10626]672                m_gst_playbin = gst_element_factory_make("playbin2", "playbin");
[13959]673                g_object_set(G_OBJECT (m_gst_playbin), "uri", tmpfile, NULL);
[10626]674                g_object_set(G_OBJECT (m_gst_playbin), "flags", flags, NULL);
[13959]675                free(tmpfile); tmpfile = NULL;
[10626]676               
[13917]677                if(m_gst_playbin)
678                        gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
679               
[13982]680                int count = 0;
681                m_gst_startpts = 0;
682                while(m_gst_startpts == 0 && count < 5)
683                {
684                        count++;
685                        sleep(1);
686                        m_gst_startpts = playergetpts();
687                }
[10626]688                return 0;
689#endif
[7557]690        }
[9746]691       
[7557]692        return 1;
693}
694
[10702]695void playerinit(int argc, char* argv[])
696{
697#ifdef EPLAYER4
698        gst_init(&argc, &argv);
699#endif
700}
701
[11089]702#ifdef EPLAYER4
703int gstbuscall(GstBus *bus, GstMessage *msg)
704{
705        int ret = 1;
[13982]706        if(!m_gst_playbin) return 0;
[13591]707        if(!msg) return ret;
[11089]708
709        gchar *sourceName = NULL;
710        GstObject *source = GST_MESSAGE_SRC(msg);
711
[13591]712        if(!GST_IS_OBJECT(source)) return ret;
[11089]713        sourceName = gst_object_get_name(source);
714
715        switch(GST_MESSAGE_TYPE(msg))
716        {
717                case GST_MESSAGE_EOS:
718                        debug(150, "gst player eof");
719                        ret = 0;
720                        break;
721                case GST_MESSAGE_STATE_CHANGED:
[13982]722                        if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
723                                break;
724
725                        GstState old_state, new_state;
726                        gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
727               
728                        if(old_state == new_state) break;
729       
730                        debug(150, "gst state change %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
731       
732                        GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
733       
734                        switch(transition)
735                        {
736                                case GST_STATE_CHANGE_NULL_TO_READY:
737                                        break;
738                                case GST_STATE_CHANGE_READY_TO_PAUSED:
739/*
740                                        GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
741                                        if(appsink)
742                                        {
743                                                g_object_set(G_OBJECT(appsink), "max-buffers", 2, NULL);
744                                                g_object_set(G_OBJECT(appsink), "sync", FALSE, NULL);
745                                                g_object_set(G_OBJECT(appsink), "emit-signals", TRUE, NULL);
746                                                gst_object_unref(appsink);
747                                        }
748*/
749                                        break;
750                                case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
751                                        //if(m_sourceinfo.is_streaming && m_streamingsrc_timeout )
752                                                //m_streamingsrc_timeout->stop();
753                                        break;
754                                case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
755                                        break;
756                                case GST_STATE_CHANGE_PAUSED_TO_READY:
757                                        break;
758                                case GST_STATE_CHANGE_READY_TO_NULL:
759                                        ret = 0;
760                                        break;
761                        }
[11089]762                        break;
763                case GST_MESSAGE_ERROR:
764                        debug(150, "gst player error");
[13982]765
766                        gchar *gdebug1;
767                        GError *err;
768
769                        gst_message_parse_error(msg, &err, &gdebug1);
770                        g_free(gdebug1);
771
772                        debug(150, "gst error: %s (%i) from %s", err->message, err->code, sourceName);
773                        if(err->domain == GST_STREAM_ERROR)
774                        {
775                                if(err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
776                                {
777                                        //if(g_strrstr(sourceName, "videosink"))
778                                        //      m_event((iPlayableService*)this, evUser+11);
779                                        //else if ( g_strrstr(sourceName, "audiosink") )
780                                        //      m_event((iPlayableService*)this, evUser+10);
781                                }
782                        }
783                        g_error_free(err);
[11089]784                        break;
785                case GST_MESSAGE_INFO:
786                        debug(150, "gst player info");
[13982]787
788/*
789                        gchar *gdebug2;
790                        GError *inf;
791       
792                        gst_message_parse_info(msg, &inf, &gdebug2);
793                        g_free(gdebug2);
794                        if(inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
795                        {
796                                //if(g_strrstr(sourceName, "videosink"))
797                                //      m_event((iPlayableService*)this, evUser+14);
798                        }
799                        g_error_free(inf);
800*/
[11089]801                        break;
802                case GST_MESSAGE_TAG:
803                        debug(150, "gst player tag");
804                        break;
[13591]805                //case GST_MESSAGE_ASYNC_DONE:
806                //      debug(150, "gst player async done");
807                //      break;
[11089]808                case GST_MESSAGE_ELEMENT:
809                        debug(150, "gst player element");
810                        break;
811                case GST_MESSAGE_BUFFERING:
812                        debug(150, "gst player buffering");
[13982]813
814/*
815                        GstBufferingMode mode;
816                        gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
817                        gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
818                        //m_event((iPlayableService*)this, evBuffering);
819*/
[11089]820                        break;
821                case GST_MESSAGE_STREAM_STATUS:
822                        debug(150, "gst player stream status");
[13982]823
824/*
825                        GstStreamStatusType type;
826                        GstElement *owner;
827
828                        gst_message_parse_stream_status(msg, &type, &owner);
829                        if(type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming)
830                        {
831                                if(GST_IS_PAD(source))
832                                        owner = gst_pad_get_parent_element(GST_PAD(source));
833                                else if(GST_IS_ELEMENT(source))
834                                        owner = GST_ELEMENT(source);
835                                else
836                                        owner = NULL;
837                                if(owner)
838                                {
839                                        GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
840                                        const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
841                                        if (!strcmp(name, "souphttpsrc"))
842                                        {
843                                                //m_streamingsrc_timeout->start(10 * 1000, true);
844                                                g_object_set(G_OBJECT(owner), "timeout", 10, NULL);
845                                        }
846                                       
847                                }
848                                if(GST_IS_PAD(source))
849                                        gst_object_unref(owner);
850                        }
851*/
[11089]852                        break;
853                default:
854                        debug(150, "gst player unknown message");
855                        break;
856        }
857        g_free(sourceName);
858        return ret;
859}
860#endif
861
[19736]862int playergetbuffersize()
863{
864        int ret = 0;
[20284]865
[19736]866#ifdef EPLAYER3
867        if(player && player->container && player->container->selectedContainer)
868                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_SIZE, (void*)&ret);
869#endif
870
871        return ret;
872}
873
874int playergetbufferstatus()
875{
876        int ret = 0;
[20284]877
[19736]878#ifdef EPLAYER3
879        if(player && player->container && player->container->selectedContainer)
880                player->container->selectedContainer->Command(player, CONTAINER_GET_BUFFER_STATUS, (void*)&ret);
881#endif
882
883        return ret;
884}
885
[19810]886int playerstopbuffer()
887{
888        int ret = 0;
889
890#ifdef EPLAYER3
[19875]891        if(player && player->container && player->container->selectedContainer)
892                player->container->selectedContainer->Command(player, CONTAINER_STOP_BUFFER, NULL);
[19810]893#endif
894
895        return ret;
896}
897
[10626]898int playerisplaying()
899{
900#ifdef SIMULATE
901        return 1;
902#endif
903
904#ifdef EPLAYER3
905        if(player != NULL && player->playback != NULL && player->playback->isPlaying)
906                return 1;
907#endif
908
[11089]909#ifdef EPLAYER4
910        int ret = 1;
911
912        if(m_gst_playbin)
913        {
914                GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(m_gst_playbin));
915                GstMessage *message = NULL;
916                while((message = gst_bus_pop(bus)))
917                {
[13591]918                        ret = gstbuscall(bus, message);
[11089]919                        gst_message_unref(message);
920                }
921        }
[13982]922        else
923                ret = 0;
924
[11089]925        return ret;
926#endif
[10626]927        return 0;
928}
929
[8451]930void playerplay()
931{
[10626]932#ifdef EPLAYER3
[8451]933        if(player && player->playback)
934                player->playback->Command(player, PLAYBACK_PLAY, NULL);
935#endif
[13982]936
937#ifdef EPLAYER4
938        if(m_gst_playbin)
939                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
940#endif
[8451]941}
942
[7557]943int playerstop()
944{
[10626]945#ifdef EPLAYER3
[9665]946        if(player && player->playback)
[7557]947                player->playback->Command(player, PLAYBACK_STOP, NULL);
[9665]948        if(player && player->container && player->container->selectedContainer)
949                player->container->selectedContainer->Command(player, CONTAINER_STOP, NULL);
[7976]950        if(player && player->output)
951        {
[9665]952                player->output->Command(player, OUTPUT_CLOSE, NULL);
[8451]953                player->output->Command(player, OUTPUT_DEL, (void*)"audio");
954                player->output->Command(player, OUTPUT_DEL, (void*)"video");
955                player->output->Command(player, OUTPUT_DEL, (void*)"subtitle");
[7976]956        }
957        if(player && player->playback)
[8451]958                player->playback->Command(player, PLAYBACK_CLOSE, NULL);
[7557]959
[7586]960        free(player);
961        player = NULL;
[7557]962#endif
[10626]963
964#ifdef EPLAYER4
965        if(m_gst_playbin)
966        {
967                gst_element_set_state(m_gst_playbin, GST_STATE_NULL);
[13591]968                gst_object_unref(GST_OBJECT(m_gst_playbin));
[13959]969                m_gst_playbin = NULL;
[10626]970        }
971#endif
972
[9593]973        writesysint("/proc/sys/vm/drop_caches", 3, 0);
[7586]974        return 0;
[7557]975}
976
[10626]977void playerafterend()
978{
979#ifdef EPLAYER3
980        if(player != NULL && player->playback != NULL)
981                playerstop();
982#endif
[13980]983
984#ifdef EPLAYER4
985        if(m_gst_playbin)
986                playerstop();
987#endif
[10626]988}
989
[7557]990void playerpause()
991{
[10626]992#ifdef EPLAYER3
[7586]993        if(player && player->playback)
[7557]994                player->playback->Command(player, PLAYBACK_PAUSE, NULL);
995#endif
[10626]996
997#ifdef EPLAYER4
998        if(m_gst_playbin)
999                gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED);
1000#endif
[7557]1001}
1002
1003void playercontinue()
1004{
[10626]1005#ifdef EPLAYER3
[7586]1006        if(player && player->playback)
[7557]1007                player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
1008#endif
[10626]1009
1010#ifdef EPLAYER4
1011        if(m_gst_playbin)
1012                gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
1013#endif
[7557]1014}
1015
1016void playerff(int speed)
1017{
[10626]1018#ifdef EPLAYER3
[7557]1019        int speedmap = 0;
1020
[8267]1021        if (speed < 1) speed = 1;
[7557]1022        if (speed > 7) speed = 7;
1023
1024        switch(speed)
1025        {
1026                case 1: speedmap = 1; break;
1027                case 2: speedmap = 3; break;
1028                case 3: speedmap = 7; break;
1029                case 4: speedmap = 15; break;
1030                case 5: speedmap = 31; break;
1031                case 6: speedmap = 63; break;
1032                case 7: speedmap = 127; break;
1033        }
1034
[7586]1035        if(player && player->playback)
[8267]1036                player->playback->Command(player, PLAYBACK_FASTFORWARD, &speedmap);
[7557]1037#endif
1038}
1039
[19762]1040void playerslow(int speed)
1041{
1042#ifdef EPLAYER3
1043        int speedmap = 0;
1044
1045        if (speed < 1) speed = 1;
1046        if (speed > 7) speed = 7;
1047
1048        switch(speed)
1049        {
1050                case 1: speedmap = 1; break;
1051                case 2: speedmap = 3; break;
1052                case 3: speedmap = 7; break;
1053                case 4: speedmap = 15; break;
1054                case 5: speedmap = 31; break;
1055                case 6: speedmap = 63; break;
1056                case 7: speedmap = 127; break;
1057        }
1058
1059        if(player && player->playback)
1060                player->playback->Command(player, PLAYBACK_SLOWMOTION, &speedmap);
1061#endif
1062}
1063
[7557]1064void playerfr(int speed)
1065{
[10626]1066#ifdef EPLAYER3
[7557]1067        int speedmap = 0;
1068
[8267]1069        if (speed > -1) speed = -1;
[7557]1070        if (speed < -7) speed = -7;
1071
1072        switch(speed)
1073        {
1074                case -1: speedmap = -5; break;
1075                case -2: speedmap = -10; break;
1076                case -3: speedmap = -20; break;
1077                case -4: speedmap = -40; break;
1078                case -5: speedmap = -80; break;
1079                case -6: speedmap = -160; break;
1080                case -7: speedmap = -320; break;
1081        }
1082
[7586]1083        if(player && player->playback)
[8267]1084                player->playback->Command(player, PLAYBACK_FASTBACKWARD, &speedmap);
[7557]1085#endif
1086}
1087
1088void playerseek(float sec)
1089{
[10626]1090#ifdef EPLAYER3
[7586]1091        if(player && player->playback)
[7557]1092                player->playback->Command(player, PLAYBACK_SEEK, (void*)&sec);
1093#endif
[10626]1094
1095#ifdef EPLAYER4
[13982]1096        gint64 nanos_pts = 0, nanos_len = 0;
1097        gint64 pts = 0, len = 0;
[15831]1098        //GstFormat fmt = GST_FORMAT_TIME;
[10626]1099               
1100        if(m_gst_playbin)
1101        {
[13982]1102                len = playergetlength();
1103                nanos_len = len * 1000000000;
1104                if(nanos_len < 0) nanos_len = 0;
1105
1106                pts = playergetpts();
1107                nanos_pts = pts * 11111;
1108                nanos_pts = nanos_pts + (sec * 1000000000);
1109                if(nanos_pts < 0) nanos_pts = 0;
1110
1111                if(nanos_pts >= nanos_len)
1112                        playerstop();
1113                else
1114                        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]1115        }
1116#endif
[7557]1117}
1118
1119void playerfreetracklist(char** TrackList)
1120{
1121        int i = 0;
1122
[7586]1123        if(TrackList != NULL)
[7557]1124        {
[7586]1125                while(TrackList[i] != NULL)
1126                {
1127                        free(TrackList[i]);
[8418]1128                        free(TrackList[i + 1]);
1129                        i += 2;
[7586]1130                }
[7557]1131        }
1132}
1133
1134char** playergettracklist(int type)
1135{
1136        char ** TrackList = NULL;
[10626]1137#ifdef EPLAYER3
[7586]1138        if(player && player->manager)
[7557]1139        {
1140                switch(type)
1141                {
1142                        case 1:
[7586]1143                                if(player->manager->audio)
1144                                {
1145                                        player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
1146                                        debug(150, "Audio Track List");
1147                                }
[7557]1148                                break;
1149                        case 2:
[7586]1150                                if(player->manager->subtitle)
1151                                {
1152                                        player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
1153                                        debug(150, "Subtitle Track List");
1154                                }
[7557]1155                                break;
1156                        default:
[7586]1157                                if(player->manager->video)
1158                                {
1159                                        player->manager->video->Command(player, MANAGER_LIST, &TrackList);
1160                                        debug(150, "Video Track List");
1161                                }
[7557]1162                }
[24058]1163               
1164                int i = 0;
[7557]1165                if(TrackList != NULL)
1166                {
[24079]1167                        while(TrackList[i] != NULL)
1168                        {
1169                                string_newline(TrackList[i]);
1170                                i += 2;
1171                        }
1172                       
[8451]1173                        debug(150, "Track List");
[24058]1174                        i = 0;
[7557]1175                        while(TrackList[i] != NULL)
1176                        {
[8418]1177                                debug(150, "%s - %s", TrackList[i], TrackList[i + 1]);
1178                                i += 2;
[7557]1179                        }
1180                }
1181        }
1182#endif
1183        return TrackList;
1184}
1185
[8451]1186//*CurTrackEncoding and *CurTrackName be freed
[7557]1187void playergetcurtrac(int type, int *CurTrackId, char** CurTrackEncoding, char** CurTrackName)
1188{
[10626]1189#ifdef EPLAYER3
[7586]1190        if(player && player->manager)
[7557]1191        {
1192                switch(type)
1193                {
1194                        case 1:
[7586]1195                                if(player->manager->audio)
1196                                {
1197                                        player->manager->audio->Command(player, MANAGER_GET, CurTrackId);
1198                                        player->manager->audio->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1199                                        player->manager->audio->Command(player, MANAGER_GETNAME, CurTrackName);
1200                                }
[7557]1201                                break;
1202                        case 2:
[7586]1203                                if(player->manager->subtitle)
1204                                {
1205                                        player->manager->subtitle->Command(player, MANAGER_GET, CurTrackId);
1206                                        player->manager->subtitle->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1207                                        player->manager->subtitle->Command(player, MANAGER_GETNAME, CurTrackName);
1208                                }
[7557]1209                                break;
1210                        default:
[7586]1211                                if(player->manager->video)
1212                                {
1213                                        player->manager->video->Command(player, MANAGER_GET, CurTrackId);
1214                                        player->manager->video->Command(player, MANAGER_GETENCODING, CurTrackEncoding);
1215                                        player->manager->video->Command(player, MANAGER_GETNAME, CurTrackName);
1216                                }
[7557]1217                }
1218
1219                if(CurTrackId != NULL)
1220                        debug(150, "Current Track ID: %d", *CurTrackId);
1221                if(*CurTrackEncoding != NULL)
1222                        debug(150, "Current Track Enc: %s", *CurTrackEncoding);
1223                if(*CurTrackName != NULL)
1224                        debug(150, "Current Track Name: %s", *CurTrackName);
1225        }
1226#endif
[10742]1227
1228#ifdef EPLAYER4
1229        if(m_gst_playbin != NULL)
1230        {
1231                switch(type)
1232                {
1233                        case 1:
1234                                g_object_get(G_OBJECT(m_gst_playbin), "current-audio", CurTrackId, NULL);
1235                                break;
1236                }
1237               
1238                if(CurTrackId != NULL)
1239                        debug(150, "Current Track ID: %d", *CurTrackId);
1240        }
1241#endif
[7557]1242}
1243
[18429]1244unsigned long long playergetpts()
[7557]1245{
[18429]1246        unsigned long long pts = 0;
1247        unsigned long long sec = 0;
[7557]1248
[10626]1249#ifdef EPLAYER3
[7586]1250        if(player && player->playback)
[7557]1251        {
1252                player->playback->Command(player, PLAYBACK_PTS, &pts);
1253                sec = pts / 90000;
[8418]1254                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
[7557]1255        }
1256#endif
1257
[10626]1258#ifdef EPLAYER4
1259        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1260       
[13982]1261/*
[10626]1262        if(m_gst_playbin)
1263        {
[13604]1264                gst_element_query_position(m_gst_playbin, &fmt, (gint64*)&pts);
[13977]1265                sec = pts / 1000000000;
1266                pts = sec * 90000;
1267                debug(150, "Pts = %02d:%02d:%02d (%llu.0000 sec)", (int)((sec / 60) / 60) % 60, (int)(sec / 60) % 60, (int)sec % 60, sec);
[10626]1268        }
[13982]1269*/
1270
1271        if(m_gst_playbin)
1272        {
1273                gint64 pos;
1274                GstElement *sink;
1275                pts = 0;
1276
1277                g_object_get(G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
1278
1279                if(!sink) g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
1280                if(!sink) return 0;
1281
1282                gchar *name = gst_element_get_name(sink);
[16471]1283                gboolean use_get_decoder_time = ostrstr(name, "dvbaudiosink") || ostrstr(name, "dvbvideosink");
[13982]1284                g_free(name);
1285
1286                if(use_get_decoder_time) g_signal_emit_by_name(sink, "get-decoder-time", &pos);
1287
1288                gst_object_unref(sink);
1289
1290                if(!use_get_decoder_time && !gst_element_query_position(m_gst_playbin, &fmt, &pos))
1291                        return 0;
1292
1293                /* pos is in nanoseconds. we have 90 000 pts per second. */
1294                pts = pos / 11111;
1295                pts = pts - m_gst_startpts;
1296                sec = pts / 90000;
1297                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);
1298        }
[10626]1299#endif
1300
[13977]1301        if(pts < 0) pts = 0;
[7557]1302        return pts;
1303}
1304
1305double playergetlength()
1306{
1307        double length = 0;
1308
[10626]1309#ifdef EPLAYER3
[9625]1310        if(player && player->playback)
[7557]1311        {
[10626]1312                player->playback->Command(player, PLAYBACK_LENGTH, &length);
1313                if(length < 0) length = 0;
1314                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
1315        }
1316#endif
[9625]1317
[10626]1318#ifdef EPLAYER4
1319        GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
1320        gint64 len;
1321
1322        if(m_gst_playbin)
1323        {
1324                gst_element_query_duration(m_gst_playbin, &fmt, &len);
[13982]1325                length = len / 1000000000;
[9625]1326                if(length < 0) length = 0;
[8418]1327                debug(150, "Length = %02d:%02d:%02d (%.4f sec)", (int)((length / 60) / 60) % 60, (int)(length / 60) % 60, (int)length % 60, length);
[7557]1328        }
1329#endif
1330
1331        return length;
1332}
1333
1334char* playergetinfo(char* tag)
1335{
[18711]1336        char* ret = NULL;
[7557]1337
[10626]1338#ifdef EPLAYER3
[18711]1339        char *tags[] = {"Title", "Artist", "Album", "Year", "Genre", "Comment", "Track", "Copyright", "TestLibEplayer", NULL};
1340        int i = 0;
[7557]1341
[7586]1342        if(player && player->playback)
[7557]1343        {
[18711]1344                while(tags[i] != NULL)
1345                {
1346                        ret = tags[i];
1347                        if(ostrcmp(tag, ret) == 0)
[18812]1348                        {
[18711]1349                                player->playback->Command(player, PLAYBACK_INFO, &ret);
[18812]1350                                break;
1351                        }
[7557]1352
[18711]1353                        i++;
1354                }
[7557]1355        }
1356#endif
1357        return ret;
1358}
1359
1360void playerchangeaudiotrack(int num)
1361{
[10626]1362#ifdef EPLAYER3
[7586]1363        if(player && player->playback)
[24079]1364                player->playback->Command(player, PLAYBACK_SWITCH_AUDIO, (void*)&num);
[7557]1365#endif
[10742]1366
1367#ifdef EPLAYER4
1368        if(m_gst_playbin != NULL)
1369                g_object_set(G_OBJECT(m_gst_playbin), "current-audio", num, NULL);     
1370#endif
[7557]1371}
1372
1373void playerchangesubtitletrack(int num)
1374{
[10626]1375#ifdef EPLAYER3
[7586]1376        if(player && player->playback)
[24079]1377                player->playback->Command(player, PLAYBACK_SWITCH_SUBTITLE, (void*)&num);
[7557]1378#endif
1379}
1380
[14261]1381void playerstopsubtitletrack()
1382{
1383#ifdef EPLAYER3
1384        if(player && player->output && player->output->subtitle)
1385                player->output->subtitle->Command(player, (OutputCmd_t)OUTPUT_STOP, NULL);
[7557]1386#endif
[14261]1387}
1388
[17698]1389int playerjumpts(struct service* servicenode, int sekunden, int *startpts, off64_t *poslastpts, off64_t *bitrate, int vpid, int tssize)
[17689]1390{
1391        int adaptation = 0;
1392        int payload = 0;
1393        int pes = 0;
[20276]1394        int tspid = 0;
[17689]1395       
1396        off64_t pts  = 0;
[18403]1397        uint64_t aktpts = 0;
1398        long long unsigned int lenpts = 0;
[20276]1399        long long unsigned int startpts1 = 0;
1400        long long unsigned int endpts = 0;
[18403]1401        long long unsigned int aktbitrate = 0;
[17689]1402        off64_t ziehlpts = 0;
1403
1404        off64_t curpos = 0;
1405        off64_t newpos = 0;
[17698]1406        off64_t jump = 0;
[17689]1407
1408        int kleiner = 0;
1409        int groesser = 0;
1410        int gleich = 0;
1411        int len = 0;
1412        int i = 0;
[17698]1413        int ret = 0;
[17689]1414
[20276]1415        if(servicenode == NULL) return -1;
1416
[17689]1417        int buflen = tssize * 15000;
1418        char *buf = malloc(buflen);
1419        if(buf == NULL)
1420                return -1;
1421       
1422        curpos = lseek64(servicenode->recsrcfd, 0, SEEK_CUR);   
1423        int dupfd = open(servicenode->recname, O_RDONLY | O_LARGEFILE);
[17698]1424        newpos = lseek64(dupfd, curpos, SEEK_SET);
1425       
[17689]1426        if (*startpts == 0)
1427        {
1428                if(videogetpts(status.aktservice->videodev, &aktpts) == 0)
1429                {
1430                                ziehlpts = (aktpts / 90000) + sekunden;
1431                }
1432                else
[17698]1433                        return 1;
[17689]1434        }
1435        else
1436        {
1437                ziehlpts = *startpts + sekunden;
1438        }
[17698]1439        *startpts = ziehlpts;
[17689]1440
[17698]1441        if(*bitrate == 0)
1442        {
[20276]1443                lenpts = servicenode->lenpts;
1444                startpts1 = servicenode->startpts;
1445                endpts = servicenode->endpts;
1446                aktbitrate = servicenode->bitrate;
1447                ret = gettsinfo(dupfd, &lenpts, &startpts1, &endpts, &aktbitrate, servicenode->tssize);
[17698]1448                if(ret != 0)
1449                {
[20443]1450                        err("can't read ts info");
[17698]1451                }
1452                else
1453                        *bitrate = aktbitrate;
1454                newpos = lseek64(dupfd, curpos, SEEK_SET);
1455        }
1456        else
1457                aktbitrate = *bitrate;
1458               
1459        if(*poslastpts == 0)
1460                *poslastpts = curpos;
1461       
[17689]1462        if(sekunden > 0)
1463        {
[19736]1464                err("not implemented");
[17698]1465                return 1;
[17689]1466        }       
1467        else if(sekunden < 0)
1468        {
[17698]1469                sekunden = sekunden * -1;
1470                if(aktbitrate != 0)
1471                {
1472                        jump = (aktbitrate / 8) * sekunden;
1473                        jump = jump + (curpos - *poslastpts);
1474                        jump = jump + (jump % servicenode->tssize);
1475                        newpos = lseek64(dupfd, -jump, SEEK_CUR);
1476                }
1477                else
1478                        newpos = lseek64(dupfd, - buflen, SEEK_CUR);
[17689]1479                if(newpos < 0)
1480                        newpos = lseek64(dupfd, tssize, SEEK_SET);
1481        }
1482        len = read(dupfd, buf, buflen);
1483        for(i = 0; i < len; i = i + 1)
1484        {
1485                if (buf[i] == 0x47 && buf[i+tssize] == 0x47)
1486                {
1487                        newpos = lseek64(dupfd, newpos + i, SEEK_SET);
1488                        break;
1489                }
1490        }
1491        if(i >= len)
1492        {
1493                newpos = lseek64(dupfd, curpos, SEEK_SET);     
[17698]1494                return 1;
[17689]1495        }
1496        while(1)
1497        {
1498        len = read(dupfd, buf, buflen);
1499
1500                if(len > 0)
1501                {
1502                        for(i = 0; i <= len-tssize; i = i + tssize)
1503                        {
1504                                payload = 0;
1505
1506                                tspid = (buf[i+1] & 0x1F) << 8;
1507                                tspid = tspid + (buf[i+2] & 0xFF);
1508                                pes = buf[i+1] & 0x40;
1509
1510                                if(tspid == vpid)
1511                                {       
1512                                        adaptation = buf[i+3] & 0x30;
1513                                        if(adaptation == 16)
1514                                        {
1515                                                payload = 4;
1516                                        }
1517                                        if(adaptation == 32)
1518                                        {
1519                                                //printf("adaptation field only\n");
1520                                        }
[20284]1521                                        if(adaptation == 48)
1522                                        {
[17689]1523                                                payload = buf[i+4] & 0xFF;
1524                                                payload = payload + 5;
1525                                        }
1526                                        if(payload != 0)
1527                                        {
1528                                                if(pes == 64)
1529                                                {
1530                                                        if(buf[i+payload+7] & 0x80) //PTS
1531                                                        {
1532                                                                pts = ((unsigned long long)(buf[i+payload+9] & 0xE)) << 29;
1533                                                                pts |= ((unsigned long long)(buf[i+payload+10] & 0xFF)) << 22;
1534                                                                pts |= ((unsigned long long)(buf[i+payload+11] & 0xFE)) << 14;
1535                                                                pts |= ((unsigned long long)(buf[i+payload+12] & 0xFF)) << 7;
1536                                                                pts |= ((unsigned long long)(buf[i+payload+13] & 0xFE)) >> 1;
1537                                                               
1538                                                                if(pts / 90000 == ziehlpts)
1539                                                                {
1540                                                                        gleich = newpos + i;
1541                                                                        break;
1542                                                                }
1543                                                                else if(pts / 90000 > ziehlpts)
1544                                                                {                                                                       
1545                                                                        groesser = newpos + i;
1546                                                                        break;
1547                                                                }
1548                                                                else
1549                                                                {
1550                                                                        kleiner = newpos + i;
1551                                                                }
1552                                                        }
1553                                                }
1554                                        }
1555                                }
1556                        }
1557                        if(gleich != 0)
1558                        {
1559                                close(dupfd);
1560                                free(buf);buf = NULL;
[17698]1561                                *poslastpts = lseek64(servicenode->recsrcfd, gleich, SEEK_SET);
1562                                return 0;
[17689]1563                        }
1564                        else if(groesser != 0 && kleiner != 0)
1565                        {
1566                                close(dupfd);
1567                                free(buf);buf = NULL;
[17698]1568                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
1569                                return 0;
[17689]1570                        }
1571                        else if(groesser != 0)
1572                        {
1573                                if((newpos - buflen)  < 0)
1574                                {
1575                                        close(dupfd);
1576                                        free(buf);buf = NULL;
[17698]1577                                        *poslastpts = 0;
[17689]1578                                        return -1       ;
1579                                }
1580                                else
[17698]1581                                {
[17689]1582                                        newpos = lseek64(dupfd, -(buflen * 2), SEEK_CUR);
[17698]1583                                }
[17689]1584                        }
1585                }
1586                else
1587                {
1588                        if(kleiner == 0)
1589                        {
1590                                close(dupfd);
1591                                free(buf);buf = NULL;
1592                                newpos = lseek64(servicenode->recsrcfd, curpos, SEEK_SET);
[17698]1593                                *poslastpts = 0;
[17689]1594                                return -1;
1595                        }
1596                        else
1597                        {
1598                                close(dupfd);
1599                                free(buf);buf = NULL;
[17698]1600                                *poslastpts = lseek64(servicenode->recsrcfd, kleiner, SEEK_SET);
1601                                return 0;
[17689]1602                        }
1603                }
1604        }
1605}
1606
1607
[14261]1608#endif
Note: See TracBrowser for help on using the repository browser.