mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-10 10:04:23 +00:00
negotiating webcam framerate now works
Original commit message from CVS: negotiating webcam framerate now works
This commit is contained in:
parent
765f8c50ba
commit
f8044583c0
3 changed files with 158 additions and 8 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2004-06-09 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* sys/v4l/gstv4lsrc.c: (gst_v4lsrc_get_fps_list),
|
||||
(gst_v4lsrc_get_fps), (gst_v4lsrc_srcconnect),
|
||||
(gst_v4lsrc_getcaps):
|
||||
* sys/v4l/v4l_calls.c: (gst_v4l_set_window_properties),
|
||||
(gst_v4l_get_picture), (gst_v4l_get_audio), (gst_v4l_set_audio):
|
||||
add querying of fps lists for webcams. Negotiating to a framerate
|
||||
now works.
|
||||
|
||||
2004-06-08 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* ext/theora/theoraenc.c: (theora_buffer_from_packet),
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include "v4lsrc_calls.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/* FIXME: small cheat */
|
||||
gboolean gst_v4l_set_window_properties (GstV4lElement * v4lelement);
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_v4lsrc_details =
|
||||
|
@ -273,6 +277,68 @@ gst_v4lsrc_close (GstElement * element, const gchar * device)
|
|||
v4lsrc->colourspaces = NULL;
|
||||
}
|
||||
|
||||
/* get a list of possible framerates
|
||||
* this is only done for webcams;
|
||||
* other devices return NULL here.
|
||||
*/
|
||||
static GValue *
|
||||
gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc)
|
||||
{
|
||||
gint fps_index;
|
||||
gfloat fps;
|
||||
struct video_window *vwin = &GST_V4LELEMENT (v4lsrc)->vwin;
|
||||
GstV4lElement *v4lelement = GST_V4LELEMENT (v4lsrc);
|
||||
|
||||
/* check if we have vwin window properties giving a framerate,
|
||||
* as is done for webcams
|
||||
* See http://www.smcc.demon.nl/webcam/api.html
|
||||
* which is used for the Philips and qce-ga drivers */
|
||||
fps_index = (vwin->flags >> 16) & 0x3F; /* 6 bit index for framerate */
|
||||
|
||||
/* webcams have a non-zero fps_index */
|
||||
if (fps_index == 0) {
|
||||
GST_DEBUG_OBJECT (v4lsrc, "fps_index is 0, no webcam");
|
||||
return NULL;
|
||||
}
|
||||
GST_DEBUG_OBJECT (v4lsrc, "fps_index is %d, so webcam", fps_index);
|
||||
|
||||
{
|
||||
gfloat current_fps;
|
||||
int i;
|
||||
GValue *list = NULL;
|
||||
GValue value = { 0 };
|
||||
|
||||
/* webcam detected, so try all framerates and return a list */
|
||||
|
||||
list = g_new0 (GValue, 1);
|
||||
g_value_init (list, GST_TYPE_LIST);
|
||||
|
||||
/* index of 16 corresponds to 15 fps */
|
||||
current_fps = fps_index * 15.0 / 16;
|
||||
GST_DEBUG_OBJECT (v4lsrc, "device reports fps of %.4f", current_fps);
|
||||
for (i = 1; i < 63; ++i) {
|
||||
/* set bits 16 to 21 to 0 */
|
||||
vwin->flags &= (0x3F00 - 1);
|
||||
/* set bits 16 to 21 to the index */
|
||||
vwin->flags |= i << 16;
|
||||
if (gst_v4l_set_window_properties (v4lelement)) {
|
||||
/* setting it succeeded. FIXME: get it and check. */
|
||||
fps = i * 15.0 / 16;
|
||||
g_value_init (&value, G_TYPE_DOUBLE);
|
||||
g_value_set_double (&value, fps);
|
||||
gst_value_list_append_value (list, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
}
|
||||
/* FIXME: set back the original fps_index */
|
||||
vwin->flags &= (0x3F00 - 1);
|
||||
vwin->flags |= fps_index << 16;
|
||||
gst_v4l_set_window_properties (v4lelement);
|
||||
return list;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gfloat
|
||||
gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc)
|
||||
{
|
||||
|
@ -286,9 +352,16 @@ gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc)
|
|||
* See http://www.smcc.demon.nl/webcam/api.html
|
||||
* which is used for the Philips and qce-ga drivers */
|
||||
fps_index = (vwin->flags >> 16) & 0x3F; /* 6 bit index for framerate */
|
||||
if (fps_index != 0)
|
||||
|
||||
/* webcams have a non-zero fps_index */
|
||||
if (fps_index != 0) {
|
||||
gfloat current_fps;
|
||||
|
||||
/* index of 16 corresponds to 15 fps */
|
||||
return fps_index * 15.0 / 16;
|
||||
current_fps = fps_index * 15.0 / 16;
|
||||
GST_LOG_OBJECT (v4lsrc, "device reports fps of %.3f", current_fps);
|
||||
return current_fps;
|
||||
}
|
||||
|
||||
if (!v4lsrc->use_fixed_fps && v4lsrc->clock != NULL && v4lsrc->handled > 0) {
|
||||
/* try to get time from clock master and calculate fps */
|
||||
|
@ -508,6 +581,21 @@ gst_v4lsrc_srcconnect (GstPad * pad, const GstCaps * vscapslist)
|
|||
gst_structure_get_int (structure, "height", &h);
|
||||
gst_structure_get_double (structure, "framerate", &fps);
|
||||
|
||||
/* set framerate if it's not already correct */
|
||||
if (fps != gst_v4lsrc_get_fps (v4lsrc)) {
|
||||
int fps_index = fps / 15.0 * 16;
|
||||
struct video_window *vwin = &GST_V4LELEMENT (v4lsrc)->vwin;
|
||||
|
||||
GST_DEBUG_OBJECT (v4lsrc, "Trying to set fps index %d", fps_index);
|
||||
/* set bits 16 to 21 to 0 */
|
||||
vwin->flags &= (0x3F00 - 1);
|
||||
/* set bits 16 to 21 to the index */
|
||||
vwin->flags |= fps_index << 16;
|
||||
if (!gst_v4l_set_window_properties (GST_V4LELEMENT (v4lsrc))) {
|
||||
GST_ELEMENT_ERROR (v4lsrc, RESOURCE, SETTINGS, (NULL),
|
||||
("Could not set framerate of %d fps", fps));
|
||||
}
|
||||
}
|
||||
switch (fourcc) {
|
||||
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
|
||||
palette = VIDEO_PALETTE_YUV420P;
|
||||
|
@ -626,14 +714,19 @@ gst_v4lsrc_getcaps (GstPad * pad)
|
|||
GstCaps *list;
|
||||
GstV4lSrc *v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad));
|
||||
struct video_capability *vcap = &GST_V4LELEMENT (v4lsrc)->vcap;
|
||||
gfloat fps;
|
||||
gfloat fps = 0.0;
|
||||
GList *item;
|
||||
static GValue *fps_list; /* FIXME: this should be done in a hash table
|
||||
* on device name instead */
|
||||
|
||||
if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) {
|
||||
return gst_caps_new_any ();
|
||||
}
|
||||
|
||||
fps = gst_v4lsrc_get_fps (v4lsrc);
|
||||
/* if not cached from last run, get it */
|
||||
if (!fps_list)
|
||||
fps_list = gst_v4lsrc_get_fps_list (v4lsrc);
|
||||
if (!fps_list)
|
||||
fps = gst_v4lsrc_get_fps (v4lsrc);
|
||||
|
||||
list = gst_caps_new_empty ();
|
||||
for (item = v4lsrc->colourspaces; item != NULL; item = item->next) {
|
||||
|
@ -649,7 +742,18 @@ gst_v4lsrc_getcaps (GstPad * pad)
|
|||
|
||||
gst_caps_set_simple (one, "width", GST_TYPE_INT_RANGE, vcap->minwidth,
|
||||
vcap->maxwidth, "height", GST_TYPE_INT_RANGE, vcap->minheight,
|
||||
vcap->maxheight, "framerate", G_TYPE_DOUBLE, fps, NULL);
|
||||
vcap->maxheight, NULL);
|
||||
|
||||
if (fps_list) {
|
||||
GstStructure *structure = gst_caps_get_structure (one, 0);
|
||||
|
||||
gst_structure_set_value (structure, "framerate", fps_list);
|
||||
} else {
|
||||
GstStructure *structure = gst_caps_get_structure (one, 0);
|
||||
|
||||
gst_structure_set (structure, "framerate", G_TYPE_DOUBLE, fps, NULL);
|
||||
}
|
||||
GST_DEBUG_OBJECT (v4lsrc, "caps: %" GST_PTR_FORMAT, one);
|
||||
gst_caps_append (list, one);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,10 +42,9 @@
|
|||
#include "gstv4lmjpegsrc.h"
|
||||
#include "gstv4lmjpegsink.h"
|
||||
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (v4l_debug);
|
||||
|
||||
#define GST_CATEGORY_DEFAULT v4l_debug
|
||||
#define GST_CAT_DEFAULT v4l_debug
|
||||
|
||||
static const char *picture_name[] = {
|
||||
"Hue",
|
||||
|
@ -98,6 +97,43 @@ gst_v4l_get_capabilities (GstV4lElement * v4lelement)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* gst_v4l_set_window_properties():
|
||||
* set the device's capturing parameters (vwin)
|
||||
* return value: TRUE on success, FALSE on error
|
||||
******************************************************/
|
||||
|
||||
gboolean
|
||||
gst_v4l_set_window_properties (GstV4lElement * v4lelement)
|
||||
{
|
||||
struct video_window vwin;
|
||||
|
||||
GST_DEBUG_OBJECT (v4lelement, "setting window flags 0x%x to device %s",
|
||||
v4lelement->vwin.flags, v4lelement->videodev);
|
||||
GST_V4L_CHECK_OPEN (v4lelement);
|
||||
|
||||
if (ioctl (v4lelement->video_fd, VIDIOCSWIN, &(v4lelement->vwin)) < 0) {
|
||||
GST_DEBUG_OBJECT (v4lelement,
|
||||
"could not ioctl window properties 0x%x to device %s",
|
||||
v4lelement->vwin.flags, v4lelement->videodev);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get it again to make sure we have it correctly */
|
||||
if (ioctl (v4lelement->video_fd, VIDIOCGWIN, &(vwin)) < 0) {
|
||||
GST_ELEMENT_ERROR (v4lelement, RESOURCE, SETTINGS, (NULL),
|
||||
("error getting window properties %s of from device %s",
|
||||
g_strerror (errno), v4lelement->videodev));
|
||||
return FALSE;
|
||||
}
|
||||
if (vwin.flags != v4lelement->vwin.flags) {
|
||||
GST_DEBUG_OBJECT (v4lelement, "set 0x%x but got 0x%x back",
|
||||
v4lelement->vwin.flags, vwin.flags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* gst_v4l_open():
|
||||
|
|
Loading…
Reference in a new issue