diff options
author | Veeresh Kadasani <external.vkadasani@jp.adit-jv.com> | 2019-07-03 19:50:30 +0900 |
---|---|---|
committer | Veeresh Kadasani <external.vkadasani@jp.adit-jv.com> | 2019-07-03 19:50:30 +0900 |
commit | f89f64d492f34bc8f62b997442317bb447c39df0 (patch) | |
tree | 4e1b060d5d19fa5712e7597e76722f75ba14048d | |
parent | 46d18bf0029988033f3294242bfb5d2a3a40d322 (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.txt | 2 | ||||
-rw-r--r-- | waltham-receiver/receiver_pipeline_example_general.cfg | 2 | ||||
-rw-r--r-- | waltham-receiver/receiver_pipeline_example_intel.cfg | 2 | ||||
-rw-r--r-- | waltham-receiver/receiver_pipeline_example_rcar.cfg | 2 | ||||
-rw-r--r-- | waltham-receiver/src/wth-receiver-gst.c | 319 |
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); |