Skip to content

Commit

Permalink
Support rotation only transformation.
Browse files Browse the repository at this point in the history
Minor bug fix in query property.
  • Loading branch information
nickel110 committed Jun 20, 2021
1 parent 8848f06 commit c7db9fe
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 35 deletions.
91 changes: 65 additions & 26 deletions thetauvc/gstthetatransform.c
Expand Up @@ -65,7 +65,9 @@ static void gst_thetatransform_get_property (GObject * object,
static gboolean gst_thetatransform_set_caps(GstGLFilter *, GstCaps *, GstCaps *);
static gboolean gst_thetatransform_start (GstGLBaseFilter *);
static void gst_thetatransform_stop (GstGLBaseFilter *);
static gboolean gst_thetatransform_filter(GstGLFilter *, GstBuffer *, GstBuffer *);
static gboolean gst_thetatransform_filter_texture(GstGLFilter *, GstGLMemory *, GstGLMemory *);

static gboolean draw(gpointer);

enum
Expand All @@ -77,7 +79,8 @@ enum
PROP_TBLFILE_L,
PROP_TBLFILE_R,
PROP_VSHADER_FILE,
PROP_FSHADER_FILE
PROP_FSHADER_FILE,
PROP_DISABLE_STITCH
};


Expand Down Expand Up @@ -109,6 +112,7 @@ gst_thetatransform_class_init (GstThetatransformClass * klass)


gl_filter_class->set_caps = GST_DEBUG_FUNCPTR (gst_thetatransform_set_caps);
gl_filter_class->filter = GST_DEBUG_FUNCPTR (gst_thetatransform_filter);
gl_filter_class->filter_texture = GST_DEBUG_FUNCPTR (gst_thetatransform_filter_texture);

gl_base_filter_class->supported_gl_api = GST_GL_API_OPENGL3 | GST_GL_API_GLES2;
Expand All @@ -117,15 +121,15 @@ gst_thetatransform_class_init (GstThetatransformClass * klass)
g_object_class_install_property(gobject_class, PROP_ROT_X,
g_param_spec_float("rotX", "Rotation X",
"Rotation angle around X-axis in degree by x-y-z intrinsic rotation",
-180.f, 180.f, 0.f, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-180.f, 180.f, 0.f, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
g_object_class_install_property(gobject_class, PROP_ROT_Y,
g_param_spec_float("rotY", "Rotation Y",
"Rotation angle around Y-axis in degree by x-y-z intrinsic rotation",
-180.f, 180.f, -90.f, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-180.f, 180.f, -90.f, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
g_object_class_install_property(gobject_class, PROP_ROT_Z,
g_param_spec_float("rotZ", "Rotation Z",
"Rotation angle around Z-axis in degree by x-y-z intrinsic rotation",
-180.f, 180.f, 0.f, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-180.f, 180.f, 0.f, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
g_object_class_install_property(gobject_class, PROP_TBLFILE_L,
g_param_spec_string("tablefile-l", "Table file L",
"transform table for left image", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
Expand All @@ -138,8 +142,10 @@ gst_thetatransform_class_init (GstThetatransformClass * klass)
g_object_class_install_property(gobject_class, PROP_FSHADER_FILE,
g_param_spec_string("fragment", "fragment shader filename",
"Alternative fragment shader", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));


g_object_class_install_property(gobject_class, PROP_DISABLE_STITCH,
g_param_spec_boolean("disable-stitch", "disable stitching",
"Disable fisheye to equirectanguler transformation", FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
Expand Down Expand Up @@ -190,6 +196,9 @@ gst_thetatransform_set_property (GObject * object, guint property_id,
case PROP_FSHADER_FILE:
thetatransform->fs_file = g_strdup(g_value_get_string(value));
break;
case PROP_DISABLE_STITCH:
thetatransform->skip_stitch = g_value_get_boolean(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
Expand Down Expand Up @@ -226,6 +235,9 @@ gst_thetatransform_get_property (GObject * object, guint property_id,
case PROP_FSHADER_FILE:
g_value_set_string(value, thetatransform->fs_file);
break;
case PROP_DISABLE_STITCH:
g_value_set_boolean(value, thetatransform->skip_stitch);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
Expand Down Expand Up @@ -466,12 +478,35 @@ load_object(GstThetatransform *thetatransform)
thetatransform->vao = vao;
}

static void
rotation(GstThetatransform *thetatransform)
{
float s[3], c[3], *mat;
int i;

for (i = 0; i < 3; i++) {
s[i] = sin(thetatransform->rotation[i] * M_PI / 180.);
c[i] = cos(thetatransform->rotation[i] * M_PI / 180.);
}

mat = thetatransform->mat;
mat[0] = c[1] * c[2];
mat[1] = -c[1] * s[2];
mat[2] = s[1];
mat[3] = s[0] * s[1] * c[2] + c[0] * s[2];
mat[4] = -s[0] * s[1] * s[2] + c[0] * c[2];
mat[5] = -s[0] * c[1];
mat[6] = -c[0] * s[1] * c[2] + s[0] * s[2];
mat[7] = c[0] * s[1] * s[2] + s[0] * c[2];
mat[8] = c[0] * c[1];

}

static gboolean
gst_thetatransform_start (GstGLBaseFilter * filter)
{
GstThetatransform *thetatransform = GST_THETATRANSFORM (filter);
struct vertexElement *ve;
float s[3], c[3], *mat;
int i;
char *vs, *fs;
gboolean ret;
Expand All @@ -495,38 +530,29 @@ gst_thetatransform_start (GstGLBaseFilter * filter)
free(vs);
if (fs != f_code)
free(fs);

if (ret) {
if (!ret)
return ret;

init_object(&thetatransform->vtx);

if (!thetatransform->skip_stitch) {
if (thetatransform->tbl_file_L == NULL || thetatransform->tbl_file_R == NULL) {
GST_ELEMENT_ERROR(thetatransform, RESOURCE, NOT_FOUND,
("Require transform table files"), (NULL));
return FALSE;
}
init_object(&thetatransform->vtx);
ret = init_tbl(thetatransform, thetatransform->tbl_file_L,
thetatransform->tbl_file_R, 960./1080.);
} else {
thetatransform->tbl.x_count=120;
thetatransform->tbl.x_count=61;
thetatransform->tbl.data = (float *)malloc(sizeof(float) * 61 * 120 * 2);

}

for (i = 0; i < 28; i++)
thetatransform->gap[i] = 0.f;

for (i = 0; i < 3; i++) {
s[i] = sin(thetatransform->rotation[i] * M_PI / 180.);
c[i] = cos(thetatransform->rotation[i] * M_PI / 180.);
}

mat = thetatransform->mat;
mat[0] = c[1] * c[2];
mat[1] = -c[1] * s[2];
mat[2] = s[1];
mat[3] = s[0] * s[1] * c[2] + c[0] * s[2];
mat[4] = -s[0] * s[1] * s[2] + c[0] * c[2];
mat[5] = -s[0] * c[1];
mat[6] = -c[0] * s[1] * c[2] + s[0] * s[2];
mat[7] = c[0] * s[1] * s[2] + s[0] * c[2];
mat[8] = c[0] * c[1];

return ret;
}

Expand Down Expand Up @@ -558,6 +584,14 @@ gst_thetatransform_stop (GstGLBaseFilter * filter)
GST_GL_BASE_FILTER_CLASS(parent_class)->gl_stop(filter);
}

static gboolean
gst_thetatransform_filter (GstGLFilter *filter, GstBuffer *inbuf, GstBuffer *outbuf)
{
gst_object_sync_values (GST_OBJECT (filter), GST_BUFFER_PTS(inbuf));

return gst_gl_filter_filter_texture(filter, inbuf, outbuf);
}

static gboolean
gst_thetatransform_filter_texture (GstGLFilter *filter, GstGLMemory *intex, GstGLMemory *outtex)
{
Expand Down Expand Up @@ -596,8 +630,12 @@ draw(gpointer ptr)
free(thetatransform->vtx.indices);
}

rotation(thetatransform);

gl->ActiveTexture(GL_TEXTURE0);
gl->BindTexture(GL_TEXTURE_2D, thetatransform->in_tex->tex_id);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);

gl->ActiveTexture(GL_TEXTURE1);
gl->BindTexture(GL_TEXTURE_2D, thetatransform->tid);
Expand All @@ -606,6 +644,7 @@ draw(gpointer ptr)
gst_gl_shader_set_uniform_1i(shader, "tbl", 1);
gst_gl_shader_set_uniform_matrix_3fv(shader, "rmat", 1, GL_TRUE, thetatransform->mat);
gst_gl_shader_set_uniform_2fv(shader, "gap", 14, thetatransform->gap);
gst_gl_shader_set_uniform_1i(shader, "skip_stitch", thetatransform->skip_stitch);
gl->BindVertexArray(thetatransform->vao);
gl->DrawElements(GL_TRIANGLES, thetatransform->vtx.i_count, GL_UNSIGNED_SHORT, 0);

Expand Down
1 change: 1 addition & 0 deletions thetauvc/gstthetatransform.h
Expand Up @@ -63,6 +63,7 @@ struct _GstThetatransform
GLuint vao, tid;
gchar *tbl_file_L, *tbl_file_R;
gchar *vs_file, *fs_file;
gboolean skip_stitch;
};

struct _GstThetatransformClass
Expand Down
7 changes: 5 additions & 2 deletions thetauvc/gstthetauvcsrc.c
Expand Up @@ -661,8 +661,11 @@ static gboolean
gst_thetauvcsrc_query(GstBaseSrc * src, GstQuery * query)
{
GstThetauvcsrc *thetauvcsrc = GST_THETAUVCSRC(src);
gboolean ret;

GST_DEBUG_OBJECT(thetauvcsrc, "query");
ret = TRUE;

switch (GST_QUERY_TYPE(query)) {
case GST_QUERY_LATENCY:
{
Expand All @@ -681,10 +684,10 @@ gst_thetauvcsrc_query(GstBaseSrc * src, GstQuery * query)
}
break;
default:
GST_BASE_SRC_CLASS(gst_thetauvcsrc_parent_class)->query(src, query);
ret = GST_BASE_SRC_CLASS(gst_thetauvcsrc_parent_class)->query(src, query);
break;
}
return TRUE;
return ret;
}

/* notify subclasses of an event */
Expand Down
50 changes: 43 additions & 7 deletions thetauvc/shader.h
Expand Up @@ -25,6 +25,7 @@ static const gchar *v_code =
"uniform sampler2D tbl; \n"
"uniform mat3 rmat; \n"
"uniform vec2[14] gap; \n"
"uniform bool skip_stitch; \n"
"out vec4 texcoord; \n"
"out float v_y; \n"
"out float va_y; \n"
Expand Down Expand Up @@ -122,11 +123,15 @@ static const gchar *v_code =
" vec2 p, pf, pm; \n"
" ivec2 sz; \n"
" gl_Position = vec4(pv, 0., 1.); \n"
" sz = textureSize(tbl, 0) -ivec2(1,2); \n"
" p = rot_coord(pv, rmat); \n"
" pf = p *vec2(sz); \n"
" pm = modify_tbl(pf, sz); \n"
" texcoord = interpolate_tbl(tbl, pf, pm); \n"
" if (skip_stitch) { \n"
" texcoord = vec4(pv, 0., 1.); \n"
" } else { \n"
" p = rot_coord(pv, rmat); \n"
" sz = textureSize(tbl, 0) -ivec2(1,2); \n"
" pf = p *vec2(sz); \n"
" pm = modify_tbl(pf, sz); \n"
" texcoord = interpolate_tbl(tbl, pf, pm); \n"
" } \n"
" va_y = p.y*2.-1.; \n"
"} \n";

Expand All @@ -139,9 +144,35 @@ static const gchar *f_code =
" \n"
"uniform sampler2D image; \n"
"uniform sampler2D tbl; \n"
"uniform mat3 rmat; \n"
"uniform bool skip_stitch; \n"
" \n"
"out vec4 fc; \n"
" \n"
"#define PI 3.14159265358 \n"
" \n"
"vec2 \n"
"rot_coord(vec2 n_coord, mat3 m) \n"
"{ \n"
" vec2 s_coord; \n"
" vec2 cv, sv; \n"
" vec3 pos; \n"
" float tn, pn; \n"
" \n"
" s_coord = (n_coord + vec2(1., 1.)) * vec2(PI, PI/2.); \n"
" cv = cos(s_coord); \n"
" sv = sin(s_coord); \n"
" pos = m * vec3(sv.y*cv.x, sv.y*sv.x, cv.y); \n"
" \n"
" tn = atan(pos.y, pos.x); \n"
" if (tn < 0.) \n"
" tn += 2.*PI; \n"
" \n"
" pn = acos(pos.z); \n"
" \n"
" return vec2(tn/(2.*PI), pn/PI); \n"
"} \n"
" \n"
"vec4[2] \n"
"pix(vec4 p, sampler2D s) \n"
"{ \n"
Expand Down Expand Up @@ -175,6 +206,11 @@ static const gchar *f_code =
" \n"
" a = alpha(va_y); \n"
" \n"
" v0 = pix(texcoord, image); \n"
" fc = mix(v0[1], v0[0], a); \n"
" if (skip_stitch) { \n"
" vec2 p = rot_coord(texcoord.xy, rmat); \n"
" fc = texture(image, p); \n"
" } else { \n"
" v0 = pix(texcoord, image); \n"
" fc = mix(v0[1], v0[0], a); \n"
" } \n"
"} \n";

0 comments on commit c7db9fe

Please sign in to comment.