Author: dmeyer
Date: Fri Jan 5 16:41:19 2007
New Revision: 2355
Modified:
trunk/popcorn/src/backends/base.py
trunk/popcorn/src/backends/gstreamer/__init__.py
trunk/popcorn/src/backends/gstreamer/player.py
trunk/popcorn/src/backends/manager.py
trunk/popcorn/src/backends/mplayer/__init__.py
trunk/popcorn/src/backends/mplayer/config.cxml
trunk/popcorn/src/backends/mplayer/player.py
trunk/popcorn/src/backends/xine/__init__.py
trunk/popcorn/src/backends/xine/player.py
trunk/popcorn/src/config.cxml
trunk/popcorn/src/generic.py
Log:
Some property and config updates. The _config object is gone
now and replaced with the global one. It only makes sense to
make a small part of it different between player and we can
use properties for that.
Modified: trunk/popcorn/src/backends/base.py
==============================================================================
--- trunk/popcorn/src/backends/base.py (original)
+++ trunk/popcorn/src/backends/base.py Fri Jan 5 16:41:19 2007
@@ -37,6 +37,7 @@
# kaa.popcorn imports
from kaa.popcorn.ptypes import *
+from kaa.popcorn.config import config
# get logging object
log = logging.getLogger('popcorn')
@@ -49,7 +50,7 @@
_instance_count = 0
- def __init__(self, config, properties):
+ def __init__(self, properties):
self.signals = {
"elapsed": kaa.notifier.Signal(),
"stream_changed": kaa.notifier.Signal(),
@@ -60,7 +61,6 @@
self._state_object = STATE_IDLE
self._window = None
self._size = None
- self._config = config
self._properties = properties
self._instance_id = "popcorn-%d-%d" % (os.getpid(),
self._instance_count)
MediaPlayer._instance_count += 1
@@ -142,7 +142,7 @@
size = self._window.get_size()
if hasattr(self._window, 'get_display'):
size = self._window.get_display().get_size()
- aspect = [ int(x) for x in self._config.monitoraspect.split(':') ]
+ aspect = [ int(x) for x in config.video.monitoraspect.split(':') ]
return aspect, size
Modified: trunk/popcorn/src/backends/gstreamer/__init__.py
==============================================================================
--- trunk/popcorn/src/backends/gstreamer/__init__.py (original)
+++ trunk/popcorn/src/backends/gstreamer/__init__.py Fri Jan 5 16:41:19 2007
@@ -26,17 +26,17 @@
#
# -----------------------------------------------------------------------------
-# kaa.popcorn imports
-from kaa.popcorn.backends import register_backend
-from kaa.popcorn.ptypes import *
-
-# player imports
-from config import config
-
def get_capabilities():
"""
Return capabilities of the gstreamer backend.
"""
+
+ # kaa.popcorn imports
+ from kaa.popcorn.ptypes import *
+
+ # player config
+ from config import config
+
capabilities = {
CAP_OSD : False,
CAP_CANVAS : False,
@@ -61,6 +61,9 @@
return capabilities, schemes, exts, codecs
-def register():
+def import_backend():
+ """
+ Return player name, class and capability function.
+ """
from player import GStreamer
- register_backend("gstreamer", GStreamer, get_capabilities)
+ return ("gstreamer", GStreamer, get_capabilities)
Modified: trunk/popcorn/src/backends/gstreamer/player.py
==============================================================================
--- trunk/popcorn/src/backends/gstreamer/player.py (original)
+++ trunk/popcorn/src/backends/gstreamer/player.py Fri Jan 5 16:41:19 2007
@@ -36,13 +36,14 @@
# kaa.popcorn imports
from kaa.popcorn.backends.base import MediaPlayer
from kaa.popcorn.ptypes import *
+from kaa.popcorn.config import config
from kaa.popcorn.utils import ChildProcess
class GStreamer(MediaPlayer):
- def __init__(self, config, properties):
- super(GStreamer, self).__init__(config, properties)
+ def __init__(self, properties):
+ super(GStreamer, self).__init__(properties)
self._state = STATE_NOT_RUNNING
self._gst = None
@@ -74,7 +75,7 @@
aspect=aspect, size=size)
else:
self._gst.configure_video('none')
- self._gst.configure_audio(self._config.audio.driver)
+ self._gst.configure_audio(config.audio.driver)
def play(self):
Modified: trunk/popcorn/src/backends/manager.py
==============================================================================
--- trunk/popcorn/src/backends/manager.py (original)
+++ trunk/popcorn/src/backends/manager.py Fri Jan 5 16:41:19 2007
@@ -26,7 +26,7 @@
#
# -----------------------------------------------------------------------------
-__all__ = [ 'register_backend', 'get_player_class', 'get_all_players' ]
+__all__ = [ 'get_player_class', 'get_all_players' ]
# python imports
import os
@@ -38,9 +38,6 @@
# kaa.popcorn imports
from kaa.popcorn.ptypes import *
-# backend imports
-from base import MediaPlayer
-
# internal list of players
_players = {}
_backends_imported = False
@@ -58,35 +55,29 @@
if os.path.isdir(dirname):
try:
# import the backend and register it.
- exec('from %s import register; register()' % backend)
+ exec('from %s import import_backend' % backend)
except ImportError, e:
- pass
+ continue
+ player_id, cls, get_caps_callback = import_backend()
+ if player_id in _players:
+ raise ValueError, "Player '%s' already registered" % name
+
+ # set player id
+ cls._player_id = player_id
+ # FIXME: we just defer calling get_caps_callback until the first
time
+ # a player is needed, but we should do this in a thread when the
system
+ # is idle.
+ _players[player_id] = {
+ "class": cls,
+ "callback": get_caps_callback,
+ "loaded": False
+ }
+
# This function only ever needs to be called once.
_backends_imported = True
-def register_backend(player_id, cls, get_caps_callback):
- """
- Register a new player.
- """
- assert(issubclass(cls, MediaPlayer))
- if player_id in _players:
- raise ValueError, "Player '%s' already registered" % name
-
- # set player id
- cls._player_id = player_id
-
- # FIXME: we just defer calling get_caps_callback until the first time
- # a player is needed, but we should do this in a thread when the system
- # is idle.
- _players[player_id] = {
- "class": cls,
- "callback": get_caps_callback,
- "loaded": False
- }
-
-
def get_player_class(media, caps = None, exclude = None, force = None,
preferred = None):
"""
Modified: trunk/popcorn/src/backends/mplayer/__init__.py
==============================================================================
--- trunk/popcorn/src/backends/mplayer/__init__.py (original)
+++ trunk/popcorn/src/backends/mplayer/__init__.py Fri Jan 5 16:41:19 2007
@@ -26,20 +26,19 @@
#
# -----------------------------------------------------------------------------
-# kaa imports
-import kaa.utils
-
-# kaa.popcorn imports
-from kaa.popcorn.backends import register_backend
-from kaa.popcorn.ptypes import *
-
-# player imports
-from config import config
-
def get_capabilities():
"""
Return capabilities of the mplayer backend.
"""
+
+ # kaa imports
+ import kaa.utils
+
+ # kaa.popcorn imports
+ from kaa.popcorn.ptypes import *
+
+ # player imports
+ from config import config
from player import _get_mplayer_info
capabilities = {
@@ -80,6 +79,9 @@
return capabilities, schemes, exts, codecs
-def register():
+def import_backend():
+ """
+ Return player name, class and capability function.
+ """
from player import MPlayer
- register_backend("mplayer", MPlayer, get_capabilities)
+ return ("mplayer", MPlayer, get_capabilities)
Modified: trunk/popcorn/src/backends/mplayer/config.cxml
==============================================================================
--- trunk/popcorn/src/backends/mplayer/config.cxml (original)
+++ trunk/popcorn/src/backends/mplayer/config.cxml Fri Jan 5 16:41:19 2007
@@ -43,9 +43,9 @@
<desc lang="en">Deinterlacer video filter to use</desc>
</var>
- <dict name="options">
+ <dict name="arguments">
<desc lang="en">
- Special mplayer options based on the file type (extention or
+ Special mplayer arguments based on the file type (extention or
scheme). Note: this variable may be deleted in the future.
</desc>
<var type="str"/>
Modified: trunk/popcorn/src/backends/mplayer/player.py
==============================================================================
--- trunk/popcorn/src/backends/mplayer/player.py (original)
+++ trunk/popcorn/src/backends/mplayer/player.py Fri Jan 5 16:41:19 2007
@@ -46,6 +46,7 @@
# kaa.popcorn base imports
from kaa.popcorn.backends.base import MediaPlayer
from kaa.popcorn.ptypes import *
+from kaa.popcorn.config import config
from child import MPlayerApp
@@ -154,10 +155,10 @@
RE_STATUS = re.compile("V:\s*([\d+\.]+)|A:\s*([\d+\.]+)\s\W")
RE_SWS = re.compile("^SwScaler: [0-9]+x[0-9]+ -> ([0-9]+)x([0-9]+)")
- def __init__(self, config, properties):
- super(MPlayer, self).__init__(config, properties)
+ def __init__(self, properties):
+ super(MPlayer, self).__init__(properties)
self._state = STATE_NOT_RUNNING
- self._mp_cmd = self._config.mplayer.path
+ self._mp_cmd = config.mplayer.path
if not self._mp_cmd:
self._mp_cmd = kaa.utils.which("mplayer")
@@ -374,7 +375,7 @@
(self._properties['deinterlace'] == 'auto' and \
self._media.get('interlaced')):
# add deinterlacer
- filter.append(self._config.mplayer.deinterlacer)
+ filter.append(config.mplayer.deinterlacer)
# FIXME: all this code seems to work. But I guess it has
# some problems when we don't have an 1:1 pixel aspect
@@ -385,7 +386,7 @@
# This may be needed for some non X based displays
args.add(screenw=size[0], screenh=size[1])
- if not self._config.widescreen == 'scaled':
+ if not config.widescreen == 'scaled':
# Expand to fit the given aspect. In scaled mode we don't
# do that which will result in a scaled image filling
# the whole screen
@@ -394,7 +395,7 @@
# FIXME: this only works if the window has the the aspect
# as the full screen. In all other cases the window is not
# fully used but at least with black bars.
- if self._config.widescreen == 'zoom':
+ if config.widescreen == 'zoom':
# This DOES NOT WORK as it should. The hardware scaler
# will ignore the settings and keep aspect and does
# not crop as default. When using vo x11 and software
@@ -433,26 +434,26 @@
# get argument and filter list
args, filters = self._mplayer.args, self._mplayer.filters
- if self._config.audio.passthrough:
+ if config.audio.passthrough:
args.add(ac='hwac3,hwdts,')
else:
- args.add(channels=self._config.audio.channels)
+ args.add(channels=config.audio.channels)
- args.add(ao=self._config.audio.driver)
+ args.add(ao=config.audio.driver)
- if self._config.audio.driver == 'alsa':
+ if config.audio.driver == 'alsa':
args[-1] += ":noblock"
n_channels = self._streaminfo.get('channels')
if self._streaminfo.get('acodec') in ('a52', 'hwac3', 'ffdts',
'hwdts'):
- device = self._config.audio.device.passthrough
+ device = config.audio.device.passthrough
elif n_channels == 1:
- device = self._config.audio.device.mono
+ device = config.audio.device.mono
elif n_channels <= 4:
- device = self._config.audio.device.surround40
+ device = config.audio.device.surround40
elif n_channels <= 6:
- device = self._config.audio.device.surround51
+ device = config.audio.device.surround51
else:
- device = self._config.audio.device.stereo
+ device = config.audio.device.stereo
if device != '':
args[-1] += ':device=' + device.replace(':', '=')
Modified: trunk/popcorn/src/backends/xine/__init__.py
==============================================================================
--- trunk/popcorn/src/backends/xine/__init__.py (original)
+++ trunk/popcorn/src/backends/xine/__init__.py Fri Jan 5 16:41:19 2007
@@ -26,17 +26,17 @@
#
# -----------------------------------------------------------------------------
-# kaa.popcorn imports
-from kaa.popcorn.backends import register_backend
-from kaa.popcorn.ptypes import *
-
-# player imports
-from config import config
-
def get_capabilities():
"""
Return capabilities of the xine backend.
"""
+
+ # kaa.popcorn imports
+ from kaa.popcorn.ptypes import *
+
+ # player imports
+ from config import config
+
capabilities = {
CAP_OSD : True,
CAP_CANVAS : True,
@@ -67,6 +67,9 @@
return capabilities, schemes, exts, codecs
-def register():
+def import_backend():
+ """
+ Return player name, class and capability function.
+ """
from player import Xine
- register_backend("xine", Xine, get_capabilities)
+ return ("xine", Xine, get_capabilities)
Modified: trunk/popcorn/src/backends/xine/player.py
==============================================================================
--- trunk/popcorn/src/backends/xine/player.py (original)
+++ trunk/popcorn/src/backends/xine/player.py Fri Jan 5 16:41:19 2007
@@ -42,6 +42,7 @@
# kaa.popcorn imports
from kaa.popcorn.backends.base import MediaPlayer
from kaa.popcorn.ptypes import *
+from kaa.popcorn.config import config
from kaa.popcorn.utils import ChildProcess
# get logging object
@@ -52,8 +53,8 @@
class Xine(MediaPlayer):
- def __init__(self, config, properties):
- super(Xine, self).__init__(config, properties)
+ def __init__(self, properties):
+ super(Xine, self).__init__(properties)
self._check_new_frame_timer =
kaa.notifier.WeakTimer(self._check_new_frame)
self._is_in_menu = False
self._cur_frame_output_mode = [True, False, None] # vo, shmem, size
@@ -233,13 +234,13 @@
return
self._xine_configured = True
- self._xine.set_config(self._config)
+ self._xine.set_config(config)
if self._window:
self._xine.configure_video(self._window.get_id(),
self._window.get_size(),
self._get_aspect())
else:
self._xine.configure_video(None, None, None)
- self._xine.configure_audio(self._config.audio.driver)
+ self._xine.configure_audio(config.audio.driver)
self._xine.configure_stream(self._properties)
Modified: trunk/popcorn/src/config.cxml
==============================================================================
--- trunk/popcorn/src/config.cxml (original)
+++ trunk/popcorn/src/config.cxml Fri Jan 5 16:41:19 2007
@@ -26,9 +26,28 @@
</desc>
</var>
- <var name="monitoraspect" default="4:3">
- <desc>Aspect ratio of the monitor or tv.</desc>
- </var>
+ <group name="video">
+ <desc lang="en">video settings</desc>
+ <var name="driver" default="xv">
+ <values>
+ <value>xv</value>
+ </values>
+ <desc>
+ Video driver; xv is the only supported video driver at this
+ moment. Please help us und extend kaa.popcorn to support other
+ video drivers as well.
+ </desc>
+ </var>
+ <var name="monitoraspect" default="4:3">
+ <desc>Aspect ratio of the monitor or tv.</desc>
+ </var>
+ <var name="postprocessing" default="False">
+ <desc>Activate postprocessing for playback as default.</desc>
+ </var>
+ <var name="software-scaler" default="False">
+ <desc>Use software scaler (slow)</desc>
+ </var>
+ </group>
<group name="audio">
<desc lang="en">audio settings</desc>
@@ -64,9 +83,17 @@
</var>
</group>
+ <group name="language">
+ <desc lang="en">
+ Language settings for prefered audio or subtitle language. Set the
+ variables to a comma seperated list of language codes.
+ </desc>
+ <var name="audio" default="en"/>
+ <var name="subtitle" default="en,de,fr"/>
+ </group>
+
<code>
import backends
-
for n, c in backends.config:
config.add_variable(n, c)
</code>
Modified: trunk/popcorn/src/generic.py
==============================================================================
--- trunk/popcorn/src/generic.py (original)
+++ trunk/popcorn/src/generic.py Fri Jan 5 16:41:19 2007
@@ -41,7 +41,7 @@
# kaa.popcorn imports
import backends.manager
-from config import config as default_config
+from config import config
from ptypes import *
# get logging object
@@ -61,7 +61,7 @@
# print 'pending:', func, self.get_state(), states
callback = kaa.notifier.Callback(func, self, *args, **kwargs)
self._pending.append((states, callback))
-
+
try:
newfunc.func_name = func.func_name
except TypeError:
@@ -77,27 +77,25 @@
Generic player. On object of this class will use the players from the
backend subdirectory for playback.
"""
- def __init__(self, window=None, config=default_config):
+ def __init__(self, window=None):
self._player = None
self._media = None
self._size = (0,0)
self.set_window(window)
- self._config = config
-
self._properties = {
# If a property is changed when no uri is loaded
# it will affect all uris loaded after this point.
# If changed when an uri is loaded it will only
- # affect this one. Some properties can't be
+ # affect this one. Some properties can not be
# changed after the stream is started because the
# backend does not support it.
# settings that are set global is most cases
- 'postprocessing': False,
- 'software-scaler': True,
+ 'postprocessing': config.video.postprocessing,
+ 'software-scaler': config.video.software_scaler,
# settings usefull for changing after a stream is
# loaded.
@@ -112,7 +110,7 @@
# plays the audio before.
'audio-delay': 0.0
}
-
+
self.signals = {
# signals created by this class
@@ -131,7 +129,7 @@
# pass thru signals from player
"elapsed": kaa.notifier.Signal(),
"stream_changed": kaa.notifier.Signal(),
- # Emitted when a new frame is availabnle. See
+ # Emitted when a new frame is availabnle. See
# set_frame_output_mode() doc for more info.
"frame": kaa.notifier.Signal(), # CAP_CANVAS
# Emitted when OSD buffer has changed. See osd_update() doc
@@ -143,7 +141,7 @@
self._pending = []
self._blocked = False
self._failed_player = []
-
+
def set_window(self, window):
if window:
@@ -163,11 +161,10 @@
"""
exclude = self._failed_player[:]
for p in backends.manager.get_all_players():
- if not getattr(self._config, p).activate and not p in exclude:
+ if not getattr(config, p).activate and not p in exclude:
exclude.append(p)
return backends.manager.get_player_class(\
- self._media, self._open_caps, exclude, player,
- self._config.preferred)
+ self._media, self._open_caps, exclude, player, config.preferred)
def _state_change(self, old_state, state):
@@ -210,7 +207,7 @@
if old_state == STATE_OPENING and state == STATE_OPEN:
# stream open now for playing
self.signals["open"].emit(self._player.get_info())
-
+
if old_state == STATE_OPEN and \
state in (STATE_PLAYING, STATE_PAUSED):
# From STATE_OPENING to playing. Signal playback start
@@ -225,18 +222,18 @@
if old_state == STATE_PLAYING and state == STATE_PAUSED:
self.signals["pause"].emit()
self.signals["pause_toggle"].emit()
-
+
if old_state == STATE_PAUSED and state == STATE_PLAYING:
self.signals["play"].emit()
self.signals["pause_toggle"].emit()
-
+
if state == STATE_NOT_RUNNING == self._player.get_state() and \
not self._pending:
# Player released the video and audio device. Right now we set
# self._player to None to simulate STATE_NOT_RUNNING.
# This needs to be fixed.
self._player = None
-
+
if self._get_state() == STATE_IDLE and not self._pending and \
not old_state == STATE_NOT_RUNNING:
# no new mrl to play, release player
@@ -267,12 +264,12 @@
properties = self._player._properties
properties = properties.copy()
- self._player = cls(self._config, properties)
+ self._player = cls(properties)
self._player._state_changed.connect_weak(self._state_change)
for signal in self._player.signals:
self._player.signals[signal].connect_weak(self.signals[signal].emit)
-
-
+
+
@required_states(STATE_NOT_RUNNING, STATE_IDLE)
def _open(self):
"""
@@ -303,11 +300,11 @@
mrl = 'file://%s'
self._media = kaa.metadata.Media(hash=dict(url=mrl,
media='MEDIA_UNKNOWN'))
self._media.scheme = self._media.url[:self._media.url.find(':/')]
-
+
self._open_caps = caps
self._failed_player = []
cls = self._get_player_class(player)
-
+
if not cls:
raise PlayerError("No supported player found to play %s", mrl)
@@ -486,7 +483,7 @@
def set_property(self, prop, value):
"""
- Set a property to a new value. If an url is open right now, this
+ Set a property to a new value. If an url is open right now, this
will only affect the current url.
"""
# FIXME: use pending for some properties to respect the state.
@@ -513,15 +510,15 @@
if self._player:
return self._player._properties.keys()
return self._properties.keys()
-
-
+
+
# For CAP_OSD
def osd_can_update(self):
"""
Returns True if it is safe to write to the player's shared memory
buffer used for OSD, and False otherwise. If this buffer is written
- to even though this function returns False, the OSD may exhibit
+ to even though this function returns False, the OSD may exhibit
corrupt output or tearing during animations.
The shared memory buffer is provided when the player starts via the
@@ -535,22 +532,22 @@
def osd_update(self, alpha = None, visible = None, invalid_regions = None):
"""
Updates the OSD of the player based on the given argments:
- alpha:
+ alpha:
the global alpha level of the OSD, 0 <= x <= 256. 255 means
fully opaque, but per-pixel alpha is still considered. If
alpha is 256, the alpha channel of the OSD buffer is ignored
and the OSD will fully obstruct the video. 0 is equivalent
to setting visible=False.
- visible:
+ visible:
True if the OSD should be visible, False otherwise. The
default state is False.
- invalid_regions:
+ invalid_regions:
A list of 4-tuples (left, top, width, height) that indicate
regions of the OSD shmem buffer that have been written to and
require synchronization with the actual OSD of the player.
-
+
It is guaranteed that all OSD changes contained in single osd_update()
call will be reflected between frames. Multiple, sequential calls to
osd_update() may occur within one or more frames, but it is
@@ -624,17 +621,17 @@
output.
If any of these parameters are None, their state will not be altered.
-
+
When notify is True, the 'frame' signal will be emitted for every new
frame. Callbacks connected to this signal will receive 5 argments:
- width, height, aspect, buffer_addr, format.
-
+ width, height, aspect, buffer_addr, format.
+
width, height:
Width and height specify the size of the frame. Note that this
size may not be the size that was passed to the last call to
set_frame_output_mode() (perhaps the player's scaler couldn't
scale to the requested size, or the frame was deposited before
- the resize request was received.)
+ the resize request was received.)
aspect:
A float specifying the aspect ratio of the given frame.
@@ -677,6 +674,7 @@
if self._player:
return self._player.unlock_frame_buffer()
+
def get_capabilities(self):
"""
Return player capabilities.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog