mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 23:06:49 +00:00
videoaggregator: don't do caps processing that is not overridable
Allows the subclass to completely override the chosen src caps. This is needed as videoaggregator generally has no idea exactly what operation is being performed. - Adds a fixate_caps vfunc for fixation - Merges gst_video_aggregator_update_converters() into gst_videoaggregator_update_src_caps() as we need some of its info for proper caps handling. - Pass the downstream caps to the update_caps vfunc https://bugzilla.gnome.org/show_bug.cgi?id=756207
This commit is contained in:
parent
f8c6be86c2
commit
e03e983e90
3 changed files with 87 additions and 31 deletions
|
@ -221,9 +221,17 @@ gst_gl_mixer_pad_sink_acceptcaps (GstPad * pad, GstGLMixer * mix,
|
||||||
|
|
||||||
/* copies the given caps */
|
/* copies the given caps */
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_update_caps (GstVideoAggregator * vagg, GstCaps * caps)
|
_update_caps (GstVideoAggregator * vagg, GstCaps * caps, GstCaps * filter)
|
||||||
{
|
{
|
||||||
return gst_gl_caps_replace_all_caps_features (caps,
|
GstCaps *tmp;
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
tmp = gst_caps_intersect (caps, filter);
|
||||||
|
} else {
|
||||||
|
tmp = caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gst_gl_caps_replace_all_caps_features (tmp,
|
||||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ GST_DEBUG_CATEGORY (gst_gl_stereo_mix_debug);
|
||||||
#define gst_gl_stereo_mix_parent_class parent_class
|
#define gst_gl_stereo_mix_parent_class parent_class
|
||||||
G_DEFINE_TYPE (GstGLStereoMix, gst_gl_stereo_mix, GST_TYPE_GL_MIXER);
|
G_DEFINE_TYPE (GstGLStereoMix, gst_gl_stereo_mix, GST_TYPE_GL_MIXER);
|
||||||
|
|
||||||
static GstCaps *_update_caps (GstVideoAggregator * vagg, GstCaps * caps);
|
static GstCaps *_update_caps (GstVideoAggregator * vagg, GstCaps * caps,
|
||||||
|
GstCaps * filter);
|
||||||
static gboolean _negotiated_caps (GstVideoAggregator * videoaggregator,
|
static gboolean _negotiated_caps (GstVideoAggregator * videoaggregator,
|
||||||
GstCaps * caps);
|
GstCaps * caps);
|
||||||
gboolean gst_gl_stereo_mix_make_output (GstGLStereoMix * mix);
|
gboolean gst_gl_stereo_mix_make_output (GstGLStereoMix * mix);
|
||||||
|
@ -153,7 +154,6 @@ gst_gl_stereo_mix_class_init (GstGLStereoMixClass * klass)
|
||||||
videoaggregator_class->get_output_buffer =
|
videoaggregator_class->get_output_buffer =
|
||||||
gst_gl_stereo_mix_get_output_buffer;
|
gst_gl_stereo_mix_get_output_buffer;
|
||||||
videoaggregator_class->find_best_format = gst_gl_stereo_mix_find_best_format;
|
videoaggregator_class->find_best_format = gst_gl_stereo_mix_find_best_format;
|
||||||
videoaggregator_class->preserve_update_caps_result = TRUE;
|
|
||||||
|
|
||||||
base_mix_class->supported_gl_api = GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
|
base_mix_class->supported_gl_api = GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
|
||||||
}
|
}
|
||||||
|
@ -471,7 +471,7 @@ get_converted_caps (GstGLStereoMix * mix, GstCaps * caps)
|
||||||
|
|
||||||
/* Return the possible output caps we decided in find_best_format() */
|
/* Return the possible output caps we decided in find_best_format() */
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_update_caps (GstVideoAggregator * vagg, GstCaps * caps)
|
_update_caps (GstVideoAggregator * vagg, GstCaps * caps, GstCaps * filter)
|
||||||
{
|
{
|
||||||
GstGLStereoMix *mix = GST_GL_STEREO_MIX (vagg);
|
GstGLStereoMix *mix = GST_GL_STEREO_MIX (vagg);
|
||||||
|
|
||||||
|
|
|
@ -460,7 +460,9 @@ static void gst_gl_video_mixer_set_property (GObject * object, guint prop_id,
|
||||||
static void gst_gl_video_mixer_get_property (GObject * object, guint prop_id,
|
static void gst_gl_video_mixer_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static GstCaps *_update_caps (GstVideoAggregator * vagg, GstCaps * caps);
|
static GstCaps *_update_caps (GstVideoAggregator * vagg, GstCaps * caps,
|
||||||
|
GstCaps * filter);
|
||||||
|
static GstCaps *_fixate_caps (GstVideoAggregator * vagg, GstCaps * caps);
|
||||||
static void gst_gl_video_mixer_reset (GstGLMixer * mixer);
|
static void gst_gl_video_mixer_reset (GstGLMixer * mixer);
|
||||||
static gboolean gst_gl_video_mixer_init_shader (GstGLMixer * mixer,
|
static gboolean gst_gl_video_mixer_init_shader (GstGLMixer * mixer,
|
||||||
GstCaps * outcaps);
|
GstCaps * outcaps);
|
||||||
|
@ -863,6 +865,7 @@ gst_gl_video_mixer_class_init (GstGLVideoMixerClass * klass)
|
||||||
gst_gl_video_mixer_process_textures;
|
gst_gl_video_mixer_process_textures;
|
||||||
|
|
||||||
vagg_class->update_caps = _update_caps;
|
vagg_class->update_caps = _update_caps;
|
||||||
|
vagg_class->fixate_caps = _fixate_caps;
|
||||||
|
|
||||||
agg_class->sinkpads_type = GST_TYPE_GL_VIDEO_MIXER_PAD;
|
agg_class->sinkpads_type = GST_TYPE_GL_VIDEO_MIXER_PAD;
|
||||||
|
|
||||||
|
@ -912,9 +915,9 @@ gst_gl_video_mixer_get_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_mixer_pad_get_output_size (GstGLVideoMixer * mix,
|
_mixer_pad_get_output_size (GstGLVideoMixer * mix,
|
||||||
GstGLVideoMixerPad * mix_pad, gint * width, gint * height)
|
GstGLVideoMixerPad * mix_pad, gint out_par_n, gint out_par_d, gint * width,
|
||||||
|
gint * height)
|
||||||
{
|
{
|
||||||
GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
|
|
||||||
GstVideoAggregatorPad *vagg_pad = GST_VIDEO_AGGREGATOR_PAD (mix_pad);
|
GstVideoAggregatorPad *vagg_pad = GST_VIDEO_AGGREGATOR_PAD (mix_pad);
|
||||||
gint pad_width, pad_height;
|
gint pad_width, pad_height;
|
||||||
guint dar_n, dar_d;
|
guint dar_n, dar_d;
|
||||||
|
@ -937,13 +940,10 @@ _mixer_pad_get_output_size (GstGLVideoMixer * mix,
|
||||||
|
|
||||||
gst_video_calculate_display_ratio (&dar_n, &dar_d, pad_width, pad_height,
|
gst_video_calculate_display_ratio (&dar_n, &dar_d, pad_width, pad_height,
|
||||||
GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
|
GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
|
||||||
GST_VIDEO_INFO_PAR_D (&vagg_pad->info),
|
GST_VIDEO_INFO_PAR_D (&vagg_pad->info), out_par_n, out_par_d);
|
||||||
GST_VIDEO_INFO_PAR_N (&vagg->info), GST_VIDEO_INFO_PAR_D (&vagg->info)
|
|
||||||
);
|
|
||||||
GST_LOG_OBJECT (mix_pad, "scaling %ux%u by %u/%u (%u/%u / %u/%u)", pad_width,
|
GST_LOG_OBJECT (mix_pad, "scaling %ux%u by %u/%u (%u/%u / %u/%u)", pad_width,
|
||||||
pad_height, dar_n, dar_d, GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
|
pad_height, dar_n, dar_d, GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
|
||||||
GST_VIDEO_INFO_PAR_D (&vagg_pad->info),
|
GST_VIDEO_INFO_PAR_D (&vagg_pad->info), out_par_n, out_par_d);
|
||||||
GST_VIDEO_INFO_PAR_N (&vagg->info), GST_VIDEO_INFO_PAR_D (&vagg->info));
|
|
||||||
|
|
||||||
if (pad_height % dar_n == 0) {
|
if (pad_height % dar_n == 0) {
|
||||||
pad_width = gst_util_uint64_scale_int (pad_height, dar_n, dar_d);
|
pad_width = gst_util_uint64_scale_int (pad_height, dar_n, dar_d);
|
||||||
|
@ -960,17 +960,45 @@ _mixer_pad_get_output_size (GstGLVideoMixer * mix,
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_update_caps (GstVideoAggregator * vagg, GstCaps * caps)
|
_update_caps (GstVideoAggregator * vagg, GstCaps * caps, GstCaps * filter)
|
||||||
|
{
|
||||||
|
GstCaps *ret;
|
||||||
|
|
||||||
|
ret =
|
||||||
|
GST_VIDEO_AGGREGATOR_CLASS (gst_gl_video_mixer_parent_class)->update_caps
|
||||||
|
(vagg, caps, NULL);
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
GstCaps *tmp = gst_caps_intersect (ret, filter);
|
||||||
|
gst_caps_unref (ret);
|
||||||
|
ret = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
_fixate_caps (GstVideoAggregator * vagg, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstGLVideoMixer *mix = GST_GL_VIDEO_MIXER (vagg);
|
GstGLVideoMixer *mix = GST_GL_VIDEO_MIXER (vagg);
|
||||||
GList *l;
|
gint best_width = 0, best_height = 0;
|
||||||
gint best_width = -1, best_height = -1;
|
gint best_fps_n = 0, best_fps_d = 0;
|
||||||
GstVideoInfo info;
|
gint par_n, par_d;
|
||||||
|
gdouble best_fps = 0.;
|
||||||
GstCaps *ret = NULL;
|
GstCaps *ret = NULL;
|
||||||
int i;
|
GstStructure *s;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
caps = gst_caps_make_writable (caps);
|
ret = gst_caps_make_writable (caps);
|
||||||
gst_video_info_from_caps (&info, caps);
|
|
||||||
|
/* we need this to calculate how large to make the output frame */
|
||||||
|
s = gst_caps_get_structure (ret, 0);
|
||||||
|
if (gst_structure_has_field (s, "pixel-aspect-ratio")) {
|
||||||
|
gst_structure_fixate_field_nearest_fraction (s, "pixel-aspect-ratio", 1, 1);
|
||||||
|
gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n, &par_d);
|
||||||
|
} else {
|
||||||
|
par_n = par_d = 1;
|
||||||
|
}
|
||||||
|
|
||||||
GST_OBJECT_LOCK (vagg);
|
GST_OBJECT_LOCK (vagg);
|
||||||
for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
|
for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
|
||||||
|
@ -978,8 +1006,12 @@ _update_caps (GstVideoAggregator * vagg, GstCaps * caps)
|
||||||
GstGLVideoMixerPad *mixer_pad = GST_GL_VIDEO_MIXER_PAD (vaggpad);
|
GstGLVideoMixerPad *mixer_pad = GST_GL_VIDEO_MIXER_PAD (vaggpad);
|
||||||
gint this_width, this_height;
|
gint this_width, this_height;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
gint fps_n, fps_d;
|
||||||
|
gdouble cur_fps;
|
||||||
|
|
||||||
_mixer_pad_get_output_size (mix, mixer_pad, &width, &height);
|
fps_n = GST_VIDEO_INFO_FPS_N (&vaggpad->info);
|
||||||
|
fps_d = GST_VIDEO_INFO_FPS_D (&vaggpad->info);
|
||||||
|
_mixer_pad_get_output_size (mix, mixer_pad, par_n, par_d, &width, &height);
|
||||||
|
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -991,20 +1023,34 @@ _update_caps (GstVideoAggregator * vagg, GstCaps * caps)
|
||||||
best_width = this_width;
|
best_width = this_width;
|
||||||
if (best_height < this_height)
|
if (best_height < this_height)
|
||||||
best_height = this_height;
|
best_height = this_height;
|
||||||
|
|
||||||
|
if (fps_d == 0)
|
||||||
|
cur_fps = 0.0;
|
||||||
|
else
|
||||||
|
gst_util_fraction_to_double (fps_n, fps_d, &cur_fps);
|
||||||
|
|
||||||
|
if (best_fps < cur_fps) {
|
||||||
|
best_fps = cur_fps;
|
||||||
|
best_fps_n = fps_n;
|
||||||
|
best_fps_d = fps_d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (vagg);
|
GST_OBJECT_UNLOCK (vagg);
|
||||||
|
|
||||||
ret =
|
if (best_fps_n <= 0 || best_fps_d <= 0 || best_fps == 0.0) {
|
||||||
GST_VIDEO_AGGREGATOR_CLASS (gst_gl_video_mixer_parent_class)->update_caps
|
best_fps_n = 25;
|
||||||
(vagg, caps);
|
best_fps_d = 1;
|
||||||
|
best_fps = 25.0;
|
||||||
for (i = 0; i < gst_caps_get_size (ret); i++) {
|
|
||||||
GstStructure *s = gst_caps_get_structure (ret, i);
|
|
||||||
|
|
||||||
gst_structure_set (s, "width", G_TYPE_INT, best_width, "height", G_TYPE_INT,
|
|
||||||
best_height, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s = gst_caps_get_structure (ret, 0);
|
||||||
|
gst_structure_fixate_field_nearest_int (s, "width", best_width);
|
||||||
|
gst_structure_fixate_field_nearest_int (s, "height", best_height);
|
||||||
|
gst_structure_fixate_field_nearest_fraction (s, "framerate", best_fps_n,
|
||||||
|
best_fps_d);
|
||||||
|
gst_structure_fixate_field_nearest_fraction (s, "pixel-aspect-ratio", 1, 1);
|
||||||
|
ret = gst_caps_fixate (ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1397,7 +1443,9 @@ gst_gl_video_mixer_callback (gpointer stuff)
|
||||||
gint pad_width, pad_height;
|
gint pad_width, pad_height;
|
||||||
gfloat w, h;
|
gfloat w, h;
|
||||||
|
|
||||||
_mixer_pad_get_output_size (video_mixer, pad, &pad_width, &pad_height);
|
_mixer_pad_get_output_size (video_mixer, pad,
|
||||||
|
GST_VIDEO_INFO_PAR_N (&vagg->info),
|
||||||
|
GST_VIDEO_INFO_PAR_D (&vagg->info), &pad_width, &pad_height);
|
||||||
|
|
||||||
w = ((gfloat) pad_width / (gfloat) out_width);
|
w = ((gfloat) pad_width / (gfloat) out_width);
|
||||||
h = ((gfloat) pad_height / (gfloat) out_height);
|
h = ((gfloat) pad_height / (gfloat) out_height);
|
||||||
|
|
Loading…
Reference in a new issue