JoelSjogren

mythlive.c

Jun 18th, 2013
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.87 KB | None | 0 0
  1. /*
  2.  *  Copyright (C) 2013, Jon Gettler
  3.  *  http://www.mvpmc.org/
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  */
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <getopt.h>
  24. #include <inttypes.h>
  25. #include <string.h>
  26. #include <fcntl.h>
  27.  
  28. #include "cmyth/cmyth.h"
  29. #include "refmem/refmem.h"
  30.  
  31. #define TSIZE   (128*1024)
  32. static char transfer[TSIZE];
  33.  
  34. static int verbose = 0;
  35.  
  36. static struct option opts[] = {
  37.     { "channel", required_argument, 0, 'c' },
  38.     { "help", no_argument, 0, 'h' },
  39.     { "megabytes", required_argument, 0, 'm' },
  40.     { "number", required_argument, 0, 'n' },
  41.     { "random", no_argument, 0, 'r' },
  42.     { "seconds", required_argument, 0, 's' },
  43.     { "verbose", no_argument, 0, 'v' },
  44.     { 0, 0, 0, 0 }
  45. };
  46.  
  47. static void
  48. print_help(char *prog)
  49. {
  50.     printf("Usage: %s [options] <backend>\n", prog);
  51.     printf("       --channel <name>     channel to record\n");
  52.     printf("       --help               print this help\n");
  53.     printf("       --megabytes <num>    megabytes to record\n");
  54.     printf("       --number <num>       number of channels to record\n");
  55.     printf("       --random             random channel changes\n");
  56.     printf("       --seconds <num>      seconds to record\n");
  57.     printf("       --verbose            verbose output\n");
  58. }
  59.  
  60. static int
  61. livetv_capture(cmyth_recorder_t rec, char *file, int mb, int seconds)
  62. {
  63.     int fd, len;
  64.     int n = 0;
  65.     int rc = -1;
  66.     struct timeval to;
  67.     time_t end = 0;
  68.     cmyth_proginfo_t prog1, prog2;
  69.     int bytes = mb*1024*1024;
  70.     char *path;
  71.  
  72.     printf("Capturing to %s\n", file);
  73.  
  74.     prog1 = cmyth_recorder_get_cur_proginfo(rec);
  75.  
  76.     if (verbose > 3) {
  77.         path = cmyth_proginfo_pathname(prog1);
  78.         printf("  pathname %s\n", path);
  79.         ref_release(path);
  80.     }
  81.  
  82.     if (seconds > 0) {
  83.         end = time(NULL) + seconds;
  84.     }
  85.  
  86.     fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0644);
  87.  
  88.     while (1) {
  89.         if (end == 0) {
  90.             if (n < bytes) {
  91.                 break;
  92.             }
  93.         } else {
  94.             if (time(NULL) >= end) {
  95.                 break;
  96.             }
  97.         }
  98.  
  99.         len = cmyth_livetv_request_block(rec, sizeof(transfer));
  100.  
  101.         if (len < 0) {
  102.             fprintf(stderr,
  103.                 "cmyth_livetv_request_block() failed!\n");
  104.             goto out;
  105.         }
  106.  
  107.         if (len == 0) {
  108.             fprintf(stderr, "no data to read...retry\n");
  109.             continue;
  110.         }
  111.  
  112.         to.tv_sec = 5;
  113.         to.tv_usec = 0;
  114.  
  115.         if (cmyth_livetv_select(rec, &to) == 0) {
  116.             fprintf(stderr, "no data to read...abort\n");
  117.             break;
  118.         }
  119.  
  120.         len = cmyth_livetv_get_block(rec, transfer, sizeof(transfer));
  121.         write(fd, transfer, len);
  122.         n += len;
  123.     }
  124.  
  125.     rc = 0;
  126.  
  127. out:
  128.     if (fd >= 0) {
  129.         close(fd);
  130.     }
  131.  
  132.     prog2 = cmyth_recorder_get_cur_proginfo(rec);
  133.  
  134.     if (verbose > 3) {
  135.         path = cmyth_proginfo_pathname(prog2);
  136.         printf("  pathname %s\n", path);
  137.         ref_release(path);
  138.     }
  139.  
  140.     if (verbose > 2) {
  141.         char *title, *chan;
  142.  
  143.         title = cmyth_proginfo_title(prog1);
  144.         chan = cmyth_proginfo_channame(prog1);
  145.         printf("  prog started as '%s' on '%s'\n", title, chan);
  146.         ref_release(title);
  147.         ref_release(chan);
  148.  
  149.         title = cmyth_proginfo_title(prog2);
  150.         chan = cmyth_proginfo_channame(prog2);
  151.         printf("  prog ended as '%s' on '%s'\n", title, chan);
  152.         ref_release(title);
  153.         ref_release(chan);
  154.     }
  155.  
  156.     ref_release(prog1);
  157.     ref_release(prog2);
  158.  
  159.     return rc;
  160. }
  161.  
  162. static int
  163. next_channel(cmyth_recorder_t rec, cmyth_chanlist_t cl, int random)
  164. {
  165.     int rc;
  166.     cmyth_proginfo_t prog1, prog2;
  167.     char *chan1, *chan2;
  168.  
  169.     prog1 = cmyth_recorder_get_cur_proginfo(rec);
  170.  
  171.     if (random) {
  172.         cmyth_channel_t chan;
  173.         int count = cmyth_chanlist_get_count(cl);
  174.         int r = rand() % count;
  175.         char *name;
  176.  
  177.         chan = cmyth_chanlist_get_item(cl, r);
  178.         name = cmyth_channel_name(chan);
  179.  
  180.         rc = cmyth_livetv_set_channel(rec, name);
  181.  
  182.         ref_release(name);
  183.         ref_release(chan);
  184.     } else {
  185.         rc = cmyth_livetv_change_channel(rec, CHANNEL_DIRECTION_UP);
  186.     }
  187.  
  188.     prog2 = cmyth_recorder_get_cur_proginfo(rec);
  189.  
  190.     if (cmyth_proginfo_compare(prog1, prog2) == 0) {
  191.         printf("%s(): program has not changed!\n", __FUNCTION__);
  192.     }
  193.  
  194.     chan1 = cmyth_proginfo_channame(prog1);
  195.     chan2 = cmyth_proginfo_channame(prog2);
  196.  
  197.     if (strcmp(chan1, chan2) == 0) {
  198.         printf("%s(): channel has not changed!\n", __FUNCTION__);
  199.     }
  200.  
  201.     ref_release(chan1);
  202.     ref_release(chan2);
  203.     ref_release(prog1);
  204.     ref_release(prog2);
  205.  
  206.     return rc;
  207. }
  208.  
  209. static int
  210. get_livetv(cmyth_conn_t control, int channels, char *channel,
  211.        int mb, int seconds, int random)
  212. {
  213.     printf("get_livetv():\n");
  214.     cmyth_recorder_t rec;
  215.     cmyth_chain_t chain;
  216.     cmyth_proginfo_t prog;
  217.     cmyth_chanlist_t cl;
  218.     int rc = -1;
  219.     int i;
  220.     int fd = -1;
  221.  
  222.     printf("  Free recorders: %d\n", cmyth_conn_get_free_recorder_count(control));
  223.     rec = cmyth_conn_get_free_recorder(control);
  224.  
  225.     if (rec == NULL) {
  226.         printf("  Recorder rec is null\n");
  227.         return -1;
  228.     }
  229.  
  230.     cl = cmyth_recorder_get_chanlist(rec);
  231.  
  232.     if (cmyth_livetv_start(rec) != 0) {
  233.         fprintf(stderr, "cmyth_livetv_start() failed!\n");
  234.         goto out;
  235.     }
  236.  
  237.     if (channel) {
  238.         if (cmyth_livetv_set_channel(rec, channel) < 0) {
  239.             fprintf(stderr, "cmyth_livetv_set_channel() failed!\n");
  240.             goto out;
  241.         }
  242.     }
  243.  
  244.     for (i=0; i<channels; i++) {
  245.         char filename[64];
  246.  
  247.         prog = cmyth_recorder_get_cur_proginfo(rec);
  248.  
  249.         if (prog) {
  250.             char *channame = cmyth_proginfo_channame(prog);
  251.             char *name = strdup(channame);
  252.             char *p;
  253.  
  254.             while ((p=strchr(name, ' ')) != NULL) {
  255.                 *p = '_';
  256.             }
  257.  
  258.             snprintf(filename, sizeof(filename),
  259.                  "livetv_%.2d-%s.mpg", i, name);
  260.  
  261.             ref_release(channame);
  262.         } else {
  263.             snprintf(filename, sizeof(filename),
  264.                  "livetv_%.2d.mpg", i);
  265.         }
  266.  
  267.         if (livetv_capture(rec, filename, mb, seconds) < 0) {
  268.             fprintf(stderr, "livetv_capture() failed!\n");
  269.             goto out;
  270.         }
  271.  
  272.         if (i < (channels-1)) {
  273.             if (next_channel(rec, cl, random) < 0) {
  274.                 fprintf(stderr, "change channel failed!\n");
  275.                 goto out;
  276.             }
  277.         }
  278.  
  279.         ref_release(prog);
  280.     }
  281.  
  282.     if (cmyth_livetv_stop(rec) < 0) {
  283.         fprintf(stderr, "stopping live TV failed!\n");
  284.     }
  285.  
  286.     chain = cmyth_livetv_get_chain(rec);
  287.  
  288.     if (chain) {
  289.         for (i=0; i<cmyth_chain_get_count(chain); i++) {
  290.             prog = cmyth_chain_get_prog(chain, i);
  291.             if (prog) {
  292.                 char *path;
  293.  
  294.                 if (verbose > 2) {
  295.                     path = cmyth_proginfo_pathname(prog);
  296.                     printf("delete prog %s\n", path);
  297.                     ref_release(path);
  298.                 }
  299.  
  300.                 cmyth_proginfo_delete_recording(control, prog);
  301.  
  302.                 ref_release(prog);
  303.             }
  304.         }
  305.  
  306.         ref_release(chain);
  307.     }
  308.  
  309.     rc = 0;
  310.  
  311. out:
  312.     if (fd >= 0) {
  313.         close(fd);
  314.     }
  315.  
  316.     ref_release(cl);
  317.     ref_release(rec);
  318.  
  319.     return rc;
  320. }
  321.  
  322. int
  323. main(int argc, char **argv)
  324. {
  325.     int c, opt_index;
  326.     char *server;
  327.     cmyth_conn_t control;
  328.     int n = 1;
  329.     char *channel = NULL;
  330.     int mb = 32;
  331.     int seconds = 0;
  332.     int rc = 0;
  333.     int random = 0;
  334.  
  335.     while ((c=getopt_long(argc, argv, "c:hm:n:rs:v",
  336.                   opts, &opt_index)) != -1) {
  337.         switch (c) {
  338.         case 'c':
  339.             channel = strdup(optarg);
  340.             break;
  341.         case 'h':
  342.             print_help(argv[0]);
  343.             exit(0);
  344.             break;
  345.         case 'm':
  346.             mb = atoi(optarg);
  347.             break;
  348.         case 'n':
  349.             n = atoi(optarg);
  350.             break;
  351.         case 'r':
  352.             random = 1;
  353.             break;
  354.         case 's':
  355.             seconds = atoi(optarg);
  356.             break;
  357.         case 'v':
  358.             verbose++;
  359.             break;
  360.         default:
  361.             print_help(argv[0]);
  362.             exit(1);
  363.             break;
  364.         }
  365.     }
  366.  
  367.     if (optind == argc) {
  368.         fprintf(stderr, "no server given!\n");
  369.         return -1;
  370.     }
  371.  
  372.     server = argv[optind];
  373.  
  374.     if ((control=cmyth_conn_connect_ctrl(server, 6543,
  375.                          16*1024, 4096)) == NULL) {
  376.         fprintf(stderr, "connection failed!\n");
  377.         return -1;
  378.     }
  379.    
  380.     printf("Got connection:\n");
  381.     printf("  protocol version: %d\n", cmyth_conn_get_protocol_version(control));
  382.    
  383.     printf("About to get_livetv():\n");
  384.     printf("  control: %p\n", &control);
  385.     printf("  n: %d\n", n);
  386.     printf("  channel: %s\n", channel);
  387.     printf("  mb: %d\n", mb);
  388.     printf("  seconds: %d\n", seconds);
  389.     printf("  random: %d\n", random);
  390.  
  391.     int get_livetv_result = get_livetv(control, n, channel, mb, seconds, random);
  392.     if (get_livetv_result < 0) {
  393.         fprintf(stderr, "livetv failed and returned %d!\n", get_livetv_result);
  394.         rc = -1;
  395.     }
  396.  
  397.     ref_release(control);
  398.  
  399.     if (verbose > 1) {
  400.         unsigned int refs, bytes;
  401.  
  402.         ref_get_usage(&refs, &bytes);
  403.  
  404.         printf("Refmem: refs  %d\n", refs);
  405.         printf("Refmem: bytes %d\n", bytes);
  406.  
  407.         if (refs > 0) {
  408.             ref_alloc_show();
  409.         }
  410.     }
  411.  
  412.     return rc;
  413. }
Add Comment
Please, Sign In to add comment