Convert elements to use fractions for their framerate.

Original commit message from CVS:
* ext/libvisual/visual.c: (gst_visual_src_setcaps), (get_buffer),
(gst_visual_chain):
* ext/ogg/gstogmparse.c: (gst_ogm_parse_chain):
* ext/theora/theoradec.c: (theora_handle_type_packet):
* ext/theora/theoraenc.c: (theora_enc_sink_setcaps),
(theora_enc_chain):
* gst-libs/gst/riff/riff-media.c: (gst_riff_create_video_caps):
* gst-libs/gst/video/video.c: (gst_video_frame_rate):
* gst-libs/gst/video/video.h:
* gst/ffmpegcolorspace/avcodec.h:
* gst/ffmpegcolorspace/gstffmpegcodecmap.c:
(gst_ffmpeg_caps_to_pixfmt):
* gst/ffmpegcolorspace/gstffmpegcolorspace.c:
(gst_ffmpegcsp_set_caps):
* gst/videorate/gstvideorate.c: (gst_videorate_transformcaps),
(gst_videorate_setcaps), (gst_videorate_blank_data),
(gst_videorate_chain):
* gst/videotestsrc/gstvideotestsrc.c:
(gst_videotestsrc_src_fixate), (gst_videotestsrc_getcaps),
(gst_videotestsrc_parse_caps), (gst_videotestsrc_setcaps),
(gst_videotestsrc_event), (gst_videotestsrc_create):
* gst/videotestsrc/gstvideotestsrc.h:
* sys/ximage/ximagesink.c: (gst_ximagesink_xcontext_get),
(gst_ximagesink_setcaps), (gst_ximagesink_change_state),
(gst_ximagesink_get_times), (gst_ximagesink_init):
* sys/ximage/ximagesink.h:
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_get_xv_support),
(gst_xvimagesink_setcaps), (gst_xvimagesink_change_state),
(gst_xvimagesink_get_times), (gst_xvimagesink_init):
* sys/xvimage/xvimagesink.h:
Convert elements to use fractions for their framerate.
V4L elements to come later tonight.
This commit is contained in:
Jan Schmidt 2005-11-22 16:08:37 +00:00
parent 08cd3b973f
commit 0e82871285
18 changed files with 230 additions and 107 deletions

View file

@ -1,3 +1,38 @@
2005-11-22 Jan Schmidt <thaytan@mad.scientist.com>
* ext/libvisual/visual.c: (gst_visual_src_setcaps), (get_buffer),
(gst_visual_chain):
* ext/ogg/gstogmparse.c: (gst_ogm_parse_chain):
* ext/theora/theoradec.c: (theora_handle_type_packet):
* ext/theora/theoraenc.c: (theora_enc_sink_setcaps),
(theora_enc_chain):
* gst-libs/gst/riff/riff-media.c: (gst_riff_create_video_caps):
* gst-libs/gst/video/video.c: (gst_video_frame_rate):
* gst-libs/gst/video/video.h:
* gst/ffmpegcolorspace/avcodec.h:
* gst/ffmpegcolorspace/gstffmpegcodecmap.c:
(gst_ffmpeg_caps_to_pixfmt):
* gst/ffmpegcolorspace/gstffmpegcolorspace.c:
(gst_ffmpegcsp_set_caps):
* gst/videorate/gstvideorate.c: (gst_videorate_transformcaps),
(gst_videorate_setcaps), (gst_videorate_blank_data),
(gst_videorate_chain):
* gst/videotestsrc/gstvideotestsrc.c:
(gst_videotestsrc_src_fixate), (gst_videotestsrc_getcaps),
(gst_videotestsrc_parse_caps), (gst_videotestsrc_setcaps),
(gst_videotestsrc_event), (gst_videotestsrc_create):
* gst/videotestsrc/gstvideotestsrc.h:
* sys/ximage/ximagesink.c: (gst_ximagesink_xcontext_get),
(gst_ximagesink_setcaps), (gst_ximagesink_change_state),
(gst_ximagesink_get_times), (gst_ximagesink_init):
* sys/ximage/ximagesink.h:
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_get_xv_support),
(gst_xvimagesink_setcaps), (gst_xvimagesink_change_state),
(gst_xvimagesink_get_times), (gst_xvimagesink_init):
* sys/xvimage/xvimagesink.h:
Convert elements to use fractions for their framerate.
V4L elements to come later tonight.
2005-11-22 Thomas Vander Stichele <thomas at apestaart dot org>
* gst-libs/gst/audio/audio.c:

View file

@ -56,7 +56,10 @@ struct _GstVisual
/* audio/video state */
gint rate; /* Input samplerate */
gdouble fps;
/* framerate numerator & denominator */
gint fps_n;
gint fps_d;
gint width;
gint height;
@ -268,6 +271,7 @@ gst_visual_src_setcaps (GstPad * pad, GstCaps * caps)
GstVisual *visual = GST_VISUAL (gst_pad_get_parent (pad));
GstStructure *structure;
gint depth;
const GValue *fps;
structure = gst_caps_get_structure (caps, 0);
@ -275,10 +279,14 @@ gst_visual_src_setcaps (GstPad * pad, GstCaps * caps)
return FALSE;
if (!gst_structure_get_int (structure, "height", &visual->height))
return FALSE;
if (!gst_structure_get_double (structure, "framerate", &visual->fps))
return FALSE;
if (!gst_structure_get_int (structure, "bpp", &depth))
return FALSE;
fps = gst_structure_get_value (structure, "framerate");
if (fps == NULL || !GST_VALUE_HOLDS_FRACTION (fps))
return FALSE;
visual->fps_n = gst_value_get_fraction_numerator (fps);
visual->fps_d = gst_value_get_fraction_denominator (fps);
visual_video_set_depth (visual->video,
visual_video_depth_enum_from_value (depth));
@ -310,6 +318,7 @@ get_buffer (GstVisual * visual, GstBuffer ** outbuf)
gint width, height, bpp;
GstStructure *s;
GstCaps *caps;
GValue target_fps = { 0 };
/* No output caps current set up. Try and pick some */
caps = gst_pad_get_allowed_caps (visual->srcpad);
@ -328,7 +337,9 @@ get_buffer (GstVisual * visual, GstBuffer ** outbuf)
gst_structure_fixate_field_nearest_int (s, "width", 320);
gst_structure_fixate_field_nearest_int (s, "height", 240);
gst_structure_fixate_field_nearest_double (s, "framerate", 30.0);
g_value_init (&target_fps, GST_TYPE_FRACTION);
gst_value_set_fraction (&target_fps, 25, 1);
gst_structure_fixate_field_nearest_fraction (s, "framerate", &target_fps);
gst_pad_fixate_caps (visual->srcpad, caps);
} else
@ -380,11 +391,12 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
}
}
/* Match timestamps from the incoming audio */
if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE)
visual->next_ts = GST_BUFFER_TIMESTAMP (buffer);
/* spf = samples per frame */
spf = visual->rate / visual->fps;
spf = ((guint64) (visual->rate) * visual->fps_n) / visual->fps_d;
gst_adapter_push (visual->adapter, buffer);
while (gst_adapter_available (visual->adapter) > MAX (512, spf) * 4 &&
@ -410,9 +422,8 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
visual_audio_analyze (&visual->audio);
visual_actor_run (visual->actor, &visual->audio);
/* FIXME: Match timestamps from the incoming audio */
GST_BUFFER_TIMESTAMP (outbuf) = visual->next_ts;
GST_BUFFER_DURATION (outbuf) = GST_SECOND / visual->fps;
GST_BUFFER_DURATION (outbuf) = GST_SECOND * visual->fps_n / visual->fps_d;
visual->next_ts += GST_BUFFER_DURATION (outbuf);
ret = gst_pad_push (visual->srcpad, outbuf);
outbuf = NULL;
@ -420,7 +431,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 = visual->rate / visual->fps;
spf = ((guint64) (visual->rate) * visual->fps_n) / visual->fps_d;
GST_DEBUG_OBJECT (visual, "finished frame, flushing %u samples from input",
spf);
gst_adapter_flush (visual->adapter,

View file

@ -608,7 +608,8 @@ gst_ogm_parse_chain (GstPad * pad, GstBuffer * buffer)
gst_caps_set_simple (caps,
"width", G_TYPE_INT, ogm->hdr.s.video.width,
"height", G_TYPE_INT, ogm->hdr.s.video.height,
"framerate", G_TYPE_DOUBLE, 10000000. / ogm->hdr.time_unit, NULL);
"framerate", GST_TYPE_FRACTION, 10000000, ogm->hdr.time_unit,
NULL);
break;
}
case 't':

View file

@ -99,7 +99,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-yuv, "
"format = (fourcc) I420, "
"framerate = (double) [0, MAX], "
"framerate = (fraction) [0/1, MAX], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
);
@ -747,8 +747,8 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
caps = gst_caps_new_simple ("video/x-raw-yuv",
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
"framerate", G_TYPE_DOUBLE,
((gdouble) dec->info.fps_numerator) / dec->info.fps_denominator,
"framerate", GST_TYPE_FRACTION,
dec->info.fps_numerator, dec->info.fps_denominator,
"pixel-aspect-ratio", GST_TYPE_FRACTION, par_num, par_den,
"width", G_TYPE_INT, dec->width, "height", G_TYPE_INT, dec->height, NULL);
gst_pad_set_caps (dec->srcpad, caps);

View file

@ -113,7 +113,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-yuv, "
"format = (fourcc) I420, "
"framerate = (double) [0, MAX], "
"framerate = (fraction) [0/1, MAX], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
);
@ -244,12 +244,11 @@ theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
GstStructure *structure = gst_caps_get_structure (caps, 0);
GstTheoraEnc *enc = GST_THEORA_ENC (gst_pad_get_parent (pad));
const GValue *par;
GValue fps = { 0 };
GValue framerate = { 0 };
const GValue *framerate;
gst_structure_get_int (structure, "width", &enc->width);
gst_structure_get_int (structure, "height", &enc->height);
gst_structure_get_double (structure, "framerate", &enc->fps);
framerate = gst_structure_get_value (structure, "framerate");
par = gst_structure_get_value (structure, "pixel-aspect-ratio");
theora_info_init (&enc->info);
@ -272,14 +271,8 @@ theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
enc->info.offset_x = enc->offset_x;
enc->info.offset_y = enc->offset_y;
/* convert double to fraction for the framerate */
g_value_init (&fps, G_TYPE_DOUBLE);
g_value_init (&framerate, GST_TYPE_FRACTION);
g_value_set_double (&fps, enc->fps);
g_value_transform (&fps, &framerate);
enc->info.fps_numerator = gst_value_get_fraction_numerator (&framerate);
enc->info.fps_denominator = gst_value_get_fraction_denominator (&framerate);
enc->info.fps_numerator = gst_value_get_fraction_numerator (framerate);
enc->info.fps_denominator = gst_value_get_fraction_denominator (framerate);
if (par) {
enc->info.aspect_numerator = gst_value_get_fraction_numerator (par);
@ -471,6 +464,9 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
/* create the remaining theora headers */
theora_comment_init (&enc->comment);
/* Currently leaks due to libtheora API brokenness, I don't think we can
* portably work around it. Leaks ~50 bytes per encoder instance, so not a
* huge problem. */
theora_encode_comment (&enc->comment, &op);
ret = theora_buffer_from_packet (enc, &op, 0, 0, &buf2);
if (ret != GST_FLOW_OK) {

View file

@ -363,12 +363,11 @@ gst_riff_create_video_caps (guint32 codec_fcc,
}
if (strh != NULL) {
gdouble fps = 1. * strh->rate / strh->scale;
gst_caps_set_simple (caps, "framerate", G_TYPE_DOUBLE, fps, NULL);
gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
strh->rate, strh->scale, NULL);
} else {
gst_caps_set_simple (caps,
"framerate", GST_TYPE_DOUBLE_RANGE, 0., G_MAXDOUBLE, NULL);
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
}
if (strf != NULL) {

View file

@ -25,11 +25,12 @@
#include "video.h"
/* This is simply a convenience function, nothing more or less */
gdouble
const GValue *
gst_video_frame_rate (GstPad * pad)
{
gdouble fps = 0.;
const GValue *fps;
gchar *fps_string;
const GstCaps *caps = NULL;
GstStructure *structure;
@ -38,18 +39,27 @@ gst_video_frame_rate (GstPad * pad)
if (caps == NULL) {
g_warning ("gstvideo: failed to get caps of pad %s:%s",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
return 0.;
return NULL;
}
structure = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_double (structure, "framerate", &fps)) {
if ((fps = gst_structure_get_value (structure, "framerate")) == NULL) {
g_warning ("gstvideo: failed to get framerate property of pad %s:%s",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
return 0.;
return NULL;
}
if (!GST_VALUE_HOLDS_FRACTION (fps)) {
g_warning
("gstvideo: framerate property of pad %s:%s is not of type Fraction",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
return NULL;
}
GST_DEBUG ("Framerate request on pad %s:%s: %f",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad), fps);
fps_string = gst_value_serialize (fps);
GST_DEBUG ("Framerate request on pad %s:%s: %s",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad),
fps_string);
g_free (fps_string);
return fps;
}

View file

@ -60,7 +60,7 @@ G_BEGIN_DECLS
#define GST_VIDEO_BLUE_MASK_15_INT 0x001f
#define GST_VIDEO_SIZE_RANGE "(int) [ 1, max ]"
#define GST_VIDEO_FPS_RANGE "(double) [ 0.0, max ]"
#define GST_VIDEO_FPS_RANGE "(fraction) [ 0, max ]"
/* consider the next 2 protected */
#define __GST_VIDEO_CAPS_MAKE_32A(R, G, B, A) \
@ -184,7 +184,7 @@ G_BEGIN_DECLS
"framerate = " GST_VIDEO_FPS_RANGE
/* functions */
gdouble gst_video_frame_rate (GstPad *pad);
const GValue *gst_video_frame_rate (GstPad *pad);
gboolean gst_video_get_size (GstPad *pad,
gint *width,
gint *height);

View file

@ -88,8 +88,6 @@ enum SampleFormat {
SAMPLE_FMT_S16 = 0, ///< signed 16 bits
};
#define DEFAULT_FRAME_RATE_BASE 1001000
/* thomas: extracted from imgconvert.c since it's also used in
* gstffmpegcodecmap.c */

View file

@ -83,14 +83,14 @@ gst_ffmpeg_set_palette (GstCaps * caps, AVCodecContext * context)
gst_caps_new_simple (mimetype, \
"width", G_TYPE_INT, context->width, \
"height", G_TYPE_INT, context->height, \
"framerate", G_TYPE_DOUBLE, 1. * context->frame_rate / \
context->frame_rate_base, \
"framerate", GST_TYPE_FRACTION, \
(gint) context->frame_rate, (gint) context->frame_rate_base, \
__VA_ARGS__, NULL) \
: \
gst_caps_new_simple (mimetype, \
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT, \
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT, \
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, \
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,\
__VA_ARGS__, NULL)
/* same for audio - now with channels/sample rate
@ -447,19 +447,22 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
AVCodecContext * context, gboolean raw)
{
GstStructure *structure;
gdouble fps;
const GValue *fps;
gboolean ret;
g_return_if_fail (gst_caps_get_size (caps) == 1);
structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &context->width);
gst_structure_get_int (structure, "height", &context->height);
ret = gst_structure_get_int (structure, "width", &context->width);
ret &= gst_structure_get_int (structure, "height", &context->height);
g_return_if_fail (ret == TRUE);
fps = gst_structure_get_value (structure, "framerate");
g_return_if_fail (GST_VALUE_HOLDS_FRACTION (fps));
/* framerate does not really matter */
if (gst_structure_get_double (structure, "framerate", &fps)) {
context->frame_rate = fps * DEFAULT_FRAME_RATE_BASE;
context->frame_rate_base = DEFAULT_FRAME_RATE_BASE;
}
context->frame_rate = gst_value_get_fraction_numerator (fps);
context->frame_rate_base = gst_value_get_fraction_denominator (fps);
if (!raw)
return;

View file

@ -163,7 +163,8 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
GstStructure *structure;
gint in_height, in_width;
gint out_height, out_width;
gdouble in_framerate, out_framerate;
const GValue *in_framerate = NULL;
const GValue *out_framerate = NULL;
const GValue *in_par = NULL;
const GValue *out_par = NULL;
AVCodecContext *ctx;
@ -177,10 +178,14 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
/* we have to have width and height */
res = gst_structure_get_int (structure, "width", &in_width);
res &= gst_structure_get_int (structure, "height", &in_height);
res &= gst_structure_get_double (structure, "framerate", &in_framerate);
if (!res)
goto no_width_height;
/* and framerate */
in_framerate = gst_structure_get_value (structure, "framerate");
if (in_framerate == NULL || !GST_VALUE_HOLDS_FRACTION (in_framerate))
goto no_framerate;
/* this is optional */
in_par = gst_structure_get_value (structure, "pixel-aspect-ratio");
@ -189,16 +194,20 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
/* we have to have width and height */
res = gst_structure_get_int (structure, "width", &out_width);
res &= gst_structure_get_int (structure, "height", &out_height);
res &= gst_structure_get_double (structure, "framerate", &out_framerate);
if (!res)
goto no_width_height;
/* and framerate */
out_framerate = gst_structure_get_value (structure, "framerate");
if (out_framerate == NULL || !GST_VALUE_HOLDS_FRACTION (out_framerate))
goto no_framerate;
/* this is optional */
out_par = gst_structure_get_value (structure, "pixel-aspect-ratio");
/* these must match */
if (in_width != out_width || in_height != out_height ||
in_framerate != out_framerate)
gst_value_compare (in_framerate, out_framerate) != GST_VALUE_EQUAL)
goto format_mismatch;
/* if present, these must match too */
@ -244,6 +253,13 @@ no_width_height:
space->to_pixfmt = PIX_FMT_NB;
return FALSE;
}
no_framerate:
{
GST_DEBUG ("did not specify framerate");
space->from_pixfmt = PIX_FMT_NB;
space->to_pixfmt = PIX_FMT_NB;
return FALSE;
}
format_mismatch:
{
GST_DEBUG ("input and output formats do not match");

View file

@ -47,7 +47,8 @@ struct _GstVideorate
GstPad *sinkpad, *srcpad;
/* video state */
gdouble from_fps, to_fps;
gint from_rate_numerator, from_rate_denominator;
gint to_rate_numerator, to_rate_denominator;
guint64 next_ts; /* Timestamp of next buffer to output */
guint64 first_ts; /* Timestamp of first buffer */
GstBuffer *prevbuf;
@ -220,7 +221,7 @@ gst_videorate_transformcaps (GstPad * in_pad, GstCaps * in_caps,
structure = gst_caps_get_structure (intersect, i);
gst_structure_set (structure,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
}
*out_caps = intersect;
@ -261,20 +262,27 @@ gst_videorate_setcaps (GstPad * pad, GstCaps * caps)
GstVideorate *videorate;
GstStructure *structure;
gboolean ret = TRUE;
double fps;
GstPad *otherpad, *opeer;
const GValue *rate;
gint rate_numerator, rate_denominator;
videorate = GST_VIDEORATE (GST_PAD_PARENT (pad));
structure = gst_caps_get_structure (caps, 0);
if (!(ret = gst_structure_get_double (structure, "framerate", &fps)))
rate = gst_structure_get_value (structure, "framerate");
if (!rate)
goto done;
rate_numerator = gst_value_get_fraction_numerator (rate);
rate_denominator = gst_value_get_fraction_denominator (rate);
if (pad == videorate->srcpad) {
videorate->to_fps = fps;
videorate->to_rate_numerator = rate_numerator;
videorate->to_rate_denominator = rate_denominator;
otherpad = videorate->sinkpad;
} else {
videorate->from_fps = fps;
videorate->from_rate_numerator = rate_numerator;
videorate->from_rate_denominator = rate_denominator;
otherpad = videorate->srcpad;
}
/* now try to find something for the peer */
@ -315,14 +323,20 @@ gst_videorate_setcaps (GstPad * pad, GstCaps * caps)
structure = gst_caps_get_structure (caps, 0);
/* and fixate */
gst_structure_fixate_field_nearest_int (structure, "framerate", fps);
gst_structure_fixate_field_nearest_fraction (structure, "framerate",
rate);
gst_structure_get_double (structure, "framerate", &fps);
rate = gst_structure_get_value (structure, "framerate");
rate_numerator = gst_value_get_fraction_numerator (rate);
rate_denominator = gst_value_get_fraction_denominator (rate);
if (otherpad == videorate->srcpad) {
videorate->to_fps = fps;
videorate->to_rate_numerator = rate_numerator;
videorate->to_rate_denominator = rate_denominator;
} else {
videorate->from_fps = fps;
videorate->from_rate_numerator = rate_numerator;
videorate->from_rate_denominator = rate_denominator;
}
gst_pad_set_caps (otherpad, caps);
ret = TRUE;
@ -341,8 +355,10 @@ gst_videorate_blank_data (GstVideorate * videorate)
gst_buffer_unref (videorate->prevbuf);
videorate->prevbuf = NULL;
videorate->from_fps = 0;
videorate->to_fps = 0;
videorate->from_rate_numerator = 0;
videorate->from_rate_denominator = 0;
videorate->to_rate_numerator = 0;
videorate->to_rate_denominator = 0;
videorate->in = 0;
videorate->out = 0;
videorate->drop = 0;
@ -435,10 +451,9 @@ gst_videorate_chain (GstPad * pad, GstBuffer * buffer)
videorate = GST_VIDEORATE (GST_PAD_PARENT (pad));
if (videorate->from_fps == 0)
return GST_FLOW_NOT_NEGOTIATED;
if (videorate->to_fps == 0)
if (videorate->from_rate_numerator == 0 ||
videorate->from_rate_denominator == 0 ||
videorate->to_rate_denominator == 0 || videorate->to_rate_numerator == 0)
return GST_FLOW_NOT_NEGOTIATED;
/* pull in 2 buffers */
@ -494,7 +509,8 @@ gst_videorate_chain (GstPad * pad, GstBuffer * buffer)
videorate->out++;
videorate->next_ts =
videorate->first_ts +
(videorate->out / videorate->to_fps * GST_SECOND);
(videorate->out * GST_SECOND *
videorate->to_rate_denominator / videorate->to_rate_numerator);
GST_BUFFER_DURATION (outbuf) =
videorate->next_ts - GST_BUFFER_TIMESTAMP (outbuf);
/* adapt for looping */

View file

@ -173,12 +173,16 @@ static void
gst_videotestsrc_src_fixate (GstPad * pad, GstCaps * caps)
{
GstStructure *structure;
GValue value = { 0 };
g_value_init (&value, GST_TYPE_FRACTION);
gst_value_set_fraction (&value, 30, 1);
structure = gst_caps_get_structure (caps, 0);
gst_structure_fixate_field_nearest_int (structure, "width", 320);
gst_structure_fixate_field_nearest_int (structure, "height", 240);
gst_structure_fixate_field_nearest_double (structure, "framerate", 30.0);
gst_structure_fixate_field_nearest_fraction (structure, "framerate", &value);
}
static void
@ -263,7 +267,7 @@ gst_videotestsrc_getcaps (GstBaseSrc * unused)
gst_structure_set (structure,
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
gst_caps_append_structure (caps, structure);
}
@ -275,11 +279,12 @@ gst_videotestsrc_getcaps (GstBaseSrc * unused)
static gboolean
gst_videotestsrc_parse_caps (const GstCaps * caps,
gint * width, gint * height, gdouble * rate,
gint * width, gint * height, gint * rate_numerator, gint * rate_denominator,
struct fourcc_list_struct **fourcc)
{
const GstStructure *structure;
GstPadLinkReturn ret;
const GValue *framerate;
GST_DEBUG ("parsing caps");
@ -296,7 +301,14 @@ gst_videotestsrc_parse_caps (const GstCaps * caps,
ret = gst_structure_get_int (structure, "width", width);
ret &= gst_structure_get_int (structure, "height", height);
ret &= gst_structure_get_double (structure, "framerate", rate);
framerate = gst_structure_get_value (structure, "framerate");
if (framerate) {
*rate_numerator = gst_value_get_fraction_numerator (framerate);
*rate_denominator = gst_value_get_fraction_denominator (framerate);
} else
ret = FALSE;
return ret;
}
@ -305,24 +317,26 @@ static gboolean
gst_videotestsrc_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
{
gboolean res;
gint width, height;
gdouble rate;
gint width, height, rate_denominator, rate_numerator;
struct fourcc_list_struct *fourcc;
GstVideoTestSrc *videotestsrc;
videotestsrc = GST_VIDEOTESTSRC (bsrc);
res = gst_videotestsrc_parse_caps (caps, &width, &height, &rate, &fourcc);
res = gst_videotestsrc_parse_caps (caps, &width, &height,
&rate_numerator, &rate_denominator, &fourcc);
if (res) {
/* looks ok here */
videotestsrc->fourcc = fourcc;
videotestsrc->width = width;
videotestsrc->height = height;
videotestsrc->rate = rate;
videotestsrc->rate_numerator = rate_numerator;
videotestsrc->rate_denominator = rate_denominator;
videotestsrc->bpp = videotestsrc->fourcc->bitspp;
GST_DEBUG_OBJECT (videotestsrc, "size %dx%d, %f fps", videotestsrc->width,
videotestsrc->height, videotestsrc->rate);
GST_DEBUG_OBJECT (videotestsrc, "size %dx%d, %d/%d fps",
videotestsrc->width, videotestsrc->height,
videotestsrc->rate_numerator, videotestsrc->rate_denominator);
}
return res;
}
@ -350,10 +364,12 @@ gst_videotestsrc_event (GstBaseSrc * bsrc, GstEvent * event)
switch (format) {
case GST_FORMAT_TIME:
new_n_frames = cur * (double) videotestsrc->rate / GST_SECOND;
new_n_frames = cur * videotestsrc->rate_numerator /
(videotestsrc->rate_denominator * GST_SECOND);
videotestsrc->segment_start_frame = new_n_frames;
videotestsrc->segment_end_frame =
stop * (double) videotestsrc->rate / GST_SECOND;
stop * videotestsrc->rate_numerator /
(videotestsrc->rate_denominator * GST_SECOND);
videotestsrc->segment = flags & GST_SEEK_FLAG_SEGMENT;
break;
case GST_FORMAT_DEFAULT:
@ -442,10 +458,16 @@ gst_videotestsrc_create (GstPushSrc * psrc, GstBuffer ** buffer)
src->width, src->height);
GST_BUFFER_TIMESTAMP (outbuf) = src->timestamp_offset + src->running_time;
GST_BUFFER_DURATION (outbuf) = GST_SECOND / (double) src->rate;
if (src->rate_numerator != 0) {
GST_BUFFER_DURATION (outbuf) = GST_SECOND * src->rate_denominator /
src->rate_numerator;
}
src->n_frames++;
src->running_time += GST_BUFFER_DURATION (outbuf);
if (src->rate_numerator != 0) {
src->running_time = src->n_frames * GST_SECOND * src->rate_denominator /
src->rate_numerator;
}
*buffer = outbuf;

View file

@ -58,7 +58,8 @@ struct _GstVideoTestSrc {
gint height;
struct fourcc_list_struct *fourcc;
gint bpp;
gdouble rate;
gint rate_numerator;
gint rate_denominator;
/* private */
gint64 timestamp_offset; /* base offset */

View file

@ -64,7 +64,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-rgb, "
"framerate = (double) [ 0.0, MAX ], "
"framerate = (fraction) [ 0, MAX ], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
);
@ -968,7 +968,7 @@ gst_ximagesink_xcontext_get (GstXImageSink * ximagesink)
"blue_mask", G_TYPE_INT, xcontext->visual->blue_mask,
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
if (ximagesink->par) {
int nom, den;
@ -1076,7 +1076,7 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
GstCaps *intersection;
const GValue *par;
gint new_width, new_height;
gdouble fps;
const GValue *fps;
ximagesink = GST_XIMAGESINK (bsink);
@ -1101,7 +1101,8 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
ret &= gst_structure_get_int (structure, "width", &new_width);
ret &= gst_structure_get_int (structure, "height", &new_height);
ret &= gst_structure_get_double (structure, "framerate", &fps);
fps = gst_structure_get_value (structure, "framerate");
ret &= (fps != NULL);
if (!ret)
return FALSE;
@ -1122,7 +1123,8 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
GST_VIDEO_SINK_WIDTH (ximagesink) = new_width;
GST_VIDEO_SINK_HEIGHT (ximagesink) = new_height;
ximagesink->framerate = fps;
ximagesink->fps_n = gst_value_get_fraction_numerator (fps);
ximagesink->fps_d = gst_value_get_fraction_denominator (fps);
/* Notify application to set xwindow id now */
if (!ximagesink->xwindow) {
@ -1199,7 +1201,8 @@ gst_ximagesink_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_PAUSED_TO_READY:
if (ximagesink->xwindow)
gst_ximagesink_xwindow_clear (ximagesink, ximagesink->xwindow);
ximagesink->framerate = 0;
ximagesink->fps_n = 0;
ximagesink->fps_d = 1;
GST_VIDEO_SINK_WIDTH (ximagesink) = 0;
GST_VIDEO_SINK_HEIGHT (ximagesink) = 0;
break;
@ -1247,8 +1250,8 @@ gst_ximagesink_get_times (GstBaseSink * bsink, GstBuffer * buf,
if (GST_BUFFER_DURATION_IS_VALID (buf)) {
*end = *start + GST_BUFFER_DURATION (buf);
} else {
if (ximagesink->framerate > 0) {
*end = *start + GST_SECOND / ximagesink->framerate;
if (ximagesink->fps_n > 0) {
*end = *start + (GST_SECOND * ximagesink->fps_d) / ximagesink->fps_n;
}
}
}
@ -1736,7 +1739,8 @@ gst_ximagesink_init (GstXImageSink * ximagesink)
ximagesink->event_thread = NULL;
ximagesink->running = FALSE;
ximagesink->framerate = 0;
ximagesink->fps_n = 0;
ximagesink->fps_d = 1;
ximagesink->x_lock = g_mutex_new ();
ximagesink->flow_lock = g_mutex_new ();

View file

@ -125,7 +125,10 @@ struct _GstXImageSink {
GThread *event_thread;
gboolean running;
gdouble framerate;
/* Framerate numerator and denominator */
gint fps_n;
gint fps_d;
GMutex *x_lock;
GMutex *flow_lock;

View file

@ -70,11 +70,11 @@ static GstStaticPadTemplate gst_xvimagesink_sink_template_factory =
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-rgb, "
"framerate = (double) [ 0.0, MAX ], "
"framerate = (fraction) [ 0, MAX ], "
"width = (int) [ 1, MAX ], "
"height = (int) [ 1, MAX ]; "
"video/x-raw-yuv, "
"framerate = (double) [ 0.0, MAX ], "
"framerate = (fraction) [ 0, MAX ], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
);
@ -998,7 +998,7 @@ gst_xvimagesink_get_xv_support (GstXvImageSink * xvimagesink,
"red_mask", G_TYPE_INT, formats[i].blue_mask,
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
break;
}
case XvYUV:
@ -1006,7 +1006,7 @@ gst_xvimagesink_get_xv_support (GstXvImageSink * xvimagesink,
"format", GST_TYPE_FOURCC, formats[i].id,
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
break;
default:
g_assert_not_reached ();
@ -1415,6 +1415,7 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
gint display_par_n, display_par_d; /* display's PAR */
GValue display_ratio = { 0, }; /* display w/h ratio */
const GValue *caps_par;
const GValue *fps;
gint num, den;
xvimagesink = GST_XVIMAGESINK (bsink);
@ -1435,11 +1436,15 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
structure = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (structure, "width", &video_width);
ret &= gst_structure_get_int (structure, "height", &video_height);
ret &= gst_structure_get_double (structure, "framerate",
&xvimagesink->framerate);
fps = gst_structure_get_value (structure, "framerate");
ret &= (fps != NULL);
if (!ret)
return FALSE;
xvimagesink->fps_n = gst_value_get_fraction_numerator (fps);
xvimagesink->fps_d = gst_value_get_fraction_denominator (fps);
xvimagesink->video_width = video_width;
xvimagesink->video_height = video_height;
im_format = gst_xvimagesink_get_format_from_caps (xvimagesink, caps);
@ -1581,7 +1586,8 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
xvimagesink->framerate = 0;
xvimagesink->fps_n = 0;
xvimagesink->fps_d = 1;
GST_VIDEO_SINK_WIDTH (xvimagesink) = 0;
GST_VIDEO_SINK_HEIGHT (xvimagesink) = 0;
break;
@ -1625,8 +1631,8 @@ gst_xvimagesink_get_times (GstBaseSink * bsink, GstBuffer * buf,
if (GST_BUFFER_DURATION_IS_VALID (buf)) {
*end = *start + GST_BUFFER_DURATION (buf);
} else {
if (xvimagesink->framerate > 0) {
*end = *start + GST_SECOND / xvimagesink->framerate;
if (xvimagesink->fps_n > 0) {
*end = *start + (GST_SECOND * xvimagesink->fps_d) / xvimagesink->fps_n;
}
}
}
@ -2147,7 +2153,8 @@ gst_xvimagesink_init (GstXvImageSink * xvimagesink)
xvimagesink->contrast = xvimagesink->brightness = 0;
xvimagesink->cb_changed = FALSE;
xvimagesink->framerate = 0;
xvimagesink->fps_n = 0;
xvimagesink->fps_d = 0;
xvimagesink->video_width = 0;
xvimagesink->video_height = 0;

View file

@ -136,7 +136,8 @@ struct _GstXvImageSink {
GstXvImageBuffer *xvimage;
GstXvImageBuffer *cur_image;
gdouble framerate;
gint fps_n;
gint fps_d;
gint brightness;
gint contrast;