source: titan/titan/service.h @ 25775

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

[titan] hold digital mute on zap

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                        if(status.mute <> 1)
393                                audioplay(audionode);
394                }
395                else
396                        err("can't get free audio dev");
397        }
398       
399        //video start
400        if(dmxvideonode != NULL)
401        {
402                if(status.aktservice->videodev != NULL && status.aktservice->videodev->fd >= 0 && status.aktservice->videodev->adapter == fenode->adapter)
403                        videonode = status.aktservice->videodev;
404                else
405                {
406                        videoclose(status.aktservice->videodev, -1);
407                        videonode = videoopen(fenode->adapter, 0);
408                        status.aktservice->videodev = videonode;
409                }
410                if(videonode != NULL)
411                {
412                        videoselectsource(videonode, VIDEO_SOURCE_DEMUX);
413                        setencoding(chnode, videonode);
414                        videoplay(videonode);
415                }
416                else
417                        err("can't get free video dev");
418        }
419
420        //unset mute if set here
421        if(tmpmute == 1)
422        {
423                tmpmute = 0;
424                audiosetmute(status.aktservice->audiodev, 0);
425                //setmute(0);
426        }
427        if(status.mute <> 1)
428                audioplay(status.aktservice->audiodev);
429       
430        //check pmt if not done
431        if(checkpmt == 0)
432        {
433                //wait for tuner lock
434                if(flag == 0)
435                {
436                        if(fenode->felasttransponder != tpnode)
437                                festatus = fewait(fenode);
438                        else
439                                festatus = fegetunlock(fenode);
440
441                        if(debug_level == 200)
442                        {
443                                fereadstatus(fenode);
444                                fegetfrontend(fenode);
445                        }
446                        if(festatus != 0)
447                        {
448                                m_unlock(&status.servicemutex, 2);
449                                return 2;
450                        }
451                }
452
453                checkpmt = 1;
454                patbuf = dvbgetpat(fenode, -1);
455                if(patbuf == NULL) status.secondzap = 3;
456                free(status.aktservice->pmtbuf);
457                status.aktservice->pmtbuf = NULL;
458                status.aktservice->pmtlen = 0;
459                if(patbuf != NULL)
460                        status.aktservice->pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, &status.aktservice->pmtlen, -1, 0);
461                else if(chnode->pmtpid > 0)
462                        status.aktservice->pmtbuf = dvbgetpmt(fenode, NULL, chnode->serviceid, &chnode->pmtpid, &status.aktservice->pmtlen, -1, 1);
463
464                if(status.aktservice->pmtbuf == NULL) status.secondzap = 4;
465                if(dvbgetinfo(status.aktservice->pmtbuf, chnode) == 1)
466                {
467                        //audio or video pid or codec changed
468                        free(status.aktservice->pmtbuf);
469                        status.aktservice->pmtbuf = NULL;
470                        status.aktservice->pmtlen = -1;
471                }
472
473                if(flag == 0)
474                {
475                        if(status.pmtmode == 1)
476                        {
477                                if(recordcheckcrypt(fenode, CHANNEL) == 0)
478                                        dvbwritepmt(status.aktservice, status.aktservice->pmtbuf);
479                                else
480                                        debug(200, "don't write pmt.tmp, another crypt channel use this frontend");
481                        }
482                        else
483                                sendcapmt(status.aktservice, 0, 0);
484                }
485                free(patbuf);
486        }
487
488        //get ait and parse it for hbbtv url
489        if(flag == 0 && chnode->aitpid > 0)
490        {
491                unsigned char* aitbuf = NULL;
492                aitbuf = dvbgetait(fenode, chnode->aitpid, 0, -1);
493                if(aitbuf != NULL)
494                {
495                        free(chnode->hbbtvurl); chnode->hbbtvurl = NULL;
496                        chnode->hbbtvurl = dvbgethbbtvurl(aitbuf);
497                }
498
499                debug(200, "hbbtvurl=%s", chnode->hbbtvurl);
500                free(aitbuf); aitbuf = NULL;
501        }
502
503        if(flag == 0)
504        {
505                //add channel to history
506                if(status.aktservice->type == CHANNEL)
507                {
508                        addchannelhistory(chnode, status.aktservice->channellist);
509                        if(status.servicetype == 0) //only for tv
510                                createmostzap(chnode->serviceid, chnode->transponderid);
511                }
512                festatus = fewait(fenode);
513                if(festatus != 0)
514                {
515                        m_unlock(&status.servicemutex, 2);
516                        return 2;
517                }
518        }
519
520        //wait for epg thread stops
521        if(flag == 0 && status.epgthread != NULL)
522        {
523                i = 0;
524                while(status.epgthread->status != INPAUSE)
525                {
526                        usleep(10000);
527                        i++; if(i > 300) break;
528                }
529                status.epgthread->aktion = START;
530        }
531
532        status.videosizevalid = time(NULL);
533        m_unlock(&status.servicemutex, 2);
534       
535        //auto change channel name
536        if(flag == 0 && status.autochangechannelname == 1)
537                addtimer(&autochangechannelname, START, 1000, 1, NULL, NULL, NULL);
538       
539        //autoresolution
540        if(flag == 0 && ostrcmp(getconfig("av_videomode_autores", NULL), "auto") == 0)
541        {
542                int sec = 7;
543                char* av_videomode_autores_ts = getconfig("av_videomode_autores_ts", NULL);
544                if(av_videomode_autores_ts != NULL)
545                        sec = atoi(av_videomode_autores_ts);
546                if(status.restimer == NULL)
547                        status.restimer = addtimer(&setaktres, START, 1000, 1, (void*)sec, NULL, NULL);
548                else
549                {
550                        status.restimer->aktion = STOP;
551                        status.restimer = addtimer(&setaktres, START, 1000, 1, (void*)sec, NULL, NULL);
552                }                       
553        }
554       
555        if(flag == 0 && status.autosubtitle == 1) subtitlestartlast(); //start subtitle
556        if(flag == 0 && status.timeshifttype == 1)
557        {
558                i = 0;
559                while(status.timeshift > 0)
560                {
561                        usleep(100000);
562                        i++; if(i > 20) break;
563                }
564                timeshiftpause(); //start permanent timeshift record
565        }
566       
567        return 0;
568}
569
570//second zap on failure
571int servicestart(struct channel* chnode, char* channellist, char* pin, int flag)
572{
573        int ret = 0;
574
575        ret = servicestartreal(chnode, channellist, pin, flag);
576
577        if(status.secondzap != 0 && ret == 0 && (flag == 0 || flag > 2))
578        {
579                debug(200, "first zap not ok, make second zap (%d)", status.secondzap);
580                ret = servicestartreal(chnode, channellist, pin, 6);
581        }
582
583        return ret;
584}
585
586//flag 0: lock
587//flag 1: no lock
588struct service* getservicebyrecname(char* file, int type, int flag)
589{
590        if(file == NULL) return NULL;
591
592        if(flag == 0) m_lock(&status.servicemutex, 2);
593        struct service* snode = service;
594
595        while(snode != NULL)
596        {
597                if(ostrcmp(snode->recname, file) == 0 && (type == 0 || (type == 1 && (snode->type == RECORDDIRECT || snode->type == RECORDTIMER))))
598                {
599                        if(flag == 0) m_unlock(&status.servicemutex, 2);
600                        return snode;
601                }
602                snode = snode->next;
603        }
604        if(flag == 0) m_unlock(&status.servicemutex, 2);
605        return NULL;
606}
607
608struct service* getservicebychannel(struct channel* chnode)
609{
610        m_lock(&status.servicemutex, 2);
611        struct service* snode = service;
612
613        while(snode != NULL)
614        {
615                if(snode->channel == chnode)
616                {
617                        m_unlock(&status.servicemutex, 2);
618                        return snode;
619                }
620                snode = snode->next;
621
622        }
623        m_unlock(&status.servicemutex, 2);
624        return NULL;
625}
626
627//flag 0: lock
628//flag 1: no lock
629struct service* getservicebyrectimestamp(char* timestamp, int flag)
630{
631        if(timestamp == 0) return NULL;
632
633        if(flag == 0) m_lock(&status.servicemutex, 2);
634        struct service* snode = service;
635
636        while(snode != NULL)
637        {
638                if(ostrcmp(snode->rectimestamp, timestamp) == 0)
639                {
640                        if(flag == 0) m_unlock(&status.servicemutex, 2);
641                        return snode;
642                }
643                snode = snode->next;
644        }
645        if(flag == 0) m_unlock(&status.servicemutex, 2);
646        return NULL;
647}
648
649struct service* getservicebyservice(struct service* node, int flag)
650{
651        if(flag == 0) m_lock(&status.servicemutex, 2);
652        struct service* snode = service;
653
654        while(snode != NULL)
655        {
656                if(snode != status.lastservice && snode != node && snode->channel == node->channel)
657                {
658                        if(flag == 0) m_unlock(&status.servicemutex, 2);
659                        return snode;
660                }
661                snode = snode->next;
662        }
663        if(flag == 0) m_unlock(&status.servicemutex, 2);
664        return NULL;
665}
666
667//flag 0: with mutex
668//flag 1: without mutex
669struct service* getservice(int type, int flag)
670{
671        if(flag == 0) m_lock(&status.servicemutex, 2);
672        struct service* snode = service;
673
674        while(snode != NULL)
675        {
676                if(snode->type == type)
677                {
678                        if(flag == 0) m_unlock(&status.servicemutex, 2);
679                        return snode;
680                }
681                snode = snode->next;
682        }
683        if(flag == 0) m_unlock(&status.servicemutex, 2);
684        return NULL;
685}
686
687//flag 0: faststop depends on param faststop
688//flag 1: always normal stop
689//flag 2: from timeshift/player
690//flag 3: same as 0 but no akttolast
691int servicestop(struct service *node, int clear, int flag)
692{
693        int rcret = 0;
694
695        if(node != NULL)
696        {
697                status.tvpic = 0;
698                if(status.timeshift == 1 && flag != 2)
699                {
700                        if(status.timeshifttype == 0 && status.asktimeshift == 0)
701                                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);
702
703                        if(rcret == 2) return 1;
704                        timeshiftstop(1);
705                }
706                if(flag != 2 && node->type != NOTHING && node->type != STILLPIC) caservicedel(node, NULL);
707
708                truncate("/tmp/ecm.info", 0);
709                unlink("/tmp/pid.info");
710                unlink("/tmp/caids.info");
711               
712                status.videosizevalid = 0;
713
714                if(status.epgthread != NULL) status.epgthread->aktion = PAUSE;
715                subtitlestop(0);
716
717                if(node->type == CHANNEL && flag < 2) akttolast();
718                if(flag != 2) node->type = NOTHING;
719
720                audiostop(node->audiodev);
721                videostop(node->videodev, clear);
722               
723                int fastzap = getconfigint("fastzap", NULL);
724
725                if(flag == 3) flag = 0;
726                if(flag == 1 || (flag == 0 && (fastzap == 0 || fastzap == 2)))
727                {
728                        audioclose(node->audiodev, -1);
729                        node->audiodev = NULL;
730                        dmxstop(node->dmxaudiodev);
731                        dmxclose(node->dmxaudiodev, -1);
732                        node->dmxaudiodev = NULL;
733                }
734               
735                if(flag == 1 || (flag == 0 && fastzap == 0))
736                {
737                        videoclose(node->videodev, -1);
738                        node->videodev = NULL;
739                        dmxstop(node->dmxvideodev);
740                        dmxclose(node->dmxvideodev, -1);
741                        node->dmxvideodev = NULL;
742                        dmxstop(node->dmxpcrdev);
743                        dmxclose(node->dmxpcrdev, -1);
744                        node->dmxpcrdev = NULL;
745                        dmxstop(node->dmxsubtitledev);
746                        dmxclose(node->dmxsubtitledev, -1);
747                        node->dmxsubtitledev = NULL;
748                }
749                return 0;
750        }
751        return 1;
752}
753
754void servicechangeaudio(struct channel* chnode, struct audiotrack* tracknode)
755{
756        if(chnode == NULL || tracknode == NULL)
757        {
758                err("NULL detect");
759                return;
760        }
761
762        if(chnode->audiopid == tracknode->audiopid && chnode->audiocodec == tracknode->audiocodec)
763                return;
764
765        chnode->audiopid = tracknode->audiopid;
766        chnode->audiocodec = tracknode->audiocodec;
767
768        status.writechannel = 1;
769        audiostop(status.aktservice->audiodev);
770        audiosetbypassmode(status.aktservice->audiodev, chnode->audiocodec);
771        //clear videobuffer on playback for syncing video / audio
772        if(status.playing == 1) videoclearbuffer(status.aktservice->videodev);
773        dmxsetpesfilter(status.aktservice->dmxaudiodev, chnode->audiopid, -1, DMX_OUT_DECODER, DMX_PES_AUDIO, 0);
774
775        //don't start audio play, if we are in timeshift record, but not playing mode
776        if(status.timeshifttype == 0 && status.timeshift == 1 && status.playing == 0) return;
777        if(status.timeshifttype == 1 && status.timeshift == 1 && status.playing == 0 && status.timeshiftpos > 0) return;
778
779        if(status.mute <> 1)
780                audioplay(status.aktservice->audiodev);
781}
782
783struct service* addservice(struct service* last)
784{
785        struct service *newnode = NULL, *node = NULL;
786
787        newnode = (struct service*)calloc(1, sizeof(struct service));
788        if(newnode == NULL)
789        {
790                err("no memory");
791                return NULL;
792        }
793
794        newnode->recdstfd = -1;
795        newnode->recsrcfd = -1;
796        newnode->tssize = 188;
797
798        m_lock(&status.servicemutex, 2);
799        node = service;
800        if(node != NULL)
801        {
802                if(last == NULL)
803                {
804                        while(node->next != NULL)
805                                node = node->next;
806                        node->next = newnode;
807                }
808                else
809                        last->next = newnode;
810        }
811        else
812                service = newnode;
813
814        m_unlock(&status.servicemutex, 2);
815        return newnode;
816}
817
818struct service* checkservice(struct service* node)
819{
820        struct service* snode = service;
821
822        while(snode != NULL)
823        {
824                if(snode == node)
825                        return snode;
826                snode = snode->next;
827        }
828        return NULL;
829}
830
831//flag 0: set mutex
832//flag 1: not set mutex
833void delservice(struct service* snode, int flag)
834{
835        m_lock(&status.servicemutex, 2);
836        struct service *node = service, *prev = service;
837        struct rectimer *rectimernode = NULL;
838
839        while(node != NULL)
840        {
841                if(node == snode)
842                {
843                        if(node == service)
844                                service = node->next;
845                        else
846                                prev->next = node->next;
847
848                        dmxclose(node->dmxaudiodev, -1);
849                        dmxclose(node->dmxvideodev, -1);
850                        dmxclose(node->dmxpcrdev, -1);
851                        dmxclose(node->dmxsubtitledev, -1);
852                        audioclose(node->audiodev, -1);
853                        videoclose(node->videodev, -1);
854                        close(node->recdstfd);
855                        close(node->recsrcfd);
856                        caservicedel(node, NULL);
857
858                        //check if a rectimer is joined with a service
859                        if(node->type == RECORDTIMER)
860                        {
861                                if(flag == 0)
862                                        m_lock(&status.rectimermutex, 1);
863
864                                rectimernode = getrectimerbyservice(node);
865                                if(rectimernode != NULL)
866                                {
867                                        rectimernode->servicenode = NULL;
868                                        if(rectimernode->status == 0 || rectimernode->status == 1)
869                                        {
870                                                rectimernode->status = 2;
871                                                status.writerectimer = 1;
872                                                writerectimer(getconfig("rectimerfile", NULL), 1);
873                                        }
874                                }
875
876                                if(flag == 0)
877                                        m_unlock(&status.rectimermutex, 1);
878                        }
879
880                        free(node->channellist);
881                        node->channellist = NULL;
882
883                        free(node->recname);
884                        node->recname = NULL;
885
886                        free(node->rectimestamp);
887                        node->rectimestamp = NULL;
888
889                        free(node->pmtbuf);
890                        node->pmtbuf = NULL;
891
892                        free(node);
893                        node = NULL;
894                        break;
895                }
896
897                prev = node;
898                node = node->next;
899        }
900        m_unlock(&status.servicemutex, 2);
901}
902
903void freeservice()
904{
905        struct service *node = service, *prev = service;
906
907        while(node != NULL)
908        {
909                prev = node;
910                node = node->next;
911                if(prev != NULL)
912                        delservice(prev, 0);
913        }
914}
915
916char* servicecheckret(int ret, int flag)
917{
918        char* tmpstr = NULL;
919
920        if(ret != 0)
921        {
922                switch(ret)
923                {
924                        case 1:
925                                tmpstr = ostrcat(_("Can't find a Tuner.\nAll Tuners in use or no Tuner defined."), NULL, 0, 0);
926                                break;
927                        case 2:
928                                tmpstr = ostrcat(_("Tuning to Channel failed!"), NULL, 0, 0);
929                                break;
930                        case 3:
931                                tmpstr = ostrcat(_("Can't open frontend dev or Frontend Type unknown!"), NULL, 0, 0);
932                                break;
933                        case 20:
934                                break;
935                        case 21:
936                                tmpstr = ostrcat(_("Channellist empty or corrupt (channel not found)!"), NULL, 0, 0);
937                                break;
938                        case 22:
939                                break;
940                }
941                if(tmpstr != NULL)
942                        textbox(_("Message"), tmpstr, _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 10, 0);
943        }
944
945        if(flag != 1)
946        {
947                free(tmpstr);
948                tmpstr = NULL;
949        }
950
951        return tmpstr;
952}
953
954#endif
Note: See TracBrowser for help on using the repository browser.