source: titan/titan/record.h @ 14357

Last change on this file since 14357 was 14357, checked in by nit, 12 years ago

[titan] last step tssize

File size: 25.1 KB
Line 
1#ifndef RECORD_H
2#define RECORD_H
3
4int recordcheckcrypt(struct dvbdev* fenode, int servicetype)
5{
6        struct service* servicenode = service;
7
8        while(servicenode != NULL)
9        {
10                if(fenode == servicenode->fedev && servicenode->channel != NULL && servicenode->channel->crypt > 0)
11                {
12                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER) return 1;
13                        if(servicetype == RECORDSTREAM && servicenode->type == RECORDTIMESHIFT) return 1;
14                        if(servicetype == CHANNEL && servicenode->type == RECORDTIMESHIFT) return 1;
15                }
16                servicenode = servicenode->next;
17        }
18        return 0;
19}
20
21//flag bit 0 = with timeout
22//flag bit 1 = show textbox
23//flag bit 2 = print debug
24//flag bit 3 = return text
25char* recordcheckret(struct stimerthread* timernode, int ret, int flag)
26{
27        char* tmpstr = NULL;
28        int timeout = 0;
29        if(checkbit(flag, 0) == 1)
30                timeout = 10;
31
32        if(ret != 0)
33        {
34                switch(ret)
35                {
36                        case 1:
37                                tmpstr = ostrcat(_("HDD not configured\ncan't find record path"), "", 0, 0);
38                                break;
39                        case 2:
40                                tmpstr = ostrcat(_("Not enought space"), "", 0, 0);
41                                break;
42                        case 3:
43                                tmpstr = ostrcat(_("Error create filename"), "", 0, 0);
44                                break;
45                        case 4:
46                                tmpstr = ostrcat(_("Can't open file"), "", 0, 0);
47                                break;
48                        case 5:
49                                tmpstr = ostrcat(_("Can't open FRONTEND device"), "", 0, 0);
50                                break;
51                        case 6:
52                                tmpstr = ostrcat(_("Can't open DMX device"), "", 0, 0);
53                                break;
54                        case 7:
55                                tmpstr = ostrcat(_("Pid's not ok"), "", 0, 0);
56                                break;
57                        case 8:
58                                tmpstr = ostrcat(_("Channel or Transponder is empty"), "", 0, 0);
59                                break;
60                        case 9:
61                                tmpstr = ostrcat(_("Write error"), "", 0, 0);
62                                break;
63                        case 10:
64                                tmpstr = ostrcat(_("No memory"), "", 0, 0);
65                                break;
66                        case 11:
67                                tmpstr = ostrcat(_("Failed open split file"), "", 0, 0);
68                                break;
69                        case 12:
70                                tmpstr = ostrcat(_("Frontend type unknown"), "", 0, 0);
71                                break;
72                        case 13:
73                                tmpstr = ostrcat(_("Tune to channel failed"), "", 0, 0);
74                                break;
75                        case 14:
76                                break;
77                        case 15:
78                                tmpstr = ostrcat(_("To many read error or end of file"), "", 0, 0);
79                                break;
80                        case 16:
81                                tmpstr = ostrcat(_("Can't create service"), "", 0, 0);
82                                break;
83                }
84                if(tmpstr != NULL)
85                {
86                        if(checkbit(flag, 2) == 1) err("%s", tmpstr);
87                        if(checkbit(flag, 1) == 1) textbox(_("Record / Timeshift / Stream"), tmpstr, _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, NULL, 0, 600, 200, timeout, 0);
88                }
89        }
90        if(checkbit(flag, 3) == 0)
91        {
92                free(tmpstr);
93                tmpstr = NULL;
94        }
95        return tmpstr;
96}
97
98void recordwriteepg(char* filename, struct channel* chnode, struct rectimer* rectimernode)
99{
100        struct epg* epgnode = NULL;
101        FILE *fd = NULL;
102        int ret = 0, count = 0;
103        char* tmpstr = NULL, *epgfilename = NULL, *buf = NULL;
104        struct tm *loctime = NULL;
105
106        if(filename == NULL)
107        {
108                err("epg record filename = NULL");
109                return;
110        }
111
112        epgfilename = changefilenameext(filename, ".epg");
113       
114        //check if epg is in rectimer time
115        if(rectimernode != NULL)
116        {
117                epgnode = getepgakt(chnode);
118                while(epgnode != NULL && (epgnode->starttime < rectimernode->begin || epgnode->starttime >= rectimernode->end))
119                        epgnode = epgnode->next;
120        }
121        else
122                epgnode = getepgbytime(chnode, time(NULL) + 60);
123       
124        if(epgnode != NULL)
125        {
126                fd = fopen(epgfilename, "w");
127                if(fd == NULL)
128                {
129                        perr("open %s", epgfilename);
130                        free(epgfilename);
131                        return;
132                }
133                chmod(epgfilename, 0666);
134
135                if(epgnode->title != NULL)
136                {
137                        buf = malloc(MINMALLOC);
138                        loctime = localtime(&epgnode->starttime);
139                        strftime(buf, MINMALLOC, "%d-%m-%Y %H:%M", loctime);
140                        ret += fwrite(buf, strlen(buf), 1, fd);
141                        ret += fwrite(" - ", 3, 1, fd);
142                        ret += fwrite(epgnode->title, strlen(epgnode->title), 1, fd);
143                        ret += fwrite("\n", 1, 1, fd);
144                        count += 4;
145                        free(buf); buf = NULL;
146                }
147                if(epgnode->subtitle != NULL)
148                {
149                        ret += fwrite(epgnode->subtitle, strlen(epgnode->subtitle), 1, fd);
150                        ret += fwrite("\n\n", 2, 1, fd);
151                        count += 2;
152                }
153                if(epgnode->desc != NULL)
154                {
155                        tmpstr = epgdescunzip(epgnode);
156                        if(tmpstr != NULL)
157                        {
158                                ret += fwrite(tmpstr, strlen(tmpstr), 1, fd);
159                                count++;
160                                free(tmpstr); tmpstr = NULL;
161                        }
162                }
163
164                if(ret != count)
165                {
166                        err("writting record epg file");
167                }
168
169                fclose(fd);
170        }
171        free(epgfilename);
172}
173
174void recordstop(struct service* node)
175{
176        debug(1000, "in");
177        struct rectimer* rectimernode = NULL;
178        int afterevent = 1, type = -1;
179
180        if(node != NULL)
181        {
182                type = node->type;
183
184                if(node->fedev != NULL && node->type != RECORDTIMESHIFT)
185                        node->fedev->felock--;
186
187                m_lock(&status.rectimermutex, 1);
188                rectimernode = getrectimerbyservice(node);
189                if(rectimernode != NULL)
190                        afterevent = rectimernode->afterevent;
191                m_unlock(&status.rectimermutex, 1);
192               
193                delservice(node, 0);
194
195                if(type == RECORDSTREAM)
196                        status.streaming--;
197                else if(type == RECORDTIMESHIFT)
198                        status.timeshift = 0;
199                else if(type == RECORDPLAY)
200                        status.playing = 0;
201                else
202                        status.recording--;
203
204                deltranspondertunablestatus();
205
206                //afterevent: 0 = auto
207                //afterevent: 1 = nothing
208                //afterevent: 2 = standby
209                //afterevent: 3 = poweroff
210                if(afterevent == 0)
211                {
212                        if(status.startmode == 1) afterevent = 2;
213                        else if(getwaswakuptimer() == 1) afterevent = 3;
214
215                }
216                if(afterevent == 2 && status.standby == 0)
217                {
218                        status.standby = 2;
219                        screenstandby();
220                }
221                if(afterevent == 3)
222                {
223                        if(status.recording < 1)
224                                oshutdown(1, 3);
225                }
226        }
227
228        debug(1000, "out");
229}
230
231int recordsplit(struct service* servicenode)
232{
233        int ret = 0;
234        char* filename = NULL;
235
236        filename = malloc(256);
237        if(filename == NULL)
238        {
239                err("no mem");
240                ret = 10;
241                servicenode->recendtime = 1;
242        }
243        else
244        {
245                fdatasync(servicenode->recdstfd);
246                close(servicenode->recdstfd);
247                servicenode->rectotal = 0;
248                servicenode->reclastsync = 0;
249
250                if(servicenode->reccount < 2)
251                {
252                        if(strlen(servicenode->recname) > 3)
253                                servicenode->recname[strlen(servicenode->recname) - 3] = '\0';
254                }
255                else
256                {
257                        if(strlen(servicenode->recname) > 7)
258                                servicenode->recname[strlen(servicenode->recname) - 7] = '\0';
259                }
260                snprintf(filename, 255, "%s.%03d.ts", servicenode->recname, servicenode->reccount++);
261                free(servicenode->recname);
262                servicenode->recname = filename;
263
264                debug(250, "split record file - Recording to %s...", filename);
265
266                servicenode->recdstfd = open(filename, O_WRONLY|O_CREAT|O_LARGEFILE, 0644);
267                if(servicenode->recdstfd < 0)
268                {
269                        debug(250, "split record file - can't open recording file!");
270                        ret = 11;
271                        servicenode->recendtime = 1;
272                }
273                else
274                        posix_fadvise(servicenode->recdstfd, 0, 0, POSIX_FADV_RANDOM);
275        }
276        return ret;
277}
278
279int readwritethread(struct stimerthread* stimer, struct service* servicenode, int flag)
280{
281        int readret = 0, writeret = 0, ret = 0, recbsize = 0;
282        int readtimeout = -1, writetimeout = -1;
283        unsigned char* buf = NULL;
284        char* retstr = NULL;
285        //off64_t pos = 0;
286
287        debug(250, "start read-write thread");
288
289        if(servicenode == NULL)
290        {
291                err("servicenode = NULL");
292                return 1;
293        }
294
295        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
296        {
297                recbsize = servicenode->tssize * 2788;
298                readtimeout = 5000000;
299                writetimeout = 5000000; //5 sec
300        }
301               
302        if(servicenode->type == RECORDPLAY || servicenode->type == RECORDSTREAM)
303        {
304                if(servicenode->recdstfd < 0)
305                {
306                        err("destination fd not ok")
307                        return 1;
308                }
309                if(servicenode->type == RECORDPLAY) recbsize = servicenode->tssize * 512;
310                if(servicenode->type == RECORDSTREAM) recbsize = servicenode->tssize * 2788;
311                readtimeout = 5000000;
312                writetimeout = 5000000;
313        }
314       
315#ifdef SIMULATE
316        int fd = open("simulate/record.ts", O_RDONLY | O_LARGEFILE);
317        if(fd < 0)
318        {
319                perr("open simulate/record.ts");
320                return 1;
321        }
322#endif
323
324        buf = malloc(recbsize);
325        if(buf == NULL)
326        {
327                err("no mem");
328                return 1;
329        }
330       
331        if(servicenode->recdmxstart == 0)
332        {
333                dmxstart(servicenode->dmxvideodev);
334                servicenode->recdmxstart = 1;
335        }
336       
337        while(1)
338        {       
339#ifdef SIMULATE
340                servicenode->recsrcfd = fd;
341                readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout);
342                usleep(1000);
343#else
344                if(servicenode->type == RECORDPLAY)
345                        m_lock(&status.tsseekmutex, 15);
346                readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout);
347                if(servicenode->type == RECORDPLAY)
348                        m_unlock(&status.tsseekmutex, 15);
349#endif
350                if(readret > 0)
351                {
352//repeatewrite:
353                        if(servicenode->type == RECORDSTREAM)
354                                writeret = sockwrite(servicenode->recdstfd, buf, readret, writetimeout);
355                        else
356                                writeret = dvbwrite(servicenode->recdstfd, buf, readret, writetimeout);
357                        //else if(servicenode->type == RECORDPLAY)
358                        //      writeret = dvbwrite(servicenode->recdstfd, buf, readret, writetimeout);
359                        //else if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
360                        //      writeret = write(servicenode->recdstfd, buf, readret);
361
362                        if(writeret < 1)
363                        {
364                                //if((servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT) && (errno == EINTR || errno == EAGAIN || errno == EBUSY))
365                                //{
366                                //      perr("record/ts write repeate");
367                                //      goto repeatewrite;
368                                //}
369                                ret = 9;
370                                servicenode->recendtime = 1;
371                        }
372                        else if(readret != writeret)
373                        {
374                                debug(250, "not all data written read=%d, written=%d", readret, writeret);
375                        }
376
377                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
378                        {
379                                //sync
380                                servicenode->reclastsync += writeret;
381                                if(servicenode->reclastsync > 524288)
382                                {
383                                        int tosync = servicenode->reclastsync > 2097152 ? 2097152 : servicenode->reclastsync &~ 4095; //sync max 2MB
384                                        //pos = lseek64(servicenode->recdstfd, 0, SEEK_CUR);
385                                        //pos -= tosync;
386                                        //posix_fadvise64(servicenode->recdstfd, pos, tosync, POSIX_FADV_DONTNEED);
387                                        servicenode->reclastsync -= tosync;
388
389                                        //split only after sync
390                                        if(status.recsplitsize && servicenode->type != RECORDTIMESHIFT)
391                                        {
392                                                servicenode->rectotal += tosync;
393                                                if(servicenode->rectotal > status.recsplitsize)
394                                                ret = recordsplit(servicenode);
395                                        }
396                                }
397                        }
398                }
399                else if(readret <= 0)
400                {
401                        ret = 15;
402                        servicenode->recendtime = 1;
403                        if(readret < -1)
404                                perr("read");
405                }
406
407                if(servicenode->recendtime != 0 && (servicenode->recendtime) < time(NULL))
408                {
409                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
410                                fdatasync(servicenode->recdstfd);
411                        if(ret != 0) // error
412                        {
413                                if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
414                                        addtimer(&recordcheckret, START, 1000, 1, (void*)ret, (void*)3, NULL);
415                                retstr = recordcheckret(NULL, ret, 12);
416
417                                //if(servicenode->type == RECORDSTREAM)
418                                //      sockwrite(servicenode->recdstfd, (unsigned char*)retstr, strlen(retstr), -1);
419                                if(servicenode->type == RECORDTIMER)
420                                {
421                                        m_lock(&status.rectimermutex, 1);
422                                        struct rectimer* rectimernode = getrectimerbyservice(servicenode);
423                                        if(rectimernode != NULL)
424                                        {
425                                                rectimernode->status = 3;
426                                                free(rectimernode->errstr);
427                                                rectimernode->errstr = ostrcat(retstr, "", 0, 0);
428                                                status.writerectimer = 1;
429                                                writerectimer(getconfig("rectimerfile", NULL), 1);
430                                        }
431                                        m_unlock(&status.rectimermutex, 1);
432                                }
433                                free(retstr); retstr = NULL;
434                        }
435                        recordstop(servicenode);
436                        break;
437                }
438        }
439
440#ifdef SIMULATE
441        close(fd);
442#endif
443        if(buf != NULL) free(buf);
444        debug(250, "stop read-write thread");
445        return 0;
446}
447
448char* recordcreatefilename(char* path, char* channelname, char* moviename, int type)
449{
450        time_t sec;
451        struct tm *loctime;
452        char *buf = NULL, *buf1 = NULL;
453        char* tmpstr = NULL;
454
455        if(path == NULL)
456                return NULL;
457
458        tmpstr = ostrcat(path, "/", 0, 0);
459        if(type != RECTIMESHIFT)
460        {
461                if(channelname == NULL || strlen(channelname) == 0)
462                        tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
463                else
464                        tmpstr = ostrcat(tmpstr, channelname, 1, 0);
465                tmpstr = ostrcat(tmpstr, "-", 1, 0);
466        }
467        if(moviename == NULL || strlen(moviename) == 0)
468                tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
469        else
470                tmpstr = ostrcat(tmpstr, moviename, 1, 0);
471
472        sec = time(NULL);
473        loctime = localtime(&sec);
474
475        buf = malloc(MINMALLOC);
476        if(buf == NULL)
477        {
478                err("no memory");
479                return NULL;
480        }
481
482        strftime(buf, MINMALLOC, "%Y%m%d%H%M%S", loctime);
483        buf1 = ostrcat(buf, "", 1, 0);
484
485        tmpstr = ostrcat(tmpstr, "-", 1, 0);
486        tmpstr = ostrcat(tmpstr, buf1, 1, 1);
487        tmpstr = ostrcat(tmpstr, ".ts", 1, 0);
488
489        debug(1000, "out");
490        return tmpstr;
491}
492
493int recordstartreal(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode, int tssize)
494{
495        int ret = 0, fd = -1, servicetype = RECORDDIRECT, festatus = 0;
496        char* path = NULL, *chname = NULL, *filename = NULL, *moviename = NULL;
497        unsigned char* patbuf = NULL, *pmtbuf = NULL;
498        struct epg* epgnode = NULL;
499        struct service* servicenode = NULL;
500        struct dvbdev* fenode = NULL, *dmxnode = NULL;
501        struct audiotrack* atrack = NULL;
502        char* tmpstr = NULL;
503        struct transponder* tpnode = NULL;
504        int input = DMX_IN_FRONTEND;
505
506        if(chnode == NULL && filefd < 0)
507        {
508                ret = 8;
509                goto end;
510        }
511
512        if(filefd < 0)
513        {
514                tpnode = chnode->transponder;
515                if(tpnode == NULL)
516                {
517                        ret = 8;
518                        goto end;
519                }
520        }
521
522        switch(type)
523        {
524                case RECPLAY:
525                        servicetype = RECORDPLAY;
526                        fd = recordfd;
527                        break;
528                case RECSTREAM:
529                        servicetype = RECORDSTREAM;
530                        fd = recordfd;
531                        break;
532                case RECTIMESHIFT:
533                        servicetype = RECORDTIMESHIFT;
534                        path = getconfig("rec_timeshiftpath", NULL);
535                        moviename = "timeshift";
536                        break;
537                case RECTIMER:
538                        servicetype = RECORDTIMER;
539                        if(rectimernode != NULL && rectimernode->recpath != NULL)
540                                path = rectimernode->recpath;
541                        else
542                                path = getconfig("rec_timerpath", NULL);
543                        if(chnode != NULL)
544                        {
545                                chname = strstrip(chnode->name);
546                                delspezchar(chname, 1);
547                        }
548                        moviename = strstrip(rectimernode->name);
549                        delspezchar(moviename, 1);
550                        break;
551                default:
552                        servicetype = RECORDDIRECT;
553                        path = getconfig("rec_path", NULL);
554                        if(chnode != NULL)
555                        {
556                                chname = strstrip(chnode->name);
557                                delspezchar(chname, 1);
558                        }
559                        epgnode = getepgbytime(status.aktservice->channel, time(NULL) + 60);
560                        if(epgnode != NULL)
561                        {
562                                moviename = strstrip(epgnode->title);
563                                delspezchar(moviename, 1);
564                        }
565                        break;
566        }
567
568        if(type != RECSTREAM && type != RECPLAY)
569        {
570                if(!isdir(path))
571                {
572                        ret = 1;
573                        goto end;
574                }
575
576                //check HDD free space
577                //deaktivate, on my 500GB FAT32 HDD, this takes mor then 10 min
578/*
579                if(getfreespace(path) < getconfigint("recordfreespace", NULL) * 1024 * 1024)
580                {
581                        ret = 2;
582                        goto end;
583                }
584*/
585
586                filename = recordcreatefilename(path, chname, moviename, type);
587                if(filename == NULL)
588                {
589                        ret = 3;
590                        goto end;
591                }
592
593                fd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0666);
594                if(fd < 0)
595                {
596                        char* fn = strrchr(filename, '/');
597                        if(fn == NULL)
598                                delspezchar(filename, 0);
599                        else
600                                delspezchar(fn + 1, 0);
601       
602                        fd = open(filename, O_WRONLY|O_CREAT|O_LARGEFILE, 0666);
603                        if(fd < 0)
604                        {
605                                ret = 4;
606                                goto end;
607                        }
608                }
609                posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); //turn off kernel cache
610        }
611
612        servicenode = addservice(NULL);
613        if(servicenode == NULL)
614        {
615                ret = 16;
616                goto end;
617        }
618        servicenode->tssize = tssize;
619        servicenode->recdstfd = fd;
620        servicenode->channel = chnode;
621        servicenode->transponder = tpnode;
622
623        if(filefd < 0)
624        {
625                //got frontend dev
626                fenode = fegetfree(tpnode, 2, NULL);
627                if(fenode == NULL)
628                {
629                        if(type == RECSTREAM)
630                        {
631                                ret = 5;
632                                goto end;
633                        }
634                        else
635                        {
636                                if(textbox(_("Message"), _("Can't find free Tuner for Record.\nSwitch to Recording/Timeshift Channel ?"), _("EXIT"), getrcconfigint("rcexit", NULL), _("OK"), getrcconfigint("rcok", NULL), NULL, 0, NULL, 0, 600, 200, 10, 0) == 1)
637                                {
638                                        ret = 14;
639                                        goto end;
640                                }
641                                else
642                                {
643                                        if(rectimernode != NULL)
644                                                servicestart(chnode, rectimernode->channellist, rectimernode->pincode, 0);
645                                        else
646                                                servicestart(chnode, NULL, NULL, 0);
647                                        fenode = fegetfree(tpnode, 2, NULL);
648                                        if(fenode == NULL)
649                                        {
650                                                ret = 5;
651                                                goto end;
652                                        }
653                                }
654                        }
655                }
656                if(type != RECTIMESHIFT) fenode->felock++;
657
658                //frontend tune
659                if(fenode != status.aktservice->fedev)
660                {
661                        if(fenode->feinfo->type == FE_QPSK)
662                        {
663                                feset(fenode, tpnode);
664                                fetunedvbs(fenode, tpnode);
665                        }
666                        else if(fenode->feinfo->type == FE_QAM)
667                                fetunedvbc(fenode, tpnode);
668                        else if(fenode->feinfo->type == FE_OFDM)
669                                fetunedvbt(fenode, tpnode);
670                        else
671                        {
672                                ret = 12;
673                                if(type != RECTIMESHIFT) fenode->felock--;
674                                goto end;
675                        }
676
677                        festatus = fewait(fenode);
678                        if(debug_level == 200) fereadstatus(fenode);
679                        if(festatus != 0)
680                        {
681                                ret = 13;
682                                if(type != RECTIMESHIFT) fenode->felock--;
683                                goto end;
684                        }
685                }
686
687                servicenode->fedev = fenode;
688
689                //demux  start
690                dmxnode = dmxopen(fenode);
691                if(dmxnode != NULL && dmxnode->fd >= 0)
692                {
693                        servicenode->recsrcfd = dmxnode->fd;
694                        if(type == RECTIMESHIFT)
695                                dmxsetbuffersize(dmxnode, getconfigint("dmxtimeshiftbuffersize", NULL));
696                        else if(type == RECSTREAM)
697                                dmxsetbuffersize(dmxnode, getconfigint("dmxstreambuffersize", NULL));
698                        else
699                                dmxsetbuffersize(dmxnode, getconfigint("dmxrecordbuffersize", NULL));
700                        servicenode->dmxaudiodev = dmxnode;
701                        servicenode->dmxvideodev = dmxnode;
702                        dmxsetsource(dmxnode, fenode->fedmxsource);
703#if DVB_API_VERSION > 3
704                        dmxsetpesfilter(dmxnode, 0, input, DMX_OUT_TSDEMUX_TAP, DMX_PES_OTHER, 1);
705#else
706                        dmxsetpesfilter(dmxnode, 0, input, DMX_OUT_TAP, 0, 1);
707#endif
708                        patbuf = dvbgetpat(fenode, -1);
709                        chnode->pmtpid = dvbgetpmtpid(patbuf, chnode->serviceid);
710
711                        m_lock(&status.servicemutex, 2);
712                        if(status.aktservice->channel != chnode)
713                        {
714                                //reset channel info
715                                serviceresetchannelinfo(chnode);
716                                pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, NULL, -1, 0);
717                                dvbgetinfo(pmtbuf, chnode);
718                        }
719                        if(status.pmtmode == 1)
720                        {
721                                if(recordcheckcrypt(fenode, servicetype) == 0)
722                                        dvbwritepmt(servicenode, pmtbuf);
723                                else
724                                        debug(250, "don't write pmt.tmp, another crypt channel use this frontend");
725                        }
726                        else
727                                sendcapmt(servicenode, 0, 3);
728                        m_unlock(&status.servicemutex, 2);
729
730                        free(pmtbuf); pmtbuf = NULL;
731                        free(patbuf); patbuf = NULL;
732                        if((chnode->audiopid < 1 && chnode->videopid < 1) || chnode->pmtpid < 1)
733                        {
734#ifndef SIMULATE
735                                ret = 7;
736                                if(type != RECTIMESHIFT) fenode->felock--;
737                                goto end;
738#endif
739                        }
740                        if(chnode->audiopid > 0) dmxaddpid(dmxnode, chnode->audiopid);
741                        if(chnode->videopid > 0) dmxaddpid(dmxnode, chnode->videopid);
742                        dmxaddpid(dmxnode, chnode->pmtpid);
743                        //dmxaddpid(dmxnode, chnode->pcrpid);
744                        //add all audiotracks
745                        atrack = chnode->audiotrack;
746                        while(atrack != NULL)
747                        {
748                                if(atrack->audiopid > 0 && atrack->audiopid != chnode->audiopid)
749                                        dmxaddpid(dmxnode, atrack->audiopid);
750                                atrack = atrack->next;
751                        }
752                }
753                else
754                {
755                        ret = 6;
756                        if(type != RECTIMESHIFT) fenode->felock--;
757                        goto end;
758                }
759        }
760
761        if(rectimernode != NULL)
762                rectimernode->servicenode = servicenode;
763
764        servicenode->recendtime = endtime;
765        servicenode->reccount = 1;
766        servicenode->type = servicetype;
767
768        if(filefd < 0)
769                deltranspondertunablestatus();
770        else
771                servicenode->recsrcfd = filefd;
772
773        if(type == RECSTREAM)
774        {
775                status.streaming++;
776                servicenode->recname = ostrcat("stream ", oitoa(recordfd), 0, 1);
777        }
778        else if(type == RECTIMESHIFT)
779        {
780                status.timeshift = 1;
781                servicenode->recname = ostrcat(filename, "", 0, 0);
782        }
783        else if(type == RECPLAY)
784        {
785                status.playing = 1;
786                servicenode->recdmxstart = 1;
787        }
788        else if(type == RECDIRECT || type == RECTIMER)
789        {
790                status.recording++;
791                servicenode->recname = ostrcat(filename, "", 0, 0);
792        }
793
794        if(type != RECSTREAM && type != RECTIMESHIFT && type != RECPLAY)
795                recordwriteepg(filename, chnode, rectimernode);
796        if(type == RECTIMER)
797        {
798                tmpstr = ostrcat(_("Timer Record start !\n"), filename, 0, 0);
799                textbox(_("Message"), tmpstr, _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, NULL, 0, 600, 200, 4, 0);
800                free(tmpstr); tmpstr = NULL;
801        }
802       
803        //start readwrite thread
804        addtimer(&readwritethread, START, 1000, 1, (void*)servicenode, NULL, NULL);
805       
806        if(filename != NULL) debug(250, "rec filename = %s\n", filename);
807
808end:
809        if(ret > 0)
810        {
811                delservice(servicenode, 1);
812                if(filename != NULL) unlink(filename);
813        }
814        free(filename); filename = NULL;
815        return ret;
816}
817
818int recordstart(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode)
819{
820        return recordstartreal(chnode, filefd, recordfd, type, endtime, rectimernode, 188);
821}
822
823struct service* getrecordbyname(char* recname, int type)
824{
825        debug(1000, "in");
826        struct service* servicenode = service;
827
828        if(recname == NULL)
829        {
830                debug(1000, "out -> NULL detect");
831                return NULL;
832        }
833
834        while(servicenode != NULL)
835        {
836                if((type == -1 && (servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)) || type == servicenode->type)
837                {
838                        if(servicenode->recname != NULL)
839                        {
840                                if(strstr(recname, servicenode->recname) != NULL)
841                                        return servicenode;
842                        }
843                }
844                servicenode = servicenode->next;
845        }
846
847        return NULL;
848        debug(1000, "out");
849}
850
851int screenrecordduration(int minutes)
852{
853                int rcret = 0, ret = 0;
854                struct skin* recordduration = getscreen("recordduration");
855                char* tmpnr = NULL;
856
857                changemask(recordduration, "0000");
858                if(minutes < 0) minutes = 0;
859                if(minutes > 9999) minutes = 9999;
860                tmpnr = malloc(5);
861                snprintf(tmpnr, 5, "%04d", minutes);
862                changeinput(recordduration, tmpnr);
863                free(tmpnr);
864
865                drawscreen(recordduration, 0);
866                addscreenrc(recordduration, recordduration);
867
868                while(1)
869                {
870                        rcret = waitrc(recordduration, 0, 0);
871                        if(rcret == getrcconfigint("rcexit", NULL))
872                        {
873                                changeret(recordduration, NULL);
874                                break;
875                        }
876                        if(rcret == getrcconfigint("rcok", NULL))
877                                break;
878                }
879
880                if(recordduration->ret != NULL && ostrcmp(recordduration->ret, "0") != 0)
881                        ret = atoi(recordduration->ret);
882
883                delownerrc(recordduration);
884                clearscreen(recordduration);
885
886                return ret;
887}
888
889void screenrecordstop()
890{
891        char* tmpstr = NULL, *mlistbox = NULL;
892        struct service* servicenode = service;
893
894        while(servicenode != NULL)
895        {
896                if((servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER) && servicenode->recname != NULL)
897                {
898                        tmpstr = ostrcat(tmpstr, _("stop"), 1, 0);
899                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
900                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
901                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
902                }
903                servicenode = servicenode->next;
904        }
905
906        mlistbox = menulistbox(NULL, tmpstr, "recordlist", "Record", NULL, 0, 0);
907        if(mlistbox != NULL && strstr(mlistbox, "stop") == mlistbox)
908        {
909                servicenode = getrecordbyname(mlistbox, RECORDDIRECT);
910                if(servicenode != NULL)
911                        servicenode->recendtime = 1;
912                else
913                {
914                        servicenode = getrecordbyname(mlistbox, RECORDTIMER);
915                        if(servicenode != NULL)
916                                servicenode->recendtime = 1;
917                }
918        }
919
920        free(tmpstr); tmpstr = NULL;
921        free(mlistbox); mlistbox = NULL;
922}
923
924void screenrecorddirect()
925{
926        char* tmpstr = NULL, *mlistbox = NULL;
927        int ret = 0, ret1 = 0;
928        struct service* servicenode = service;
929        struct epg* epgnode = NULL;
930
931        while(servicenode != NULL)
932        {
933                if(servicenode->type == RECORDDIRECT && servicenode->recname != NULL)
934                {
935                        tmpstr = ostrcat(tmpstr, _("stop"), 1, 0);
936                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
937                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
938                        tmpstr = ostrcat(tmpstr, ")\n", 1, 0);
939                        tmpstr = ostrcat(tmpstr, _("change"), 1, 0);
940                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
941                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
942                        tmpstr = ostrcat(tmpstr, ")\n", 1, 0);
943                }
944                servicenode = servicenode->next;
945        }
946
947        //tmpstr = ostrcat(tmpstr, "add recording (stop after current event)\nadd recording (indefinitely)\nadd recording (enter duration)\nadd recording (enter endtime)", 1, 0);
948        tmpstr = ostrcat(tmpstr, "add recording (stop after current event)\nadd recording (indefinitely)\nadd recording (enter duration)", 1, 0);
949
950        mlistbox = menulistbox(NULL, tmpstr, "recordlist", "Record", NULL, 0, 0);
951        if(mlistbox != NULL && strstr(mlistbox, "stop") == mlistbox)
952        {
953                servicenode = getrecordbyname(mlistbox, RECORDDIRECT);
954                if(servicenode != NULL)
955                        servicenode->recendtime = 1;
956        }
957        if(mlistbox != NULL && strstr(mlistbox, "change") == mlistbox)
958        {
959                servicenode = getrecordbyname(mlistbox, RECORDDIRECT);
960                if(servicenode != NULL)
961                {
962                        ret1 = (servicenode->recendtime - time(NULL)) / 60;
963                        ret1 = screenrecordduration(ret1);
964                        if(ret1 > 0)
965                                servicenode->recendtime = time(NULL) + (ret1 * 60);
966                }
967        }
968        if(ostrcmp(mlistbox, "add recording (stop after current event)") == 0)
969        {
970                epgnode = getepgbytime(status.aktservice->channel, time(NULL) + 60);
971#ifndef SIMULATE
972                if(epgnode != NULL && epgnode->endtime > time(NULL))
973                        ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, epgnode->endtime, NULL);
974                else
975                        textbox(_("Message"), _("Can't get EPG time or EPG endtime not ok"), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, NULL, 0, 600, 200, 0, 0);
976#else
977                ret = recordstart(status.aktservice->channel, -1,  0, RECDIRECT, time(NULL) + 5, NULL);
978#endif
979        }
980        if(ostrcmp(mlistbox, "add recording (indefinitely)") == 0)
981                ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, 0, NULL);
982        if(ostrcmp(mlistbox, "add recording (enter duration)") == 0)
983        {
984                ret1 = screenrecordduration(0);
985
986                if(ret1 > 0)
987                        ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, time(NULL) + (ret1 * 60), NULL);
988        }
989        //if(ostrcmp(mlistbox, "add recording (enter endtime)") == 0)
990        //      ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, 0, NULL);
991
992        recordcheckret(NULL, ret, 6);
993        free(tmpstr); tmpstr = NULL;
994        free(mlistbox); mlistbox = NULL;
995}
996
997#endif
Note: See TracBrowser for help on using the repository browser.