diff -r 2061bf4c30c7 -r 5ab6a453da43 gmyth-stream/server/plugins/transcoders/mencoder.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth-stream/server/plugins/transcoders/mencoder.py	Wed Sep 05 21:30:56 2007 +0100
@@ -0,0 +1,334 @@
+#!/usr/bin/env python
+
+__author__ = "Artur Duque de Souza"
+__author_email__ = "artur.souza@indt.org.br"
+__license__ = "GPL"
+__version__ = "0.3"
+
+import os
+import time
+import fcntl
+import shlex
+import socket
+import struct
+import signal
+import subprocess
+
+import lib.utils as utils
+import lib.server as server
+import plugins.transcoders.mencoder_lib.mythtv as mythtv
+
+from select import select
+import lib.transcoder as transcoder
+
+__all__ = ("TranscoderMencoder",)
+
+class TranscoderMencoder(transcoder.Transcoder):
+    """Transcoder class that implements a transcoder using Mencoder"""
+    mencoder_path = utils.which("mencoder")
+    name = "mencoder"
+    priority = -1
+    args = {}
+    proc = None
+    gmyth = None
+
+    # only works with avi container
+    status = 0
+
+    def _setup_params(self):
+        params_first = self.params_first
+
+        # general_opts
+        self.args["local"]    = params_first("local", False)
+        self.args["language"] = params_first("language", False)
+        self.args["subtitle"] = params_first("subtitle", False)
+        self.args["format"]   = params_first("format", "mpeg1")
+        self.args["outfile"]  = params_first("outfile", "-")
+
+        # input_opt
+        self.args["type"]     = params_first("type", "file")
+        self.args["input"]    = params_first("uri", "-")
+
+        # audio_opts
+        self.args["acodec"]   = params_first("acodec", "mp2")
+        self.args["abitrate"] = params_first("abitrate", 192)
+        self.args["volume"]   = params_first("volume", 5)
+
+        # video_opts
+        self.args["mux"]      = params_first("mux", "mpeg")
+        self.args["fps"]      = params_first("fps", 25)
+        self.args["vcodec"]   = params_first("vcodec", "mpeg1video")
+        self.args["vbitrate"] = params_first("vbitrate", 400)
+        self.args["width"]    = params_first("width", 320)
+        self.args["height"]   = params_first("height", 240)
+    # _setup_params()
+
+
+    def _setup_audio(self):
+        if self.args["acodec"] == "mp3lame":
+            audio = "-oac mp3lame -lameopts cbr:br=%s vol=%s" % (
+                self.args["abitrate"], self.args["volume"])
+        else:
+            audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (
+                self.args["acodec"], self.args["abitrate"])
+
+        return audio
+    # _setup_audio()
+
+
+    def _setup_video(self):
+        video = " -of %s" % self.args["mux"]
+        video += " -ofps %s" % self.args["fps"]
+
+        vcodec = self.args["vcodec"]
+        if vcodec == "nuv" or vcodec == "xvid"\
+               or vcodec == "qtvideo" or vcodec == "copy":
+            video += " -ovc %s" % vcodec
+        else:
+            video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % (
+                vcodec, self.args["vbitrate"])
+
+        if self.args["mux"] == "mpeg":
+            video += " -mpegopts format=%s" % self.args["format"]
+
+        video += " -vf scale=%s:%s" % (self.args["width"], self.args["height"])
+        return video
+    # _setup_video()
+
+
+    def _arg_append(self, args, options):
+        for arg in shlex.split(options):
+            args.append(arg)
+    # arg_append()
+
+    def _setup_mencoder_opts(self, args):
+        args.append(self.mencoder_path)
+
+        if self.args["type"] and self.args["type"] == "tv":
+            self._arg_append(args, self.args["tv"])
+        elif self.args["outfile"] == "-" and self.args["type"]:
+            args.append(self.args["input"])
+        else:
+            args.append("-")
+
+        if self.args["language"]:
+            self._arg_append(args, "-alang %s" % self.args["language"])
+
+        if self.args["subtitle"]:
+            self._arg_append(args, "-slang %s" % self.args["subtitle"])
+            self._arg_append(args, "-subfps %s" % self.args["fps"])
+
+        self._arg_append(args, "-idx")
+        self._arg_append(args, "-cache 1024")
+        self._arg_append(args, self._setup_audio())
+        self._arg_append(args, self._setup_video())
+
+        self._arg_append(args, "-really-quiet")
+
+        if self.args["outfile"] != "-":
+            self.args["outfile"] = ".transcoded/%s" % (
+                                   os.path.basename(self.args["outfile"]))
+
+        self._arg_append(args, "-o %s" % self.args["outfile"])
+        self._arg_append(args, "2>%s" % os.devnull)
+    # _setup_args()
+
+    def _setup_filename(self):
+        """This function setups the file to encode parsing the uri.
+        So, type can be:
+        * file
+        * dvd
+        * myth
+
+        If the last one is detected we have to parse the uri to find args.
+        Then we store all the args inside a dictionary: self.args['gmyth-cat']
+        """
+        _type = self.args["type"]
+
+        if _type == "file":
+            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://%s" % self.args["input"]
+
+        elif _type == "myth":
+            self.args["gmyth-cat"] = mythtv._setup_mythfilename(self)
+
+        elif _type == "tv":
+            driver = self.params_first("driver", "v4l2")
+            norm = self.params_first("norm", "pal-m")
+            channel = self.params_first("channel", "13")
+            chanlist = self.params_first("chanlist", "us-bcast")
+            outfmt = self.params_first("outfmt", "yuy2")
+            vdev = self.params_first("vdev", "/dev/video0")
+            adev = self.params_first("adev", "/dev/dsp")
+            self.args["tv"] = "tv:// -v -tv driver=%s:norm=%s:channel=%s:" \
+                              "chanlist=%s:width=%s:height=%s:outfmt=%s:" \
+                              "device=%s:adevice=%s" % (driver, norm,
+                                                        channel, chanlist,
+                                                        self.args["width"],
+                                                        self.args["height"],
+                                                        outfmt, vdev, adev)
+    # _setup_filename()
+
+
+    def __init__(self, params):
+        transcoder.Transcoder.__init__(self, params)
+        self.mencoder_opts = []
+
+        try:
+            self._setup_params()
+            self._setup_filename()
+            self._setup_mencoder_opts(self.mencoder_opts)
+        except Exception, e:
+            if self.log:
+                self.log.error(self.tid, "Error: %s" % e)
+            else:
+                raise
+    # __init__()
+
+
+    def _check_opened_file(self, stdw, _stdin):
+        loop = True
+        while loop:
+            try:
+                return open(self.args["outfile"])
+            except:
+                os.write(stdw, _stdin.read(1024))
+    # _check_opened_file
+
+
+    def _start_outfile(self, outfd):
+        finished = False
+
+        # Configuring stdin
+        try:
+            filename = self.args["input"].split("://")[1]
+            _stdin = open(filename)
+            size = int(os.path.getsize(filename))
+        except Exception, e:
+            self.log.error(self.tid, "Error: Mencoder stdin"\
+                           " setup error: %s" % e)
+            outfd.write("Error: Mencoder stdin setup error: %s" %e)
+            return False
+
+        self.status = 0
+        total_read = 0
+
+        # Configuring pipes
+        stdr, stdw = os.pipe()
+
+        if not self._run_mencoder(input=stdr):
+            return False
+
+        stdout = self._check_opened_file(stdw, _stdin)
+        outfd.write("OK   ")
+
+        try:
+            while self.proc and self.proc.poll() == None:
+                if not finished:
+                    data_in = _stdin.read(4096)
+                    if data_in != "":
+                        os.write(stdw, data_in)
+                        total_read += 4096
+                        d = stdout.read(4096)
+                        self.status = utils.progress_bar(total_read,
+                                                         size, 50)
+                    else:
+                        finished = True
+                        os.close(stdw)
+
+                else:
+                    d = stdout.read(4096)
+
+        except Exception, e:
+            self.log.error(self.tid, "Error: %s" % e)
+            self.stop()
+            return False
+
+        self.log.info(self.tid, "OK: Done")
+        return True
+    # _start_outfile()
+
+
+    def _start(self, outfd):
+        # Play a file on disk or DVD
+        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)
+                outfd.write(d)
+        except Exception, e:
+            self.log.error(self.tid, "Error: %s" % e)
+            return False
+
+        self.log.info(self.tid, "OK: Done")
+        return True
+    # _start()
+
+    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(self.tid, "Error: Mencoder: %s" % e)
+            return False
+
+        return True
+    # _run_mencoder()
+
+    def start(self, outfd):
+        cmd = " ".join(self.mencoder_opts)
+        self.log.debug(self.tid, "Plugin's tid: %s" % self.tid)
+        self.log.debug(self.tid, "Mencoder: %s" % cmd)
+
+        ret = False
+
+        if self.args["outfile"] == "-" and \
+               self.args["type"] in ["file", "dvd", "tv"]:
+            ret = self._start(outfd)
+
+        elif self.args["type"] == "myth":
+            ret = mythtv.start_myth(self, outfd)
+
+        else:
+            ret = self._start_outfile(outfd)
+
+        self.stop()
+
+        if not ret:
+            self.log.error(self.tid, "Error: Problems while "\
+                           "starting streaming.")
+
+        return ret
+    # start()
+
+    def _aux_stop(self, obj, next=False):
+        if obj:
+            try:
+                os.kill(obj.pid, signal.SIGKILL)
+                if next:
+                    os.kill(obj.pid+1, signal.SIGKILL)
+            except OSError, e:
+                pass
+
+            try:
+                obj.wait()
+            except Exception, e:
+                pass
+
+            obj = None
+    # _aux_stop
+
+    def stop(self):
+        self._aux_stop(self.proc, True)
+        self._aux_stop(self.gmyth)
+    # stop()
+
+# TranscoderMencoder