source: titan/titan/service.h @ 25695

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

test a function

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