[prev in list] [next in list] [prev in thread] [next in thread] 

List:       helix-player-dev
Subject:    Re: [Player-dev] CR: player_kit_python_hxrecord: Runtime config of
From:       Greg Wright <gwright () real ! com>
Date:       2007-10-18 20:26:03
Message-ID: 4717C15B.8080306 () real ! com
[Download RAW message or body]

Looks good.
--greg.


Peter Krenesky wrote:
> Modified by: Peter Krenesky <peter@osuosl.org>
> Date: <10:04:07>
> Project: player_kit_python_hxrecord
> 
> Synopsis: hxrecord has functions for setting library paths but they did not 
> function.  Currently the libraries must be in a specific directory structure 
> making it hard to setup.  This patch allows for the library path to be set at 
> runtime by different means.
> 
> version 2 of this CR - no longer supports current working directory as a 
> default
> 
> Overview:
> 
> * All librarys are required to be in a single directory.
> * functions for setting path explicitly are hxrecord.setEnginePath() and 
> hxrecord.setPluginPath().  They expect the directory path containing the main 
> engine library and plugins directory respectively
> * Logic for default paths and setting a custom path has been refactored.  
> Path will be chosen in this priority:
> 1) User defined path with hxrecord.setDLLPath() or 
> hxrecord.setPluginPath()
> 2) directory specified by HELIX_LIBS env variable
> * Example code added to samples/pygtk-producer.py
> * setPluginPath() can be called at any time before encoding job and its 
> children objects are created
> 
> Files Modified: 
> hxrecord.cpp
> hxrecord.h
> pyrecord.cpp
> samples/command_line_encoder.py
> samples/pygtk-producer.py
> 
> Platforms and Profiles Functionality verified:
> x86 helix-client-OLPC
> 
> Branch: HEAD
> 
> Copyright assignment:
> 
> In consideration for RealNetworks' hosting and maintenance of my modification,
> I agree to assign to RealNetworks full copyright ownership of the code 
> included
> in the attached patch, and agree that RealNetworks has no duty of accounting 
> to
> me for it. I warrant that this code is entirely original to and owned by me, 
> that I can legally grant the copyright assignment, and that my contribution
> does not violate any other person's rights, and laws or breach any contract. I
> understand that RealNetworks may license this code under RPSL, RCSL, and/or 
> any
> other license at RealNetworks' discretion, and use the code in any way.
> 
> QA Instructions: Try different methods of setting the path or placement of 
> libraries
> 
> 
> Index: hxrecord.cpp
> ===================================================================
> RCS file: /cvsroot/player/kit/python/hxrecord/hxrecord.cpp,v
> retrieving revision 1.1
> diff -u -w -r1.1 hxrecord.cpp
> --- hxrecord.cpp	24 Sep 2007 17:04:26 -0000	1.1
> +++ hxrecord.cpp	17 Oct 2007 20:07:26 -0000
> @@ -910,59 +910,8 @@
> , m_fpCreateJobFactory(NULL)    
> , m_fpSetDllAccessPath(NULL)
> {
> -    memset(m_szLibPath, 0, sizeof(m_szLibPath));
> -	memset(m_szPluginPath, 0, sizeof(m_szPluginPath));
> -
> -    //setup default path	
> -#ifdef _MACINTOSH
> -    char                    dllhome[MAX_PATH]       = {'\0'}; /* Flawfinder: 
> ignore */
> -#elif defined(_SYMBIAN)
> -    char                    dllhome[MAX_PATH]       = "c:"; /* Flawfinder: 
> ignore */
> -#else
> -    char                    dllhome[MAX_PATH]       = {'.','\0'}; /* 
> Flawfinder: ignore */
> -#endif
> -    
> -    //See if the user has set their HELIX_LIBS env var. This is overridden by 
> the
> -    //const char* pszHelixLibs = getenv("HELIX_LIBS");
> -    //if( pszHelixLibs )
> -    //   strcpy( dllhome,  pszHelixLibs);
> -
> -	//default name for core library
> -    sprintf(m_szLibPath, "%s/%s", dllhome, "tools/encsession.so");
> -	
> -
> -    // Note that if you do not call SetDLLAccessPaths, the SDK will assume 
> the current working
> -    // directory matches the structure of %sdk_install_dir%\bin.  Namely, 
> that the current working directory
> -    // has plugins, codecs, tools, and common subdirectories with the 
> appropriate DLLs.  As long as this application is run
> -    // from the %sdk_install_dir%\bin directory, you can skip this step (just 
> comment out the call to SetDLLAccessPath
> -    // to try it)
> -    
> -    // Create a null delimited, double-null terminated string containing DLL 
> category
> -    // name/path pairs.  The default structure of the SDK has discrete 
> subdirectories for each DLL category.  If
> -    // you wish, all DLLs can be placed within a single directory.  The path 
> passed to SetDLLAccessPath simply
> -    // needs to reflect this.
> -    
> -    
> -    UINT32 ulNumChars = 0;
> -    
> -    // Assume the current working directory is %sdk_install_dir%\bin -- this 
> would normally be set to an absolute path
> -    // Note that this is the one and only place in the Producer SDK that 
> requires an HFS path (all other pathnames
> -    // on the Mac should be POSIX-style).
> -#ifdef _WINDOWS	
> -    const char* pCurrentDir = ".\\";
> -#elif defined _LINUX
> -    const char* pCurrentDir = "./";
> -#elif defined _MAC_UNIX
> -    const char* pCurrentDir = "./";
> -#endif
> -    
> -    ulNumChars += sprintf(m_szPluginPath+ulNumChars, "%s=%s%s", "DT_Plugins", 
> pCurrentDir, "plugins") + 1;
> -    ulNumChars += sprintf(m_szPluginPath+ulNumChars, "%s=%s%s", "DT_Codecs", 
> pCurrentDir, "codecs") + 1;
> -    ulNumChars += sprintf(m_szPluginPath+ulNumChars, "%s=%s%s", "DT_EncSDK", 
> pCurrentDir, "tools") + 1;
> -    ulNumChars += sprintf(m_szPluginPath+ulNumChars, "%s=%s%s", "DT_Common", 
> pCurrentDir, "common") + 1;	
> -	
> -	
> -	
> +    m_szLibPath[0] = 0;
> +    m_szPluginPath[0] = 0;
> }
> 
> /*
> @@ -980,6 +929,23 @@
> PyHxRecordCore::Load()
> {
> HX_RESULT  res;
> +    const char* pszHelixLibs = NULL;
> +
> +    //set default path if none is set
> +    if(m_szLibPath[0] == 0)
> +    {
> +        //See if the user has set their HELIX_LIBS env var. HELIX_LIBS is 
> overridden by setting the path explicitly
> +        pszHelixLibs = getenv("HELIX_LIBS");
> +        if( pszHelixLibs )
> +        {
> +           SetDLLPath(pszHelixLibs);
> +        }
> +        else
> +        {
> +            //for now path must be explicitly set
> +            return 0;
> +        }
> +    }
> 
> // prepare/load the HXRecord module
> m_lib = LoadLib(m_szLibPath);
> @@ -1009,8 +975,31 @@
> // Create the job class factory	
> 	res = (*m_fpCreateJobFactory)(&m_piClassFactory);    
> 
> -    // Set plugin Paths
> +    // Note that if you do not call SetDLLAccessPaths, the SDK will assume 
> the current working
> +    // directory matches the structure of %sdk_install_dir%\bin.  Namely, 
> that the current working directory
> +    // has plugins, codecs, tools, and common subdirectories with the 
> appropriate DLLs.      
> +
> +    // use current working directory as default plugin path if path not 
> already set
> +    if (m_szPluginPath[0] == 0)
> +    {
> +        if (!pszHelixLibs)
> +            pszHelixLibs = getenv("HELIX_LIBS");
> +
> +        if (pszHelixLibs)
> +        {
> +           SetPluginPath(pszHelixLibs);
> +        }
> +        else
> +        {
> +            // for now path must be explicitly set
> +            return 0;
> +        }
> +    }
> +    else
> +    {
> +        //even if path was not null, it couldn't have been set yet in the 
> library so call the library function.
> res = (*m_fpSetDllAccessPath)(m_szPluginPath);        
> +    }
> 
> /* initialize the player callbacks */
> for (int i = 0; i < NUM_EHXTEVENTS; ++i)
> @@ -1065,44 +1054,54 @@
> *  Set the access path from which to load plugins at each
> *  CreateJob() call. 
> */
> -PyObject *
> +HX_RESULT
> PyHxRecordCore::SetPluginPath(const char *path)
> {
> HX_RESULT res = HXR_OK;    
> +    UINT32 ulNumChars = 0;
> 
> -	if (m_fpSetDllAccessPath)
> -	{	  	    
> -	    if (m_fpSetDllAccessPath)
> -	    {
> -		    res = (*m_fpSetDllAccessPath)(path);
> -            if (SUCCEEDED(res))
> -            {
> -            //m_szPluginPath = path;    
> -	        }
> -	        else
> +#ifndef _MACINTOSH
> +    /* make sure the path exists */
> +    struct stat st;
> +    if (0 != stat(path, &st) || !(st.st_mode & S_IFDIR))
> 	        {
> -		    res = HXR_FAIL;
> -	        }
> -        }
> +	PyErr_Format(PyExc_ValueError, "No such directory: %s", path);
> +	return HXR_FAIL;
> 	}
> -	else
> +#endif
> +
> +    //empty the path
> +    memset(m_szPluginPath, 0, sizeof(m_szPluginPath));
> +
> +    // Create a null delimited, double-null terminated string containing DLL 
> category
> +    // name/path pairs.  The default structure of the SDK has discrete 
> subdirectories for each DLL category.  If
> +    // you wish, all DLLs can be placed within a single directory.  The path 
> passed to SetDLLAccessPath simply
> +    // needs to reflect this.
> +
> +    //for now all libraries should be in the same directory       
> +    ulNumChars += sprintf(m_szPluginPath+ulNumChars, "%s=%s", "DT_Codecs", 
> path) + 1;
> +    ulNumChars += sprintf(m_szPluginPath+ulNumChars, "%s=%s", "DT_Common", 
> path) + 1;
> +    ulNumChars += sprintf(m_szPluginPath+ulNumChars, "%s=%s", "DT_EncSDK", 
> path) + 1;
> +    ulNumChars += sprintf(m_szPluginPath+ulNumChars, "%s=%s", "DT_Plugins", 
> path) + 1;
> +
> +    // check for library function, if it is not null
> +    // the module was already initialized and the path
> +    // should be updated
> +	if (m_fpSetDllAccessPath)
> 	{
> -	    res = HXR_FAIL;
> +	    res = (*m_fpSetDllAccessPath)(m_szPluginPath);
> 	}
> 
> -    Py_INCREF(Py_None);
> -    return Py_None;
> +    return res;
> }
> 
> /*
> - *  Set the access path from which to load codecs at each
> - *  CreatePlayer() call. 
> + *  Set the access path from which to load the main library
> */
> -PyObject *
> +HX_RESULT
> PyHxRecordCore::SetDLLPath(const char *path)
> {
> -    char      *accesspaths;    
> -    int       pathsize;    
> +    memset(m_szLibPath, 0, sizeof(m_szLibPath));
> 
> #ifndef _MACINTOSH
> /* make sure the path exists */
> @@ -1110,16 +1109,14 @@
> if (0 != stat(path, &st) || !(st.st_mode & S_IFDIR))
> {
> 	PyErr_Format(PyExc_ValueError, "No such directory: %s", path);
> -	return NULL;
> +	return HXR_FAIL;
> }
> #endif
> 
> -    pathsize = MAX_PATH + 2; /* double null-terminated */
> -    accesspaths = new char[pathsize]; 
> -    memset(accesspaths, 0, pathsize);
> +    //default name for core library
> +    sprintf(m_szLibPath, "%s/%s", path, "encsession.so");
> 	       
> -    Py_INCREF(Py_None);
> -    return Py_None;
> +    return HXR_OK;
> }
> 
> void 
> Index: hxrecord.h
> ===================================================================
> RCS file: /cvsroot/player/kit/python/hxrecord/hxrecord.h,v
> retrieving revision 1.1
> diff -u -w -r1.1 hxrecord.h
> --- hxrecord.h	24 Sep 2007 17:04:26 -0000	1.1
> +++ hxrecord.h	17 Oct 2007 20:07:26 -0000
> @@ -89,8 +89,8 @@
> const char *GetPath()
> { return m_szLibPath; }
> 
> -    PyObject* SetDLLPath(const char *path);
> -    PyObject* SetPluginPath(const char *path);    
> +    HX_RESULT SetDLLPath(const char *path);
> +    HX_RESULT SetPluginPath(const char *path);    
> HX_RESULT InitializeLogSystem(const char *path);
> 
> void SetPyError(HX_RESULT res);    
> Index: pyrecord.cpp
> ===================================================================
> RCS file: /cvsroot/player/kit/python/hxrecord/pyrecord.cpp,v
> retrieving revision 1.1
> diff -u -w -r1.1 pyrecord.cpp
> --- pyrecord.cpp	24 Sep 2007 17:04:26 -0000	1.1
> +++ pyrecord.cpp	17 Oct 2007 20:07:26 -0000
> @@ -80,8 +80,7 @@
> static char hx_version[] = "0.0.0.1";
> 
> /* module function doc strings */
> -static char hx_codecpath_doc[] = "Set the location that the client engine 
> searches for codecs \
> -    path -- the path to search";
> +
> static char hx_create_audience_doc[] = "Creates an audience using the 
> dictionary of properties passed in";
> static char hx_create_destination_doc[] = "Creates a destination using the 
> dictionary of properties passed in";
> static char hx_create_input_doc[] = "Creates an input using the dictionary of 
> properties passed in";
> @@ -94,36 +93,18 @@
> static char hx_create_time_doc[] = "Creates a time object";
> static char hx_init_doc[] = "Initializes the Helix engine core";
> static char hx_init_logging_doc[] = "Initializes the logging system and opens 
> the file requested as a log file";
> -static char hx_pluginpath_doc[] = "Set the location that the client engine 
> searches for plugins \
> -    path -- the path to search";
> static char hx_set_callback_doc[] = "Sets an event callback to the python 
> function passed in";
> +static char hx_set_dllpath_doc[] = "Set the location of the producer engine \
> +    path -- the path to search";
> +static char hx_set_pluginpath_doc[] = "Set the location that the client 
> engine searches for plugins \
> +    path -- the path to search";
> 
> 
> -/* module function definitions */
> 
> +/* module function definitions */
> 
> 
> 
> -/*
> - *  Set the client engine codec path.
> - */
> -static PyObject *
> -hx_codecpath
> -(
> -    PyObject *self,
> -    PyObject *args
> -)
> -{
> -    const char *path;
> -    
> -    if (!PyArg_ParseTuple(args, "s", &path))
> -    return NULL;
> -    
> -    // TODO IMPLEMENT THIS?
> -    //return core->SetCodecPath(path);
> -    return NULL;
> -}
> -
> static PyObject*
> hx_create_audience
> (
> @@ -150,7 +131,6 @@
> 
> if (FAILED(res)) 
> {
> -        Py_INCREF(Py_None);
> return NULL;
> }
> 
> @@ -489,59 +469,89 @@
> }
> 
> /*
> - *  Set the client engine plugin path.
> + *  Sets an event callback
> */
> static PyObject *
> -hx_pluginpath
> +hx_set_callback
> (
> PyObject *self,
> PyObject *args
> )
> {
> -    const char *path;
> +    UINT32 event;
> +    PyObject *func;
> 
> -    if (!PyArg_ParseTuple(args, "s", &path))
> +    if (!PyArg_ParseTuple(args, "iO", &event, &func))
> return NULL;
> 
> -    return core->SetPluginPath(path);    
> +    /* check for a valid callback */
> +    if (!PyCallable_Check(func))
> +    {
> +	    PyErr_SetString(PyExc_ValueError, 
> +	        "parameter must be callable");
> +	    return NULL;
> +    }
> +
> +    core->SetCallback(event, func);
> +
> +    Py_INCREF(Py_None);
> +    return Py_None;
> }
> 
> /*
> - *  Sets an event callback
> + *  Set the client engine path.
> */
> static PyObject *
> -hx_set_callback
> +hx_set_dllpath
> (
> PyObject *self,
> PyObject *args
> )
> {
> -    UINT32 event;
> -    PyObject *func;
> +    const char *path;
> 
> -    if (!PyArg_ParseTuple(args, "iO", &event, &func))
> +    if (!PyArg_ParseTuple(args, "s", &path))
> return NULL;
> 
> -    /* check for a valid callback */
> -    if (!PyCallable_Check(func))
> +    if(SUCCEEDED(core->SetDLLPath(path)))
> {
> -	    PyErr_SetString(PyExc_ValueError, 
> -	        "parameter must be callable");
> +        Py_INCREF(Py_None);
> +        return Py_None;  
> +    }
> +    
> 	    return NULL;
> }
> 
> -    core->SetCallback(event, func);
> +/*
> + *  Set the client engine plugin path.
> + */
> +static PyObject *
> +hx_set_pluginpath
> +(
> +    PyObject *self,
> +    PyObject *args
> +)
> +{
> +    const char *path;
> +
> +    if (!PyArg_ParseTuple(args, "s", &path))
> +    return NULL;
> 
> +    if(SUCCEEDED(core->SetPluginPath(path)))
> +    {
> Py_INCREF(Py_None);
> return Py_None;    
> }
> 
> +    return NULL;
> +}
> +
> /* module function mappings*/
> static PyMethodDef PyHxMethods[] = 
> {   
> 
> -    {"codecpath",      (PyCFunction)hx_codecpath,  METH_VARARGS,
> -    (char *)hx_codecpath_doc},
> +    {"setEnginePath",      (PyCFunction)hx_set_dllpath,  METH_VARARGS,
> +    (char *)hx_set_dllpath_doc},
> {"createAudience", (PyCFunction)hx_create_audience,  METH_VARARGS,
> (char *)hx_create_audience_doc},
> {"createDestination", (PyCFunction)hx_create_destination,  METH_VARARGS,
> @@ -567,8 +577,8 @@
> {"initLogging",           (PyCFunction)hx_init_logging,METH_VARARGS,
> (char *)hx_init_logging_doc},
> 
> -    {"pluginpath",     (PyCFunction)hx_pluginpath, METH_VARARGS,
> -    (char *)hx_pluginpath_doc},
> +    {"setPluginPath",     (PyCFunction)hx_set_pluginpath, METH_VARARGS,
> +    (char *)hx_set_pluginpath_doc},
> 
> {"setCallback",   (PyCFunction)hx_set_callback,  METH_VARARGS,
> (char *)hx_set_callback_doc},
> Index: samples/command_line_encoder.py
> ===================================================================
> RCS 
> file: /cvsroot/player/kit/python/hxrecord/samples/command_line_encoder.py,v
> retrieving revision 1.1
> diff -u -w -r1.1 command_line_encoder.py
> --- samples/command_line_encoder.py	24 Sep 2007 18:11:36 -0000	1.1
> +++ samples/command_line_encoder.py	17 Oct 2007 20:07:26 -0000
> @@ -127,7 +127,7 @@
> 
> 
> #open preview
> -input.openVideoPreview()
> +#input.openVideoPreview()
> #input.openAudioPreview(callback_audioPreview)
> 
> 
> Index: samples/pygtk-producer.py
> ===================================================================
> RCS file: /cvsroot/player/kit/python/hxrecord/samples/pygtk-producer.py,v
> retrieving revision 1.1
> diff -u -w -r1.1 pygtk-producer.py
> --- samples/pygtk-producer.py	9 Oct 2007 17:49:38 -0000	1.1
> +++ samples/pygtk-producer.py	17 Oct 2007 20:07:26 -0000
> @@ -7,9 +7,8 @@
> 
> class Producer:
> 
> -    # This is a callback function. The data arguments are ignored
> -    # in this example. More on callbacks below.
> -    def openVideoPreview(self, widget, data=None):          
> +    
> +    def openVideoPreview(self, widget):
> #TODO real check for windows
> xwindows = 1
> if (xwindows):
> @@ -22,6 +21,10 @@
> # except for resize.  preview is always the size requested 
> self.input.openVideoPreview(self.width, self.height, xid)        
> 
> +    def record(self, widget):
> +        self.job.startEncoding(False)
> +
> +
> def delete_event(self, widget, event, data=None):        
> return False
> 
> @@ -39,14 +42,20 @@
> self.window.add(vbox)
> 
> self.button = gtk.Button("Start Preview")    
> -        self.button.connect("clicked", self.openVideoPreview, None)      
> +        self.button.connect("clicked", self.openVideoPreview)
> +
> +        vbox.add(self.button)
> +        self.button.show()
> +
> +        self.button = gtk.Button("Record")
> +        self.button.connect("clicked", self.record)
> 
> vbox.add(self.button)           
> self.button.show()
> 
> #create drawing area for preview
> -        self.width=320;
> -        self.height=240;
> +        self.width=320
> +        self.height=240
> self.subwin = gtk.DrawingArea()
> color = gtk.gdk.color_parse('#440044')
> self.subwin.modify_bg(gtk.STATE_NORMAL, color)
> @@ -74,6 +83,12 @@
> if __name__ == "__main__":
> producer = Producer()
> 
> +    #Set Engine path (encsession.so) - must be done before hxrecord.init()
> +    hxrecord.setEnginePath("lib")
> +
> +    #Set plugin path - must be done before encoding job and other objects are 
> created
> +    hxrecord.setPluginPath("lib");
> +
> hxrecord.init()
> hxrecord.initLogging("test.log")
> 
> @@ -83,7 +98,7 @@
> 
> 
> #create capture input
> -    duration = hxrecord.createTime("000:00:15");
> +    duration = hxrecord.createTime("000:00:05");
> print "duration: " + str(duration)
> 
> #both
> @@ -95,7 +110,8 @@
> #audio only
> #dict = 
> {'pluginType':'captureInput','audioDeviceID':'0','audioDevicePort':'2','audioMixerID':'0','audioMixerPort':'2','duration':duration}
>  
> -    #dict = {'pluginType':'avFileInput','filename':'','duration':duration}
> +    #video file
> +    #dict = 
> {'pluginType':'avFileInput','filename':'carphone.avi','duration':duration}
> 
> input = hxrecord.createInput(dict)
> print "input: " + str(input)
> @@ -124,7 +140,6 @@
> print "destination count: " + str(outputProfile.getDestinationCount())
> 
> 
> -    
> # Create Media Profile
> dict = {'videoMode':'sharp', 'audioMode':'voice'}
> mediaProfile = hxrecord.createMediaProfile(dict)
> @@ -191,12 +206,13 @@
> hxrecord.setCallback(hxrecord.eEventEncodeProgress, 
> callback_encodingProgress);
> 
> producer.input = input
> +    producer.job = job
> 
> #open preview
> #input.openAudioPreview(callback_audioPreview)
> 
> 
> #encode!
> -    #job.startEncoding(True)
> +    #
> 
> producer.main()
> 
> _______________________________________________
> Player-dev mailing list
> Player-dev@helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/player-dev


_______________________________________________
Player-dev mailing list
Player-dev@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/player-dev


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic