changeset 538:571d058c9838

vidref refactor, start gui layout Ignore-this: 68728a495bdaaa1316e70fdddfbfc037
author drewp@bigasterisk.com
date Sun, 13 Jun 2010 07:57:29 +0000
parents 1929e0e1053e
children 5cf326ef965a
files light9/vidref/main.py light9/vidref/replay.py light9/vidref/vidref.glade
diffstat 3 files changed, 343 insertions(+), 158 deletions(-) [+]
line wrap: on
line diff
--- a/light9/vidref/main.py	Sun Jun 13 07:57:00 2010 +0000
+++ b/light9/vidref/main.py	Sun Jun 13 07:57:29 2010 +0000
@@ -10,23 +10,16 @@
 pygst.require("0.10")
 import gst, gobject, time, jsonlib, restkit, logging, os, traceback
 from decimal import Decimal
-from bisect import bisect_left
-import pygtk
 import gtk
 from twisted.python.util import sibpath
 import Image
 from threading import Thread
 from Queue import Queue
 from light9 import networking
+from light9.vidref.replay import ReplayViews
 
 log = logging.getLogger()
 
-existingDir = "/tmp/vidref/play-_my_proj_light9_show_dance2010_music_07-jacksonmix-complete.wav-1276331148"
-existingFrames = sorted([Decimal(f.split('.jpg')[0])
-                         for f in os.listdir(existingDir)])
-
-otherPic = None
-
 class MusicTime(object):
     """
     fetch times from ascoltami in a background thread; return times
@@ -44,6 +37,8 @@
         """
         dict with 't' and 'song', etc.
         """
+        if not hasattr(self, 'position'):
+            return {'t' : 0, 'song' : None}
         pos = self.position.copy()
         if pos['playing']:
             pos['t'] = pos['t'] + (time.time() - self.positionFetchTime)
@@ -56,26 +51,6 @@
             self.positionFetchTime = time.time()
             self.position = position
             time.sleep(self.period)
-
-class ReplayFrames(object):
-    """
-    supplies all the frames from disk for the replay videos
-    """
-    def update(self, position):
-        inPic = self.findClosestFrame(position['t']+.2)
-        with gtk.gdk.lock:
-            otherPic.set_from_file(inPic)
-            if 0:
-                # force redraw of that widget
-                otherPic.queue_draw_area(0,0,320,240)
-                otherPic.get_window().process_updates(True)
-
-    def findClosestFrame(self, t):
-        i = bisect_left(existingFrames, Decimal(str(t)))
-        if i >= len(existingFrames):
-            i = len(existingFrames) - 1
-        return os.path.join(existingDir, "%08.03f.jpg" % existingFrames[i])
-
         
 class VideoRecordSink(gst.Element):
     _sinkpadtemplate = gst.PadTemplate ("sinkpadtemplate",
@@ -109,7 +84,6 @@
         t.start()
 
     def chainfunc(self, pad, buffer):
-        return gst.FLOW_OK
         global nextImageCb
         self.info("%s timestamp(buffer):%d" % (pad, buffer.timestamp))
 
@@ -160,25 +134,31 @@
 
 class Main(object):
     def __init__(self):
-        global otherPic
         wtree = gtk.Builder()
         wtree.add_from_file(sibpath(__file__, "vidref.glade"))
         mainwin = wtree.get_object("MainWindow")
-        otherPic = wtree.get_object("liveVideo")
         mainwin.connect("destroy", gtk.main_quit)
         wtree.connect_signals(self)
 
-        # other sources: videotestsrc, v4l2src device=/dev/video0
-        ## if 0:
-        ##     source = makeElem("videotestsrc", "video")
-        ## else:
-        ##     source = makeElem("v4l2src", "vsource")
-        ##     source.set_property("device", "/dev/video0")
+        self.replayViews = ReplayViews(wtree.get_object("image1"))#"replayScroll"))
+
+        mainwin.show_all()
+        self.liveVideoXid = wtree.get_object("vid3").window.xid
+
+        self.setInput('dv')
+
+    def getInputs(self):
+        return ['auto', 'dv', 'video0']
 
-        dv = "dv1394src name=src1 ! dvdemux ! dvdec"
-        v4l = "v4l2src device=/dev/video0 ! hqdn3d" 
+    def setInput(self, name):
+        sourcePipe = {
+            "auto": "autovideosrc name=src1",
+            "testpattern" : "videotestsrc name=src1",
+            "dv": "dv1394src name=src1 ! dvdemux ! dvdec",
+            "v4l": "v4l2src device=/dev/video0 name=src1 ! hqdn3d" ,
+            }[name]
 
-        cam = (dv + " ! "
+        cam = (sourcePipe + " ! "
               "videorate ! video/x-raw-yuv,framerate=15/1 ! "
               "videoscale ! video/x-raw-yuv,width=320,height=240;video/x-raw-rgb,width=320,height=240 ! "
               "queue name=vid")
@@ -191,8 +171,7 @@
             return e
         
         sink = makeElem("xvimagesink")
-        replay = ReplayFrames()
-        recSink = VideoRecordSink(replay)
+        recSink = VideoRecordSink(self.replayViews)
         self.pipeline.add(recSink)
 
         tee = makeElem("tee")
@@ -202,12 +181,8 @@
 
         gst.element_link_many(self.pipeline.get_by_name("vid"), tee, sink)
         gst.element_link_many(tee, makeElem("ffmpegcolorspace"), caps, recSink)
-
-        mainwin.show_all()
-
-        sink.set_xwindow_id(wtree.get_object("vid3").window.xid)
-
-        self.pipeline.set_state(gst.STATE_PLAYING)
+        sink.set_xwindow_id(self.liveVideoXid)
+        self.pipeline.set_state(gst.STATE_PLAYING)        
 
     def on_liveVideoEnabled_toggled(self, widget):
         if widget.get_active():
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/light9/vidref/replay.py	Sun Jun 13 07:57:29 2010 +0000
@@ -0,0 +1,62 @@
+import os, gtk
+from bisect import bisect_left
+from decimal import Decimal
+
+existingDir = "/tmp/vidref/play-_my_proj_light9_show_dance2010_music_01-chorusmix.wav-1276415052"
+existingFrames = sorted([Decimal(f.split('.jpg')[0])
+                         for f in os.listdir(existingDir)])
+
+
+class ReplayViews(object):
+    """
+    the whole list of replay windows. parent is the scrolling area for
+    these windows to be added
+    """
+    def __init__(self, parent):
+        self.out = ReplayView(parent, Replay(existingDir))
+        return
+        for x in range(1000):
+            lab = gtk.Label()
+            lab.set_text("hello")
+            parent.add_with_viewport(lab)
+    
+    def update(self, position):
+        """
+        freshen all replay windows. We get called this about every
+        time there's a new live video frame.
+
+        may be responsible for making new children if we change song
+        """
+        self.out.updatePic(position)
+
+class Replay(object):
+    """
+    model for one of the replay widgets
+    """
+    def __init__(self, sourceDir):
+        self.sourceDir = sourceDir
+
+    def findClosestFrame(self, t):
+        i = bisect_left(existingFrames, Decimal(str(t)))
+        if i >= len(existingFrames):
+            i = len(existingFrames) - 1
+        return os.path.join(existingDir, "%08.03f.jpg" % existingFrames[i])
+
+class ReplayView(object):
+    """
+    one of the replay widgets
+    """
+    def __init__(self, parent, replay):
+        self.replay = replay
+#        self.loadWindwos
+        self.picWidget = parent
+        
+    def updatePic(self, position):
+        inPic = self.replay.findClosestFrame(position['t']+.25)
+        with gtk.gdk.lock:
+            self.picWidget.set_from_file(inPic)
+            if 0:
+                # force redraw of that widget
+                self.picWidget.queue_draw_area(0,0,320,240)
+                self.picWidget.get_window().process_updates(True)
+    
--- a/light9/vidref/vidref.glade	Sun Jun 13 07:57:00 2010 +0000
+++ b/light9/vidref/vidref.glade	Sun Jun 13 07:57:29 2010 +0000
@@ -6,60 +6,286 @@
     <property name="default_width">500</property>
     <property name="default_height">500</property>
     <child>
-      <object class="GtkFixed" id="fixed1">
+      <object class="GtkHBox" id="hbox3">
         <property name="visible">True</property>
         <child>
-          <object class="GtkFrame" id="frame1">
-            <property name="width_request">336</property>
-            <property name="height_request">277</property>
+          <object class="GtkVBox" id="vbox3">
             <property name="visible">True</property>
-            <property name="label_xalign">0</property>
-            <property name="shadow_type">out</property>
             <child>
-              <object class="GtkFixed" id="fixed2">
+              <object class="GtkFrame" id="frame1">
+                <property name="width_request">336</property>
+                <property name="height_request">277</property>
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">out</property>
+                <child>
+                  <object class="GtkAspectFrame" id="aspectframe2">
+                    <property name="visible">True</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
+                    <property name="ratio">1.3300000429153442</property>
+                    <child>
+                      <object class="GtkDrawingArea" id="vid3">
+                        <property name="width_request">320</property>
+                        <property name="height_request">240</property>
+                        <property name="visible">True</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Live view&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox4">
                 <property name="visible">True</property>
                 <child>
-                  <object class="GtkDrawingArea" id="vid3">
-                    <property name="width_request">320</property>
-                    <property name="height_request">240</property>
+                  <object class="GtkToggleButton" id="liveVideoEnabled">
+                    <property name="label" translatable="yes">Enabled</property>
+                    <property name="width_request">110</property>
+                    <property name="height_request">36</property>
                     <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="active">True</property>
+                    <signal name="toggled" handler="on_liveVideoEnabled_toggled"/>
                   </object>
                   <packing>
-                    <property name="x">7</property>
-                    <property name="y">8</property>
+                    <property name="expand">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox4">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkLabel" id="label1">
+                        <property name="width_request">75</property>
+                        <property name="height_request">20</property>
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Frame rate</property>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="liveFrameRate">
+                        <property name="width_request">52</property>
+                        <property name="height_request">25</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                        <property name="numeric">True</property>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox5">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkLabel" id="label4">
+                        <property name="width_request">85</property>
+                        <property name="height_request">20</property>
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Input source</property>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBox" id="videoSource">
+                        <property name="width_request">100</property>
+                        <property name="visible">True</property>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
               </object>
-            </child>
-            <child type="label">
-              <object class="GtkLabel" id="label2">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">&lt;b&gt;Live view&lt;/b&gt;</property>
-                <property name="use_markup">True</property>
-              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
             </child>
           </object>
           <packing>
-            <property name="x">15</property>
-            <property name="y">10</property>
+            <property name="expand">False</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
-          <object class="GtkFrame" id="frame2">
+          <object class="GtkFrame" id="replayHalf">
             <property name="width_request">336</property>
             <property name="height_request">259</property>
             <property name="visible">True</property>
             <property name="label_xalign">0</property>
             <property name="shadow_type">out</property>
             <child>
-              <object class="GtkAlignment" id="alignment1">
+              <object class="GtkScrolledWindow" id="replayScrollWin">
+                <property name="width_request">571</property>
+                <property name="height_request">367</property>
                 <property name="visible">True</property>
-                <property name="left_padding">12</property>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">automatic</property>
+                <property name="vscrollbar_policy">automatic</property>
+                <property name="shadow_type">out</property>
                 <child>
-                  <object class="GtkImage" id="liveVideo">
-                    <property name="width_request">320</property>
-                    <property name="height_request">240</property>
+                  <object class="GtkViewport" id="replayScroll">
                     <property name="visible">True</property>
+                    <property name="resize_mode">queue</property>
+                    <child>
+                      <object class="GtkVBox" id="vbox1">
+                        <property name="visible">True</property>
+                        <child>
+                          <object class="GtkHandleBox" id="handlebox1">
+                            <property name="height_request">273</property>
+                            <property name="visible">True</property>
+                            <child>
+                              <object class="GtkHBox" id="hbox1">
+                                <property name="visible">True</property>
+                                <child>
+                                  <object class="GtkAspectFrame" id="aspectframe1">
+                                    <property name="width_request">320</property>
+                                    <property name="height_request">240</property>
+                                    <property name="visible">True</property>
+                                    <property name="label_xalign">0</property>
+                                    <property name="shadow_type">out</property>
+                                    <property name="ratio">1.3300000429153442</property>
+                                    <child>
+                                      <object class="GtkImage" id="image1">
+                                        <property name="width_request">320</property>
+                                        <property name="height_request">240</property>
+                                        <property name="visible">True</property>
+                                        <property name="stock">gtk-missing-image</property>
+                                      </object>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkVBox" id="vbox2">
+                                    <property name="visible">True</property>
+                                    <child>
+                                      <object class="GtkHBox" id="hbox2">
+                                        <property name="visible">True</property>
+                                        <child>
+                                          <object class="GtkLabel" id="label5">
+                                            <property name="visible">True</property>
+                                            <property name="label" translatable="yes">Started:</property>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkEntry" id="entry1">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="editable">False</property>
+                                            <property name="invisible_char">&#x25CF;</property>
+                                            <property name="width_chars">12</property>
+                                            <property name="text" translatable="yes">Sat 14:22:25</property>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkToggleButton" id="togglebutton1">
+                                        <property name="label" translatable="yes">Enabled</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">True</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkButton" id="button1">
+                                        <property name="label" translatable="yes">Delete</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">True</property>
+                                        <property name="image">image2</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="position">2</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkCheckButton" id="checkbutton1">
+                                        <property name="label" translatable="yes">Pin to top</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">False</property>
+                                        <property name="draw_indicator">True</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="position">3</property>
+                                      </packing>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </object>
+                    </child>
                   </object>
                 </child>
               </object>
@@ -73,92 +299,14 @@
             </child>
           </object>
           <packing>
-            <property name="x">373</property>
-            <property name="y">23</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkToggleButton" id="liveVideoEnabled">
-            <property name="label" translatable="yes">Enabled</property>
-            <property name="width_request">110</property>
-            <property name="height_request">36</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="active">True</property>
-            <signal name="toggled" handler="on_liveVideoEnabled_toggled"/>
-          </object>
-          <packing>
-            <property name="x">20</property>
-            <property name="y">307</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkSpinButton" id="liveFrameRate">
-            <property name="width_request">52</property>
-            <property name="height_request">25</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="invisible_char">&#x25CF;</property>
-            <property name="numeric">True</property>
-          </object>
-          <packing>
-            <property name="x">96</property>
-            <property name="y">360</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="label1">
-            <property name="width_request">75</property>
-            <property name="height_request">20</property>
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">Frame rate</property>
-          </object>
-          <packing>
-            <property name="x">16</property>
-            <property name="y">363</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkComboBox" id="videoSource">
-            <property name="width_request">100</property>
-            <property name="visible">True</property>
-          </object>
-          <packing>
-            <property name="x">114</property>
-            <property name="y">405</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="label4">
-            <property name="width_request">85</property>
-            <property name="height_request">20</property>
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">Input source</property>
-          </object>
-          <packing>
-            <property name="x">20</property>
-            <property name="y">407</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkScrolledWindow" id="scrolledwindow1">
-            <property name="width_request">336</property>
-            <property name="height_request">310</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="hscrollbar_policy">automatic</property>
-            <property name="vscrollbar_policy">automatic</property>
-            <child>
-              <placeholder/>
-            </child>
-          </object>
-          <packing>
-            <property name="x">383</property>
-            <property name="y">323</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
     </child>
   </object>
+  <object class="GtkImage" id="image2">
+    <property name="visible">True</property>
+    <property name="stock">gtk-delete</property>
+  </object>
 </interface>