source: titan/titan/pip.h @ 42987

Last change on this file since 42987 was 41902, checked in by gost, 6 years ago

[titan] fix pip

File size: 16.4 KB
Line 
1#ifndef PIP_H
2#define PIP_H
3
4//flag 0: channel
5//flag 1: playback
6//flag 3: same as 0 but don't check chnode
7//flag 4: same as 0 but new tuning
8//flag 5: same as 3 but new tuning
9int pipstartreal(struct channel* chnode, char* pin, int flag)
10{
11        struct transponder* tpnode = NULL;
12        struct dvbdev *fenode = NULL;
13        struct dvbdev *dmxvideonode = NULL;
14        struct dvbdev *videonode = NULL;
15        int ret = 0, festatus = 1;
16        unsigned char *patbuf = NULL;
17        int checkpmt = 0, pincheck = 0, ageprotect = 0, tune = 0;
18        struct epg* epgnode = NULL;
19
20        m_lock(&status.servicemutex, 2);
21
22        status.secondzap = 0;
23
24        if(flag == 4 || flag == 5) tune = 1;
25        if(flag == 4) flag = 0;
26
27        if(flag == 0 && status.pipservice->type == CHANNEL && status.pipservice->channel != NULL && chnode == status.pipservice->channel)
28        {
29                m_unlock(&status.servicemutex, 2);
30                return 20;
31        }
32        if(flag == 3 || flag == 5) flag = 0;
33
34        if(chnode == NULL)
35        {
36                m_unlock(&status.servicemutex, 2);
37                return 21;
38        }
39       
40        ageprotect = getconfigint("ageprotect", NULL);
41        if(ageprotect > 0) epgnode = getepgakt(chnode);
42        if(chnode->protect > 0 || (epgnode != NULL && epgnode->parentalrating >= ageprotect))
43        {
44                pincheck = screenpincheck(1, pin);
45                if(pincheck == 1)
46                {
47                        m_unlock(&status.servicemutex, 2);
48                        return 22;
49                }
50        }
51
52        //got transponder
53        if(flag == 0)
54        {
55                if(chnode->transponder == NULL)
56                        tpnode = gettransponder(chnode->transponderid);
57                else
58                        tpnode = chnode->transponder;
59        }
60
61        ret = pipstop(status.pipservice, 0);
62
63        //can't stop service (timeshift ??)
64        if(ret == 1)
65        {
66                m_unlock(&status.servicemutex, 2);
67                return 22;
68        }
69       
70        status.pipservice->transponder = tpnode;
71        status.pipservice->channel = chnode;
72        status.pipservice->type = CHANNEL;
73        free(status.pipservice->channellist);
74        status.pipservice->channellist = ostrcat(status.aktservice->channellist, NULL, 0, 0);
75       
76
77        //got frontend dev
78        if(flag == 0)
79        {
80                fenode = fegetfree(tpnode, 0, NULL);
81                if(fenode == NULL)
82                {
83                        m_unlock(&status.servicemutex, 2);
84                        return 1;
85                }
86
87                status.pipservice->fedev = fenode;
88               
89                //frontend tune
90                if(fenode->felasttransponder != tpnode || tune == 1)
91                {
92                        if(fenode->feinfo->type == FE_QPSK)
93                        {
94                                feset(fenode, tpnode);
95                                fetunedvbs(fenode, tpnode);
96                        }
97                        else if(fenode->feinfo->type == FE_QAM)
98                                fetunedvbc(fenode, tpnode);
99                        else if(fenode->feinfo->type == FE_OFDM)
100                                fetunedvbt(fenode, tpnode);
101                        else
102                        {
103                                m_unlock(&status.servicemutex, 2);
104                                return 3;
105                        }
106                }
107        }
108        else if(flag == 1)
109        {
110                fenode = fegetdummy();
111                status.pipservice->fedev = fenode;
112        }
113
114        if(fenode == NULL)
115        {
116                m_unlock(&status.servicemutex, 2);
117                return 1;
118        }
119
120        //check pmt if not all infos in channellist
121        if(chnode->videopid == -1 || chnode->videocodec == -1)
122        {
123                //wait for tuner lock
124                if(flag == 0)
125                {
126                        if(fenode->felasttransponder != tpnode)
127                                festatus = fewait(fenode);
128                        else
129                                festatus = fegetunlock(fenode);
130
131                        if(debug_level == 200) 
132                        {
133                                fereadstatus(fenode);
134                                fegetfrontend(fenode);
135                        }
136                        if(festatus != 0)
137                        {
138                                m_unlock(&status.servicemutex, 2);
139                                return 2;
140                        }
141                }
142
143                checkpmt = 1;
144                if(flag != 1 || (flag == 1 && chnode->pmtpid == 0))
145                {
146                        patbuf = dvbgetpat(fenode, -1);
147                        if(patbuf == NULL) status.secondzap = 1;
148                }
149                free(status.pipservice->pmtbuf);
150                status.pipservice->pmtbuf = NULL;
151                status.pipservice->pmtlen = 0;
152                if(patbuf != NULL)
153                        status.pipservice->pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, &status.pipservice->pmtlen, -1, 0);
154                else if(chnode->pmtpid > 0)
155                        status.pipservice->pmtbuf = dvbgetpmt(fenode, NULL, chnode->serviceid, &chnode->pmtpid, &status.pipservice->pmtlen, -1, 1);
156
157                if(status.pipservice->pmtbuf == NULL) status.secondzap = 2;
158                dvbgetinfo(status.pipservice->pmtbuf, chnode);
159
160                if(flag == 0) sendcapmt(status.pipservice, 0, 0);
161                free(patbuf);
162        }
163
164        if(flag != 0) checkpmt = 1;
165
166        //demux video start
167        if(chnode->videopid > 0)
168        {
169                if(status.pipservice->dmxvideodev != NULL && status.pipservice->dmxvideodev->fd >= 0 && status.pipservice->dmxvideodev->adapter == fenode->adapter && status.pipservice->dmxvideodev->devnr == fenode->devnr)
170                        dmxvideonode = status.pipservice->dmxvideodev;
171                else
172                {
173                        dmxclose(status.pipservice->dmxvideodev, -1);
174                        dmxvideonode = dmxopen(fenode, 2);
175                        if(dmxsetbuffersize(dmxvideonode, getconfigint("dmxvideobuffersize", NULL)) != 0)
176                        {
177                                dmxclose(dmxvideonode, -1);
178                                dmxvideonode = NULL;
179                        }
180                        status.pipservice->dmxvideodev = dmxvideonode;
181                }
182                if(dmxvideonode != NULL)
183                {
184                        if(dmxsetsource(dmxvideonode, fenode->fedmxsource) != 0)
185                        {
186                                dmxclose(dmxvideonode, -1);
187                                dmxvideonode = NULL;
188                        }
189                        if(dmxsetpesfilter(dmxvideonode, chnode->videopid, -1, DMX_OUT_DECODER, DMX_PES_VIDEO1, 0) != 0)
190                        {
191                                dmxclose(dmxvideonode, -1);
192                                dmxvideonode = NULL;
193                        }
194                }
195                else
196                        err("demux video dev not ok");
197        }
198        else
199        {
200                err("dmx videopid not valid (%d)", chnode->videopid);
201                dmxclose(status.pipservice->dmxvideodev, -1);
202        }
203
204        status.pipservice->dmxvideodev = dmxvideonode;
205
206        //video start
207        if(dmxvideonode != NULL)
208        {
209                if(status.pipservice->videodev != NULL && status.pipservice->videodev->fd >= 0 && status.pipservice->videodev->adapter == fenode->adapter)
210                        videonode = status.pipservice->videodev;
211                else
212                {
213                        videoclose(status.pipservice->videodev, -1);
214                        videonode = videoopen(fenode->adapter, 1);
215                        status.pipservice->videodev = videonode;
216                }
217                if(videonode != NULL)
218                {
219                        videoselectsource(videonode, VIDEO_SOURCE_DEMUX);
220                        if(chnode->videocodec == VC1)
221                        {
222                                videosetstreamtype(videonode, 1); //transportstream
223                                videosetencoding(videonode, chnode->videocodec);
224                        }
225                        else
226                                videosetstreamtype(videonode, chnode->videocodec);
227                        videoplay(videonode);
228                }
229                else
230                        err("can't get free video dev");
231        }
232
233        //check pmt if not done
234        if(checkpmt == 0)
235        {
236                //wait for tuner lock
237                if(flag == 0)
238                {
239                        if(fenode->felasttransponder != tpnode)
240                                festatus = fewait(fenode);
241                        else
242                                festatus = fegetunlock(fenode);
243
244                        if(debug_level == 200)
245                        {
246                                fereadstatus(fenode);
247                                fegetfrontend(fenode);
248                        }
249                        if(festatus != 0)
250                        {
251                                m_unlock(&status.servicemutex, 2);
252                                return 2;
253                        }
254                }
255                checkpmt = 1;
256                patbuf = dvbgetpat(fenode, -1);
257                if(patbuf == NULL) status.secondzap = 3;
258                free(status.pipservice->pmtbuf);
259                status.pipservice->pmtbuf = NULL;
260                status.pipservice->pmtlen = 0;
261                if(patbuf != NULL)
262                        status.pipservice->pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, &status.pipservice->pmtlen, -1, 0);
263                else if(chnode->pmtpid > 0)
264                        status.pipservice->pmtbuf = dvbgetpmt(fenode, NULL, chnode->serviceid, &chnode->pmtpid, &status.pipservice->pmtlen, -1, 1);
265
266                if(status.pipservice->pmtbuf == NULL) status.secondzap = 4;
267                if(dvbgetinfo(status.pipservice->pmtbuf, chnode) == 1)
268                {
269                        //audio or video pid or codec changed
270                        free(status.pipservice->pmtbuf);
271                        status.pipservice->pmtbuf = NULL;
272                        status.pipservice->pmtlen = 0;
273                }
274
275                if(flag == 0) sendcapmt(status.pipservice, 0, 0);
276                free(patbuf);
277        }
278        if(flag == 0)
279        {
280                festatus = fewait(fenode);
281                if(festatus != 0)
282                {
283                        m_unlock(&status.servicemutex, 2);
284                        return 2;
285                }
286        }
287        m_unlock(&status.servicemutex, 2);
288        return 0;
289}
290
291int setvmpeg2(struct dvbdev* node, int value, int flag)
292{
293        debug(4440, "in");
294        char* vmpegdev = NULL, *tmpstr = NULL, *buf = NULL;
295        int ret = 0;
296
297        if(getconfig("vmpegleftdev", NULL) == NULL)
298        {
299                addconfig("vmpegleftdev", "/proc/stb/vmpeg/%d/dst_left");
300                addconfig("vmpegtopdev", "/proc/stb/vmpeg/%d/dst_top");
301                addconfig("vmpegwidthdev", "/proc/stb/vmpeg/%d/dst_width");
302                addconfig("vmpegheightdev", "/proc/stb/vmpeg/%d/dst_height");
303                addconfig("vmpegapplydev", "/proc/stb/vmpeg/%d/dst_apply");
304        }
305       
306        if(node == NULL) return 1;
307        if(flag == 0)  vmpegdev = getconfig("vmpegleftdev", NULL);
308        if(flag == 1)  vmpegdev = getconfig("vmpegtopdev", NULL);
309        if(flag == 2)  vmpegdev = getconfig("vmpegwidthdev", NULL);
310        if(flag == 3)  vmpegdev = getconfig("vmpegheightdev", NULL);
311        if(flag == 99) vmpegdev = getconfig("vmpegapplydev", NULL);
312
313        if(vmpegdev != NULL)
314        {
315                buf = malloc(MINMALLOC);
316                if(buf == NULL)
317                {
318                        err("no mem");
319                        return 1;
320                }
321               
322                tmpstr = malloc(10);
323                if(tmpstr == NULL)
324                {
325                        err("no mem");
326                        free(buf);
327                        return 1;
328                }
329               
330                snprintf(buf, MINMALLOC, vmpegdev, node->devnr);
331                snprintf(tmpstr, 10, "%x", value);
332                debug(444, "set %s to %s", buf, tmpstr);
333                status.tvpic = 1;
334                ret = writesys(buf, tmpstr, 1);
335               
336                free(tmpstr);
337                free(buf);
338                return ret;
339        }
340
341        debug(4440, "out");
342        return 0;
343}
344
345// flag = 0 --> nicht aktivieren
346// flag = 1 --> aktiviere Einstellungen
347int pippos(struct dvbdev* node, int dst_width, int dst_height, int dst_left, int dst_top, int flag)
348{
349        int ret = 0;
350       
351        if(node == NULL) return 1;
352       
353        ret = setvmpeg2(node, dst_left, 0);
354        ret = setvmpeg2(node, dst_top, 1);
355        ret = setvmpeg2(node, dst_width, 2);
356        ret = setvmpeg2(node, dst_height, 3);
357       
358        if(flag == 1) ret = setvmpeg2(node, 0, 99);
359       
360        return ret;
361}
362
363
364//second zap on failure
365//TODO: use flag 6 (same as 5 but no pin question on second tune)
366int pipstart(struct channel* chnode, char* pin, int flag)
367{
368        int ret = 0;
369
370        int dst_width = getconfigint("pip_dst_width", NULL);
371        int dst_height = getconfigint("pip_dst_height", NULL);
372        int dst_left = getconfigint("pip_dst_left", NULL);
373        int dst_top = getconfigint("pip_dst_top", NULL);
374
375        if(dst_width == 0) dst_width = 180;
376        if(dst_height == 0) dst_height = 144;
377        if(dst_left == 0) dst_left = 505;
378        if(dst_top == 0) dst_top = 36;
379
380        if(status.pipservice->type == CHANNEL)
381                pipstop(status.pipservice, 1);
382       
383        ret = pipstartreal(chnode, pin, flag);
384       
385        if(status.secondzap != 0 && ret == 0 && (flag == 0 || flag > 2))
386        {
387                debug(200, "first zap not ok, make second zap (%d)", status.secondzap);
388                ret = pipstartreal(chnode, pin, 5);
389        }
390
391        if(ret == 0)
392        {
393                status.pipservice->fedev->felock++;
394                deltranspondertunablestatus();
395                ret = pippos(status.pipservice->videodev, dst_width, dst_height, dst_left, dst_top, 1);
396                status.pipzap = getconfigint("pip_zap", NULL);
397        }
398
399        return ret;
400}
401
402int pipstop(struct service *node, int flag)
403{
404
405        if(node != NULL)
406        {
407                if(node->dmxvideodev != NULL)
408                {
409                        node->fedev->felock--;
410                        deltranspondertunablestatus();
411                        if(node->type != NOTHING && node->type != STILLPIC) caservicedel(node, NULL);
412                }
413
414                node->type = NOTHING;
415
416                videostop(node->videodev, 1);
417                videoclose(node->videodev, -1);
418               
419                if(flag == 0 && checkbox("DM900") != 1 && checkbox("DM920") != 1)
420                        pippos(node->videodev, 0, 0, 0, 0, 1);
421               
422                node->videodev = NULL;
423               
424                if(node->dmxvideodev != NULL)
425                {
426                        dmxstop(node->dmxvideodev);
427                        dmxclose(node->dmxvideodev, -1);
428                        node->dmxvideodev = NULL;
429                }
430                status.pipzap = 0;             
431                return 0;
432        }
433        return 1;
434}
435
436int piphdmi(struct service *node, int flag)
437{
438        struct dvbdev *videonode = NULL;
439       
440        if(node != NULL && node->type != NOTHING && node->type != HDMIIN)
441                pipstop(status.pipservice, 1);
442       
443        videonode = videoopen(0, 1);
444        node->videodev = videonode;
445        node->type = HDMIIN;
446       
447        if(videonode != NULL)
448        {
449                videoselectsource(videonode, VIDEO_SOURCE_HDMI);
450                videosetstreamtype(videonode, 0);
451                videoplay(videonode);
452        }
453        status.pipzap = 0;
454       
455        return 0;
456}
457
458int pipswap(struct service *node)
459{
460        int hdmi = 0;
461        char* tmpstr = NULL;
462        struct channel* chnodeP = node->channel;
463        struct channel* chnodeT = status.aktservice->channel;
464        if(node->type == CHANNEL && chnodeP != NULL && chnodeP != chnodeT)
465        {
466                if(status.aktservice->type == HDMIIN)
467                {
468                        hdmi = 1;
469                        pipstop(node, 1);
470                }
471                else
472                        pipstop(node, 0);
473                tmpstr = ostrcat(node->channellist, NULL, 0, 0);
474                servicecheckret(servicestart(chnodeP, tmpstr, NULL, 0), 0);
475                free(tmpstr); tmpstr = NULL;
476                if(hdmi == 1)
477                {
478                        piphdmi(node, 0);
479                        free(node->channellist);
480                        node->channellist = NULL;
481                        node->channellist = ostrcat(status.lastservice->channellist, NULL, 0, 0);
482                }
483                else
484                {
485                        status.aktservice->fedev->felock++;
486                        pipstart(chnodeT, NULL, 0);
487                        status.aktservice->fedev->felock--;
488                        free(node->channellist);
489                        node->channellist = NULL;
490                        node->channellist = ostrcat(status.lastservice->channellist, NULL, 0, 0);
491                }
492        }
493#ifdef MIPSEL
494        else if(node->type == HDMIIN)
495        {
496                pipstop(node, 0);
497                servicestop(status.aktservice, 1, 1);
498                servicefullHDMIin_start();
499                pipstart(chnodeT, NULL, 0);
500                free(node->channellist);
501                node->channellist = ostrcat(status.lastservice->channellist, NULL, 0, 0);
502        }
503#endif
504        else
505        {
506                return 1;
507        }
508        return 0;
509}
510       
511       
512
513void pipmenu()
514{
515        struct skin* pipscreen = getscreen("pipscreen");
516        struct skin* hdmi = getscreennode(pipscreen, "hdmi");
517        struct skin* b3 = getscreennode(pipscreen, "b3");
518        int rcret = 0;
519       
520        int dst_width = getconfigint("pip_dst_width", NULL);
521        int dst_height = getconfigint("pip_dst_height", NULL);
522        int dst_left = getconfigint("pip_dst_left", NULL);
523        int dst_top = getconfigint("pip_dst_top", NULL);
524
525        if(checkbox("DM900") == 1 || checkbox("DM920") == 1 || checkbox("DM520") == 1 || checkbox("DM525") == 1)
526        {
527                b3->hidden = YES;
528                hdmi->hidden = YES;
529        }
530       
531        if(dst_width == 0)
532        {
533                dst_width = 180;
534                dst_height = 144;
535        }
536        if(dst_height == 0)
537        {
538                dst_width = 180;
539                dst_height = 144;
540        }
541        if(dst_left == 0) dst_left = 505;
542        if(dst_top == 0) dst_top = 36;
543               
544        if(status.aktservice->type == HDMIIN)
545                changetext(hdmi, "no function");
546        else if(status.pipservice->type == HDMIIN)
547                changetext(hdmi, "live TV");
548        else
549                changetext(hdmi, "HDMI-in");
550       
551        while(1)
552        {
553                drawscreen(pipscreen, 0, 0);
554                rcret = waitrc(pipscreen, 0, 0);
555                clearscreen(pipscreen);
556               
557                if(rcret == getrcconfigint("rcexit", NULL))
558                {
559                        pipstop(status.pipservice, 0);
560                        break;
561                }
562                       
563                if(rcret == getrcconfigint("rcok", NULL))
564                {
565                        addconfigint("pip_dst_width", dst_width);
566                        addconfigint("pip_dst_height", dst_height);
567                        addconfigint("pip_dst_left", dst_left);
568                        addconfigint("pip_dst_top", dst_top);
569                        break;
570                }
571                if(checkbox("DM900") != 1 && checkbox("DM920") != 1 && checkbox("DM520") != 1 && checkbox("DM525") != 1)
572                {
573                        if(rcret == getrcconfigint("rcred", NULL))
574                        {
575                                if(status.aktservice->type == HDMIIN)
576                                        continue;
577                                if(status.pipservice->type == HDMIIN)
578                                {
579                                        pipstop(status.pipservice, 1);
580                                        pipstart(status.aktservice->channel, NULL, 0);
581                                        changetext(hdmi, "HDMI-in");
582                                }
583                                else
584                                {
585                                        piphdmi(status.pipservice, 0);
586                                        changetext(hdmi, "live TV");
587                                }
588                                continue;
589                        }
590                }
591               
592                if(rcret == getrcconfigint("rcblue", NULL))
593                {
594                        pipswap(status.pipservice);
595                        if(status.aktservice->type == HDMIIN)
596                                changetext(hdmi, "no function");
597                        else if(status.pipservice->type != HDMIIN)
598                                changetext(hdmi, "HDMI-in");
599                        else
600                                changetext(hdmi, "live TV");
601                        continue;
602                }
603                       
604                if(rcret == getrcconfigint("rcdown", NULL))
605                {
606                        if(dst_top+1 < 576-dst_height) dst_top++;
607                }
608                if(rcret == getrcconfigint("rcup", NULL))
609                {
610                        if(dst_top-1 > 0) dst_top--;
611                }
612                if(rcret == getrcconfigint("rcleft", NULL))
613                {
614                        if(dst_left-1 > 0) dst_left--;
615                }
616                if(rcret == getrcconfigint("rcright", NULL))
617                {
618                        if(dst_left+1 < 720-dst_width) dst_left++;
619                }
620               
621                if(rcret == getrcconfigint("rcchdown", NULL))
622                {
623                        if(dst_width-4 > 10)
624                        {
625                                dst_width = dst_width - 4;
626                                dst_height = 576 * dst_width / 720;
627                        }
628                }
629                if(rcret == getrcconfigint("rcchup", NULL))
630                {
631                        if(dst_width+4 < 720)
632                        {
633                                dst_width = dst_width + 4;
634                                dst_height = 576 * dst_width / 720;
635                               
636                                if(dst_width + dst_left > 720)
637                                        dst_left = 720 - dst_width;
638                                       
639                                if(dst_height + dst_top > 576)
640                                        dst_top = 576 - dst_height;
641                        }
642                }
643                pippos(status.pipservice->videodev, dst_width, dst_height, dst_left, dst_top, 1);
644        }
645}
646       
647void pipsetup()
648{
649        struct skin* pipmenu = getscreen("pipsetup");
650        struct skin* kchupdown = getscreennode(pipmenu, "pipzap");
651        struct skin* kpip = getscreennode(pipmenu, "pip");
652        struct skin* k0 = getscreennode(pipmenu, "null");
653       
654        struct skin* listbox = getscreennode(pipmenu, "listbox");
655        struct skin* tmp = NULL;
656
657        int rcret = 0;
658       
659        addchoicebox(k0, "0", _("default"));
660        addchoicebox(k0, "1", _("->swap<-"));
661        setchoiceboxselection(k0, getconfig("pip_swap", NULL));
662       
663        addchoicebox(kpip, "0", _("pip menu"));
664        addchoicebox(kpip, "1", _("pip end"));
665        setchoiceboxselection(kpip, getconfig("pip_screen", NULL));
666       
667        addchoicebox(kchupdown, "0", _("default"));
668        addchoicebox(kchupdown, "1", _("pip zap"));
669        setchoiceboxselection(kchupdown, getconfig("pip_zap", NULL));
670       
671        drawscreen(pipmenu, 0, 0);
672        addscreenrc(pipmenu, listbox);
673        tmp = listbox->select;
674       
675        while(1)
676        {
677                addscreenrc(pipmenu, tmp);
678                rcret = waitrc(pipmenu, 0, 0);
679                tmp = listbox->select;
680               
681                if(rcret == getrcconfigint("rcexit", NULL))
682                        break;
683                if(rcret == getrcconfigint("rcok", NULL))       
684                {
685                        addconfig("pip_swap", k0->ret);
686                        addconfig("pip_screen", kpip->ret);
687                        addconfig("pip_zap", kchupdown->ret);
688                        break;
689                }
690                drawscreen(pipmenu, 0, 0);
691        }
692        delownerrc(pipmenu);
693        clearscreen(pipmenu);
694}
695
696
697#endif
Note: See TracBrowser for help on using the repository browser.