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:
Jan Schmidt 2005-11-22 23:39:12 +00:00
parent f5ddd5037a
commit 674ee67e8b
10 changed files with 142 additions and 92 deletions

View file

@ -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,

View file

@ -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;
/**

View file

@ -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)) {

View file

@ -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);

View file

@ -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);

View file

@ -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'):

View file

@ -82,7 +82,6 @@ struct _GstV4lSrc
gboolean quit;
gint offset;
gfloat fps;
/* list of supported colorspaces (as integers) */
GList *colorspaces;

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);