Propeller Backpack: Capture NTSC Video
Phil Pilgrim (PhiPi)
Posts: 23,514
There have been a few threads lately about capturing NTSC video with the Propeller. I had a suspicion it could be done with the Propeller Backpack but had never tried it until now. It turns out that it works! Here's a sample image that I captured with just the Backpack, an NTSC video camera, and one external resistor:
The Backpack is programmed to sense sync pulses on P22, using a DUTY-mode analog clamp output on P19 to set and maintain the sync threshold. This is the same method used in the overlay object, which I started with for this program. The signal is also shunted to the "output" side of the Backpack's video circuitry by turning on the MOSFET switch and leaving it on. Capturing the luminance levels is done on hte "output" side with a sigma-delta ADC that uses P14 as the input, P12 as the feedback, and P17 to ground the filter cap. The conversion gain has to be set with an external resistor, which can be installed across the OVL pins. I used an 0805 resistor soldered to a two-pin header connector plugged onto the OVL pins. One could also solder the resistor to the bottom of the board. (The VID pins should be left unjumpered.) Here's a schematic that shows just the key Backpack components:
The integration time for the sigma-delta ADC was set to 45 clocks, or 562.5 ns and yields 91 horizontal pixels from each line with about 5 bits of grayscale. This integration time was set to correspond to two complete 3.57 MHz chroma cycles, which eliminates vertical striping in the image. (I didn't want to filter out the chroma, because I believe now that I can also capture the colors.)
The attached Spin program samples 238 lines in the even field, outputting each one after it's sampled in the form of a 91-character ASCII string. The output can then be copied from the PST screen and pasted into the attached Perl* program. The Perl program scales the data, applies gamma correction, and produces a JPEG file, like the one above. This results in an image whose vertical resolution is about 3.75 times its horizontal resolution.
Needless to say, this is suitable for still subjects only, as the image takes several seconds to acquire and transmit. However, it's entirely feasible to capture and store within the Propeller itself an image with a greatly reduced vertical resolution. By modifying the PASM code to write to a two-dimensional frame buffer, this could be done in one frame time, or 1/30th of a second. To make this happen, it's important that the captured line numbers be all even or all odd. Otherwise, if the lines are acquired sequentially, the capture will bounce back and forth between fields, requiring 1/60th of a second for each line.
One important note: I'm acquiring images without a monitor plugged into the Backpack's Video Out, which means that the camera output does not have a 75-ohm load. This will only work for cameras that produce a proper 2V P-P video output without a load. Some cheaply-built cameras that do not meet this requirement will not sync under no-load conditions. With the 330-ohm external resistor, I get a little bit of saturation at high light levels. To eliminate all saturation, at the possible expense of dynamic range, you can also provide a 75-ohm load, in the form of either a monitor plugged into Video Out or a resistor soldered to the bottom of the board. Another option for limiting saturation would be to increase the value of the external resistor slightly, thus reducing the ADC gain.
I'd spend more time tidying the Perl program to make it more user-friendly, except I'm in hot pursuit of the holy grail, i.e. color capture. More on that later!
-Phil
*If you don't already have Perl installed on your PC, you can obtain it here or here.
The Backpack is programmed to sense sync pulses on P22, using a DUTY-mode analog clamp output on P19 to set and maintain the sync threshold. This is the same method used in the overlay object, which I started with for this program. The signal is also shunted to the "output" side of the Backpack's video circuitry by turning on the MOSFET switch and leaving it on. Capturing the luminance levels is done on hte "output" side with a sigma-delta ADC that uses P14 as the input, P12 as the feedback, and P17 to ground the filter cap. The conversion gain has to be set with an external resistor, which can be installed across the OVL pins. I used an 0805 resistor soldered to a two-pin header connector plugged onto the OVL pins. One could also solder the resistor to the bottom of the board. (The VID pins should be left unjumpered.) Here's a schematic that shows just the key Backpack components:
The integration time for the sigma-delta ADC was set to 45 clocks, or 562.5 ns and yields 91 horizontal pixels from each line with about 5 bits of grayscale. This integration time was set to correspond to two complete 3.57 MHz chroma cycles, which eliminates vertical striping in the image. (I didn't want to filter out the chroma, because I believe now that I can also capture the colors.)
The attached Spin program samples 238 lines in the even field, outputting each one after it's sampled in the form of a 91-character ASCII string. The output can then be copied from the PST screen and pasted into the attached Perl* program. The Perl program scales the data, applies gamma correction, and produces a JPEG file, like the one above. This results in an image whose vertical resolution is about 3.75 times its horizontal resolution.
Needless to say, this is suitable for still subjects only, as the image takes several seconds to acquire and transmit. However, it's entirely feasible to capture and store within the Propeller itself an image with a greatly reduced vertical resolution. By modifying the PASM code to write to a two-dimensional frame buffer, this could be done in one frame time, or 1/30th of a second. To make this happen, it's important that the captured line numbers be all even or all odd. Otherwise, if the lines are acquired sequentially, the capture will bounce back and forth between fields, requiring 1/60th of a second for each line.
One important note: I'm acquiring images without a monitor plugged into the Backpack's Video Out, which means that the camera output does not have a 75-ohm load. This will only work for cameras that produce a proper 2V P-P video output without a load. Some cheaply-built cameras that do not meet this requirement will not sync under no-load conditions. With the 330-ohm external resistor, I get a little bit of saturation at high light levels. To eliminate all saturation, at the possible expense of dynamic range, you can also provide a 75-ohm load, in the form of either a monitor plugged into Video Out or a resistor soldered to the bottom of the board. Another option for limiting saturation would be to increase the value of the external resistor slightly, thus reducing the ADC gain.
I'd spend more time tidying the Perl program to make it more user-friendly, except I'm in hot pursuit of the holy grail, i.e. color capture. More on that later!
-Phil
*If you don't already have Perl installed on your PC, you can obtain it here or here.
Comments
Once again we see that the prop still has a lot of untapped power/functionality to be explored.
Smaller resolution for faster capture sounds great, hope that works.
Color would be awesome, even if it was very low res.
Great news Phil!.
I knew the backpack could do this. Just could not fathom the sync code.
One of the biggest problems is presentation, none of the video reference drivers has any pixel depth. I have been succesful with Eric Balls code in Grey scale to record and present such images with sound on SD cards for a while with the "stupid Video Capture"
Going to try your code with mine to-day, I like that you have computed the NTSC color timing. against the dots.
I have been wondering if the "Phase comparator" could do color decoding. I believe the NTSC spec says that the burst is aligned with the sync trailing edge. you should be able to calculate the reference phase?
Thanks for all your great works!
Perry
Hanno