intervideosrc: Negotiate framerate with downstream

Prefer the closest framerate to the input framerate though.
This commit is contained in:
Sebastian Dröge 2014-11-03 16:54:58 +01:00
parent 85f66e3531
commit dda95aeb50

View file

@ -189,6 +189,9 @@ gst_inter_video_src_get_caps (GstBaseSrc * src, GstCaps * filter)
g_mutex_lock (&intervideosrc->surface->mutex); g_mutex_lock (&intervideosrc->surface->mutex);
if (intervideosrc->surface->video_info.finfo) { if (intervideosrc->surface->video_info.finfo) {
caps = gst_video_info_to_caps (&intervideosrc->surface->video_info); caps = gst_video_info_to_caps (&intervideosrc->surface->video_info);
gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION_RANGE, 1,
G_MAXINT, G_MAXINT, 1, NULL);
if (filter) { if (filter) {
GstCaps *tmp; GstCaps *tmp;
@ -313,9 +316,18 @@ gst_inter_video_src_create (GstBaseSrc * src, guint64 offset, guint size,
g_mutex_lock (&intervideosrc->surface->mutex); g_mutex_lock (&intervideosrc->surface->mutex);
if (intervideosrc->surface->video_info.finfo) { if (intervideosrc->surface->video_info.finfo) {
if (!gst_video_info_is_equal (&intervideosrc->surface->video_info, GstVideoInfo tmp_info = intervideosrc->surface->video_info;
&intervideosrc->info)) {
caps = gst_video_info_to_caps (&intervideosrc->surface->video_info); /* We negotiate the framerate ourselves */
tmp_info.fps_n = intervideosrc->info.fps_n;
tmp_info.fps_d = intervideosrc->info.fps_d;
if (intervideosrc->info.flags & GST_VIDEO_FLAG_VARIABLE_FPS)
tmp_info.flags |= GST_VIDEO_FLAG_VARIABLE_FPS;
else
tmp_info.flags &= ~GST_VIDEO_FLAG_VARIABLE_FPS;
if (!gst_video_info_is_equal (&tmp_info, &intervideosrc->info)) {
caps = gst_video_info_to_caps (&tmp_info);
intervideosrc->timestamp_offset += intervideosrc->timestamp_offset +=
gst_util_uint64_scale (GST_SECOND * intervideosrc->n_frames, gst_util_uint64_scale (GST_SECOND * intervideosrc->n_frames,
GST_VIDEO_INFO_FPS_D (&intervideosrc->info), GST_VIDEO_INFO_FPS_D (&intervideosrc->info),
@ -334,14 +346,64 @@ gst_inter_video_src_create (GstBaseSrc * src, guint64 offset, guint size,
g_mutex_unlock (&intervideosrc->surface->mutex); g_mutex_unlock (&intervideosrc->surface->mutex);
if (caps) { if (caps) {
gboolean ret = gst_base_src_set_caps (src, caps); gboolean ret;
gst_caps_unref (caps); GstStructure *s;
if (!ret) { GstCaps *downstream_caps;
GST_ERROR_OBJECT (src, "Failed to set caps %" GST_PTR_FORMAT, caps); GstCaps *tmp, *negotiated_caps;
gint fps_n = 0, fps_d = 1;
/* Negotiate a framerate with downstream */
downstream_caps = gst_pad_get_allowed_caps (GST_BASE_SRC_PAD (src));
/* Remove all framerates */
tmp = gst_caps_copy (caps);
s = gst_caps_get_structure (tmp, 0);
gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d);
if (fps_n == 0)
gst_structure_get_fraction (s, "max-framerate", &fps_n, &fps_d);
gst_structure_remove_field (s, "framerate");
gst_structure_remove_field (s, "max-framerate");
negotiated_caps =
gst_caps_intersect_full (downstream_caps, tmp,
GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (tmp);
gst_caps_unref (downstream_caps);
if (gst_caps_is_empty (negotiated_caps)) {
GST_ERROR_OBJECT (src, "Failed to negotiate caps %" GST_PTR_FORMAT, caps);
if (buffer) if (buffer)
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
gst_caps_unref (caps);
return GST_FLOW_NOT_NEGOTIATED; return GST_FLOW_NOT_NEGOTIATED;
} }
gst_caps_unref (caps);
caps = NULL;
/* Prefer what the source produces, otherwise 30 fps */
if (fps_n == 0) {
fps_n = 30;
fps_d = 1;
}
negotiated_caps = gst_caps_truncate (negotiated_caps);
s = gst_caps_get_structure (negotiated_caps, 0);
if (!gst_structure_has_field (s, "framerate"))
gst_structure_set (s, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
else
gst_structure_fixate_field_nearest_fraction (s, "framerate", fps_n,
fps_d);
ret = gst_base_src_set_caps (src, negotiated_caps);
if (!ret) {
GST_ERROR_OBJECT (src, "Failed to set caps %" GST_PTR_FORMAT,
negotiated_caps);
if (buffer)
gst_buffer_unref (buffer);
gst_caps_unref (negotiated_caps);
return GST_FLOW_NOT_NEGOTIATED;
}
gst_caps_unref (negotiated_caps);
} }
if (buffer == NULL) { if (buffer == NULL) {