source: titan/titan/record.h @ 39797

Last change on this file since 39797 was 39797, checked in by gost, 6 years ago

[titan] long press pip shows record channel

File size: 43.5 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#ifdef MIPSEL
304                if(node->encoderdev != NULL)
305                {
306                        if(node->videodev != NULL)
307                        {
308                                videostop(node->videodev, 1);
309                                videoclose(node->videodev, -1);
310                                dmxclose(node->dmxvideodev, -1);
311                        }
312                        if(node->audiodev != NULL)
313                        {
314                                audiostop(node->audiodev);
315                                audioclose(node->audiodev, -1);
316                                dmxclose(node->dmxaudiodev, -1);
317                        }
318                        encoderclose(node->encoderdev, -1);
319                }
320#endif
321                delservice(node, 0);
322
323                if(type == RECORDSTREAM)
324                        status.streaming--;
325                else if(type == RECORDTIMESHIFT)
326                {
327                        if(ret != 0) // on error stop timeshift
328                                timeshiftstop(2);
329                        status.timeshift = 0;
330                }
331                else if(type == RECORDPLAY)
332                        status.playing = 0;
333                else
334                {
335                        status.recchnode[status.recording] = NULL;
336                        status.recording--;
337                }
338       
339                deltranspondertunablestatus();
340
341                if(dname != NULL && filename != NULL && getconfigint("recordpicture", NULL) == 1)
342                        recthumblastthread = addtimer(&createrecthumblastthread, START, 1000, 1, (void*)ostrcat(dname, NULL, 0, 0), (void*)ostrcat(filename, NULL, 0, 0), NULL);
343
344                if(file_exist(getconfig("skriptafterrec", NULL)))
345                {
346                        char* cmd = NULL;
347                        cmd = ostrcat(getconfig("skriptafterrec", NULL), " \"", 0, 0);
348                        cmd = ostrcat(cmd, dname, 1, 0);
349                        cmd = ostrcat(cmd, "/", 1, 0);
350                        cmd = ostrcat(cmd, filename, 1, 0);
351                        cmd = ostrcat(cmd, "\" &", 1, 0);
352                        debug(250, "start cmd: %s", cmd);
353                        system(cmd);
354                        debug(250, "done cmd: %s", cmd);               
355                        free(cmd), cmd = NULL;
356                }
357
358                free(dname), dname = NULL;
359                free(filename), filename = NULL;
360
361                //afterevent: 0 = auto
362                //afterevent: 1 = nothing
363                //afterevent: 2 = standby
364                //afterevent: 3 = poweroff
365                if(afterevent == 0)
366                {
367                        //not needed
368                        //if(status.startmode == 1) afterevent = 2;
369                        //else
370                        if(getwaswakuptimer() == 1) afterevent = 3;
371                }
372                if(afterevent == 2 && status.standby == 0)
373                {
374                        status.standby = 2;
375                        screenstandby();
376                }
377                if(afterevent == 3)
378                {
379                        if(status.recording < 1)
380                        {
381                                //wait for recthumblastthread end before shutdown
382                                int count = 0;
383                                while(gettimer(recthumblastthread) != NULL && count < 60)
384                                {
385                                        sleep(1);
386                                        count++;
387                                }
388                                int ret = 0;
389                                if(status.standby == 0)
390                                        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);
391                                if(ret == 0 || ret == 2)
392                                        oshutdown(1, 3);
393                        }
394                }
395        }
396}
397
398//flag 0: record split
399//flag 1: play split
400int recordsplit(struct service* servicenode, int flag)
401{
402        int ret = 0;
403        char* filename = NULL;
404
405        filename = malloc(256);
406        if(filename == NULL)
407        {
408                err("no mem");
409                ret = 10;
410                servicenode->recendtime = 1;
411        }
412        else
413        {
414                if(flag == 0)
415                {
416                        fdatasync(servicenode->recdstfd);
417                        close(servicenode->recdstfd);
418                }
419                else
420                        close(servicenode->recsrcfd);
421
422                servicenode->rectotal = 0;
423                servicenode->reclastsync = 0;
424
425                if(servicenode->reccount < 2)
426                {
427                        if(strlen(servicenode->recname) > 3)
428                                servicenode->recname[strlen(servicenode->recname) - 3] = '\0';
429                }
430                else
431                {
432                        if(strlen(servicenode->recname) > 7)
433                                servicenode->recname[strlen(servicenode->recname) - 7] = '\0';
434                }
435                snprintf(filename, 255, "%s.%03d.ts", servicenode->recname, servicenode->reccount++);
436                free(servicenode->recname);
437                servicenode->recname = filename;
438
439                if(flag == 0)
440                {
441                        debug(250, "split record file - Recording to %s...", filename);
442                }
443                else
444                {
445                        debug(250, "split play file - Playing %s...", filename);
446                }
447
448                if(flag == 0)
449                        servicenode->recdstfd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
450                else
451                        servicenode->recsrcfd = open(filename, O_RDONLY | O_LARGEFILE | O_NONBLOCK);
452
453                if(flag == 0)
454                {
455                        if(servicenode->recdstfd < 0)
456                        {
457                                debug(250, "split record file - can't open recording file!");
458                                ret = 11;
459                                servicenode->recendtime = 1;
460                        }
461                        else
462                                posix_fadvise(servicenode->recdstfd, 0, 0, POSIX_FADV_RANDOM);
463                }
464                else
465                {
466                        if(servicenode->recsrcfd < 0)
467                        {
468                                debug(250, "split play file - can't open play file!");
469                                ret = 15;
470                                servicenode->recendtime = 1;
471                        }
472                }
473        }
474        return ret;
475}
476
477int readwritethread(struct stimerthread* stimer, struct service* servicenode, int flag)
478{
479        int readret = 0, writeret = 0, ret = 0, recbsize = 0, tmprecbsize = 0, i = 0, pktcount = 0, frbsize = 0, frmulti = 0, frmultiread = 0;
480        int readtimeout = -1, writetimeout = -1;
481        int recsync = 0, frcount = 0, count = 0;
482        unsigned char* buf = NULL, *tmpbuf = NULL;
483        char* retstr = NULL;
484
485        debug(250, "start read-write thread");
486
487        if(servicenode == NULL)
488        {
489                err("servicenode = NULL");
490                return 1;
491        }
492
493        recsync = getconfigint("recsync", NULL);
494        frbsize = servicenode->tssize * 3072; //aligned to 188 and 4096
495
496        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
497        {
498                recbsize = servicenode->tssize * 1024; //aligned to 188 and 4096
499                readtimeout = 7000000;
500                writetimeout = 7000000; //5 sec
501        }
502               
503        if(servicenode->type == RECORDPLAY || servicenode->type == RECORDSTREAM)
504        {
505                if(servicenode->recdstfd < 0)
506                {
507                        err("destination fd not ok")
508                        return 1;
509                }
510                if(servicenode->type == RECORDPLAY)
511                {
512                        recbsize = servicenode->tssize * 188;
513                        tmprecbsize = 188 * 188;
514                }
515                readtimeout = 7000000;
516                writetimeout = 7000000;
517                if(servicenode->type == RECORDSTREAM)
518                {
519                        recbsize = servicenode->tssize * 1024; //aligned to 188 and 4096
520                        writetimeout = 60000000 * 30; // 30min if player is in pause
521                }
522        }
523       
524#ifdef SIMULATE
525        int fd = open("simulate/record.ts", O_RDONLY | O_LARGEFILE);
526        if(fd < 0)
527        {
528                perr("open simulate/record.ts");
529                return 1;
530        }
531#endif
532
533        buf = malloc(recbsize);
534        if(buf == NULL)
535        {
536                err("no mem");
537                return 1;
538        }
539       
540        if(servicenode->type == RECORDPLAY && servicenode->tssize == 192)
541        {
542                tmpbuf = malloc(tmprecbsize);
543                if(tmpbuf == NULL)
544                {
545                        err("no mem");
546                        return 1;
547                }
548        }
549       
550        if(servicenode->recdmxstart == 0)
551        {
552                dmxstart(servicenode->dmxvideodev);
553                servicenode->recdmxstart = 1;
554        }
555        while(1)
556        {       
557#ifdef SIMULATE
558                servicenode->recsrcfd = fd;
559                readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 0);
560                usleep(1000);
561#else
562                if(servicenode->type == RECORDPLAY)
563                {
564                       
565                        if(status.playspeed != 0)
566                        {
567                                if(status.videosize.w > 720)
568                                {
569                                        frmulti = 16;
570                                        frmultiread = 8;
571                                }
572                                else
573                                {
574                                        frmulti = 8;
575                                        frmultiread = 4;
576                                }
577                                                               
578                                if(status.playspeed == -4)
579                                        frmulti = frmulti + (frmulti/2);
580                                else if(status.playspeed == -5)
581                                        frmulti = frmultiread * 4;
582                                else if(status.playspeed == -6)
583                                        frmulti = frmultiread * 8;
584                                else if(status.playspeed == 4)
585                                        frmulti = frmulti + frmultiread ;
586                                else if(status.playspeed == 5)
587                                        frmulti = frmultiread * 4;
588                                else if(status.playspeed == 6)
589                                        frmulti = frmultiread * 8;                             
590                        }                       
591                       
592                        if(frcount == 0 && (status.playspeed < 0 || status.playspeed > 3))
593                        {                               
594                                pthread_mutex_lock(&status.tsseekmutex);
595                                off64_t pos = 0;
596                                if(status.playspeed < 0)
597                                        pos = lseek64(servicenode->recsrcfd, -(frbsize * frmulti), SEEK_CUR);
598                                else if(status.playspeed == 4 || status.playspeed == 5 || status.playspeed == 6)
599                                        pos = lseek64(servicenode->recsrcfd, ((frbsize * frmulti) - ( frbsize * frmultiread )), SEEK_CUR);
600
601                                //begin of file
602                                if(pos <= 0)
603                                {
604                                        //videoclearbuffer(status.aktservice->videodev);
605                                        //audioclearbuffer(status.aktservice->audiodev);
606                                        playerpausets();
607                                        playercontinuets();
608                                        playerresetts();
609
610                                        status.playspeed = 0;
611                                        status.pause = 0;
612                                        status.play = 1;
613                                }
614                                else
615                                {
616                                        if(status.playspeed < 0)
617                                                videodiscontinuityskip(status.aktservice->videodev, -1);
618                                        else
619                                                videodiscontinuityskip(status.aktservice->videodev, 1);
620                                }
621                                pthread_mutex_unlock(&status.tsseekmutex);
622                        }
623
624                        if(frcount != 0 && status.playspeed == 0)
625                                frcount = 0;
626                       
627                        pthread_mutex_lock(&status.tsseekmutex);
628                        readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 1);
629                        if(readret <= 0 && status.timeshift > 0)
630                        {
631                                playerpausets();
632                                playercontinuets();
633                                //playerresetts();
634                                status.playspeed = 0;
635                                status.pause = 0;
636                                status.play = 1;
637                                playerseekts(servicenode, -3, 1);
638                                readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 1);
639                        }
640                        pthread_mutex_unlock(&status.tsseekmutex);                             
641               
642                        if(status.playspeed < 0 || status.playspeed > 0)
643                        {
644                                frcount += readret;
645                                if(frcount >= frbsize * frmultiread)
646                                        frcount = 0;
647                        }
648                }
649                else
650                        readret = dvbreadfd(servicenode->recsrcfd, buf, 0, recbsize, readtimeout, 0);
651#endif
652                if(readret > 0)
653                {
654                        if(servicenode->type == RECORDSTREAM)
655                        {
656//Workaround scrambled Bits
657                                if(getconfigint("stream_workaround_off", NULL) == 0)
658                                        {
659#ifdef MIPSEL
660                                                debug(251, "data len %i", readret);
661                                                if(servicenode->tssize == 188)
662                                                {
663                                                        i = 0;
664                                                        if(buf[i] != 0x47)
665                                                        {
666                                                                debug(251, "no sync byte at beginn len %i", readret);
667                                                                i = 1;
668                                                                while(i <= 188)
669                                                                {
670                                                                        if(buf[i] == 0x47)
671                                                                        {
672                                                                                 debug(251, "sync byte found at offset %i", i);
673                                                                                 break;
674                                                                        }
675                                                                        i++;
676                                                                }
677                                                        }
678                                                        if(i <= 188)
679                                                        {
680                                                                while(i < readret-4)
681                                                                {
682                                                                        if(buf[i] == 0x47)
683                                                                        {
684                                                                                buf[i+3] = buf[i+3] & 0x3f;
685                                                                                i = i + 188;
686                                                                        }
687                                                                        else
688                                                                        {
689                                                                                debug(251, "no sync byte at data len %i", readret);
690                                                                                while(i < readret-4)
691                                                                                {
692                                                                                        i = i + 1;
693                                                                                        if(buf[i] == 0x47)
694                                                                                        {
695                                                                                                debug(251, "sync byte found at offset %i", i);
696                                                                                                buf[i+3] = buf[i+3] & 0x3f;
697                                                                                                i = i + 188;
698                                                                                                break;
699                                                                                        }
700                                                                                }       
701                                                                        }
702                                                                }
703                                                        }
704                                                }
705#endif
706                                        }
707//*
708                                writeret = sockwrite(servicenode->recdstfd, buf, readret, writetimeout);
709                        }
710                        else
711                        {
712                                if(servicenode->type == RECORDPLAY && servicenode->tssize == 192)
713                                {
714                                        // remove 4 bytes per paket from mts and m2ts streams
715                                        pktcount = readret / 192;
716                                        for(i = 0; i < pktcount; i++)
717                                                memcpy(tmpbuf + (i * 188), buf + (i * 192) + 4, 188);
718                                        writeret = dvbwrite(servicenode->recdstfd, tmpbuf, pktcount * 188, writetimeout);
719                                        writeret = writeret + (pktcount * 4);
720                                }
721                                else
722                                {
723                                /*if(buf[0] != 0x47)
724                                {
725                                        debug(200, "resync");
726                                        i = 1;
727                                        while(i < 188)
728                                        {
729                                                if(buf[i] == 0x47) break;
730                                                i++;
731                                        }
732                                        if(i < 188)
733                                        {
734                                                memcpy(buf, buf + i, recbsize - i);
735                                                dvbreadfd(servicenode->recsrcfd, buf, recbsize - i, i, readtimeout, 0);
736                                        }
737                                }*/
738//Workaround scrambled Bits
739                                        if(getconfigint("rec_workaround_off", NULL) == 0)
740                                        {
741#ifndef MIPSEL
742                                                if(servicenode->type == RECORDPLAY)
743                                                {
744#endif                 
745                                                        i = 0;
746                                                        if(buf[i] != 0x47)
747                                                        {
748                                                                i = 1;
749                                                                while(i <= 188)
750                                                                {
751                                                                        if(buf[i] == 0x47) break;
752                                                                        i++;
753                                                                }
754                                                        }
755                                                        if(i <= 188)
756                                                        {
757                                                                while(i < readret-4)
758                                                                {
759                                                                        if(buf[i] == 0x47)
760                                                                        {
761                                                                                buf[i+3] = buf[i+3] & 0x3f;
762                                                                                i = i + 188;
763                                                                        }
764                                                                        else
765                                                                        {
766                                                                                while(i < readret-4)
767                                                                                {
768                                                                                        i = i + 1;
769                                                                                        if(buf[i] == 0x47)
770                                                                                        {
771                                                                                                buf[i+3] = buf[i+3] & 0x3f;
772                                                                                                i = i + 188;
773                                                                                                break;
774                                                                                        }
775                                                                                }       
776                                                                        }
777                                                                }
778                                                        }
779#ifndef MIPSEL
780                                                }                                               
781#endif
782                                        }
783//*
784                                        writeret = dvbwrite(servicenode->recdstfd, buf, readret, writetimeout);
785                                }
786
787                                //inject first pakets slower/smaler, so demux can start and read
788                                if(servicenode->type == RECORDPLAY && count < 20)
789                                {
790                                        if(status.timeshift == 0)
791                                                usleep(50000);
792                                        else
793                                                count = 19;
794                                        if(count == 19)
795                                        {
796                                                recbsize = servicenode->tssize * 1024; //aligned to 188 and 4096
797                                                tmprecbsize = 188 * 1024; //aligned to 188 and 4096
798
799                                                free(buf);
800                                                buf = malloc(recbsize);
801                                                if(buf == NULL)
802                                                {
803                                                        err("no mem");
804                                                        servicenode->recendtime = 1;
805                                                }
806
807                                                if(servicenode->tssize == 192)
808                                                {
809                                                        free(tmpbuf);
810                                                        tmpbuf = malloc(tmprecbsize);
811                                                        if(tmpbuf == NULL)
812                                                        {
813                                                                err("no mem");
814                                                                servicenode->recendtime = 1;
815                                                        }
816                                                }
817                                        }
818                                        count++;
819                                }
820                        }
821
822                        if(writeret < 1)
823                        {
824                                ret = 9;
825                                if(writeret == -ENOSPC) ret = 17;
826                                servicenode->recendtime = 1;
827                        }
828                        else if(readret != writeret)
829                        {
830                                debug(250, "not all data written read=%d, written=%d", readret, writeret);
831                        }
832
833                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
834                        {
835                                //sync
836                                if(recsync == 1)
837                                {
838                                        servicenode->reclastsync += writeret;
839                                        if(servicenode->reclastsync > 524288)
840                                        {
841                                                fdatasync(servicenode->recdstfd);
842                                                posix_fadvise64(servicenode->recdstfd, 0, 0, POSIX_FADV_DONTNEED);
843                                                servicenode->reclastsync = 0;
844                                        }
845                                }
846
847                                if(status.recsplitsize && servicenode->type != RECORDTIMESHIFT)
848                                {
849                                        servicenode->rectotal += writeret;
850                                        if(servicenode->rectotal > status.recsplitsize)
851                                                ret = recordsplit(servicenode, 0);
852                                }
853                        }
854                }
855                else if(readret <= 0)
856                {
857                        if(readret == 0 && servicenode->type == RECORDPLAY)
858                        {
859                                if(getconfigint("playsplitfiles", NULL) == 1)
860                                        ret = recordsplit(servicenode, 1);
861                                else
862                                {
863                                        ret = 15;
864                                        servicenode->recendtime = 1;
865                                }
866                        }
867                        else
868                        {
869                                ret = 15;
870                                servicenode->recendtime = 1;
871                        }
872
873                        if(readret < -1)
874                                perr("read");
875                }
876
877                if(servicenode->recendtime != 0 && servicenode->recendtime < time(NULL))
878                {
879                        if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
880                                fdatasync(servicenode->recdstfd);
881                        if(ret != 0) // error
882                        {
883                                if(servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)
884                                        addtimer(&recordcheckret, START, 1000, 1, (void*)ret, (void*)3, NULL);
885                                retstr = recordcheckret(NULL, ret, 12);
886
887                                //if(servicenode->type == RECORDSTREAM)
888                                //      sockwrite(servicenode->recdstfd, (unsigned char*)retstr, strlen(retstr), -1);
889                                if(servicenode->type == RECORDTIMER)
890                                {
891                                        m_lock(&status.rectimermutex, 1);
892                                        struct rectimer* rectimernode = getrectimerbyservice(servicenode);
893                                        if(rectimernode != NULL)
894                                        {
895                                                rectimernode->status = 3;
896                                                free(rectimernode->errstr);
897                                                rectimernode->errstr = ostrcat(retstr, NULL, 0, 0);
898                                                status.writerectimer = 1;
899                                                writerectimer(getconfig("rectimerfile", NULL), 1);
900                                        }
901                                        m_unlock(&status.rectimermutex, 1);
902                                }
903                                free(retstr); retstr = NULL;
904                        }
905                        recordstop(servicenode, ret);
906                        break;
907                }
908        }
909
910#ifdef SIMULATE
911        close(fd);
912#endif
913        if(buf != NULL) free(buf);
914        if(tmpbuf != NULL) free(tmpbuf);
915        debug(250, "stop read-write thread");
916        return 0;
917}
918
919char* recordcreatefilename(char* path, char* channelname, char* moviename, int type)
920{
921        time_t sec;
922        struct tm *loctime;
923        char *buf = NULL, *buf1 = NULL;
924        char* tmpstr = NULL;
925        int recordnamefmt = getconfigint("recordnamefmt", NULL);
926
927        if(path == NULL)
928                return NULL;
929
930        tmpstr = ostrcat(path, "/", 0, 0);
931        if(type != RECTIMESHIFT && recordnamefmt == 0)
932        {
933                tmpstr = ostrcat(tmpstr, "(", 1, 0);
934                if(channelname == NULL || strlen(channelname) == 0)
935                        tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
936                else
937                        tmpstr = ostrcat(tmpstr, channelname, 1, 0);
938                tmpstr = ostrcat(tmpstr, ") ", 1, 0);
939        }
940
941        if(moviename == NULL || strlen(moviename) == 0)
942                tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
943        else
944                tmpstr = ostrcat(tmpstr, moviename, 1, 0);
945
946        if(type != RECTIMESHIFT && recordnamefmt == 1)
947        {
948                tmpstr = ostrcat(tmpstr, " (", 1, 0);
949                if(channelname == NULL || strlen(channelname) == 0)
950                        tmpstr = ostrcat(tmpstr, "unknown", 1, 0);
951                else
952                        tmpstr = ostrcat(tmpstr, channelname, 1, 0);
953        }
954
955        sec = time(NULL);
956        loctime = localtime(&sec);
957
958        buf = malloc(MINMALLOC);
959        if(buf == NULL)
960        {
961                err("no memory");
962                return NULL;
963        }
964
965        strftime(buf, MINMALLOC, "%Y%m%d%H%M", loctime);
966        buf1 = ostrcat(buf, NULL, 1, 0);
967
968        if(type != RECTIMESHIFT && recordnamefmt == 1)
969                tmpstr = ostrcat(tmpstr, "-", 1, 0);
970        else
971                tmpstr = ostrcat(tmpstr, " (", 1, 0);   
972        tmpstr = ostrcat(tmpstr, buf1, 1, 1);
973        tmpstr = ostrcat(tmpstr, ")", 1, 0);
974        if(ostrcmp(channelname, "HDMIIN") == 0)
975                tmpstr = ostrcat(tmpstr, ".mpeg", 1, 0);
976        else
977                tmpstr = ostrcat(tmpstr, ".ts", 1, 0);
978
979        return tmpstr;
980}
981
982int recordstartreal(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode, int tssize)
983{
984        int ret = 0, fd = -1, servicetype = RECORDDIRECT, festatus = 0, pcrpidmatch = 0;
985        char* path = NULL, *chname = NULL, *filename = NULL, *moviename = NULL;
986        unsigned char* patbuf = NULL, *pmtbuf = NULL;
987        struct epg* epgnode = NULL;
988        struct service* servicenode = NULL;
989        struct dvbdev* fenode = NULL, *dmxnode = NULL;
990#ifdef MIPSEL
991        struct dvbdev* encnode = NULL, *videonode = NULL, *audionode = NULL;
992#endif
993        struct audiotrack* atrack = NULL;
994        struct subtitle *subnode = NULL;
995        char* tmpstr = NULL;
996        struct transponder* tpnode = NULL;
997        int input = DMX_IN_FRONTEND;
998
999        //wakeup hdd work
1000        if(type != RECSTREAM && type != RECSTREAMENC)
1001                wakeup_record_device();
1002
1003        if(chnode == NULL && filefd < 0)
1004        {
1005                ret = 8;
1006                goto end;
1007        }
1008
1009        //hdmi record.. serviceid=65535
1010        if(filefd < 0 && chnode->serviceid != 65535)
1011        {
1012                tpnode = chnode->transponder;
1013                if(tpnode == NULL)
1014                {
1015                        ret = 8;
1016                        goto end;
1017                }
1018        }
1019
1020        switch(type)
1021        {
1022                case RECPLAY:
1023                        servicetype = RECORDPLAY;
1024                        fd = recordfd;
1025                        break;
1026                case RECSTREAM:
1027                        servicetype = RECORDSTREAM;
1028                        fd = recordfd;
1029                        break;
1030                case RECSTREAMENC:
1031                        servicetype = RECORDSTREAM;
1032                        fd = recordfd;
1033                        break;
1034                case RECTIMESHIFT:
1035                        servicetype = RECORDTIMESHIFT;
1036                        path = getconfig("rec_timeshiftpath", NULL);
1037                        moviename = "timeshift";
1038                        break;
1039                case RECTIMER:
1040                        servicetype = RECORDTIMER;
1041                        if(rectimernode != NULL && rectimernode->recpath != NULL)
1042                                path = rectimernode->recpath;
1043                        else
1044                                path = getconfig("rec_timerpath", NULL);
1045                        if(chnode != NULL)
1046                        {
1047                                chname = strstrip(chnode->name);
1048                                delspezchar(chname, 2);
1049                        }
1050                        if(rectimernode != NULL && rectimernode->name != NULL)
1051                        {
1052                                moviename = strstrip(rectimernode->name);
1053                                delspezchar(moviename, 2);
1054                        }
1055                        break;
1056                default:
1057                        servicetype = RECORDDIRECT;
1058                        path = getconfig("rec_path", NULL);
1059                        if(chnode != NULL)
1060                        {
1061                                chname = strstrip(chnode->name);
1062                                delspezchar(chname, 2);
1063                        }
1064                        epgnode = getepgbytime(status.aktservice->channel, time(NULL) + 60);
1065                        if(epgnode != NULL)
1066                        {
1067                                moviename = strstrip(epgnode->title);
1068                                delspezchar(moviename, 2);
1069
1070                        }
1071                        break;
1072        }
1073
1074        if(type != RECSTREAM && type != RECSTREAMENC && type != RECPLAY)
1075        {
1076                if(!isdir(path))
1077                {
1078                        ret = 1;
1079                        goto end;
1080/*
1081not needed we use wakeup_record_device on recordstartreal
1082                        char *dev = NULL;
1083                        dev = getmoviedev();
1084                        if(dev == NULL)
1085                        {
1086                                ret = 1;
1087                                goto end;
1088                        }
1089                        else
1090                        {
1091                                free(dev);dev=NULL;
1092                                sleep(3);
1093                                if(!isdir(path))
1094                                {
1095                                        ret = 1;
1096                                        goto end;
1097                                }
1098                        }
1099*/
1100                }
1101
1102                //check HDD free space
1103                //deaktivate, on my 500GB FAT32 HDD, this takes mor then 10 min
1104#ifdef MIPSEL
1105                if(getfreespace(path) < getconfigint("recordfreespace", NULL) * 1024 * 1024)
1106                {
1107                        ret = 2;
1108                        goto end;
1109                }
1110#endif
1111
1112                filename = recordcreatefilename(path, chname, moviename, type);
1113                if(filename == NULL)
1114                {
1115                        ret = 3;
1116                        goto end;
1117                }
1118
1119                fd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0666);
1120                if(fd < 0)
1121                {
1122                        char* fn = strrchr(filename, '/');
1123                        if(fn == NULL)
1124                                delspezchar(filename, 0);
1125                        else
1126                                delspezchar(fn + 1, 0);
1127       
1128                        fd = open(filename, O_WRONLY | O_CREAT | O_LARGEFILE, 0666);
1129                        if(fd < 0)
1130                        {
1131                                ret = 4;
1132                                goto end;
1133                        }
1134                }
1135                posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); //turn off kernel cache
1136        }
1137
1138        servicenode = addservice(NULL);
1139        if(servicenode == NULL)
1140        {
1141                ret = 16;
1142                goto end;
1143        }
1144        servicenode->tssize = tssize;
1145        servicenode->recdstfd = fd;
1146        servicenode->channel = chnode;
1147        servicenode->transponder = tpnode;
1148        if(rectimernode != NULL) servicenode->rectimestamp = ostrcat(rectimernode->timestamp, NULL, 0, 0);
1149
1150        if(filefd < 0 && chnode->serviceid != 65535)
1151        {
1152                //got frontend dev
1153                fenode = fegetfree(tpnode, 2, NULL);
1154                if(fenode == NULL)
1155                {
1156                        if(status.standby == 0 && (type == RECSTREAM || type == RECSTREAMENC))
1157                        {
1158                                ret = 5;
1159                                goto end;
1160                        }
1161                        else
1162                        {
1163                                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)
1164                                {
1165                                        ret = 14;
1166                                        goto end;
1167                                }
1168                                else
1169                                {
1170                                        if(rectimernode != NULL)
1171                                                servicestart(chnode, rectimernode->channellist, rectimernode->pincode, 0);
1172                                        else
1173                                                servicestart(chnode, NULL, NULL, 0);
1174                                       
1175                                        if(status.standby > 0) servicestop(status.aktservice, 1, 0);   
1176                                       
1177                                        fenode = fegetfree(tpnode, 2, NULL);
1178                                        if(fenode == NULL)
1179                                        {
1180                                                ret = 5;
1181                                                goto end;
1182                                        }
1183                                }
1184                        }
1185                }
1186                if(type != RECTIMESHIFT) fenode->felock++;
1187
1188                //frontend tune
1189                if(fenode != status.aktservice->fedev || (status.standby > 0 && getconfigint("standbytuneroff", NULL) == 1))
1190                {
1191                        if(fenode->feinfo->type == FE_QPSK)
1192                        {
1193                                feset(fenode, tpnode);
1194                                fetunedvbs(fenode, tpnode);
1195                        }
1196                        else if(fenode->feinfo->type == FE_QAM)
1197                                fetunedvbc(fenode, tpnode);
1198                        else if(fenode->feinfo->type == FE_OFDM)
1199                                fetunedvbt(fenode, tpnode);
1200                        else
1201                        {
1202                                ret = 12;
1203                                if(type != RECTIMESHIFT) fenode->felock--;
1204                                goto end;
1205                        }
1206
1207                        festatus = fewait(fenode);
1208                        if(debug_level == 200) fereadstatus(fenode);
1209                        if(festatus != 0)
1210                        {
1211                                ret = 13;
1212                                if(type != RECTIMESHIFT) fenode->felock--;
1213                                goto end;
1214                        }
1215                }
1216
1217                servicenode->fedev = fenode;
1218
1219                //demux  start
1220                dmxnode = dmxopen(fenode, 1);
1221                if(dmxnode != NULL && dmxnode->fd >= 0)
1222                {
1223                        servicenode->recsrcfd = dmxnode->fd;
1224                        if(type == RECTIMESHIFT)
1225                                dmxsetbuffersize(dmxnode, getconfigint("dmxtimeshiftbuffersize", NULL));
1226                        else if(type == RECSTREAM || type == RECSTREAMENC )
1227                                dmxsetbuffersize(dmxnode, getconfigint("dmxstreambuffersize", NULL));
1228                        else
1229                                dmxsetbuffersize(dmxnode, getconfigint("dmxrecordbuffersize", NULL));
1230                        servicenode->dmxaudiodev = dmxnode;
1231                        servicenode->dmxvideodev = dmxnode;
1232                        dmxsetsource(dmxnode, fenode->fedmxsource);
1233#if DVB_API_VERSION > 3
1234                        dmxsetpesfilter(dmxnode, 0, input, DMX_OUT_TSDEMUX_TAP, DMX_PES_OTHER, 1);
1235#else
1236                        dmxsetpesfilter(dmxnode, 0, input, DMX_OUT_TAP, 0, 1);
1237#endif
1238                        patbuf = dvbgetpat(fenode, -1);
1239                        chnode->pmtpid = dvbgetpmtpid(patbuf, chnode->serviceid);
1240
1241                        m_lock(&status.servicemutex, 2);
1242                        if(status.aktservice->channel != chnode)
1243                        {
1244                                //reset channel info
1245                                serviceresetchannelinfo(chnode);
1246                                pmtbuf = dvbgetpmt(fenode, patbuf, chnode->serviceid, &chnode->pmtpid, NULL, -1, 0);
1247                                dvbgetinfo(pmtbuf, chnode);
1248                        }
1249                        if(status.pmtmode == 1)
1250                        {
1251                                if(recordcheckcrypt(fenode, servicetype) == 0)
1252                                        dvbwritepmt(servicenode, pmtbuf);
1253                                else
1254                                        debug(250, "don't write pmt.tmp, another crypt channel use this frontend");
1255                        }
1256                        else
1257                                sendcapmt(servicenode, 0, 3);
1258                        m_unlock(&status.servicemutex, 2);
1259
1260                        free(pmtbuf); pmtbuf = NULL;
1261                        free(patbuf); patbuf = NULL;
1262                        if((chnode->audiopid < 1 && chnode->videopid < 1) || chnode->pmtpid < 1)
1263                        {
1264#ifndef SIMULATE
1265                                ret = 7;
1266                                if(type != RECTIMESHIFT) fenode->felock--;
1267                                goto end;
1268#endif
1269                        }
1270#ifdef MIPSEL
1271                        if(type == RECSTREAMENC)
1272                        {
1273       
1274                                dmxclose(dmxnode, -1);
1275
1276                                encnode = encoderopen(0);
1277                                servicenode->encoderdev = encnode;
1278                               
1279                                servicenode->dmxaudiodev = dmxopen(fenode, 2);
1280                                dmxsetbuffersize(servicenode->dmxaudiodev, getconfigint("dmxaudiobuffersize", NULL));
1281                                dmxsetsource(servicenode->dmxaudiodev, fenode->fedmxsource);
1282                                switch(encnode->decoder)
1283                                {
1284                                        case 2: dmxsetpesfilter(servicenode->dmxaudiodev, chnode->audiopid, -1, DMX_OUT_DECODER, DMX_PES_AUDIO2, 0); break;
1285                                        case 3: dmxsetpesfilter(servicenode->dmxaudiodev, chnode->audiopid, -1, DMX_OUT_DECODER, DMX_PES_AUDIO3, 0); break;
1286                                }
1287
1288                                audionode = audioopen(encnode->decoder);
1289                                servicenode->audiodev = audionode;
1290                                audioselectsource(servicenode->audiodev, AUDIO_SOURCE_DEMUX);
1291                                if(chnode->audiocodec != AC3)
1292                                        audiosetbypassmode(servicenode->audiodev, 1);
1293                                else
1294                                        audiosetbypassmode(servicenode->audiodev, 0);
1295                                audioplay(servicenode->audiodev);
1296                               
1297                                servicenode->dmxvideodev = dmxopen(fenode, 2);
1298                                dmxsetbuffersize(servicenode->dmxvideodev, getconfigint("dmxvideobuffersize", NULL));
1299                                dmxsetsource(servicenode->dmxvideodev, fenode->fedmxsource);
1300                               
1301                                switch(encnode->decoder)
1302                                {
1303                                        case 2: dmxsetpesfilter(servicenode->dmxvideodev, chnode->videopid, -1, DMX_OUT_DECODER, DMX_PES_VIDEO2, 0); break;
1304                                        case 3: dmxsetpesfilter(servicenode->dmxvideodev, chnode->videopid, -1, DMX_OUT_DECODER, DMX_PES_VIDEO3, 0); break;
1305                                }
1306                               
1307                                videonode = videoopen(0, encnode->decoder);
1308                                servicenode->videodev = videonode;
1309                                videoselectsource(servicenode->videodev, VIDEO_SOURCE_DEMUX);
1310                                setencoding(chnode, servicenode->videodev);
1311                                videoplay(servicenode->videodev);
1312                                 
1313                                encnode->fd = encoderopendirect(encnode->dev);
1314                                servicenode->recdmxstart = 1;
1315                                servicenode->recsrcfd = encnode->fd;
1316                        }
1317                        else
1318                        {
1319#endif
1320                                if(chnode->audiopid > 0) dmxaddpid(dmxnode, chnode->audiopid);
1321                                if(chnode->videopid > 0) dmxaddpid(dmxnode, chnode->videopid);
1322                                dmxaddpid(dmxnode, chnode->pmtpid);
1323                                //add all audiotracks
1324                                atrack = chnode->audiotrack;
1325                                while(atrack != NULL)
1326                                {
1327                                        if(atrack->audiopid > 0 && atrack->audiopid != chnode->audiopid)
1328                                                dmxaddpid(dmxnode, atrack->audiopid);
1329                                        if(atrack->audiopid == chnode->pcrpid) pcrpidmatch = 1;
1330                                        atrack = atrack->next;
1331                                }
1332                                if(chnode->pcrpid > 0 && chnode->pcrpid != chnode->videopid && chnode->pcrpid != chnode->audiopid && pcrpidmatch == 0) dmxaddpid(dmxnode, chnode->pcrpid);
1333                       
1334                                //add all subtitle
1335                                m_lock(&status.subtitlemutex, 8);
1336                                subnode = chnode->subtitle;
1337                                while(subnode != NULL)
1338                                {
1339                                        if(subnode->pid > 0)
1340                                                dmxaddpid(dmxnode, subnode->pid);
1341                                        subnode = subnode->next;
1342                                }
1343                                m_unlock(&status.subtitlemutex, 8);
1344                       
1345                                //add epg pid
1346                                if(getconfigint("epg2record", NULL) == 1) dmxaddpid(dmxnode, 0x12);     
1347#ifdef MIPSEL
1348                        }
1349#endif
1350                }
1351                else
1352                {
1353                        ret = 6;
1354                        if(type != RECTIMESHIFT) fenode->felock--;
1355                        goto end;
1356                }
1357        }
1358#ifdef MIPSEL
1359        if(filefd < 0 && chnode->serviceid == 65535)
1360        //else if(chnode->serviceid == 65535 && servicetype == RECORDDIRECT)
1361        {
1362                ret = encoderset(-1, 1, 1024*1024*8, 1280, 720, 25000, 0, 0);
1363                ret = 0;
1364                encnode = encoderopen(0);
1365                servicenode->encoderdev = encnode;
1366               
1367                videonode = videoopen(0, encnode->decoder);
1368                servicenode->videodev = videonode;
1369                videoselectsource(servicenode->videodev, VIDEO_SOURCE_HDMI);
1370                videoplay(servicenode->videodev);
1371
1372                audionode = audioopen(encnode->decoder);
1373                servicenode->audiodev = audionode;
1374                audioselectsource(servicenode->audiodev, AUDIO_SOURCE_HDMI);
1375                audioplay(servicenode->audiodev);
1376
1377                encnode->fd = encoderopendirect(encnode->dev);
1378                servicenode->recdmxstart = 1;
1379                servicenode->recsrcfd = encnode->fd;
1380        }
1381#endif
1382        if(rectimernode != NULL)
1383                rectimernode->servicenode = servicenode;
1384
1385        servicenode->recendtime = endtime;
1386        servicenode->reccount = 1;
1387        servicenode->type = servicetype;
1388
1389        if(filefd < 0)
1390                deltranspondertunablestatus();
1391        else
1392                servicenode->recsrcfd = filefd;
1393#ifdef MIPSEL
1394        if(type == RECSTREAMENC)
1395                servicenode->recsrcfd = encnode->fd;
1396#endif
1397
1398        if(type == RECSTREAM || type == RECSTREAMENC)
1399        {
1400                status.streaming++;
1401                servicenode->recname = ostrcat("stream ", oitoa(recordfd), 0, 1);
1402        }
1403        else if(type == RECTIMESHIFT)
1404        {
1405                status.timeshift = 1;
1406                servicenode->recname = ostrcat(filename, NULL, 0, 0);
1407        }
1408        else if(type == RECPLAY)
1409        {
1410                status.playing = 1;
1411                servicenode->recdmxstart = 1;
1412        }
1413        else if(type == RECDIRECT || type == RECTIMER)
1414        {
1415                status.recording++;
1416                status.recchnode[status.recording] = chnode;
1417                servicenode->recname = ostrcat(filename, NULL, 0, 0);
1418                if(VFD_Recordthread == NULL && getconfigint("vfdisplayrecord", NULL) != 0)
1419                        VFD_Recordthread = addtimer(&vfdrecordthread, START, 10000, 1, NULL, NULL, NULL);
1420#ifdef MIPSEL
1421                if(chnode->serviceid == 65535)
1422                        servicenode->recsrcfd = encnode->fd;
1423#endif
1424        }
1425
1426        if(type != RECSTREAM && type != RECSTREAMENC && type != RECTIMESHIFT && type != RECPLAY)
1427                recordwriteepg(filename, chnode, rectimernode);
1428
1429        //start readwrite thread
1430        addtimer(&readwritethread, START, 1000, 1, (void*)servicenode, NULL, NULL);
1431
1432        if(type == RECTIMER && status.standby == 0)
1433        {
1434                char* subfile = NULL;
1435                subfile = ostrstr(filename, "/movie/");
1436                if(subfile != NULL)
1437                        subfile = subfile + 7;
1438                else
1439                        subfile = filename;
1440                tmpstr = ostrcat(_("Timer Record start !"), subfile, 0, 0);
1441                textbox(_("Message"), tmpstr, _("OK"), getrcconfigint("rcok", NULL), NULL, 0, NULL, 0, NULL, 0, 900, 200, 4, 0);
1442                free(tmpstr); tmpstr = NULL;
1443        }
1444       
1445        if(filename != NULL) debug(250, "rec filename = %s\n", filename);
1446
1447end:
1448        if(ret > 0)
1449        {
1450                delservice(servicenode, 1);
1451                if(filename != NULL) unlink(filename);
1452        }
1453        free(filename); filename = NULL;
1454        return ret;
1455}
1456
1457#ifdef MIPSEL
1458int recordstartencode(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode,        int bitrate, int width, int height, int framerate, int interlaced, int aspectratio)
1459{
1460        if(type == RECSTREAMENC)
1461        {
1462                if(bitrate == 0)
1463                {
1464                        if(encodersetweb(-1, 1) != 0)
1465                                return -1;
1466                }       
1467                else if(encoderset(-1, 1, bitrate, width, height, framerate, interlaced, aspectratio) != 0)
1468                        return -1;
1469        }       
1470        return recordstartreal(chnode, filefd, recordfd, type, endtime, rectimernode, 188);
1471}
1472#endif
1473               
1474int recordstart(struct channel* chnode, int filefd, int recordfd, int type, time_t endtime, struct rectimer* rectimernode)
1475{
1476        return recordstartreal(chnode, filefd, recordfd, type, endtime, rectimernode, 188);
1477}
1478
1479struct service* getrecordbyname(char* recname, int type)
1480{
1481        struct service* servicenode = service;
1482
1483        if(recname == NULL)
1484        {
1485                err("NULL detect");
1486                return NULL;
1487        }
1488
1489        while(servicenode != NULL)
1490        {
1491                if((type == -1 && (servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER || servicenode->type == RECORDTIMESHIFT)) || type == servicenode->type)
1492                {
1493                        if(servicenode->recname != NULL)
1494                        {
1495                                if(ostrstr(recname, servicenode->recname) != NULL)
1496                                        return servicenode;
1497                        }
1498                }
1499                servicenode = servicenode->next;
1500        }
1501
1502        return NULL;
1503}
1504
1505int screenrecordduration(int minutes, int nextmin)
1506{
1507                int rcret = 0, ret = 0;
1508                struct skin* recordduration = getscreen("recordduration");
1509                struct skin* b1 = getscreennode(recordduration, "b1");
1510                char* tmpnr = NULL;
1511
1512                if(nextmin == 0)
1513                        b1->hidden = YES;
1514                else
1515                {
1516                        if(nextmin > 9999) nextmin = 9999;
1517                        b1->hidden = NO;
1518                }
1519
1520                changemask(recordduration, "0000");
1521                if(minutes < 0) minutes = 0;
1522                if(minutes > 9999) minutes = 9999;
1523                tmpnr = malloc(5);
1524                snprintf(tmpnr, 5, "%04d", minutes);
1525                changeinput(recordduration, tmpnr);
1526                free(tmpnr); tmpnr = NULL;
1527
1528                drawscreen(recordduration, 0, 0);
1529                addscreenrc(recordduration, recordduration);
1530
1531                while(1)
1532                {
1533                        rcret = waitrc(recordduration, 0, 0);
1534                        if(nextmin > 0 && rcret == getrcconfigint("rcred", NULL))
1535                        {
1536                                changemask(recordduration, "0000");
1537                                tmpnr = malloc(5);
1538                                snprintf(tmpnr, 5, "%04d", nextmin);
1539                                changeinput(recordduration, tmpnr);
1540                                changeret(recordduration, tmpnr);
1541                                free(tmpnr); tmpnr = NULL;
1542                                drawscreen(recordduration, 0, 0);
1543                        }
1544                        if(rcret == getrcconfigint("rcexit", NULL))
1545                        {
1546                                changeret(recordduration, NULL);
1547                                break;
1548                        }
1549                        if(rcret == getrcconfigint("rcok", NULL))
1550                                break;
1551                }
1552
1553                if(recordduration->ret != NULL && ostrcmp(recordduration->ret, "0") != 0)
1554                        ret = atoi(recordduration->ret);
1555
1556                delownerrc(recordduration);
1557                clearscreen(recordduration);
1558
1559                return ret;
1560}
1561
1562void screenrecordstop()
1563{
1564        char* tmpstr = NULL;
1565        struct service* servicenode = service;
1566        struct menulist* mlist = NULL, *mbox = NULL, *tmpmbox = NULL;
1567
1568        while(servicenode != NULL)
1569        {
1570                if((servicenode->type == RECORDDIRECT || servicenode->type == RECORDTIMER) && servicenode->recname != NULL)
1571                {
1572                        tmpstr = ostrcat(tmpstr, _("stop"), 1, 0);
1573                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1574                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1575                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1576                       
1577                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1578                        free(tmpstr); tmpstr = NULL;
1579                        if(tmpmbox != NULL)
1580                        {
1581                                tmpmbox->param = ostrcat(tmpmbox->param, _("stop"), 1, 0);
1582                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1583                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1584                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1585                        }
1586                }
1587                servicenode = servicenode->next;
1588        }
1589
1590        mbox = menulistbox(mlist, "recordlist", _("Record"), NULL, NULL, NULL, 0, 0);
1591       
1592        if(mbox != NULL && mbox->param != NULL && ostrstr(mbox->param, _("stop")) == mbox->param)
1593        {
1594                servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1595                if(servicenode != NULL)
1596                        servicenode->recendtime = 2;
1597                else
1598                {
1599                        servicenode = getrecordbyname(mbox->param, RECORDTIMER);
1600                        if(servicenode != NULL)
1601                                servicenode->recendtime = 2;
1602                }
1603        }
1604       
1605        freemenulist(mlist, 1); mlist = NULL;
1606}
1607
1608void screenrecorddirect()
1609{
1610        char* tmpstr = NULL;
1611        int ret = 0, ret1 = 0, newstart = 0;
1612        struct service* servicenode = service;
1613        struct epg* epgnode = NULL;
1614        struct menulist* mlist = NULL, *mbox = NULL, *tmpmbox = NULL;
1615        struct stimerthread *recthumbfirstthread = NULL;
1616
1617        while(servicenode != NULL)
1618        {
1619                if(servicenode->type == RECORDDIRECT && servicenode->recname != NULL)
1620                {
1621                        tmpstr = ostrcat(tmpstr, _("stop"), 1, 0);
1622                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1623                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1624                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1625                       
1626                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1627                        free(tmpstr); tmpstr = NULL;
1628                        if(tmpmbox != NULL)
1629                        {
1630                                tmpmbox->param = ostrcat(tmpmbox->param, _("stop"), 1, 0);
1631                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1632                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1633                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1634                        }
1635                       
1636                        tmpstr = ostrcat(tmpstr, _("change"), 1, 0);
1637                        tmpstr = ostrcat(tmpstr, " (", 1, 0);
1638                        tmpstr = ostrcat(tmpstr, servicenode->recname, 1, 0);
1639                        tmpstr = ostrcat(tmpstr, ")", 1, 0);
1640                       
1641                        tmpmbox = addmenulist(&mlist, tmpstr, NULL, NULL, 0, 0);
1642                        free(tmpstr); tmpstr = NULL;
1643                        if(tmpmbox != NULL)
1644                        {
1645                                tmpmbox->param = ostrcat(tmpmbox->param, _("change"), 1, 0);
1646                                tmpmbox->param = ostrcat(tmpmbox->param, " (", 1, 0);
1647                                tmpmbox->param = ostrcat(tmpmbox->param, servicenode->recname, 1, 0);
1648                                tmpmbox->param = ostrcat(tmpmbox->param, ")", 1, 0);
1649                        }
1650                }
1651                servicenode = servicenode->next;
1652        }
1653
1654                //65535 gleich HDMIIN
1655        if(status.aktservice->channel->serviceid != 65535)
1656                addmenulist(&mlist, _("add recording (stop after current event)"), NULL, NULL, 0, 0);
1657        addmenulist(&mlist, _("add recording (indefinitely)"), NULL, NULL, 0, 0);
1658        addmenulist(&mlist, _("add recording (enter duration)"), NULL, NULL, 0, 0);
1659
1660        mbox = menulistbox(mlist, "recordlist", _("Record"), NULL, NULL, NULL, 0, 0);
1661       
1662        if(mbox != NULL)
1663        {
1664                if(mbox->param != NULL && ostrstr(mbox->param, _("stop")) == mbox->param)
1665                {
1666                        servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1667                        if(servicenode != NULL)
1668                                servicenode->recendtime = 2;
1669                }
1670                if(mbox->param != NULL && ostrstr(mbox->param, _("change")) == mbox->param)
1671                {
1672                        servicenode = getrecordbyname(mbox->param, RECORDDIRECT);
1673                        if(servicenode != NULL)
1674                        {
1675                                int nextmin = 0;
1676                                epgnode = getepgbytime(servicenode->channel, time(NULL));
1677                                if(epgnode != NULL) epgnode = epgnode->next;
1678                                if(epgnode != NULL) nextmin = (epgnode->endtime - time(NULL)) / 60;
1679                                if(nextmin < 0) nextmin = 0;
1680                                ret1 = (servicenode->recendtime - time(NULL)) / 60;
1681                                ret1 = screenrecordduration(ret1, nextmin);
1682                                if(ret1 > 0)
1683                                        servicenode->recendtime = time(NULL) + (ret1 * 60);
1684                        }
1685                }
1686                if(ostrcmp(mbox->name, _("add recording (stop after current event)")) == 0)
1687                {
1688                        epgnode = getepgbytime(status.aktservice->channel, time(NULL) + 60);
1689#ifndef SIMULATE
1690                        if(epgnode != NULL && epgnode->endtime > time(NULL))
1691                                ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, epgnode->endtime, NULL);
1692                        else
1693                                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);
1694#else
1695                        ret = recordstart(status.aktservice->channel, -1,  0, RECDIRECT, time(NULL) + 5, NULL);
1696#endif
1697                        newstart = 1;
1698                }
1699                if(ostrcmp(mbox->name, _("add recording (indefinitely)")) == 0)
1700                {
1701                        ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, 0, NULL);
1702                        newstart = 1;
1703                }
1704                if(ostrcmp(mbox->name, _("add recording (enter duration)")) == 0)
1705                {
1706                        ret1 = screenrecordduration(0, 0);
1707
1708                        if(ret1 > 0)
1709                        {
1710                                ret = recordstart(status.aktservice->channel, -1, 0, RECDIRECT, time(NULL) + (ret1 * 60), NULL);
1711                                newstart = 1;
1712                        }
1713                }
1714
1715                recordcheckret(NULL, ret, 6);
1716                if(ret == 0 && newstart == 1)
1717                {
1718                        textbox(_("Message"), _("Record started"), _("OK"), getrcconfigint("rcok", NULL), NULL, 0, NULL, 0, NULL, 0, 600, 200, 7, 0);
1719                        if(getconfigint("recordpicture", NULL) == 1)
1720                                recthumbfirstthread = addtimer(&createrecthumbfirstthread, START, 1000, 1, NULL, NULL, NULL);
1721                }
1722        }
1723        freemenulist(mlist, 1); mlist = NULL;
1724}
1725
1726#endif
Note: See TracBrowser for help on using the repository browser.