source: titan/titan/record.h @ 14369

Last change on this file since 14369 was 14369, checked in by nit, 10 years ago

[titan] fix mts and m2ts for internal player (timeline/jump not working, must be fixed)

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