Programming the camera: Difference between revisions

From OLPC
Jump to navigation Jump to search
(→‎Elements: added fdsrc)
 
(12 intermediate revisions by 7 users not shown)
Line 8: Line 8:
gst-launch-0.10 v4l2src ! ffmpegcolorspace ! pngenc ! filesink location=foo.png
gst-launch-0.10 v4l2src ! ffmpegcolorspace ! pngenc ! filesink location=foo.png


You'll need to run the above command in either a terminal in the developer console (<tt>alt-=</tt>) or one of the virtual terminals (e.g. <tt>ctrl-alt-f1</tt>). Note this means you don't need the Sugar GUI to be running to access the camera.
If you're typing that command in by hand, note that "v4l2src" begins with the characters vee-four-ell-two, an abbreviation for "Video 4 Linux 2.0", and not the number four hundred and twelve. You'll need to run the above command in a terminal, either the Terminal activity, in the developer console (<tt>alt-=</tt>) or one of the virtual terminals (e.g. <tt>ctrl-alt-f1</tt>). Note this means you don't need the Sugar GUI to be running to access the camera.


You can view the PNG image created as a result of the command in the Web activity.
You can view the PNG image created as a result of the command in the Web activity.
Line 14: Line 14:
Now, let's try and get some video on the screen:
Now, let's try and get some video on the screen:


gst-launch-0.10 v4l2src ! ximagesink
gst-launch-0.10 v4l2src ! xvimagesink


Unlike the first command this command will only work when executed in a terminal in the developer console. The resulting video will appear <i>behind </i>the developer console window so you'll need to move the developer console window aside to see the video.
Unlike the first command this command will only work with an X display, eg when executed in Terminal activity or a terminal in the developer console.


Since you've now had your first hit of "ooo, shiny" moving pictures let's take a look at what's happening behind the scenes.
Since you've now had your first hit of "ooo, shiny" moving pictures let's take a look at what's happening behind the scenes.
Line 22: Line 22:
== What just happened? ==
== What just happened? ==


I'm going to assume you have a passing familiarity with GStreamer, if not, you could go read about it. Basically, it's a series of pipes you can throw multimedia data down and get something in a file or on screen at the end. The data starts at a source (<tt>src</tt>) and ends up in a sink (<tt>sink</tt>) and can go through a number of intermediate manipulations along the way.
I'm going to assume you have a passing familiarity with [http://gstreamer.freedesktop.org/ GStreamer], if not, you could go read about it. Basically, it's a series of pipes you can throw multimedia data down and get something in a file or on screen at the end. The data starts at a source (<tt>src</tt>) and ends up in a sink (<tt>sink</tt>) and can go through a number of intermediate manipulations along the way.


While we will get to using the camera from Python eventually, we've started out with using the GStreamer command line tool <tt>gst-launch</tt>. The <tt>gst-launch</tt> tool is a quick way to experiment with putting a pipeline together and seeing what it does.
While we will get to using the camera from Python eventually, we've started out with using the GStreamer command line tool <tt>gst-launch</tt>. The <tt>gst-launch</tt> tool is a quick way to experiment with putting a pipeline together and seeing what it does.
Line 30: Line 30:
gst-launch-0.10 v4l2src ! ffmpegcolorspace ! pngenc ! filesink location=foo.png
gst-launch-0.10 v4l2src ! ffmpegcolorspace ! pngenc ! filesink location=foo.png


The camera in a XO laptop is a regular [http://linuxtv.org/v4lwiki/ Video4Linux 2] device which is accessed via GStreamer's <tt>v4l2src</tt> source--see that wasn't just a pile of random characters my cat threw up. Since the camera is our source it's the first item in our pipeline--notice the individual parts of the pipeline are separated with <tt>!</tt> characters. (You could say the data goes out with a bang but it'd be a pretty bad joke.)
The camera in a XO laptop is a regular [http://linuxtv.org/v4lwiki/ Video4Linux 2] device which is accessed via GStreamer's <tt>v4l2src</tt> source. Since the camera is our source it's the first item in our pipeline--notice the individual parts of the pipeline are separated with <tt>!</tt> characters. (You could say the data goes out with a bang but it'd be a pretty bad joke.)


Next, we'll skip to look at the end of the pipeline--the sink end--here we find the <tt>filesink</tt> which simply outputs some data to a particular file. The name of the file (in our case <tt>foo.png</tt>) is provided by specifying <tt>location=foo.png</tt>&mdash;this is an example of how to supply arguments to the individual items in the pipeline. (Note: if you try to use <tt>name=</tt> it won't work! The <tt>name</tt> parameter is for referring to the element in the pipeline, <i>not</i> the name of the destination file.)
Next, we'll skip to look at the end of the pipeline--the sink end--here we find the <tt>filesink</tt> which simply outputs some data to a particular file. The name of the file (in our case <tt>foo.png</tt>) is provided by specifying <tt>location=foo.png</tt>&mdash;this is an example of how to supply arguments to the individual items in the pipeline. (Note: if you try to use <tt>name=</tt> it won't work! The <tt>name</tt> parameter is for referring to the element in the pipeline, <i>not</i> the name of the destination file.)
Line 37: Line 37:


The only other item in the pipeline is the delightfully named <tt>ffmpegcolorspace</tt> plugin which performs colorspace conversions&mdash;essentially the <tt>v4l2src</tt> and <tt>pngenc</tt> plugins can't talk to each other directly because they each describe images in different ways, it's the job of <tt>ffmpegcolorspace</tt> to enable them to communicate by translating between the two styles of image description.
The only other item in the pipeline is the delightfully named <tt>ffmpegcolorspace</tt> plugin which performs colorspace conversions&mdash;essentially the <tt>v4l2src</tt> and <tt>pngenc</tt> plugins can't talk to each other directly because they each describe images in different ways, it's the job of <tt>ffmpegcolorspace</tt> to enable them to communicate by translating between the two styles of image description.

<i>More to come...</i>
----
Note: The author is learning this as he goes along, so items described may not be the best way or correct way to do anything. And he might get bored with writing this and stop halfw


== Doing it in Python ==
== Doing it in Python ==
Line 73: Line 69:
==GStreamer 101==
==GStreamer 101==


Moved to [[GStreamer#GStreamer 101]].
===Examples===
v4l2src can always be replaced by videotestsrc, and alsasrc by audiotestsrc.

Beginning of a normal video pipeline:
v4l2src ! queue ! videorate ! video/x-raw-yuv,framerate=15/1 ! videoscale ! video/x-raw-yuv,width=160,height=120 ! ...
Beginning of a normal audio pipeline:
alsasrc ! audio/x-raw-int,rate=8000,channels=1,depth=8 ! ...
Video encoding:
... ! ffmpegcolorspace ! theoraenc ! ...
Audio encoding:
... ! audioconvert ! vorbisenc ! ...
Video output:
... ! ffmpegcolorspace ! videoscale ! ximagesink
Audio output:
... ! audioconvert ! alsasink ''sync=false''
Stdout:
... ! fdsink ''fd=1''

Encode video+audio as ogg:
v4l2src ! queue ! ffmpegcolorspace ! theoraenc ! queue ! \
oggmux name=mux alsasrc ! queue ! audioconvert ! vorbisenc ! queue ! mux. mux. ! queue ! ...

A long version of videotestsrc ! ximagesink:
videotestsrc ! theoraenc ! oggmux ! oggdemux ! theoradec ! ffmpegcolorspace ! videoscale ! ximagesink
A long version of videotestsrc ! ximagesink &amp;; audiotestsrc ! alsasink:
videotestsrc ! ffmpegcolorspace ! theoraenc ! queue ! \
oggmux name=mux audiotestsrc ! audioconvert ! vorbisenc ! queue ! mux. mux. ! queue ! \
oggdemux name=demux ! queue ! theoradec ! ffmpegcolorspace ! \
ximagesink demux. ! queue ! vorbisdec ! audioconvert ! alsasink
:Hangs on current fc6. [[User:MitchellNCharity|MitchellNCharity]] 17:43, 12 June 2007 (EDT)

Live video streaming to an icecast server:
v4l2src ! ffmpegcolorspace ! videoscale ! video/x-raw-yuv,width=320,height=240 ! theoraenc quality=16 ! oggmux ! shout2send ip=192.168.1.100 port=8000 password=hackme mount=olpc.ogg

Live streaming to an icecast server:
v4l2src ! queue ! ffmpegcolorspace ! theoraenc quality=16 ! queue ! oggmux name=mux alsasrc ! audio/x-raw-int,rate=8000,channels=1,depth=8 ! queue ! audioconvert ! vorbisenc ! queue ! mux. mux. ! \
queue ! shout2send ip=... port=... password=... mount=/''whatever''.ogg

===Notes===
====video size, framerate, and theoraenc quality====

====audio encoding====
glive.py used wav rather than vorbis. Why?

===Elements===

Adapters:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-tee.html tee]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-queue.html queue]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-videoscale.html videoscale] Convert video size.
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-videorate.html videorate] Convert video rate.
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-ffmpegcolorspace.html ffmpegcolorspace] Convert video colorspace.
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-audioconvert.html audioconvert] Convert audio format.

Video characteristics:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html#table-video-types video/x-raw-yuv]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html#table-video-types framerate=15/1]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html#table-video-types width=160,height=120]
Audio characteristics:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html#table-audio-types audio/x-raw-int,rate=8000,channels=1,depth=8]

File I/O:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-fdsrc.html fdsrc]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-fdsink.html fdsink]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-filesrc.html filesrc]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-filesink.html filesink]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-gnomevfssrc.html gnomevfssrc]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-gnomevfssink.html gnomevfssink]

Video sources:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-videotestsrc.html videotestsrc]
*{{broken link|[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-v4l2src.html v4l2src]}}

Audio sources:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-audiotestsrc.html audiotestsrc]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-alsasrc.html alsasrc]

Coding video:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-theoraenc.html theoraenc]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-theoradec.html theoradec]

Coding audio:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-vorbisenc.html vorbisenc]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-vorbisdec.html vorbisdec]

Wrapping:
*{{broken link|[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-oggmux.html oggmux]}} ''([[User:MitchellNCharity|MitchellNCharity]] 11:44, 13 June 2007 (EDT))''
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-oggdemux.html oggdemux]

Outputing video:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-ximagesink.html ximagesink] ''or'' [http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-xvimagesink.html xvimagesink]

Outputting audio:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-alsasink.html alsasink]

Not sure about:
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-vorbisparse.html vorbisparse]

Sending ogg to an icecast streaming server:
... ! shout2send ip=... port=... password=... mount=/whatever.ogg
gst-launch ... ! fdsink '''|''' oggfwd ''host port password mount''

:Regretabbly, it appears fc6, and thus olpc, does not include shout2send in gst-plugins-good-plugins. Nor does it have rpms for [http://www.v2v.cc/~j/ffmpeg2theora/oggfwd/ oggfwd], or other possible alternatives. You can grab a random binary of oggfwd from it's site, or compile shout2send from source. :( [[User:MitchellNCharity|MitchellNCharity]] 17:43, 12 June 2007 (EDT)

:Correction, shout2send is on the olpc. oggfwd is not. --[[User:Damonkohler|Damonkohler]] 23:14, 13 September 2007 (EDT)

===Doing live streaming video from an xo===

==Section TODO==
*Fill in blank sections.
*Include snapshot recipes.
*Discuss python interfacing.


== Other resources ==
==See also==
*[[:Category:Camera]]
*http://mediamods.com/public-svn/camera-activity/Camera.activity/glive.py
*[[Vision processing]]
*https://coderanger.net/svn/projects/olpc/games/olpcgames/camera.py ''(said to not really be working (trouble knowing when gs is done) [[User:MitchellNCharity|MitchellNCharity]] 18:24, 12 June 2007 (EDT))''
*http://gburt.blogspot.com/2007/11/one-laptop-per-photographer.html
*''Where is the camera code in sugar?'' [[User:MitchellNCharity|MitchellNCharity]] 18:16, 12 June 2007 (EDT)
*http://auricle.dyndns.org/ALE/ ALE is an image-processing program used for tasks such as image mosaicking, super-resolution, deblurring, noise reduction, anti-aliasing, and scene reconstruction. Its principle of operation is synthetic capture, combining multiple inputs representing the same scene.
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/index.html gstreamer-plugins]
*[[MotionDetection]]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-plugin-coreelements.html gstreamer-plugins-plugin-coreelements]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/index.html gst-plugins-base-plugins]
*[http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/index.html gst-plugins-good-plugins]
*[http://www.google.com/search?hl=en&q=site%3Agstreamer.freedesktop.org&btnG=Search google search "site:gstreamer.freedesktop.org"]
*http://xiph.org/ Ogg/Theora/Vorbis


[[Category:Developers]]
[[Category:Developers]]

Latest revision as of 07:41, 9 June 2015

  english | 한국어 HowTo [ID# 297406]  +/-  

This page explores how to interact with the laptop's built-in video camera.

Getting started

First, let's see the quickest way we can capture a still image from the camera--using a GStreamer command-line tool:

 gst-launch-0.10 v4l2src ! ffmpegcolorspace ! pngenc ! filesink location=foo.png

If you're typing that command in by hand, note that "v4l2src" begins with the characters vee-four-ell-two, an abbreviation for "Video 4 Linux 2.0", and not the number four hundred and twelve. You'll need to run the above command in a terminal, either the Terminal activity, in the developer console (alt-=) or one of the virtual terminals (e.g. ctrl-alt-f1). Note this means you don't need the Sugar GUI to be running to access the camera.

You can view the PNG image created as a result of the command in the Web activity.

Now, let's try and get some video on the screen:

 gst-launch-0.10 v4l2src ! xvimagesink

Unlike the first command this command will only work with an X display, eg when executed in Terminal activity or a terminal in the developer console.

Since you've now had your first hit of "ooo, shiny" moving pictures let's take a look at what's happening behind the scenes.

What just happened?

I'm going to assume you have a passing familiarity with GStreamer, if not, you could go read about it. Basically, it's a series of pipes you can throw multimedia data down and get something in a file or on screen at the end. The data starts at a source (src) and ends up in a sink (sink) and can go through a number of intermediate manipulations along the way.

While we will get to using the camera from Python eventually, we've started out with using the GStreamer command line tool gst-launch. The gst-launch tool is a quick way to experiment with putting a pipeline together and seeing what it does.

Let's take a look at that first command line again:

 gst-launch-0.10 v4l2src ! ffmpegcolorspace ! pngenc ! filesink location=foo.png

The camera in a XO laptop is a regular Video4Linux 2 device which is accessed via GStreamer's v4l2src source. Since the camera is our source it's the first item in our pipeline--notice the individual parts of the pipeline are separated with ! characters. (You could say the data goes out with a bang but it'd be a pretty bad joke.)

Next, we'll skip to look at the end of the pipeline--the sink end--here we find the filesink which simply outputs some data to a particular file. The name of the file (in our case foo.png) is provided by specifying location=foo.png—this is an example of how to supply arguments to the individual items in the pipeline. (Note: if you try to use name= it won't work! The name parameter is for referring to the element in the pipeline, not the name of the destination file.)

As you can probably guess, the pngenc plugin is in the pipeline to convert the data from the video camera into the PNG file format before it is written to the the file.

The only other item in the pipeline is the delightfully named ffmpegcolorspace plugin which performs colorspace conversions—essentially the v4l2src and pngenc plugins can't talk to each other directly because they each describe images in different ways, it's the job of ffmpegcolorspace to enable them to communicate by translating between the two styles of image description.

Doing it in Python

Implementing the same pipeline in Python might look like this:

import gst
import tempfile

GST_PIPE = ['v4l2src', 'ffmpegcolorspace', 'pngenc']

class Camera(object):

  """A class representing the OLPC camera."""

  def __init__(self):
    snap_file, self.snap_path = tempfile.mkstemp()
    pipe = GST_PIPE + ['filesink location=%s' % self.snap_path]
    self.pipe = gst.parse_launch('!'.join(pipe))
    self.bus = self.pipe.get_bus()

  def Snap(self):
    """Take a snapshot."""
    self.pipe.set_state(gst.STATE_PLAYING)
    self.bus.poll(gst.MESSAGE_EOS, -1)

if __name__ == '__main__':
  c = Camera()
  c.Snap()
  print c.snap_path

GStreamer 101

Moved to GStreamer#GStreamer 101.

See also