# HG changeset patch # User morphbr # Date 1177953396 -3600 # Node ID 4dd9bf602c18a04316a618b2642b4ba49963a20d # Parent fb0bf39636d6261382e910555ee1dbbb8eec95cd [svn r611] * GMyth-Streamer - updated mencoder plugin * GMyth - samples: gmyth_cat code update diff -r fb0bf39636d6 -r 4dd9bf602c18 gmyth-stream/server/0.2/plugins/transcoders/mencoder.py --- a/gmyth-stream/server/0.2/plugins/transcoders/mencoder.py Mon Apr 30 16:04:20 2007 +0100 +++ b/gmyth-stream/server/0.2/plugins/transcoders/mencoder.py Mon Apr 30 18:16:36 2007 +0100 @@ -18,6 +18,7 @@ priority = -1 args = {} proc = None + gmyth = None # only works with avi container status = 0 @@ -38,7 +39,7 @@ self.args["sendback"] = False # input_opt - uri = params_first("uri", "file://-").split("://") + uri = params_first("uri", "file:-").split(":", 1) self.args["type"] = uri[0] self.args["input"] = uri[1] @@ -109,6 +110,7 @@ self._arg_append(args, "-subfps %s" % self.args["fps"]) self._arg_append(args, "-idx") + self._arg_append(args, "-cache 500") self._arg_append(args, self._setup_audio()) self._arg_append(args, self._setup_video()) @@ -125,6 +127,8 @@ if not os.path.exists(self.args["input"]): raise IOError,\ "File requested does not exist: %s." % self.args["input"] + else: + self.args["input"] = "file://%s" % self.args["input"] elif _type == "dvd": self.args["input"] = "dvd://".join(self.args["input"]) @@ -134,6 +138,7 @@ # gmyth-cat -h 192.168.1.124 -p 6543 -f file.nuv # myth://IP:PORT:type:file self.args["gmyth-cat"] = self.args["input"].split(":") + self.args["input"] = "-" # _setup_filename() @@ -175,10 +180,7 @@ # Configuring pipes stdr, stdw = os.pipe() - try: - self.proc = subprocess.Popen(self.mencoder_opts, stdin=stdr, close_fds=True) - except Exception, e: - self.log.error("Error executing mencoder: %s" % e) + if not self._run_mencoder(input=stdr): return False stdout = self._check_opened_file(stdw, _stdin) @@ -215,14 +217,9 @@ # _start_outfile() def _start(self, outfd): - try: - self.proc = subprocess.Popen(self.mencoder_opts, - stdout=subprocess.PIPE, close_fds=True) - except Exception, e: - self.log.error("Error executing mencoder: %s" % e) + if not self._run_mencoder(output=subprocess.PIPE): return False - try: while self.proc and self.proc.poll() == None: d = self.proc.stdout.read(1024) @@ -235,22 +232,76 @@ return True # _start() + def _start_myth(self, outfd): + # gmyth-cat -h 192.168.1.124 -p 6543 -c 111 + # gmyth-cat -h 192.168.1.124 -p 6543 -f file.nuv + # myth://IP:PORT:type:file + host = self.args["gmyth-cat"][0] + port = self.args["gmyth-cat"][1] + kind = self.args["gmyth-cat"][2] + fchan = self.args["gmyth-cat"][3] + + gmyth_cat = utils.which("gmyth-cat") + opts = [gmyth_cat, "-h", host, "-p", port, "-" + kind, fchan] + gr, gw = os.pipe() + + try: + self.gmyth = subprocess.Popen(opts, stdout=subprocess.PIPE, close_fds=True) + except Exception, e: + self.log.error("Error executing gmyth-cat: %s" % e) + return False + + if not self._run_mencoder(input=self.gmyth.stdout, output=subprocess.PIPE): + return False + + try: + while self.proc and self.proc.poll() == None: + r, w, x = select([self.proc.stdout], [], [], 0) + if self.proc.stdout in r: + d = self.proc.stdout.read(4096) + outfd.write(d) + except Exception, e: + self.log.error("Problems handling data: %s" % e) + return False + + return True + # _start_myth() + + def _run_mencoder(self, input=None, output=None): + try: + self.proc = subprocess.Popen(self.mencoder_opts, stdin=input, + stdout=output, close_fds=True) + except Exception, e: + self.log.error("Error executing mencoder: %s" % e) + return False + + return True + # _run_mencoder() def start(self, outfd): cmd = " ".join(self.mencoder_opts) self.log.debug("Mencoder: %s" % cmd) - if self.args["outfile"] == "-": - return self._start(outfd) + ret = False + + if self.args["outfile"] == "-" and self.args["type"] in ["file", "dvd"]: + ret = self._start(outfd) + + elif self.args["type"] == "myth": + ret = self._start_myth(outfd) + else: - return self._start_outfile(outfd) + ret = self._start_outfile(outfd) + + self.stop() + return ret # start() def stop(self): if self.proc: try: - os.kill(self.proc.pid, signal.SIGTERM) + os.kill(self.proc.pid, signal.SIGKILL) except OSError, e: pass @@ -260,6 +311,20 @@ pass self.proc = None + + if self.gmyth: + try: + os.kill(self.gmyth.pid, signal.SIGKILL) + except OSError, e: + pass + + try: + self.gmyth.wait() + except Exception, e: + pass + + self.gmyth = None + # stop() # TranscoderMencoder diff -r fb0bf39636d6 -r 4dd9bf602c18 gmyth/samples/gmyth_cat.c --- a/gmyth/samples/gmyth_cat.c Mon Apr 30 16:04:20 2007 +0100 +++ b/gmyth/samples/gmyth_cat.c Mon Apr 30 18:16:36 2007 +0100 @@ -4,7 +4,7 @@ #endif #include -#include +#include #include "gmyth_backendinfo.h" #include "gmyth_file_transfer.h" @@ -14,7 +14,6 @@ typedef struct { GMythBackendInfo *b_info; - char* filename; char* channel; } cat_options_t; @@ -50,24 +49,31 @@ gchar *filename = NULL; gchar *channel = NULL; - GOptionEntry entries[] = + GOptionEntry entries[] = { - { "hostname", 'h', 0, G_OPTION_ARG_STRING, &host_ip, "Mythtv backend hostname or IP address", "IP_ADDRESS" }, + { "hostname", 'h', 0, G_OPTION_ARG_STRING, &host_ip, "Mythtv backend hostname or " + "IP address", "IP_ADDRESS" }, + { "port", 'p', 0, G_OPTION_ARG_INT, &host_port, "Mythtv backend port", "PORT" }, - { "filename", 'f', 0, G_OPTION_ARG_STRING, &filename, "Recorded file name available in the Mythtv backend", "FILE" }, + + { "filename", 'f', 0, G_OPTION_ARG_STRING, &filename, "Recorded file name available " + "in the Mythtv backend", "FILE" }, + { "channel", 'c', 0, G_OPTION_ARG_STRING, &channel, "Mythtv channel number", "CHANNEL" }, + { NULL } }; g_return_val_if_fail (options != NULL, FALSE); - context = g_option_context_new ("- loads a mythtv backend recorded file and prints it on the standard output\n"); + context = g_option_context_new ("- loads a mythtv backend recorded file and prints " + "it on the standard output\n"); g_option_context_add_main_entries (context, entries, NULL); g_option_context_parse (context, &argc, &argv, &error); g_option_context_set_help_enabled (context, TRUE); g_option_context_free (context); - + if ((!host_ip) || (host_port == 0) ) { g_free (host_ip); g_free (filename); @@ -92,35 +98,40 @@ static gboolean _cat_recorded_file (cat_options_t *options) { - GByteArray *array = NULL; + GArray *array = NULL; GMythFileTransfer *transfer; guint64 size = 0, total = 0; - + g_return_val_if_fail (options != NULL, FALSE); g_return_val_if_fail (options->b_info != NULL, FALSE); g_return_val_if_fail (options->filename != NULL, FALSE); - if (!gmyth_util_file_exists (options->b_info, options->filename)) { + if (!gmyth_util_file_exists (options->b_info, options->filename)) + { g_printerr ("File %s was not found in the mythtv server\n", options->filename); return FALSE; } transfer = gmyth_file_transfer_new (options->b_info); - if (!gmyth_file_transfer_open (transfer, options->filename)) { + if (!gmyth_file_transfer_open (transfer, options->filename)) + { g_printerr ("File %s could not be opened\n", options->filename); return FALSE; } size = gmyth_file_transfer_get_filesize (transfer); - while (total != size) { + array = g_array_new (FALSE, TRUE, sizeof(gchar)); + + while (total != size) + { GMythFileReadResult res; - array = g_byte_array_new (); - res = gmyth_file_transfer_read (transfer, array, + res = gmyth_file_transfer_read (transfer, (GByteArray*)array, (size - total) > 64000 ? 64000 : (size - total), FALSE); - if ((res != GMYTH_FILE_READ_OK) && (res != GMYTH_FILE_READ_EOF)) { - g_byte_array_free (array, TRUE); + if ((res != GMYTH_FILE_READ_OK) && (res != GMYTH_FILE_READ_EOF)) + { + g_array_free (array, TRUE); g_printerr ("Error while reading the file: aborting!!\n"); break; } @@ -129,10 +140,12 @@ fflush (stdout); total += array->len; - g_byte_array_free (array, TRUE); + g_array_remove_range (array, 0, array->len); + //usleep(300000); } - + gmyth_file_transfer_close (transfer); + g_array_free (array, TRUE); g_object_unref (transfer); return TRUE; @@ -143,73 +156,58 @@ { GMythLiveTV * livetv = NULL; GMythFile *gmyth_file = NULL; - GByteArray *array = NULL; - gint tries = 0; - GMythFileReadResult res; + GArray *array = NULL; g_return_val_if_fail (options != NULL, FALSE); g_return_val_if_fail (options->b_info != NULL, FALSE); g_return_val_if_fail (options->channel != NULL, FALSE); livetv = gmyth_livetv_new (options->b_info); - if (gmyth_livetv_channel_name_setup (livetv, options->channel) == FALSE) { - g_printerr ("coult not setup remote livetv"); + + if (gmyth_livetv_channel_name_setup (livetv, options->channel) == FALSE) + { + g_printerr ("Could not setup remote livetv"); g_object_unref (livetv); return FALSE; } gmyth_file = GMYTH_FILE( gmyth_livetv_create_file_transfer (livetv) ); - if (gmyth_file == NULL) { + if (gmyth_file == NULL) + { g_printerr ("Could not open livetv recording file for transfer"); g_object_unref (livetv); return FALSE; } if (!gmyth_file_transfer_open ( GMYTH_FILE_TRANSFER(gmyth_file), - livetv->uri != NULL ? - gmyth_uri_get_path (livetv->uri) : - livetv->proginfo->pathname->str)) { + livetv->uri != NULL ? + gmyth_uri_get_path (livetv->uri) : + livetv->proginfo->pathname->str)) + { - g_printerr ("Couldn't open MythTV FileTransfer is NULL!\n"); + g_printerr ("Couldn't open MythTV. FileTransfer is NULL!\n"); return FALSE; } - while (TRUE) { - array = g_byte_array_new (); + array = g_array_new (FALSE, TRUE, sizeof(gchar)); - res = gmyth_file_transfer_read ( GMYTH_FILE_TRANSFER(gmyth_file), - array, 64000, TRUE); - if (res == GMYTH_FILE_READ_OK) { - tries = 0; - fwrite (array->data, array->len, 1, stdout); - fflush (stdout); + while( gmyth_file_transfer_read + (GMYTH_FILE_TRANSFER(gmyth_file), + (GByteArray*)array, 64000, TRUE) == GMYTH_FILE_READ_OK ) + { - if (array->len == 64000) { - tries = 0; - } else { - tries += 1; - // after 20 tries without any data, we give up - g_printerr ("-----> 20 read tries exceeded\n"); - if (tries > 20) { - g_byte_array_free (array, TRUE); - goto error; - } - g_usleep (10000); - } - } else { - g_printerr ("Error while file transfer read\n"); - goto error; - } - g_byte_array_free (array, TRUE); + fwrite (array->data, array->len, 1, stdout); + fflush (stdout); + g_array_remove_range (array, 0, array->len); } -error: + g_array_free (array, TRUE); g_object_unref (gmyth_file); g_object_unref (livetv); return TRUE; } -int +int main (int argc, char *argv[]) { gboolean res = FALSE; @@ -217,7 +215,7 @@ g_type_init (); g_thread_init (NULL); - + options = _cat_options_new (); res = _parse_args (argc, argv, options); if (!res) { @@ -225,14 +223,14 @@ return 1; } - if (options->filename) { + if (options->filename) res = _cat_recorded_file (options); - } else if (options->channel) { - res = _cat_channel (options); - } else { - g_printerr ("Argument invalid. You must specify --filename or --channel.\nType --help for more information.\n"); - res = FALSE; - } + else + if (options->channel) + res = _cat_channel (options); + else + g_printerr ("Argument invalid. You must specify --filename or --channel.\n" + "Type --help for more information.\n"); _cat_options_free (options);