Search code examples
pythonopencvwebcamvideo-capture

How to grab frames from a frame grabber card?


I am trying to write a custom software (in python) to grab frames from a frame grabber card (Hauppauge WinTV-HVR-1900), and I cannot get it to work. The bundled WinTV software works perfectly, and I am able to grab frames from usb webcams, so I know the hardware works. I manage to capture something though, since my screen is completely black but changes to the right size and resolution, so my hunch is it is some sort of decoding problem.

Could anyone help me with an indication or provide a code example for frame extraction from such hardware, please? Should I write an entire custom driver? Or maybe use the VLC python bindings (since VLC does succeed in reading the video stream)?

EDIT:

Basically, my question comes down to this: How is my frame grabber different from a webcam, since the integrated hardware encoder yields an MPEG-2 stream? Shouldn't is behave just as my webcam?

The logic file of my attempt (QT framework using pyQt4 with python 2.7 on windows 7):

#-*- coding: utf-8 -*-
import sys
from VideoCapture import Device
#import Gui files and classes 
import FloGui
import deviceDialog
# PyQT4 imports
from PyQt4 import QtGui, QtCore

class devicedialog(QtGui.QDialog, deviceDialog.Ui_streamDialog):
    #the logic of the streaming device choice dialog
    def __init__(self,parent=None):
        super(devicedialog,self).__init__(parent)
        self.setupUi(self)
        self.retranslateUi(self)
        self.index = None
        i=0
        self.camlist=list()
        while True:
            try:
                cam = Device(i,0)
                name = cam.getDisplayName()
                dev = [name,i]
                self.camlist.append(dev)
                i+=1
                del cam
            except:
                break
        for j in xrange(len(self.camlist)):
            item = QtGui.QListWidgetItem(self.camlist[j][0])
            self.deviceListBox.addItem(item)
        self.exec_()

    def accept(self):
        selected = self.deviceListBox.currentItem().text()
        for k in xrange(len(self.camlist)):
            if self.camlist[k][0]==selected:
                self.index = k
        QtGui.QDialog.accept(self)

class Flolog(QtGui.QMainWindow,FloGui.Ui_MainWindow):
    """
    Flolog is inherited from both QtGui.QDialog and FloGui.Ui_MainWindow
    """
    def __init__(self, parent=None):
        """
            Initialization of the class. Call the __init__ for the super classes
        """
        super(Flolog,self).__init__(parent)
        self.setupUi(self)
        self.retranslateUi(self)
        self.connectActions()

    def streamchoice(self):
        streamdialog = devicedialog()
        self.VideoWidget.stop()
        self.VideoWidget.path = streamdialog.index
        self.VideoWidget.load()
        self.playButton.setEnabled(True)

    def menuloadfile(self):
        filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File', '.')
        self.VideoWidget.stop()
        self.VideoWidget.path = str(filename)
        self.VideoWidget.load()
        self.playButton.setEnabled(True)


    def playbutton(self):
        self.VideoWidget.play()
        self.playButton.setEnabled(False)

    def main(self):
        self.show()

    def quit_(self):
        sys.exit(0)

    def connectActions(self):
        """
        Connect the user interface controls to the logic
        """
        self.actionFile.triggered.connect(self.menuloadfile)
        self.actionStream.triggered.connect(self.streamchoice)
        self.actionQuit.triggered.connect(self.quit_)
        self.playButton.clicked.connect(self.playbutton)
        self.stopButton.clicked.connect(self.VideoWidget.stop)




if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    Flologob = Flolog()
    Flologob.main()
    sys.exit(app.exec_())

Solution

  • I actually finally did solve this. The problem stemmed from the fact that one should first specify which video device should be used by the graphics driver, either manually or in the code. I solved this on Linux Ubuntu by switching devices via the v4l2 graphics driver. I know there is an equivalent maneuver to be performed on Windows.