summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVeeresh Kadasani <external.vkadasani@jp.adit-jv.com>2019-07-03 19:50:30 +0900
committerVeeresh Kadasani <external.vkadasani@jp.adit-jv.com>2019-07-03 19:50:30 +0900
commitf89f64d492f34bc8f62b997442317bb447c39df0 (patch)
tree4e1b060d5d19fa5712e7597e76722f75ba14048d
parent46d18bf0029988033f3294242bfb5d2a3a40d322 (diff)
wth-receiver-gst:use waylandsink instead of appsink
Use waylandsink with external display and surface handle Signed-off-by: Veeresh Kadasani <external.vkadasani@jp.adit-jv.com>
-rw-r--r--waltham-receiver/CMakeLists.txt2
-rw-r--r--waltham-receiver/receiver_pipeline_example_general.cfg2
-rw-r--r--waltham-receiver/receiver_pipeline_example_intel.cfg2
-rw-r--r--waltham-receiver/receiver_pipeline_example_rcar.cfg2
-rw-r--r--waltham-receiver/src/wth-receiver-gst.c319
5 files changed, 25 insertions, 302 deletions
diff --git a/waltham-receiver/CMakeLists.txt b/waltham-receiver/CMakeLists.txt
index a31a37a..fc6331e 100644
--- a/waltham-receiver/CMakeLists.txt
+++ b/waltham-receiver/CMakeLists.txt
@@ -18,6 +18,7 @@ pkg_check_modules(IVI-APPLICATION ivi-application REQUIRED)
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
find_library(GST_ALLOCATOR NAMES gstallocators-1.0 PATHs /usr/lib64)
find_library(GST_VIDEO NAMES gstvideo-1.0 PATHs /usr/lib64)
+find_library(GSTREAMER_WAYLANDSINK NAMES gstwayland-1.0 PATHs ${LIBS})
include_directories(
${WAYLAND_CLIENT_INCLUDE_DIR}
@@ -61,6 +62,7 @@ SET(LIBS
${GST_ALLOCATOR}
${GST_VIDEO}
${IVI-APPLICATION_LIBRARIES}
+ ${GSTREAMER_WAYLANDSINK}
)
SET(SRC_FILES
diff --git a/waltham-receiver/receiver_pipeline_example_general.cfg b/waltham-receiver/receiver_pipeline_example_general.cfg
index d5a5136..be4d562 100644
--- a/waltham-receiver/receiver_pipeline_example_general.cfg
+++ b/waltham-receiver/receiver_pipeline_example_general.cfg
@@ -1 +1 @@
- udpsrc port=YOUR_RECIEVER_PORT caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)JPEG,payload=(int)26" ! rtpjpegdepay ! jpegdec ! videoconvert ! video/x-raw,format=RGBA ! appsink name=sink sync=true
+ udpsrc port=YOUR_RECIEVER_PORT caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)JPEG,payload=(int)26" ! rtpjpegdepay ! jpegdec ! waylandsink name=sink sync=true
diff --git a/waltham-receiver/receiver_pipeline_example_intel.cfg b/waltham-receiver/receiver_pipeline_example_intel.cfg
index c1000bf..3872f28 100644
--- a/waltham-receiver/receiver_pipeline_example_intel.cfg
+++ b/waltham-receiver/receiver_pipeline_example_intel.cfg
@@ -1 +1 @@
- udpsrc port=YOUR_RECIEVER_PORT caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264,payload=(int)96" ! rtpjitterbuffer latency=0 ! rtph264depay ! h264parse config-interval=1 disable-passthrough=true ! mfxdecode ! videoconvert ! video/x-raw,format=RGBA ! appsink name=sink sync=true
+ udpsrc port=YOUR_RECIEVER_PORT caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264,payload=(int)96" ! rtpjitterbuffer latency=0 ! rtph264depay ! h264parse config-interval=1 disable-passthrough=true ! mfxdecode ! waylandsink name=sink sync=true
diff --git a/waltham-receiver/receiver_pipeline_example_rcar.cfg b/waltham-receiver/receiver_pipeline_example_rcar.cfg
index 2655016..15fd4ef 100644
--- a/waltham-receiver/receiver_pipeline_example_rcar.cfg
+++ b/waltham-receiver/receiver_pipeline_example_rcar.cfg
@@ -1 +1 @@
- udpsrc port=YOUR_RECIEVER_PORT caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264,payload=(int)96" ! rtpjitterbuffer latency=0 ! rtph264depay ! h264parse config-interval=1 disable-passthrough=true ! omxh264dec no-reorder=true ! appsink name=sink
+ udpsrc port=YOUR_RECIEVER_PORT caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264,payload=(int)96" ! rtpjitterbuffer latency=0 ! rtph264depay ! h264parse config-interval=1 disable-passthrough=true ! omxh264dec no-reorder=true ! waylandsink name=sink
diff --git a/waltham-receiver/src/wth-receiver-gst.c b/waltham-receiver/src/wth-receiver-gst.c
index b151897..92a093c 100644
--- a/waltham-receiver/src/wth-receiver-gst.c
+++ b/waltham-receiver/src/wth-receiver-gst.c
@@ -43,6 +43,8 @@
#include <gst/allocators/gstdmabuf.h>
#include <gst/app/gstappsink.h>
#include <pthread.h>
+#include <gst/wayland/wayland.h>
+#include <gst/video/videooverlay.h>
#include <xf86drm.h>
#include <drm.h>
@@ -52,28 +54,17 @@
#include "os-compatibility.h"
#include "ivi-application-client-protocol.h"
#include "bitmap.h"
-#define MAX_SAMPLE 60
static int running = 1;
-typedef struct client_sample{
- GstBuffer *gstbuffer;
- int dma_fd[2];
-}client_sample;
-
typedef struct _GstAppContext
{
GMainLoop *loop;
GstBus *bus;
GstElement *pipeline;
GstElement *sink;
- client_sample sample_queue[MAX_SAMPLE];
- int front,rear;
struct display *display;
struct window *window;
GstVideoInfo info;
- /*num_sample just for debugging*/
- int num_of_sample_in_queue;
- bool no_dma_buf;
}GstAppContext;
static const gchar *vertex_shader_str =
@@ -330,53 +321,6 @@ add_seat(struct display *display, uint32_t id, uint32_t version)
wth_verbose(" <<< %s \n",__func__);
}
-static int
-drm_fourcc_from_gst_format(GstVideoFormat format)
-{
- switch (format) {
- case GST_VIDEO_FORMAT_RGB16:
- case GST_VIDEO_FORMAT_BGR16:
- return DRM_FORMAT_RGB565;
-
- case GST_VIDEO_FORMAT_RGB:
- case GST_VIDEO_FORMAT_BGR:
- return DRM_FORMAT_BGR888;
-
- case GST_VIDEO_FORMAT_RGBA:
- case GST_VIDEO_FORMAT_RGBx:
- case GST_VIDEO_FORMAT_BGRA:
- case GST_VIDEO_FORMAT_BGRx:
- case GST_VIDEO_FORMAT_ARGB:
- case GST_VIDEO_FORMAT_xRGB:
- case GST_VIDEO_FORMAT_ABGR:
- case GST_VIDEO_FORMAT_xBGR:
- case GST_VIDEO_FORMAT_AYUV:
- return DRM_FORMAT_ARGB8888;
-
- case GST_VIDEO_FORMAT_GRAY8:
- return DRM_FORMAT_R8;
-
- case GST_VIDEO_FORMAT_YUY2:
- case GST_VIDEO_FORMAT_UYVY:
- case GST_VIDEO_FORMAT_GRAY16_LE:
- case GST_VIDEO_FORMAT_GRAY16_BE:
- return DRM_FORMAT_GR88;
-
- case GST_VIDEO_FORMAT_I420:
- case GST_VIDEO_FORMAT_YV12:
- case GST_VIDEO_FORMAT_Y41B:
- case GST_VIDEO_FORMAT_Y42B:
- case GST_VIDEO_FORMAT_Y444:
- return DRM_FORMAT_R8;
-
- case GST_VIDEO_FORMAT_NV12:
- return DRM_FORMAT_NV12;
-
- default:
- return -1;
- }
-}
-
gboolean bus_message(GstBus *bus, GstMessage *message, gpointer p)
{
GstAppContext *gstctx = p;
@@ -427,219 +371,6 @@ gboolean bus_message(GstBus *bus, GstMessage *message, gpointer p)
fprintf(stderr, "-----------------\n");
}
-EGLImageKHR create_eglImage(GstAppContext* gstctx)
-{
- struct display *display = gstctx->display;
- GstVideoMeta *vmeta=gst_buffer_get_video_meta(gstctx->sample_queue[gstctx->front].gstbuffer);
- uint32_t n_planes;
- EGLint attribs[30];
- int fourcc;
- int atti = 0;
-
- fourcc = drm_fourcc_from_gst_format(vmeta->format);
-
- n_planes = GST_VIDEO_INFO_N_PLANES(&(gstctx->info));
-
- attribs[atti++] = EGL_WIDTH;
- attribs[atti++] = vmeta->width;
- attribs[atti++] = EGL_HEIGHT;
- attribs[atti++] = vmeta->height;
- attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
- attribs[atti++] = fourcc;
- /*
- * Offset value for both the planes i.e Y and UV is "0"
- * The omxdec gives the output is 2 different memory blocks,
- * One for Y -> dmafd[0] and other for UV -> dmafd[1]
- */
- if (n_planes > 0) {
- attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
- attribs[atti++] = gstctx->sample_queue[gstctx->front].dma_fd[0];
- attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
- attribs[atti++] = 0;
- attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
- attribs[atti++] = vmeta->stride[0];
- }
-
- if (n_planes > 1) {
- attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
- attribs[atti++] = gstctx->sample_queue[gstctx->front].dma_fd[1];;
- attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
- attribs[atti++] = 0;
- attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
- attribs[atti++] = vmeta->stride[1];
- }
-
- attribs[atti++] = EGL_NONE;
-
- return display->egl.create_image(display->egl.dpy, EGL_NO_CONTEXT,
- EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)NULL,
- attribs);
-}
-
-static int
-redraw(GstAppContext* gstctx)
-{
- struct display *display = gstctx->display;
- GstVideoMeta *vmeta=gst_buffer_get_video_meta(gstctx->sample_queue[gstctx->front].gstbuffer);
- struct window *window = display->window;
- GLfloat vVertices[] = { -1.0f, 1.0f, 1.0f, // Position 0
- 0.0f, 0.0f, // TexCoord 0
- -1.0f, -1.0f, 1.0f, // Position 1
- 0.0f, 1.0f, // TexCoord 1
- 1.0f, -1.0f, 1.0f, // Position 2
- 1.0f, 1.0f, // TexCoord 2
- 1.0f, 1.0f, 1.0f, // Position 3, skewed a bit
- 1.0f, 0.0f // TexCoord 3
- };
-
- GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
- glViewport(0,0,vmeta->width,vmeta->height);
-
- /* Resize Window same as buffer size*/
- if(window->height != vmeta->height && window->width != vmeta->width){
- wl_egl_window_resize(window->native,vmeta->width,vmeta->height,0,0);
- window->height=vmeta->height;
- window->width=vmeta->width;
- }
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
- glUseProgram(display->gl.program_object);
-
- /* Load the vertex position */
- GLint positionLoc = glGetAttribLocation(display->gl.program_object, "a_position");
- glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices);
- /* Load the texture coordinate */
- GLint texCoordLoc = glGetAttribLocation(display->gl.program_object, "a_texCoord");
- glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]);
- glEnableVertexAttribArray(positionLoc);
- glEnableVertexAttribArray(texCoordLoc);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, display->gl.texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-
- if(gstctx->no_dma_buf == false && window->egl_img != NULL )
- {
- display->egl.image_texture_2d(GL_TEXTURE_2D, window->egl_img);
- }
- else
- {
- GstMapInfo map;
- gst_buffer_map(gstctx->sample_queue[gstctx->front].gstbuffer, &map, GST_MAP_READ);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, vmeta->width, vmeta->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)map.data);
- gst_buffer_unmap(gstctx->sample_queue[gstctx->front].gstbuffer, &map);
- }
-
- /* Set the texture sampler to texture unit 0 */
- GLint tex = glGetUniformLocation(display->gl.program_object, "tex");
- glUniform1i(tex, 0);
-
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
-
- eglSwapBuffers(display->egl.dpy, window->egl_surface);
-}
-
-int is_sample_queue_full(GstAppContext *gctx){
- if( (gctx->front == gctx->rear + 1) || (gctx->front == 0 && gctx->rear == MAX_SAMPLE-1))
- return 1;
- return 0;
-}
-
-int is_sample_queue_empty(GstAppContext *gctx)
-{
- if(gctx->front == -1 || gctx->front == gctx->rear)
- return 1;
- return 0;
-}
-
-int sample_enqueue(GstElement *obj, GstAppContext *ctx){
- GstSample *sample=NULL;
- GstBuffer *gstbuffer=NULL;
- GstMemory *mem=NULL;
- int n_mem;
- int i;
- wth_verbose("%s >>> \n",__func__);
- sample = gst_app_sink_pull_sample((GstAppSink*)((void*)obj));
- if(sample == NULL) {
- wth_error("No frame received\n");
- return -1;
- }
- else {
- wth_verbose("Frame received\n");
- }
-
- gstbuffer = gst_sample_get_buffer(sample);
- if(!gstbuffer){
- wth_error("Cannot get buffer from sample\n");
- }
-
- n_mem = gst_buffer_n_memory(gstbuffer);
- if (n_mem < 1) {
- wth_error("Buffer with no mem!\n");
- }
-
- for (i = 0; i < n_mem; i++) {
- /* get dmabuf fd from gstbuffer */
- mem = gst_buffer_peek_memory (gstbuffer, i);
- if (!gst_is_dmabuf_memory(mem)) {
- wth_verbose("Memory is not of dmabuf type \n");
- ctx->no_dma_buf = true;
-
- if(is_sample_queue_full(ctx)){
- wth_error("\nQueue is full\n");
-
- }
-
- else{
- if(ctx->front==-1)
- ctx->front=0;
- ctx->rear=(ctx->rear+1)%MAX_SAMPLE;
- gst_buffer_ref(gstbuffer);
- ctx->sample_queue[ctx->rear].gstbuffer=gstbuffer;
- ctx->num_of_sample_in_queue++;
- }
- gst_sample_unref(sample);
- return 0;
- }
- ctx->sample_queue[ctx->rear].dma_fd[i] = gst_dmabuf_memory_get_fd(mem);
- }
-
- if (ctx->sample_queue[ctx->rear].dma_fd[0] < 0 || ctx->sample_queue[ctx->rear].dma_fd[1] < 0 ) {
- wth_error("dma fd is null \n");
- return -1;
- }
- if(is_sample_queue_full(ctx))
- wth_error("\nQueue is full\n");
- else{
- if(ctx->front==-1)
- ctx->front=0;
- ctx->rear=(ctx->rear+1)%MAX_SAMPLE;
- gst_buffer_ref(gstbuffer);
- ctx->sample_queue[ctx->rear].gstbuffer=gstbuffer;
- ctx->num_of_sample_in_queue++;
- }
- gst_sample_unref(sample);
- wth_verbose("<<< %s \n",__func__);
- return 0;
-}
-
-static GstFlowReturn
-appsink_callback(GstElement *object, gpointer *data)
-{
- wth_verbose("%s >>> \n",__func__);
- GstAppContext *gstctx = (struct gstApplContext *)data;
-
- if(sample_enqueue(object,gstctx)==-1){
- return GST_FLOW_ERROR;
- }
- wth_verbose(" <<< %s \n",__func__);
- return GST_FLOW_OK;
-}
-
/*
* registry callback
*/
@@ -1006,6 +737,11 @@ pad_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
return GST_PAD_PROBE_OK;
}
+ dec->window->width=GST_VIDEO_INFO_WIDTH(&dec->info);
+ dec->window->height=GST_VIDEO_INFO_HEIGHT(&dec->info);
+ gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY (dec->sink),0,0,dec->window->width,dec->window->height);
+ wl_surface_commit(dec->window->surface);
+
wth_verbose(" <<< %s \n",__func__);
return GST_PAD_PROBE_OK;
}
@@ -1033,6 +769,7 @@ wth_receiver_weston_main(struct window *window)
FILE *pFile;
long lSize;
size_t res;
+ GstContext *context;
memset(&gstctx, 0, sizeof(gstctx));
/* Initialization for window creation */
@@ -1045,8 +782,6 @@ wth_receiver_weston_main(struct window *window)
gstctx.display->window = window;
- gstctx.front=-1;
- gstctx.rear=-1;
wth_verbose("display %p\n", gstctx.display);
wth_verbose("display->window %p\n", gstctx.display->window);
wth_verbose("window %p\n", window);
@@ -1101,10 +836,15 @@ wth_receiver_weston_main(struct window *window)
gst_bus_add_watch(gstctx.bus, bus_message, &gstctx);
fprintf(stderr, "registered bus signal\n");
+ /* get sink element */
gstctx.sink = gst_bin_get_by_name(GST_BIN(gstctx.pipeline), "sink");
- g_object_set(G_OBJECT(gstctx.sink), "emit-signals", TRUE, NULL);
- g_signal_connect(gstctx.sink, "new-sample", G_CALLBACK(appsink_callback), &gstctx);
- g_object_set(G_OBJECT(gstctx.sink), "drop", TRUE, "max-buffers",-1, NULL);
+ /* get display context */
+ context = gst_wayland_display_handle_context_new(gstctx.display->display);
+ /* set external display from context to sink */
+ gst_element_set_context(gstctx.sink,context);
+ /* Attach existing surface to sink */
+ gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY (gstctx.sink),window->surface);
+
gst_pad_add_probe(gst_element_get_static_pad(gstctx.sink, "sink"),
GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
pad_probe, &gstctx, NULL);
@@ -1117,30 +857,10 @@ wth_receiver_weston_main(struct window *window)
fprintf(stderr, "rendering part\n");
+ wth_verbose("in render loop\n");
+ while (running && ret != -1)
+ ret=wl_display_dispatch_pending(gstctx.display->display);
- while (running && ret != -1) {
- wth_verbose("in render loop\n");
- ret=wl_display_roundtrip(gstctx.display->display);
- if(is_sample_queue_empty(&gstctx))
- {
- wth_verbose("DEBUG:queue empty ...\n");
- continue;
- }
-
- if(gstctx.no_dma_buf == false)
- {
- wth_verbose("create egl image\n");
- window->egl_img = create_eglImage(&gstctx);
- }
-
- wth_verbose("redraw\n");
- redraw(&gstctx);
- wth_verbose("fin redraw\n");
- gstctx.display->egl.destroy_image(gstctx.display->egl.dpy, window->egl_img);
- gst_buffer_unref(gstctx.sample_queue[gstctx.front].gstbuffer);
- gstctx.front=(gstctx.front+1)%MAX_SAMPLE;
- gstctx.num_of_sample_in_queue--;
- }
wth_verbose("wth_receiver_gst_main exiting\n");
@@ -1149,6 +869,7 @@ wth_receiver_weston_main(struct window *window)
ivi_application_destroy(window->display->ivi_application);
}
+ gst_element_set_state((GstElement*)((void*)gstctx.pipeline), GST_STATE_NULL);
destroy_window(window);
destroy_display(gstctx.display);