From: Matthew Waters Date: Thu, 20 Sep 2012 13:27:00 +0000 (+1000) Subject: [587/906] mixer: mirror the changes done for filter X-Git-Tag: 1.19.3~511^2~1989^2~1920 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=89569276c563d3343417ea5e34bddcd0714131d7;p=platform%2Fupstream%2Fgstreamer.git [587/906] mixer: mirror the changes done for filter --- diff --git a/gst-libs/gst/gl/gstglmixer.c b/gst-libs/gst/gl/gstglmixer.c index 30aa633..5696572 100644 --- a/gst-libs/gst/gl/gstglmixer.c +++ b/gst-libs/gst/gl/gstglmixer.c @@ -130,10 +130,10 @@ gst_gl_mixer_update_src_caps (GstGLMixer * mix) gint fps_n, fps_d; gint width, height; - fps_n = GST_VIDEO_INFO_FPS_N (&mpad->info); - fps_d = GST_VIDEO_INFO_FPS_D (&mpad->info); - width = GST_VIDEO_INFO_WIDTH (&mpad->info); - height = GST_VIDEO_INFO_HEIGHT (&mpad->info); + fps_n = GST_VIDEO_INFO_FPS_N (&mpad->in_info); + fps_d = GST_VIDEO_INFO_FPS_D (&mpad->in_info); + width = GST_VIDEO_INFO_WIDTH (&mpad->in_info); + height = GST_VIDEO_INFO_HEIGHT (&mpad->in_info); if (fps_n == 0 || fps_d == 0 || width == 0 || height == 0) continue; @@ -169,66 +169,50 @@ gst_gl_mixer_update_src_caps (GstGLMixer * mix) GstStructure *s; GstVideoInfo info; - if (GST_VIDEO_INFO_FPS_N (&mix->info) != best_fps_n || - GST_VIDEO_INFO_FPS_D (&mix->info) != best_fps_d) { + if (GST_VIDEO_INFO_FPS_N (&mix->out_info) != best_fps_n || + GST_VIDEO_INFO_FPS_D (&mix->out_info) != best_fps_d) { if (mix->segment.position != -1) { mix->ts_offset = mix->segment.position - mix->segment.start; mix->nframes = 0; } } - gst_video_info_set_format (&info, GST_VIDEO_INFO_FORMAT (&mix->info), - best_width, best_height); - info.fps_n = best_fps_n; - info.fps_d = best_fps_d; - info.par_n = GST_VIDEO_INFO_PAR_N (&mix->info); - info.par_d = GST_VIDEO_INFO_PAR_D (&mix->info); - caps = gst_video_info_to_caps (&info); + caps = gst_caps_new_empty_simple ("video/x-raw"); peercaps = gst_pad_peer_query_caps (mix->srcpad, NULL); if (peercaps) { GstCaps *tmp; - - s = gst_caps_get_structure (caps, 0); - gst_structure_set (s, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", - GST_TYPE_INT_RANGE, 1, G_MAXINT, "framerate", GST_TYPE_FRACTION_RANGE, - 0, 1, G_MAXINT, 1, NULL); - tmp = gst_caps_intersect (caps, peercaps); gst_caps_unref (caps); gst_caps_unref (peercaps); caps = tmp; - if (gst_caps_is_empty (caps)) { - GST_DEBUG_OBJECT (mix, "empty caps"); - ret = FALSE; - GST_GL_MIXER_UNLOCK (mix); - goto done; - } + } + + if (!gst_caps_is_fixed (caps)) { + caps = gst_caps_make_writable (caps); caps = gst_caps_truncate (caps); + s = gst_caps_get_structure (caps, 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_string (s, "format", "RGBA"); gst_structure_get_int (s, "width", &info.width); gst_structure_get_int (s, "height", &info.height); gst_structure_get_fraction (s, "fraction", &info.fps_n, &info.fps_d); - gst_caps_unref (caps); + GST_DEBUG_OBJECT (mix, "fixated caps to %" GST_PTR_FORMAT, caps); } - caps = gst_video_info_to_caps (&info); - GST_GL_MIXER_UNLOCK (mix); ret = gst_gl_mixer_src_setcaps (mix->srcpad, mix, caps); -// ret = gst_pad_set_caps (mix->srcpad, caps); - gst_caps_unref (caps); } else { + GST_INFO_OBJECT (mix, "Invalid caps"); GST_GL_MIXER_UNLOCK (mix); } -done: return ret; } @@ -238,7 +222,7 @@ gst_gl_mixer_pad_sink_setcaps (GstPad * pad, GstObject * parent, GstCaps * caps) GstGLMixer *mix; GstGLMixerPad *mixpad; GstVideoInfo info; - gboolean ret = FALSE; + gboolean ret = TRUE; GST_INFO_OBJECT (pad, "Setting caps %" GST_PTR_FORMAT, caps); @@ -251,18 +235,9 @@ gst_gl_mixer_pad_sink_setcaps (GstPad * pad, GstObject * parent, GstCaps * caps) } GST_GL_MIXER_LOCK (mix); - if (GST_VIDEO_INFO_FORMAT (&mix->info) != GST_VIDEO_FORMAT_UNKNOWN) { - if (GST_VIDEO_INFO_FORMAT (&mix->info) != GST_VIDEO_INFO_FORMAT (&info) || - GST_VIDEO_INFO_PAR_N (&mix->info) != GST_VIDEO_INFO_PAR_N (&info) || - GST_VIDEO_INFO_PAR_D (&mix->info) != GST_VIDEO_INFO_PAR_D (&info)) { - GST_ERROR_OBJECT (pad, "Caps not compatible with other pads' caps"); - GST_GL_MIXER_UNLOCK (mix); - goto beach; - } - } - mix->info = info; - mixpad->info = info; + mix->out_info = info; + mixpad->in_info = info; GST_GL_MIXER_UNLOCK (mix); @@ -325,6 +300,7 @@ gst_gl_mixer_pad_sink_acceptcaps (GstPad * pad, GstGLMixer * mix, gst_structure_set (s, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + gst_structure_remove_field (s, "format"); if (!gst_structure_has_field (s, "pixel-aspect-ratio")) gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); @@ -344,7 +320,6 @@ gst_gl_mixer_sink_query (GstCollectPads * pads, GstCollectData * data, GstQuery * query, GstGLMixer * mix) { GstPad *pad = data->pad; - GstGLMixerPad *mixpad = GST_GL_MIXER_PAD (data->pad); gboolean ret = FALSE; GST_TRACE ("QUERY %" GST_PTR_FORMAT, query); @@ -378,27 +353,8 @@ gst_gl_mixer_sink_query (GstCollectPads * pads, GstCollectData * data, GstStructure *structure = gst_query_writable_structure (query); if (gst_structure_has_name (structure, "gstgldisplay")) { - gulong foreign_gl_context = 0; - - foreign_gl_context = - gst_gl_display_get_internal_gl_context (mix->display); - - g_return_val_if_fail (mixpad->display != NULL, FALSE); - - gst_gl_display_activate_gl_context (mix->display, FALSE); - - ret = gst_gl_display_create_context (mixpad->display, - foreign_gl_context); - - gst_gl_display_activate_gl_context (mix->display, TRUE); - - if (ret) { - gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, - mixpad->display, NULL); - } else { - GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, - GST_GL_DISPLAY_ERR_MSG (mixpad->display), (NULL)); - } + gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, + mix->display, NULL); } else { ret = gst_collect_pads_query_default (pads, data, query, FALSE); } @@ -415,7 +371,6 @@ gst_gl_mixer_sink_query (GstCollectPads * pads, GstCollectData * data, static void gst_gl_mixer_pad_init (GstGLMixerPad * mixerpad) { - mixerpad->display = NULL; } /* GLMixer signals and args */ @@ -433,13 +388,13 @@ enum static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_GL_VIDEO_CAPS) + GST_STATIC_CAPS (GST_GL_UPLOAD_VIDEO_CAPS) ); static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d", GST_PAD_SINK, GST_PAD_REQUEST, - GST_STATIC_CAPS (GST_GL_VIDEO_CAPS) + GST_STATIC_CAPS (GST_GL_DOWNLOAD_VIDEO_CAPS) ); static void gst_gl_mixer_finalize (GObject * object); @@ -580,7 +535,7 @@ gst_gl_mixer_reset (GstGLMixer * mix) GstGLMixerPrivate *priv = mix->priv; GSList *l; - gst_video_info_init (&mix->info); + gst_video_info_init (&mix->out_info); mix->ts_offset = 0; mix->nframes = 0; @@ -596,7 +551,7 @@ gst_gl_mixer_reset (GstGLMixer * mix) mixcol->start_time = -1; mixcol->end_time = -1; - gst_video_info_init (&p->info); + gst_video_info_init (&p->in_info); } mix->newseg_pending = TRUE; @@ -740,7 +695,7 @@ gst_gl_mixer_query_caps (GstPad * pad, GstObject * parent, GstQuery * query) gst_query_parse_caps (query, &filter); - if (GST_VIDEO_INFO_FORMAT (&mix->info) != GST_VIDEO_FORMAT_UNKNOWN) { + if (GST_VIDEO_INFO_FORMAT (&mix->out_info) != GST_VIDEO_FORMAT_UNKNOWN) { caps = gst_pad_get_current_caps (mix->srcpad); } else { caps = gst_pad_get_pad_template_caps (mix->srcpad); @@ -753,7 +708,7 @@ gst_gl_mixer_query_caps (GstPad * pad, GstObject * parent, GstQuery * query) s = gst_caps_get_structure (caps, n); gst_structure_set (s, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - if (GST_VIDEO_INFO_FPS_D (&mix->info) != 0) { + if (GST_VIDEO_INFO_FPS_D (&mix->out_info) != 0) { gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); } @@ -863,7 +818,8 @@ gst_gl_mixer_update_qos (GstGLMixer * mix, gdouble proportion, if (G_UNLIKELY (diff > 0)) mix->earliest_time = timestamp + 2 * diff + gst_util_uint64_scale_int (GST_SECOND, - GST_VIDEO_INFO_FPS_D (&mix->info), GST_VIDEO_INFO_FPS_N (&mix->info)); + GST_VIDEO_INFO_FPS_D (&mix->out_info), + GST_VIDEO_INFO_FPS_N (&mix->out_info)); else mix->earliest_time = timestamp + diff; } else { @@ -1000,7 +956,6 @@ gst_gl_mixer_decide_allocation (GstGLMixer * mix, GstQuery * query) GstCaps *caps; guint min, max, size; gboolean update_pool; - guint idx; gst_query_parse_allocation (query, &caps, NULL); @@ -1024,13 +979,7 @@ gst_gl_mixer_decide_allocation (GstGLMixer * mix, GstQuery * query) config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); - if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, &idx)) { - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - } - if (gst_query_find_allocation_meta (query, GST_GL_META_API_TYPE, &idx)) { - gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_GL_META); - } + gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_set_config (pool, config); @@ -1156,8 +1105,8 @@ gst_gl_mixer_src_setcaps (GstPad * pad, GstGLMixer * mix, GstCaps * caps) GST_GL_MIXER_LOCK (mix); - if (GST_VIDEO_INFO_FPS_N (&mix->info) != GST_VIDEO_INFO_FPS_N (&info) || - GST_VIDEO_INFO_FPS_D (&mix->info) != GST_VIDEO_INFO_FPS_D (&info)) { + if (GST_VIDEO_INFO_FPS_N (&mix->out_info) != GST_VIDEO_INFO_FPS_N (&info) || + GST_VIDEO_INFO_FPS_D (&mix->out_info) != GST_VIDEO_INFO_FPS_D (&info)) { if (mix->segment.position != -1) { mix->ts_offset = mix->segment.position - mix->segment.start; mix->nframes = 0; @@ -1165,14 +1114,32 @@ gst_gl_mixer_src_setcaps (GstPad * pad, GstGLMixer * mix, GstCaps * caps) gst_gl_mixer_reset_qos (mix); } - mix->info = info; + mix->out_info = info; GST_GL_MIXER_UNLOCK (mix); - if (!gst_gl_display_gen_fbo (mix->display, GST_VIDEO_INFO_WIDTH (&mix->info), - GST_VIDEO_INFO_HEIGHT (&mix->info), &mix->fbo, &mix->depthbuffer)) + if (!gst_gl_display_gen_fbo (mix->display, + GST_VIDEO_INFO_WIDTH (&mix->out_info), + GST_VIDEO_INFO_HEIGHT (&mix->out_info), &mix->fbo, &mix->depthbuffer)) goto display_error; + mix->download = gst_gl_display_find_download (mix->display, + GST_VIDEO_INFO_FORMAT (&mix->out_info), + GST_VIDEO_INFO_WIDTH (&mix->out_info), + GST_VIDEO_INFO_HEIGHT (&mix->out_info)); + + gst_gl_download_init_format (mix->download, + GST_VIDEO_INFO_FORMAT (&mix->out_info), + GST_VIDEO_INFO_WIDTH (&mix->out_info), + GST_VIDEO_INFO_HEIGHT (&mix->out_info)); + + if (mix->out_tex_id) + gst_gl_display_del_texture (mix->display, &mix->out_tex_id); + gst_gl_display_gen_texture (mix->display, &mix->out_tex_id, + GST_VIDEO_INFO_FORMAT (&mix->out_info), + GST_VIDEO_INFO_WIDTH (&mix->out_info), + GST_VIDEO_INFO_HEIGHT (&mix->out_info)); + if (mixer_class->set_caps) mixer_class->set_caps (mix, caps); @@ -1227,7 +1194,7 @@ gst_gl_mixer_request_new_pad (GstElement * element, g_free (name); mixcol = (GstGLMixerCollect *) - gst_collect_pads_add_pad_full (mix->collect, GST_PAD (mixpad), + gst_collect_pads_add_pad (mix->collect, GST_PAD (mixpad), sizeof (GstGLMixerCollect), (GstCollectDataDestroyNotify) gst_gl_mixer_collect_free, TRUE); @@ -1278,7 +1245,8 @@ gst_gl_mixer_release_pad (GstElement * element, GstPad * pad) GST_OBJECT_NAME (mixpad)); mix->numpads--; - update_caps = GST_VIDEO_INFO_FORMAT (&mix->info) != GST_VIDEO_FORMAT_UNKNOWN; + update_caps = + GST_VIDEO_INFO_FORMAT (&mix->out_info) != GST_VIDEO_FORMAT_UNKNOWN; GST_GL_MIXER_UNLOCK (mix); gst_collect_pads_remove_pad (mix->collect, pad); @@ -1457,15 +1425,35 @@ gst_gl_mixer_fill_queues (GstGLMixer * mix, return 1; } -static void -gst_gl_mixer_process_buffers (GstGLMixer * mix, GstBuffer * outbuf) +gboolean +gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) { GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); GSList *walk = mix->sinkpads; - gint array_index = 0; + GstVideoFrame out_frame; + gboolean out_gl_wrapped = FALSE; + guint out_tex; + guint array_index = 0; + guint i; GST_TRACE ("Processing buffers"); + if (!gst_video_frame_map (&out_frame, &mix->out_info, outbuf, + GST_MAP_WRITE | GST_MAP_GL)) { + return FALSE; + } + + if (gst_is_gl_memory (out_frame.map[0].memory)) { + out_tex = *(guint *) out_frame.data[0]; + } else { + GST_INFO ("Output Buffer does not contain correct memory, " + "attempting to wrap for download"); + + out_tex = mix->out_tex_id;; + + out_gl_wrapped = TRUE; + } + while (walk) { /* We walk with this list because it's ordered */ GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data); GstGLMixerCollect *mixcol = pad->mixcol; @@ -1476,6 +1464,8 @@ gst_gl_mixer_process_buffers (GstGLMixer * mix, GstBuffer * outbuf) GstClockTime timestamp; gint64 stream_time; GstSegment *seg; + guint in_tex; + GstVideoFrame *in_frame; seg = &mixcol->collect.segment; @@ -1488,23 +1478,104 @@ gst_gl_mixer_process_buffers (GstGLMixer * mix, GstBuffer * outbuf) if (GST_CLOCK_TIME_IS_VALID (stream_time)) gst_object_sync_values (GST_OBJECT (pad), stream_time); - /* put buffer into array */ - mix->array_buffers->pdata[array_index] = mixcol->buffer; + in_frame = g_ptr_array_index (mix->in_frames, array_index); + + if (!gst_video_frame_map (in_frame, &pad->in_info, mixcol->buffer, + GST_MAP_READ | GST_MAP_GL)) { + break; + } + + if (gst_is_gl_memory (in_frame->map[0].memory)) { + in_tex = *(guint *) in_frame->data[0]; + } else { + GstGLUpload *upload; + + GST_DEBUG ("Input buffer:%p does not contain correct memory, " + "attempting to wrap for upload", mixcol->buffer); + + upload = gst_gl_display_find_upload (mix->display, + GST_VIDEO_FRAME_FORMAT (in_frame), + GST_VIDEO_FRAME_WIDTH (in_frame), + GST_VIDEO_FRAME_HEIGHT (in_frame)); + + gst_gl_upload_init_format (upload, + GST_VIDEO_FRAME_FORMAT (in_frame), + GST_VIDEO_FRAME_WIDTH (in_frame), + GST_VIDEO_FRAME_HEIGHT (in_frame)); + + if (!pad->in_tex_id) + gst_gl_display_gen_texture (mix->display, &pad->in_tex_id, + GST_VIDEO_INFO_FORMAT (&mix->out_info), + GST_VIDEO_INFO_WIDTH (&mix->out_info), + GST_VIDEO_INFO_HEIGHT (&mix->out_info)); + + gst_gl_upload_perform_with_data (upload, pad->in_tex_id, + in_frame->data); + + in_tex = pad->in_tex_id; + pad->uploaded = TRUE; + } + + g_array_index (mix->array_textures, guint, array_index) = in_tex; + } + ++array_index; + } + + mix_class->process_textures (mix, mix->array_textures, mix->in_frames, + out_tex); - /*if (pad == mix->master) { - gint64 running_time; + if (out_gl_wrapped) { + gst_gl_download_perform_with_data (mix->download, out_tex, out_frame.data); + } + + i = 0; + walk = mix->sinkpads; + while (walk) { + GstVideoFrame *in_frame = g_ptr_array_index (mix->in_frames, i); + + if (in_frame) + gst_video_frame_unmap (in_frame); + + walk = g_slist_next (walk); + i++; + } - running_time = - gst_segment_to_running_time (seg, GST_FORMAT_TIME, timestamp); */ + gst_video_frame_unmap (&out_frame); + + return TRUE; +} + +static void +gst_gl_mixer_process_buffers (GstGLMixer * mix, GstBuffer * outbuf) +{ + GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); + GSList *walk = mix->sinkpads; + guint array_index = 0; - /* outgoing buffers need the running_time */ - /*GST_BUFFER_TIMESTAMP (outbuf) = running_time; - GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (mixcol->buffer); + while (walk) { /* We walk with this list because it's ordered */ + GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data); + GstGLMixerCollect *mixcol = pad->mixcol; + + walk = g_slist_next (walk); + + if (mixcol->buffer != NULL) { + GstClockTime timestamp; + gint64 stream_time; + GstSegment *seg; + + seg = &mixcol->collect.segment; + + timestamp = GST_BUFFER_TIMESTAMP (mixcol->buffer); - mix->last_ts = running_time; - if (GST_BUFFER_DURATION_IS_VALID (outbuf)) - mix->last_ts += GST_BUFFER_DURATION (outbuf); - } */ + stream_time = + gst_segment_to_stream_time (seg, GST_FORMAT_TIME, timestamp); + + /* sync object properties on stream time */ + if (GST_CLOCK_TIME_IS_VALID (stream_time)) + gst_object_sync_values (GST_OBJECT (pad), stream_time); + + /* put buffer into array */ + mix->array_buffers->pdata[array_index] = mixcol->buffer; } ++array_index; } @@ -1557,6 +1628,7 @@ gst_gl_mixer_do_qos (GstGLMixer * mix, GstClockTime timestamp) static GstFlowReturn gst_gl_mixer_collected (GstCollectPads * pads, GstGLMixer * mix) { + GstGLMixerClass *mix_class; GstFlowReturn ret; GstClockTime output_start_time, output_end_time; GstBuffer *outbuf = NULL; @@ -1565,9 +1637,13 @@ gst_gl_mixer_collected (GstCollectPads * pads, GstGLMixer * mix) g_return_val_if_fail (GST_IS_GL_MIXER (mix), GST_FLOW_ERROR); + mix_class = GST_GL_MIXER_GET_CLASS (mix); + /* If we're not negotiated yet... */ - if (GST_VIDEO_INFO_FORMAT (&mix->info) == GST_VIDEO_FORMAT_UNKNOWN) + if (GST_VIDEO_INFO_FORMAT (&mix->out_info) == GST_VIDEO_FORMAT_UNKNOWN) { + GST_ELEMENT_ERROR (mix, CORE, NEGOTIATION, ("not negotiated"), (NULL)); return GST_FLOW_NOT_NEGOTIATED; + } if (g_atomic_int_compare_and_exchange (&mix->flush_stop_pending, TRUE, FALSE)) { GST_DEBUG_OBJECT (mix, "pending flush stop"); @@ -1600,8 +1676,8 @@ gst_gl_mixer_collected (GstCollectPads * pads, GstGLMixer * mix) output_end_time = mix->ts_offset + gst_util_uint64_scale (mix->nframes + 1, - GST_SECOND * GST_VIDEO_INFO_FPS_D (&mix->info), - GST_VIDEO_INFO_FPS_N (&mix->info)); + GST_SECOND * GST_VIDEO_INFO_FPS_D (&mix->out_info), + GST_VIDEO_INFO_FPS_N (&mix->out_info)); if (mix->segment.stop != -1) output_end_time = MIN (output_end_time, mix->segment.stop); @@ -1638,7 +1714,13 @@ gst_gl_mixer_collected (GstCollectPads * pads, GstGLMixer * mix) ret = gst_buffer_pool_acquire_buffer (mix->priv->pool, &outbuf, NULL); - gst_gl_mixer_process_buffers (mix, outbuf); + g_assert (mix_class->process_buffers || mix_class->process_textures); + + if (mix_class->process_buffers) + gst_gl_mixer_process_buffers (mix, outbuf); + else if (mix_class->process_textures) + gst_gl_mixer_process_textures (mix, outbuf); + mix->qos_processed++; } else { GstMessage *msg; @@ -1746,7 +1828,8 @@ gst_gl_mixer_sink_clip (GstCollectPads * pads, if (end_time == -1) end_time = gst_util_uint64_scale_int (GST_SECOND, - GST_VIDEO_INFO_FPS_D (&pad->info), GST_VIDEO_INFO_FPS_N (&pad->info)); + GST_VIDEO_INFO_FPS_D (&pad->in_info), + GST_VIDEO_INFO_FPS_N (&pad->in_info)); if (end_time == -1) { *outbuf = buf; return GST_FLOW_OK; @@ -1967,8 +2050,6 @@ static void gst_gl_mixer_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - //GstGLMixer *mix = GST_GL_MIXER (object); - switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1980,8 +2061,6 @@ static void gst_gl_mixer_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - //GstGLMixer *mix = GST_GL_MIXER (object); - switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -2004,35 +2083,40 @@ gst_gl_mixer_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: { - GSList *walk = mix->sinkpads; - gint i = 0; - - /* instanciate a gldisplay for each sink pad */ - while (walk) { - GstGLMixerPad *sink_pad = GST_GL_MIXER_PAD (walk->data); - walk = g_slist_next (walk); - sink_pad->display = gst_gl_display_new (); - } - mix->array_buffers = g_ptr_array_sized_new (mix->next_sinkpad); - for (i = 0; i < mix->next_sinkpad; ++i) { - g_ptr_array_add (mix->array_buffers, NULL); + guint i; + + mix->array_buffers = g_ptr_array_new_full (mix->numpads, NULL); + mix->in_frames = g_ptr_array_new_full (mix->numpads, NULL); + mix->array_textures = + g_array_sized_new (FALSE, TRUE, sizeof (guint), mix->numpads); + + g_ptr_array_set_size (mix->array_buffers, mix->numpads); + g_ptr_array_set_size (mix->in_frames, mix->numpads); + g_array_set_size (mix->array_textures, mix->numpads); + + for (i = 0; i < mix->numpads; i++) { + mix->in_frames->pdata[i] = g_slice_alloc (sizeof (GstVideoFrame)); } + GST_LOG_OBJECT (mix, "starting collectpads"); gst_collect_pads_start (mix->collect); break; } case GST_STATE_CHANGE_PAUSED_TO_READY: { - GSList *walk = mix->sinkpads; + guint i; + GST_LOG_OBJECT (mix, "stopping collectpads"); gst_collect_pads_stop (mix->collect); - g_ptr_array_free (mix->array_buffers, TRUE); - while (walk) { - GstGLMixerPad *sink_pad = GST_GL_MIXER_PAD (walk->data); - walk = g_slist_next (walk); - if (sink_pad->display) - gst_gl_display_activate_gl_context (sink_pad->display, FALSE); + + for (i = 0; i < mix->numpads; i++) { + g_slice_free1 (sizeof (GstVideoFrame), mix->in_frames->pdata[i]); } + + g_ptr_array_free (mix->array_buffers, TRUE); + g_ptr_array_free (mix->in_frames, TRUE); + g_array_free (mix->array_textures, TRUE); + if (mixer_class->reset) mixer_class->reset (mix); if (mix->fbo) { @@ -2044,16 +2128,6 @@ gst_gl_mixer_change_state (GstElement * element, GstStateChange transition) g_object_unref (mix->display); mix->display = NULL; } - walk = mix->sinkpads; - while (walk) { - GstGLMixerPad *sink_pad = GST_GL_MIXER_PAD (walk->data); - walk = g_slist_next (walk); - if (sink_pad->display) { - gst_gl_display_activate_gl_context (sink_pad->display, TRUE); - g_object_unref (sink_pad->display); - sink_pad->display = NULL; - } - } break; } default: diff --git a/gst-libs/gst/gl/gstglmixer.h b/gst-libs/gst/gl/gstglmixer.h index 5823c6e..50769e9 100644 --- a/gst-libs/gst/gl/gstglmixer.h +++ b/gst-libs/gst/gl/gstglmixer.h @@ -50,6 +50,8 @@ typedef gboolean (*GstGLMixerSetCaps) (GstGLMixer* mixer, typedef void (*GstGLMixerReset) (GstGLMixer *mixer); typedef gboolean (*GstGLMixerProcessFunc) (GstGLMixer *mix, GPtrArray *buffers, GstBuffer *outbuf); +typedef gboolean (*GstGLMixerProcessTextures) (GstGLMixer *mix, + GArray *in_textures, GPtrArray *in_frames, guint out_tex); struct _GstGLMixer { @@ -72,8 +74,12 @@ struct _GstGLMixer gint next_sinkpad; GPtrArray *array_buffers; + GArray *array_textures; + GPtrArray *in_frames; - GstVideoInfo info; + GstVideoInfo out_info; + GLuint out_tex_id; + GstGLDownload *download; gboolean newseg_pending; gboolean flush_stop_pending; @@ -99,9 +105,12 @@ struct _GstGLMixerClass GstGLMixerSetCaps set_caps; GstGLMixerReset reset; GstGLMixerProcessFunc process_buffers; + GstGLMixerProcessTextures process_textures; }; GType gst_gl_mixer_get_type(void); +gboolean gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf); + G_END_DECLS #endif /* __GST_GL_MIXER_H__ */ diff --git a/gst-libs/gst/gl/gstglmixerpad.h b/gst-libs/gst/gl/gstglmixerpad.h index 3127822..a1e2807 100644 --- a/gst-libs/gst/gl/gstglmixerpad.h +++ b/gst-libs/gst/gl/gstglmixerpad.h @@ -24,7 +24,7 @@ #include #include -#include "gstglmeta.h" +#include "gstgldisplay.h" G_BEGIN_DECLS @@ -61,9 +61,9 @@ struct _GstGLMixerPad GstPad parent; /* subclass the pad */ /* */ - GstVideoInfo info; - - GstGLDisplay *display; + GstVideoInfo in_info; + guint in_tex_id; + gboolean uploaded; GstGLMixerCollect *mixcol; };