source: titan/titan/record.h @ 40424

Last change on this file since 40424 was 39869, checked in by obi, 7 years ago

fix warnings

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