mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
ext/libvisual/visual.c: Fix the fps calculations.
Original commit message from CVS: * ext/libvisual/visual.c: (gst_visual_chain): Fix the fps calculations. * gst/ffmpegcolorspace/avcodec.h: Move structure element for clarity * gst-libs/gst/interfaces/tunernorm.c: (gst_tuner_norm_init): * gst-libs/gst/interfaces/tunernorm.h: * sys/v4l/gstv4ljpegsrc.c: (gst_v4ljpegsrc_src_link): * sys/v4l/gstv4lmjpegsink.c: (gst_v4lmjpegsink_base_init): * sys/v4l/gstv4lmjpegsrc.c: (gst_v4lmjpegsrc_base_init), (gst_v4lmjpegsrc_get_fps), (gst_v4lmjpegsrc_src_convert), (gst_v4lmjpegsrc_src_query), (gst_v4lmjpegsrc_get), (gst_v4lmjpegsrc_getcaps): * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_fixate), (gst_v4lsrc_get_caps), (gst_v4lsrc_set_caps): * sys/v4l/gstv4lsrc.h: * sys/v4l/v4l_calls.c: (gst_v4l_open): * sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_get_fps), (gst_v4lsrc_get_fps_list), (gst_v4lsrc_buffer_new): * sys/v4l/v4lsrc_calls.h: Fractional framerates...
This commit is contained in:
parent
f5ddd5037a
commit
674ee67e8b
10 changed files with 142 additions and 92 deletions
|
@ -396,7 +396,7 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
|
|||
visual->next_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* spf = samples per frame */
|
||||
spf = ((guint64) (visual->rate) * visual->fps_n) / visual->fps_d;
|
||||
spf = ((guint64) (visual->rate) * visual->fps_d) / visual->fps_n;
|
||||
gst_adapter_push (visual->adapter, buffer);
|
||||
|
||||
while (gst_adapter_available (visual->adapter) > MAX (512, spf) * 4 &&
|
||||
|
@ -423,7 +423,8 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
|
|||
visual_actor_run (visual->actor, &visual->audio);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = visual->next_ts;
|
||||
GST_BUFFER_DURATION (outbuf) = GST_SECOND * visual->fps_n / visual->fps_d;
|
||||
GST_BUFFER_DURATION (outbuf) = gst_util_clock_time_scale (GST_SECOND,
|
||||
visual->fps_d, visual->fps_n);
|
||||
visual->next_ts += GST_BUFFER_DURATION (outbuf);
|
||||
ret = gst_pad_push (visual->srcpad, outbuf);
|
||||
outbuf = NULL;
|
||||
|
@ -431,7 +432,7 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
|
|||
|
||||
/* Flush out the number of samples per frame * channels * sizeof (gint16) */
|
||||
/* Recompute spf in case caps changed */
|
||||
spf = ((guint64) (visual->rate) * visual->fps_n) / visual->fps_d;
|
||||
spf = ((guint64) (visual->rate) * visual->fps_d) / visual->fps_n;
|
||||
GST_DEBUG_OBJECT (visual, "finished frame, flushing %u samples from input",
|
||||
spf);
|
||||
gst_adapter_flush (visual->adapter,
|
||||
|
|
|
@ -132,6 +132,14 @@ typedef struct AVCodecContext {
|
|||
*/
|
||||
int frame_rate;
|
||||
|
||||
/**
|
||||
* frame_rate_base.
|
||||
* for variable fps this is 1
|
||||
* - encoding: set by user.
|
||||
* - decoding: set by lavc.
|
||||
*/
|
||||
|
||||
int frame_rate_base;
|
||||
/**
|
||||
* picture width / height.
|
||||
* - encoding: MUST be set by user.
|
||||
|
@ -162,16 +170,6 @@ typedef struct AVCodecContext {
|
|||
* - decoding: set by user.
|
||||
*/
|
||||
struct AVPaletteControl *palctrl;
|
||||
|
||||
/**
|
||||
* frame_rate_base.
|
||||
* for variable fps this is 1
|
||||
* - encoding: set by user.
|
||||
* - decoding: set by lavc.
|
||||
* @todo move this after frame_rate
|
||||
*/
|
||||
|
||||
int frame_rate_base;
|
||||
} AVCodecContext;
|
||||
|
||||
/**
|
||||
|
|
|
@ -117,7 +117,7 @@ gst_v4ljpegsrc_src_link (GstPad * pad, const GstCaps * vscapslist)
|
|||
GstV4lJpegSrc *v4ljpegsrc;
|
||||
GstV4lSrc *v4lsrc;
|
||||
gint w, h, palette = -1;
|
||||
gdouble fps;
|
||||
const GValue *fps;
|
||||
GstStructure *structure;
|
||||
gboolean was_capturing;
|
||||
struct video_window *vwin;
|
||||
|
@ -144,9 +144,11 @@ gst_v4ljpegsrc_src_link (GstPad * pad, const GstCaps * vscapslist)
|
|||
|
||||
gst_structure_get_int (structure, "width", &w);
|
||||
gst_structure_get_int (structure, "height", &h);
|
||||
gst_structure_get_double (structure, "framerate", &fps);
|
||||
fps = gst_structure_get_value (structure, "framerate");
|
||||
|
||||
GST_DEBUG_OBJECT (v4ljpegsrc, "linking with %dx%d at %f fps", w, h, fps);
|
||||
GST_DEBUG_OBJECT (v4ljpegsrc, "linking with %dx%d at %d/%d fps", w, h,
|
||||
gst_value_get_fraction_numerator (fps),
|
||||
gst_value_get_fraction_denominator (fps));
|
||||
|
||||
/* set framerate if it's not already correct */
|
||||
if (fps != gst_v4lsrc_get_fps (v4lsrc)) {
|
||||
|
|
|
@ -114,7 +114,7 @@ gst_v4lmjpegsink_base_init (gpointer g_class)
|
|||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("image/jpeg, "
|
||||
"width = (int) [ 1, MAX ], "
|
||||
"height = (int) [ 1, MAX ], " "framerate = (double) [ 0, MAX ]")
|
||||
"height = (int) [ 1, MAX ], " "framerate = (fraction) [ 0, MAX ]")
|
||||
);
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ gst_v4lmjpegsrc_base_init (gpointer g_class)
|
|||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("image/jpeg, "
|
||||
"width = (int) [ 0, MAX ], "
|
||||
"height = (int) [ 0, MAX ], " "framerate = (double) [ 0, MAX ]")
|
||||
"height = (int) [ 0, MAX ], " "framerate = (fraction) [ 0, MAX ]")
|
||||
);
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
|
@ -268,11 +268,12 @@ gst_v4lmjpegsrc_init (GstV4lMjpegSrc * v4lmjpegsrc)
|
|||
}
|
||||
|
||||
|
||||
static gfloat
|
||||
gst_v4lmjpegsrc_get_fps (GstV4lMjpegSrc * v4lmjpegsrc)
|
||||
static gboolean
|
||||
gst_v4lmjpegsrc_get_fps (GstV4lMjpegSrc * v4lmjpegsrc, GValue * fps)
|
||||
{
|
||||
gint norm;
|
||||
gfloat fps;
|
||||
|
||||
g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (fps), FALSE);
|
||||
|
||||
if (!v4lmjpegsrc->use_fixed_fps &&
|
||||
v4lmjpegsrc->clock != NULL && v4lmjpegsrc->handled > 0) {
|
||||
|
@ -285,17 +286,17 @@ gst_v4lmjpegsrc_get_fps (GstV4lMjpegSrc * v4lmjpegsrc)
|
|||
/* if that failed ... */
|
||||
|
||||
if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lmjpegsrc)))
|
||||
return 0.;
|
||||
return FALSE;
|
||||
|
||||
if (!gst_v4l_get_chan_norm (GST_V4LELEMENT (v4lmjpegsrc), NULL, &norm))
|
||||
return 0.;
|
||||
return FALSE;
|
||||
|
||||
if (norm == VIDEO_MODE_NTSC)
|
||||
fps = 30000 / 1001;
|
||||
gst_value_set_fraction (fps, 30000, 1001);
|
||||
else
|
||||
fps = 25.;
|
||||
gst_value_set_fraction (fps, 25, 1);
|
||||
|
||||
return fps;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -304,39 +305,46 @@ gst_v4lmjpegsrc_src_convert (GstPad * pad,
|
|||
gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
|
||||
{
|
||||
GstV4lMjpegSrc *v4lmjpegsrc;
|
||||
gdouble fps;
|
||||
GValue fps = { 0 };
|
||||
gboolean result = TRUE;
|
||||
|
||||
v4lmjpegsrc = GST_V4LMJPEGSRC (gst_pad_get_parent (pad));
|
||||
|
||||
if ((fps = gst_v4lmjpegsrc_get_fps (v4lmjpegsrc)) == 0)
|
||||
g_value_init (&fps, GST_VALUE_FRACTION);
|
||||
if (!gst_v4lmjpegsrc_get_fps (v4lmjpegsrc, &fps))
|
||||
return FALSE;
|
||||
|
||||
switch (src_format) {
|
||||
case GST_FORMAT_TIME:
|
||||
switch (*dest_format) {
|
||||
case GST_FORMAT_DEFAULT:
|
||||
*dest_value = src_value * fps / GST_SECOND;
|
||||
*dest_value = gst_util_uint64_scale (src_value,
|
||||
gst_value_get_fraction_numerator (&fps),
|
||||
gst_value_get_fraction_denominator (&fps) * GST_SECOND);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
result = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case GST_FORMAT_DEFAULT:
|
||||
switch (*dest_format) {
|
||||
case GST_FORMAT_TIME:
|
||||
*dest_value = src_value * GST_SECOND / fps;
|
||||
*dest_value = src_value * gst_util_clock_time_scale (GST_SECOND,
|
||||
gst_value_get_fraction_denominator (&fps),
|
||||
gst_value_get_fraction_numerator (&fps));
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
result = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
g_value_unset (&fps);
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -345,16 +353,19 @@ gst_v4lmjpegsrc_src_query (GstPad * pad,
|
|||
{
|
||||
GstV4lMjpegSrc *v4lmjpegsrc = GST_V4LMJPEGSRC (gst_pad_get_parent (pad));
|
||||
gboolean res = TRUE;
|
||||
gdouble fps;
|
||||
GValue fps = { 0 };
|
||||
|
||||
if ((fps = gst_v4lmjpegsrc_get_fps (v4lmjpegsrc)) == 0)
|
||||
g_value_init (&fps, GST_VALUE_FRACTION);
|
||||
if (!gst_v4lmjpegsrc_get_fps (v4lmjpegsrc, &fps))
|
||||
return FALSE;
|
||||
|
||||
switch (type) {
|
||||
case GST_QUERY_POSITION:
|
||||
switch (*format) {
|
||||
case GST_FORMAT_TIME:
|
||||
*value = v4lmjpegsrc->handled * GST_SECOND / fps;
|
||||
*value = v4lmjpegsrc->handled * gst_util_clock_time_scale (GST_SECOND,
|
||||
gst_value_get_fraction_denominator (&fps),
|
||||
gst_value_get_fraction_numerator (&fps));
|
||||
break;
|
||||
case GST_FORMAT_DEFAULT:
|
||||
*value = v4lmjpegsrc->handled;
|
||||
|
@ -369,6 +380,7 @@ gst_v4lmjpegsrc_src_query (GstPad * pad,
|
|||
break;
|
||||
}
|
||||
|
||||
g_value_unset (&fps);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -497,15 +509,30 @@ gst_v4lmjpegsrc_get (GstPad * pad)
|
|||
GstV4lMjpegSrc *v4lmjpegsrc;
|
||||
GstBuffer *buf;
|
||||
gint num;
|
||||
gdouble fps = 0;
|
||||
GValue fps = { 0 };
|
||||
GstClockTime duration;
|
||||
GstClockTime cur_frame_time;
|
||||
|
||||
g_return_val_if_fail (pad != NULL, NULL);
|
||||
|
||||
v4lmjpegsrc = GST_V4LMJPEGSRC (gst_pad_get_parent (pad));
|
||||
|
||||
if (v4lmjpegsrc->use_fixed_fps &&
|
||||
(fps = gst_v4lmjpegsrc_get_fps (v4lmjpegsrc)) == 0)
|
||||
return NULL;
|
||||
if (v4lmjpegsrc->use_fixed_fps) {
|
||||
g_value_init (&fps, GST_VALUE_FRACTION);
|
||||
duration = gst_util_clock_time_scale (GST_SECOND,
|
||||
gst_value_get_fraction_denominator (&fps),
|
||||
gst_value_get_fraction_numerator (&fps));
|
||||
cur_frame_time =
|
||||
gst_util_clock_time_scale (v4lmjpegsrc->handled * GST_SECOND,
|
||||
gst_value_get_fraction_denominator (&fps),
|
||||
gst_value_get_fraction_numerator (&fps));
|
||||
|
||||
|
||||
if (!gst_v4lmjpegsrc_get_fps (v4lmjpegsrc, &fps)) {
|
||||
g_value_unset (&fps);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (v4lmjpegsrc->need_writes > 0) {
|
||||
/* use last frame */
|
||||
|
@ -550,14 +577,12 @@ gst_v4lmjpegsrc_get (GstPad * pad)
|
|||
* timeframe. This means that if time - begin_time = X sec,
|
||||
* we want to have written X*fps frames. If we've written
|
||||
* more - drop, if we've written less - dup... */
|
||||
if (v4lmjpegsrc->handled * (GST_SECOND / fps) - time >
|
||||
1.5 * (GST_SECOND / fps)) {
|
||||
if (cur_frame_time - time > 1.5 * duration) {
|
||||
/* yo dude, we've got too many frames here! Drop! DROP! */
|
||||
v4lmjpegsrc->need_writes--; /* -= (v4lmjpegsrc->handled - (time / fps)); */
|
||||
g_signal_emit (G_OBJECT (v4lmjpegsrc),
|
||||
gst_v4lmjpegsrc_signals[SIGNAL_FRAME_DROP], 0);
|
||||
} else if (v4lmjpegsrc->handled * (GST_SECOND / fps) - time <
|
||||
-1.5 * (GST_SECOND / fps)) {
|
||||
} else if (cur_frame_time - time < -1.5 * duration) {
|
||||
/* this means we're lagging far behind */
|
||||
v4lmjpegsrc->need_writes++; /* += ((time / fps) - v4lmjpegsrc->handled); */
|
||||
g_signal_emit (G_OBJECT (v4lmjpegsrc),
|
||||
|
@ -590,7 +615,7 @@ gst_v4lmjpegsrc_get (GstPad * pad)
|
|||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_READONLY);
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE);
|
||||
if (v4lmjpegsrc->use_fixed_fps)
|
||||
GST_BUFFER_TIMESTAMP (buf) = v4lmjpegsrc->handled * GST_SECOND / fps;
|
||||
GST_BUFFER_TIMESTAMP (buf) = cur_frame_time;
|
||||
else /* calculate time based on our own clock */
|
||||
GST_BUFFER_TIMESTAMP (buf) =
|
||||
GST_TIMEVAL_TO_TIME (v4lmjpegsrc->bsync.timestamp) -
|
||||
|
@ -609,23 +634,27 @@ gst_v4lmjpegsrc_getcaps (GstPad * pad)
|
|||
{
|
||||
GstV4lMjpegSrc *v4lmjpegsrc = GST_V4LMJPEGSRC (gst_pad_get_parent (pad));
|
||||
struct video_capability *vcap = &GST_V4LELEMENT (v4lmjpegsrc)->vcap;
|
||||
gdouble fps;
|
||||
GstCaps *caps;
|
||||
GstStructure *str;
|
||||
gint i;
|
||||
GValue w = { 0 }, h = {
|
||||
0}, w1 = {
|
||||
0}, h1 = {
|
||||
0}, fps = {
|
||||
0};
|
||||
|
||||
if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lmjpegsrc))) {
|
||||
return gst_caps_copy (gst_pad_get_pad_template_caps (pad));
|
||||
}
|
||||
|
||||
fps = gst_v4lmjpegsrc_get_fps (v4lmjpegsrc);
|
||||
caps = gst_caps_new_simple ("image/jpeg",
|
||||
"framerate", G_TYPE_DOUBLE, fps, NULL);
|
||||
g_value_init (&fps, GST_TYPE_FRACTION);
|
||||
gst_return_val_if_fail (gst_v4lmjpegsrc_get_fps (v4lmjpegsrc, &fps), NULL);
|
||||
|
||||
caps = gst_caps_new_simple ("image/jpeg", NULL);
|
||||
str = gst_caps_get_structure (caps, 0);
|
||||
gst_structure_set_value (str, "framerate", &fps);
|
||||
g_value_unset (&fps);
|
||||
|
||||
g_value_init (&w, GST_TYPE_LIST);
|
||||
g_value_init (&h, GST_TYPE_LIST);
|
||||
g_value_init (&w1, G_TYPE_INT);
|
||||
|
|
|
@ -371,7 +371,7 @@ gst_v4lsrc_get_caps (GstBaseSrc * src)
|
|||
gint width = GST_V4LELEMENT (src)->vcap.minwidth;
|
||||
gint height = GST_V4LELEMENT (src)->vcap.minheight;
|
||||
gint i;
|
||||
gdouble fps;
|
||||
GValue fps = { 0 };
|
||||
GList *item;
|
||||
|
||||
if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) {
|
||||
|
@ -402,7 +402,9 @@ gst_v4lsrc_get_caps (GstBaseSrc * src)
|
|||
}
|
||||
}
|
||||
|
||||
fps = gst_v4lsrc_get_fps (v4lsrc);
|
||||
|
||||
if (!gst_v4lsrc_get_fps (v4lsrc, &fps))
|
||||
gst_value_set_fraction (&fps, 0, 1);
|
||||
|
||||
list = gst_caps_new_empty ();
|
||||
for (item = v4lsrc->colorspaces; item != NULL; item = item->next) {
|
||||
|
@ -416,8 +418,10 @@ gst_v4lsrc_get_caps (GstBaseSrc * src)
|
|||
}
|
||||
|
||||
GST_DEBUG_OBJECT (v4lsrc,
|
||||
"Device reports w: %d-%d, h: %d-%d, fps: %f for palette %d",
|
||||
vcap->minwidth, vcap->maxwidth, vcap->minheight, vcap->maxheight, fps,
|
||||
"Device reports w: %d-%d, h: %d-%d, fps: %d/%d for palette %d",
|
||||
vcap->minwidth, vcap->maxwidth, vcap->minheight, vcap->maxheight,
|
||||
gst_value_get_fraction_numerator (&fps),
|
||||
gst_value_get_fraction_denominator (&fps),
|
||||
GPOINTER_TO_INT (item->data));
|
||||
|
||||
if (vcap->minwidth < vcap->maxwidth) {
|
||||
|
@ -434,21 +438,22 @@ gst_v4lsrc_get_caps (GstBaseSrc * src)
|
|||
}
|
||||
|
||||
if (v4lsrc->autoprobe_fps) {
|
||||
if (v4lsrc->fps_list) {
|
||||
GstStructure *structure = gst_caps_get_structure (one, 0);
|
||||
GstStructure *structure = gst_caps_get_structure (one, 0);
|
||||
|
||||
if (v4lsrc->fps_list) {
|
||||
gst_structure_set_value (structure, "framerate", v4lsrc->fps_list);
|
||||
} else {
|
||||
gst_caps_set_simple (one, "framerate", G_TYPE_DOUBLE, fps, NULL);
|
||||
gst_structure_set_value (structure, "framerate", &fps);
|
||||
}
|
||||
} else {
|
||||
gst_caps_set_simple (one, "framerate", GST_TYPE_DOUBLE_RANGE,
|
||||
(gdouble) 1.0, (gdouble) 100.0, NULL);
|
||||
gst_caps_set_simple (one, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
1, 1, 100, 1, NULL);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (v4lsrc, "caps: %" GST_PTR_FORMAT, one);
|
||||
gst_caps_append (list, one);
|
||||
}
|
||||
g_value_unset (&fps);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@ -459,7 +464,8 @@ gst_v4lsrc_set_caps (GstBaseSrc * src, GstCaps * caps)
|
|||
GstV4lSrc *v4lsrc;
|
||||
guint32 fourcc;
|
||||
gint bpp, depth, w, h, palette = -1;
|
||||
gdouble fps;
|
||||
const GValue *new_fps;
|
||||
GValue cur_fps = { 0 };
|
||||
GstStructure *structure;
|
||||
struct video_window *vwin;
|
||||
|
||||
|
@ -488,12 +494,19 @@ gst_v4lsrc_set_caps (GstBaseSrc * src, GstCaps * caps)
|
|||
|
||||
gst_structure_get_int (structure, "width", &w);
|
||||
gst_structure_get_int (structure, "height", &h);
|
||||
gst_structure_get_double (structure, "framerate", &fps);
|
||||
GST_DEBUG_OBJECT (v4lsrc, "linking with %dx%d at %f fps", w, h, fps);
|
||||
new_fps = gst_structure_get_value (structure, "framerate");
|
||||
|
||||
GST_DEBUG_OBJECT (v4lsrc, "linking with %dx%d at %d/%d fps", w, h,
|
||||
gst_value_get_fraction_numerator (new_fps),
|
||||
gst_value_get_fraction_denominator (new_fps));
|
||||
|
||||
/* set framerate if it's not already correct */
|
||||
if (fps != gst_v4lsrc_get_fps (v4lsrc)) {
|
||||
int fps_index = fps / 15.0 * 16;
|
||||
if (!gst_v4lsrc_get_fps (v4lsrc, &cur_fps))
|
||||
return FALSE;
|
||||
|
||||
if (gst_value_compare (new_fps, &cur_fps) != GST_VALUE_EQUAL) {
|
||||
int fps_index = (gst_value_get_fraction_numerator (new_fps) * 16) /
|
||||
(gst_value_get_fraction_denominator (new_fps) * 15);
|
||||
|
||||
GST_DEBUG_OBJECT (v4lsrc, "Trying to set fps index %d", fps_index);
|
||||
/* set bits 16 to 21 to 0 */
|
||||
|
@ -501,9 +514,11 @@ gst_v4lsrc_set_caps (GstBaseSrc * src, GstCaps * caps)
|
|||
/* set bits 16 to 21 to the index */
|
||||
vwin->flags |= fps_index << 16;
|
||||
if (!gst_v4l_set_window_properties (GST_V4LELEMENT (v4lsrc))) {
|
||||
g_value_unset (&cur_fps);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
g_value_unset (&cur_fps);
|
||||
|
||||
switch (fourcc) {
|
||||
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
|
||||
|
|
|
@ -82,7 +82,6 @@ struct _GstV4lSrc
|
|||
gboolean quit;
|
||||
|
||||
gint offset;
|
||||
gfloat fps;
|
||||
|
||||
/* list of supported colorspaces (as integers) */
|
||||
GList *colorspaces;
|
||||
|
|
|
@ -205,7 +205,11 @@ gst_v4l_open (GstV4lElement * v4lelement)
|
|||
GstTunerNorm *norm = GST_TUNER_NORM (v4lnorm);
|
||||
|
||||
norm->label = g_strdup (norm_name[num]);
|
||||
norm->fps = (num == 1) ? (30000. / 1001) : 25.;
|
||||
if (num == 1)
|
||||
gst_value_set_fraction (&norm->framerate, 30000, 1001);
|
||||
else
|
||||
gst_value_set_fraction (&norm->framerate, 25, 1);
|
||||
|
||||
v4lnorm->index = num;
|
||||
v4lelement->norms = g_list_append (v4lelement->norms, (gpointer) norm);
|
||||
}
|
||||
|
|
|
@ -500,14 +500,15 @@ gst_v4lsrc_palette_name (int i)
|
|||
return v4l_palette_name[i];
|
||||
}
|
||||
|
||||
gfloat
|
||||
gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc)
|
||||
gboolean
|
||||
gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc, GValue * fps)
|
||||
{
|
||||
gint norm;
|
||||
gint fps_index;
|
||||
gfloat fps;
|
||||
struct video_window *vwin = &GST_V4LELEMENT (v4lsrc)->vwin;
|
||||
|
||||
g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (fps), FALSE);
|
||||
|
||||
/* check if we have vwin window properties giving a framerate,
|
||||
* as is done for webcams
|
||||
* See http://www.smcc.demon.nl/webcam/api.html
|
||||
|
@ -516,12 +517,12 @@ gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc)
|
|||
|
||||
/* webcams have a non-zero fps_index */
|
||||
if (fps_index != 0) {
|
||||
gfloat current_fps;
|
||||
|
||||
/* index of 16 corresponds to 15 fps */
|
||||
current_fps = fps_index * 15.0 / 16;
|
||||
GST_LOG_OBJECT (v4lsrc, "device reports fps of %.4f", current_fps);
|
||||
return current_fps;
|
||||
GST_DEBUG_OBJECT (v4lsrc, "device reports fps of %d/%d (%.4f)",
|
||||
fps_index * 15, 16, fps_index * 15.0 / 16);
|
||||
|
||||
gst_value_set_fraction (fps, fps_index * 15, 16);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* removed fps estimation code here */
|
||||
|
@ -529,17 +530,17 @@ gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc)
|
|||
/* if that failed ... */
|
||||
|
||||
if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc)))
|
||||
return 0.;
|
||||
return FALSE;
|
||||
|
||||
if (!gst_v4l_get_chan_norm (GST_V4LELEMENT (v4lsrc), NULL, &norm))
|
||||
return 0.;
|
||||
return FALSE;
|
||||
|
||||
if (norm == VIDEO_MODE_NTSC)
|
||||
fps = 30000 / 1001;
|
||||
gst_value_set_fraction (fps, 30000, 1001);
|
||||
else
|
||||
fps = 25.;
|
||||
gst_value_set_fraction (fps, 25, 1);
|
||||
|
||||
return fps;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* get a list of possible framerates
|
||||
|
@ -551,7 +552,6 @@ 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);
|
||||
|
||||
|
@ -569,7 +569,6 @@ gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc)
|
|||
GST_DEBUG_OBJECT (v4lsrc, "fps_index is %d, so webcam", fps_index);
|
||||
|
||||
{
|
||||
gfloat current_fps;
|
||||
int i;
|
||||
GValue *list = NULL;
|
||||
GValue value = { 0 };
|
||||
|
@ -580,8 +579,8 @@ gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc)
|
|||
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);
|
||||
GST_DEBUG_OBJECT (v4lsrc, "device reports fps of %d/%d (%.4f)",
|
||||
fps_index * 15, 16, fps_index * 15.0 / 16);
|
||||
for (i = 0; i < 63; ++i) {
|
||||
/* set bits 16 to 21 to 0 */
|
||||
vwin->flags &= (0x3F00 - 1);
|
||||
|
@ -589,9 +588,8 @@ gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc)
|
|||
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);
|
||||
g_value_init (&value, GST_TYPE_FRACTION);
|
||||
gst_value_set_fraction (&value, i * 15, 16);
|
||||
gst_value_list_append_value (list, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
@ -687,9 +685,13 @@ GstBuffer *
|
|||
gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
GValue fps = { 0 };
|
||||
|
||||
GST_DEBUG_OBJECT (v4lsrc, "creating buffer for frame %d", num);
|
||||
|
||||
g_value_init (&fps, GST_TYPE_FRACTION);
|
||||
g_return_val_if_fail (gst_v4lsrc_get_fps (v4lsrc, &fps), NULL);
|
||||
|
||||
buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_V4LSRC_BUFFER);
|
||||
|
||||
GST_V4LSRC_BUFFER (buf)->num = num;
|
||||
|
@ -701,15 +703,15 @@ gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
|
|||
GST_BUFFER_OFFSET (buf) = v4lsrc->offset++;
|
||||
GST_BUFFER_TIMESTAMP (buf) = gst_clock_get_time (GST_ELEMENT (v4lsrc)->clock);
|
||||
GST_BUFFER_TIMESTAMP (buf) -= GST_ELEMENT (v4lsrc)->base_time;
|
||||
/* fixme: this is a most ghetto timestamp/duration */
|
||||
/* FIXME: this is a most ghetto timestamp/duration */
|
||||
|
||||
if (!v4lsrc->fps)
|
||||
v4lsrc->fps = gst_v4lsrc_get_fps (v4lsrc);
|
||||
if (v4lsrc->fps)
|
||||
GST_BUFFER_DURATION (buf) = GST_SECOND / v4lsrc->fps;
|
||||
GST_BUFFER_DURATION (buf) = gst_util_clock_time_scale (GST_SECOND,
|
||||
gst_value_get_fraction_numerator (&fps),
|
||||
gst_value_get_fraction_denominator (&fps));
|
||||
|
||||
/* the negotiate() method already set caps on the source pad */
|
||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (v4lsrc)));
|
||||
|
||||
g_value_unset (&fps);
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ guint8 * gst_v4lsrc_get_buffer (GstV4lSrc *v4lsrc, gint num);
|
|||
gboolean gst_v4lsrc_requeue_frame (GstV4lSrc *v4lsrc, gint num);
|
||||
gboolean gst_v4lsrc_capture_stop (GstV4lSrc *v4lsrc);
|
||||
gboolean gst_v4lsrc_capture_deinit (GstV4lSrc *v4lsrc);
|
||||
gfloat gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc);
|
||||
gboolean gst_v4lsrc_get_fps (GstV4lSrc * v4lsrc, GValue *fps);
|
||||
GValue * gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc);
|
||||
GstBuffer *gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num);
|
||||
|
||||
|
|
Loading…
Reference in a new issue