summaryrefslogtreecommitdiff
path: root/sys/pvr2d/gstpvrvideosink.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pvr2d/gstpvrvideosink.c')
-rw-r--r--sys/pvr2d/gstpvrvideosink.c1479
1 files changed, 0 insertions, 1479 deletions
diff --git a/sys/pvr2d/gstpvrvideosink.c b/sys/pvr2d/gstpvrvideosink.c
deleted file mode 100644
index 4e32a8c06..000000000
--- a/sys/pvr2d/gstpvrvideosink.c
+++ /dev/null
@@ -1,1479 +0,0 @@
-/* GStreamer
- *
- * Copyright (C) 2011 Collabora Ltda
- * Copyright (C) 2011 Texas Instruments
- * @author: Luciana Fujii Pontello <luciana.fujii@collabora.co.uk>
- * @author: Edward Hervey <edward@collabora.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/* Object header */
-#include "gstpvrvideosink.h"
-#include "gstpvrbufferpool.h"
-
-#include <gst/video/gstvideosink.h>
-#include <gst/video/videooverlay.h>
-/* Helper functions */
-#include <gst/video/gstvideometa.h>
-
-/* Debugging category */
-#include <gst/gstinfo.h>
-
-#define LINUX
-#include <dri2_ws.h>
-#include <services.h>
-#include <img_defs.h>
-#include <servicesext.h>
-
-#define DEFAULT_QUEUE_SIZE 12
-
-GST_DEBUG_CATEGORY_EXTERN (gst_debug_pvrvideosink);
-#define GST_CAT_DEFAULT gst_debug_pvrvideosink
-
-#define PVR2DMEMINFO_INITIALISE(d, s) \
-{ \
- (d)->hPrivateData = (IMG_VOID *)(s); \
- (d)->hPrivateMapData = (IMG_VOID *)(s->hKernelMemInfo); \
- (d)->ui32DevAddr = (IMG_UINT32) (s)->sDevVAddr.uiAddr; \
- (d)->ui32MemSize = (s)->uAllocSize; \
- (d)->pBase = (s)->pvLinAddr;\
- (d)->ulFlags = (s)->ui32Flags;\
-}
-
-/* end of internal definitions */
-
-static void gst_pvrvideosink_reset (GstPVRVideoSink * pvrvideosink);
-static void gst_pvrvideosink_xwindow_draw_borders (GstPVRVideoSink *
- pvrvideosink, GstXWindow * xwindow, GstVideoRectangle rect);
-static void gst_pvrvideosink_expose (GstVideoOverlay * overlay);
-static void gst_pvrvideosink_xwindow_destroy (GstPVRVideoSink * pvrvideosink,
- GstXWindow * xwindow);
-static void gst_pvrvideosink_dcontext_free (GstDrawContext * dcontext);
-
-static void gst_pvrvideosink_videooverlay_init (GstVideoOverlayInterface *
- iface);
-
-#define gst_pvrvideosink_parent_class parent_class
-G_DEFINE_TYPE_WITH_CODE (GstPVRVideoSink, gst_pvrvideosink, GST_TYPE_VIDEO_SINK,
- G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY,
- gst_pvrvideosink_videooverlay_init));
-
-
-static GstStaticPadTemplate gst_pvrvideosink_sink_template_factory =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("NV12")));
-
-enum
-{
- PROP_0,
- PROP_FORCE_ASPECT_RATIO,
- PROP_WINDOW_WIDTH,
- PROP_WINDOW_HEIGHT
-};
-
-/* ============================================================= */
-/* */
-/* Private Methods */
-/* */
-/* ============================================================= */
-
-/* pvrvideo buffers */
-
-static void
-gst_pvrvideosink_xwindow_update_geometry (GstPVRVideoSink * pvrvideosink)
-{
- XWindowAttributes attr;
- WSEGLError glerror;
- WSEGLDrawableParams source_params;
- PVRSRV_CLIENT_MEM_INFO *client_mem_info;
-
- /* Update the window geometry */
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
- if (G_UNLIKELY (pvrvideosink->xwindow == NULL)) {
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
- return;
- }
- pvrvideosink->redraw_borders = TRUE;
-
- XGetWindowAttributes (pvrvideosink->dcontext->x_display,
- pvrvideosink->xwindow->window, &attr);
-
- pvrvideosink->xwindow->width = attr.width;
- pvrvideosink->xwindow->height = attr.height;
-
- if (!pvrvideosink->have_render_rect) {
- pvrvideosink->render_rect.x = pvrvideosink->render_rect.y = 0;
- pvrvideosink->render_rect.w = attr.width;
- pvrvideosink->render_rect.h = attr.height;
- }
- if (pvrvideosink->dcontext != NULL) {
- glerror =
- pvrvideosink->dcontext->wsegl_table->
- pfnWSEGL_DeleteDrawable (pvrvideosink->dcontext->drawable_handle);
- if (glerror != WSEGL_SUCCESS) {
- GST_ERROR_OBJECT (pvrvideosink, "Error destroying drawable");
- return;
- }
- glerror =
- pvrvideosink->dcontext->wsegl_table->
- pfnWSEGL_CreateWindowDrawable (pvrvideosink->dcontext->display_handle,
- pvrvideosink->dcontext->glconfig,
- &pvrvideosink->dcontext->drawable_handle,
- (NativeWindowType) pvrvideosink->xwindow->window,
- &pvrvideosink->dcontext->rotation);
- if (glerror != WSEGL_SUCCESS) {
- GST_ERROR_OBJECT (pvrvideosink, "Error creating drawable");
- return;
- }
- glerror =
- pvrvideosink->dcontext->wsegl_table->
- pfnWSEGL_GetDrawableParameters (pvrvideosink->dcontext->drawable_handle,
- &source_params, &pvrvideosink->render_params);
- if (glerror != WSEGL_SUCCESS) {
- GST_ERROR_OBJECT (pvrvideosink, "Error getting Drawable params");
- return;
- }
-
- client_mem_info =
- (PVRSRV_CLIENT_MEM_INFO *) pvrvideosink->render_params.hPrivateData;
- PVR2DMEMINFO_INITIALISE (&pvrvideosink->dcontext->dst_mem, client_mem_info);
- }
-
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
-}
-
-/* This function handles XEvents that might be in the queue. It generates
- GstEvent that will be sent upstream in the pipeline to handle interactivity
- and navigation. It will also listen for configure events on the window to
- trigger caps renegotiation so on the fly software scaling can work. */
-static void
-gst_pvrvideosink_handle_xevents (GstPVRVideoSink * pvrvideosink)
-{
- XEvent e;
- gboolean exposed = FALSE;
- gboolean configured = FALSE;
-
- g_mutex_lock (pvrvideosink->flow_lock);
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
-
- /* Handle Expose */
- while (XCheckWindowEvent (pvrvideosink->dcontext->x_display,
- pvrvideosink->xwindow->window, ExposureMask | StructureNotifyMask,
- &e)) {
- switch (e.type) {
- case Expose:
- exposed = TRUE;
- break;
- case ConfigureNotify:
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
- gst_pvrvideosink_xwindow_update_geometry (pvrvideosink);
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
- configured = TRUE;
- break;
- default:
- break;
- }
- }
-
- if (exposed || configured) {
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
- g_mutex_unlock (pvrvideosink->flow_lock);
-
- gst_pvrvideosink_expose (GST_VIDEO_OVERLAY (pvrvideosink));
-
- g_mutex_lock (pvrvideosink->flow_lock);
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
- }
-
- /* Handle Display events */
- while (XPending (pvrvideosink->dcontext->x_display)) {
- XNextEvent (pvrvideosink->dcontext->x_display, &e);
-
- switch (e.type) {
- case ClientMessage:{
- Atom wm_delete;
-
- wm_delete = XInternAtom (pvrvideosink->dcontext->x_display,
- "WM_DELETE_WINDOW", True);
- if (wm_delete != None && wm_delete == (Atom) e.xclient.data.l[0]) {
- /* Handle window deletion by posting an error on the bus */
- GST_ELEMENT_ERROR (pvrvideosink, RESOURCE, NOT_FOUND,
- ("Output window was closed"), (NULL));
-
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
- gst_pvrvideosink_xwindow_destroy (pvrvideosink,
- pvrvideosink->xwindow);
- pvrvideosink->xwindow = NULL;
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
- }
- break;
- }
- default:
- break;
- }
- }
-
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
- g_mutex_unlock (pvrvideosink->flow_lock);
-}
-
-static gpointer
-gst_pvrvideosink_event_thread (GstPVRVideoSink * pvrvideosink)
-{
- GST_OBJECT_LOCK (pvrvideosink);
- while (pvrvideosink->running) {
- GST_OBJECT_UNLOCK (pvrvideosink);
-
- if (pvrvideosink->xwindow) {
- gst_pvrvideosink_handle_xevents (pvrvideosink);
- }
- g_usleep (G_USEC_PER_SEC / 20);
-
- GST_OBJECT_LOCK (pvrvideosink);
- }
- GST_OBJECT_UNLOCK (pvrvideosink);
-
- return NULL;
-}
-
-static void
-gst_pvrvideosink_manage_event_thread (GstPVRVideoSink * pvrvideosink)
-{
- GThread *thread = NULL;
-
- /* don't start the thread too early */
- if (pvrvideosink->dcontext == NULL) {
- return;
- }
-
- GST_OBJECT_LOCK (pvrvideosink);
- if (!pvrvideosink->event_thread) {
- /* Setup our event listening thread */
- GST_DEBUG_OBJECT (pvrvideosink, "run xevent thread");
- pvrvideosink->running = TRUE;
- pvrvideosink->event_thread = g_thread_create (
- (GThreadFunc) gst_pvrvideosink_event_thread, pvrvideosink, TRUE, NULL);
- }
- GST_OBJECT_UNLOCK (pvrvideosink);
-
- /* Wait for our event thread to finish */
- if (thread)
- g_thread_join (thread);
-}
-
-
-static GstDrawContext *
-gst_pvrvideosink_get_dcontext (GstPVRVideoSink * pvrvideosink)
-{
- GstDrawContext *dcontext = NULL;
- PVR2DERROR pvr_error;
- gint refresh_rate;
- DRI2WSDisplay *displayImpl;
- WSEGLError glerror;
- const WSEGLCaps *glcaps;
-
- GST_DEBUG_OBJECT (pvrvideosink, "Getting draw context");
-
- dcontext = g_new0 (GstDrawContext, 1);
- dcontext->x_lock = g_mutex_new ();
-
- dcontext->p_blt_info = g_new0 (PVR2D_3DBLT_EXT, 1);
- if (!dcontext->p_blt_info)
- goto p_blt_info_alloc_failed;
-
- dcontext->p_blt2d_info = g_new0 (PVR2DBLTINFO, 1);
-
- GST_LOG_OBJECT (pvrvideosink, "Opening X Display");
- dcontext->x_display = XOpenDisplay (NULL);
-
- if (dcontext->x_display == NULL)
- goto fail_open_display;
-
- GST_LOG_OBJECT (pvrvideosink, "WSEGL_GetFunctionTablePointer()");
- dcontext->wsegl_table = WSEGL_GetFunctionTablePointer ();
-
- GST_LOG_OBJECT (pvrvideosink, "pfnWSEGL_IsDisplayValid()");
- glerror = dcontext->wsegl_table->pfnWSEGL_IsDisplayValid (
- (NativeDisplayType) dcontext->x_display);
-
- if (glerror != WSEGL_SUCCESS)
- goto display_invalid;
-
- GST_LOG_OBJECT (pvrvideosink, "pfnWSEGL_InitialiseDisplay()");
-
- glerror = dcontext->wsegl_table->pfnWSEGL_InitialiseDisplay (
- (NativeDisplayType) dcontext->x_display, &dcontext->display_handle,
- &glcaps, &dcontext->glconfig);
- if (glerror != WSEGL_SUCCESS)
- goto display_init_failed;
-
- displayImpl = (DRI2WSDisplay *) dcontext->display_handle;
- dcontext->pvr_context = displayImpl->hContext;
-
- GST_LOG_OBJECT (pvrvideosink, "PVR2DGetScreenMode()");
-
- pvr_error = PVR2DGetScreenMode (dcontext->pvr_context,
- &dcontext->display_format, &dcontext->display_width,
- &dcontext->display_height, &dcontext->stride, &refresh_rate);
- if (pvr_error != PVR2D_OK)
- goto screen_mode_failed;
-
- GST_DEBUG_OBJECT (pvrvideosink,
- "Got format:%d, width:%d, height:%d, stride:%d, refresh_rate:%d",
- dcontext->display_format, dcontext->display_width,
- dcontext->display_height, dcontext->stride, refresh_rate);
-
- dcontext->screen_num = DefaultScreen (dcontext->x_display);
- dcontext->black = XBlackPixel (dcontext->x_display, dcontext->screen_num);
-
- GST_DEBUG_OBJECT (pvrvideosink, "Returning dcontext %p", dcontext);
-
- return dcontext;
-
-p_blt_info_alloc_failed:
- {
- GST_ERROR_OBJECT (pvrvideosink, "Alloc of bltinfo failed");
- gst_pvrvideosink_dcontext_free (dcontext);
- return NULL;
- }
-
-fail_open_display:
- {
- GST_ERROR_OBJECT (pvrvideosink, "Failed to open X Display");
- gst_pvrvideosink_dcontext_free (dcontext);
- return NULL;
- }
-
-display_invalid:
- {
- GST_ERROR_OBJECT (pvrvideosink, "Display is not valid (glerror:%d)",
- glerror);
- gst_pvrvideosink_dcontext_free (dcontext);
- return NULL;
- }
-
-display_init_failed:
- {
- GST_ERROR_OBJECT (pvrvideosink, "Error initializing display (glerror:%d)",
- glerror);
- gst_pvrvideosink_dcontext_free (dcontext);
- return NULL;
- }
-
-screen_mode_failed:
- {
- GST_ERROR_OBJECT (pvrvideosink, "Failed to get screen mode. error : %s",
- gst_pvr2d_error_get_string (pvr_error));
- gst_pvrvideosink_dcontext_free (dcontext);
- return NULL;
- }
-}
-
-static void
-gst_pvrvideosink_xwindow_set_title (GstPVRVideoSink * pvrvideosink,
- GstXWindow * xwindow, const gchar * media_title)
-{
- if (media_title) {
- g_free (pvrvideosink->media_title);
- pvrvideosink->media_title = g_strdup (media_title);
- }
- if (xwindow) {
- /* we have a window */
- if (xwindow->internal) {
- XTextProperty xproperty;
- const gchar *app_name;
- const gchar *title = NULL;
- gchar *title_mem = NULL;
-
- /* set application name as a title */
- app_name = g_get_application_name ();
-
- if (app_name && pvrvideosink->media_title) {
- title = title_mem = g_strconcat (pvrvideosink->media_title, " : ",
- app_name, NULL);
- } else if (app_name) {
- title = app_name;
- } else if (pvrvideosink->media_title) {
- title = pvrvideosink->media_title;
- }
-
- if (title) {
- if ((XStringListToTextProperty (((char **) &title), 1,
- &xproperty)) != 0) {
- XSetWMName (pvrvideosink->dcontext->x_display, xwindow->window,
- &xproperty);
- XFree (xproperty.value);
- }
-
- g_free (title_mem);
- }
- }
- }
-}
-
-static GstXWindow *
-gst_pvrvideosink_create_window (GstPVRVideoSink * pvrvideosink, gint width,
- gint height)
-{
- WSEGLError glerror;
- WSEGLDrawableParams source_params;
- Window root;
- GstXWindow *xwindow;
- GstDrawContext *dcontext;
- XGCValues values;
- Atom wm_delete;
- PVRSRV_CLIENT_MEM_INFO *client_mem_info;
-
- GST_DEBUG_OBJECT (pvrvideosink, "begin");
-
- dcontext = pvrvideosink->dcontext;
- xwindow = g_new0 (GstXWindow, 1);
-
- xwindow->internal = TRUE;
- pvrvideosink->render_rect.x = pvrvideosink->render_rect.y = 0;
- pvrvideosink->render_rect.w = width;
- pvrvideosink->render_rect.h = height;
- xwindow->width = width;
- xwindow->height = height;
- xwindow->internal = TRUE;
-
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
-
- root = DefaultRootWindow (dcontext->x_display);
- xwindow->window = XCreateSimpleWindow (dcontext->x_display, root, 0, 0,
- width, height, 2, 2, pvrvideosink->dcontext->black);
- XSelectInput (dcontext->x_display, xwindow->window,
- ExposureMask | StructureNotifyMask);
-
- /* Tell the window manager we'd like delete client messages instead of
- * being killed */
- wm_delete = XInternAtom (pvrvideosink->dcontext->x_display,
- "WM_DELETE_WINDOW", True);
- if (wm_delete != None) {
- (void) XSetWMProtocols (pvrvideosink->dcontext->x_display, xwindow->window,
- &wm_delete, 1);
- }
-
- XMapWindow (dcontext->x_display, xwindow->window);
-
- /* We have to do that to prevent X from redrawing the background on
- * ConfigureNotify. This takes away flickering of video when resizing. */
- XSetWindowBackgroundPixmap (pvrvideosink->dcontext->x_display,
- xwindow->window, None);
-
- gst_pvrvideosink_xwindow_set_title (pvrvideosink, xwindow, NULL);
-
- xwindow->gc = XCreateGC (pvrvideosink->dcontext->x_display,
- xwindow->window, 0, &values);
-
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
-
- glerror =
- dcontext->wsegl_table->
- pfnWSEGL_CreateWindowDrawable (dcontext->display_handle,
- dcontext->glconfig, &(dcontext->drawable_handle),
- (NativeWindowType) xwindow->window, &(dcontext->rotation));
-
- if (glerror != WSEGL_SUCCESS) {
- GST_ERROR_OBJECT (pvrvideosink, "Error creating drawable");
- return NULL;
- }
- glerror =
- dcontext->wsegl_table->
- pfnWSEGL_GetDrawableParameters (dcontext->drawable_handle, &source_params,
- &pvrvideosink->render_params);
- client_mem_info =
- (PVRSRV_CLIENT_MEM_INFO *) pvrvideosink->render_params.hPrivateData;
- PVR2DMEMINFO_INITIALISE (&dcontext->dst_mem, client_mem_info);
-
- GST_DEBUG_OBJECT (pvrvideosink, "end");
- return xwindow;
-}
-
-static void
-gst_pvrvideosink_blit (GstPVRVideoSink * pvrvideosink, GstBuffer * buffer)
-{
- PVR2DERROR pvr_error;
- GstDrawContext *dcontext = pvrvideosink->dcontext;
- gint video_width;
- gint video_height;
- gboolean draw_border = FALSE;
- PPVR2D_3DBLT_EXT p_blt_3d;
- PVR2DMEMINFO *src_mem;
- PVR2DFORMAT pvr_format;
- GstVideoRectangle result;
- GstPVRMeta *meta;
- GstVideoCropMeta *cropmeta;
-
- GST_DEBUG_OBJECT (pvrvideosink, "buffer %p", buffer);
-
- pvr_format =
- GST_VIDEO_INFO_FORMAT (&pvrvideosink->info) ==
- GST_VIDEO_FORMAT_NV12 ? PVR2D_YUV420_2PLANE : PVR2D_ARGB8888;
-
- g_mutex_lock (pvrvideosink->flow_lock);
- if (buffer == NULL)
- buffer = pvrvideosink->current_buffer;
-
- if (buffer == NULL)
- goto done;
-
- meta = gst_buffer_get_pvr_meta (buffer);
- if (G_UNLIKELY (meta == NULL))
- goto no_pvr_meta;
-
- src_mem = meta->src_mem;
- p_blt_3d = dcontext->p_blt_info;
-
- video_width = GST_VIDEO_SINK_WIDTH (pvrvideosink);
- video_height = GST_VIDEO_SINK_HEIGHT (pvrvideosink);
-
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
-
- /* Draw borders when displaying the first frame. After this
- draw borders only on expose event or after a size change. */
- if (!(pvrvideosink->current_buffer) || pvrvideosink->redraw_borders) {
- draw_border = TRUE;
- }
-
- /* Store a reference to the last image we put, lose the previous one */
- if (buffer && pvrvideosink->current_buffer != buffer) {
- if (pvrvideosink->current_buffer) {
- GST_LOG_OBJECT (pvrvideosink, "unreffing %p",
- pvrvideosink->current_buffer);
- gst_buffer_unref (GST_BUFFER_CAST (pvrvideosink->current_buffer));
- }
- GST_LOG_OBJECT (pvrvideosink, "reffing %p as our current buffer", buffer);
- pvrvideosink->current_buffer = gst_buffer_ref (buffer);
- }
-
- if (pvrvideosink->keep_aspect) {
- GstVideoRectangle src = { 0, };
- GstVideoRectangle dst = { 0, };
-
- src.w = GST_VIDEO_SINK_WIDTH (pvrvideosink);
- src.h = GST_VIDEO_SINK_HEIGHT (pvrvideosink);
- dst.w = pvrvideosink->render_rect.w;
- dst.h = pvrvideosink->render_rect.h;
- gst_video_sink_center_rect (src, dst, &result, TRUE);
- result.x += pvrvideosink->render_rect.x;
- result.y += pvrvideosink->render_rect.y;
- } else {
- memcpy (&result, &pvrvideosink->render_rect, sizeof (GstVideoRectangle));
- }
-
- p_blt_3d->sDst.pSurfMemInfo = &dcontext->dst_mem;
- p_blt_3d->sDst.SurfOffset = 0;
- p_blt_3d->sDst.Stride = 4 * pvrvideosink->render_params.ui32Stride;
- p_blt_3d->sDst.Format = PVR2D_ARGB8888;
- p_blt_3d->sDst.SurfWidth = pvrvideosink->xwindow->width;
- p_blt_3d->sDst.SurfHeight = pvrvideosink->xwindow->height;
-
- p_blt_3d->rcDest.left = result.x;
- p_blt_3d->rcDest.top = result.y;
- p_blt_3d->rcDest.right = result.w + result.x;
- p_blt_3d->rcDest.bottom = result.h + result.y;
-
- p_blt_3d->sSrc.pSurfMemInfo = src_mem;
- p_blt_3d->sSrc.SurfOffset = 0;
- p_blt_3d->sSrc.Stride = GST_VIDEO_INFO_COMP_STRIDE (&pvrvideosink->info, 0);
- p_blt_3d->sSrc.Format = pvr_format;
- p_blt_3d->sSrc.SurfWidth = video_width;
- p_blt_3d->sSrc.SurfHeight = video_height;
-
- /* If buffer has crop information, use that */
- if ((cropmeta = gst_buffer_get_video_crop_meta (buffer))) {
- p_blt_3d->rcSource.left = cropmeta->x;
- p_blt_3d->rcSource.top = cropmeta->y;
- p_blt_3d->rcSource.right = cropmeta->x + cropmeta->width;
- p_blt_3d->rcSource.bottom = cropmeta->y + cropmeta->height;
- } else {
- p_blt_3d->rcSource.left = 0;
- p_blt_3d->rcSource.top = 0;
- p_blt_3d->rcSource.right = video_width;
- p_blt_3d->rcSource.bottom = video_height;
- }
-
- p_blt_3d->hUseCode = NULL;
-
- if (GST_VIDEO_INFO_FORMAT (&pvrvideosink->info) == GST_VIDEO_FORMAT_NV12)
- p_blt_3d->bDisableDestInput = TRUE;
- else
- /* blit fails for RGB without this... not sure why yet... */
- p_blt_3d->bDisableDestInput = FALSE;
-
- GST_DEBUG_OBJECT (pvrvideosink, "about to blit");
-
- pvr_error = PVR2DBlt3DExt (pvrvideosink->dcontext->pvr_context,
- dcontext->p_blt_info);
-
- if (pvr_error != PVR2D_OK) {
- GST_ERROR_OBJECT (pvrvideosink, "Failed to blit. Error : %s",
- gst_pvr2d_error_get_string (pvr_error));
- goto done;
- }
- dcontext->wsegl_table->pfnWSEGL_SwapDrawable (dcontext->drawable_handle, 1);
-
- if (draw_border) {
- gst_pvrvideosink_xwindow_draw_borders (pvrvideosink, pvrvideosink->xwindow,
- result);
- pvrvideosink->redraw_borders = FALSE;
- }
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
-
-done:
- GST_DEBUG_OBJECT (pvrvideosink, "end");
- g_mutex_unlock (pvrvideosink->flow_lock);
- return;
-
- /* Error cases */
-
-no_pvr_meta:
- {
- g_mutex_unlock (pvrvideosink->flow_lock);
- GST_ERROR_OBJECT (pvrvideosink, "Got a buffer without GstPVRMeta");
- return;
- }
-}
-
-static void
-gst_pvrvideosink_destroy_drawable (GstPVRVideoSink * pvrvideosink)
-{
- GST_DEBUG_OBJECT (pvrvideosink, "dcontext : %p", pvrvideosink->dcontext);
-
- if (pvrvideosink->dcontext != NULL) {
- if (pvrvideosink->dcontext->drawable_handle) {
- GST_DEBUG_OBJECT (pvrvideosink, "Deleting Drawable (drawable_handle:%p)",
- pvrvideosink->dcontext->drawable_handle);
- pvrvideosink->dcontext->wsegl_table->
- pfnWSEGL_DeleteDrawable (pvrvideosink->dcontext->drawable_handle);
- }
-
- GST_DEBUG_OBJECT (pvrvideosink, "Closing display (display_handle:%p)",
- pvrvideosink->dcontext->display_handle);
- pvrvideosink->dcontext->wsegl_table->
- pfnWSEGL_CloseDisplay (pvrvideosink->dcontext->display_handle);
- }
-}
-
-/* We are called with the x_lock taken */
-static void
-gst_pvrvideosink_pvrfill_rectangle (GstPVRVideoSink * pvrvideosink,
- GstVideoRectangle rect)
-{
- PVR2DERROR pvr_error;
- PPVR2DBLTINFO p_blt2d_info = 0;
- GstDrawContext *dcontext = pvrvideosink->dcontext;
-
- GST_DEBUG_OBJECT (pvrvideosink, "begin");
-
- p_blt2d_info = dcontext->p_blt2d_info;
-
- p_blt2d_info->pDstMemInfo = &dcontext->dst_mem;
- p_blt2d_info->BlitFlags = PVR2D_BLIT_DISABLE_ALL;
- p_blt2d_info->DstOffset = 0;
- p_blt2d_info->CopyCode = PVR2DROPclear;
- p_blt2d_info->DstStride = 4 * pvrvideosink->render_params.ui32Stride;
- p_blt2d_info->DstFormat = PVR2D_ARGB8888;
- p_blt2d_info->DstSurfWidth = pvrvideosink->xwindow->width;
- p_blt2d_info->DstSurfHeight = pvrvideosink->xwindow->height;
- p_blt2d_info->DstX = rect.x;
- p_blt2d_info->DstY = rect.y;
- p_blt2d_info->DSizeX = rect.w;
- p_blt2d_info->DSizeY = rect.h;
-
- pvr_error = PVR2DBlt (pvrvideosink->dcontext->pvr_context, p_blt2d_info);
-
- if (pvr_error != PVR2D_OK) {
- GST_ERROR_OBJECT (pvrvideosink, "Failed to blit. Error : %s",
- gst_pvr2d_error_get_string (pvr_error));
- goto done;
- }
- dcontext->wsegl_table->pfnWSEGL_SwapDrawable (dcontext->drawable_handle, 1);
-
-done:
- GST_DEBUG_OBJECT (pvrvideosink, "end");
-}
-
-/* We are called with the x_lock taken */
-static void
-gst_pvrvideosink_xwindow_draw_borders (GstPVRVideoSink * pvrvideosink,
- GstXWindow * xwindow, GstVideoRectangle rect)
-{
- gint t1, t2;
- GstVideoRectangle result;
-
- g_return_if_fail (GST_IS_PVRVIDEOSINK (pvrvideosink));
- g_return_if_fail (xwindow != NULL);
-
- /* Left border */
- result.x = pvrvideosink->render_rect.x;
- result.y = pvrvideosink->render_rect.y;
- result.w = rect.x - pvrvideosink->render_rect.x;
- result.h = pvrvideosink->render_rect.h;
- if (rect.x > pvrvideosink->render_rect.x)
- gst_pvrvideosink_pvrfill_rectangle (pvrvideosink, result);
-
- /* Right border */
- t1 = rect.x + rect.w;
- t2 = pvrvideosink->render_rect.x + pvrvideosink->render_rect.w;
- result.x = t1;
- result.y = pvrvideosink->render_rect.y;
- result.w = t2 - t1;
- result.h = pvrvideosink->render_rect.h;
- if (t1 < t2)
- gst_pvrvideosink_pvrfill_rectangle (pvrvideosink, result);
-
- /* Top border */
- result.x = pvrvideosink->render_rect.x;
- result.y = pvrvideosink->render_rect.y;
- result.w = pvrvideosink->render_rect.w;
- result.h = rect.y - pvrvideosink->render_rect.y;
- if (rect.y > pvrvideosink->render_rect.y)
- gst_pvrvideosink_pvrfill_rectangle (pvrvideosink, result);
-
- /* Bottom border */
- t1 = rect.y + rect.h;
- t2 = pvrvideosink->render_rect.y + pvrvideosink->render_rect.h;
- result.x = pvrvideosink->render_rect.x;
- result.y = t1;
- result.w = pvrvideosink->render_rect.w;
- result.h = t2 - t1;
- if (t1 < t2)
- gst_pvrvideosink_pvrfill_rectangle (pvrvideosink, result);
-}
-
-/* Element stuff */
-
-static gboolean
-gst_pvrvideosink_setcaps (GstBaseSink * bsink, GstCaps * caps)
-{
- GstPVRVideoSink *pvrvideosink;
- GstVideoInfo info;
- GstStructure *structure;
- GstBufferPool *oldpool, *newpool;
-
- pvrvideosink = GST_PVRVIDEOSINK (bsink);
-
- GST_DEBUG_OBJECT (pvrvideosink,
- "sinkconnect possible caps with given caps %" GST_PTR_FORMAT, caps);
-
- if (!gst_video_info_from_caps (&info, caps))
- goto invalid_format;
-
- GST_VIDEO_SINK_WIDTH (pvrvideosink) = info.width;
- GST_VIDEO_SINK_HEIGHT (pvrvideosink) = info.height;
-
- /* Notify application to set xwindow id now */
- g_mutex_lock (pvrvideosink->flow_lock);
- if (!pvrvideosink->xwindow) {
- g_mutex_unlock (pvrvideosink->flow_lock);
- gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (pvrvideosink));
- } else {
- g_mutex_unlock (pvrvideosink->flow_lock);
- }
-
- g_mutex_lock (pvrvideosink->flow_lock);
- if (!pvrvideosink->xwindow)
- pvrvideosink->xwindow = gst_pvrvideosink_create_window (pvrvideosink,
- GST_VIDEO_SINK_WIDTH (pvrvideosink),
- GST_VIDEO_SINK_HEIGHT (pvrvideosink));
- g_mutex_unlock (pvrvideosink->flow_lock);
-
- pvrvideosink->info = info;
-
- /* After a resize, we want to redraw the borders in case the new frame size
- * doesn't cover the same area */
- pvrvideosink->redraw_borders = TRUE;
-
- /* create a new pool for the new configuration */
- newpool = gst_pvr_buffer_pool_new (GST_ELEMENT_CAST (pvrvideosink));
-
- /* PVR needs at least 3 buffers */
- structure = gst_buffer_pool_get_config (newpool);
- gst_buffer_pool_config_set (structure, caps, GST_VIDEO_INFO_SIZE (&info), 3,
- 0, 0, 15);
- if (!gst_buffer_pool_set_config (newpool, structure))
- goto config_failed;
-
- oldpool = pvrvideosink->pool;
- pvrvideosink->pool = newpool;
- g_mutex_unlock (pvrvideosink->flow_lock);
-
- /* unref the old sink */
- if (oldpool) {
- /* we don't deactivate, some elements might still be using it, it will
- * be deactivated when the last ref is gone */
- gst_object_unref (oldpool);
- }
-
- return TRUE;
-
-config_failed:
- {
- GST_ERROR_OBJECT (pvrvideosink, "failed to set config.");
- g_mutex_unlock (pvrvideosink->flow_lock);
- return FALSE;
- }
-
-invalid_format:
- {
- GST_DEBUG_OBJECT (pvrvideosink,
- "Could not locate image format from caps %" GST_PTR_FORMAT, caps);
- return FALSE;
- }
-}
-
-static GstCaps *
-gst_pvrvideosink_getcaps (GstBaseSink * bsink, GstCaps * filter)
-{
- GstPVRVideoSink *pvrvideosink;
- GstCaps *caps;
-
- GST_DEBUG_OBJECT (bsink, "filter:%" GST_PTR_FORMAT, filter);
-
- pvrvideosink = GST_PVRVIDEOSINK (bsink);
-
- /* FIXME : If we have curently configured caps, we should return those
- * intersected with the filter*/
-
- caps = gst_pad_get_pad_template_caps (GST_BASE_SINK (pvrvideosink)->sinkpad);
- if (filter) {
- GstCaps *intersection;
-
- intersection =
- gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref (caps);
- caps = intersection;
- }
-
- GST_DEBUG_OBJECT (bsink, "Returning %" GST_PTR_FORMAT, caps);
-
- return caps;
-}
-
-static GstStateChangeReturn
-gst_pvrvideosink_change_state (GstElement * element, GstStateChange transition)
-{
- GstPVRVideoSink *pvrvideosink;
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
- GstDrawContext *dcontext;
-
- pvrvideosink = GST_PVRVIDEOSINK (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (pvrvideosink->dcontext == NULL) {
- dcontext = gst_pvrvideosink_get_dcontext (pvrvideosink);
- if (dcontext == NULL)
- return GST_STATE_CHANGE_FAILURE;
- GST_OBJECT_LOCK (pvrvideosink);
- pvrvideosink->dcontext = dcontext;
- GST_OBJECT_UNLOCK (pvrvideosink);
- }
- gst_pvrvideosink_manage_event_thread (pvrvideosink);
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- GST_VIDEO_SINK_WIDTH (pvrvideosink) = 0;
- GST_VIDEO_SINK_HEIGHT (pvrvideosink) = 0;
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- gst_pvrvideosink_reset (pvrvideosink);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static void
-gst_pvrvideosink_get_times (GstBaseSink * bsink, GstBuffer * buf,
- GstClockTime * start, GstClockTime * end)
-{
- GstPVRVideoSink *pvrvideosink;
-
- pvrvideosink = GST_PVRVIDEOSINK (bsink);
-
- if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
- *start = GST_BUFFER_TIMESTAMP (buf);
- if (GST_BUFFER_DURATION_IS_VALID (buf)) {
- *end = *start + GST_BUFFER_DURATION (buf);
- } else {
- gint fps_n, fps_d;
- fps_n = GST_VIDEO_INFO_FPS_N (&pvrvideosink->info);
- fps_d = GST_VIDEO_INFO_FPS_D (&pvrvideosink->info);
- if (fps_n > 0) {
- *end = *start + gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
- }
- }
- }
-}
-
-static GstFlowReturn
-gst_pvrvideosink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
-{
- GstPVRVideoSink *pvrvideosink = GST_PVRVIDEOSINK (vsink);
- GstPVRMeta *meta;
-
- GST_DEBUG_OBJECT (pvrvideosink, "render buffer: %p", buf);
-
- meta = gst_buffer_get_pvr_meta (buf);
-
- if (G_UNLIKELY (meta == NULL)) {
- meta = gst_buffer_add_pvr_meta (buf, GST_ELEMENT_CAST (pvrvideosink));
- if (meta == NULL)
- goto meta_failure;
- }
-
- gst_pvrvideosink_blit (pvrvideosink, buf);
-
- return GST_FLOW_OK;
-
-meta_failure:
- {
- GST_WARNING_OBJECT (pvrvideosink, "Failed to map incoming buffer");
- return GST_FLOW_ERROR;
- }
-}
-
-static gboolean
-gst_pvrvideosink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
-{
- GstPVRVideoSink *pvrvideosink = (GstPVRVideoSink *) bsink;
- GstBufferPool *pool;
- GstStructure *config;
- GstCaps *caps;
- guint size;
- gboolean need_pool;
-
- gst_query_parse_allocation (query, &caps, &need_pool);
-
- if (caps == NULL)
- goto no_caps;
-
- g_mutex_lock (pvrvideosink->flow_lock);
- if ((pool = pvrvideosink->pool))
- gst_object_ref (pool);
- g_mutex_unlock (pvrvideosink->flow_lock);
-
- if (pool != NULL) {
- const GstCaps *pcaps;
-
- /* we had a pool, check caps */
- GST_DEBUG_OBJECT (pvrvideosink, "check existing pool caps");
- config = gst_buffer_pool_get_config (pool);
- gst_buffer_pool_config_get (config, &pcaps, &size, NULL, NULL, NULL, NULL);
- gst_structure_free (config);
-
- if (!gst_caps_is_equal (caps, pcaps)) {
- GST_DEBUG_OBJECT (pvrvideosink, "pool has different caps");
- /* different caps, we can't use this pool */
- gst_object_unref (pool);
- pool = NULL;
- }
- }
-
- if (pool == NULL && need_pool) {
- GstVideoInfo info;
-
- GST_DEBUG_OBJECT (pvrvideosink, "create new pool");
- pool = gst_pvr_buffer_pool_new (GST_ELEMENT_CAST (pvrvideosink));
-
- if (!gst_video_info_from_caps (&info, caps))
- goto invalid_caps;
-
- /* the normal size of a frame */
- size = info.size;
-
- config = gst_buffer_pool_get_config (pool);
- gst_buffer_pool_config_set (config, caps, size, 0, 0, 0, 0);
- if (!gst_buffer_pool_set_config (pool, config))
- goto config_failed;
- }
- /* we need at least 3 buffers */
- gst_query_set_allocation_params (query, size, 3, 0, 0, 0, pool);
-
- /* we also support various metadata */
- gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API, NULL);
-
- gst_object_unref (pool);
-
- return TRUE;
-
- /* ERRORS */
-no_caps:
- {
- GST_DEBUG_OBJECT (bsink, "no caps specified");
- return FALSE;
- }
-invalid_caps:
- {
- GST_DEBUG_OBJECT (bsink, "invalid caps specified");
- return FALSE;
- }
-config_failed:
- {
- GST_DEBUG_OBJECT (bsink, "failed setting config");
- return FALSE;
- }
-}
-
-/* Interfaces stuff */
-
-/* This function destroys a GstXWindow */
-static void
-gst_pvrvideosink_xwindow_destroy (GstPVRVideoSink * pvrvideosink,
- GstXWindow * xwindow)
-{
- g_return_if_fail (xwindow != NULL);
-
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
-
- /* If we did not create that window we just free the GC and let it live */
- if (xwindow->internal)
- XDestroyWindow (pvrvideosink->dcontext->x_display, xwindow->window);
- else
- XSelectInput (pvrvideosink->dcontext->x_display, xwindow->window, 0);
-
- XFreeGC (pvrvideosink->dcontext->x_display, xwindow->gc);
-
- XSync (pvrvideosink->dcontext->x_display, FALSE);
-
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
-
- g_free (xwindow);
-}
-
-static void
-gst_pvrvideosink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
-{
- XID window_handle = id;
- GstPVRVideoSink *pvrvideosink = GST_PVRVIDEOSINK (overlay);
- GstXWindow *xwindow = NULL;
-
- g_return_if_fail (GST_IS_PVRVIDEOSINK (pvrvideosink));
-
- g_mutex_lock (pvrvideosink->flow_lock);
-
- /* If we already use that window return */
- if (pvrvideosink->xwindow && (window_handle == pvrvideosink->xwindow->window)) {
- g_mutex_unlock (pvrvideosink->flow_lock);
- return;
- }
-
- /* If the element has not initialized the X11 context try to do so */
- if (!pvrvideosink->dcontext && !(pvrvideosink->dcontext =
- gst_pvrvideosink_get_dcontext (pvrvideosink))) {
- g_mutex_unlock (pvrvideosink->flow_lock);
- /* we have thrown a GST_ELEMENT_ERROR now */
- return;
- }
-
- /* If a window is there already we destroy it */
- if (pvrvideosink->xwindow) {
- gst_pvrvideosink_xwindow_destroy (pvrvideosink, pvrvideosink->xwindow);
- pvrvideosink->xwindow = NULL;
- }
-
- /* If the xid is 0 we will create an internal one in buffer_alloc */
- if (window_handle != 0) {
- XWindowAttributes attr;
- WSEGLError glerror;
- WSEGLDrawableParams source_params;
- PVRSRV_CLIENT_MEM_INFO *client_mem_info;
-
- xwindow = g_new0 (GstXWindow, 1);
- xwindow->window = window_handle;
-
- /* Set the event we want to receive and create a GC */
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
-
- XGetWindowAttributes (pvrvideosink->dcontext->x_display, xwindow->window,
- &attr);
-
- xwindow->width = attr.width;
- xwindow->height = attr.height;
- xwindow->internal = FALSE;
- if (!pvrvideosink->have_render_rect) {
- pvrvideosink->render_rect.x = pvrvideosink->render_rect.y = 0;
- pvrvideosink->render_rect.w = attr.width;
- pvrvideosink->render_rect.h = attr.height;
- }
- XSelectInput (pvrvideosink->dcontext->x_display, xwindow->window,
- ExposureMask | StructureNotifyMask);
-
- XSetWindowBackgroundPixmap (pvrvideosink->dcontext->x_display,
- xwindow->window, None);
-
- XMapWindow (pvrvideosink->dcontext->x_display, xwindow->window);
- xwindow->gc = XCreateGC (pvrvideosink->dcontext->x_display,
- xwindow->window, 0, NULL);
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
-
- glerror =
- pvrvideosink->dcontext->wsegl_table->
- pfnWSEGL_CreateWindowDrawable (pvrvideosink->dcontext->display_handle,
- pvrvideosink->dcontext->glconfig,
- &(pvrvideosink->dcontext->drawable_handle),
- (NativeWindowType) xwindow->window,
- &(pvrvideosink->dcontext->rotation));
-
- if (glerror != WSEGL_SUCCESS) {
- GST_ERROR_OBJECT (pvrvideosink, "Error creating drawable");
- return;
- }
- glerror =
- pvrvideosink->dcontext->wsegl_table->
- pfnWSEGL_GetDrawableParameters (pvrvideosink->dcontext->drawable_handle,
- &source_params, &pvrvideosink->render_params);
-
- client_mem_info =
- (PVRSRV_CLIENT_MEM_INFO *) pvrvideosink->render_params.hPrivateData;
- PVR2DMEMINFO_INITIALISE (&pvrvideosink->dcontext->dst_mem, client_mem_info);
- }
-
- if (xwindow)
- pvrvideosink->xwindow = xwindow;
-
- g_mutex_unlock (pvrvideosink->flow_lock);
-}
-
-static void
-gst_pvrvideosink_expose (GstVideoOverlay * overlay)
-{
- GstPVRVideoSink *pvrvideosink = GST_PVRVIDEOSINK (overlay);
-
- gst_pvrvideosink_blit (pvrvideosink, NULL);
-}
-
-static void
-gst_pvrvideosink_set_event_handling (GstVideoOverlay * overlay,
- gboolean handle_events)
-{
- GstPVRVideoSink *pvrvideosink = GST_PVRVIDEOSINK (overlay);
-
- g_mutex_lock (pvrvideosink->flow_lock);
-
- if (G_UNLIKELY (!pvrvideosink->xwindow)) {
- g_mutex_unlock (pvrvideosink->flow_lock);
- return;
- }
-
- g_mutex_lock (pvrvideosink->dcontext->x_lock);
-
- XSelectInput (pvrvideosink->dcontext->x_display,
- pvrvideosink->xwindow->window, ExposureMask | StructureNotifyMask);
-
- g_mutex_unlock (pvrvideosink->dcontext->x_lock);
-
- g_mutex_unlock (pvrvideosink->flow_lock);
-}
-
-static void
-gst_pvrvideosink_set_render_rectangle (GstVideoOverlay * overlay, gint x,
- gint y, gint width, gint height)
-{
- GstPVRVideoSink *pvrvideosink = GST_PVRVIDEOSINK (overlay);
-
- /* FIXME: how about some locking? */
- if (width >= 0 && height >= 0) {
- pvrvideosink->render_rect.x = x;
- pvrvideosink->render_rect.y = y;
- pvrvideosink->render_rect.w = width;
- pvrvideosink->render_rect.h = height;
- pvrvideosink->have_render_rect = TRUE;
- } else {
- pvrvideosink->render_rect.x = 0;
- pvrvideosink->render_rect.y = 0;
- pvrvideosink->render_rect.w = pvrvideosink->xwindow->width;
- pvrvideosink->render_rect.h = pvrvideosink->xwindow->height;
- pvrvideosink->have_render_rect = FALSE;
- }
-}
-
-static void
-gst_pvrvideosink_videooverlay_init (GstVideoOverlayInterface * iface)
-{
- iface->set_window_handle = gst_pvrvideosink_set_window_handle;
- iface->expose = gst_pvrvideosink_expose;
- iface->handle_events = gst_pvrvideosink_set_event_handling;
- iface->set_render_rectangle = gst_pvrvideosink_set_render_rectangle;
-}
-
-/* =========================================== */
-/* */
-/* Init & Class init */
-/* */
-/* =========================================== */
-
-static void
-gst_pvrvideosink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstPVRVideoSink *pvrvideosink;
-
- g_return_if_fail (GST_IS_PVRVIDEOSINK (object));
-
- pvrvideosink = GST_PVRVIDEOSINK (object);
-
- switch (prop_id) {
- case PROP_FORCE_ASPECT_RATIO:
- pvrvideosink->keep_aspect = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_pvrvideosink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstPVRVideoSink *pvrvideosink;
-
- g_return_if_fail (GST_IS_PVRVIDEOSINK (object));
-
- pvrvideosink = GST_PVRVIDEOSINK (object);
-
- switch (prop_id) {
- case PROP_FORCE_ASPECT_RATIO:
- g_value_set_boolean (value, pvrvideosink->keep_aspect);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-void
-gst_pvrvideosink_track_buffer (GstPVRVideoSink * pvrsink, GstBuffer * buffer)
-{
- GST_DEBUG_OBJECT (pvrsink, "Adding buffer %p to tracked buffers", buffer);
- pvrsink->metabuffers = g_list_prepend (pvrsink->metabuffers, buffer);
-}
-
-void
-gst_pvrvideosink_untrack_buffer (GstPVRVideoSink * pvrsink, GstBuffer * buffer)
-{
- GST_DEBUG_OBJECT (pvrsink, "Removing buffer %p from tracked buffers", buffer);
- pvrsink->metabuffers = g_list_remove_all (pvrsink->metabuffers, buffer);
-}
-
-static void
-gst_pvrvideosink_release_pvr_metas (GstPVRVideoSink * pvrsink)
-{
- GstBuffer *buf;
- GstPVRMeta *pvrmeta;
-
- GST_DEBUG_OBJECT (pvrsink, "Releasing pending PVR metas");
-
- while (pvrsink->metabuffers) {
- buf = (GstBuffer *) pvrsink->metabuffers->data;
-
- pvrmeta = gst_buffer_get_pvr_meta (buf);
- if (pvrmeta)
- gst_buffer_remove_meta (buf, (GstMeta *) pvrmeta);
- }
-
- GST_DEBUG_OBJECT (pvrsink, "Done");
-}
-
-static void
-gst_pvrvideosink_dcontext_free (GstDrawContext * dcontext)
-{
- GST_DEBUG ("Freeing dcontext %p", dcontext);
-
- g_free (dcontext->p_blt_info);
- g_free (dcontext->p_blt2d_info);
-
- if (dcontext->x_lock)
- g_mutex_lock (dcontext->x_lock);
- if (dcontext->x_display) {
- GST_LOG ("Closing display");
- XCloseDisplay (dcontext->x_display);
- }
- if (dcontext->x_lock) {
- g_mutex_unlock (dcontext->x_lock);
- g_mutex_free (dcontext->x_lock);
- }
-
- g_free (dcontext);
-}
-
-static void
-gst_pvrvideosink_dcontext_clear (GstPVRVideoSink * pvrvideosink)
-{
- GstDrawContext *dcontext;
-
- GST_DEBUG_OBJECT (pvrvideosink, "Clearing dcontext %p",
- pvrvideosink->dcontext);
-
- GST_OBJECT_LOCK (pvrvideosink);
- if (!pvrvideosink->dcontext) {
- GST_OBJECT_UNLOCK (pvrvideosink);
- return;
- }
-
- dcontext = pvrvideosink->dcontext;
- pvrvideosink->dcontext = NULL;
- GST_OBJECT_UNLOCK (pvrvideosink);
-
- gst_pvrvideosink_dcontext_free (dcontext);
-}
-
-static void
-gst_pvrvideosink_reset (GstPVRVideoSink * pvrvideosink)
-{
- GThread *thread;
-
- GST_DEBUG_OBJECT (pvrvideosink, "Resetting");
-
- GST_OBJECT_LOCK (pvrvideosink);
- pvrvideosink->running = FALSE;
- thread = pvrvideosink->event_thread;
- pvrvideosink->event_thread = NULL;
- GST_OBJECT_UNLOCK (pvrvideosink);
-
- if (thread)
- g_thread_join (thread);
-
- if (pvrvideosink->current_buffer) {
- GST_LOG_OBJECT (pvrvideosink, "Removing cached buffer");
- gst_buffer_unref (pvrvideosink->current_buffer);
- pvrvideosink->current_buffer = NULL;
- }
-
- if (pvrvideosink->pool) {
- GST_LOG_OBJECT (pvrvideosink, "Unreffing pool");
- gst_object_unref (pvrvideosink->pool);
- pvrvideosink->pool = NULL;
- }
- memset (&pvrvideosink->render_params, 0, sizeof (WSEGLDrawableParams));
-
- pvrvideosink->render_rect.x = pvrvideosink->render_rect.y = 0;
- pvrvideosink->render_rect.w = pvrvideosink->render_rect.h = 0;
- pvrvideosink->have_render_rect = FALSE;
-
- gst_pvrvideosink_release_pvr_metas (pvrvideosink);
-
- gst_pvrvideosink_destroy_drawable (pvrvideosink);
-
- if (pvrvideosink->xwindow) {
- gst_pvrvideosink_xwindow_destroy (pvrvideosink, pvrvideosink->xwindow);
- pvrvideosink->xwindow = NULL;
- }
-
- gst_pvrvideosink_dcontext_clear (pvrvideosink);
-}
-
-static void
-gst_pvrvideosink_finalize (GObject * object)
-{
- GstPVRVideoSink *pvrvideosink;
-
- pvrvideosink = GST_PVRVIDEOSINK (object);
-
- gst_pvrvideosink_reset (pvrvideosink);
-
- if (pvrvideosink->flow_lock) {
- g_mutex_free (pvrvideosink->flow_lock);
- pvrvideosink->flow_lock = NULL;
- }
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_pvrvideosink_init (GstPVRVideoSink * pvrvideosink)
-{
- pvrvideosink->running = FALSE;
-
- pvrvideosink->flow_lock = g_mutex_new ();
- pvrvideosink->pool = NULL;
-
- pvrvideosink->keep_aspect = FALSE;
- pvrvideosink->current_caps = NULL;
- pvrvideosink->dcontext = NULL;
- pvrvideosink->xwindow = NULL;
- pvrvideosink->redraw_borders = TRUE;
- pvrvideosink->current_buffer = NULL;
- pvrvideosink->event_thread = NULL;
- memset (&pvrvideosink->render_params, 0, sizeof (WSEGLDrawableParams));
-}
-
-static void
-gst_pvrvideosink_class_init (GstPVRVideoSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
- GstBaseSinkClass *gstbasesink_class;
- GstVideoSinkClass *videosink_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
- videosink_class = (GstVideoSinkClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_pvrvideosink_finalize;
- gobject_class->set_property = gst_pvrvideosink_set_property;
- gobject_class->get_property = gst_pvrvideosink_get_property;
-
- g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
- g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
- "When enabled, reverse caps negotiation (scaling) will respect "
- "original aspect ratio", TRUE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- gst_element_class_set_static_metadata (gstelement_class,
- "PVR Video sink", "Sink/Video",
- "A PVR videosink",
- "Luciana Fujii Pontello <luciana.fujii@collabora.co.uk");
-
- gst_element_class_add_static_pad_template (gstelement_class,
- &gst_pvrvideosink_sink_template_factory);
-
- gstelement_class->change_state = gst_pvrvideosink_change_state;
-
- gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_pvrvideosink_setcaps);
- gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_pvrvideosink_getcaps);
- gstbasesink_class->propose_allocation =
- GST_DEBUG_FUNCPTR (gst_pvrvideosink_propose_allocation);
- gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_pvrvideosink_get_times);
-
- videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_pvrvideosink_show_frame);
-}