Commit e28b1236 authored by Joan Pau Beltran's avatar Joan Pau Beltran Committed by Tim-Philipp Müller

dc1394src: port to 1.X

The dc1394src is a PushSrc element for IIDC cameras based on libdc1394.
The implementation from the 0.x series is deffective:
caps negotiation does not work, and some video formats
provided by the camera are not supported.

Refactor the code to port it to 1.X and enhance the support
for the full set of video options of IIDC cameras:

  - The IIDC specification includes a set of camera video modes
    (video format, frame size, and frame rates).
    They do not map perfectly to Gstreamer formats, but those that
    do not match are very rare (if used at all by any camera).
    In addition, although the specification includes a raw format,
    some cameras use mono video formats to capture in Bayer format.
    Map corresponding video modes to Gstreamer formats in capabilities,
    allowing both gray raw and Bayer video formats for mono video modes.

  - The specification includes scalable video modes (Format7),
    where the frame size and rate can be set to arbitrary values
    (within the limits of the camera and the bus transport).
    Allow the use of such mode, using the frame size and rate
    from the negotiatied caps, and set the camera frame rate
    adjusting the packet size as in:
    <http://damien.douxchamps.net/ieee1394/libdc1394/faq/#How_do_I_set_the_frame_rate>

    The scalable modes also allow for a custom ROI offset.
    Support for it can be easily added later using properties.

  - Camera operation using libdc1394 is as follows:

      1. Enumerate cameras on the system and open the camera
         identified the enumeration index or by a GUID (64bit hex code).

      2. Query the video formats supported by the camera.

      3. Configure the camera for the desired video format.

      4. Setup the capture resources for the configured video format
         and start the camera transmission.

      5. Capture frames from the camera and release them when not used.

      6. Stop the camera transmission and clear the capture resources.

      7. Close the camera freeing its resources.

    Do steps 2 and 3 when getting and setting the caps respectively.
    Ideally 4 and 6 would be done when going from PAUSED to PLAYING
    and viceversa, but since caps might not be set yet, the video mode
    is not properly configured leaving the camera in a broken state.
    Hence, setup capture and start transmission in the set caps method,
    and consequently clear the capture and stop the transmission
    when going from PAUSED to READY (instead of PLAYING to PAUSED).
    Symmetrycally, open the camera when going from READY to PAUSED,
    allowing to probe the camera caps in the negotiation stage.
    Implement that using the `start` and `stop` methods of `GstBaseSrc`,
    instead of the `change-state` method of `GstElement`.
    Stop the camera before setting new caps and restarting it again
    to handle caps reconfiguration while in PLAYING (it has no effect
    if the camera is not started).

  - Create buffers copying the bytes of the captured frames.
    Alternatively, the buffers could just wrap the bytes of the frames,
    releasing the frame in the buffer's destroy notify function,
    if all buffers were destroyed before going from PLAYING to PAUSED.

  - No timestamp nor offset is set when creating buffers.
    Timestamping is delegated to the parent class BaseSrc,
    setting `gst_base_src_set_live` TRUE, `gst_base_src_set_format`
    with GST_FORMAT_TIME and `gst_base_src_set_do_timestamp`.
    Captured frames have a timestamp field with the system time
    at the completion of the transmission of the frame,
    but it is not sure that this comes from a monotonic clock,
    and it seems to be left NULL in Windows.

  - Use GUID and unit properties to select the camera to operate on.
    The camera number used in version 0.X does not uniquely identify
    the device (it depends on the set of cameras currently detected).
    Since the GUID is 64bit identifier (same as MAC address),
    handle it with a string property with its hexadecimal representation.
    For practicality, operate on the first camera available if the GUID
    is null (default) and match any camera unit number if unit is -1.
    Alternatively, the GUID could be handed with an unsigned 64 bit
    integer type property, using `0xffffffffffffffff` as default value
    to select the first camera available (it is not a valid GUID value).

  - Keep name `GstDc1394` and prefix `gst_dc1394` as in version 0.X,
    although `GstDC1394Src` and `gst_dc1394_src` are more descriptive.

  - Adjust build files to reenable the compilation of the plugin.

    Remove dc1394 from the list of unported plugins in configure.ac.

    Add the missing flags and libraries to Makefile.
    Use `$()` for variable substitution, as many plugins do,
    although other plugins use `@@` instead.

https://bugzilla.gnome.org/show_bug.cgi?id=763026
parent deb686cf
......@@ -450,7 +450,7 @@ GST_PLUGINS_NONPORTED=" cdxaparse \
sdi tta \
videomeasure \
linsys \
apexsink dc1394 \
apexsink \
musepack nas sdl timidity \
wininet \
xvid sndio libvisual"
......
plugin_LTLIBRARIES = \
libgstdc1394.la
plugin_LTLIBRARIES = libgstdc1394.la
libgstdc1394_la_SOURCES = \
gstdc1394.c
libgstdc1394_la_CFLAGS = \
$(LIBDC1394_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \
$(GST_CFLAGS)
libgstdc1394_la_LIBADD = \
$(LIBDC1394_LIBS) \
$(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \
$(GST_BASE_LIBS) \
$(GST_LIBS)
libgstdc1394_la_LDFLAGS = \
$(GST_PLUGIN_LDFLAGS)
libgstdc1394_la_LIBTOOLFLAGS = \
$(GST_PLUGIN_LIBTOOLFLAGS)
libgstdc1394_la_SOURCES = gstdc1394.c
libgstdc1394_la_CFLAGS = $(GST_CFLAGS) \
$(LIBDC1394_CFLAGS)
libgstdc1394_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstdc1394_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
libgstdc1394_la_LIBADD = $(GST_BASE_LIBS) \
$(LIBDC1394_LIBS)
noinst_HEADERS = gstdc1394.h
noinst_HEADERS = \
gstdc1394.h
This diff is collapsed.
......@@ -27,47 +27,26 @@
G_BEGIN_DECLS
#define GST_TYPE_DC1394 \
(gst_dc1394_get_type())
#define GST_DC1394(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DC1394,GstDc1394))
#define GST_DC1394_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DC1394,GstDc1394))
#define GST_IS_DC1394(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DC1394))
#define GST_IS_DC1394_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DC1394))
#define GST_TYPE_DC1394 (gst_dc1394_get_type())
#define GST_DC1394(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DC1394,GstDc1394))
#define GST_DC1394_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DC1394,GstDc1394))
#define GST_IS_DC1394(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DC1394))
#define GST_IS_DC1394_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DC1394))
typedef struct _GstDc1394 GstDc1394;
typedef struct _GstDc1394Class GstDc1394Class;
struct _GstDc1394 {
GstPushSrc element;
GstPushSrc pushsrc;
/* video state */
gint width;
gint height;
gint vmode;
gint bpp;
gint rate_numerator;
gint rate_denominator;
/* private */
gint64 timestamp_offset; /* base offset */
GstClockTime running_time; /* total running time */
gint64 n_frames; /* total frames sent */
gint64 segment_start_frame;
gint64 segment_end_frame;
gboolean segment;
gint camnum;
gint bufsize;
gint iso_speed;
GstCaps * caps;
uint64_t guid;
int unit;
dc1394speed_t iso_speed;
uint32_t dma_buffer_size;
dc1394camera_t * camera;
dc1394_t * dc1394;
dc1394camera_t * camera;
GstCaps *caps;
};
struct _GstDc1394Class {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment