Author: duncan
Date: Thu Oct 19 16:49:39 2006
New Revision: 8423

Added:
   branches/rel-1/freevo/src/encodingcore.py
      - copied, changed from r8410, 
/branches/rel-1/freevo/src/helpers/encodingcore.py
   branches/rel-1/freevo/src/video/encodingclient.py   (contents, props changed)
      - copied, changed from r8414, /branches/rel-1/freevo/src/encodingclient.py
   branches/rel-1/freevo/src/video/plugins/reencode.py
Removed:
   branches/rel-1/freevo/src/encodingclient.py
   branches/rel-1/freevo/src/helpers/encodingcore.py
Modified:
   branches/rel-1/freevo/src/helpers/encodingserver.py
   branches/rel-1/freevo/src/video/plugins/dvdbackup.py

Log:
[ 1580642 ] Use the encoding server to re-encode recorded programmes
Updated for an experimental version of re-encoding tv programmes


Copied: branches/rel-1/freevo/src/encodingcore.py (from r8410, 
/branches/rel-1/freevo/src/helpers/encodingcore.py)
==============================================================================
--- /branches/rel-1/freevo/src/helpers/encodingcore.py  (original)
+++ branches/rel-1/freevo/src/encodingcore.py   Thu Oct 19 16:49:39 2006
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # -----------------------------------------------------------------------
-# EncodingCore.py, part of EncodingServer - for use with or without Freevo
+# EncodingCore.py, part of EncodingServer - for use with Freevo
 # -----------------------------------------------------------------------
 # $Id: rc.py 8278 2006-09-30 07:22:11Z duncan $
 #
@@ -32,7 +32,7 @@
 import threading
 from time import sleep
 import sys, os, re, popen2 #, ConfigParser, copy
-#import config   # QuickRip global configuration.
+import config
 import mmpython
 from copy import copy
 from string import split, join
@@ -48,10 +48,15 @@
 __copyright__ = "Copyright (C) 2004 den_RDC"
 __license__ = "GPL"
 
-DEBUG=False
+def _debug_(text, level=1):
+    if DEBUG >= level:
+        try:
+            self.log.debug(String(text))
+        except:
+            print(String(text))
 
 #"hardcoded capabilities" .. these might change or become dynamic in the 
future, when more capabilities are supported
-#the "container format" will remain hardcoded 
+#the "container format" will remain hardcoded
 
 ContainerCapList = [ 'Avi' ]
 VideoCodecList = [ 'MPEG 4 (lavc)', 'XViD']
@@ -70,7 +75,7 @@
     'Normal denoise' : "denoise3d",
     'HQ denoise' : "hqdn3d"
     }
-    
+
 MencoderMapping = {
     'MPEG 4 (lavc)' : 
["lavc",["-lavcopts","vcodec=mpeg4:vhq:vqmin=2:v4mv:trell:autoaspect:vbitrate=%s%s"]],
 #to hard    'MPEG 4 (lavc)' : 
["lavc",["-lavcopts","vcodec=mpeg4:vhq:vqmin=2:v4mv:vlelim=-4:vcelim=9:lumi_mask=0.05:dark_mask=0.01:autoaspect:vbitrate=%s%s"]],
@@ -79,7 +84,7 @@
     'MPEG 1 Layer 3 (mp3)' : ["mp3lame",["-lameopts", "cbr:br=%s"]]
     }
 
-    
+
 #from pytvgrab enum.py, see http://pytvgrab.sourceforge.net
 class Enum(dict):
     """Enum
@@ -90,102 +95,103 @@
         for i in range(x, x+len(names)):
           self.__dict__[names[i-x]]=i
           self[i]=names[i-x]
-    # __init__()            
-    
-    
-status = Enum(["notset","apass","vpass1","vpassfinal","postmerge"])    
+    # __init__()
+
+
+status = Enum(["notset","apass","vpass1","vpassfinal","postmerge"])
 
 class EncodingJob:
     """Class for creation & configuration of EncodingJobs. This generates the 
mencoder commands"""
-    
+
     def __init__(self, source, output, friendlyname, idnr, chapter=None):
         """Initialize class instance"""
+        _debug_('__init__(self, %s, %s, %s, %s, %s)' % (source, output, 
friendlyname, idnr, chapter), 2)
         #currently only MEncoder can be used, but who knows what will happen 
in the future :)
         self._generateCL = self._GenerateCLMencoder
-        
+
         self.source = source
         self.output = output
         self.name = friendlyname
         self.idnr = idnr
         self.chapter = chapter
-        
+
         self.sourcetype = None
-        
+
         self.container = "Avi"
-        
+
         self.tgtsize = None
         self.length = None
-        
+
         self.vcodec = None
         self.vbrate = None
         self.multipass = False
         self.vfilters = []
         self.crop = None
-        
-        
+
+
         self.acodec = AudioCodecList[0]
         self.abrate = 128
         self.afilters = {} # Not used atm, might be used in the future
-        
+
         self.cls = []
-        
+
         self.percentage = 0
         self.trem = 0
-        
+
         self.status = status.notset
         self.pid = 0
-        
+
         self.pal = False
         self.ntsc = False
         self.ntscprog = False
         self.ana = False
-        
+
         #Analyze our source
         self.finishedanalyze = False
         self._AnalyzeSource()
-        
-            
+
+
     def setContainer(self, container):
         """Set a container to hold the audio & video streams"""
         #safety checks
         if container not in ContainerCapList:
             return "Unknown container format"
-            
+
         self.container = container
-        
+
     def getContainerList(self):
         return ContainerCapList
-        
-            
+
+
     def getVideoCodecList(self):
         """Return a possible video codec list"""
         return VideoCodecList
-            
+
     def setVideoCodec(self, vcodec, tgtsize, multipass=False):
         """Set video codec and target filesize (in MB)"""
         #safety checks first
         if vcodec not in self.getVideoCodecList():
             return "Unknown video codec"
-        
+
         self.vcodec = vcodec
         self.tgtsize = (int(tgtsize) * 1024) #filesize is internally stored in 
kb
         self.multipass = multipass
-        
-        
+
+
     def getAudioCodecList(self):
         """Return a possible audio codec list"""
         return AudioCodecList
-        
-        
+
+
     def setAudioCodec(self, acodec, abrate=128):
         """Set audio codec & bitrate"""
         #safety first
         if acodec not in self.getAudioCodecList():
             return "Unknown audio codec"
-        
+
         self.acodec = acodec
         self.abrate = abrate
-        
+
     def getVideoFiltersList(self):
         """Return a list of possible video filters"""
         if self.ntsc:
@@ -194,41 +200,49 @@
             non_ivtcdict = VFDict.copy()
             del non_ivtcdict['Inverse Telecine']
             return non_ivtcdict
-        
+
     def setVideoFilters(self, videofilters):
         """Set video filters"""
         for vfilter, option in videofilters.items():
             if MencoderFilters.has_key(option):
                 self.vfilters += [ MencoderFilters[option] ]
-        
+
     def _CalcVideoBR(self):
         """Calculates the video bitrate"""
-        
+
         self.vbrate = int((((int(self.tgtsize)*8) / int(self.length)) - 
int(self.abrate)) / 0.98)
         if self.vbrate > 12000: #we got a very short file, very high bitrates 
are interpreted as bit/s instead of kbit/s, shitty qual
             self.vbrate = 6000
-        
-        
+
+
     def _AnalyzeSource(self):
         """Find out some basic information about the source
-    
+
         ATM we will blindly assume it's a dvdrom device or a disk dvd image, 
if a chapter is given"""
-        
+        _debug_('_AnalyzeSource(self)', 2)
+
         if self.chapter:
             self.sourcetype = "dvd"
-            
             #check some things, like length
             mmpython.disc.ifoparser.open(self.source)
             data = mmpython.disc.ifoparser.title(self.chapter)
             self.length = data[2]
-            if DEBUG: print "Video length: %s" % self.length
+            _debug_("Video length: %s" % self.length)
             #NI : maybe implement procedure to get resolution, handy for 
scaling/manual cropping
             self._CropDetect()
-            
-            
+        else:
+            data = mmpython.parse(self.source)
+            self.sourcetype = data['type'].encode('latin1')
+            for f in dir(data):
+                print '%s: %s' % (f, eval('data["%s"]' % f))
+            self.length = data.get_length()
+            _debug_("Video length: %s" % self.length)
+            self._CropDetect()
+
+
     def _CropDetect(self): #contains pieces of QuickRip
         """Detect cropping
-        
+
         Function is always called because cropping is a good thing, and we can 
pass our ideal values
         back to the client wich can verify them visually if needed.""" #not 
true atm
         #build mplayer parameters
@@ -243,53 +257,57 @@
             arguments += [ '-dvd-device', self.source, 'dvd://%s' % 
self.chapter ]
         else:
             arguments += [ self.source ]
-            
+
+        _debug_('arguments=%s' % arguments)
+        _debug_('_run(mplayer, arguments, self._CropDetectParse, None, 0, 
None)', 2)
         self._run(mplayer, arguments, self._CropDetectParse, None, 0, None)
-        
+
     def _GenerateCLMencoder(self):
         """Generate the command line(s) to be executed, using MEncoder for 
encoding"""
         #calculate the videobitrate
         self._CalcVideoBR()
-        
+
         #generate the audio pass
         audiopass = []
-               
-        
+
+
         audiopass += self._GCLMAudiopass()
         audiopass += self._GCLMSource()
-        
+
         #for single passes
         if not self.multipass:
-            videopass = [] 
+            videopass = []
             videopass += self._GCLMVideopass(0)
             videopass += self._GCLMSource()
-    
+
             self.cls = [ audiopass, videopass ]
-            
+
         else:
             videopass1 = []
             videopass2 = []
-            
+
             videopass1 += self._GCLMVideopass(1)
-            videopass1 += self._GCLMSource()    
-            
+            videopass1 += self._GCLMSource()
+
             videopass2 += self._GCLMVideopass(2)
-            videopass2 += self._GCLMSource()  
-           
-            self.cls = [ audiopass, videopass1, videopass2 ] 
-    
+            videopass2 += self._GCLMSource()
+
+            self.cls = [ audiopass, videopass1, videopass2 ]
+
     def _GCLMSource(self):
         """Returns source part of mencoder"""
         if self.sourcetype == "dvd":
             #return [ "-endpos", "10","-dvd-device", self.source , "dvd://%s" 
% self.chapter]
             return [ "-dvd-device", self.source , "dvd://%s" % self.chapter]
-            
+        else:
+            return [ self.source ]
+
     def _GCLMAudiopass(self):
         """Returns audio pass specefic part of mencoder cl"""
-        return ["-ovc", "frameno", "-oac", MencoderMapping[self.acodec][0], 
MencoderMapping[self.acodec][1][0], 
+        return ["-ovc", "frameno", "-oac", MencoderMapping[self.acodec][0], 
MencoderMapping[self.acodec][1][0],
                 MencoderMapping[self.acodec][1][1] % self.abrate,
                 "-o", "frameno.avi"]
-                
+
     def _GCLMVideopass(self, passnr):
         """Returns video pass specefic part of mencoder cl"""
         vf = copy(self.vfilters)
@@ -303,13 +321,13 @@
                 passname = ":pass=%s"
             else:
                 passname = ":vpass=%s"
-                
+
             vpass = passname % passnr
 
-        #generate videofilters first, NI completly yet        
+        #generate videofilters first, NI completly yet
         if self.crop != None:
             vf += [ "crop=%s" % self.crop ]
-        
+
         #in case of xvid and anamorphic dvd, add scaling to compensate AR.. if 
we didn't find cropping we have no res, so no tricks
         if self.vcodec == "XViD" and (self.crop != None):
             if self.ana:
@@ -319,59 +337,59 @@
                 yscaled -= rounded
                 if rounded > 7.5:
                     yscaled += 16
-                if DEBUG: print "Rescaled, corrected for AR res is %sx%s" % 
(self.cropres[0], int(yscaled))
+                _debug_("Rescaled, corrected for AR res is %sx%s" % 
(self.cropres[0], int(yscaled)))
             else: # no scaling, w ehave a 4/3
                 yscaled = self.cropres[1]
             #new, calculate ideal res based on BPP
             idealres = self._OptimalRes(self.cropres[0], int(yscaled))
-            if DEBUG: print "Rescaled, rounded yres is %sx%s" % (idealres[0], 
idealres[1])
+            _debug_("Rescaled, rounded yres is %sx%s" % (idealres[0], 
idealres[1]))
             vf += [ "scale=%s:%s" % (idealres[0], idealres[1])]
-            
-        if DEBUG: print "Video filters: %s" % vf
-        
+
+        _debug_("Video filters: %s" % vf)
+
         #join vf options
         if len(vf)> 1:
             for vfopt in vf[0:-1]:
                 vfilter = vfilter + vfopt + ","
         if len(vf) >= 1:
             vfilter = vfilter + vf[-1]
-            
-        #if we have a dualpass, for the first pass, dump the output to 
/dev/null 
+
+        #if we have a dualpass, for the first pass, dump the output to 
/dev/null
         if passnr == 1:
             output="/dev/null"
         else:
             output=self.output
-        
+
         args = ["-oac", "copy", "-ovc",MencoderMapping[self.vcodec][0], 
MencoderMapping[self.vcodec][1][0],
-                MencoderMapping[self.vcodec][1][1] % (self.vbrate, vpass), 
+                MencoderMapping[self.vcodec][1][1] % (self.vbrate, vpass),
                 "-vf", vfilter, "-o", output]
-        
+
         #if we have a progressive ntsc file, lock the output fps (do this with 
ivtc too)
         if ("ivtc=1" in vf) or self.ntscprog:
             args = ["-ofps","23.976"].append(args)
-            
+
         #if we scale, use the bilinear algorithm
         if yscaled:
             args += ["-sws","1"]
-                
+
         return args
-    
+
     #from QuickRip, heavily adapted, new algo
     #TODO give this another name, it does more then crop detection only
-    def _CropDetectParse(self, lines, data): #seek to remove data 
-        """Parses Mplayer output to obtain ideal cropping parameters, and do 
PAL/NTSC detection""" 
-        
+    def _CropDetectParse(self, lines, data): #seek to remove data
+        """Parses Mplayer output to obtain ideal cropping parameters, and do 
PAL/NTSC detection"""
+
         re_crop = re.compile('.*-vf crop=(\d*:\d*:\d*:\d*).*')
         re_ntscprog = re.compile('24fps progressive NTSC content detected')
         re_pal = re.compile('25.000 fps')
         re_ana = re.compile('(aspect 3)')
-        
+
         crop_options = {}
 ##~         common_crop = ""
 ##~         cc_hits = 2
-        
+
         foundtype = False
-        
+
         for line in lines:
             if re_crop.search(line):
                 crop = re_crop.search(line).group(1)
@@ -381,7 +399,7 @@
 ##~                         common_crop = crop
                 except:
                     crop_options[crop] = 1
-                    
+
             #try to see if this is a PAL DVD, an NTSC Progressive DVD, ar an 
NTSC DVD
             if not foundtype and self.sourcetype == "dvd":
                 if re_pal.search(line):
@@ -391,25 +409,25 @@
                     if re_ntscprog.search(line):
                         self.ntscprog = True
                         foundtype = True
-                        
+
             if re_ana.search(line):
                 self.ana = True
 
         if not foundtype: self.ntsc = True
-        
-        if DEBUG: 
+
+        if DEBUG:
             print "All collected cropopts: %s" % crop_options
             if self.pal: print "This is a PAL dvd"
             if self.ntsc: print "This is an NTSC dvd"
-            if self.ntscprog: print "This is a progressive NTSC dvd" 
-        
+            if self.ntscprog: print "This is a progressive NTSC dvd"
+
         #if we didn't find cropping options (seems to happen sometimes on VERY 
short dvd chapters)
         if crop_options == {}:
             #end analyzing
             self.finishedanalyze = True
             return
-        
-        
+
+
         #some homegrown sleezy alghorythm to pick the best crop options
         hcounter = 0
         possible_crop = []
@@ -419,16 +437,16 @@
             if counter > hcounter:
                 hcounter = counter
                 possible_crop = [crop]
-        
+
         self.crop = possible_crop[0]
-        
+
         if len(possible_crop) > 1:
             for crop in possible_crop:
                 if crop < self.crop:
                     self.crop = crop
-                
-        
-        
+
+
+
         #make the final crop outputs a resolution wich is a multiple of 16 , v 
and h ....
         crop = split(self.crop, ":")
         adjustedcrop = []
@@ -438,26 +456,26 @@
         adjustedcrop += crop[2:]
         #save cropped resolution for later
         self.cropres = ( int(adjustedcrop[0]), int(adjustedcrop[1]) )
-        
+
         self.crop = join(adjustedcrop, ":")
-        
-        if DEBUG: print "Selected crop option: %s" % self.crop
-        
+
+        _debug_("Selected crop option: %s" % self.crop)
+
         #end analyzing
         self.finishedanalyze = True
-        
+
     def _CalcBPP(self, x, y):
         """Perform a BPP (Bits per Pixel calculation)"""
         if self.pal: fps = 25.000
         if self.ntscprog: fps = 23.976
         if self.ntsc: fps = 29.970
         return (self.vbrate * 1000)/(x * y * fps)
-        
+
     def _OptimalRes(self, x, y):
         """Using BPP calculations, try to find out the ideal resolution for 
this movie"""
         nonoptimal = True
         optx = x
-         
+
         #scale down until or ideal size is met
         while nonoptimal:
             #scale down x with 16 pix, calc y with the same AR as original x & 
y
@@ -470,11 +488,11 @@
                 opty += 16
             if self._CalcBPP( optx, opty ) >= 0.22:
                 nonoptimal = False
-                
+
         return ( int(optx), int (opty) )
-        
+
     #from Quickrip, adapted
-    def _MencoderParse(self, line, data): #seek to remove data 
+    def _MencoderParse(self, line, data): #seek to remove data
         """Parses mencoder stdout to get progress and trem"""
         #(passtype, title) = data
 
@@ -483,22 +501,22 @@
             self.percentage = re_progress.search(line).group(1)
             self.trem = re_progress.search(line).group(2)
             #self.ui_updateProgress(perc, trem, passtype)
-            
+
     #from QuickRip, adapted
     def _run(self, program, arguments, finalfunc, updatefunc=None,
                 flushbuffer=0, data=None, lock=None): # seek to remove data 
andor crop (not really used)
         """Runs a program; supply program name (string) and arguments (list)"""
-        command = [program] 
+        command = [program]
         command += arguments
 
         self.thread = CommandThread(self, command, updatefunc, finalfunc,
                                     flushbuffer, data, None) #self.lock)
-        self.thread.start()    
-        
-        
+        self.thread.start()
+
+
+
+
 
-        
-        
 #command executing class - Taken from Quickrip & adapted.
 class CommandThread(threading.Thread): # seek to remove data andor crop (not 
really used)
     """Handle threading of external commands"""
@@ -518,16 +536,16 @@
         pid = self.pipe.pid
         self.parent.pid = copy(pid)
         totallines = []
-        
-        if DEBUG: print "Mencoder running at PID %s" % self.pipe.pid
-        
+
+        _debug_("Mencoder running at PID %s" % self.pipe.pid)
+
         while 1:
             if self.flushbuffer:
                 line = self.pipe.fromchild.read(1000)
             else:
                 line = self.pipe.fromchild.readline()
 
-            if DEBUG: print line
+            _debug_(line)
             if not line:
                 break
             else:
@@ -540,7 +558,7 @@
 
         # Clean up process table--you already handle exceptions in the function
         #self.kill_pipe()
-        
+
         #give mplayer/mencoder some time to die before we try & kill it, or 
zombies will raise from their grave :)
         sleep(0.5)
 
@@ -548,14 +566,14 @@
             os.waitpid(pid, os.WNOHANG)
         except:
             pass
-            
+
         self.kill_pipe()
-        
+
         if self.finalFunc != None:
             self.finalFunc(totallines, self.data)
 
         #self.lock.release()
-        
+
         sys.exit(2)
 
 
@@ -566,28 +584,30 @@
             os.waitpid(self.pipe.pid, os.WNOHANG)
         except:
             pass
-            
-            
-            
+
+
+
 class EncodingQueue:
     """Class for generating an encoding queue"""
-    
-    def __init__(self, logger):
+
+    def __init__(self, logger, debug=0):
         #we keep a list and a dict because a dict doesn't store an order
+        global DEBUG
+        DEBUG = debug
         self.qlist = []
         self.qdict = {}
         self.running = False
         self.log = logger
-        
+
         #remove old files
         self._removeTmp()
-        
+
     def addEncodingJob(self, encjob):
         """Adds an encodingjob to the queue"""
-        
+
         self.qlist += [encjob]
         self.qdict[encjob.idnr] = encjob
-        
+
     def getProgress(self):
         """Gets progress on the current job"""
         if hasattr(self,"currentjob"):
@@ -595,14 +615,14 @@
                     int(self.currentjob.percentage), self.currentjob.trem)
         else:
             return "No job currently running"
-            
+
     def startQueue(self):
         """Start the queue"""
         if not self.running:
             self.running = True
-            self.log.info("queue started")
+            _debug_("queue started", 0)
             self._runQueue()
-            
+
     def listJobs(self):
         """Returns a list of queue'ed jobs"""
         if self.qdict == {}:
@@ -612,15 +632,15 @@
             for idnr, job in self.qdict.items():
                 jlist += [ (idnr, job.name, job.status) ]
             return jlist
-            
+
     def _removeTmp(self):
         """Removes possible temporary files created during encoding"""
         tmpfiles = ['frameno.avi', 'divx2pass.log', 'xvid-twopass.stats' ]
-        
+
         for tmpfile in tmpfiles:
             if os.path.exists(tmpfile):
                 os.remove(tmpfile)
-        
+
     def _runQueue(self, line="", data=""):
         """Executes the jobs in the queue, and gets called after every 
mencoder run is completed"""
         if self.qlist == []:
@@ -628,32 +648,32 @@
             self.running = False
             if hasattr(self,"currentjob"):
                 del self.currentjob
-            self.log.info("queue empty, stopping processing...")
+            _debug_("queue empty, stopping processing...", 0)
             return
-        
-        if DEBUG: print "runQueue callback data : %s" % line 
+
+        _debug_("runQueue callback data : %s" % line)
         #get the first queued object
         self.currentjob = self.qlist[0]
-        
-        if DEBUG: print "PID %s" % self.currentjob.pid
-        
+
+        _debug_("PID %s" % self.currentjob.pid)
+
         if self.currentjob.status == status.vpassfinal:
-            self.log.info("Job %s finished" % self.currentjob.idnr)
+            _debug_("Job %s finished" % self.currentjob.idnr, 0)
             #we are done with this job, remove it
             del self.qlist[0]
             del self.qdict[self.currentjob.idnr]
             #currently, keep running  until the queue is empty
             self._runQueue()
             return
-            
+
         if self.currentjob.status == status.vpass1:
             #start final video encoding pass
             self.currentjob.cls.pop(0)
             self.currentjob.status = status.vpassfinal
             #start video encoding
-            self.currentjob._run(mencoder, self.currentjob.cls[0], 
self._runQueue, 
+            self.currentjob._run(mencoder, self.currentjob.cls[0], 
self._runQueue,
                             self.currentjob._MencoderParse, 1, None)
-                            
+
         if self.currentjob.status == status.apass:
             #in case audio encoding started before auto-crop detection 
returned, we are gonna
             #rebuild the clis... audio encoding doesn't need cropping
@@ -665,37 +685,38 @@
                 self.currentjob.status = status.vpassfinal
             else:
                 self.currentjob.status = status.vpass1
-            self.currentjob._run(mencoder, self.currentjob.cls[0], 
self._runQueue, 
+            self.currentjob._run(mencoder, self.currentjob.cls[0], 
self._runQueue,
                             self.currentjob._MencoderParse, 1, None)
-                            
+
 
         if self.currentjob.status == status.notset:
             #generate cli's
             self.currentjob._generateCL()
-            if DEBUG: print "CLIs : %s" % self.currentjob.cls
-            
+            _debug_("CLIs : %s" % self.currentjob.cls)
+
             #clean out temporary files
             self._removeTmp()
-            
+
             #start audio encoding
             self.currentjob.status = status.apass
-            self.currentjob._run(mencoder, self.currentjob.cls[0], 
self._runQueue, 
+            self.currentjob._run(mencoder, self.currentjob.cls[0], 
self._runQueue,
                             self.currentjob._MencoderParse, 1, None)
-                            
-        self.log.info("Started job %s, %s on PID %s" % (self.currentjob.idnr, 
status[self.currentjob.status], self.currentjob.pid))
-        self.log.info("Encoder Command is %s" % self.currentjob.cls[0])
-            
-    
-            
+
+        _debug_("Started job %s, %s on PID %s" % (self.currentjob.idnr, \
+            status[self.currentjob.status], self.currentjob.pid), 0)
+        _debug_("Encoder Command is %s" % self.currentjob.cls[0], 0)
+
+
+
 # -----DEBUGGING STUFF BELOW---USE ONLY WHEN WEARING A BULLETPROOF VEST ;)
-            
-            
+
+
 ##~ def conc(list):
 ##~     str = ""
 ##~     for el in list:
 ##~         str = str + el + " "
-##~     return str            
-            
+##~     return str
+
 #FOR TESTING ONLY
 if __name__ == '__main__':
     encjob = EncodingJob('/storage/video/dvd/BRUCE_ALMIGHTY/', 
'test.avi','lala', 456789, 17)
@@ -716,10 +737,7 @@
     import logging
     log = logging.getLogger("EncodingCore")
     log.setLevel(logging.DEBUG)
-    
-    queue = encodingqueue(log)
+
+    queue = encodingqueue(log, 2)
     queue.addEncodingJob(encjob)
     queue.startqueue()
-    
-
-    

Modified: branches/rel-1/freevo/src/helpers/encodingserver.py
==============================================================================
--- branches/rel-1/freevo/src/helpers/encodingserver.py (original)
+++ branches/rel-1/freevo/src/helpers/encodingserver.py Thu Oct 19 16:49:39 2006
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 # -----------------------------------------------------------------------
-# EncodingServer.py, part of EncodingServer - for use with or without Freevo
+# EncodingServer.py, part of EncodingServer - for use with Freevo
 # -----------------------------------------------------------------------
 # $Id: rc.py 8278 2006-09-30 07:22:11Z duncan $
 #
@@ -27,14 +27,34 @@
 #
 # -----------------------------------------------------------------------
 
-#Import statements
+import sys, string, random, time, os, re, pwd, stat
+import config
+from util import vfs
+
+appname = os.path.splitext(os.path.basename(sys.argv[0]))[0]
+appconf = appname.upper()
+
+# change uid
+if __name__ == '__main__':
+    uid='config.'+appconf+'_UID'
+    gid='config.'+appconf+'_GID'
+    try:
+        if eval(uid) and os.getuid() == 0:
+            os.setgid(eval(gid))
+            os.setuid(eval(uid))
+            os.environ['USER'] = pwd.getpwuid(os.getuid())[0]
+            os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]
+    except Exception, e:
+        print e
+
 from twisted.web import xmlrpc, server
 from twisted.internet.app import Application
 from twisted.internet import reactor
 from twisted.python import log
 from util.marmalade import jellyToXML, unjellyFromXML
-import logging
 import time, random, sys, os
+import logging
+import config
 
 from encodingcore import EncodingJob, EncodingQueue
 
@@ -44,9 +64,19 @@
 __copyright__ = "Copyright (C) 2004 den_RDC"
 __license__ = "GPL"
 
-tmppath = '/tmp/encodingserver'
+DEBUG = hasattr(config, appconf+'_DEBUG') and eval('config.'+appconf+'_DEBUG') 
or config.DEBUG
 
-DEBUG=False
+logfile = '%s/%s-%s.log' % (config.LOGDIR, appname, os.getuid())
+log.startLogging(open(logfile, 'a'))
+
+def _debug_(text, level=1):
+    if DEBUG >= level:
+        try:
+            log.debug(String(text))
+        except:
+            print String(text)
+
+tmppath = '/tmp/encodingserver'
 
 jam = jellyToXML
 unjam = unjellyFromXML
@@ -57,23 +87,25 @@
         self.jobs = {}
         
         #setup a logger
-        if debug: #when debugging, output everything to stdout using the root 
logging class
-            self.log = logging
-        else: #normally, write nice formatted messages to a logfile)
-            self.log = logging.getLogger("EncodingServer")
-            self.log.setLevel(logging.INFO)
-            FHandler = logging.FileHandler("encodingserver.log")
-            FHandler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s 
%(message)s"))
-            self.log.addHandler(FHandler)
+        #if debug: #when debugging, output everything to stdout using the root 
logging class
+        #    self.log = logging
+        #else: #normally, write nice formatted messages to a logfile)
+        #    self.log = logging.getLogger("EncodingServer")
+        #    self.log.setLevel(logging.INFO)
+        #    FHandler = logging.FileHandler("encodingserver.log")
+        #    
FHandler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s 
%(message)s"))
+        #    self.log.addHandler(FHandler)
         
-        self.queue = EncodingQueue(self.log)
+        self.queue = EncodingQueue(log, DEBUG)
         
-        self.log.info("EncodingServer started...")
+        _debug_("EncodingServer started...", 0)
         
     def xmlrpc_echotest(self, blah):
+        _debug_("xmlrpc_echotest(self, blah)", 2)
         return (True, 'EncodingServer::echotest: %s' % blah)
 
     def xmlrpc_initEncodeJob(self, source, output, friendlyname="", 
chapter=None):
+        _debug_("xmlrpc_initEncodeJob(self, %s, %s, %s, %s)" % (source, 
output, friendlyname, chapter), 2)
         #safety checks
         if not (source or output):
             return (False, 'EncodingServer::initEncodeJob:  no source or 
output given')
@@ -81,20 +113,23 @@
         #in p2.3 , int() can return long int's, wich is fine, except it makes 
XMLRPC fail somwhere along the way
         # so we devide or random number by 100 :)
         idnr = int((time.time() / random.random()) / 100)
+        _debug_("idnr=%s" % (idnr), 2)
         self.jobs[idnr] = EncodingJob(source, output, friendlyname, idnr, 
chapter)
         
         #wait for the analyzing to end
         while not self.jobs[idnr].finishedanalyze:
             time.sleep(0.1)
         
-        self.log.info("Initialized job %s (idnr : %s)" % (friendlyname,idnr))
+        _debug_("Initialized job %s (idnr : %s)" % (friendlyname,idnr), 0)
         
         return (True, idnr)
         
     def xmlrpc_getContainerCAP(self, idnr):
+        _debug_("xmlrpc_getContainerCAP(self, idnr)", 2)
         return (True, jam(self.jobs[idnr].getContainerList()))
        
     def xmlrpc_setContainer(self, idnr, container):
+        _debug_("xmlrpc_setContainer(self, idnr, container)", 2)
         status = self.jobs[idnr].setContainer(container)
         
         if not status:
@@ -103,9 +138,11 @@
             return (False, "EncodingServer::setContainer: %s" % status)
             
     def xmlrpc_getVideoCodecCAP(self, idnr):
+        _debug_("xmlrpc_getVideoCodecCAP(self, idnr)", 2)
         return (True, jam(self.jobs[idnr].getVideoCodecList()))
         
     def xmlrpc_setVideoCodec(self, idnr, vcodec, tgtsize, multipass=False):
+        _debug_("xmlrpc_setVideoCodec(self, idnr, vcodec, tgtsize, 
multipass=False)", 2)
         #safety checks
         if not (vcodec or tgtsize):
             return (False, 'EncodingServer::setVideoCodec:  no codec or target 
size given')
@@ -118,9 +155,11 @@
             return (False, "EncodingServer::setVideoCodec: %s" % status)   
            
     def xmlrpc_getAudioCodecCAP(self, idnr):
+        _debug_("xmlrpc_getAudioCodecCAP(self, idnr)", 2)
         return (True, jam(self.jobs[idnr].getAudioCodecList()))
         
     def xmlrpc_setAudioCodec(self, idnr, acodec, abrate):
+        _debug_("xmlrpc_setAudioCodec(self, idnr, acodec, abrate)", 2)
         #safety checks
         if not (acodec or abrate):
             return (False, 'EncodingServer::setAudioCodec:  no codec or 
bitrate given')
@@ -133,10 +172,12 @@
             return (False, "EncodingServer::setAudioCodec: %s" % status)
             
     def xmlrpc_getVideoFiltersCAP(self, idnr):
+        _debug_("xmlrpc_getVideoFiltersCAP(self, idnr)", 2)
         return (True, jam(self.jobs[idnr].getVideoFiltersList()))
         
 
     def xmlrpc_setVideoFilters(self, idnr, filters):
+        _debug_("xmlrpc_setVideoFilters(self, idnr, filters)", 2)
         #safety checks
         if not filters:
             return (False, 'EncodingServer::setAudioCodec:  no codec or 
bitrate given')
@@ -149,33 +190,34 @@
             return (False, "EncodingServer::setVideoFilters: %s" % status)
         
     def xmlrpc_queueIt(self, idnr, now=False):
+        _debug_("xmlrpc_queueIt(self, idnr, now=False)", 2)
         self.queue.addEncodingJob(self.jobs[idnr])
         del self.jobs[idnr]
-        self.log.info("Added job %s to the queue" % idnr)
+        _debug_("Added job %s to the queue" % idnr, 0)
         if now:
             self.queue.startQueue()
         return (True, "EncodingServer::queueIt: OK")
         
     def xmlrpc_getProgress(self):
+        _debug_("xmlrpc_getProgress(self)", 2)
         prog = self.queue.getProgress()
         if type(prog) is str:
             return (False, "EncodingServer::getProgress: %s" % prog)
         return (True, jam(prog))
         
     def xmlrpc_startQueue(self):
+        _debug_("xmlrpc_startQueue(self)", 2)
         self.queue.startQueue()
-        
         return (True, "EncodingServer::startqueue: OK")
         
     def xmlrpc_listJobs(self):
+        _debug_("xmlrpc_listJobs(self)", 2)
         jlist = self.queue.listJobs()
-        
         return (True, jam(jlist))
 
         
-        
-
 def main():
+    global DEBUG
     #check for /tmp/encodingserver and if it doesn't exist make it
     if not (os.path.exists(tmppath) and os.path.isdir(tmppath)):
         os.mkdir(tmppath)
@@ -185,12 +227,15 @@
     app = Application("EncodingServer")
     if len(sys.argv) >= 2 and sys.argv[1] == "debug":
         es = EncodingServer(True)
-        DEBUG=True
         import encodingcore
         encodingcore.DEBUG=True
     else:
         es = EncodingServer()
-    app.listenTCP(6666, server.Site(es))
+    _debug_('main: DEBUG=%s' % DEBUG, 0)
+    if (DEBUG == 0):
+        app.listenTCP(config.ENCODINGSERVER_PORT, server.Site(es, 
logPath='/dev/null'))
+    else:
+        app.listenTCP(config.ENCODINGSERVER_PORT, server.Site(es))
     app.run(save=0)
     
 
@@ -204,5 +249,5 @@
         except:
             traceback.print_exc()
             if start + 10 > time.time():
-                print 'server problem, sleeping 1 min'
+                _debug_('server problem, sleeping 1 min', 0)
                 time.sleep(60)

Copied: branches/rel-1/freevo/src/video/encodingclient.py (from r8414, 
/branches/rel-1/freevo/src/encodingclient.py)
==============================================================================
--- /branches/rel-1/freevo/src/encodingclient.py        (original)
+++ branches/rel-1/freevo/src/video/encodingclient.py   Thu Oct 19 16:49:39 2006
@@ -27,17 +27,18 @@
 # -----------------------------------------------------------------------
 
 import xmlrpclib, sys
-from twisted.persisted import marmalade
+from util.marmalade import jellyToXML, unjellyFromXML
+import config
 
 
 server_string = 'http://%s:%s/' % \
-                ("localhost", 6666)
+                (config.ENCODINGSERVER_IP, config.ENCODINGSERVER_PORT)
 
-server = xmlrpclib.Server(server_string)
+server = xmlrpclib.Server(server_string, allow_none=1)
 #server = object() - uncomment this and comment the previous line to enable 
pychecker testing
 
-jam = marmalade.jellyToXML
-unjam = marmalade.unjellyFromXML
+jam = jellyToXML
+unjam = unjellyFromXML
 
 #some data
 __author__ = "den_RDC ([EMAIL PROTECTED])"
@@ -115,14 +116,15 @@
     This call can take some time (10 seconds on average) before returning, 
because the
     encodingserver analyzes the video during this call."""
         
+    _debug_('initEncodeJob(%s, %s, %s, %s)' % (source, output, friendlyname, 
title), 0)
     if not (source or output):
         return (False, "EncodingClient: no source and/or output")
         
     try:
         (status, response) = server.initEncodeJob(source, output, 
friendlyname, title)
     except:
-##~         print "Unexpected eroor:", sys.exc_info()[0]
-##~         raise
+        print "Unexpected error:", sys.exc_info()[0]
+        raise
         return (False, 'EncodingClient: connection error')
     
     return (status, response)

Modified: branches/rel-1/freevo/src/video/plugins/dvdbackup.py
==============================================================================
--- branches/rel-1/freevo/src/video/plugins/dvdbackup.py        (original)
+++ branches/rel-1/freevo/src/video/plugins/dvdbackup.py        Thu Oct 19 
16:49:39 2006
@@ -30,7 +30,7 @@
 from os.path import join, split
 import plugin, config, menu
 #import config
-from encodingclient import *
+from video.encodingclient import *
 from gui.AlertBox import AlertBox
 from gui.PopupBox import PopupBox
 
@@ -84,6 +84,8 @@
         menuw.pushmenu(encoding_menu)
         
     def create_job(self, menuw=None, arg=None):
+        '''
+        '''
         #create a filename for the to-be-encoded dvd title
         #title = int(self.item.url[6:])
         fname = join(config.VIDEO_ITEMS[0][1], "%s_%s.avi" % 
(self.item.parent.name, self.title))

Added: branches/rel-1/freevo/src/video/plugins/reencode.py
==============================================================================
--- (empty file)
+++ branches/rel-1/freevo/src/video/plugins/reencode.py Thu Oct 19 16:49:39 2006
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# re-encode recorded TV programmes
+# -----------------------------------------------------------------------
+# $Id: encode.py $
+#
+# Notes:
+#    To activate, put the following line in local_conf.py:
+#       plugin.activate('tv.encode')
+# ToDo:        
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al. 
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+
+from os.path import join, split
+import plugin
+import menu
+import config
+from video.encodingclient import *
+from gui.AlertBox import AlertBox
+from gui.PopupBox import PopupBox
+
+DEBUG = config.DEBUG
+DEBUG = 9
+
+print "DJW: reencode DEBUG=%s" % DEBUG
+
+class PluginInterface(plugin.ItemPlugin):
+    """
+    Plug-in to archive recorded TV programmes using EncodingServer
+    
+    This plugin NEEDS a running encodingserver to work properly.
+    You can start an encodingserver with "freevo encodingserver start".
+    """
+
+class PluginInterface(plugin.ItemPlugin):
+    def __init__(self):
+        _debug_('__init__')
+        plugin.ItemPlugin.__init__(self)
+
+
+    def actions(self, item):
+        #testing stuff
+        for d in dir(item):
+            print '%s: %s' % (d, eval('item.%s' % d))
+        for d in dir(item.info):
+            print '%s: %s' % (d, eval('item.info.%s' % d))
+        print 'type:', item.type
+        print 'mode:', item.mode
+        print 'name:', type(item.name)
+        print 'name:', item.name.encode('utf-8')
+        print 'filename:', item.filename
+        if hasattr(item, 'parentname'):
+            print item.parentname
+        if hasattr(item, 'media'):
+            print 'media:', item.media
+            if hasattr(item.media, 'devicename'):
+                print item.media.devicename
+            
+        if item.type == 'video' and item.mode == 'file':
+                #for dvd on disc
+                self.dvdsource = item.filename
+                
+                self.title = item.name
+                self.source = item.filename
+                self.filename = 
item.filename[0:item.filename.rfind('.')]+'.divx'
+
+                self.item = item
+                return [ (self.encoding_profile_menu, _('Re-encode this 
program...')) ]
+        return []
+        
+    def encoding_profile_menu(self, menuw=None, arg=None):
+        #create a menu with a few encoding options (1cd, 2cd, xvid, mpeg4)
+        #args : tuple, (videocodec, size, multipass
+        menu_items = [ menu.MenuItem("XViD, 700mb", self.create_job, 
(1,700,False)) ]
+        menu_items.append( menu.MenuItem("XViD, 700mb, High Quality", 
self.create_job, (1,700,True)) )
+        menu_items.append( menu.MenuItem("XViD, 1400mb", self.create_job, 
(1,1400,False)) )
+        menu_items.append( menu.MenuItem("XViD, 1400mb, High Quality", 
self.create_job, (1,1400,True)) )
+        menu_items.append( menu.MenuItem("DivX, 700mb", self.create_job, 
(0,700,False)) )
+        menu_items.append( menu.MenuItem("DivX, 700mb, High Quality", 
self.create_job, (0,700,True)) )
+        menu_items.append( menu.MenuItem("DivX, 1400mb", self.create_job, 
(0,1400,False)) )
+        menu_items.append( menu.MenuItem("DivX, 1400mb, High Quality", 
self.create_job, (0,1400,True)) )
+        
+        encoding_menu = menu.Menu(_('Choose your encoding profile'), 
menu_items)
+        menuw.pushmenu(encoding_menu)
+        
+    def create_job(self, menuw=None, arg=None):
+        print 'arg:', arg
+        #unwrap settings tupple
+        vcodecnr, tgtsize, mpass = arg
+
+        #we are going to create a job and send it to the encoding server, this 
can take some time while analyzing
+        
+        box = PopupBox(text=_('Please wait, analyzing video...'))
+        box.show()
+
+        (status, resp) = initEncodeJob(self.source, self.filename, self.title)
+        print 'initEncodeJob:status:', status, ' resp:', resp
+                
+        box.destroy()
+        
+        if not status:
+            self.error(resp)
+            return
+            
+        idnr = resp
+        
+        #ask for possible containers and set the first one (should be avi), we 
will get a list
+        (status, resp) = getContainerCAP(idnr)
+        print 'getContainerCAP:status:', status, ' resp:', resp
+            
+        if not status:
+            self.error(resp)
+            return
+        
+        container = resp[0]
+        
+        (status, resp) = setContainer(idnr, container)
+        print 'setContainer:status:', status, ' resp:', resp
+        
+        if not status:
+            self.error(resp)
+            return
+            
+        #ask for possible videocodec and set the first one (should be mpeg4), 
we will get a list
+        (status, resp) = getVideoCodecCAP(idnr)
+        print 'getVideoCodecCAP:status:', status, ' resp:', resp
+            
+        if not status:
+            self.error(resp)
+            return
+        
+        vcodec = resp[vcodecnr]
+        
+        (status, resp) = setVideoCodec(idnr, vcodec, tgtsize, mpass)
+        print 'setVideoCodec:status:', status, ' resp:', resp
+        
+        if not status:
+            self.error(resp)
+            return
+            
+        #ask for possible audiocodec and set the first one (should be mp3), we 
will get a list
+        #Audiocodec call isn't necessary atm, it defaults to 128 kbit mp3, but 
this might change in the future
+        #so we play safe
+        (status, resp) = getAudioCodecCAP(idnr)
+        print 'getAudioCodecCAP:status:', status, ' resp:', resp
+            
+        if not status:
+            self.error(resp)
+            return
+        
+        acodec = resp[0]
+        
+        (status, resp) = setAudioCodec(idnr, acodec, 128)
+        print 'setAudioCodec:status:', status, ' resp:', resp
+        
+        if not status:
+            self.error(resp)
+            return
+        
+        #And finally, qeue and start the job
+        (status, resp) = queueIt(idnr, True)
+        print 'queueIt:status:', status, ' resp:', resp
+            
+        if not status:
+            self.error(resp)
+            return
+        
+        self.menuw = menuw
+        AlertBox(width=400, height=200, text=_("Encoding started"), 
handler=self.mopup).show()
+        
+        print "boe"
+        #menuw.delete_menu()
+        #menuw.delete_menu()       
+        
+        
+        
+    def error(self, text=""):
+        AlertBox(width=400, height=200, text="ERROR: %s" % text).show()
+        
+    
+    def mopup(self):
+        self.menuw.delete_menu()
+        self.menuw.back_one_menu()

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to