Author: dmeyer
Date: Sun Apr 29 19:59:01 2007
New Revision: 2663
Modified:
trunk/popcorn/src/backends/xine/child.py
Log:
Handle scale setting. This also works during runtime and respects monitor
aspect even when the window has a different aspect than the screen.
The only value not working is SCALE_ZOOM because xine crashes when doing the
crop setting. On the downside, I found some strange bugs: First, the expand
filter is messing with this. Using the filter results in a black border
sometimes or has no effect at all. The filter is deactivated now. The
second bug is that the aspect given to _xine_frame_output_cb toggles between
two values on some combinations between each frame. There is a workaround
in the code now.
Modified: trunk/popcorn/src/backends/xine/child.py
==============================================================================
--- trunk/popcorn/src/backends/xine/child.py (original)
+++ trunk/popcorn/src/backends/xine/child.py Sun Apr 29 19:59:01 2007
@@ -50,6 +50,12 @@
BUFFER_UNLOCKED = 0x10
BUFFER_LOCKED = 0x20
+# The expand post-processing filter messes up changing the aspect
+# during runtime. It results in a black border sometimes, sometimes
+# the aspect change does not even work at all. Removing it fixes this
+# problem. This needs to be fixed!
+USE_EXPAND = False
+
class XinePlayerChild(Player):
def __init__(self, osd_shmkey, frame_shmkey):
@@ -67,8 +73,11 @@
self._status = kaa.notifier.WeakTimer(self._status_output)
self._status_last = None
self._vo_settings = None
- self._fit_method = None
self._zoom = 100
+ self._stream_settings = {
+ 'pixel-aspect': 1.0,
+ 'scale' : 'keep',
+ }
self._xine.set_config_value("effects.goom.fps", 20)
self._xine.set_config_value("effects.goom.width", 512)
@@ -145,56 +154,64 @@
def _xine_frame_output_cb(self, width, height, aspect):
"""
- Return the frame output position and dimensions
+ Return the frame output position, dimensions and aspect
"""
- if self._vo_settings == (width, height, aspect):
- # use cache when nothing has changed
- return self._vo_settings_calculated
- # TODO: check if this is right when given aspect is not 1.0
- video_aspect = float(width) / (aspect * height)
+ if self._vo_settings:
+ if self._vo_settings[0] and self._vo_settings[1][:2] == (width,
height):
+ # Use cached values. Dimensions have not changed between the
+ # last frame. The aspect may be different now because we
messed with
+ # it. This is a bug somehow and it happens. So we return the
cached
+ # values and reset self._vo_settings[0] so we recalculate when
+ # the aspect changes the next time.
+ self._vo_settings[0] = False
+ return self._vo_settings_calculated
+ if self._vo_settings[1] == (width, height, aspect):
+ # use cache when nothing has changed
+ return self._vo_settings_calculated
+
+ self._vo_settings = [ True, (width, height, aspect) ]
+
+ vid_w, vid_h, vid_a = width, height, aspect
if self._zoom < 100 and 0:
# FIMXE: this crashes when using a timer to zoom from 100
# in 10% steps.
- crop_x = width - int(width * self._zoom / 100)
- crop_y = height - int(height * self._zoom / 100)
+ crop_x = vid_w - int(vid_w * self._zoom / 100)
+ crop_y = vid_h - int(vid_h * self._zoom / 100)
self._stream.set_parameter(xine.PARAM_VO_CROP_LEFT, crop_x)
self._stream.set_parameter(xine.PARAM_VO_CROP_RIGHT, crop_x)
self._stream.set_parameter(xine.PARAM_VO_CROP_TOP, crop_y)
self._stream.set_parameter(xine.PARAM_VO_CROP_BOTTOM, crop_y)
- self._vo_settings = (width, height, aspect)
log.info('calculate frame output')
- w, h, a = self._xine._get_vo_display_size(width, height, aspect)
- if abs(self._window_aspect - a) > 0.01:
- log.debug('VO: %dx%d -> %dx%d', width, height, w, h)
+ win_w, win_h, win_a = self._xine._get_vo_display_size(vid_w, vid_h,
vid_a)
+ if abs(self._window_aspect - win_a) > 0.01:
+ log.debug('VO: %dx%d -> %dx%d', vid_w, vid_h, win_w, win_h)
# FIXME: maybe not resize the parent window, make this an option
- self.parent.resize((w, h))
- self._window_aspect = a
+ self.parent.resize((win_w, win_h))
+ self._window_aspect = win_a
if self._window_size != (0, 0):
- w, h = self._window_size
- # FIXME: this could be wrong
- windows_aspect = float(w) / h
+ win_w, win_h = self._window_size
- if self._fit_method == 'scale':
+ if self._stream_settings['scale'] == SCALE_IGNORE:
# ignore aspect. The whole window is used and the video
# is scaled to fill it. The aspect is ignore to do that.
- # FIXME: this is wrong. It works for scaling 4:3 content to a
- # 16:9 output window. All other combinations including
- # the movie is already fullscreen does not work.
- aspect = 1.0 / video_aspect
+ aspect = (float(vid_w) * win_h) / (float(win_w) * vid_h)
else:
- # FIXME: this is wrong. The aspect may not be 1.0 depending on
- # the pixel aspect of the output display. This needs to be
- # adjusted. For some recordings with an overscan it would also
- # be nice to have a zoom mode cutting off some pixel at the
- # left and right and zoom it it to fill the screen. This
- # return value also needs to respect widescreen settings from
- # the config to scale a 4:3 image to 16:9 or cut off top and
- # bottom so it fots the 16:9 screen (in case black bars are in
- # the encoding).
- aspect = 1.0
- self._vo_settings_calculated = (0, 0), (0, 0), (w, h), aspect
+ # get aspect from pre-calculated value
+ aspect = self._stream_settings['pixel-aspect']
+ if self._stream_settings['scale'] == SCALE_4_3:
+ # force 4:3
+ aspect *= (float(vid_w) * 3) / (float(4) * vid_h)
+ if self._stream_settings['scale'] == SCALE_16_9:
+ # force 16:9
+ aspect *= (float(vid_w) * 9) / (float(16) * vid_h)
+ # FIXME: add SCALE_ZOOM
+
+ # keep given video aspect in calculation (in most cases 1.0)
+ aspect *= vid_a
+
+ self._vo_settings_calculated = (0, 0), (0, 0), (win_w, win_h), aspect
return self._vo_settings_calculated
@@ -278,6 +295,12 @@
vo_kwargs = {'passthrough': 'none'}
self._vo_visible = False
+ if aspect:
+ # aspect is (aspect_w, aspect_h), (screen_w, screen_h)
+ aspect, fs = aspect
+ a = (float(aspect[0])/aspect[1]) / (float(fs[0])/fs[1])
+ self._stream_settings['pixel-aspect'] = a
+
# FIXME: this should work but it crashes with an exception that
# video.device.xv_colorkey is not defined.
# if colorkey is not None:
@@ -298,12 +321,14 @@
f.set_parameters(method = self.config.xine.deinterlacer.method,
chroma_filter =
self.config.xine.deinterlacer.chroma_filter)
- f = self._vfilter.get("expand")
- if aspect:
- aspect, fullscreen = aspect
- # FIXME: is this correct? What about the fullscreen size?
- f.set_parameters(aspect=float(aspect[0])/aspect[1])
- f.set_parameters(enable_automatic_shift = True)
+ if USE_EXPAND:
+ f = self._vfilter.get("expand")
+ if size is not None:
+ # FIXME: see notice an USE_EXPAND definition
+ aspect = float(size[0]) / size[1]
+ aspect *= self._stream_settings['pixel-aspect']
+ f.set_parameters(aspect=aspect)
+ f.set_parameters(enable_automatic_shift = True)
if self._driver_control:
self._driver_control("set_passthrough", False)
@@ -366,9 +391,10 @@
chain.append('tvtime')
if properties.get('postprocessing'):
chain.append('pp')
- chain.append('expand')
- if properties.get('fit-method'):
- self._fit_method = properties.get('fit-method')
+ if USE_EXPAND:
+ chain.append('expand')
+ if properties.get('scale'):
+ self._stream_settings['scale'] = properties.get('scale')
if properties.get('zoom'):
self._zoom = properties.get('zoom')
self._vfilter.wire(self._stream.get_video_source(), *chain)
@@ -530,6 +556,16 @@
"""
Set a property to a new value.
"""
+ if prop == 'scale':
+ self._vo_settings = None
+ self._stream_settings['scale'] = value
+ return
+
+ if prop == 'zoom':
+ self._vo_settings = None
+ self._zoom = value
+ return
+
current = self._vfilter.get_chain()
chain = []
if prop == 'deinterlace':
@@ -544,13 +580,6 @@
elif 'pp' in current:
chain.append('pp')
- if prop == 'fit-method':
- self._vo_settings = None
- self._fit_method = value
-
- if prop == 'zoom':
- self._vo_settings = None
- self._zoom = value
-
- chain.append('expand')
+ if USE_EXPAND:
+ chain.append('expand')
self._vfilter.rewire(*chain)
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog