gles2.c
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <inttypes.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <gst/gst.h>
#include <gst/base/gstbasesink.h> #include "gles2util.h"
#include "gles2.h"
GLuint *img_ptr;
GLuint img_h;
GLuint img_w;
#if 0
#else
volatile gint gles2_sem;
#endif
bool glt_active;
pthread_t glt;
static void *parent_class;
struct gst_gles2_sink {
GstBaseSink parent;
};
struct gst_gles2_sink_class {
GstBaseSinkClass parent_class;
};
static GstCaps * generate_sink_template(void){
GstStructure *struc;
GstCaps *caps;
fprintf(stderr, "--> %s\n", __func__);
caps = gst_caps_new_empty();
struc = gst_structure_new(
"video/x-raw-rgb",
"width",
GST_TYPE_INT_RANGE, 16, 4096,
"height",
GST_TYPE_INT_RANGE, 16, 4096,
"bpp", G_TYPE_INT, 32,
"depth", G_TYPE_INT, 24,
"endianness", G_TYPE_INT, 4321,
"green_mask", G_TYPE_INT, 16711680,
"blue_mask", G_TYPE_INT, 65280,
"red_mask", G_TYPE_INT, -16777216,
"framerate",
GST_TYPE_FRACTION_RANGE,
0, 1, 30, 1,
NULL);
gst_caps_append_structure(caps, struc);
return caps;
}
static gboolean setup(struct gst_gles2_sink *self, GstCaps *caps){
GstStructure *structure;
int bufsize, width, height;
fprintf(stderr, "--> %s\n", __func__);
structure = gst_caps_get_structure(caps, 0);
gst_structure_get_int(structure, "width", &width);
gst_structure_get_int(structure, "height", &height);
img_h = height;
img_w = width;
bufsize = img_h * img_w * 4;
if (posix_memalign((void **) &img_ptr, 4, bufsize)) {
fprintf(stderr, "Error allocating frame buffers: %d bytes\n", bufsize);
return false;
}
#if 0
#else
gles2_sem = 0;
#endif
glt_active = true; pthread_create(&glt, NULL, gles2_thread, NULL);
return true;
}
static gboolean setcaps(GstBaseSink *base, GstCaps *caps){
struct gst_gles2_sink *self = (struct gst_gles2_sink *)base;
return setup(self, caps);
}
static gboolean start(GstBaseSink *base){
struct gst_gles2_sink *self = (struct gst_gles2_sink *)base;
fprintf(stderr, "--> %s\n", __func__);
if (0 > gles2_start()) {
return false;
}
return true;
}
static gboolean stop(GstBaseSink *base){
struct gst_gles2_sink *self = (struct gst_gles2_sink *)base;
fprintf(stderr, "--> %s\n", __func__);
return true;
}
static GstFlowReturn render(GstBaseSink *base, GstBuffer *buffer){
struct gst_gles2_sink *self = (struct gst_gles2_sink *)base;
fprintf(stderr, "--> %d\n",
GST_BUFFER_SIZE(buffer));
#if 0
#else if
(g_atomic_int_compare_and_exchange(&gles2_sem, 0, 1)) {
memcpy(img_ptr,
GST_BUFFER_DATA(buffer),
GST_BUFFER_SIZE(buffer));
g_atomic_int_set(&gles2_sem, 2);
}
#endif
if (!glt_active)
return GST_FLOW_UNEXPECTED;
return GST_FLOW_OK;
}
static void class_init(void *g_class, void *class_data){
GstBaseSinkClass *base_sink_class;
fprintf(stderr, "--> %s\n", __func__);
base_sink_class = g_class;
parent_class = g_type_class_ref(
GST_GLES2_SINK_TYPE);
base_sink_class->set_caps = setcaps;
base_sink_class->start = start;
base_sink_class->stop = stop;
base_sink_class->render = render;
base_sink_class->preroll = render;
}
static void base_init(void *g_class){
GstElementClass *element_class = g_class;
GstPadTemplate *template;
fprintf(stderr, "--> %s\n", __func__);
gst_element_class_set_details_simple(
element_class,
"Experimental GLES2 plugin",
"Sink/Video",
"Renders video with gles2",
"matsi");
template =
gst_pad_template_new("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
generate_sink_template());
gst_element_class_add_pad_template(
element_class, template);
gst_object_unref(template);
}
GType gst_gles2_sink_get_type(void){
static GType type;
fprintf(stderr, "--> %s\n", __func__);
if (G_UNLIKELY(type == 0)) {
GTypeInfo type_info = {
.class_size = sizeof(struct
gst_gles2_sink_class),
.class_init = class_init,
.base_init = base_init,
.instance_size = sizeof(struct gst_gles2_sink),
};
type = g_type_register_static(
GST_TYPE_BASE_SINK,
"GstGles2Sink", &type_info, 0);
}
return type;
}
static gboolean plugin_init(GstPlugin *plugin){
fprintf(stderr, "--> %s\n", __func__);
if (!gst_element_register(plugin,
"gles2sink",
GST_RANK_SECONDARY,
GST_GLES2_SINK_TYPE))
return false;
return true;
}
GstPluginDesc gst_plugin_desc = {
.major_version = GST_VERSION_MAJOR,
.minor_version = GST_VERSION_MINOR,
.name = "gles2",
.description = (gchar *) "Experimental GLES2 plugin",
.plugin_init = plugin_init,
.version = VERSION,
.license = "LGPL",
.source = "source",
.package = "package",
.origin = "origin",
};
shutil.c
#include <stdlib.h>
#include <stdio.h>
#include "shutil.h"
char *shader_fread(char *name){
char *buffer;
long fsize;
FILE *fh;
buffer = NULL;
fh = fopen(name, "r");
if (fh) {
fseek(fh, 0L, SEEK_END);
fsize = ftell(fh);
rewind(fh);
buffer = (char *) calloc(1, fsize);
if (buffer) {
fread(buffer, fsize, 1, fh);
}
fclose(fh);
} else {
perror("can't open shader file");
}
return buffer;
}