source: titan/titan/record.h @ 26912

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

fix

File size: 36.4 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"), NULL, 0, 0);
38                                break;
39                        case 2:
40                                tmpstr = ostrcat(_("Not enought space"), NULL, 0, 0);
41                                break;
42                        case 3:
43                                tmpstr = ostrcat(_("Error create filename"), NULL, 0, 0);
44                                break;
45                        case 4:
46                                tmpstr = ostrcat(_("Can't open file"), NULL, 0, 0);
47                                break;
48                        case 5:
49                                tmpstr = ostrcat(_("Can't open FRONTEND device"), NULL, 0, 0);
50                                break;
51                        case 6:
52                                tmpstr = ostrcat(_("Can't open DMX device"), NULL, 0, 0);
53                                break;
54                        case 7:
55                                tmpstr = ostrcat(_("Pid's not ok"), NULL, 0, 0);
56                                break;
57                        case 8:
58                                tmpstr = ostrcat(_("Channel or Transponder is empty"), NULL, 0, 0);
59                                break;
60                        case 9:
61                                tmpstr = ostrcat(_("Write error"), NULL, 0, 0);
62                                break;
63                        case 10:
64                                tmpstr = ostrcat(_("No memory"), NULL, 0, 0);
65                                break;
66                        case 11:
67                                tmpstr = ostrcat(_("Failed open split file"), NULL, 0, 0);
68                                break;
69                        case 12:
70                                tmpstr = ostrcat(_("Frontend type unknown"), NULL, 0, 0);
71                                break;
72                        case 13:
73                                tmpstr = ostrcat(_("Tune to channel failed"), NULL, 0, 0);
74                                break;
75                        case 14:
76                                break;
77                        case 15:
78                                tmpstr = ostrcat(_("To many read error or end of file"), NULL, 0, 0);
79                                break;
80                        case 16:
81                                tmpstr = ostrcat(_("Can't create service"), NULL, 0, 0);
82                                break;
83                        case 17:
84                                tmpstr = ostrcat(_("No space left on device"), NULL, 0, 0);
85                                break;
86                }
87                if(tmpstr != NULL)
88                {
89                        if(checkbit(flag, 2) == 1) err("%s", tmpstr);
90                        if(checkbit(flag, 1) == 1) textbox(_("Record / Timeshift / Stream"), tmpstr, _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, NULL, 0, 800, 200, timeout, 0);
91                }
92        }
93        if(checkbit(flag, 3) == 0)
94        {
95                free(tmpstr);
96                tmpstr = NULL;
97        }
98        return tmpstr;
99}
100
101void recordwriteepg(char* filename, struct channel* chnode, struct rectimer* rectimernode)
102{
103        struct epg* epgnode = NULL;
104        FILE *fd = NULL;
105        int ret = 0, count = 0;
106        char* tmpstr = NULL, *epgfilename = NULL, *buf = NULL;
107        struct tm *loctime = NULL;
108
109        if(filename == NULL)
110        {
111                err("epg record filename = NULL");
112                return;
113        }
114
115        epgfilename = changefilenameext(filename, ".epg");
116       
117        //check if epg is in rectimer time
118        if(rectimernode != NULL)
119        {
120                epgnode = getepgakt(chnode);
121                while(epgnode != NULL && (epgnode->starttime < rectimernode->begin || epgnode->starttime >= rectimernode->end))
122                        epgnode = epgnode->next;
123        }
124        else
125                epgnode = getepgbytime(chnode, time(NULL) + 60);
126       
127        if(epgnode != NULL)
128        {
129                fd = fopen(epgfilename, "w");
130                if(fd == NULL)
131                {
132                        perr("open %s", epgfilename);
133                        free(epgfilename);
134                        return;
135                }
136                chmod(epgfilename, 0666);
137
138                if(epgnode->title != NULL)
139                {
140                        buf = malloc(MINMALLOC);
141                        loctime = localtime(&epgnode->starttime);
142                        strftime(buf, MINMALLOC, "%d-%m-%Y %H:%M", loctime);
143                        ret += fwrite(buf, strlen(buf), 1, fd);
144                        ret += fwrite(" - ", 3, 1, fd);
145                        ret += fwrite(epgnode->title, strlen(epgnode->title), 1, fd);
146                        ret += fwrite("\n", 1, 1, fd);
147                        count += 4;
148                        free(buf); buf = NULL;
149                }
150                if(epgnode->subtitle != NULL)
151                {
152                        ret += fwrite(epgnode->subtitle, strlen(epgnode->subtitle), 1, fd);
153                        ret += fwrite("\n\n", 2, 1, fd);
154                        count += 2;
155                }
156                if(epgnode->desc != NULL)
157                {
158                        tmpstr = epgdescunzip(epgnode);
159                        if(tmpstr != NULL)
160                        {
161                                ret += fwrite(tmpstr, strlen(tmpstr), 1, fd);
162                                count++;
163                                free(tmpstr); tmpstr = NULL;
164                        }
165                }
166
167                if(ret != count)
168                {
169                        err("writting record epg file ret=%d, count=%d", ret, count);
170                }
171
172                fclose(fd);
173        }
174        free(epgfilename);
175}
176
177void createrecthumblastthread(struct stimerthread* self, char* dname, char* filename)
178{
179        if(status.mediadbthread != NULL || self == NULL) return;
180
181        debug(777, "createrecthumbfirst thread (record thumb) start");
182
183        status.mediadbthreadstatus = 1;
184        status.mediadbthread = self;
185        status.mediadbsavetime = 1;
186
187        if(dname != NULL && filename != NULL)
188        {
189                readmediadb(getconfig("mediadbfile", NULL), 0, 0);
190
191                debug(133, "path: %s",dname);
192                debug(133, "file: %s",filename);
193                debug(133, "type: 2");
194       
195                addconfigtmp("mediadbscantimeout", "0");
196                mediadbfindfilecb(dname, filename, 0, NULL, 0);
197                delconfigtmp("mediadbscantimeout");
198        }
199
200        free(dname); dname = NULL;
201        free(filename); filename = NULL;
202        status.mediadbsavetime = 0;
203        status.mediadbthread = NULL;
204        status.mediadbthreadstatus = 0;
205
206        debug(777, "createrecthumbfirst thread (record thumb) end");
207}
208
209void createrecthumbfirstthread(struct stimerthread* self, char* dname, char* filename)
210{
211        debug(777, "createrecthumblast thread (record thumb) start");
212       
213        int count = 0;
214
215        while(count < 600)
216        {
217                sleep(1);
218                count++;
219        }
220
221        if(status.recording > 0)
222        {
223                char* cmd = NULL;
224                cmd = ostrcat("/sbin/grab -v -j 100 -r 1280:720 /tmp/screenshot_backdrop1.jpg", NULL, 0, 0);
225       
226                if(cmd != NULL)
227                        system(cmd);
228                debug(777, "cmd: %s", cmd);
229
230                free(cmd);
231        }
232
233        count = 0;
234        while(count < 60)
235        {
236                sleep(1);
237                count++;
238        }
239
240        if(status.recording > 0)
241        {
242                char* cmd = NULL;
243                cmd = ostrcat("/sbin/grab -v -j 100 -r 500:400 /tmp/screenshot_cover.jpg", NULL, 0, 0);
244       
245                if(cmd != NULL)
246                        system(cmd);
247                debug(777, "cmd: %s", cmd);
248
249                free(cmd);
250        }
251
252        count = 0;
253        while(count < 10)
254        {
255                sleep(1);
256                count++;
257        }
258
259        if(status.recording > 0)
260        {
261                char* cmd = NULL;
262                cmd = ostrcat("/sbin/grab -v -j 100 -r 160:120 /tmp/screenshot_thumb.jpg", NULL, 0, 0);
263       
264                if(cmd != NULL)
265                        system(cmd);
266                debug(777, "cmd: %s", cmd);
267
268                free(cmd);
269        }
270
271        debug(777, "createrecthumblast thread (record thumb) end");
272
273}
274
275void recordstop(struct service* node, int ret)
276{
277        struct stimerthread *recthumblastthread = NULL;
278        struct rectimer* rectimernode = NULL;
279        int afterevent = 1, type = -1;
280
281        if(node != NULL)
282        {
283                type = node->type;
284
285                if(node->fedev != NULL && node->type != RECORDTIMESHIFT)
286                        node->fedev->felock--;
287
288                m_lock(&status.rectimermutex, 1);
289                rectimernode = getrectimerbyservice(node);
290                if(rectimernode != NULL && node->recendtime != 2) //2 = manuall rec stop
291                        afterevent = rectimernode->afterevent;
292                m_unlock(&status.rectimermutex, 1);
293
294                char* dname = NULL, *filename = NULL;
295
296                if(type != RECORDSTREAM && type != RECORDTIMESHIFT && type != RECORDPLAY)
297                {
298                        dname = ostrcat(node->recname, NULL, 0, 0);
299                        dname = dirname(dname);
300                        filename = ostrcat(basename(node->recname), NULL, 0, 0);
301                }
302                       
303                delservice(node, 0);
304
305                if(type == RECORDSTREAM)
306                        status.streaming--;
307                else if(type == RECORDTIMESHIFT)
308                {
309                        if(ret != 0) // on error stop timeshift
310                                timeshiftstop(2);
311                        status.timeshift = 0;
312                }
313                else if(type == RECORDPLAY)
314                        status.playing = 0;
315                else
316                        status.recording--;
317       
318                deltranspondertunablestatus();
319
320                if(dname != NULL && filename != NULL && getconfigint("recordpicture", NULL) == 1)
321                        recthumblastthread = addtimer(&createrecthumblastthread, START, 1000, 1, (void*)ostrcat(dname, NULL, 0, 0), (void*)ostrcat(filename, NULL, 0, 0), NULL);
322
323                free(dname); dname = NULL;
324                free(filename); filename = NULL;
325
326                //afterevent: 0 = auto
327                //afterevent: 1 = nothing
328                //afterevent: 2 = standby
329                //afterevent: 3 = poweroff
330                if(afterevent == 0)
331                {
332                        //not needed
333                        //if(status.startmode == 1) afterevent = 2;
334                        //else
335                        if(getwaswakuptimer() == 1) afterevent = 3;
336                }
337                if(afterevent == 2 && status.standby == 0)
338                {
339                        status.standby = 2;
340                        screenstandby();
341                }
342                if(afterevent == 3)
343                {
344                        if(status.recording < 1)
345                        {
346                                //wait for recthumblastthread end before shutdown
347                                int count = 0;
348                                while(gettimer(recthumblastthread) != NULL && count < 60)
349                                {
350                                        sleep(1);
351                                        count++;
352                                }
353                                int ret = 0;
354                                if(status.standby == 0)
355                                        ret = textbox(_("Message"), _("Box recording finished poweroff in 30sec !"), _("EXIT"), getrcconfigint("rcexit", NULL), _("OK"), getrcconfigint("rcok", NULL), NULL, 0, NULL, 0, 900, 200, 30, 0);
356                                if(ret == 0 || ret == 2)
357                                        oshutdown(1, 3);
358                        }
359                }
360        }
361}
362
363//flag 0: record split
364//flag 1: play split
365int recordsplit(struct service* servicenode, int flag)
366{
367        int ret = 0;
368        char* filename = NULL;
369
370        filename = malloc(256);
371        if(filename == NULL)
372        {
373                err("no mem");
374                ret = 10;
375                servicenode->recendtime = 1;
376        }
377        else
378        {
379                if(flag == 0)
380                {
381                        fdatasync(servicenode->recdstfd);
382                        close(servicenode->recdstfd);
383                }
384                else
385                        close(servicenode->recsrcfd);
386
387                servicenode->rectotal = 0;
388                servicenode->reclastsync = 0;
389
390                if(servicenode->reccount < 2)
391                {
392                        if(strlen(servicenode->recname) > 3)
393                                servicenode->recname[strlen(servicenode->recname) - 3] = '\0';
394                }
395                else
396                {
397                        if(strlen(servicenode->recname) > 7)
398                                servicenode->recname[strlen(servicenode->recname) - 7] = '\0';
399                }
400                snprintf(filename, 255, "%s.%03d.ts", servicenode->recname, servicenode->reccount++);
401                free(servicenode->recname);
402                servicenode->recname = filename;
403
404                if(flag == 0)
405                {
406                        debug(250, "split record file - Recording to %s...", filename);
407                }
408                else
409                {
410                        debug(250, "split play file - Playing %s...", filename);
411                }
412
413                if(flag == 0)
414                        servicenode->recdstfd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
415                else
416                        servicenode->recsrcfd = open(filename, O_RDONLY | O_LARGEFILE | O_NONBLOCK);
417
418                if(flag == 0)
419                {
420                        if(servicenode->recdstfd < 0)
421                        {
422                                debug(250, "split record file - can't open recording file!");
423                                ret = 11;
424                                servicenode->recendtime = 1;
425                        }
426                        else
427                                posix_fadvise(servicenode->recdstfd, 0, 0, POSIX_FADV_RANDOM);
428                }
429                else
430                {
431                        if(servicenode->recsrcfd < 0)
432                        {
433                                debug(250, "split play file - can't open play file!");
434                                ret = 15;
435                                servicenode->recendtime = 1;
436                        }
437                }
438        }
439        return ret;
440}
441
442int readwritethread(struct stimerthread* stimer, struct service* servicenode, int flag)
443{
444        int readret = 0, writeret = 0, ret = 0, recbsize = 0, tmprecbsize = 0, i = 0, pktcount = 0, frbsize = 0, frmulti = 0, frmultiread = 0;
445        int readtimeout = -1, writetimeout = -1;
446        int recsync = 0, frcount = 0, count = 0;
447        unsigned char* buf = NULL, *tmpbuf = NULL;
448        char* retstr = NULL;
449
450        debug(250, "start read-write thread");
451
452        if(servicenode == NULL)
453        {
454                err("servicenode = NULL");
455                return 1;
456        }
457
458        recsync = getconfigint("recsync", NULL);
459        frbsize = servicenode->tssize * 3072; //aligned to 188 and 4096
460
461        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
462        {
463                recbsize = servicenode->tssize * 1024; //aligned to 188 and 4096
464                readtimeout = 5000000;
465                writetimeout = 5000000; //5 sec
466        }
467               
468        if(servicenode->type == RECORDPLAY || servicenode->type == RECORDSTREAM)
469        {
470                if(servicenode->recdstfd < 0)
471                {
472                        err("destination fd not ok")
473                        return 1;
474                }
475                if(servicenode->type == RECORDPLAY)
476                {
477                        recbsize = servicenode->tssize * 188;
478                        tmprecbsize = 188 * 188;
479                }
480                readtimeout = 5000000;
481                writetimeout = 5000000;
482                if(servicenode->type == RECORDSTREAM)
483                {
484                        recbsize = servicenode->tssize * 1024; //aligned to 188 and 4096
485                        writetimeout = 60000000 * 30; // 30min if player is in pause
486                }
487        }
488       
489#ifdef SIMULATE
490        int fd = open("simulate/record.ts", O_RDONLY | O_LARGEFILE);
491        if(fd < 0)
492        {
493                perr("open simulate/record.ts");
494                return 1;
495        }
496#endif
497
498        buf = malloc(recbsize);
499        if(buf == NULL)
500        {
501                err("no mem");
502                return 1;
503        }
504       
505        if(servicenode->type == RECORDPLAY && servicenode->tssize == 192)
506        {
507                tmpbuf = malloc(tmprecbsize);
508                if(tmpbuf == NULL)
509                {
510                        err("no mem");
511                        return 1;
512                }
513        }
514       
515        if(servicenode->recdmxstart == 0)
516        {
517                dmxstart(servicenode->dmxvideodev);
518                servicenode->recdmxstart = 1;
519        }
520#ifdef MIPSEL
521        sleep(1);
522#endif 
523        while(1)
524        {       
525#ifdef SIMULATE
526                servicenode->recsrcfd = fd;
527                readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 0);
528                usleep(1000);
529#else
530                if(servicenode->type == RECORDPLAY)
531                {
532                       
533                        if(status.playspeed != 0)
534                        {
535                                if(status.videosize.w > 720)
536                                {
537                                        frmulti = 16;
538                                        frmultiread = 8;
539                                }
540                                else
541                                {
542                                        frmulti = 8;
543                                        frmultiread = 4;
544                                }
545                                                               
546                                if(status.playspeed == -4)
547                                        frmulti = frmulti + (frmulti/2);
548                                else if(status.playspeed == -5)
549                                        frmulti = frmultiread * 4;
550                                else if(status.playspeed == -6)
551                                        frmulti = frmultiread * 8;
552                                else if(status.playspeed == 4)
553                                        frmulti = frmulti + frmultiread ;
554                                else if(status.playspeed == 5)
555                                        frmulti = frmultiread * 4;
556                                else if(status.playspeed == 6)
557                                        frmulti = frmultiread * 8;                             
558                        }                       
559                       
560                        if(frcount == 0 && (status.playspeed < 0 || status.playspeed > 3))
561                        {                               
562                                pthread_mutex_lock(&status.tsseekmutex);
563                                off64_t pos = 0;
564                                if(status.playspeed < 0)
565                                        pos = lseek64(servicenode->recsrcfd, -(frbsize * frmulti), SEEK_CUR);
566                                else if(status.playspeed == 4 || status.playspeed == 5 || status.playspeed == 6)
567                                        pos = lseek64(servicenode->recsrcfd, ((frbsize * frmulti) - ( frbsize * frmultiread )), SEEK_CUR);
568
569                                //begin of file
570                                if(pos <= 0)
571                                {
572                                        //videoclearbuffer(status.aktservice->videodev);
573                                        //audioclearbuffer(status.aktservice->audiodev);
574                                        playerpausets();
575                                        playercontinuets();
576                                        playerresetts();
577
578                                        status.playspeed = 0;
579                                        status.pause = 0;
580                                        status.play = 1;
581                                }
582                                else
583                                {
584                                        if(status.playspeed < 0)
585                                                videodiscontinuityskip(status.aktservice->videodev, -1);
586                                        else
587                                                videodiscontinuityskip(status.aktservice->videodev, 1);
588                                }
589                                pthread_mutex_unlock(&status.tsseekmutex);
590                        }
591
592                        if(frcount != 0 && status.playspeed == 0)
593                                frcount = 0;
594                       
595                        pthread_mutex_lock(&status.tsseekmutex);
596                        readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 1);
597                        if(readret <= 0 && status.timeshift > 0)
598                        {
599                                playerpausets();
600                                playercontinuets();
601                                //playerresetts();
602                                status.playspeed = 0;
603                                status.pause = 0;
604                                status.play = 1;
605                                playerseekts(servicenode, -3, 1);
606                                readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 1);
607                        }
608                        pthread_mutex_unlock(&status.tsseekmutex);                             
609               
610                        if(status.playspeed < 0 || status.playspeed > 0)
611                        {
612                                frcount += readret;
613                                if(frcount >= frbsize * frmultiread)
614                                        frcount = 0;
615                        }
616                }
617                else
618                        readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 0);
619#endif
620                if(readret > 0)
621                {
622                        if(servicenode->type == RECORDSTREAM)
623                                writeret = sockwrite(servicenode->recdstfd, buf, readret, writetimeout);
624                        else
625                        {
626                                if(servicenode->type == RECORDPLAY && servicenode->tssize == 192)
627                                {
628                                        // remove 4 bytes per paket from mts and m2ts streams
629                                        pktcount = readret / 192;
630                                        for(i = 0; i < pktcount; i++)
631                                                memcpy(tmpbuf + (i * 188), buf + (i * 192) + 4, 188);
632                                        writeret = dvbwrite(servicenode->recdstfd, tmpbuf, pktcount * 188, writetimeout);
633                                        writeret = writeret + (pktcount * 4);
634                                }
635                                else
636                                {
637                                        if(buf[0] != 0x47)
638                                        {
639                                                debug(200, "resync");
640                                                i = 1;
641                                                while(i < 188)
642                                                {
643                                                        if(buf[i] == 0x47) break;
644                                                        i++;
645                                                }
646                                                if(i < 188)
647                                                {
648                                                        memcpy(buf, buf + i, recbsize - i);
649                                                        dvbreadfd(servicenode->recsrcfd, buf, recbsize - i, i, readtimeout, 0);
650                                                }
651                                        }
652                                        writeret = dvbwrite(servicenode->recdstfd, buf, readret, writetimeout);
653                                }
654
655                                //inject first pakets slower/smaler, so demux can start and read
656                                if(servicenode->type == RECORDPLAY && count < 20)
657                                {
658                                        if(status.timeshift == 0)
659#ifdef MIPSEL
660                                                usleep(100000);
661#else
662                                                usleep(50000);
663#endif
664                                        else
665                                                count = 19;
666                                        if(count == 19)
667                                        {
668                                                recbsize = servicenode->tssize * 1024; //aligned to 188 and 4096
669                                                tmprecbsize = 188 * 1024; //aligned to 188 and 4096
670
671                                                free(buf);
672                                                buf = malloc(recbsize);
673                                                if(buf == NULL)
674                                                {
675                                                        err("no mem");
676                                                        servicenode->recendtime = 1;
677                                                }
678
679                                                if(servicenode->tssize == 192)
680                                                {
681                                                        free(tmpbuf);
682                                                        tmpbuf = malloc(tmprecbsize);
683                                                        if(tmpbuf == NULL)
684                                                        {
685                                                                err("no mem");
686                                                                servicenode->recendtime = 1;
687                                                        }
688                                                }
689                                        }
690                                        count++;
691                                }
692                        }
693
694                        if(writeret < 1)
695                        {
696                                ret = 9;
697                                if(writeret == -ENOSPC) ret = 17;
698                                servicenode->recendtime = 1;
699                        }
700                        else if(readret != writeret)
701                        {
702                                debug(250, "not all data written read=%d, written=%d", readret, writeret);
703                        }
704
705                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
706                        {
707                                //sync
708                                if(recsync == 1)
709                                {
710                                        servicenode->reclastsync += writeret;
711                                        if(servicenode->reclastsync > 524288)
712                                        {
713                                                fdatasync(servicenode->recdstfd);
714                                                posix_fadvise64(servicenode->recdstfd, 0, 0, POSIX_FADV_DONTNEED);
715                                                servicenode->reclastsync = 0;
716                                        }
717                                }
718
719                                if(status.recsplitsize && servicenode->type != RECORDTIMESHIFT)
720                                {
721                                        servicenode->rectotal += writeret;
722                                        if(servicenode->rectotal > status.recsplitsize)
723                                                ret = recordsplit(servicenode, 0);
724                                }
725                        }
726                }
727                else if(readret <= 0)
728                {
729                        if(readret == 0 && servicenode->type == RECORDPLAY)
730                        {
731                                if(getconfigint("playsplitfiles", NULL) == 1)
732                                        ret = recordsplit(servicenode, 1);
733                                else
734                                {
735                                        ret = 15;
736                                        servicenode->recendtime = 1;
737                                }
738                        }
739                        else
740                        {
741                                ret = 15;
742                                servicenode->recendtime = 1;
743                        }
744
745                        if(readret < -1)
746                                perr("read");
747                }
748
749                if(servicenode->recendtime != 0 && servicenode->recendtime < time(NULL))
750                {
751                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
752                                fdatasync(servicenode->recdstfd);
753                        if(ret != 0) // error
754                        {
755                                if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
756                                        addtimer(&recordcheckret, START, 1000, 1, (void*)ret, (void*)3, NULL);
757                                retstr = recordcheckret(NULL, ret, 12);
758
759                                //if(servicenode->type == RECORDSTREAM)
760                                //      sockwrite(servicenode->recdstfd, (unsigned char*)retstr, strlen(retstr), -1);
761                                if(servicenode->type == RECORDTIMER)
762                                {
763                                        m_lock(&status.rectimermutex, 1);
764                                        struct rectimer* rectimernode = getrectimerbyservice(servicenode);
765                                        if(rectimernode != NULL)
766                                        {
767                                                rectimernode->status = 3;
768                                                free(rectimernode->errstr);
769                                                rectimernode->errstr = ostrcat(retstr, NULL, 0, 0);
770                                                status.writerectimer = 1;
771                                                writerectimer(getconfig("rectimerfile", NULL), 1);
772                                        }
773                                        m_unlock(&status.rectimermutex, 1);
774                                }
775                                free(retstr); retstr = NULL;
776                        }
777                        recordstop(servicenode, ret);
778                        break;
779                }
780        }
781
782#ifdef SIMULATE
783        close(fd);
784#endif
785        if(buf != NULL) free(buf);
786        if(tmpbuf != NULL) free(tmpbuf);
787        debug(250, "stop read-write thread");
788        return 0;
789}
790
791char* recordcreatefilename(char* path, char* channelname, char* moviename, int type)
792{
793        time_t sec;
794        struct tm *loctime;
795        char *buf = NULL, *buf1 = NULL;
796        char* tmpstr = NULL;
797        int recordnamefmt = getconfigint("recordnamefmt", NULL);
798
799        if(path == NULL)
800                return NULL;
801
802        tmpstr = ostrcat(path, "/", 0, 0);
803        if(type != RECTIMESHIFT && recordnamefmt == 0)
804        {
805                if(channelname == NULL || strlen(channelname) == 0)
806                        tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
807                else
808                        tmpstr = ostrcat(tmpstr, channelname, 1, 0);
809                tmpstr = ostrcat(tmpstr, "-", 1, 0);
810        }
811
812        if(moviename == NULL || strlen(moviename) == 0)
813                tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
814        else
815                tmpstr = ostrcat(tmpstr, moviename, 1, 0);
816
817        if(type != RECTIMESHIFT && recordnamefmt == 1)
818        {
819                tmpstr = ostrcat(tmpstr, "-", 1, 0);
820                if(channelname == NULL || strlen(channelname) == 0)
821                        tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
822                else
823                        tmpstr = ostrcat(tmpstr, channelname, 1, 0);
824        }
825
826        sec = time(NULL);
827        loctime = localtime(&sec);
828
829        buf = malloc(MINMALLOC);
830        if(buf == NULL)
831        {
832                err("no memory");
833                return NULL;
834        }
835
836        strftime(buf, MINMALLOC, "%Y%m%d%H%M%S", loctime);
837        buf1 = ostrcat(buf, NULL, 1, 0);
838
839        tmpstr = ostrcat(tmpstr, "-", 1, 0);
840        tmpstr = ostrcat(tmpstr, buf1, 1, 1);
841        tmpstr = ostrcat(tmpstr, ".ts", 1, 0);
842
843        return tmpstr;
844}
845
846int recordstartreal(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode, int tssize)
847{
848        int ret = 0, fd = -1, servicetype = RECORDDIRECT, festatus = 0, pcrpidmatch = 0;
849        char* path = NULL, *chname = NULL, *filename = NULL, *moviename = NULL;
850        unsigned char* patbuf = NULL, *pmtbuf = NULL;
851        struct epg* epgnode = NULL;
852        struct service* servicenode = NULL;
853        struct dvbdev* fenode = NULL, *dmxnode = NULL;
854        struct audiotrack* atrack = NULL;
855        struct subtitle *subnode = NULL;
856        char* tmpstr = NULL;
857        struct transponder* tpnode = NULL;
858        int input = DMX_IN_FRONTEND;
859
860        if(chnode == NULL && filefd < 0)
861        {
862                ret = 8;
863                goto end;
864        }
865
866        if(filefd < 0)
867        {
868                tpnode = chnode->transponder;
869                if(tpnode == NULL)
870                {
871                        ret = 8;
872                        goto end;
873                }
874        }
875
876        switch(type)
877        {
878                case RECPLAY:
879                        servicetype = RECORDPLAY;
880                        fd = recordfd;
881                        break;
882                case RECSTREAM:
883                        servicetype = RECORDSTREAM;
884                        fd = recordfd;
885                        break;
886                case RECTIMESHIFT:
887                        servicetype = RECORDTIMESHIFT;
888                        path = getconfig("rec_timeshiftpath", NULL);
889                        moviename = "timeshift";
890                        break;
891                case RECTIMER:
892                        servicetype = RECORDTIMER;
893                        if(rectimernode != NULL && rectimernode->recpath != NULL)
894                                path = rectimernode->recpath;
895                        else
896                                path = getconfig("rec_timerpath", NULL);
897                        if(chnode != NULL)
898                        {
899                                chname = strstrip(chnode->name);
900                                delspezchar(chname, 2);
901                        }
902                        if(rectimernode != NULL && rectimernode->name != NULL)
903                        {
904                                moviename = strstrip(rectimernode->name);
905                                delspezchar(moviename, 2);
906                        }
907                        break;
908                default:
909                        servicetype = RECORDDIRECT;
910                        path = getconfig("rec_path", NULL);
911                        if(chnode != NULL)
912                        {
913                                chname = strstrip(chnode->name);
914                                delspezchar(chname, 2);
915                        }
916                        epgnode = getepgbytime(status.aktservice->channel, time(NULL) + 60);
917                        if(epgnode != NULL)
918                        {
919                                moviename = strstrip(epgnode->title);
920                                delspezchar(moviename, 2);
921                        }
922                        break;
923        }
924
925        if(type != RECSTREAM && type != RECPLAY)
926        {
927                if(!isdir(path))
928                {
929                        ret = 1;
930                        goto end;
931                }
932
933                //check HDD free space
934                //deaktivate, on my 500GB FAT32 HDD, this takes mor then 10 min
935/*
936                if(getfreespace(path) < getconfigint("recordfreespace", NULL) * 1024 * 1024)
937                {
938                        ret = 2;
939                        goto end;
940                }
941*/
942
943                filename = recordcreatefilename(path, chname, moviename, type);
944                if(filename == NULL)
945                {
946                        ret = 3;
947                        goto end;
948                }
949
950                fd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0666);
951                if(fd < 0)
952                {
953                        char* fn = strrchr(filename, '/');
954                        if(fn == NULL)
955                                delspezchar(filename, 0);
956                        else
957                                delspezchar(fn + 1, 0);
958       
959                        fd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0666);
960                        if(fd < 0)
961                        {
962                                ret = 4;
963                                goto end;
964                        }
965                }
966                posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); //turn off kernel cache
967        }
968
969        servicenode = addservice(NULL);
970        if(servicenode == NULL)
971        {
972                ret = 16;
973                goto end;
974        }
975        servicenode->tssize = tssize;
976        servicenode->recdstfd = fd;
977        servicenode->channel = chnode;
978        servicenode->transponder = tpnode;
979        if(rectimernode != NULL) servicenode->rectimestamp = ostrcat(rectimernode->timestamp, NULL, 0, 0);
980
981        if(filefd < 0)
982        {
983                //got frontend dev
984                fenode = fegetfree(tpnode, 2, NULL);
985                if(fenode == NULL)
986                {
987                        if(status.standby == 0 && type == RECSTREAM)
988                        {
989                                ret = 5;
990                                goto end;
991                        }
992                        else
993                        {
994                                if(status.standby == 0 && 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, 800, 200, 10, 0) == 1)
995                                {
996                                        ret = 14;
997                                        goto end;
998                                }
999                                else
1000                                {
1001                                        if(rectimernode != NULL)
1002                                                servicestart(chnode, rectimernode->channellist, rectimernode->pincode, 0);
1003                                        else
1004                                                servicestart(chnode, NULL, NULL, 0);
1005                                       
1006                                        if(status.standby > 0) servicestop(status.aktservice, 1, 0);   
1007                                       
1008                                        fenode = fegetfree(tpnode, 2, NULL);
1009                                        if(fenode == NULL)
1010                                        {
1011                                                ret = 5;
1012                                                goto end;
1013                                        }
1014                                }
1015                        }
1016                }
1017                if(type != RECTIMESHIFT) fenode->felock++;
1018
1019                //frontend tune
1020                if(fenode != status.aktservice->fedev || (status.standby > 0 && getconfigint("standbytuneroff", NULL) == 1))
1021                {
1022                        if(fenode->feinfo->type == FE_QPSK)
1023                        {
1024                                feset(fenode, tpnode);
1025                                fetunedvbs(fenode, tpnode);
1026                        }
1027                        else if(fenode->feinfo->type == FE_QAM)
1028                                fetunedvbc(fenode, tpnode);
1029                        else if(fenode->feinfo->type == FE_OFDM)
1030                                fetunedvbt(fenode, tpnode);
1031                        else
1032                        {
1033                                ret = 12;
1034                                if(type != RECTIMESHIFT) fenode->felock--;
1035                                goto end;
1036                        }
1037
1038                        festatus = fewait(fenode);
1039                        if(debug_level == 200) fereadstatus(fenode);
1040                        if(festatus != 0)
1041                        {
1042                                ret = 13;
1043                                if(type != RECTIMESHIFT) fenode->felock--;
1044                                goto end;
1045                        }
1046                }
1047
1048                servicenode->fedev = fenode;
1049
1050                //demux  start
1051                dmxnode = dmxopen(fenode);
1052                if(dmxnode != NULL && dmxnode->fd >= 0)
1053                {
1054                        servicenode->recsrcfd = dmxnode->fd;
1055                        if(type == RECTIMESHIFT)
1056                                dmxsetbuffersize(dmxnode, getconfigint("dmxtimeshiftbuffersize", NULL));
1057                        else if(type == RECSTREAM)
1058                                dmxsetbuffersize(dmxnode, getconfigint("dmxstreambuffersize", NULL));
1059                        else
1060                                dmxsetbuffersize(dmxnode, getconfigint("dmxrecordbuffersize", NULL));
1061                        servicenode->dmxaudiodev = dmxnode;
1062                        servicenode->dmxvideodev = dmxnode;
1063                        dmxsetsource(dmxnode, fenode->fedmxsource);
1064#if DVB_API_VERSION > 3
1065                        dmxsetpesfilter(dmxnode, 0, input, DMX_OUT_TSDEMUX_TAP, DMX_PES_OTHER, 1);
1066#else
1067                        dmxsetpesfilter(dmxnode, 0, input, DMX_OUT_TAP, 0, 1);
1068#endif
1069                        patbuf = dvbgetpat(fenode, -1);
1070                        chnode->pmtpid = dvbgetpmtpid(patbuf, chnode->serviceid);
1071
1072                        m_lock(&status.servicemutex, 2);
1073                        if(status.aktservice->channel != chnode)
1074                        {
1075                                //reset channel info
1076                                serviceresetchannelinfo(chnode);
1077                                pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, NULL, -1, 0);
1078                                dvbgetinfo(pmtbuf, chnode);
1079                        }
1080                        if(status.pmtmode == 1)
1081                        {
1082                                if(recordcheckcrypt(fenode, servicetype) == 0)
1083                                        dvbwritepmt(servicenode, pmtbuf);
1084                                else
1085                                        debug(250, "don't write pmt.tmp, another crypt channel use this frontend");
1086                        }
1087                        else
1088                                sendcapmt(servicenode, 0, 3);
1089                        m_unlock(&status.servicemutex, 2);
1090
1091                        free(pmtbuf); pmtbuf = NULL;
1092                        free(patbuf); patbuf = NULL;
1093                        if((chnode->audiopid < 1 && chnode->videopid < 1) || chnode->pmtpid < 1)
1094                        {
1095#ifndef SIMULATE
1096                                ret = 7;
1097                                if(type != RECTIMESHIFT) fenode->felock--;
1098                                goto end;
1099#endif
1100                        }
1101                        if(chnode->audiopid > 0) dmxaddpid(dmxnode, chnode->audiopid);
1102                        if(chnode->videopid > 0) dmxaddpid(dmxnode, chnode->videopid);
1103                        dmxaddpid(dmxnode, chnode->pmtpid);
1104                        //add all audiotracks
1105                        atrack = chnode->audiotrack;
1106                        while(atrack != NULL)
1107                        {
1108                                if(atrack->audiopid > 0 && atrack->audiopid != chnode->audiopid)
1109                                        dmxaddpid(dmxnode, atrack->audiopid);
1110                                if(atrack->audiopid == chnode->pcrpid) pcrpidmatch = 1;
1111                                atrack = atrack->next;
1112                        }
1113                        if(chnode->pcrpid > 0 && chnode->pcrpid != chnode->videopid && chnode->pcrpid != chnode->audiopid && pcrpidmatch == 0) dmxaddpid(dmxnode, chnode->pcrpid);
1114                       
1115                        //add all subtitle
1116                        m_lock(&status.subtitlemutex, 8);
1117                        subnode = chnode->subtitle;
1118                        while(subnode != NULL)
1119                        {
1120                                if(subnode->pid > 0)
1121                                        dmxaddpid(dmxnode, subnode->pid);
1122                                subnode = subnode->next;
1123                        }
1124                        m_unlock(&status.subtitlemutex, 8);
1125                       
1126                        //add epg pid
1127                        if(getconfigint("epg2record", NULL) == 1) dmxaddpid(dmxnode, 0x12);     
1128                }
1129                else
1130                {
1131                        ret = 6;
1132                        if(type != RECTIMESHIFT) fenode->felock--;
1133                        goto end;
1134                }
1135        }
1136
1137        if(rectimernode != NULL)
1138                rectimernode->servicenode = servicenode;
1139
1140        servicenode->recendtime = endtime;
1141        servicenode->reccount = 1;
1142        servicenode->type = servicetype;
1143
1144        if(filefd < 0)
1145                deltranspondertunablestatus();
1146        else
1147                servicenode->recsrcfd = filefd;
1148
1149        if(type == RECSTREAM)
1150        {
1151                status.streaming++;
1152                servicenode->recname = ostrcat("stream ", oitoa(recordfd), 0, 1);
1153        }
1154        else if(type == RECTIMESHIFT)
1155        {
1156                status.timeshift = 1;
1157                servicenode->recname = ostrcat(filename, NULL, 0, 0);
1158        }
1159        else if(type == RECPLAY)
1160        {
1161                status.playing = 1;
1162                servicenode->recdmxstart = 1;
1163        }
1164        else if(type == RECDIRECT || type == RECTIMER)
1165        {
1166                status.recording++;
1167                servicenode->recname = ostrcat(filename, NULL, 0, 0);
1168                if(VFD_Recordthread == NULL && getconfigint("vfdisplayrecord", NULL) != 0)
1169                        VFD_Recordthread = addtimer(&vfdrecordthread, START, 10000, 1, NULL, NULL, NULL);
1170        }
1171
1172        if(type != RECSTREAM && type != RECTIMESHIFT && type != RECPLAY)
1173                recordwriteepg(filename, chnode, rectimernode);
1174
1175        //start readwrite thread
1176        addtimer(&readwritethread, START, 1000, 1, (void*)servicenode, NULL, NULL);
1177
1178        if(type == RECTIMER && status.standby == 0)
1179        {
1180                tmpstr = ostrcat(_("Timer Record start !"), filename, 0, 0);
1181                textbox(_("Message"), tmpstr, _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, NULL, 0, 800, 200, 4, 0);
1182                free(tmpstr); tmpstr = NULL;
1183        }
1184       
1185        if(filename != NULL) debug(250, "rec filename = %s\n", filename);
1186
1187end:
1188        if(ret > 0)
1189        {
1190                delservice(servicenode, 1);
1191                if(filename != NULL) unlink(filename);
1192        }
1193        free(filename); filename = NULL;
1194        return ret;
1195}
1196
1197int recordstart(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode)
1198{
1199        return recordstartreal(chnode, filefd, recordfd, type, endtime, rectimernode, 188);
1200}
1201
1202struct service* getrecordbyname(char* recname, int type)
1203{
1204        struct service* servicenode = service;
1205
1206        if(recname == NULL)
1207        {
1208                err("NULL detect");
1209                return NULL;
1210        }
1211
1212        while(servicenode != NULL)
1213        {
1214                if((type == -1 && (servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)) || type == servicenode->type)
1215                {
1216                        if(servicenode->recname != NULL)
1217                        {
1218                                if(ostrstr(recname, servicenode->recname) != NULL)
1219                                        return servicenode;
1220                        }
1221                }
1222                servicenode = servicenode->next;
1223        }
1224
1225        return NULL;
1226}
1227
1228int screenrecordduration(int minutes, int nextmin)
1229{
1230                int rcret = 0, ret = 0;
1231                struct skin* recordduration = getscreen("recordduration");
1232                struct skin* b1 = getscreennode(recordduration, "b1");
1233                char* tmpnr = NULL;
1234
1235                if(nextmin == 0)
1236                        b1->hidden = YES;
1237                else
1238                {
1239                        if(nextmin > 9999) nextmin = 9999;
1240                        b1->hidden = NO;
1241                }
1242
1243                changemask(recordduration, "0000");
1244                if(minutes < 0) minutes = 0;
1245                if(minutes > 9999) minutes = 9999;
1246                tmpnr = malloc(5);
1247                snprintf(tmpnr, 5, "%04d", minutes);
1248                changeinput(recordduration, tmpnr);
1249                free(tmpnr); tmpnr = NULL;
1250
1251                drawscreen(recordduration, 0, 0);
1252                addscreenrc(recordduration, recordduration);
1253
1254                while(1)
1255                {
1256                        rcret = waitrc(recordduration, 0, 0);
1257                        if(nextmin > 0 && rcret == getrcconfigint("rcred", NULL))
1258                        {
1259                                changemask(recordduration, "0000");
1260                                tmpnr = malloc(5);
1261                                snprintf(tmpnr, 5, "%04d", nextmin);
1262                                changeinput(recordduration, tmpnr);
1263                                changeret(recordduration, tmpnr);
1264                                free(tmpnr); tmpnr = NULL;
1265                                drawscreen(recordduration, 0, 0);
1266                        }
1267                        if(rcret == getrcconfigint("rcexit", NULL))
1268                        {
1269                                changeret(recordduration, NULL);
1270                                break;
1271                        }
1272                        if(rcret == getrcconfigint("rcok", NULL))
1273                                break;
1274                }
1275
1276                if(recordduration->ret != NULL && ostrcmp(recordduration->ret, "0") != 0)
1277                        ret = atoi(recordduration->ret);
1278
1279                delownerrc(recordduration);
1280                clearscreen(recordduration);
1281
1282                return ret;
1283}
1284
1285void screenrecordstop()
1286{
1287        char* tmpstr = NULL;
1288        struct service* servicenode = service;
1289        struct menulist* mlist = NULL, *mbox = NULL, *tmpmbox = NULL;
1290
1291        while(servicenode != NULL)
1292        {
1293                if((servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER) && servicenode->recname != NULL)
1294                {
1295                        tmpstr = ostrcat(tmpstr, _("stop"), 1, 0);
1296                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1297                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1298                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1299                       
1300                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1301                        free(tmpstr); tmpstr = NULL;
1302                        if(tmpmbox != NULL)
1303                        {
1304                                tmpmbox->param = ostrcat(tmpmbox->param, _("stop"), 1, 0);
1305                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1306                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1307                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1308                        }
1309                }
1310                servicenode = servicenode->next;
1311        }
1312
1313        mbox = menulistbox(mlist, "recordlist", _("Record"), NULL, NULL, 0, 0);
1314       
1315        if(mbox != NULL && mbox->param != NULL && ostrstr(mbox->param, _("stop")) == mbox->param)
1316        {
1317                servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1318                if(servicenode != NULL)
1319                        servicenode->recendtime = 2;
1320                else
1321                {
1322                        servicenode = getrecordbyname(mbox->param, RECORDTIMER);
1323                        if(servicenode != NULL)
1324                                servicenode->recendtime = 2;
1325                }
1326        }
1327       
1328        freemenulist(mlist, 1); mlist = NULL;
1329}
1330
1331void screenrecorddirect()
1332{
1333        char* tmpstr = NULL, *cmd = NULL;
1334        int ret = 0, ret1 = 0, newstart = 0;
1335        struct service* servicenode = service;
1336        struct epg* epgnode = NULL;
1337        struct menulist* mlist = NULL, *mbox = NULL, *tmpmbox = NULL;
1338        struct stimerthread *recthumbfirstthread = NULL;
1339
1340        cmd = ostrcat("ls -al ", getconfig("rec_path", NULL), 0, 0);
1341        cmd = ostrcat(cmd, " >/dev/null &", 1, 0);
1342        printf("cmd: %s\n", cmd);
1343        system(cmd);
1344        free(cmd), cmd = NULL;
1345       
1346        while(servicenode != NULL)
1347        {
1348                if(servicenode->type == RECORDDIRECT && servicenode->recname != NULL)
1349                {
1350                        tmpstr = ostrcat(tmpstr, _("stop"), 1, 0);
1351                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1352                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1353                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1354                       
1355                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1356                        free(tmpstr); tmpstr = NULL;
1357                        if(tmpmbox != NULL)
1358                        {
1359                                tmpmbox->param = ostrcat(tmpmbox->param, _("stop"), 1, 0);
1360                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1361                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1362                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1363                        }
1364                       
1365                        tmpstr = ostrcat(tmpstr, _("change"), 1, 0);
1366                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1367                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1368                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1369                       
1370                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1371                        free(tmpstr); tmpstr = NULL;
1372                        if(tmpmbox != NULL)
1373                        {
1374                                tmpmbox->param = ostrcat(tmpmbox->param, _("change"), 1, 0);
1375                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1376                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1377                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1378                        }
1379                }
1380                servicenode = servicenode->next;
1381        }
1382
1383        addmenulist(&mlist, _("add recording (stop after current event)"), NULL, NULL, 0, 0);
1384        addmenulist(&mlist, _("add recording (indefinitely)"), NULL, NULL, 0, 0);
1385        addmenulist(&mlist, _("add recording (enter duration)"), NULL, NULL, 0, 0);
1386
1387        mbox = menulistbox(mlist, "recordlist", _("Record"), NULL, NULL, 0, 0);
1388       
1389        if(mbox != NULL)
1390        {
1391                if(mbox->param != NULL && ostrstr(mbox->param, _("stop")) == mbox->param)
1392                {
1393                        servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1394                        if(servicenode != NULL)
1395                                servicenode->recendtime = 2;
1396                }
1397                if(mbox->param != NULL && ostrstr(mbox->param, _("change")) == mbox->param)
1398                {
1399                        servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1400                        if(servicenode != NULL)
1401                        {
1402                                int nextmin = 0;
1403                                epgnode = getepgbytime(servicenode->channel, time(NULL));
1404                                if(epgnode != NULL) epgnode = epgnode->next;
1405                                if(epgnode != NULL) nextmin = (epgnode->endtime - time(NULL)) / 60;
1406                                if(nextmin < 0) nextmin = 0;
1407                                ret1 = (servicenode->recendtime - time(NULL)) / 60;
1408                                ret1 = screenrecordduration(ret1, nextmin);
1409                                if(ret1 > 0)
1410                                        servicenode->recendtime = time(NULL) + (ret1 * 60);
1411                        }
1412                }
1413                if(ostrcmp(mbox->name, _("add recording (stop after current event)")) == 0)
1414                {
1415                        epgnode = getepgbytime(status.aktservice->channel, time(NULL) + 60);
1416#ifndef SIMULATE
1417                        if(epgnode != NULL && epgnode->endtime > time(NULL))
1418                                ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, epgnode->endtime, NULL);
1419                        else
1420                                textbox(_("Message"), _("Can't get EPG time or EPG endtime not ok"), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, NULL, 0, 800, 200, 0, 0);
1421#else
1422                        ret = recordstart(status.aktservice->channel, -1,  0, RECDIRECT, time(NULL) + 5, NULL);
1423#endif
1424                        newstart = 1;
1425                }
1426                if(ostrcmp(mbox->name, _("add recording (indefinitely)")) == 0)
1427                {
1428                        ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, 0, NULL);
1429                        newstart = 1;
1430                }
1431                if(ostrcmp(mbox->name, _("add recording (enter duration)")) == 0)
1432                {
1433                        ret1 = screenrecordduration(0, 0);
1434
1435                        if(ret1 > 0)
1436                        {
1437                                ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, time(NULL) + (ret1 * 60), NULL);
1438                                newstart = 1;
1439                        }
1440                }
1441
1442                recordcheckret(NULL, ret, 6);
1443                if(ret == 0 && newstart == 1)
1444                {
1445                        textbox(_("Message"), _("Record started"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 7, 0);
1446                        if(getconfigint("recordpicture", NULL) == 1)
1447                                recthumbfirstthread = addtimer(&createrecthumbfirstthread, START, 1000, 1, NULL, NULL, NULL);
1448                }
1449        }
1450        freemenulist(mlist, 1); mlist = NULL;
1451}
1452
1453#endif
Note: See TracBrowser for help on using the repository browser.