source: titan/titan/service.h @ 25697

Last change on this file since 25697 was 25697, checked in by gost, 10 years ago

next knack test

File size: 23.5 KB
Line 
1#ifndef SERVICE_H
2#define SERVICE_H
3
4void debugservice()
5{
6        struct service* node = service;
7        int count = 0;
8
9        while(node != NULL)
10        {
11                printf("Service %d\n", count);
12                count++;
13
14                if(node->channel != NULL) printf("%s (%llu)\n", node->channel->name, node->channel->transponderid);
15                if(node->transponder != NULL) printf("TransponderID %llu\n", node->transponder->id);
16                if(node->fedev != NULL) printf("%s (%d)\n", node->fedev->dev, node->fedev->fd);
17                if(node->dmxaudiodev != NULL) printf("%s (%d)\n", node->dmxaudiodev->dev, node->dmxaudiodev->fd);
18                if(node->dmxvideodev != NULL) printf("%s (%d)\n", node->dmxvideodev->dev, node->dmxvideodev->fd);
19                if(node->dmxpcrdev != NULL) printf("%s (%d)\n", node->dmxpcrdev->dev, node->dmxpcrdev->fd);
20                if(node->audiodev != NULL) printf("%s (%d)\n", node->audiodev->dev, node->audiodev->fd);
21                if(node->videodev != NULL) printf("%s (%d)\n", node->videodev->dev, node->videodev->fd);
22                node = node->next;
23        }
24}
25
26void serviceresetchannelinfo(struct channel* chnode)
27{
28        if(chnode == NULL) return;
29
30        freeaudiotrack(chnode);
31        freesubtitle(chnode);
32        freepmt(chnode);
33        freecadesc(chnode);
34        freeesinfo(chnode);
35        chnode->txtpid = 0;
36        chnode->pmtpid = 0;
37        chnode->crypt = 0;
38}
39
40void akttolast()
41{
42        if(status.aktservice->fedev != NULL && status.aktservice->fedev->type == FRONTENDDEVDUMMY) return;
43        status.lastservice->fedev = status.aktservice->fedev;
44        status.lastservice->dmxaudiodev = status.aktservice->dmxaudiodev;
45        status.lastservice->dmxvideodev = status.aktservice->dmxvideodev;
46        status.lastservice->dmxpcrdev = status.aktservice->dmxpcrdev;
47        status.lastservice->dmxsubtitledev = status.aktservice->dmxsubtitledev;
48        status.lastservice->audiodev = status.aktservice->audiodev;
49        status.lastservice->videodev = status.aktservice->videodev;
50        status.lastservice->transponder = status.aktservice->transponder;
51        status.lastservice->channel = status.aktservice->channel;
52        free(status.lastservice->channellist);
53        status.lastservice->channellist = ostrcat(status.aktservice->channellist, NULL, 0, 0);
54}
55
56//flag 0: channel
57//flag 1: playback
58//flag 2: timeshift
59//flag 3: same as 0 but don't check chnode
60//flag 4: same as 0 but new tuning
61//flag 5: same as 3 but new tuning
62//flag 6: same as 5 but second zap
63int servicestartreal(struct channel* chnode, char* channellist, char* pin, int flag)
64{
65        struct transponder* tpnode = NULL;
66        struct dvbdev *fenode = NULL;
67        struct dvbdev *dmxaudionode = NULL;
68        struct dvbdev *dmxvideonode = NULL;
69        struct dvbdev *dmxpcrnode = NULL;
70        struct dvbdev *audionode = NULL;
71        struct dvbdev *videonode = NULL;
72        int ret = 0, festatus = 1, tmpmute = 0, i = 0;
73        unsigned char *patbuf = NULL;
74        int checkpmt = 0, pincheck = 0, stopflag = 0, ageprotect = 0, tune = 0, secondzap = 0;
75        struct epg* epgnode = NULL;
76
77        m_lock(&status.servicemutex, 2);
78
79        status.secondzap = 0;
80
81        if(flag == 4 || flag == 5 || flag == 6) tune = 1;
82        if(flag == 6) secondzap = 1;
83        if(flag == 4) flag = 0;
84
85        if(flag == 0 && status.aktservice->type == CHANNEL && status.aktservice->channel != NULL && chnode == status.aktservice->channel)
86        {
87                m_unlock(&status.servicemutex, 2);
88                return 20;
89        }
90        if(flag == 3 || flag == 5 || flag == 6) flag = 0;
91
92        if(chnode == NULL)
93        {
94                m_unlock(&status.servicemutex, 2);
95                return 21;
96        }
97       
98        //stop running autoresolution
99        if(status.restimer != NULL)
100                status.restimer->aktion = STOP;
101
102        if(secondzap == 0)
103        {
104                ageprotect = getconfigint("ageprotect", NULL);
105                if(ageprotect > 0) epgnode = getepgakt(chnode);
106                if(chnode->protect > 0 || (epgnode != NULL && epgnode->parentalrating >= ageprotect))
107                {
108                        pincheck = screenpincheck(1, pin);
109                        if(pincheck == 1)
110                        {
111                                m_unlock(&status.servicemutex, 2);
112                                return 22;
113                        }
114                }
115        }
116
117        //got transponder
118        if(flag == 0)
119        {
120                if(chnode->transponder == NULL)
121                        tpnode = gettransponder(chnode->transponderid);
122                else
123                        tpnode = chnode->transponder;
124        }
125
126        if(flag == 1 || flag == 2)
127                stopflag = 2;
128        else if(secondzap == 1)
129                stopflag = 3;
130        if(getconfigint("nozapclear", NULL) == 1)
131                ret = servicestop(status.aktservice, 0, stopflag);
132        else
133                ret = servicestop(status.aktservice, 1, stopflag);
134
135        //can't stop service (timeshift ??)
136        if(ret == 1)
137        {
138                m_unlock(&status.servicemutex, 2);
139                return 22;
140        }
141       
142        //reset channel info
143        if(flag == 0) serviceresetchannelinfo(chnode);
144
145        status.aktservice->transponder = tpnode;
146        status.aktservice->channel = chnode;
147        status.aktservice->type = CHANNEL;
148        if(status.epgthread != NULL) status.epgthread->aktion = PAUSE;
149
150        if(flag == 0 && status.aktservice->type == CHANNEL)
151                changechannellist(chnode, channellist);
152
153        //got frontend dev
154        if(flag == 0)
155        {
156                fenode = fegetfree(tpnode, 0, NULL);
157                if(fenode == NULL)
158                {
159                        m_unlock(&status.servicemutex, 2);
160                        return 1;
161                }
162
163                status.aktservice->fedev = fenode;
164
165                //frontend tune
166                if(fenode->felasttransponder != tpnode || tune == 1)
167                {
168                        if(fenode->feinfo->type == FE_QPSK)
169                        {
170                                feset(fenode, tpnode);
171                                fetunedvbs(fenode, tpnode);
172                        }
173                        else if(fenode->feinfo->type == FE_QAM)
174                                fetunedvbc(fenode, tpnode);
175                        else if(fenode->feinfo->type == FE_OFDM)
176                                fetunedvbt(fenode, tpnode);
177                        else
178                        {
179                                m_unlock(&status.servicemutex, 2);
180                                return 3;
181                        }
182                }
183        }
184        else if(flag == 1 || flag == 2)
185        {
186                fenode = fegetdummy();
187                status.aktservice->fedev = fenode;
188        }
189
190        if(fenode == NULL)
191        {
192                m_unlock(&status.servicemutex, 2);
193                return 1;
194        }
195
196        //check pmt if not all infos in channellist
197        if(chnode->audiopid == -1 || chnode->videopid == -1 || chnode->pcrpid == -1 || chnode->audiocodec == -1 || chnode->videocodec == -1 || (getconfigint("av_ac3default", NULL) == YES && chnode->audiocodec != AC3))
198        {
199                //wait for tuner lock
200                if(flag == 0)
201                {
202                        if(fenode->felasttransponder != tpnode)
203                                festatus = fewait(fenode);
204                        else
205                                festatus = fegetunlock(fenode);
206
207                        if(debug_level == 200) 
208                        {
209                                fereadstatus(fenode);
210                                fegetfrontend(fenode);
211                        }
212                        if(festatus != 0)
213                        {
214                                m_unlock(&status.servicemutex, 2);
215                                return 2;
216                        }
217                }
218
219                checkpmt = 1;
220                if(flag != 1 || (flag == 1 && chnode->pmtpid == 0))
221                {
222                        patbuf = dvbgetpat(fenode, -1);
223                        if(patbuf == NULL) status.secondzap = 1;
224                }
225                free(status.aktservice->pmtbuf);
226                status.aktservice->pmtbuf = NULL;
227                status.aktservice->pmtlen = 0;
228                if(patbuf != NULL)
229                        status.aktservice->pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, &status.aktservice->pmtlen, -1, 0);
230                else if(chnode->pmtpid > 0)
231                        status.aktservice->pmtbuf = dvbgetpmt(fenode, NULL, chnode->serviceid, &chnode->pmtpid, &status.aktservice->pmtlen, -1, 1);
232
233                if(status.aktservice->pmtbuf == NULL) status.secondzap = 2;
234                dvbgetinfo(status.aktservice->pmtbuf, chnode);
235
236                if(flag == 0)
237                {
238                        if(status.pmtmode == 1)
239                        {
240                                if(recordcheckcrypt(fenode, CHANNEL) == 0)
241                                        dvbwritepmt(status.aktservice, status.aktservice->pmtbuf);
242                                else
243                                        debug(200, "don't write pmt.tmp, another crypt channel use this frontend");
244                        }
245                        else
246                                sendcapmt(status.aktservice, 0, 0);
247                }
248                free(patbuf);
249        }
250
251        if(flag != 0) checkpmt = 1;
252
253        //set mute for scat problem
254        if(status.mute == 0)
255        {
256                tmpmute = 1;
257                //setmute(1);
258                audiosetmute(status.aktservice->audiodev, 1);
259        }
260        audiostop(status.aktservice->audiodev);
261        //demux pcr start
262        if(flag == 0 && chnode->pcrpid > 0)
263        {
264                if(status.aktservice->dmxpcrdev != NULL && status.aktservice->dmxpcrdev->fd >= 0 && status.aktservice->dmxpcrdev->adapter == fenode->adapter && status.aktservice->dmxpcrdev->devnr == fenode->devnr)
265                        dmxpcrnode = status.aktservice->dmxpcrdev;
266                else
267                {
268                        dmxclose(status.aktservice->dmxpcrdev, -1);
269                        dmxpcrnode = dmxopen(fenode);
270                }
271                if(dmxpcrnode != NULL)
272                {
273                        if(dmxsetsource(dmxpcrnode, fenode->fedmxsource) != 0)
274                        {
275                                dmxclose(dmxpcrnode, -1);
276                                dmxpcrnode = NULL;
277                        }
278                        if(dmxsetpesfilter(dmxpcrnode, chnode->pcrpid, -1, DMX_OUT_DECODER, DMX_PES_PCR, 0) != 0)
279                        {
280                                dmxclose(dmxpcrnode, -1);
281                                dmxpcrnode = NULL;
282                        }
283                }
284                else
285                        err("demux pcr dev not ok");
286        }
287        else
288        {
289                err("dmx pcrpid not valid (%d)", chnode->pcrpid);
290                dmxclose(status.aktservice->dmxpcrdev, -1);
291        }
292
293        status.aktservice->dmxpcrdev = dmxpcrnode;
294
295        //demux audio start
296        if(chnode->audiopid > 0)
297        {
298                if(status.aktservice->dmxaudiodev != NULL && status.aktservice->dmxaudiodev->fd >= 0 && status.aktservice->dmxaudiodev->adapter == fenode->adapter && status.aktservice->dmxaudiodev->devnr == fenode->devnr)
299                        dmxaudionode = status.aktservice->dmxaudiodev;
300                else
301                {
302                        dmxclose(status.aktservice->dmxaudiodev, -1);
303                        dmxaudionode = dmxopen(fenode);
304                        if(dmxsetbuffersize(dmxaudionode, getconfigint("dmxaudiobuffersize", NULL)) != 0)
305                        {
306                                dmxclose(dmxaudionode, -1);
307                                dmxaudionode = NULL;
308                        }
309                }
310                if(dmxaudionode != NULL)
311                {
312                        if(dmxsetsource(dmxaudionode, fenode->fedmxsource) != 0)
313                        {
314                                dmxclose(dmxaudionode, -1);
315                                dmxaudionode = NULL;
316                        }
317                        if(dmxsetpesfilter(dmxaudionode, chnode->audiopid, -1, DMX_OUT_DECODER, DMX_PES_AUDIO, 0) != 0)
318                        {
319                                dmxclose(dmxaudionode, -1);
320                                dmxaudionode = NULL;
321                        }
322                }
323                else
324                        err("demux audio dev not ok");
325        }
326        else
327        {
328                err("dmx audiopid not valid (%d)", chnode->audiopid);
329                dmxclose(status.aktservice->dmxaudiodev, -1);
330        }
331
332        status.aktservice->dmxaudiodev = dmxaudionode;
333
334        //demux video start
335        if(chnode->videopid > 0)
336        {
337                if(status.aktservice->dmxvideodev != NULL && status.aktservice->dmxvideodev->fd >= 0 && status.aktservice->dmxvideodev->adapter == fenode->adapter && status.aktservice->dmxvideodev->devnr == fenode->devnr)
338                        dmxvideonode = status.aktservice->dmxvideodev;
339                else
340                {
341                        dmxclose(status.aktservice->dmxvideodev, -1);
342                        dmxvideonode = dmxopen(fenode);
343                        if(dmxsetbuffersize(dmxvideonode, getconfigint("dmxvideobuffersize", NULL)) != 0)
344                        {
345                                dmxclose(dmxvideonode, -1);
346                                dmxvideonode = NULL;
347                        }
348                        status.aktservice->dmxvideodev = dmxvideonode;
349                }
350                if(dmxvideonode != NULL)
351                {
352                        if(dmxsetsource(dmxvideonode, fenode->fedmxsource) != 0)
353                        {
354                                dmxclose(dmxvideonode, -1);
355                                dmxvideonode = NULL;
356                        }
357                        if(dmxsetpesfilter(dmxvideonode, chnode->videopid, -1, DMX_OUT_DECODER, DMX_PES_VIDEO, 0) != 0)
358                        {
359                                dmxclose(dmxvideonode, -1);
360                                dmxvideonode = NULL;
361                        }
362                }
363                else
364                        err("demux video dev not ok");
365        }
366        else
367        {
368                err("dmx videopid not valid (%d)", chnode->videopid);
369                dmxclose(status.aktservice->dmxvideodev, -1);
370        }
371
372        status.aktservice->dmxvideodev = dmxvideonode;
373       
374        //workaround for some audio channel not playing (for test)
375        usleep(100000);
376
377        //audio start
378        if(dmxaudionode != NULL)
379        {
380                if(status.aktservice->audiodev != NULL && status.aktservice->audiodev->fd >= 0 && status.aktservice->audiodev->adapter == fenode->adapter)
381                        audionode = status.aktservice->audiodev;
382                else
383                {
384                        audioclose(status.aktservice->audiodev, -1);
385                        audionode = audioopen(fenode->adapter);
386                        status.aktservice->audiodev = audionode;
387                }
388                if(audionode != NULL)
389                {
390                        audioselectsource(audionode, AUDIO_SOURCE_DEMUX);
391                        audiosetbypassmode(audionode, chnode->audiocodec);
392                        audioplay(audionode);
393                }
394                else
395                        err("can't get free audio dev");
396        }
397       
398        //video start
399        if(dmxvideonode != NULL)
400        {
401                if(status.aktservice->videodev != NULL && status.aktservice->videodev->fd >= 0 && status.aktservice->videodev->adapter == fenode->adapter)
402                        videonode = status.aktservice->videodev;
403                else
404                {
405                        videoclose(status.aktservice->videodev, -1);
406                        videonode = videoopen(fenode->adapter, 0);
407                        status.aktservice->videodev = videonode;
408                }
409                if(videonode != NULL)
410                {
411                        videoselectsource(videonode, VIDEO_SOURCE_DEMUX);
412                        setencoding(chnode, videonode);
413                        videoplay(videonode);
414                }
415                else
416                        err("can't get free video dev");
417        }
418
419        //unset mute if set here
420        if(tmpmute == 1)
421        {
422                tmpmute = 0;
423                audiosetmute(status.aktservice->audiodev, 0);
424                //setmute(0);
425        }
426        audioplay(status.aktservice->audiodev);
427       
428        //check pmt if not done
429        if(checkpmt == 0)
430        {
431                //wait for tuner lock
432                if(flag == 0)
433                {
434                        if(fenode->felasttransponder != tpnode)
435                                festatus = fewait(fenode);
436                        else
437                                festatus = fegetunlock(fenode);
438
439                        if(debug_level == 200)
440                        {
441                                fereadstatus(fenode);
442                                fegetfrontend(fenode);
443                        }
444                        if(festatus != 0)
445                        {
446                                m_unlock(&status.servicemutex, 2);
447                                return 2;
448                        }
449                }
450
451                checkpmt = 1;
452                patbuf = dvbgetpat(fenode, -1);
453                if(patbuf == NULL) status.secondzap = 3;
454                free(status.aktservice->pmtbuf);
455                status.aktservice->pmtbuf = NULL;
456                status.aktservice->pmtlen = 0;
457                if(patbuf != NULL)
458                        status.aktservice->pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, &status.aktservice->pmtlen, -1, 0);
459                else if(chnode->pmtpid > 0)
460                        status.aktservice->pmtbuf = dvbgetpmt(fenode, NULL, chnode->serviceid, &chnode->pmtpid, &status.aktservice->pmtlen, -1, 1);
461
462                if(status.aktservice->pmtbuf == NULL) status.secondzap = 4;
463                if(dvbgetinfo(status.aktservice->pmtbuf, chnode) == 1)
464                {
465                        //audio or video pid or codec changed
466                        free(status.aktservice->pmtbuf);
467                        status.aktservice->pmtbuf = NULL;
468                        status.aktservice->pmtlen = -1;
469                }
470
471                if(flag == 0)
472                {
473                        if(status.pmtmode == 1)
474                        {
475                                if(recordcheckcrypt(fenode, CHANNEL) == 0)
476                                        dvbwritepmt(status.aktservice, status.aktservice->pmtbuf);
477                                else
478                                        debug(200, "don't write pmt.tmp, another crypt channel use this frontend");
479                        }
480                        else
481                                sendcapmt(status.aktservice, 0, 0);
482                }
483                free(patbuf);
484        }
485
486        //get ait and parse it for hbbtv url
487        if(flag == 0 && chnode->aitpid > 0)
488        {
489                unsigned char* aitbuf = NULL;
490                aitbuf = dvbgetait(fenode, chnode->aitpid, 0, -1);
491                if(aitbuf != NULL)
492                {
493                        free(chnode->hbbtvurl); chnode->hbbtvurl = NULL;
494                        chnode->hbbtvurl = dvbgethbbtvurl(aitbuf);
495                }
496
497                debug(200, "hbbtvurl=%s", chnode->hbbtvurl);
498                free(aitbuf); aitbuf = NULL;
499        }
500
501        if(flag == 0)
502        {
503                //add channel to history
504                if(status.aktservice->type == CHANNEL)
505                {
506                        addchannelhistory(chnode, status.aktservice->channellist);
507                        if(status.servicetype == 0) //only for tv
508                                createmostzap(chnode->serviceid, chnode->transponderid);
509                }
510                festatus = fewait(fenode);
511                if(festatus != 0)
512                {
513                        m_unlock(&status.servicemutex, 2);
514                        return 2;
515                }
516        }
517
518        //wait for epg thread stops
519        if(flag == 0 && status.epgthread != NULL)
520        {
521                i = 0;
522                while(status.epgthread->status != INPAUSE)
523                {
524                        usleep(10000);
525                        i++; if(i > 300) break;
526                }
527                status.epgthread->aktion = START;
528        }
529
530        status.videosizevalid = time(NULL);
531        m_unlock(&status.servicemutex, 2);
532       
533        //auto change channel name
534        if(flag == 0 && status.autochangechannelname == 1)
535                addtimer(&autochangechannelname, START, 1000, 1, NULL, NULL, NULL);
536       
537        //autoresolution
538        if(flag == 0 && ostrcmp(getconfig("av_videomode_autores", NULL), "auto") == 0)
539        {
540                int sec = 7;
541                char* av_videomode_autores_ts = getconfig("av_videomode_autores_ts", NULL);
542                if(av_videomode_autores_ts != NULL)
543                        sec = atoi(av_videomode_autores_ts);
544                if(status.restimer == NULL)
545                        status.restimer = addtimer(&setaktres, START, 1000, 1, (void*)sec, NULL, NULL);
546                else
547                {
548                        status.restimer->aktion = STOP;
549                        status.restimer = addtimer(&setaktres, START, 1000, 1, (void*)sec, NULL, NULL);
550                }                       
551        }
552       
553        if(flag == 0 && status.autosubtitle == 1) subtitlestartlast(); //start subtitle
554        if(flag == 0 && status.timeshifttype == 1)
555        {
556                i = 0;
557                while(status.timeshift > 0)
558                {
559                        usleep(100000);
560                        i++; if(i > 20) break;
561                }
562                timeshiftpause(); //start permanent timeshift record
563        }
564       
565        return 0;
566}
567
568//second zap on failure
569int servicestart(struct channel* chnode, char* channellist, char* pin, int flag)
570{
571        int ret = 0;
572
573        ret = servicestartreal(chnode, channellist, pin, flag);
574
575        if(status.secondzap != 0 && ret == 0 && (flag == 0 || flag > 2))
576        {
577                debug(200, "first zap not ok, make second zap (%d)", status.secondzap);
578                ret = servicestartreal(chnode, channellist, pin, 6);
579        }
580
581        return ret;
582}
583
584//flag 0: lock
585//flag 1: no lock
586struct service* getservicebyrecname(char* file, int type, int flag)
587{
588        if(file == NULL) return NULL;
589
590        if(flag == 0) m_lock(&status.servicemutex, 2);
591        struct service* snode = service;
592
593        while(snode != NULL)
594        {
595                if(ostrcmp(snode->recname, file) == 0 && (type == 0 || (type == 1 && (snode->type == RECORDDIRECT || snode->type == RECORDTIMER))))
596                {
597                        if(flag == 0) m_unlock(&status.servicemutex, 2);
598                        return snode;
599                }
600                snode = snode->next;
601        }
602        if(flag == 0) m_unlock(&status.servicemutex, 2);
603        return NULL;
604}
605
606struct service* getservicebychannel(struct channel* chnode)
607{
608        m_lock(&status.servicemutex, 2);
609        struct service* snode = service;
610
611        while(snode != NULL)
612        {
613                if(snode->channel == chnode)
614                {
615                        m_unlock(&status.servicemutex, 2);
616                        return snode;
617                }
618                snode = snode->next;
619
620        }
621        m_unlock(&status.servicemutex, 2);
622        return NULL;
623}
624
625//flag 0: lock
626//flag 1: no lock
627struct service* getservicebyrectimestamp(char* timestamp, int flag)
628{
629        if(timestamp == 0) return NULL;
630
631        if(flag == 0) m_lock(&status.servicemutex, 2);
632        struct service* snode = service;
633
634        while(snode != NULL)
635        {
636                if(ostrcmp(snode->rectimestamp, timestamp) == 0)
637                {
638                        if(flag == 0) m_unlock(&status.servicemutex, 2);
639                        return snode;
640                }
641                snode = snode->next;
642        }
643        if(flag == 0) m_unlock(&status.servicemutex, 2);
644        return NULL;
645}
646
647struct service* getservicebyservice(struct service* node, int flag)
648{
649        if(flag == 0) m_lock(&status.servicemutex, 2);
650        struct service* snode = service;
651
652        while(snode != NULL)
653        {
654                if(snode != status.lastservice && snode != node && snode->channel == node->channel)
655                {
656                        if(flag == 0) m_unlock(&status.servicemutex, 2);
657                        return snode;
658                }
659                snode = snode->next;
660        }
661        if(flag == 0) m_unlock(&status.servicemutex, 2);
662        return NULL;
663}
664
665//flag 0: with mutex
666//flag 1: without mutex
667struct service* getservice(int type, int flag)
668{
669        if(flag == 0) m_lock(&status.servicemutex, 2);
670        struct service* snode = service;
671
672        while(snode != NULL)
673        {
674                if(snode->type == type)
675                {
676                        if(flag == 0) m_unlock(&status.servicemutex, 2);
677                        return snode;
678                }
679                snode = snode->next;
680        }
681        if(flag == 0) m_unlock(&status.servicemutex, 2);
682        return NULL;
683}
684
685//flag 0: faststop depends on param faststop
686//flag 1: always normal stop
687//flag 2: from timeshift/player
688//flag 3: same as 0 but no akttolast
689int servicestop(struct service *node, int clear, int flag)
690{
691        int rcret = 0;
692
693        if(node != NULL)
694        {
695                status.tvpic = 0;
696                if(status.timeshift == 1 && flag != 2)
697                {
698                        if(status.timeshifttype == 0 && status.asktimeshift == 0)
699                                rcret = textbox(_("Message"), _("Timeshift is running !!!\nStop it and switch ?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 400, 10, 0);
700
701                        if(rcret == 2) return 1;
702                        timeshiftstop(1);
703                }
704                if(flag != 2 && node->type != NOTHING && node->type != STILLPIC) caservicedel(node, NULL);
705
706                truncate("/tmp/ecm.info", 0);
707                unlink("/tmp/pid.info");
708                unlink("/tmp/caids.info");
709               
710                status.videosizevalid = 0;
711
712                if(status.epgthread != NULL) status.epgthread->aktion = PAUSE;
713                subtitlestop(0);
714
715                if(node->type == CHANNEL && flag < 2) akttolast();
716                if(flag != 2) node->type = NOTHING;
717
718                audiostop(node->audiodev);
719                videostop(node->videodev, clear);
720               
721                int fastzap = getconfigint("fastzap", NULL);
722
723                if(flag == 3) flag = 0;
724                if(flag == 1 || (flag == 0 && (fastzap == 0 || fastzap == 2)))
725                {
726                        audioclose(node->audiodev, -1);
727                        node->audiodev = NULL;
728                        dmxstop(node->dmxaudiodev);
729                        dmxclose(node->dmxaudiodev, -1);
730                        node->dmxaudiodev = NULL;
731                }
732               
733                if(flag == 1 || (flag == 0 && fastzap == 0))
734                {
735                        videoclose(node->videodev, -1);
736                        node->videodev = NULL;
737                        dmxstop(node->dmxvideodev);
738                        dmxclose(node->dmxvideodev, -1);
739                        node->dmxvideodev = NULL;
740                        dmxstop(node->dmxpcrdev);
741                        dmxclose(node->dmxpcrdev, -1);
742                        node->dmxpcrdev = NULL;
743                        dmxstop(node->dmxsubtitledev);
744                        dmxclose(node->dmxsubtitledev, -1);
745                        node->dmxsubtitledev = NULL;
746                }
747                return 0;
748        }
749        return 1;
750}
751
752void servicechangeaudio(struct channel* chnode, struct audiotrack* tracknode)
753{
754        if(chnode == NULL || tracknode == NULL)
755        {
756                err("NULL detect");
757                return;
758        }
759
760        if(chnode->audiopid == tracknode->audiopid && chnode->audiocodec == tracknode->audiocodec)
761                return;
762
763        chnode->audiopid = tracknode->audiopid;
764        chnode->audiocodec = tracknode->audiocodec;
765
766        status.writechannel = 1;
767        audiostop(status.aktservice->audiodev);
768        audiosetbypassmode(status.aktservice->audiodev, chnode->audiocodec);
769        //clear videobuffer on playback for syncing video / audio
770        if(status.playing == 1) videoclearbuffer(status.aktservice->videodev);
771        dmxsetpesfilter(status.aktservice->dmxaudiodev, chnode->audiopid, -1, DMX_OUT_DECODER, DMX_PES_AUDIO, 0);
772
773        //don't start audio play, if we are in timeshift record, but not playing mode
774        if(status.timeshifttype == 0 && status.timeshift == 1 && status.playing == 0) return;
775        if(status.timeshifttype == 1 && status.timeshift == 1 && status.playing == 0 && status.timeshiftpos > 0) return;
776
777        audioplay(status.aktservice->audiodev);
778}
779
780struct service* addservice(struct service* last)
781{
782        struct service *newnode = NULL, *node = NULL;
783
784        newnode = (struct service*)calloc(1, sizeof(struct service));
785        if(newnode == NULL)
786        {
787                err("no memory");
788                return NULL;
789        }
790
791        newnode->recdstfd = -1;
792        newnode->recsrcfd = -1;
793        newnode->tssize = 188;
794
795        m_lock(&status.servicemutex, 2);
796        node = service;
797        if(node != NULL)
798        {
799                if(last == NULL)
800                {
801                        while(node->next != NULL)
802                                node = node->next;
803                        node->next = newnode;
804                }
805                else
806                        last->next = newnode;
807        }
808        else
809                service = newnode;
810
811        m_unlock(&status.servicemutex, 2);
812        return newnode;
813}
814
815struct service* checkservice(struct service* node)
816{
817        struct service* snode = service;
818
819        while(snode != NULL)
820        {
821                if(snode == node)
822                        return snode;
823                snode = snode->next;
824        }
825        return NULL;
826}
827
828//flag 0: set mutex
829//flag 1: not set mutex
830void delservice(struct service* snode, int flag)
831{
832        m_lock(&status.servicemutex, 2);
833        struct service *node = service, *prev = service;
834        struct rectimer *rectimernode = NULL;
835
836        while(node != NULL)
837        {
838                if(node == snode)
839                {
840                        if(node == service)
841                                service = node->next;
842                        else
843                                prev->next = node->next;
844
845                        dmxclose(node->dmxaudiodev, -1);
846                        dmxclose(node->dmxvideodev, -1);
847                        dmxclose(node->dmxpcrdev, -1);
848                        dmxclose(node->dmxsubtitledev, -1);
849                        audioclose(node->audiodev, -1);
850                        videoclose(node->videodev, -1);
851                        close(node->recdstfd);
852                        close(node->recsrcfd);
853                        caservicedel(node, NULL);
854
855                        //check if a rectimer is joined with a service
856                        if(node->type == RECORDTIMER)
857                        {
858                                if(flag == 0)
859                                        m_lock(&status.rectimermutex, 1);
860
861                                rectimernode = getrectimerbyservice(node);
862                                if(rectimernode != NULL)
863                                {
864                                        rectimernode->servicenode = NULL;
865                                        if(rectimernode->status == 0 || rectimernode->status == 1)
866                                        {
867                                                rectimernode->status = 2;
868                                                status.writerectimer = 1;
869                                                writerectimer(getconfig("rectimerfile", NULL), 1);
870                                        }
871                                }
872
873                                if(flag == 0)
874                                        m_unlock(&status.rectimermutex, 1);
875                        }
876
877                        free(node->channellist);
878                        node->channellist = NULL;
879
880                        free(node->recname);
881                        node->recname = NULL;
882
883                        free(node->rectimestamp);
884                        node->rectimestamp = NULL;
885
886                        free(node->pmtbuf);
887                        node->pmtbuf = NULL;
888
889                        free(node);
890                        node = NULL;
891                        break;
892                }
893
894                prev = node;
895                node = node->next;
896        }
897        m_unlock(&status.servicemutex, 2);
898}
899
900void freeservice()
901{
902        struct service *node = service, *prev = service;
903
904        while(node != NULL)
905        {
906                prev = node;
907                node = node->next;
908                if(prev != NULL)
909                        delservice(prev, 0);
910        }
911}
912
913char* servicecheckret(int ret, int flag)
914{
915        char* tmpstr = NULL;
916
917        if(ret != 0)
918        {
919                switch(ret)
920                {
921                        case 1:
922                                tmpstr = ostrcat(_("Can't find a Tuner.\nAll Tuners in use or no Tuner defined."), NULL, 0, 0);
923                                break;
924                        case 2:
925                                tmpstr = ostrcat(_("Tuning to Channel failed!"), NULL, 0, 0);
926                                break;
927                        case 3:
928                                tmpstr = ostrcat(_("Can't open frontend dev or Frontend Type unknown!"), NULL, 0, 0);
929                                break;
930                        case 20:
931                                break;
932                        case 21:
933                                tmpstr = ostrcat(_("Channellist empty or corrupt (channel not found)!"), NULL, 0, 0);
934                                break;
935                        case 22:
936                                break;
937                }
938                if(tmpstr != NULL)
939                        textbox(_("Message"), tmpstr, _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 10, 0);
940        }
941
942        if(flag != 1)
943        {
944                free(tmpstr);
945                tmpstr = NULL;
946        }
947
948        return tmpstr;
949}
950
951#endif
Note: See TracBrowser for help on using the repository browser.