diff options
Diffstat (limited to 'waltham-transmitter/waltham-renderer/waltham-renderer.c')
-rw-r--r-- | waltham-transmitter/waltham-renderer/waltham-renderer.c | 270 |
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 +}; |