1.1 --- a/gmyth-stream/server/0.2/plugins/transcoders/mencoder.py Mon Apr 30 16:04:20 2007 +0100
1.2 +++ b/gmyth-stream/server/0.2/plugins/transcoders/mencoder.py Mon Apr 30 18:16:36 2007 +0100
1.3 @@ -18,6 +18,7 @@
1.4 priority = -1
1.5 args = {}
1.6 proc = None
1.7 + gmyth = None
1.8
1.9 # only works with avi container
1.10 status = 0
1.11 @@ -38,7 +39,7 @@
1.12 self.args["sendback"] = False
1.13
1.14 # input_opt
1.15 - uri = params_first("uri", "file://-").split("://")
1.16 + uri = params_first("uri", "file:-").split(":", 1)
1.17 self.args["type"] = uri[0]
1.18 self.args["input"] = uri[1]
1.19
1.20 @@ -109,6 +110,7 @@
1.21 self._arg_append(args, "-subfps %s" % self.args["fps"])
1.22
1.23 self._arg_append(args, "-idx")
1.24 + self._arg_append(args, "-cache 500")
1.25 self._arg_append(args, self._setup_audio())
1.26 self._arg_append(args, self._setup_video())
1.27
1.28 @@ -125,6 +127,8 @@
1.29 if not os.path.exists(self.args["input"]):
1.30 raise IOError,\
1.31 "File requested does not exist: %s." % self.args["input"]
1.32 + else:
1.33 + self.args["input"] = "file://%s" % self.args["input"]
1.34
1.35 elif _type == "dvd":
1.36 self.args["input"] = "dvd://".join(self.args["input"])
1.37 @@ -134,6 +138,7 @@
1.38 # gmyth-cat -h 192.168.1.124 -p 6543 -f file.nuv
1.39 # myth://IP:PORT:type:file
1.40 self.args["gmyth-cat"] = self.args["input"].split(":")
1.41 + self.args["input"] = "-"
1.42 # _setup_filename()
1.43
1.44
1.45 @@ -175,10 +180,7 @@
1.46 # Configuring pipes
1.47 stdr, stdw = os.pipe()
1.48
1.49 - try:
1.50 - self.proc = subprocess.Popen(self.mencoder_opts, stdin=stdr, close_fds=True)
1.51 - except Exception, e:
1.52 - self.log.error("Error executing mencoder: %s" % e)
1.53 + if not self._run_mencoder(input=stdr):
1.54 return False
1.55
1.56 stdout = self._check_opened_file(stdw, _stdin)
1.57 @@ -215,14 +217,9 @@
1.58 # _start_outfile()
1.59
1.60 def _start(self, outfd):
1.61 - try:
1.62 - self.proc = subprocess.Popen(self.mencoder_opts,
1.63 - stdout=subprocess.PIPE, close_fds=True)
1.64 - except Exception, e:
1.65 - self.log.error("Error executing mencoder: %s" % e)
1.66 + if not self._run_mencoder(output=subprocess.PIPE):
1.67 return False
1.68
1.69 -
1.70 try:
1.71 while self.proc and self.proc.poll() == None:
1.72 d = self.proc.stdout.read(1024)
1.73 @@ -235,22 +232,76 @@
1.74 return True
1.75 # _start()
1.76
1.77 + def _start_myth(self, outfd):
1.78 + # gmyth-cat -h 192.168.1.124 -p 6543 -c 111
1.79 + # gmyth-cat -h 192.168.1.124 -p 6543 -f file.nuv
1.80 + # myth://IP:PORT:type:file
1.81 + host = self.args["gmyth-cat"][0]
1.82 + port = self.args["gmyth-cat"][1]
1.83 + kind = self.args["gmyth-cat"][2]
1.84 + fchan = self.args["gmyth-cat"][3]
1.85 +
1.86 + gmyth_cat = utils.which("gmyth-cat")
1.87 + opts = [gmyth_cat, "-h", host, "-p", port, "-" + kind, fchan]
1.88 + gr, gw = os.pipe()
1.89 +
1.90 + try:
1.91 + self.gmyth = subprocess.Popen(opts, stdout=subprocess.PIPE, close_fds=True)
1.92 + except Exception, e:
1.93 + self.log.error("Error executing gmyth-cat: %s" % e)
1.94 + return False
1.95 +
1.96 + if not self._run_mencoder(input=self.gmyth.stdout, output=subprocess.PIPE):
1.97 + return False
1.98 +
1.99 + try:
1.100 + while self.proc and self.proc.poll() == None:
1.101 + r, w, x = select([self.proc.stdout], [], [], 0)
1.102 + if self.proc.stdout in r:
1.103 + d = self.proc.stdout.read(4096)
1.104 + outfd.write(d)
1.105 + except Exception, e:
1.106 + self.log.error("Problems handling data: %s" % e)
1.107 + return False
1.108 +
1.109 + return True
1.110 + # _start_myth()
1.111 +
1.112 + def _run_mencoder(self, input=None, output=None):
1.113 + try:
1.114 + self.proc = subprocess.Popen(self.mencoder_opts, stdin=input,
1.115 + stdout=output, close_fds=True)
1.116 + except Exception, e:
1.117 + self.log.error("Error executing mencoder: %s" % e)
1.118 + return False
1.119 +
1.120 + return True
1.121 + # _run_mencoder()
1.122
1.123 def start(self, outfd):
1.124 cmd = " ".join(self.mencoder_opts)
1.125 self.log.debug("Mencoder: %s" % cmd)
1.126
1.127 - if self.args["outfile"] == "-":
1.128 - return self._start(outfd)
1.129 + ret = False
1.130 +
1.131 + if self.args["outfile"] == "-" and self.args["type"] in ["file", "dvd"]:
1.132 + ret = self._start(outfd)
1.133 +
1.134 + elif self.args["type"] == "myth":
1.135 + ret = self._start_myth(outfd)
1.136 +
1.137 else:
1.138 - return self._start_outfile(outfd)
1.139 + ret = self._start_outfile(outfd)
1.140 +
1.141 + self.stop()
1.142 + return ret
1.143 # start()
1.144
1.145
1.146 def stop(self):
1.147 if self.proc:
1.148 try:
1.149 - os.kill(self.proc.pid, signal.SIGTERM)
1.150 + os.kill(self.proc.pid, signal.SIGKILL)
1.151 except OSError, e:
1.152 pass
1.153
1.154 @@ -260,6 +311,20 @@
1.155 pass
1.156
1.157 self.proc = None
1.158 +
1.159 + if self.gmyth:
1.160 + try:
1.161 + os.kill(self.gmyth.pid, signal.SIGKILL)
1.162 + except OSError, e:
1.163 + pass
1.164 +
1.165 + try:
1.166 + self.gmyth.wait()
1.167 + except Exception, e:
1.168 + pass
1.169 +
1.170 + self.gmyth = None
1.171 +
1.172 # stop()
1.173
1.174 # TranscoderMencoder
2.1 --- a/gmyth/samples/gmyth_cat.c Mon Apr 30 16:04:20 2007 +0100
2.2 +++ b/gmyth/samples/gmyth_cat.c Mon Apr 30 18:16:36 2007 +0100
2.3 @@ -4,7 +4,7 @@
2.4 #endif
2.5
2.6 #include <stdio.h>
2.7 -#include <glib.h>
2.8 +#include <glib.h>
2.9
2.10 #include "gmyth_backendinfo.h"
2.11 #include "gmyth_file_transfer.h"
2.12 @@ -14,7 +14,6 @@
2.13
2.14 typedef struct {
2.15 GMythBackendInfo *b_info;
2.16 -
2.17 char* filename;
2.18 char* channel;
2.19 } cat_options_t;
2.20 @@ -50,24 +49,31 @@
2.21 gchar *filename = NULL;
2.22 gchar *channel = NULL;
2.23
2.24 - GOptionEntry entries[] =
2.25 + GOptionEntry entries[] =
2.26 {
2.27 - { "hostname", 'h', 0, G_OPTION_ARG_STRING, &host_ip, "Mythtv backend hostname or IP address", "IP_ADDRESS" },
2.28 + { "hostname", 'h', 0, G_OPTION_ARG_STRING, &host_ip, "Mythtv backend hostname or "
2.29 + "IP address", "IP_ADDRESS" },
2.30 +
2.31 { "port", 'p', 0, G_OPTION_ARG_INT, &host_port, "Mythtv backend port", "PORT" },
2.32 - { "filename", 'f', 0, G_OPTION_ARG_STRING, &filename, "Recorded file name available in the Mythtv backend", "FILE" },
2.33 +
2.34 + { "filename", 'f', 0, G_OPTION_ARG_STRING, &filename, "Recorded file name available "
2.35 + "in the Mythtv backend", "FILE" },
2.36 +
2.37 { "channel", 'c', 0, G_OPTION_ARG_STRING, &channel, "Mythtv channel number", "CHANNEL" },
2.38 +
2.39 { NULL }
2.40 };
2.41
2.42 g_return_val_if_fail (options != NULL, FALSE);
2.43
2.44 - context = g_option_context_new ("- loads a mythtv backend recorded file and prints it on the standard output\n");
2.45 + context = g_option_context_new ("- loads a mythtv backend recorded file and prints "
2.46 + "it on the standard output\n");
2.47 g_option_context_add_main_entries (context, entries, NULL);
2.48 g_option_context_parse (context, &argc, &argv, &error);
2.49 g_option_context_set_help_enabled (context, TRUE);
2.50
2.51 g_option_context_free (context);
2.52 -
2.53 +
2.54 if ((!host_ip) || (host_port == 0) ) {
2.55 g_free (host_ip);
2.56 g_free (filename);
2.57 @@ -92,35 +98,40 @@
2.58 static gboolean
2.59 _cat_recorded_file (cat_options_t *options)
2.60 {
2.61 - GByteArray *array = NULL;
2.62 + GArray *array = NULL;
2.63 GMythFileTransfer *transfer;
2.64 guint64 size = 0, total = 0;
2.65 -
2.66 +
2.67 g_return_val_if_fail (options != NULL, FALSE);
2.68 g_return_val_if_fail (options->b_info != NULL, FALSE);
2.69 g_return_val_if_fail (options->filename != NULL, FALSE);
2.70
2.71 - if (!gmyth_util_file_exists (options->b_info, options->filename)) {
2.72 + if (!gmyth_util_file_exists (options->b_info, options->filename))
2.73 + {
2.74 g_printerr ("File %s was not found in the mythtv server\n", options->filename);
2.75 return FALSE;
2.76 }
2.77
2.78 transfer = gmyth_file_transfer_new (options->b_info);
2.79 - if (!gmyth_file_transfer_open (transfer, options->filename)) {
2.80 + if (!gmyth_file_transfer_open (transfer, options->filename))
2.81 + {
2.82 g_printerr ("File %s could not be opened\n", options->filename);
2.83 return FALSE;
2.84 }
2.85
2.86 size = gmyth_file_transfer_get_filesize (transfer);
2.87 - while (total != size) {
2.88 + array = g_array_new (FALSE, TRUE, sizeof(gchar));
2.89 +
2.90 + while (total != size)
2.91 + {
2.92 GMythFileReadResult res;
2.93
2.94 - array = g_byte_array_new ();
2.95 - res = gmyth_file_transfer_read (transfer, array,
2.96 + res = gmyth_file_transfer_read (transfer, (GByteArray*)array,
2.97 (size - total) > 64000 ? 64000 : (size - total),
2.98 FALSE);
2.99 - if ((res != GMYTH_FILE_READ_OK) && (res != GMYTH_FILE_READ_EOF)) {
2.100 - g_byte_array_free (array, TRUE);
2.101 + if ((res != GMYTH_FILE_READ_OK) && (res != GMYTH_FILE_READ_EOF))
2.102 + {
2.103 + g_array_free (array, TRUE);
2.104 g_printerr ("Error while reading the file: aborting!!\n");
2.105 break;
2.106 }
2.107 @@ -129,10 +140,12 @@
2.108 fflush (stdout);
2.109
2.110 total += array->len;
2.111 - g_byte_array_free (array, TRUE);
2.112 + g_array_remove_range (array, 0, array->len);
2.113 + //usleep(300000);
2.114 }
2.115 -
2.116 +
2.117 gmyth_file_transfer_close (transfer);
2.118 + g_array_free (array, TRUE);
2.119 g_object_unref (transfer);
2.120
2.121 return TRUE;
2.122 @@ -143,73 +156,58 @@
2.123 {
2.124 GMythLiveTV * livetv = NULL;
2.125 GMythFile *gmyth_file = NULL;
2.126 - GByteArray *array = NULL;
2.127 - gint tries = 0;
2.128 - GMythFileReadResult res;
2.129 + GArray *array = NULL;
2.130
2.131 g_return_val_if_fail (options != NULL, FALSE);
2.132 g_return_val_if_fail (options->b_info != NULL, FALSE);
2.133 g_return_val_if_fail (options->channel != NULL, FALSE);
2.134 livetv = gmyth_livetv_new (options->b_info);
2.135 - if (gmyth_livetv_channel_name_setup (livetv, options->channel) == FALSE) {
2.136 - g_printerr ("coult not setup remote livetv");
2.137 +
2.138 + if (gmyth_livetv_channel_name_setup (livetv, options->channel) == FALSE)
2.139 + {
2.140 + g_printerr ("Could not setup remote livetv");
2.141 g_object_unref (livetv);
2.142 return FALSE;
2.143 }
2.144
2.145 gmyth_file = GMYTH_FILE( gmyth_livetv_create_file_transfer (livetv) );
2.146 - if (gmyth_file == NULL) {
2.147 + if (gmyth_file == NULL)
2.148 + {
2.149 g_printerr ("Could not open livetv recording file for transfer");
2.150 g_object_unref (livetv);
2.151 return FALSE;
2.152 }
2.153
2.154 if (!gmyth_file_transfer_open ( GMYTH_FILE_TRANSFER(gmyth_file),
2.155 - livetv->uri != NULL ?
2.156 - gmyth_uri_get_path (livetv->uri) :
2.157 - livetv->proginfo->pathname->str)) {
2.158 + livetv->uri != NULL ?
2.159 + gmyth_uri_get_path (livetv->uri) :
2.160 + livetv->proginfo->pathname->str))
2.161 + {
2.162
2.163 - g_printerr ("Couldn't open MythTV FileTransfer is NULL!\n");
2.164 + g_printerr ("Couldn't open MythTV. FileTransfer is NULL!\n");
2.165 return FALSE;
2.166 }
2.167
2.168 - while (TRUE) {
2.169 - array = g_byte_array_new ();
2.170 + array = g_array_new (FALSE, TRUE, sizeof(gchar));
2.171
2.172 - res = gmyth_file_transfer_read ( GMYTH_FILE_TRANSFER(gmyth_file),
2.173 - array, 64000, TRUE);
2.174 - if (res == GMYTH_FILE_READ_OK) {
2.175 - tries = 0;
2.176 - fwrite (array->data, array->len, 1, stdout);
2.177 - fflush (stdout);
2.178 + while( gmyth_file_transfer_read
2.179 + (GMYTH_FILE_TRANSFER(gmyth_file),
2.180 + (GByteArray*)array, 64000, TRUE) == GMYTH_FILE_READ_OK )
2.181 + {
2.182
2.183 - if (array->len == 64000) {
2.184 - tries = 0;
2.185 - } else {
2.186 - tries += 1;
2.187 - // after 20 tries without any data, we give up
2.188 - g_printerr ("-----> 20 read tries exceeded\n");
2.189 - if (tries > 20) {
2.190 - g_byte_array_free (array, TRUE);
2.191 - goto error;
2.192 - }
2.193 - g_usleep (10000);
2.194 - }
2.195 - } else {
2.196 - g_printerr ("Error while file transfer read\n");
2.197 - goto error;
2.198 - }
2.199 - g_byte_array_free (array, TRUE);
2.200 + fwrite (array->data, array->len, 1, stdout);
2.201 + fflush (stdout);
2.202 + g_array_remove_range (array, 0, array->len);
2.203 }
2.204
2.205 -error:
2.206 + g_array_free (array, TRUE);
2.207 g_object_unref (gmyth_file);
2.208 g_object_unref (livetv);
2.209
2.210 return TRUE;
2.211 }
2.212
2.213 -int
2.214 +int
2.215 main (int argc, char *argv[])
2.216 {
2.217 gboolean res = FALSE;
2.218 @@ -217,7 +215,7 @@
2.219
2.220 g_type_init ();
2.221 g_thread_init (NULL);
2.222 -
2.223 +
2.224 options = _cat_options_new ();
2.225 res = _parse_args (argc, argv, options);
2.226 if (!res) {
2.227 @@ -225,14 +223,14 @@
2.228 return 1;
2.229 }
2.230
2.231 - if (options->filename) {
2.232 + if (options->filename)
2.233 res = _cat_recorded_file (options);
2.234 - } else if (options->channel) {
2.235 - res = _cat_channel (options);
2.236 - } else {
2.237 - g_printerr ("Argument invalid. You must specify --filename or --channel.\nType --help for more information.\n");
2.238 - res = FALSE;
2.239 - }
2.240 + else
2.241 + if (options->channel)
2.242 + res = _cat_channel (options);
2.243 + else
2.244 + g_printerr ("Argument invalid. You must specify --filename or --channel.\n"
2.245 + "Type --help for more information.\n");
2.246
2.247 _cat_options_free (options);
2.248