Tuesday, April 26, 2011

First steps

Ffmpeg, on which I have decided to base the vidplay's decoding, is a library for C. Luckily, C and Python are integrable rather easily, since Python is based on C, and there are a number of ways to cause programs written in the two languages to interact. In some final draft I plan to compile a real installable Python library, but the quickest (and dirtiest) way that I know of to run C code from Python is the ctypes library.

In my first stages, I wrote a rough decoding function in C based on this tutorial. I hadn't really done considerable amounts of work in C before, so I found the code a bit confusing, but after some work made sense of it, and managed to modify it slightly to encode each frame of video to an array passed in standard RGB format and  pack it up nicely in a dll which I can call from Python.

In Python, I used Pygame's handy surfarray module to create a Pygame surface complete with image data from the decoded frame, converted it to a numpy array, and displayed it to the screen! My first step was achieved: data decoding and transfer.

Now, I wrote a quick Thread in Python to decode the data on the fly (Python 2.5, the preferred version for Pygame, does not support multiprocessing), and had the dll decode continuously to an array generated by ctypes and passed from Python. This was nice since I could handle all timing of playback in the C and Ffmpeg proper, and have Python play back each frame whenever it was ready and relevant. However, I reached my first major bottleneck, one that is inevitably hit in any processing-intensive Python project: Python is excruciatingly slow. On a virtual machine with a 1.5 ghz processor and 758 meg of memory, running XP, I achieved about 1.5 frames per second.

My code sits there now, ready for tinkering. I have to cut out much of the junk, delegate as much processing to the C code as possible, and see how much I can improve performance. If that proves to be not enough, I may move from using surfarray to the hardware-accelerated Pygame YUV overlay , but I really don't want to do this, since I have had some difficult time with hardware-acceleration in Pygame in the past, and am aiming for maximum compatibility. If multiprocessingincreases performance considerably, I may move up to Python 2.6 (though Pygame is not as well supported as in 2.5 there yet).


No comments:

Post a Comment