summaryrefslogtreecommitdiffstats
path: root/waltham-transmitter/waltham-renderer/waltham-renderer.c
diff options
context:
space:
mode:
Diffstat (limited to 'waltham-transmitter/waltham-renderer/waltham-renderer.c')
-rw-r--r--waltham-transmitter/waltham-renderer/waltham-renderer.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/waltham-transmitter/waltham-renderer/waltham-renderer.c b/waltham-transmitter/waltham-renderer/waltham-renderer.c
new file mode 100644
index 0000000..d274e3b
--- /dev/null
+++ b/waltham-transmitter/waltham-renderer/waltham-renderer.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2017 Advanced Driver Information Technology GmbH, Advanced Driver Information Technology Corporation, Robert Bosch GmbH, Robert Bosch Car Multimedia GmbH, DENSO Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include <gst/gst.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/allocators/gstdmabuf.h>
+#include <gst/app/gstappsrc.h>
+
+#include "compositor.h"
+
+#include "transmitter_api.h"
+#include "waltham-renderer.h"
+#include "plugin.h"
+
+struct waltham_renderer {
+ struct renderer base;
+};
+
+struct GstAppContext
+{
+ GMainLoop *loop;
+ GstBus *bus;
+ GstElement *pipeline;
+ GstElement *appsrc;
+ GstBuffer *gstbuffer;
+};
+
+gboolean bus_message(GstBus *bus, GstMessage *message, gpointer p)
+{
+ struct GstAppContext *gstctx = p;
+
+ switch( GST_MESSAGE_TYPE(message)) {
+ case GST_MESSAGE_ERROR:
+ {
+ GError *err;
+ gchar *debug;
+
+ gst_message_parse_error(message, &err, &debug);
+ g_print("ERROR: %s\n", err->message);
+
+ g_error_free(err);
+ g_free(debug);
+ g_main_loop_quit(gstctx->loop);
+ break;
+ }
+
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ GstState oldstate, newstate;
+
+ gst_message_parse_state_changed(message, &oldstate, &newstate, NULL);
+ switch (newstate){
+ case GST_STATE_NULL:
+ fprintf(stderr, "%s: state is NULL\n", GST_MESSAGE_SRC_NAME(message));
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "Unhandled message\n");
+ break;
+ }
+}
+
+static int
+gst_pipe_init(struct weston_transmitter_output *output, struct gst_settings *settings)
+{
+ struct GstAppContext *gstctx;
+ gstctx=zalloc(sizeof (*gstctx));
+ if(!gstctx){
+ weston_log("Enable to allocate memory\n");
+ return -1;
+ }
+ GstCaps *caps;
+ int ret = 0;
+ GError *gerror = NULL;
+ FILE * pFile;
+ long lSize;
+ char * pipe = NULL;
+ size_t res;
+
+ /* create gstreamer pipeline */
+ gst_init(NULL, NULL);
+ gstctx->loop = g_main_loop_new(NULL, FALSE);
+
+ /* read pipeline from file */
+ pFile = fopen ( "/etc/xdg/weston/pipeline.cfg" , "rb" );
+ if (pFile==NULL)
+ {
+ weston_log("File open error\n");
+ return -1;
+ }
+
+ /* obtain file size */
+ fseek (pFile , 0 , SEEK_END);
+ lSize = ftell (pFile);
+ rewind (pFile);
+
+ /* allocate memory to contain the whole file: */
+ pipe = (char*) zalloc (sizeof(char)*lSize);
+ if (pipe == NULL)
+ {
+ weston_log("Cannot allocate memory\n");
+ return -1;
+ }
+
+ /* copy the file into the buffer: */
+ res = fread (pipe,1,lSize,pFile);
+ if (res != lSize)
+ {
+ weston_log("File read error\n");
+ return -1;
+ }
+
+ /* close file */
+ fclose (pFile);
+ weston_log("Parsing GST pipeline:%s",pipe);
+ gstctx->pipeline = gst_parse_launch(pipe, &gerror);
+ free(pipe);
+ if(!gstctx->pipeline)
+ weston_log("Could not create gstreamer pipeline.\n");
+
+ gstctx->bus = gst_pipeline_get_bus((GstPipeline*)((void*)gstctx->pipeline));
+ gst_bus_add_watch(gstctx->bus, bus_message, &gstctx);
+
+ gstctx->appsrc = (GstAppSrc*)
+ gst_bin_get_by_name(GST_BIN(gstctx->pipeline), "src");
+ if (!gstctx->appsrc)
+ return -1;
+
+ caps = gst_caps_new_simple("video/x-raw",
+ "format", G_TYPE_STRING, "BGRx",
+ "width", G_TYPE_INT, settings->width,
+ "height", G_TYPE_INT, settings->height,
+ NULL);
+ if (!caps)
+ return -1;
+
+ g_object_set(G_OBJECT(gstctx->appsrc),
+ "caps", caps,
+ "stream-type", 0,
+ "format", GST_FORMAT_TIME,
+ "is-live", TRUE,
+ NULL);
+ gst_caps_unref(caps);
+
+ gst_element_set_state((GstElement*)((void*)gstctx->pipeline), GST_STATE_PLAYING);
+ output->renderer->ctx = gstctx;
+
+ return 0;
+}
+
+static int
+recorder_enable(struct weston_transmitter_output *output)
+{
+ struct gst_settings *settings;
+
+ struct weston_output* base = &output->base;
+ struct weston_compositor *compositor = base->compositor;
+ struct weston_transmitter_remote* remote = output->remote;
+
+ /*
+ * Limitation:
+ * Hard coding bitrate and crop params.
+ * In case of gst-recorder case these were taken from weston.ini
+ */
+ int32_t bitrate = 3000000;
+
+ settings = malloc(sizeof(* settings));
+ settings->ip = remote->addr;
+
+ settings->port = atoi(remote->port);
+
+ settings->bitrate = bitrate;
+ settings->width = output->renderer->surface_width;
+ settings->height = output->renderer->surface_height;
+
+ weston_log("gst-setting are :-->\n");
+ weston_log("ip = %s \n",settings->ip);
+ weston_log("port = %d \n",settings->port);
+ weston_log("bitrate = %d \n",settings->bitrate);
+ weston_log("width = %d \n",settings->width);
+ weston_log("height = %d \n",settings->height);
+
+ gst_pipe_init(output, settings);
+
+ return 0;
+err:
+ weston_log("[gst recorder] %s:"
+ " invalid settings\n",
+ output->base.name);
+ free(settings);
+ return -1;
+}
+
+static void waltham_renderer_repaint_output(struct weston_transmitter_output *output)
+{
+ GstBuffer *gstbuffer;
+ GstMemory *mem;
+ GstAllocator *allocator;
+ int stride = output->renderer->surface_width * 4;
+ gsize offset = 0;
+
+ if(!output->renderer->recorder_enabled)
+ {
+ recorder_enable(&output->base);
+ output->renderer->recorder_enabled = 1;
+ }
+
+ gstbuffer = gst_buffer_new();
+ allocator = gst_dmabuf_allocator_new();
+ mem = gst_dmabuf_allocator_alloc(allocator, output->renderer->dmafd,
+ stride * output->renderer->surface_height);
+ gst_buffer_append_memory(gstbuffer, mem);
+ gst_buffer_add_video_meta_full(gstbuffer,
+ GST_VIDEO_FRAME_FLAG_NONE,
+ GST_VIDEO_FORMAT_BGRx,
+ output->renderer->surface_width,
+ output->renderer->surface_height,
+ 1,
+ &offset,
+ &stride);
+
+ gst_app_src_push_buffer(output->renderer->ctx->appsrc, gstbuffer);
+ gst_object_unref(allocator);
+}
+
+static int
+waltham_renderer_display_create(struct weston_transmitter_output *output)
+{
+ struct waltham_renderer *wth_renderer;
+
+ wth_renderer = zalloc(sizeof *wth_renderer);
+ if (wth_renderer == NULL)
+ return -1;
+ wth_renderer->base.repaint_output = waltham_renderer_repaint_output;
+
+ output->renderer = &wth_renderer->base;
+
+ return 0;
+}
+
+WL_EXPORT struct waltham_renderer_interface waltham_renderer_interface = {
+ .display_create = waltham_renderer_display_create
+};