Dynamic change of glshader element

Christian Winkler christian at heidelbergs.de
Sat Nov 15 02:10:22 PST 2014


Dear Members,

 

i am trying to change a glshader element at runtime in a native Gstreamer
application.

 

The idea is to convert a rtsp Stream to an side-by-side view for a android
google cardboard VR device.

I want to implement headtracking as well and therefore want to change the
opengl fragment dynamically based on head position.

 

The code below works for a static .frag file.

 

QUESTION: How can i change for example 

const vec2 leftCenter = vec2(0.25, 0.4);

const vec2 rightCenter = vec2(0.75, 0.4);

DYNAMICALLY during runtime in the native code?

 

There used tob o something like gstglfiltershader, but i can not find a
similar functionality in the current 1.4.x releases.

 

Thanks!!!!

Kind regards

Christian

 

 

The current Pipeline is set up as follows (JNI Code for an Android App).

This 

 

 

                ..

                // rtspsrc location=rtsp://192.168.137.240:8554/test
latency=0 drop-on-latency=true ! application/x-rtp, payload=96 !
rtph264depay ! decodebin ! glimagesink  sync=false

                data->source = gst_element_factory_make
("rtspsrc","rtspsrc");

                g_object_set(G_OBJECT
(data->source),"location",pipelineParameterFromJava,"latency",0,"drop-on-lat
ency",true,NULL);

 

                data->pipeline = gst_pipeline_new ("fpv-pipeline");

 
data->filter=gst_element_factory_make("capsfilter","filter");

                data->depayloader  = gst_element_factory_make
("rtph264depay","rtph264depay");

                data->decoder  = gst_element_factory_make
("decodebin","decodebin");

                data->distortion = gst_element_factory_make
("glshader","glshader");

                data->video_sink = gst_element_factory_make
("glimagesink","glimagesink");

 

                filtercaps = gst_caps_new_simple
("application/x-rtp","payload", G_TYPE_INT, 96,NULL);

                g_object_set (G_OBJECT (data->filter), "caps", filtercaps,
NULL);

                g_object_set (G_OBJECT (data->distortion), "location",
"/data/data/com.lonestar.groundpi/files/distortion.frag", NULL);

                gst_caps_unref (filtercaps);

                g_object_set(G_OBJECT (data->video_sink),"sync",false,NULL);

 

                if (!data->pipeline || !data->source || !data->filter ||
!data->depayloader || !data->decoder || !data->video_sink ||
!data->distortion) {

                  g_printerr ("One element could not be created.
Exiting.\n");

                  return -1;

                }

 

                gst_bin_add_many (GST_BIN (data->pipeline), data->source,
data->filter, data->depayloader, data->decoder, data->video_sink,
data->distortion, NULL);

                gst_element_link_many (data->filter, data->depayloader,
data->decoder, NULL);

                gst_element_link_many (data->distortion, data->video_sink,
NULL);

                g_signal_connect (data->source, "pad-added", G_CALLBACK
(cb_new_pad), data->filter);

                g_signal_connect (data->decoder, "pad-added", G_CALLBACK
(cb_new_pad), data->distortion);

..

 

 

 

 

Distortion.frag:

 

#extension GL_ARB_texture_rectangle : enable

precision mediump float;

varying vec2 v_texcoord;

uniform sampler2D tex;

const vec4 kappa = vec4(2.75,1.7,0.5,0.5);

const float screen_width = 1920.0;

const float screen_height = 1080.0;

const float scaleFactor = 0.62;

const vec2 leftCenter = vec2(0.25, 0.4);

const vec2 rightCenter = vec2(0.75, 0.4);

const float separation = -0.025;

const bool stereo_input = false;

 

// Scales input texture coordinates for distortion.

vec2 hmdWarp(vec2 LensCenter, vec2 texCoord, vec2 Scale, vec2 ScaleIn) {

vec2 theta = (texCoord - LensCenter) * ScaleIn;

float rSq = theta.x * theta.x + theta.y * theta.y;

vec2 rvector = theta * (kappa.x + kappa.y * rSq + kappa.z * rSq * rSq +
kappa.w * rSq * rSq * rSq);

vec2 tc = LensCenter + Scale * rvector;

return tc;

}

bool validate(vec2 tc, int eye) {

if ( stereo_input ) {

//keep within bounds of texture

if ((eye == 1 && (tc.x < 0.0 || tc.x > 0.5)) ||

(eye == 0 && (tc.x < 0.5 || tc.x > 1.0)) ||

tc.y < 0.0 || tc.y > 1.0) {

return false;

}

} else {

if ( tc.x < 0.0 || tc.x > 1.0 ||

tc.y < 0.0 || tc.y > 1.0 ) {

return false;

}

}

return true;

}

void main() {

float as = float(screen_width / 2.0) / float(screen_height);

vec2 Scale = vec2(0.25, as);

vec2 ScaleIn = vec2(2.0 * scaleFactor, 1.0 / as * scaleFactor);

vec2 texCoord = v_texcoord;

vec2 tc = vec2(0);

vec4 color = vec4(0);

if ( texCoord.x < 0.5 ) {

texCoord.x += separation;

texCoord = hmdWarp(leftCenter, texCoord, Scale, ScaleIn );

if ( !stereo_input ) {

texCoord.x *= 2.0;

}

color = texture2D(tex, texCoord);

if ( !validate(texCoord, 0) ) {

color = vec4(0);

}

} else {

texCoord.x -= separation;

texCoord = hmdWarp(rightCenter, texCoord, Scale, ScaleIn);

if ( !stereo_input ) {

texCoord.x = (texCoord.x - 0.5) * 2.0;

}

color = texture2D(tex, texCoord);

if ( !validate(texCoord, 1) ) {

color = vec4(0);

}

}

gl_FragColor = color;

}

 

 

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20141115/2bd2295b/attachment-0001.html>


More information about the gstreamer-devel mailing list