[xiph-commits] r7426 - in trunk/xinloe: . icons/48x48
arc at motherfish-iii.xiph.org
arc
Thu Aug 5 19:04:39 PDT 2004
Author: arc
Date: Thu Aug 5 19:04:39 2004
New Revision: 7426
Added:
trunk/xinloe/icons/48x48/oggfile.png
Modified:
trunk/xinloe/general.py
trunk/xinloe/handlers.py
trunk/xinloe/infobox.py
trunk/xinloe/main.py
trunk/xinloe/sandbox.py
Log:
Wow, alot of work tonight.
Well the infobox is working now. It will display useful information for
files, chains, and streams and properly calculates offsets for muxed and
chained bitstreams when calculating these totals.
I don't have the calcs for Theora or FLAC granulepos yet. Monday night.
It's also not caching 'cut points' (page/packet boundries), but then
again, we don't have a project workspace yet so this is not so
important. Now that it's processing the streams fully, not just page0,
it's "ready" for this additional code to be added easily.
Project window is the next priority.
Modified: trunk/xinloe/general.py
===================================================================
--- trunk/xinloe/general.py 2004-07-31 02:32:32 UTC (rev 7425)
+++ trunk/xinloe/general.py 2004-07-31 05:45:43 UTC (rev 7426)
@@ -24,13 +24,15 @@
import os
import wx
import ogg2
-import time
+import time, string
from wxPython.wx import *
from wxPython.lib.scrolledpanel import wxScrolledPanel
def geticon(name, size=1):
sizes=('16x16','22x22','32x32','48x48')
f = 'icons/%s/%s.png' % (sizes[size], name)
+ if not os.path.exists(f) :
+ f = 'icons/%s/%s.png' % (sizes[size], 'unknown')
return wxImage(f, wxBITMAP_TYPE_PNG).ConvertToBitmap()
def gettext(parent, string, size=1):
@@ -40,4 +42,30 @@
text.SetFont(font)
return text
+def timestr(seconds):
+ hours = seconds/3600
+ minutes = (seconds-( hours*3600 ))/60
+ seconds = (seconds-((hours*3600)+(minutes*60)))
+ return '%s:%s:%s' % \
+ (str(hours).zfill(2), str(minutes).zfill(2), str(seconds).zfill(2))
+def ratestr(bytes, seconds):
+ if seconds == 0 : return '0bps'
+ bps = (bytes * 8.0) / seconds
+ if bps > 1073741823:
+ return '%dgbps' % round(bps/1073741824,2)
+ if bps > 1048575 :
+ return '%dmbps' % round(bps/1048576,1)
+ if bps > 1023 :
+ return '%dkbps' % round(bps/1024,0)
+ return '%dbps' % round(bps,0)
+
+def bytestr(bytes):
+ if bytes > 1073741823:
+ return '%dgb' % round(bytes/1073741824,2)
+ if bytes > 1048575 :
+ return '%dmb' % round(bytes/1048576,1)
+ if bytes > 1023 :
+ return '%dkb' % round(bytes/1024,0)
+ return '%db' % round(bytes,0)
+
Modified: trunk/xinloe/handlers.py
===================================================================
--- trunk/xinloe/handlers.py 2004-07-31 02:32:32 UTC (rev 7425)
+++ trunk/xinloe/handlers.py 2004-07-31 05:45:43 UTC (rev 7426)
@@ -18,18 +18,20 @@
'''
-#
-# Every codec is expected to have a name, desc, icon, and version
-# All other variables are up to the codec to set and use as needed
-#
-
class GenCodec:
def __init__(self, header):
self.name = ''
self.desc = ''
self.icon = ''
+ self.b = 0
+ self.q = 0
+ self.length = 0
+ self.bytes = 0
self.version = 0
+ def PageIn(self, page):
+ self.bytes = self.bytes + len(page)
+
class Vorbis(GenCodec):
def __init__(self, header):
GenCodec.__init__(self, '')
@@ -44,9 +46,15 @@
(ord(header[14])*65536) + (ord(header[15])*16777216)
else :
self.name = 'Vorbis (Unsupported Version)'
- self.desc = ''
self.version = chr(ord(header[7]) + (ord(header[8])*256) + \
(ord(header[9])*65536) + (ord(header[10])*16777216))
+ self.samplerate = 0
+
+ def PageIn(self, page):
+ self.bytes = self.bytes + len(page)
+ if self.samplerate > 0 :
+ self.length = page.granulepos / self.samplerate
+
class Theora(GenCodec):
def __init__(self, header):
@@ -74,7 +82,6 @@
else :
self.name = 'Theora (Unsupported Version)'
- self.desc = ''
self.version = str(ord(header[7])) + '.' + \
str(ord(header[8])) + '.' + \
str(ord(header[9]))
@@ -107,10 +114,15 @@
(ord(header[58])*65536) + (ord(header[59])*16777216)
else :
self.name = 'Speex (Unsupported Version)'
- self.desc = ''
self.version = str(ord(header[28]) + (ord(header[29])*256) + \
(ord(header[30])*65536) + (ord(header[31])*16777216))
+ self.samplerate = 0
+ def PageIn(self, page):
+ self.bytes = self.bytes + len(page)
+ if self.samplerate > 0 :
+ self.length = page.granulepos / self.samplerate
+
class FLAC(GenCodec):
def __init__(self, header):
GenCodec.__init__(self, '')
@@ -119,12 +131,7 @@
self.desc = 'Lossless Audio'
self.icon = 'flac'
self.version = '0'
- #
- # Someone needs to teach these guys about Ogg info headers!!!
- #
- #self.channels = ord(header[11])
- #self.samplerate = ord(header[12]) + (ord(header[13])*256) + \
- # (ord(header[14])*65536) + (ord(header[15])*16777216)
+ # need samplerate, channels, samplesize, and bitrate
class Writ(GenCodec):
def __init__(self, header):
@@ -140,10 +147,8 @@
d = ord(header[11]) + (ord(header[12])*256) + \
(ord(header[13])*65536) + (ord(header[14])*16777216)
self.framerate = float(n)/float(d)
- print self.version, self.framerate
else :
self.name = 'Writ (Unsupported Version)'
- self.desc = ''
self.version = str(ord(header[5]))
codecs = (Vorbis, Theora, Speex, FLAC, Writ, GenCodec)
Added: trunk/xinloe/icons/48x48/oggfile.png
===================================================================
(Binary files differ)
Property changes on: trunk/xinloe/icons/48x48/oggfile.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/xinloe/infobox.py
===================================================================
--- trunk/xinloe/infobox.py 2004-07-31 02:32:32 UTC (rev 7425)
+++ trunk/xinloe/infobox.py 2004-07-31 05:45:43 UTC (rev 7426)
@@ -20,24 +20,45 @@
from general import *
-class InfoboxPanel(wxWindow, wxScrolledPanel):
+class InfoboxPanel(wxScrolledPanel):
def __init__(self, parent):
wxScrolledPanel.__init__(self, parent, -1)
- self.SetBackgroundColour('White')
- infobox = wxBoxSizer(wxVERTICAL)
- title = gettext(self, ' Theora I - General Purpose Video ', 5)
- general = gettext(self, '00:01:59 205kbps (293293942 bytes)', 3)
+ self.infowin = InfoboxScrolledPanel(self)
+ self.topsizer = wxBoxSizer(wxVERTICAL)
+ self.topsizer.Add(self.infowin, 1, wxEXPAND, 0)
+ self.SetSizer(self.topsizer)
+ self.SetupScrolling(scroll_x=False)
+ self.SetAutoLayout(1)
+
+ def ShowCodec(self, handler):
+ self.topsizer.Remove(self.infowin)
+ self.infowin.Destroy()
+ self.infowin = InfoboxScrolledPanel(self)
+ self.topsizer.Add(self.infowin, 1, wxEXPAND, 0)
+
+ bmp = geticon(handler.icon,3)
+ logo = wxStaticBitmap(self.infowin, -1, bmp, wxPoint(16, 16),
+ wxSize(bmp.GetWidth(), bmp.GetHeight()))
+ title = gettext(self.infowin, ' %s - %s '%(handler.name, handler.desc), 5)
+ general = gettext(self.infowin, '%s %s (%s)' % (timestr(handler.length),
+ ratestr(handler.bytes, handler.length),
+ bytestr(handler.bytes)), 3)
+
topbox = wxBoxSizer(wxHORIZONTAL)
- bmp = geticon('theora',3)
- logo = wxStaticBitmap(self, -1, bmp, wxPoint(16, 16),
- wxSize(bmp.GetWidth(), bmp.GetHeight()))
topbox.Add(logo, 0, wxALIGN_LEFT, 4)
titlebox = wxBoxSizer(wxVERTICAL)
titlebox.Add(title, 0, wxALIGN_LEFT, 4)
titlebox.Add(general, 0, wxALIGN_CENTER, 4)
topbox.AddSizer(titlebox, 0)
- self.SetSizer(infobox)
- self.SetAutoLayout(1)
- self.SetupScrolling(scroll_x=False)
+ infobox = wxBoxSizer(wxVERTICAL)
infobox.AddSizer(topbox, 0)
+ self.infowin.SetAutoLayout(1)
+ self.infowin.SetSizer(infobox)
+ self.topsizer.Layout()
+class InfoboxScrolledPanel(wxWindow, wxPanel):
+ def __init__(self, parent):
+ wxPanel.__init__(self, parent, -1)
+ self.SetBackgroundColour('White')
+ self.SetAutoLayout(1)
+
Modified: trunk/xinloe/main.py
===================================================================
--- trunk/xinloe/main.py 2004-07-31 02:32:32 UTC (rev 7425)
+++ trunk/xinloe/main.py 2004-07-31 05:45:43 UTC (rev 7426)
@@ -141,7 +141,7 @@
self.infoboxWin = InfoboxPanel(self)
self.SetMinimumPaneSize(5)
- self.SplitVertically(self.sandboxWin, self.infoboxWin, 200)
+ self.SplitVertically(self.sandboxWin, self.infoboxWin, 150)
Modified: trunk/xinloe/sandbox.py
===================================================================
--- trunk/xinloe/sandbox.py 2004-07-31 02:32:32 UTC (rev 7425)
+++ trunk/xinloe/sandbox.py 2004-07-31 05:45:43 UTC (rev 7426)
@@ -33,13 +33,17 @@
class SandboxPanel(wxPanel):
def __init__(self, parent):
wxPanel.__init__(self, parent, -1, style=wxWANTS_CHARS)
+ self.parent = parent
+
EVT_SIZE(self, self.OnSize)
+ self.tid = wxNewId()
+ self.tree = SBTreeCtrl(self, self.tid, wxDefaultPosition,
+ wxDefaultSize, wxTR_HAS_BUTTONS
+ | wxTR_HIDE_ROOT | wxTR_TWIST_BUTTONS)
- #self.tree = wxTreeListCtrl(self, -1, style = wxTR_TWIST_BUTTONS)
- self.tree = SBTreeCtrl(self, -1, wxDefaultPosition, wxDefaultSize,
- wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS
- | wxTR_MULTIPLE | wxTR_HIDE_ROOT
- | wxTR_TWIST_BUTTONS)
+ EVT_RIGHT_DOWN(self.tree, self.OnRightDown)
+ EVT_TREE_SEL_CHANGED(self, self.tid, self.OnSelChanged)
+
isz = (16,16)
il = wxImageList(isz[0], isz[1])
self.lclidx = il.Add(geticon('dev-lcl',0))
@@ -77,13 +81,12 @@
self.tree.SetItemImage(self.web, self.webidx, which = wxTreeItemIcon_Normal)
self.tree.Expand(self.root)
- EVT_RIGHT_DOWN(self.tree, self.OnRightClick)
def OnSize(self, evt):
self.tree.SetSize(self.GetSize())
- def OnRightClick(self, evt):
+ def OnRightDown(self, evt):
pt = evt.GetPosition()
item, flags = self.tree.HitTest(pt)
if item == self.devlocal :
@@ -101,41 +104,114 @@
menu.Destroy()
def OnNewLocalFile(self, evt):
- dlg = wxFileDialog(None, "Choose a file", os.getcwd(), "",
+ dlg = wxFileDialog(self, "Choose a file", os.getcwd(), "",
"Ogg Media (.ogg)|*.ogg|All Files (*)|*",
- wxOPEN | wxMULTIPLE | wxCHANGE_DIR )
+ wxOPEN
+ # | wxMULTIPLE we're not ready for this yet
+ # | wxCHANGE_DIR this messes up our path!
+ )
if dlg.ShowModal() == wxID_OK:
paths = dlg.GetPaths()
for path in paths :
- self.AddNewFile(path)
+ newfile = LocalFile(self, path)
dlg.Destroy()
+ def OnSelChanged(self, evt):
+ item = evt.GetItem()
+ handler = self.tree.GetItemData(item).GetData()
+ if handler :
+ self.parent.infoboxWin.ShowCodec(handler)
- def AddNewFile(self, path):
- fd = open(path,'r')
- if fd.read(4) != 'OggS' :
- print 'Non-Ogg file detected!'
- return
- fd.seek(0)
- newfile = self.tree.AppendItem(self.devlocal, os.path.split(path)[1])
- self.tree.SetPyData(newfile, None)
- self.tree.SetItemImage(newfile, self.fileidx, which = wxTreeItemIcon_Normal)
- chain = self.tree.AppendItem(newfile, 'Chain #0')
- self.tree.SetPyData(chain, None)
- self.tree.SetItemImage(chain, self.muxpackidx, which = wxTreeItemIcon_Normal)
- self.tree.SetItemImage(chain, self.muxopenidx, which = wxTreeItemIcon_Expanded)
- sy = ogg2.OggSyncState()
- while sy:
- sy.input(fd)
+class LocalFile:
+ def __init__(self, parent, path):
+ self.parent = parent
+ self.path = path
+ self.chains = []
+ self.length = 0
+ self.bytes = 0
+ self.eof = False
+ self.name = os.path.split(path)[1]
+ self.desc = 'application/ogg'
+ self.icon = 'oggfile'
+
+ self.sy = ogg2.OggSyncState()
+ self.fd = open(path,'r')
+ if self.fd.read(4) != 'OggS' :
+ return
+ self.fd.seek(0)
+ self.branch = parent.tree.AppendItem(parent.devlocal, self.name)
+ parent.tree.SetPyData(self.branch, self)
+ parent.tree.SetItemImage(self.branch, parent.fileidx, which = wxTreeItemIcon_Normal)
+
+ self.page = None
+ while not self.eof:
+ self.chains.append(self.Chain(self))
+ self.bytes = self.bytes + self.chains[-1].bytes
+ self.length = self.length + self.chains[-1].length
+
+ class Chain:
+ def __init__(self, parent):
+ self.parent = parent
+ grandparent = parent.parent
+ self.icon = ''
+
+ chain = grandparent.tree.AppendItem(parent.branch, \
+ 'Chain %d (%s offset)' % (len(parent.chains), timestr(parent.length)))
+ grandparent.tree.SetPyData(chain, self)
+ grandparent.tree.SetItemImage(chain, grandparent.muxpackidx,
+ which = wxTreeItemIcon_Normal)
+ grandparent.tree.SetItemImage(chain, grandparent.muxopenidx,
+ which = wxTreeItemIcon_Expanded)
+ self.serials = {}
+
+ bitstreams = self.GetNewStreams()
+ for handler in bitstreams:
+ self.serials[handler.serialno] = handler
+ stream = grandparent.tree.AppendItem(chain, handler.name)
+ grandparent.tree.SetPyData(stream, handler)
+ if not grandparent.codecidx.has_key(handler.icon) :
+ print 'Missing icon for %s' % handler.name
+ handler.icon = ''
+ grandparent.tree.SetItemImage(stream,
+ grandparent.codecidx[handler.icon], which = wxTreeItemIcon_Normal)
+
+ while parent.page and parent.page.pageno > 0:
+ self.serials[parent.page.serialno].PageIn(parent.page)
+ parent.page = None
+ while not parent.page:
+ if self.parent.sy.input(parent.fd) == 0 :
+ parent.eof = True
+ break # End of file reached.
+ parent.page = parent.sy.pageout()
+
+ self.bytes = 0
+ self.length = 0
+ for handler in bitstreams:
+ self.bytes = self.bytes + handler.bytes
+ if handler.length > self.length :
+ self.length = handler.length
+
+
+ def GetNewStreams(self):
+ parent = self.parent
+
+ bitstreams = []
while 1:
- page = sy.pageout()
- if page :
- if page.pageno > 0 :
- sy = None
- break
- st = ogg2.OggStreamState(page.serialno)
- st.pagein(page)
+ while 1:
+ while not parent.page:
+ if parent.sy.input(parent.fd) == 0 :
+ parent.page = None
+ parent.eof = True
+ return bitstreams # End of file reached.
+ parent.page = parent.sy.pageout()
+ if parent.page.pageno > 0 :
+ return bitstreams
+
+ serialno = parent.page.serialno
+ pagesize = len(parent.page)
+ st = ogg2.OggStreamState(serialno)
+ st.pagein(parent.page)
packet = st.packetout()
bp = ogg2.OggPackBuff(packet)
header = ""
@@ -146,11 +222,8 @@
for c in handlers.codecs :
handler = c(header)
if handler.name : break
- stream = self.tree.AppendItem(chain, handler.name)
- self.tree.SetPyData(stream, handler)
- if not self.codecidx.has_key(handler.icon) :
- print 'Missing icon for %s' % handler.name
- handler.icon = ''
- self.tree.SetItemImage(stream, self.codecidx[handler.icon],
- which = wxTreeItemIcon_Normal)
- else : break
+ bitstreams.append(handler)
+ handler.state = st
+ handler.serialno = serialno
+ handler.bytes = pagesize
+ parent.page = None
More information about the commits
mailing list