pitivi r1329 - in trunk: . pitivi
- From: edwardrv svn gnome org
- To: svn-commits-list gnome org
- Subject: pitivi r1329 - in trunk: . pitivi
- Date: Thu, 16 Oct 2008 14:20:49 +0000 (UTC)
Author: edwardrv
Date: Thu Oct 16 14:20:48 2008
New Revision: 1329
URL: http://svn.gnome.org/viewvc/pitivi?rev=1329&view=rev
Log:
* pitivi/objectfactory.py:
* pitivi/stream.py:
* pitivi/Makefile.am:
Use python properties.
Move MultimediaStream to separate module.
Comments and cleanups.
* pitivi/discoverer.py:
Update code for modifications in objectfactory
Added:
trunk/pitivi/stream.py
Modified:
trunk/ChangeLog
trunk/pitivi/Makefile.am
trunk/pitivi/discoverer.py
trunk/pitivi/objectfactory.py
Modified: trunk/pitivi/Makefile.am
==============================================================================
--- trunk/pitivi/Makefile.am (original)
+++ trunk/pitivi/Makefile.am Thu Oct 16 14:20:48 2008
@@ -30,6 +30,7 @@
signalgroup.py \
signalinterface.py \
sourcelist.py \
+ stream.py \
threads.py \
thumbnailer.py \
utils.py
Modified: trunk/pitivi/discoverer.py
==============================================================================
--- trunk/pitivi/discoverer.py (original)
+++ trunk/pitivi/discoverer.py Thu Oct 16 14:20:48 2008
@@ -312,7 +312,8 @@
if caps and caps.is_fixed():
if not self.currentfactory:
- self.currentfactory = FileSourceFactory(self.current, self.project)
+ self.currentfactory = FileSourceFactory(filename=self.current,
+ project=self.project)
self.emit("new_sourcefilefactory", self.currentfactory)
if caps.to_string().startswith("audio/x-raw") and not self.currentfactory.audio_info:
self.currentfactory.audio_info = caps
@@ -407,12 +408,14 @@
gst.info("pad:%s caps:%s is_last:%s" % (pad, capsstr, is_last))
if capsstr.startswith("video/x-raw"):
if not self.currentfactory:
- self.currentfactory = FileSourceFactory(self.current, self.project)
+ self.currentfactory = FileSourceFactory(filename=self.current,
+ project=self.project)
self.emit("new_sourcefilefactory", self.currentfactory)
self._newVideoPadCb(element, pad)
elif capsstr.startswith("audio/x-raw"):
if not self.currentfactory:
- self.currentfactory = FileSourceFactory(self.current, self.project)
+ self.currentfactory = FileSourceFactory(filename=self.current,
+ project=self.project)
self.emit("new_sourcefilefactory", self.currentfactory)
self._newAudioPadCb(element, pad)
else:
Modified: trunk/pitivi/objectfactory.py
==============================================================================
--- trunk/pitivi/objectfactory.py (original)
+++ trunk/pitivi/objectfactory.py Thu Oct 16 14:20:48 2008
@@ -34,6 +34,7 @@
from serializable import Serializable
from settings import ExportSettings
+from stream import get_stream_for_caps
from gettext import gettext as _
@@ -54,10 +55,12 @@
# FIXME : Use Setter/Getter for internal values !
- def __init__(self, name="", displayname="",
+ def __init__(self, name="", displayname="", project=None,
**unused_kw):
- self.name = name
- self.displayname = displayname
+ gst.info("name:%s , project:%r" % (name, project))
+ self._project = project
+ self._name = name
+ self._displayname = displayname
self._is_audio = False
self._is_video = False
self.is_effect = False
@@ -71,6 +74,9 @@
self.artist = None
self.uid = -1
+ def __repr__(self):
+ return "<%s: %s>" % (self.__class__.__name__, self._displayname or self._name)
+
## properties
def _get_is_audio(self):
@@ -106,20 +112,37 @@
video_info = property(_get_video_info, _set_video_info,
doc="Video information as gst.Caps")
- def _get_audio_info_stream(self):
+ # read only properties
+ @property
+ def audio_info_stream(self):
+ """Audio information of a Stream"""
return self._audio_info_stream
- audio_info_stream = property(_get_audio_info_stream,
- doc="Audio information as a Stream")
- def _get_video_info_stream(self):
+ @property
+ def video_info_stream(self):
+ """Video information of a Stream"""
return self._video_info_stream
- video_info_stream = property(_get_video_info_stream,
- doc="Video information as a Stream")
+ @property
+ def name(self):
+ """Name of the factory"""
+ return self._name
+
+ @property
+ def displayname(self):
+ """Name of the factory for display"""
+ return self._displayname
+
+ @property
+ def project(self):
+ """Project this factory is being used in"""
+ return self._project
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self.displayname or self.name)
+ # FIXME : Media Tags are only Source specific (or not ?)
+ # FIXME : if so, should be moved down
def addMediaTags(self, tags=[]):
""" Add the given gst.Tag or gst.TagList to the factory """
gst.debug("tags:%s" % tags)
@@ -133,9 +156,9 @@
self._mediaTags[tag] = "%s/%s/%s" % (d.day, d.month, d.year)
gst.debug("tags:%s" % self._mediaTags)
if self.video_info_stream:
- self.video_info_stream.set_codec(self._mediaTags.get(gst.TAG_VIDEO_CODEC))
+ self.video_info_stream.codec = self._mediaTags.get(gst.TAG_VIDEO_CODEC)
if self.audio_info_stream:
- self.audio_info_stream.set_codec(self._mediaTags.get(gst.TAG_AUDIO_CODEC))
+ self.audio_info_stream.codec = self._mediaTags.get(gst.TAG_AUDIO_CODEC)
self.artist = self._mediaTags.get(gst.TAG_ARTIST)
if self.artist:
self.artist.strip()
@@ -143,6 +166,7 @@
if self.title:
self.title.strip()
+ # FIXME : Method can stay here, but implementation is wrong
def getPrettyInfo(self):
""" Returns a prettyfied information string """
if self.is_effect:
@@ -154,6 +178,8 @@
if not self.is_video and not self.is_audio:
"Unknown"
stl = []
+ # FIXME : file is FileSourceFactory specific !
+ # FIXME : and it might not be a file:// but maybe a http://
filename = os.path.basename(unquote(self.name))
if not self.title:
stl.append(_("<b>%s</b><small>") % gobject.markup_escape_text(filename))
@@ -166,11 +192,12 @@
stl.append(_("<b>%s</b>") % gobject.markup_escape_text(self.title))
stl.append(_("<small><b>File:</b> %s") % filename)
if self.is_video and self.video_info_stream:
- stl.append(self.video_info_stream.getMarkup())
+ stl.append(self.video_info_stream.markup)
if self.is_audio and self.audio_info_stream:
- stl.append(self.audio_info_stream.getMarkup())
+ stl.append(self.audio_info_stream.markup)
return string.join(stl, "\n") + "</small>"
+ # FIXME : Too limited and ugly. What if we have non-AV streams ??
def makeAudioBin(self):
""" returns a audio only bin """
raise NotImplementedError
@@ -180,6 +207,8 @@
raise NotImplementedError
+ # FIXME : ALL the following methods will die once we switch to a saner
+ # FIXME : and more flexible way of doing file save/load
# Serializable methods
def toDataFormat(self):
@@ -193,10 +222,10 @@
def fromDataFormat(self, obj):
Serializable.fromDataFormat(self, obj)
- self.name = obj["name"]
- self.displayname = obj["displayname"]
- self.is_audio = obj["is_audio"]
- self.is_video = obj["is_video"]
+ self._name = obj["name"]
+ self._displayname = obj["displayname"]
+ self._is_audio = obj["is_audio"]
+ self._is_video = obj["is_video"]
self.setUniqueID(obj["uid"])
# Unique ID methods
@@ -273,6 +302,13 @@
# FIXME : It might not just be files (network sources ?) !
# FIMXE : It might not even had a URI ! (audio/video generators for ex)
+
+
+
+# FIXME : Figure out everything which is Source specific and put it here
+# FIXME : It might not just be files (network sources ?) !
+# FIMXE : It might not even had a URI ! (audio/video generators for ex)
+
class SourceFactory(ObjectFactory):
"""
Provides sources usable in a timeline
@@ -299,17 +335,22 @@
"""
return self.duration
- ## properties
+ ## read only properties
- def __getDefaultDuration(self):
+ @property
+ def default_duration(self):
+ """Default duration of the source in nanoseconds"""
return self._getDefaultDuration()
- default_duration = property(__getDefaultDuration,
- doc = "Default duration of a source in nanoseconds")
- def __getDuration(self):
+ @property
+ def duration(self):
+ """Maximum duration of the source in nanoseconds"""
return self._getDuration()
- duration = property(__getDuration,
- doc = "Maximum duration of the source in nanoseconds")
+
+
+
+# FIXME : What about non-file sources ???
+
@@ -322,12 +363,12 @@
__data_type__ = "file-source-factory"
- def __init__(self, filename="", project=None, **kwargs):
- gst.info("filename:%s , project:%s" % (filename, project))
- SourceFactory.__init__(self, **kwargs)
- self.project = project
- self.name = filename
- self.displayname = os.path.basename(unquote(self.name))
+ # FIXME : filename is specific to this class and should be obvious
+ def __init__(self, filename="", **kwargs):
+ name = kwargs.pop("name", filename)
+ displayname = kwargs.pop("displayname", os.path.basename(unquote(filename)))
+ SourceFactory.__init__(self, name=name, displayname=displayname,
+ **kwargs)
self.lastbinid = 0
self._length = 0
self._thumbnail = ""
@@ -341,7 +382,7 @@
gst.debug("length:%r" % length)
self._length = length
length = property(_get_length, _set_length,
- doc="Length in nanoseconds")
+ doc="Length of the file in nanoseconds")
def _get_thumbnail(self):
return self._thumbnail
@@ -355,7 +396,6 @@
def _getDuration(self):
return self._length
-
def makeBin(self):
""" returns a source bin with all pads """
bin = gst.Bin("%s-%d" % (self.name, self.lastbinid))
@@ -406,12 +446,14 @@
return
bin.remove_pad(mypad)
+ # WTF, code used nowhere ???
def binIsDestroyed(self, bin):
""" Remove the given bin from the list of instances """
if bin in self.instances:
self.instances.remove(bin)
+ # FIXME : Shouldn't this be in a parent class ???
def getExportSettings(self):
""" Returns the ExportSettings corresponding to this source """
if self.settings:
@@ -439,13 +481,11 @@
def toDataFormat(self):
ret = ObjectFactory.toDataFormat(self)
- ret["filename"] = self.name
ret["length"] = self._length
return ret
def fromDataFormat(self, obj):
ObjectFactory.fromDataFormat(self, obj)
- self.name = obj["filename"]
self._length = obj["length"]
@@ -471,9 +511,9 @@
def __init__(self, elementfactory, **kwargs):
""" elementfactory is the GstElementFactory """
- OperationFactory.__init__(self, **kwargs)
- self.name = elementfactory.get_name()
- self.displayname = elementfactory.get_longname()
+ OperationFactory.__init__(self, name=elementfactory.get_name(),
+ displayname=elementfactory.get_longname(),
+ **kwargs)
# check what type the output pad is (AUDIO/VIDEO)
for padt in elementfactory.get_pad_templates():
if padt.direction == gst.PAD_SRC:
@@ -504,177 +544,8 @@
def __init__(self, **kwargs):
TransitionFactory.__init__(self, **kwargs)
-##
-## Multimedia streams, used for definition of media streams
-##
-
-
-class MultimediaStream:
- """
- Defines a media stream
-
- Properties:
- * raw (boolean) : True if the stream is a raw media format
- * fixed (boolean) : True if the stream is entirely defined
- * codec (string) : User-friendly description of the codec used
- * caps (gst.Caps) : Caps corresponding to the stream
- """
-
- def __init__(self, caps):
- gst.log("new with caps %s" % caps.to_string())
- self.caps = caps
- self.raw = False
- self.fixed = True
- self.codec = None
- self._analyzeCaps()
-
- def set_codec(self, codecstring=None):
- if codecstring and codecstring.strip():
- self.codec = codecstring.strip()
-
- def _analyzeCaps(self):
- raise NotImplementedError
-
- def getMarkup(self):
- """
- Returns a pango-markup string definition of the stream
- Subclasses need to implement this
- """
- raise NotImplementedError
-
-class VideoStream(MultimediaStream):
- """
- Video Stream
- """
-
- def _analyzeCaps(self):
- if len(self.caps) > 1:
- self.fixed = False
-
- struct = self.caps[0]
- self.videotype = struct.get_name()
- if self.videotype.startswith("video/x-raw-"):
- self.raw=True
- else:
- self.raw=False
- try:
- self.format = struct["format"]
- except:
- self.format = None
- try:
- self.width = struct["width"]
- except:
- self.width = None
- try:
- self.height = struct["height"]
- except:
- self.height = None
- try:
- self.framerate = struct["framerate"]
- except:
- # if no framerate was given, use 1fps
- self.framerate = gst.Fraction(1,1)
- try:
- self.par = struct["pixel-aspect-ratio"]
- except:
- # use a default setting, None is not valid !
- self.par = gst.Fraction(1,1)
- if self.width and self.height and self.par:
- self.dar = gst.Fraction(self.width * self.par.num, self.height * self.par.denom)
- else:
- if self.width and self.height:
- self.dar = gst.Fraction(self.width, self.height)
- else:
- self.dar = gst.Fraction(4, 3)
- def getMarkup(self):
- if self.raw:
- if self.framerate.num:
- templ = _("<b>Video:</b> %d x %d <i>pixels</i> at %.2f<i>fps</i>")
- templ = templ % (self.dar * self.height , self.height, float(self.framerate))
- else:
- templ = _("<b>Image:</b> %d x %d <i>pixels</i>")
- templ = templ % (self.dar * self.height, self.height)
- if self.codec:
- templ = templ + _(" <i>(%s)</i>") % self.codec
- return templ
- return _("<b>Unknown Video format:</b> %s") % self.videotype
-
-class AudioStream(MultimediaStream):
- """
- Audio stream
- """
-
- def _analyzeCaps(self):
- if len(self.caps) > 1:
- self.fixed = False
-
- struct = self.caps[0]
- self.audiotype = struct.get_name()
- if self.audiotype.startswith("audio/x-raw-"):
- self.raw = True
- else:
- self.raw = False
- if self.audiotype == "audio/x-raw-float":
- self.float = True
- else:
- self.float = False
- try:
- self.channels = struct["channels"]
- except:
- self.channels = None
- try:
- self.rate = struct["rate"]
- except:
- self.rate = None
- try:
- self.width = struct["width"]
- except:
- self.width = None
- try:
- self.depth = struct["depth"]
- except:
- self.depth = self.width
-
- def getMarkup(self):
- if self.raw:
- templ = _("<b>Audio:</b> %d channels at %d <i>Hz</i> (%d <i>bits</i>)")
- templ = templ % (self.channels, self.rate, self.width)
- if self.codec:
- templ = templ + _(" <i>(%s)</i>") % self.codec
- return templ
- return _("<b>Unknown Audio format:</b> %s") % self.audiotype
-
-class TextStream(MultimediaStream):
- """
- Text media stream
- """
-
- def _analyzeCaps(self):
- if len(self.caps) > 1:
- self.fixed = False
-
- self.texttype = self.caps[0].get_name()
-
- def getMarkup(self):
- return _("<b>Text:</b> %s") % self.texttype
-
-def get_stream_for_caps(caps):
- """
- Returns the appropriate MediaStream corresponding to the
- given caps.
- """
- val = caps.to_string()
- if val.startswith("video/"):
- return VideoStream(caps)
- elif val.startswith("audio/"):
- return AudioStream(caps)
- elif val.startswith("text/"):
- return TextStream(caps)
- else:
- # FIXME : we should have an 'unknow' data stream class
- return None
Added: trunk/pitivi/stream.py
==============================================================================
--- (empty file)
+++ trunk/pitivi/stream.py Thu Oct 16 14:20:48 2008
@@ -0,0 +1,287 @@
+# PiTiVi , Non-linear video editor
+#
+# pitivi/stream.py
+#
+# Copyright (c) 2008, Edward Hervey <bilboed bilboed com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 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
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser 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.
+
+"""
+Multimedia stream, used for definition of media streams
+"""
+
+
+# FIXME : If theses streams stay, they should go in a different file/module
+
+##
+## Multimedia streams, used for definition of media streams
+##
+from gettext import gettext as _
+
+import gst
+
+class MultimediaStream:
+ """
+ Defines a media stream
+
+ Properties:
+ * raw (boolean) : True if the stream is a raw media format
+ * fixed (boolean) : True if the stream is entirely defined
+ * codec (string) : User-friendly description of the codec used
+ * caps (gst.Caps) : Caps corresponding to the stream
+ """
+
+ def __init__(self, caps):
+ gst.log("new with caps %s" % caps.to_string())
+ self._caps = caps
+ self._raw = False
+ if len(self._caps) > 1:
+ self._fixed = False
+ else:
+ self._fixed = True
+ self._codec = None
+ self._analyzeCaps()
+
+ ## read-only properties
+ def _get_caps(self):
+ return self._caps
+ caps = property(_get_caps,
+ doc="Original gst.Caps")
+
+ def _get_raw(self):
+ return self._raw
+ raw = property(_get_raw,
+ doc="True if the stream is a raw stream")
+
+ def _get_fixed(self):
+ return self._fixed
+ fixed = property(_get_fixed,
+ doc="True if the stream has fixed caps")
+
+
+ def _get_codec(self):
+ return self._codec
+
+ def _set_codec(self, codecstring=None):
+ if codecstring and codecstring.strip():
+ self._codec = codecstring.strip()
+ codec = property(_get_codec, _set_codec,
+ doc="Codec used in the stream")
+
+ @property
+ def markup(self):
+ """Pango-markup string definition"""
+ return self._getMarkup()
+
+ def _analyzeCaps(self):
+ raise NotImplementedError
+
+ def _getMarkup(self):
+ """
+ Returns a pango-markup string definition of the stream
+ Subclasses need to implement this
+ """
+ raise NotImplementedError
+
+ def __repr__(self):
+ return "%s" % self.caps
+
+class VideoStream(MultimediaStream):
+ """
+ Video Stream
+ """
+
+ # read-only properties
+ @property
+ def format(self):
+ """YUV format of the raw video stream"""
+ return self._format
+
+ @property
+ def width(self):
+ """Width of the video stream in pixels"""
+ return self._width
+
+ @property
+ def height(self):
+ """Height of the video stream in pixels"""
+ return self._height
+
+ @property
+ def framerate(self):
+ """Framerate"""
+ return self._framerate
+
+ @property
+ def par(self):
+ """Pixel Aspect Ratio in fraction"""
+ return self._par
+
+ @property
+ def dar(self):
+ """Display Aspect Ratio in fraction"""
+ return self._dar
+
+ def _analyzeCaps(self):
+ # WARNING/FIXME : Only analyses first structure !
+ struct = self.caps[0]
+ self.videotype = struct.get_name()
+ if self.videotype.startswith("video/x-raw-"):
+ self._raw=True
+ else:
+ self._raw=False
+
+ try:
+ self._format = struct["format"]
+ except:
+ self._format = None
+ try:
+ self._width = struct["width"]
+ except:
+ self._width = None
+ try:
+ self._height = struct["height"]
+ except:
+ self._height = None
+ try:
+ self._framerate = struct["framerate"]
+ except:
+ # if no framerate was given, use 1fps
+ self._framerate = gst.Fraction(1,1)
+ try:
+ self._par = struct["pixel-aspect-ratio"]
+ except:
+ # use a default setting, None is not valid !
+ self._par = gst.Fraction(1,1)
+
+ if self.width and self.height and self.par:
+ self._dar = gst.Fraction(self.width * self.par.num, self.height * self.par.denom)
+ else:
+ if self.width and self.height:
+ self._dar = gst.Fraction(self.width, self.height)
+ else:
+ self._dar = gst.Fraction(4, 3)
+
+ def _getMarkup(self):
+ if self._raw:
+ if self._framerate.num:
+ templ = _("<b>Video:</b> %d x %d <i>pixels</i> at %.2f<i>fps</i>")
+ templ = templ % (self.dar * self.height , self.height, float(self.framerate))
+ else:
+ templ = _("<b>Image:</b> %d x %d <i>pixels</i>")
+ templ = templ % (self.dar * self.height, self.height)
+ if self._codec:
+ templ = templ + _(" <i>(%s)</i>") % self.codec
+ return templ
+ return _("<b>Unknown Video format:</b> %s") % self.videotype
+
+class AudioStream(MultimediaStream):
+ """
+ Audio stream
+ """
+
+
+ @property
+ def float(self):
+ """True if the audio stream contains raw float data"""
+ return self._float
+
+ @property
+ def channels(self):
+ """Number of channels"""
+ return self._channels
+
+ @property
+ def rate(self):
+ """Rate in samples/seconds"""
+ return self._rate
+
+ @property
+ def width(self):
+ """Width of an individual sample (in bits)"""
+ return self._width
+
+ @property
+ def depth(self):
+ """Depth of an individual sample (in bits)"""
+ return self._depth
+
+ def _analyzeCaps(self):
+ # WARNING/FIXME : Only analyses first structure !
+ struct = self.caps[0]
+ self.audiotype = struct.get_name()
+ if self.audiotype.startswith("audio/x-raw-"):
+ self._raw = True
+ else:
+ self._raw = False
+
+ if self.audiotype == "audio/x-raw-float":
+ self._float = True
+ else:
+ self._float = False
+
+ try:
+ self._channels = struct["channels"]
+ except:
+ self._channels = None
+ try:
+ self._rate = struct["rate"]
+ except:
+ self._rate = None
+ try:
+ self._width = struct["width"]
+ except:
+ self._width = None
+ try:
+ self._depth = struct["depth"]
+ except:
+ self._depth = self.width
+
+ def _getMarkup(self):
+ if self.raw:
+ templ = _("<b>Audio:</b> %d channels at %d <i>Hz</i> (%d <i>bits</i>)")
+ templ = templ % (self.channels, self.rate, self.width)
+ if self.codec:
+ templ = templ + _(" <i>(%s)</i>") % self.codec
+ return templ
+ return _("<b>Unknown Audio format:</b> %s") % self.audiotype
+
+class TextStream(MultimediaStream):
+ """
+ Text media stream
+ """
+
+ def _analyzeCaps(self):
+ self.texttype = self.caps[0].get_name()
+
+ def _getMarkup(self):
+ return _("<b>Text:</b> %s") % self.texttype
+
+def get_stream_for_caps(caps):
+ """
+ Returns the appropriate MediaStream corresponding to the
+ given caps.
+ """
+ val = caps.to_string()
+ if val.startswith("video/"):
+ return VideoStream(caps)
+ elif val.startswith("audio/"):
+ return AudioStream(caps)
+ elif val.startswith("text/"):
+ return TextStream(caps)
+ else:
+ # FIXME : we should have an 'unknow' data stream class
+ return None
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]