source: titan/titan/record.h @ 26927

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

[titan] fix play ts .. mipsel .. I hope

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        while(1)
521        {       
522#ifdef SIMULATE
523                servicenode->recsrcfd = fd;
524                readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 0);
525                usleep(1000);
526#else
527                if(servicenode->type == RECORDPLAY)
528                {
529                       
530                        if(status.playspeed != 0)
531                        {
532                                if(status.videosize.w > 720)
533                                {
534                                        frmulti = 16;
535                                        frmultiread = 8;
536                                }
537                                else
538                                {
539                                        frmulti = 8;
540                                        frmultiread = 4;
541                                }
542                                                               
543                                if(status.playspeed == -4)
544                                        frmulti = frmulti + (frmulti/2);
545                                else if(status.playspeed == -5)
546                                        frmulti = frmultiread * 4;
547                                else if(status.playspeed == -6)
548                                        frmulti = frmultiread * 8;
549                                else if(status.playspeed == 4)
550                                        frmulti = frmulti + frmultiread ;
551                                else if(status.playspeed == 5)
552                                        frmulti = frmultiread * 4;
553                                else if(status.playspeed == 6)
554                                        frmulti = frmultiread * 8;                             
555                        }                       
556                       
557                        if(frcount == 0 && (status.playspeed < 0 || status.playspeed > 3))
558                        {                               
559                                pthread_mutex_lock(&status.tsseekmutex);
560                                off64_t pos = 0;
561                                if(status.playspeed < 0)
562                                        pos = lseek64(servicenode->recsrcfd, -(frbsize * frmulti), SEEK_CUR);
563                                else if(status.playspeed == 4 || status.playspeed == 5 || status.playspeed == 6)
564                                        pos = lseek64(servicenode->recsrcfd, ((frbsize * frmulti) - ( frbsize * frmultiread )), SEEK_CUR);
565
566                                //begin of file
567                                if(pos <= 0)
568                                {
569                                        //videoclearbuffer(status.aktservice->videodev);
570                                        //audioclearbuffer(status.aktservice->audiodev);
571                                        playerpausets();
572                                        playercontinuets();
573                                        playerresetts();
574
575                                        status.playspeed = 0;
576                                        status.pause = 0;
577                                        status.play = 1;
578                                }
579                                else
580                                {
581                                        if(status.playspeed < 0)
582                                                videodiscontinuityskip(status.aktservice->videodev, -1);
583                                        else
584                                                videodiscontinuityskip(status.aktservice->videodev, 1);
585                                }
586                                pthread_mutex_unlock(&status.tsseekmutex);
587                        }
588
589                        if(frcount != 0 && status.playspeed == 0)
590                                frcount = 0;
591                       
592                        pthread_mutex_lock(&status.tsseekmutex);
593                        readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 1);
594                        if(readret <= 0 && status.timeshift > 0)
595                        {
596                                playerpausets();
597                                playercontinuets();
598                                //playerresetts();
599                                status.playspeed = 0;
600                                status.pause = 0;
601                                status.play = 1;
602                                playerseekts(servicenode, -3, 1);
603                                readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 1);
604                        }
605                        pthread_mutex_unlock(&status.tsseekmutex);                             
606               
607                        if(status.playspeed < 0 || status.playspeed > 0)
608                        {
609                                frcount += readret;
610                                if(frcount >= frbsize * frmultiread)
611                                        frcount = 0;
612                        }
613                }
614                else
615                        readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 0);
616#endif
617                if(readret > 0)
618                {
619                        if(servicenode->type == RECORDSTREAM)
620                                writeret = sockwrite(servicenode->recdstfd, buf, readret, writetimeout);
621                        else
622                        {
623                                if(servicenode->type == RECORDPLAY && servicenode->tssize == 192)
624                                {
625                                        // remove 4 bytes per paket from mts and m2ts streams
626                                        pktcount = readret / 192;
627                                        for(i = 0; i < pktcount; i++)
628                                                memcpy(tmpbuf + (i * 188), buf + (i * 192) + 4, 188);
629                                        writeret = dvbwrite(servicenode->recdstfd, tmpbuf, pktcount * 188, writetimeout);
630                                        writeret = writeret + (pktcount * 4);
631                                }
632                                else
633                                {
634                                        if(buf[0] != 0x47)
635                                        {
636                                                debug(200, "resync");
637                                                i = 1;
638                                                while(i < 188)
639                                                {
640                                                        if(buf[i] == 0x47) break;
641                                                        i++;
642                                                }
643                                                if(i < 188)
644                                                {
645                                                        memcpy(buf, buf + i, recbsize - i);
646                                                        dvbreadfd(servicenode->recsrcfd, buf, recbsize - i, i, readtimeout, 0);
647                                                }
648                                        }
649                                        writeret = dvbwrite(servicenode->recdstfd, buf, readret, writetimeout);
650                                }
651
652                                //inject first pakets slower/smaler, so demux can start and read
653                                if(servicenode->type == RECORDPLAY && count < 20)
654                                {
655                                        if(status.timeshift == 0)
656                                                usleep(50000);
657                                        else
658                                                count = 19;
659                                        if(count == 19)
660                                        {
661                                                recbsize = servicenode->tssize * 1024; //aligned to 188 and 4096
662                                                tmprecbsize = 188 * 1024; //aligned to 188 and 4096
663
664                                                free(buf);
665                                                buf = malloc(recbsize);
666                                                if(buf == NULL)
667                                                {
668                                                        err("no mem");
669                                                        servicenode->recendtime = 1;
670                                                }
671
672                                                if(servicenode->tssize == 192)
673                                                {
674                                                        free(tmpbuf);
675                                                        tmpbuf = malloc(tmprecbsize);
676                                                        if(tmpbuf == NULL)
677                                                        {
678                                                                err("no mem");
679                                                                servicenode->recendtime = 1;
680                                                        }
681                                                }
682                                        }
683                                        count++;
684                                }
685                        }
686
687                        if(writeret < 1)
688                        {
689                                ret = 9;
690                                if(writeret == -ENOSPC) ret = 17;
691                                servicenode->recendtime = 1;
692                        }
693                        else if(readret != writeret)
694                        {
695                                debug(250, "not all data written read=%d, written=%d", readret, writeret);
696                        }
697
698                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
699                        {
700                                //sync
701                                if(recsync == 1)
702                                {
703                                        servicenode->reclastsync += writeret;
704                                        if(servicenode->reclastsync > 524288)
705                                        {
706                                                fdatasync(servicenode->recdstfd);
707                                                posix_fadvise64(servicenode->recdstfd, 0, 0, POSIX_FADV_DONTNEED);
708                                                servicenode->reclastsync = 0;
709                                        }
710                                }
711
712                                if(status.recsplitsize && servicenode->type != RECORDTIMESHIFT)
713                                {
714                                        servicenode->rectotal += writeret;
715                                        if(servicenode->rectotal > status.recsplitsize)
716                                                ret = recordsplit(servicenode, 0);
717                                }
718                        }
719                }
720                else if(readret <= 0)
721                {
722                        if(readret == 0 && servicenode->type == RECORDPLAY)
723                        {
724                                if(getconfigint("playsplitfiles", NULL) == 1)
725                                        ret = recordsplit(servicenode, 1);
726                                else
727                                {
728                                        ret = 15;
729                                        servicenode->recendtime = 1;
730                                }
731                        }
732                        else
733                        {
734                                ret = 15;
735                                servicenode->recendtime = 1;
736                        }
737
738                        if(readret < -1)
739                                perr("read");
740                }
741
742                if(servicenode->recendtime != 0 && servicenode->recendtime < time(NULL))
743                {
744                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
745                                fdatasync(servicenode->recdstfd);
746                        if(ret != 0) // error
747                        {
748                                if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
749                                        addtimer(&recordcheckret, START, 1000, 1, (void*)ret, (void*)3, NULL);
750                                retstr = recordcheckret(NULL, ret, 12);
751
752                                //if(servicenode->type == RECORDSTREAM)
753                                //      sockwrite(servicenode->recdstfd, (unsigned char*)retstr, strlen(retstr), -1);
754                                if(servicenode->type == RECORDTIMER)
755                                {
756                                        m_lock(&status.rectimermutex, 1);
757                                        struct rectimer* rectimernode = getrectimerbyservice(servicenode);
758                                        if(rectimernode != NULL)
759                                        {
760                                                rectimernode->status = 3;
761                                                free(rectimernode->errstr);
762                                                rectimernode->errstr = ostrcat(retstr, NULL, 0, 0);
763                                                status.writerectimer = 1;
764                                                writerectimer(getconfig("rectimerfile", NULL), 1);
765                                        }
766                                        m_unlock(&status.rectimermutex, 1);
767                                }
768                                free(retstr); retstr = NULL;
769                        }
770                        recordstop(servicenode, ret);
771                        break;
772                }
773        }
774
775#ifdef SIMULATE
776        close(fd);
777#endif
778        if(buf != NULL) free(buf);
779        if(tmpbuf != NULL) free(tmpbuf);
780        debug(250, "stop read-write thread");
781        return 0;
782}
783
784char* recordcreatefilename(char* path, char* channelname, char* moviename, int type)
785{
786        time_t sec;
787        struct tm *loctime;
788        char *buf = NULL, *buf1 = NULL;
789        char* tmpstr = NULL;
790        int recordnamefmt = getconfigint("recordnamefmt", NULL);
791
792        if(path == NULL)
793                return NULL;
794
795        tmpstr = ostrcat(path, "/", 0, 0);
796        if(type != RECTIMESHIFT && recordnamefmt == 0)
797        {
798                if(channelname == NULL || strlen(channelname) == 0)
799                        tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
800                else
801                        tmpstr = ostrcat(tmpstr, channelname, 1, 0);
802                tmpstr = ostrcat(tmpstr, "-", 1, 0);
803        }
804
805        if(moviename == NULL || strlen(moviename) == 0)
806                tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
807        else
808                tmpstr = ostrcat(tmpstr, moviename, 1, 0);
809
810        if(type != RECTIMESHIFT && recordnamefmt == 1)
811        {
812                tmpstr = ostrcat(tmpstr, "-", 1, 0);
813                if(channelname == NULL || strlen(channelname) == 0)
814                        tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
815                else
816                        tmpstr = ostrcat(tmpstr, channelname, 1, 0);
817        }
818
819        sec = time(NULL);
820        loctime = localtime(&sec);
821
822        buf = malloc(MINMALLOC);
823        if(buf == NULL)
824        {
825                err("no memory");
826                return NULL;
827        }
828
829        strftime(buf, MINMALLOC, "%Y%m%d%H%M%S", loctime);
830        buf1 = ostrcat(buf, NULL, 1, 0);
831
832        tmpstr = ostrcat(tmpstr, "-", 1, 0);
833        tmpstr = ostrcat(tmpstr, buf1, 1, 1);
834        tmpstr = ostrcat(tmpstr, ".ts", 1, 0);
835
836        return tmpstr;
837}
838
839int recordstartreal(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode, int tssize)
840{
841        int ret = 0, fd = -1, servicetype = RECORDDIRECT, festatus = 0, pcrpidmatch = 0;
842        char* path = NULL, *chname = NULL, *filename = NULL, *moviename = NULL;
843        unsigned char* patbuf = NULL, *pmtbuf = NULL;
844        struct epg* epgnode = NULL;
845        struct service* servicenode = NULL;
846        struct dvbdev* fenode = NULL, *dmxnode = NULL;
847        struct audiotrack* atrack = NULL;
848        struct subtitle *subnode = NULL;
849        char* tmpstr = NULL;
850        struct transponder* tpnode = NULL;
851        int input = DMX_IN_FRONTEND;
852
853        if(chnode == NULL && filefd < 0)
854        {
855                ret = 8;
856                goto end;
857        }
858
859        if(filefd < 0)
860        {
861                tpnode = chnode->transponder;
862                if(tpnode == NULL)
863                {
864                        ret = 8;
865                        goto end;
866                }
867        }
868
869        switch(type)
870        {
871                case RECPLAY:
872                        servicetype = RECORDPLAY;
873                        fd = recordfd;
874                        break;
875                case RECSTREAM:
876                        servicetype = RECORDSTREAM;
877                        fd = recordfd;
878                        break;
879                case RECTIMESHIFT:
880                        servicetype = RECORDTIMESHIFT;
881                        path = getconfig("rec_timeshiftpath", NULL);
882                        moviename = "timeshift";
883                        break;
884                case RECTIMER:
885                        servicetype = RECORDTIMER;
886                        if(rectimernode != NULL && rectimernode->recpath != NULL)
887                                path = rectimernode->recpath;
888                        else
889                                path = getconfig("rec_timerpath", NULL);
890                        if(chnode != NULL)
891                        {
892                                chname = strstrip(chnode->name);
893                                delspezchar(chname, 2);
894                        }
895                        if(rectimernode != NULL && rectimernode->name != NULL)
896                        {
897                                moviename = strstrip(rectimernode->name);
898                                delspezchar(moviename, 2);
899                        }
900                        break;
901                default:
902                        servicetype = RECORDDIRECT;
903                        path = getconfig("rec_path", NULL);
904                        if(chnode != NULL)
905                        {
906                                chname = strstrip(chnode->name);
907                                delspezchar(chname, 2);
908                        }
909                        epgnode = getepgbytime(status.aktservice->channel, time(NULL) + 60);
910                        if(epgnode != NULL)
911                        {
912                                moviename = strstrip(epgnode->title);
913                                delspezchar(moviename, 2);
914                        }
915                        break;
916        }
917
918        if(type != RECSTREAM && type != RECPLAY)
919        {
920                if(!isdir(path))
921                {
922                        ret = 1;
923                        goto end;
924                }
925
926                //check HDD free space
927                //deaktivate, on my 500GB FAT32 HDD, this takes mor then 10 min
928/*
929                if(getfreespace(path) < getconfigint("recordfreespace", NULL) * 1024 * 1024)
930                {
931                        ret = 2;
932                        goto end;
933                }
934*/
935
936                filename = recordcreatefilename(path, chname, moviename, type);
937                if(filename == NULL)
938                {
939                        ret = 3;
940                        goto end;
941                }
942
943                fd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0666);
944                if(fd < 0)
945                {
946                        char* fn = strrchr(filename, '/');
947                        if(fn == NULL)
948                                delspezchar(filename, 0);
949                        else
950                                delspezchar(fn + 1, 0);
951       
952                        fd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0666);
953                        if(fd < 0)
954                        {
955                                ret = 4;
956                                goto end;
957                        }
958                }
959                posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); //turn off kernel cache
960        }
961
962        servicenode = addservice(NULL);
963        if(servicenode == NULL)
964        {
965                ret = 16;
966                goto end;
967        }
968        servicenode->tssize = tssize;
969        servicenode->recdstfd = fd;
970        servicenode->channel = chnode;
971        servicenode->transponder = tpnode;
972        if(rectimernode != NULL) servicenode->rectimestamp = ostrcat(rectimernode->timestamp, NULL, 0, 0);
973
974        if(filefd < 0)
975        {
976                //got frontend dev
977                fenode = fegetfree(tpnode, 2, NULL);
978                if(fenode == NULL)
979                {
980                        if(status.standby == 0 && type == RECSTREAM)
981                        {
982                                ret = 5;
983                                goto end;
984                        }
985                        else
986                        {
987                                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)
988                                {
989                                        ret = 14;
990                                        goto end;
991                                }
992                                else
993                                {
994                                        if(rectimernode != NULL)
995                                                servicestart(chnode, rectimernode->channellist, rectimernode->pincode, 0);
996                                        else
997                                                servicestart(chnode, NULL, NULL, 0);
998                                       
999                                        if(status.standby > 0) servicestop(status.aktservice, 1, 0);   
1000                                       
1001                                        fenode = fegetfree(tpnode, 2, NULL);
1002                                        if(fenode == NULL)
1003                                        {
1004                                                ret = 5;
1005                                                goto end;
1006                                        }
1007                                }
1008                        }
1009                }
1010                if(type != RECTIMESHIFT) fenode->felock++;
1011
1012                //frontend tune
1013                if(fenode != status.aktservice->fedev || (status.standby > 0 && getconfigint("standbytuneroff", NULL) == 1))
1014                {
1015                        if(fenode->feinfo->type == FE_QPSK)
1016                        {
1017                                feset(fenode, tpnode);
1018                                fetunedvbs(fenode, tpnode);
1019                        }
1020                        else if(fenode->feinfo->type == FE_QAM)
1021                                fetunedvbc(fenode, tpnode);
1022                        else if(fenode->feinfo->type == FE_OFDM)
1023                                fetunedvbt(fenode, tpnode);
1024                        else
1025                        {
1026                                ret = 12;
1027                                if(type != RECTIMESHIFT) fenode->felock--;
1028                                goto end;
1029                        }
1030
1031                        festatus = fewait(fenode);
1032                        if(debug_level == 200) fereadstatus(fenode);
1033                        if(festatus != 0)
1034                        {
1035                                ret = 13;
1036                                if(type != RECTIMESHIFT) fenode->felock--;
1037                                goto end;
1038                        }
1039                }
1040
1041                servicenode->fedev = fenode;
1042
1043                //demux  start
1044                dmxnode = dmxopen(fenode);
1045                if(dmxnode != NULL && dmxnode->fd >= 0)
1046                {
1047                        servicenode->recsrcfd = dmxnode->fd;
1048                        if(type == RECTIMESHIFT)
1049                                dmxsetbuffersize(dmxnode, getconfigint("dmxtimeshiftbuffersize", NULL));
1050                        else if(type == RECSTREAM)
1051                                dmxsetbuffersize(dmxnode, getconfigint("dmxstreambuffersize", NULL));
1052                        else
1053                                dmxsetbuffersize(dmxnode, getconfigint("dmxrecordbuffersize", NULL));
1054                        servicenode->dmxaudiodev = dmxnode;
1055                        servicenode->dmxvideodev = dmxnode;
1056                        dmxsetsource(dmxnode, fenode->fedmxsource);
1057#if DVB_API_VERSION > 3
1058                        dmxsetpesfilter(dmxnode, 0, input, DMX_OUT_TSDEMUX_TAP, DMX_PES_OTHER, 1);
1059#else
1060                        dmxsetpesfilter(dmxnode, 0, input, DMX_OUT_TAP, 0, 1);
1061#endif
1062                        patbuf = dvbgetpat(fenode, -1);
1063                        chnode->pmtpid = dvbgetpmtpid(patbuf, chnode->serviceid);
1064
1065                        m_lock(&status.servicemutex, 2);
1066                        if(status.aktservice->channel != chnode)
1067                        {
1068                                //reset channel info
1069                                serviceresetchannelinfo(chnode);
1070                                pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, NULL, -1, 0);
1071                                dvbgetinfo(pmtbuf, chnode);
1072                        }
1073                        if(status.pmtmode == 1)
1074                        {
1075                                if(recordcheckcrypt(fenode, servicetype) == 0)
1076                                        dvbwritepmt(servicenode, pmtbuf);
1077                                else
1078                                        debug(250, "don't write pmt.tmp, another crypt channel use this frontend");
1079                        }
1080                        else
1081                                sendcapmt(servicenode, 0, 3);
1082                        m_unlock(&status.servicemutex, 2);
1083
1084                        free(pmtbuf); pmtbuf = NULL;
1085                        free(patbuf); patbuf = NULL;
1086                        if((chnode->audiopid < 1 && chnode->videopid < 1) || chnode->pmtpid < 1)
1087                        {
1088#ifndef SIMULATE
1089                                ret = 7;
1090                                if(type != RECTIMESHIFT) fenode->felock--;
1091                                goto end;
1092#endif
1093                        }
1094                        if(chnode->audiopid > 0) dmxaddpid(dmxnode, chnode->audiopid);
1095                        if(chnode->videopid > 0) dmxaddpid(dmxnode, chnode->videopid);
1096                        dmxaddpid(dmxnode, chnode->pmtpid);
1097                        //add all audiotracks
1098                        atrack = chnode->audiotrack;
1099                        while(atrack != NULL)
1100                        {
1101                                if(atrack->audiopid > 0 && atrack->audiopid != chnode->audiopid)
1102                                        dmxaddpid(dmxnode, atrack->audiopid);
1103                                if(atrack->audiopid == chnode->pcrpid) pcrpidmatch = 1;
1104                                atrack = atrack->next;
1105                        }
1106                        if(chnode->pcrpid > 0 && chnode->pcrpid != chnode->videopid && chnode->pcrpid != chnode->audiopid && pcrpidmatch == 0) dmxaddpid(dmxnode, chnode->pcrpid);
1107                       
1108                        //add all subtitle
1109                        m_lock(&status.subtitlemutex, 8);
1110                        subnode = chnode->subtitle;
1111                        while(subnode != NULL)
1112                        {
1113                                if(subnode->pid > 0)
1114                                        dmxaddpid(dmxnode, subnode->pid);
1115                                subnode = subnode->next;
1116                        }
1117                        m_unlock(&status.subtitlemutex, 8);
1118                       
1119                        //add epg pid
1120                        if(getconfigint("epg2record", NULL) == 1) dmxaddpid(dmxnode, 0x12);     
1121                }
1122                else
1123                {
1124                        ret = 6;
1125                        if(type != RECTIMESHIFT) fenode->felock--;
1126                        goto end;
1127                }
1128        }
1129
1130        if(rectimernode != NULL)
1131                rectimernode->servicenode = servicenode;
1132
1133        servicenode->recendtime = endtime;
1134        servicenode->reccount = 1;
1135        servicenode->type = servicetype;
1136
1137        if(filefd < 0)
1138                deltranspondertunablestatus();
1139        else
1140                servicenode->recsrcfd = filefd;
1141
1142        if(type == RECSTREAM)
1143        {
1144                status.streaming++;
1145                servicenode->recname = ostrcat("stream ", oitoa(recordfd), 0, 1);
1146        }
1147        else if(type == RECTIMESHIFT)
1148        {
1149                status.timeshift = 1;
1150                servicenode->recname = ostrcat(filename, NULL, 0, 0);
1151        }
1152        else if(type == RECPLAY)
1153        {
1154                status.playing = 1;
1155                servicenode->recdmxstart = 1;
1156        }
1157        else if(type == RECDIRECT || type == RECTIMER)
1158        {
1159                status.recording++;
1160                servicenode->recname = ostrcat(filename, NULL, 0, 0);
1161                if(VFD_Recordthread == NULL && getconfigint("vfdisplayrecord", NULL) != 0)
1162                        VFD_Recordthread = addtimer(&vfdrecordthread, START, 10000, 1, NULL, NULL, NULL);
1163        }
1164
1165        if(type != RECSTREAM && type != RECTIMESHIFT && type != RECPLAY)
1166                recordwriteepg(filename, chnode, rectimernode);
1167
1168        //start readwrite thread
1169        addtimer(&readwritethread, START, 1000, 1, (void*)servicenode, NULL, NULL);
1170
1171        if(type == RECTIMER && status.standby == 0)
1172        {
1173                tmpstr = ostrcat(_("Timer Record start !"), filename, 0, 0);
1174                textbox(_("Message"), tmpstr, _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, NULL, 0, 800, 200, 4, 0);
1175                free(tmpstr); tmpstr = NULL;
1176        }
1177       
1178        if(filename != NULL) debug(250, "rec filename = %s\n", filename);
1179
1180end:
1181        if(ret > 0)
1182        {
1183                delservice(servicenode, 1);
1184                if(filename != NULL) unlink(filename);
1185        }
1186        free(filename); filename = NULL;
1187        return ret;
1188}
1189
1190int recordstart(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode)
1191{
1192        return recordstartreal(chnode, filefd, recordfd, type, endtime, rectimernode, 188);
1193}
1194
1195struct service* getrecordbyname(char* recname, int type)
1196{
1197        struct service* servicenode = service;
1198
1199        if(recname == NULL)
1200        {
1201                err("NULL detect");
1202                return NULL;
1203        }
1204
1205        while(servicenode != NULL)
1206        {
1207                if((type == -1 && (servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)) || type == servicenode->type)
1208                {
1209                        if(servicenode->recname != NULL)
1210                        {
1211                                if(ostrstr(recname, servicenode->recname) != NULL)
1212                                        return servicenode;
1213                        }
1214                }
1215                servicenode = servicenode->next;
1216        }
1217
1218        return NULL;
1219}
1220
1221int screenrecordduration(int minutes, int nextmin)
1222{
1223                int rcret = 0, ret = 0;
1224                struct skin* recordduration = getscreen("recordduration");
1225                struct skin* b1 = getscreennode(recordduration, "b1");
1226                char* tmpnr = NULL;
1227
1228                if(nextmin == 0)
1229                        b1->hidden = YES;
1230                else
1231                {
1232                        if(nextmin > 9999) nextmin = 9999;
1233                        b1->hidden = NO;
1234                }
1235
1236                changemask(recordduration, "0000");
1237                if(minutes < 0) minutes = 0;
1238                if(minutes > 9999) minutes = 9999;
1239                tmpnr = malloc(5);
1240                snprintf(tmpnr, 5, "%04d", minutes);
1241                changeinput(recordduration, tmpnr);
1242                free(tmpnr); tmpnr = NULL;
1243
1244                drawscreen(recordduration, 0, 0);
1245                addscreenrc(recordduration, recordduration);
1246
1247                while(1)
1248                {
1249                        rcret = waitrc(recordduration, 0, 0);
1250                        if(nextmin > 0 && rcret == getrcconfigint("rcred", NULL))
1251                        {
1252                                changemask(recordduration, "0000");
1253                                tmpnr = malloc(5);
1254                                snprintf(tmpnr, 5, "%04d", nextmin);
1255                                changeinput(recordduration, tmpnr);
1256                                changeret(recordduration, tmpnr);
1257                                free(tmpnr); tmpnr = NULL;
1258                                drawscreen(recordduration, 0, 0);
1259                        }
1260                        if(rcret == getrcconfigint("rcexit", NULL))
1261                        {
1262                                changeret(recordduration, NULL);
1263                                break;
1264                        }
1265                        if(rcret == getrcconfigint("rcok", NULL))
1266                                break;
1267                }
1268
1269                if(recordduration->ret != NULL && ostrcmp(recordduration->ret, "0") != 0)
1270                        ret = atoi(recordduration->ret);
1271
1272                delownerrc(recordduration);
1273                clearscreen(recordduration);
1274
1275                return ret;
1276}
1277
1278void screenrecordstop()
1279{
1280        char* tmpstr = NULL;
1281        struct service* servicenode = service;
1282        struct menulist* mlist = NULL, *mbox = NULL, *tmpmbox = NULL;
1283
1284        while(servicenode != NULL)
1285        {
1286                if((servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER) && servicenode->recname != NULL)
1287                {
1288                        tmpstr = ostrcat(tmpstr, _("stop"), 1, 0);
1289                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1290                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1291                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1292                       
1293                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1294                        free(tmpstr); tmpstr = NULL;
1295                        if(tmpmbox != NULL)
1296                        {
1297                                tmpmbox->param = ostrcat(tmpmbox->param, _("stop"), 1, 0);
1298                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1299                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1300                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1301                        }
1302                }
1303                servicenode = servicenode->next;
1304        }
1305
1306        mbox = menulistbox(mlist, "recordlist", _("Record"), NULL, NULL, 0, 0);
1307       
1308        if(mbox != NULL && mbox->param != NULL && ostrstr(mbox->param, _("stop")) == mbox->param)
1309        {
1310                servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1311                if(servicenode != NULL)
1312                        servicenode->recendtime = 2;
1313                else
1314                {
1315                        servicenode = getrecordbyname(mbox->param, RECORDTIMER);
1316                        if(servicenode != NULL)
1317                                servicenode->recendtime = 2;
1318                }
1319        }
1320       
1321        freemenulist(mlist, 1); mlist = NULL;
1322}
1323
1324void screenrecorddirect()
1325{
1326        char* tmpstr = NULL, *cmd = NULL;
1327        int ret = 0, ret1 = 0, newstart = 0;
1328        struct service* servicenode = service;
1329        struct epg* epgnode = NULL;
1330        struct menulist* mlist = NULL, *mbox = NULL, *tmpmbox = NULL;
1331        struct stimerthread *recthumbfirstthread = NULL;
1332
1333        cmd = ostrcat("ls -al ", getconfig("rec_path", NULL), 0, 0);
1334        cmd = ostrcat(cmd, " >/dev/null &", 1, 0);
1335        printf("cmd: %s\n", cmd);
1336        system(cmd);
1337        free(cmd), cmd = NULL;
1338       
1339        while(servicenode != NULL)
1340        {
1341                if(servicenode->type == RECORDDIRECT && servicenode->recname != NULL)
1342                {
1343                        tmpstr = ostrcat(tmpstr, _("stop"), 1, 0);
1344                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1345                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1346                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1347                       
1348                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1349                        free(tmpstr); tmpstr = NULL;
1350                        if(tmpmbox != NULL)
1351                        {
1352                                tmpmbox->param = ostrcat(tmpmbox->param, _("stop"), 1, 0);
1353                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1354                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1355                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1356                        }
1357                       
1358                        tmpstr = ostrcat(tmpstr, _("change"), 1, 0);
1359                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1360                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1361                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1362                       
1363                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1364                        free(tmpstr); tmpstr = NULL;
1365                        if(tmpmbox != NULL)
1366                        {
1367                                tmpmbox->param = ostrcat(tmpmbox->param, _("change"), 1, 0);
1368                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1369                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1370                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1371                        }
1372                }
1373                servicenode = servicenode->next;
1374        }
1375
1376        addmenulist(&mlist, _("add recording (stop after current event)"), NULL, NULL, 0, 0);
1377        addmenulist(&mlist, _("add recording (indefinitely)"), NULL, NULL, 0, 0);
1378        addmenulist(&mlist, _("add recording (enter duration)"), NULL, NULL, 0, 0);
1379
1380        mbox = menulistbox(mlist, "recordlist", _("Record"), NULL, NULL, 0, 0);
1381       
1382        if(mbox != NULL)
1383        {
1384                if(mbox->param != NULL && ostrstr(mbox->param, _("stop")) == mbox->param)
1385                {
1386                        servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1387                        if(servicenode != NULL)
1388                                servicenode->recendtime = 2;
1389                }
1390                if(mbox->param != NULL && ostrstr(mbox->param, _("change")) == mbox->param)
1391                {
1392                        servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1393                        if(servicenode != NULL)
1394                        {
1395                                int nextmin = 0;
1396                                epgnode = getepgbytime(servicenode->channel, time(NULL));
1397                                if(epgnode != NULL) epgnode = epgnode->next;
1398                                if(epgnode != NULL) nextmin = (epgnode->endtime - time(NULL)) / 60;
1399                                if(nextmin < 0) nextmin = 0;
1400                                ret1 = (servicenode->recendtime - time(NULL)) / 60;
1401                                ret1 = screenrecordduration(ret1, nextmin);
1402                                if(ret1 > 0)
1403                                        servicenode->recendtime = time(NULL) + (ret1 * 60);
1404                        }
1405                }
1406                if(ostrcmp(mbox->name, _("add recording (stop after current event)")) == 0)
1407                {
1408                        epgnode = getepgbytime(status.aktservice->channel, time(NULL) + 60);
1409#ifndef SIMULATE
1410                        if(epgnode != NULL && epgnode->endtime > time(NULL))
1411                                ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, epgnode->endtime, NULL);
1412                        else
1413                                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);
1414#else
1415                        ret = recordstart(status.aktservice->channel, -1,  0, RECDIRECT, time(NULL) + 5, NULL);
1416#endif
1417                        newstart = 1;
1418                }
1419                if(ostrcmp(mbox->name, _("add recording (indefinitely)")) == 0)
1420                {
1421                        ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, 0, NULL);
1422                        newstart = 1;
1423                }
1424                if(ostrcmp(mbox->name, _("add recording (enter duration)")) == 0)
1425                {
1426                        ret1 = screenrecordduration(0, 0);
1427
1428                        if(ret1 > 0)
1429                        {
1430                                ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, time(NULL) + (ret1 * 60), NULL);
1431                                newstart = 1;
1432                        }
1433                }
1434
1435                recordcheckret(NULL, ret, 6);
1436                if(ret == 0 && newstart == 1)
1437                {
1438                        textbox(_("Message"), _("Record started"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 7, 0);
1439                        if(getconfigint("recordpicture", NULL) == 1)
1440                                recthumbfirstthread = addtimer(&createrecthumbfirstthread, START, 1000, 1, NULL, NULL, NULL);
1441                }
1442        }
1443        freemenulist(mlist, 1); mlist = NULL;
1444}
1445
1446#endif
Note: See TracBrowser for help on using the repository browser.