#include <dri2/dri2.h>
#include <tbm_bufmgr.h>
-/* for performance checking */
-#include <mm_ta.h>
+/* for setting vconf about xv state */
+#include <vconf.h>
+#include <vconf-internal-player-keys.h>
+
enum {
SECURE_PATH_INIT = -1,
DRM_LEVEL_1
};
+enum
+{
+ DISPLAY_STATUS_NULL = 0,
+ DISPLAY_STATUS_HDMI_ACTIVE,
+ DISPLAY_STATUS_UNKNOWN_ACTIVE,
+};
+
+enum
+{
+ XV_STATUS_NULL = 0,
+ XV_STATUS_READY,
+ XV_STATUS_PAUSED,
+ XV_STATUS_PLAYING,
+ XV_STATUS_SEEK,
+};
+
typedef enum {
BUF_SHARE_METHOD_PADDR = 0,
BUF_SHARE_METHOD_FD,
enum
{
SIGNAL_FRAME_RENDER_ERROR,
+ SIGNAL_DISPLAY_STATUS,
+ SIGNAL_EXTERNAL_RESOLUTION,
+ SIGNAL_WINDOW_STATUS,
+ SIGNAL_QUICKPANEL_STATUS,
+ SIGNAL_MULTIWINDOW_STATUS,
LAST_SIGNAL
};
static guint gst_xvimagesink_signals[LAST_SIGNAL] = { 0 };
static void _add_displaying_buffer(GstXvImageSink *xvimagesink, XV_DATA_PTR img_data, GstBuffer *buffer);
static void _remove_displaying_buffer(GstXvImageSink *xvimagesink, unsigned int *gem_name);
static int _is_connected_to_external_display(GstXvImageSink *xvimagesink);
+static void check_hdmi_connected(GstXvImageSink *xvimagesink);
+static int get_window_prop_card32_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int len);
+static gboolean check_supportable_port_attr(GstXvImageSink * xvimagesink, gchar* attr_name);
#endif /* GST_EXT_XV_ENHANCEMENT */
/* Default template - initiated with class struct to allow gst-register to work
PROP_ZOOM,
PROP_ZOOM_POS_X,
PROP_ZOOM_POS_Y,
+ PROP_ORIENTATION,
PROP_DST_ROI_MODE,
- PROP_DST_ROI_ORIENTATION,
PROP_DST_ROI_X,
PROP_DST_ROI_Y,
PROP_DST_ROI_W,
PROP_STOP_VIDEO,
PROP_PIXMAP_CB,
PROP_PIXMAP_CB_USER_DATA,
+ PROP_SUBPICTURE,
+ PROP_EXTERNAL_WIDTH,
+ PROP_EXTERNAL_HEIGHT,
PROP_ENABLE_FLUSH_BUFFER,
PROP_PIXMAP,
+ PROP_HIDED_WINDOW,
+ PROP_QUICKPANEL_ON,
+ PROP_MULTIWINDOW_ACTIVE,
+ PROP_KEEP_EXTERNAL_FULLSCREEN_POST,
+ PROP_KEEP_EXTERNAL_FULLSCREEN_PREV,
#endif /* GST_EXT_XV_ENHANCEMENT */
};
SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
if (SHMInfo.shmid == -1) {
GST_WARNING ("could not get shared memory of %d bytes", size);
- GST_ERROR("Failed to shmget: %s", g_strerror (errno));
goto beach;
}
xvimagesink->aligned_width = xvimage->width;
xvimagesink->aligned_height = xvimage->height;
}
+ if (xvimagesink->subpicture) {
+ GST_LOG("because of subpicture's format, pass xvimage_new");
+ return xvimage;
+ }
#endif /* GST_EXT_XV_ENHANCEMENT */
xvimage->im_format = gst_xvimagesink_get_format_from_caps (xvimagesink, caps);
xvimage->width, xvimage->height),
("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
xvimage->size));
- GST_ERROR_OBJECT(xvimagesink, "Failed to shmget: %s", g_strerror (errno));
goto beach_unlocked;
}
return xvimage;
}
-#ifdef GST_EXT_XV_ENHANCEMENT
-/* This function handles GstXvImage creation depending on XShm availability */
-static GstXvImageBuffer *
-gst_xvimagesink_xvimage_new_for_last_image (GstXvImageSink * xvimagesink, gint im_format)
-{
- GstXvImageBuffer *xvimage = NULL;
- GstStructure *structure = NULL;
- gboolean succeeded = FALSE;
- int (*handler) (Display *, XErrorEvent *);
-
- g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), NULL);
-
- xvimage = (GstXvImageBuffer *) gst_mini_object_new (GST_TYPE_XVIMAGE_BUFFER);
- GST_DEBUG_OBJECT (xvimage, "Creating new XvImageBuffer for last image");
-
- xvimage->width = xvimagesink->xvimage->width;
- xvimage->height = xvimagesink->xvimage->height;
-
- GST_LOG_OBJECT (xvimagesink, "creating %dx%d", xvimage->width,
- xvimage->height);
-
- xvimage->im_format = im_format;
- if (xvimage->im_format == -1) {
- GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
- ("Failed to create output image buffer of %dx%d pixels",
- xvimage->width, xvimage->height), ("Invalid input caps"));
- goto beach_unlocked;
- }
- xvimage->xvimagesink = gst_object_ref (xvimagesink);
-
- g_mutex_lock (xvimagesink->x_lock);
-
- XSync (xvimagesink->xcontext->disp, FALSE);
-
- /* Setting an error handler to catch failure */
- error_caught = FALSE;
- handler = XSetErrorHandler (gst_xvimagesink_handle_xerror);
-
-#ifdef HAVE_XSHM
- if (xvimagesink->xcontext->use_xshm) {
- int expected_size;
-
- xvimage->xvimage = XvShmCreateImage (xvimagesink->xcontext->disp,
- xvimagesink->xcontext->xv_port_id,
- xvimage->im_format, NULL,
- xvimage->width, xvimage->height, &xvimage->SHMInfo);
- if (!xvimage->xvimage || error_caught) {
- g_mutex_unlock (xvimagesink->x_lock);
-
- /* Reset error flag */
- error_caught = FALSE;
-
- /* Push a warning */
- GST_ELEMENT_WARNING (xvimagesink, RESOURCE, WRITE,
- ("Failed to create output image buffer of %dx%d pixels",
- xvimage->width, xvimage->height),
- ("could not XvShmCreateImage a %dx%d image",
- xvimage->width, xvimage->height));
-
- /* must not change "use_xshm",
- because it causes memory curruption when buffer created by XvShmCreateImage is destroyed */
- goto beach_unlocked;
- }
-
- /* we have to use the returned data_size for our shm size */
- xvimage->size = xvimage->xvimage->data_size;
- GST_LOG_OBJECT (xvimagesink, "XShm image size is %" G_GSIZE_FORMAT,
- xvimage->size);
-
- /* calculate the expected size. This is only for sanity checking the
- * number we get from X. */
- switch (xvimage->im_format) {
- case GST_MAKE_FOURCC ('I', '4', '2', '0'):
- case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
- {
- gint pitches[3];
- gint offsets[3];
- guint plane;
-
- offsets[0] = 0;
- pitches[0] = GST_ROUND_UP_4 (xvimage->width);
- offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (xvimage->height);
- pitches[1] = GST_ROUND_UP_8 (xvimage->width) / 2;
- offsets[2] =
- offsets[1] + pitches[1] * GST_ROUND_UP_2 (xvimage->height) / 2;
- pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2;
-
- expected_size =
- offsets[2] + pitches[2] * GST_ROUND_UP_2 (xvimage->height) / 2;
-
- for (plane = 0; plane < xvimage->xvimage->num_planes; plane++) {
- GST_DEBUG_OBJECT (xvimagesink,
- "Plane %u has a expected pitch of %d bytes, " "offset of %d",
- plane, pitches[plane], offsets[plane]);
- }
- break;
- }
- case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
- case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
- case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
- expected_size = xvimage->height * GST_ROUND_UP_4 (xvimage->width * 2);
- break;
- default:
- expected_size = 0;
- break;
- }
- if (expected_size != 0 && xvimage->size != expected_size) {
- GST_WARNING_OBJECT (xvimagesink,
- "unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)",
- xvimage->size, expected_size);
- }
-
- /* Be verbose about our XvImage stride */
- {
- guint plane;
-
- for (plane = 0; plane < xvimage->xvimage->num_planes; plane++) {
- GST_DEBUG_OBJECT (xvimagesink, "Plane %u has a pitch of %d bytes, "
- "offset of %d", plane, xvimage->xvimage->pitches[plane],
- xvimage->xvimage->offsets[plane]);
- }
- }
-
- xvimage->SHMInfo.shmid = shmget (IPC_PRIVATE, xvimage->size,
- IPC_CREAT | 0777);
- if (xvimage->SHMInfo.shmid == -1) {
- g_mutex_unlock (xvimagesink->x_lock);
- GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
- ("Failed to create output image buffer of %dx%d pixels",
- xvimage->width, xvimage->height),
- ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
- xvimage->size));
- GST_ERROR_OBJECT(xvimagesink, "Failed to shmget: %s", g_strerror (errno));
- goto beach_unlocked;
- }
-
- xvimage->SHMInfo.shmaddr = shmat (xvimage->SHMInfo.shmid, NULL, 0);
- if (xvimage->SHMInfo.shmaddr == ((void *) -1)) {
- g_mutex_unlock (xvimagesink->x_lock);
- GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
- ("Failed to create output image buffer of %dx%d pixels",
- xvimage->width, xvimage->height),
- ("Failed to shmat: %s", g_strerror (errno)));
- /* Clean up the shared memory segment */
- shmctl (xvimage->SHMInfo.shmid, IPC_RMID, NULL);
- goto beach_unlocked;
- }
-
- xvimage->xvimage->data = xvimage->SHMInfo.shmaddr;
- xvimage->SHMInfo.readOnly = FALSE;
-
- if (XShmAttach (xvimagesink->xcontext->disp, &xvimage->SHMInfo) == 0) {
- /* Clean up the shared memory segment */
- shmctl (xvimage->SHMInfo.shmid, IPC_RMID, NULL);
-
- g_mutex_unlock (xvimagesink->x_lock);
- GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
- ("Failed to create output image buffer of %dx%d pixels",
- xvimage->width, xvimage->height), ("Failed to XShmAttach"));
- goto beach_unlocked;
- }
-
- XSync (xvimagesink->xcontext->disp, FALSE);
-
- /* Delete the shared memory segment as soon as we everyone is attached.
- * This way, it will be deleted as soon as we detach later, and not
- * leaked if we crash. */
- shmctl (xvimage->SHMInfo.shmid, IPC_RMID, NULL);
-
- GST_DEBUG_OBJECT (xvimagesink, "XServer ShmAttached to 0x%x, id 0x%lx",
- xvimage->SHMInfo.shmid, xvimage->SHMInfo.shmseg);
- } else
-#endif /* HAVE_XSHM */
- {
- xvimage->xvimage = XvCreateImage (xvimagesink->xcontext->disp,
- xvimagesink->xcontext->xv_port_id,
- xvimage->im_format, NULL, xvimagesink->aligned_width, xvimagesink->aligned_height);
- if (!xvimage->xvimage || error_caught) {
- g_mutex_unlock (xvimagesink->x_lock);
- /* Reset error handler */
- error_caught = FALSE;
- XSetErrorHandler (handler);
- /* Push an error */
- GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
- ("Failed to create outputimage buffer of %dx%d pixels",
- xvimage->width, xvimage->height),
- ("could not XvCreateImage a %dx%d image",
- xvimage->width, xvimage->height));
- goto beach_unlocked;
- }
-
- /* we have to use the returned data_size for our image size */
- xvimage->size = xvimage->xvimage->data_size;
- xvimage->xvimage->data = g_malloc (xvimage->size);
-
- XSync (xvimagesink->xcontext->disp, FALSE);
- }
-
- /* Reset error handler */
- error_caught = FALSE;
- XSetErrorHandler (handler);
-
- succeeded = TRUE;
-
- GST_BUFFER_DATA (xvimage) = (guchar *) xvimage->xvimage->data;
- GST_BUFFER_SIZE (xvimage) = xvimage->size;
-
- g_mutex_unlock (xvimagesink->x_lock);
-
-beach_unlocked:
- if (!succeeded) {
- gst_xvimage_buffer_free (xvimage);
- xvimage = NULL;
- }
-
- return xvimage;
-}
-
-static gboolean
-gst_xvimagesink_xvimage_handle_last_buffer (GstXvImageSink * xvimagesink, gint im_format)
-{
- g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), FALSE);
-
- xvimagesink->last_image = gst_xvimagesink_xvimage_new_for_last_image (xvimagesink, im_format);
- if (!xvimagesink->last_image) {
- /* The create method should have posted an informative error */
- GST_WARNING_OBJECT (xvimagesink, "could not create last image");
- return FALSE;
- }
-
- GST_INFO_OBJECT(xvimagesink, "last_image(%p)->xvimage->data:0x%x, last_image->size:%d",
- xvimagesink->last_image, xvimagesink->last_image->xvimage->data, xvimagesink->last_image->size);
-
- switch (im_format) {
- case GST_MAKE_FOURCC('N', 'V', '1', '2'):
- {
- int i = 0;
- gint y_size = 0;
- char *y_data = xvimagesink->last_image->xvimage->data;
- y_size = xvimagesink->last_image->width * xvimagesink->last_image->height;
- if (xvimagesink->last_image_vaddr[0]) {
- for(i = 0; i < xvimagesink->last_image->height; i++) {
- memcpy (y_data + i*xvimagesink->last_image->width, xvimagesink->last_image_vaddr[0] + i*xvimagesink->aligned_width, xvimagesink->last_image->width);
- }
- }
- if (xvimagesink->last_image_vaddr[1]) {
- for(i = 0; i < xvimagesink->last_image->height/2; i++) {
- memcpy (y_data + y_size + i*xvimagesink->last_image->width, xvimagesink->last_image_vaddr[1] + i*xvimagesink->aligned_width, xvimagesink->last_image->width);
- }
- }
- GST_LOG_OBJECT(xvimagesink, "last image was copied in NV12 format (w:%d, h:%d, y_size:%d", xvimagesink->last_image->width, xvimagesink->last_image->height, y_size);
- break;
- }
- default:
- GST_ERROR_OBJECT(xvimagesink, "Not support format for last image");
- gst_xvimage_buffer_destroy (xvimagesink->last_image);
- xvimagesink->last_image = NULL;
- GST_WARNING_OBJECT (xvimagesink, "could not create last image");
- return FALSE;
- }
-
- return TRUE;
-}
-#endif
-
/* We are called with the x_lock taken */
static void
gst_xvimagesink_xwindow_draw_borders (GstXvImageSink * xvimagesink,
static Atom atom_rotation = None;
static Atom atom_hflip = None;
static Atom atom_vflip = None;
+ static Atom atom_contents_rotation = None;
gboolean set_hflip = FALSE;
gboolean set_vflip = FALSE;
XWindowAttributes map_attr;
gint res_rotate_angle = 0;
int rotate = 0;
+ int orientation = 0;
int ret = 0;
int idx = 0;
int (*handler) (Display *, XErrorEvent *) = NULL;
gboolean res = FALSE;
XV_DATA_PTR img_data = NULL;
+
+ if (xvimagesink->is_subpicture_format)
+ return TRUE;
#endif /* GST_EXT_XV_ENHANCEMENT */
/* We take the flow_lock. If expose is in there we don't want to run
return TRUE;
}
} else {
- GST_WARNING_OBJECT(xvimagesink, "XGetWindowAttributes failed");
+ GST_WARNING_OBJECT(xvimagesink, "XGetWindowAttributes failed");
}
}
}
-
- /* check visible status */
- if (xvimagesink->visible == FALSE ||
- xvimagesink->is_hided && GST_STATE(xvimagesink) != GST_STATE_PLAYING) {
- GST_INFO("visible[%d] or is_hided[%d]. Skip xvimage_put.",
- xvimagesink->visible, xvimagesink->is_hided);
- g_mutex_unlock(xvimagesink->flow_lock);
- return TRUE;
- }
#endif /* GST_EXT_XV_ENHANCEMENT */
/* Draw borders when displaying the first frame. After this
}
#ifdef GST_EXT_XV_ENHANCEMENT
+ gboolean enable_last_buffer;
+ g_object_get(G_OBJECT(xvimagesink), "enable-last-buffer", &enable_last_buffer, NULL);
+ if(enable_last_buffer) {
+ if (xvimagesink->cur_image && xvimagesink->is_zero_copy_format) {
+ GstBuffer *last_buffer= NULL;
+ g_object_get(G_OBJECT(xvimagesink), "last-buffer", &last_buffer, NULL);
+ if (last_buffer) {
+ if(last_buffer != xvimagesink->cur_image)
+ {
+ GST_LOG("curimage : %p , last_buffer : %p", xvimagesink->cur_image, last_buffer);
+ }
+ } else {
+ GST_WARNING_OBJECT(xvimagesink, "zero copy format and last buffer is NULL, so skip this putimage");
+ g_mutex_unlock (xvimagesink->flow_lock);
+ return TRUE;
+ }
+ gst_buffer_unref(last_buffer);
+ last_buffer = NULL;
+ }
+ }
+
+ if (xvimagesink->visible == FALSE ||
+ (xvimagesink->is_hided && GST_STATE(xvimagesink) != GST_STATE_PLAYING)) {
+ GST_INFO("visible[%d] or is_hided[%d]. Skip xvimage_put.",
+ xvimagesink->visible, xvimagesink->is_hided);
+ g_mutex_unlock(xvimagesink->flow_lock);
+ return TRUE;
+ }
+
if (!xvimagesink->get_pixmap_cb) {
gst_xvimagesink_xwindow_update_geometry( xvimagesink );
+ if (!xvimagesink->subpicture && !xvimagesink->is_during_seek) {
+ if(xvimagesink->is_multi_window && (GST_STATE(xvimagesink) != GST_STATE_PLAYING)) {
+ set_display_mode(xvimagesink->xcontext, DISPLAY_MODE_PRI_VIDEO_ON_AND_SEC_VIDEO_CLONE);
+ } else {
+ set_display_mode(xvimagesink->xcontext, xvimagesink->display_mode);
+ }
+ }
} else {
/* for multi-pixmap usage for the video texture */
gst_xvimagesink_set_pixmap_handle ((GstXOverlay *)xvimagesink, xvimagesink->get_pixmap_cb(xvimagesink->get_pixmap_cb_user_data));
src_input.w = src_origin.w = xvimagesink->video_width;
src_input.h = src_origin.h = xvimagesink->video_height;
+ if ((xvimagesink->display_geometry_method == DISP_GEO_METHOD_LETTER_BOX ||
+ xvimagesink->display_geometry_method == DISP_GEO_METHOD_FULL_SCREEN ||
+ xvimagesink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_DST_ROI) &&
+ xvimagesink->src_crop.w && xvimagesink->src_crop.h) {
+ GST_LOG_OBJECT(xvimagesink, "set src crop %d,%d,%dx%d -> %d,%d,%dx%d",
+ src_input.x, src_input.y, src_input.w, src_input.h,
+ xvimagesink->src_crop.x, xvimagesink->src_crop.y, xvimagesink->src_crop.w, xvimagesink->src_crop.h);
+ src_input.x = src_origin.w = xvimagesink->src_crop.x;
+ src_input.y = src_origin.y = xvimagesink->src_crop.y;
+ src_input.w = src_origin.w = xvimagesink->src_crop.w;
+ src_input.h = src_origin.h = xvimagesink->src_crop.h;
+ }
+
if (xvimagesink->rotate_angle == DEGREE_0 ||
xvimagesink->rotate_angle == DEGREE_180) {
src.w = src_origin.w;
case ROI_DISP_GEO_METHOD_LETTER_BOX:
{
GstVideoRectangle roi_result;
- if (xvimagesink->dst_roi_orientation == DEGREE_0 ||
- xvimagesink->dst_roi_orientation == DEGREE_180) {
+ if (xvimagesink->orientation == DEGREE_0 ||
+ xvimagesink->orientation == DEGREE_180) {
src.w = src_origin.w;
src.h = src_origin.h;
} else {
}
/* orientation setting for auto rotation in DST ROI */
- if (xvimagesink->dst_roi_orientation) {
- res_rotate_angle = (xvimagesink->rotate_angle - xvimagesink->dst_roi_orientation);
+ if (xvimagesink->orientation) {
+ res_rotate_angle = (xvimagesink->rotate_angle - xvimagesink->orientation);
if (res_rotate_angle < 0) {
res_rotate_angle += DEGREE_NUM;
}
GST_LOG_OBJECT(xvimagesink, "changing rotation value internally by ROI orientation[%d] : rotate[%d->%d]",
- xvimagesink->dst_roi_orientation, xvimagesink->rotate_angle, res_rotate_angle);
+ xvimagesink->orientation, xvimagesink->rotate_angle, res_rotate_angle);
}
GST_LOG_OBJECT(xvimagesink, "rotate[%d], dst ROI: orientation[%d], mode[%d], input[%d,%d,%dx%d]->result[%d,%d,%dx%d]",
- xvimagesink->rotate_angle, xvimagesink->dst_roi_orientation, xvimagesink->dst_roi_mode,
+ xvimagesink->rotate_angle, xvimagesink->orientation, xvimagesink->dst_roi_mode,
xvimagesink->dst_roi.x, xvimagesink->dst_roi.y, xvimagesink->dst_roi.w, xvimagesink->dst_roi.h,
result.x, result.y, result.w, result.h);
break;
}
if (xvimagesink->zoom > 1.0 && xvimagesink->zoom <= 9.0) {
- GST_LOG_OBJECT(xvimagesink, "before zoom[%lf], src_input[x:%d,y:%d,w:%d,h%d]",
+ GST_LOG_OBJECT(xvimagesink, "before zoom[%lf], src_input[x:%d,y:%d,w:%d,h:%d]",
xvimagesink->zoom, src_input.x, src_input.y, src_input.w, src_input.h);
+ gint default_offset_x = 0;
+ gint default_offset_y = 0;
gfloat w = (gfloat)src_input.w;
gfloat h = (gfloat)src_input.h;
- gint default_offset_x = ((gint)(w - (w/xvimagesink->zoom)))>>1;
- gint default_offset_y = ((gint)(h - (h/xvimagesink->zoom)))>>1;
- GST_LOG_OBJECT(xvimagesink, "default offset x:%d y:%d", default_offset_x, default_offset_y);
+ if (xvimagesink->orientation == DEGREE_0 ||
+ xvimagesink->orientation == DEGREE_180) {
+ default_offset_x = ((gint)(w - (w/xvimagesink->zoom)))>>1;
+ default_offset_y = ((gint)(h - (h/xvimagesink->zoom)))>>1;
+ } else {
+ default_offset_y = ((gint)(w - (w/xvimagesink->zoom)))>>1;
+ default_offset_x = ((gint)(h - (h/xvimagesink->zoom)))>>1;
+ }
+ GST_LOG_OBJECT(xvimagesink, "default offset x[%d] y[%d], orientation[%d]", default_offset_x, default_offset_y, xvimagesink->orientation);
if (xvimagesink->zoom_pos_x == -1) {
src_input.x += default_offset_x;
} else {
- if ((gint)w/xvimagesink->zoom > w - xvimagesink->zoom_pos_x) {
- xvimagesink->zoom_pos_x = default_offset_x * 2;
+ if (xvimagesink->orientation == DEGREE_0 ||
+ xvimagesink->orientation == DEGREE_180) {
+ if ((w/xvimagesink->zoom) > w - xvimagesink->zoom_pos_x) {
+ xvimagesink->zoom_pos_x = w - (w/xvimagesink->zoom);
+ }
+ src_input.x += xvimagesink->zoom_pos_x;
+ } else {
+ if ((h/xvimagesink->zoom) > h - xvimagesink->zoom_pos_x) {
+ xvimagesink->zoom_pos_x = h - (h/xvimagesink->zoom);
+ }
+ src_input.y += (h - h/xvimagesink->zoom) - xvimagesink->zoom_pos_x;
}
- src_input.x += xvimagesink->zoom_pos_x;
}
if (xvimagesink->zoom_pos_y == -1) {
src_input.y += default_offset_y;
} else {
- if ((gint)h/xvimagesink->zoom > h - xvimagesink->zoom_pos_y) {
- xvimagesink->zoom_pos_y = default_offset_y * 2;
+ if (xvimagesink->orientation == DEGREE_0 ||
+ xvimagesink->orientation == DEGREE_180) {
+ if ((h/xvimagesink->zoom) > h - xvimagesink->zoom_pos_y) {
+ xvimagesink->zoom_pos_y = h - (h/xvimagesink->zoom);
+ }
+ src_input.y += xvimagesink->zoom_pos_y;
+ } else {
+ if ((w/xvimagesink->zoom) > w - xvimagesink->zoom_pos_y) {
+ xvimagesink->zoom_pos_y = w - (w/xvimagesink->zoom);
+ }
+ src_input.x += (xvimagesink->zoom_pos_y);
}
- src_input.y += xvimagesink->zoom_pos_y;
}
-
src_input.w = (gint)(w/xvimagesink->zoom);
src_input.h = (gint)(h/xvimagesink->zoom);
GST_LOG_OBJECT(xvimagesink, "after zoom[%lf], src_input[x:%d,y:%d,w:%d,h%d], zoom_pos[x:%d,y:%d]",
src_input.h += 1;
}
- if ((xvimagesink->display_geometry_method == DISP_GEO_METHOD_LETTER_BOX ||
- xvimagesink->display_geometry_method == DISP_GEO_METHOD_FULL_SCREEN) &&
- xvimagesink->src_crop.w && xvimagesink->src_crop.h) {
- GST_LOG_OBJECT(xvimagesink, "set src crop %d,%d,%dx%d -> %d,%d,%dx%d",
- src_input.x, src_input.y, src_input.w, src_input.h,
- xvimagesink->src_crop.x, xvimagesink->src_crop.y, xvimagesink->src_crop.w, xvimagesink->src_crop.h);
- src_input.x = xvimagesink->src_crop.x;
- src_input.y = xvimagesink->src_crop.y;
- src_input.w = xvimagesink->src_crop.w;
- src_input.h = xvimagesink->src_crop.h;
- }
-
if (!xvimagesink->get_pixmap_cb) {
GST_LOG_OBJECT( xvimagesink, "screen[%dx%d],window[%d,%d,%dx%d],method[%d],rotate[%d],zoom[%f],dp_mode[%d],src[%dx%d],dst[%d,%d,%dx%d],input[%d,%d,%dx%d],result[%d,%d,%dx%d]",
xvimagesink->scr_w, xvimagesink->scr_h,
return TRUE;
}
- /* set display rotation */
- if (atom_rotation == None) {
- atom_rotation = XInternAtom(xvimagesink->xcontext->disp,
+ static gboolean is_exist = FALSE;
+ gchar *attr_name = g_strdup("_USER_WM_PORT_ATTRIBUTE_ROTATION");
+ is_exist = check_supportable_port_attr(xvimagesink, attr_name);
+ g_free(attr_name);
+
+ if (is_exist) {
+ /* set display rotation */
+ if (atom_rotation == None) {
+ atom_rotation = XInternAtom(xvimagesink->xcontext->disp,
"_USER_WM_PORT_ATTRIBUTE_ROTATION", False);
- }
+ }
+ ret = XvSetPortAttribute(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id,
+ atom_rotation, rotate);
+ if (ret != Success) {
+ GST_ERROR_OBJECT( xvimagesink, "XvSetPortAttribute failed[%d]. disp[%x],xv_port_id[%d],atom[%x],rotate[%d]",
+ ret, xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_rotation, rotate );
- ret = XvSetPortAttribute(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_rotation, rotate);
- if (ret != Success) {
- GST_ERROR_OBJECT( xvimagesink, "XvSetPortAttribute failed[%d]. disp[%x],xv_port_id[%d],atom[%x],rotate[%d]",
- ret, xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_rotation, rotate );
- g_mutex_unlock(xvimagesink->x_lock);
- g_mutex_unlock(xvimagesink->flow_lock);
- return FALSE;
+ g_mutex_unlock(xvimagesink->x_lock);
+ g_mutex_unlock(xvimagesink->flow_lock);
+ return FALSE;
+ }
+ } else {
+ GST_WARNING("_USER_WM_PORT_ATTRIBUTE_ROTATION is not existed");
}
- /* set display flip */
- if (atom_hflip == None) {
- atom_hflip = XInternAtom(xvimagesink->xcontext->disp,
- "_USER_WM_PORT_ATTRIBUTE_HFLIP", False);
+ switch( xvimagesink->orientation )
+ {
+ case DEGREE_0:
+ orientation = 0;
+ break;
+ case DEGREE_90:
+ orientation = 90;
+ break;
+ case DEGREE_180:
+ orientation = 180;
+ break;
+ case DEGREE_270:
+ orientation = 270;
+ break;
+ default:
+ GST_WARNING_OBJECT( xvimagesink, "Unsupported orientation [%d]...",
+ xvimagesink->orientation );
+ break;
}
- if (atom_vflip == None) {
- atom_vflip = XInternAtom(xvimagesink->xcontext->disp,
- "_USER_WM_PORT_ATTRIBUTE_VFLIP", False);
+
+ is_exist = FALSE;
+ attr_name = g_strdup("_USER_WM_PORT_ATTRIBUTE_CONTENTS_ROTATION");
+ is_exist = check_supportable_port_attr(xvimagesink, attr_name);
+ g_free(attr_name);
+
+ if (is_exist) {
+ /* set contents rotation for connecting with external display */
+ if (atom_contents_rotation == None) {
+ atom_contents_rotation = XInternAtom(xvimagesink->xcontext->disp,
+ "_USER_WM_PORT_ATTRIBUTE_CONTENTS_ROTATION", False);
+ }
+ ret = XvSetPortAttribute(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id,
+ atom_contents_rotation, orientation);
+ if (ret != Success) {
+ GST_ERROR_OBJECT( xvimagesink, "XvSetPortAttribute failed[%d]. disp[%x],xv_port_id[%d],atom[%x],orientation[%d]",
+ ret, xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_contents_rotation, orientation );
+
+ g_mutex_unlock(xvimagesink->x_lock);
+ g_mutex_unlock(xvimagesink->flow_lock);
+ return FALSE;
+ }
+ }else {
+ GST_WARNING("_USER_WM_PORT_ATTRIBUTE_CONTENTS_ROTATION is not existed");
}
switch (xvimagesink->flip) {
GST_LOG("set HFLIP %d, VFLIP %d", set_hflip, set_vflip);
- ret = XvSetPortAttribute(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_hflip, set_hflip);
- if (ret != Success) {
- GST_WARNING("set HFLIP failed[%d]. disp[%x],xv_port_id[%d],atom[%x],hflip[%d]",
- ret, xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_hflip, set_hflip);
+ is_exist = FALSE;
+ attr_name = g_strdup("_USER_WM_PORT_ATTRIBUTE_HFLIP");
+ is_exist = check_supportable_port_attr(xvimagesink, attr_name);
+ g_free(attr_name);
+
+ if (is_exist) {
+ if (atom_hflip == None) {
+ /* set display flip */
+ atom_hflip = XInternAtom(xvimagesink->xcontext->disp,
+ "_USER_WM_PORT_ATTRIBUTE_HFLIP", False);
+ }
+ ret = XvSetPortAttribute(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_hflip, set_hflip);
+ if (ret != Success) {
+ GST_WARNING("set HFLIP failed[%d]. disp[%x],xv_port_id[%d],atom[%x],hflip[%d]",
+ ret, xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_hflip, set_hflip);
+ }
}
- ret = XvSetPortAttribute(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_vflip, set_vflip);
- if (ret != Success) {
- GST_WARNING("set VFLIP failed[%d]. disp[%x],xv_port_id[%d],atom[%x],vflip[%d]",
- ret, xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_vflip, set_vflip);
+
+ is_exist = FALSE;
+ attr_name = g_strdup("_USER_WM_PORT_ATTRIBUTE_VFLIP");
+ is_exist = check_supportable_port_attr(xvimagesink, attr_name);
+ g_free(attr_name);
+
+ if (is_exist) {
+ if (atom_vflip == None) {
+ /* set display flip */
+ atom_vflip = XInternAtom(xvimagesink->xcontext->disp,
+ "_USER_WM_PORT_ATTRIBUTE_VFLIP", False);
+ }
+ ret = XvSetPortAttribute(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_vflip, set_vflip);
+ if (ret != Success) {
+ GST_WARNING("set VFLIP failed[%d]. disp[%x],xv_port_id[%d],atom[%x],vflip[%d]",
+ ret, xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_vflip, set_vflip);
+ }
}
/* set error handler */
}
/* store buffer */
- if (xvimagesink->is_zero_copy_format && xvimage->xvimage->data && !xvimagesink->last_image) {
+ if (xvimagesink->is_zero_copy_format && xvimage->xvimage->data) {
img_data = (XV_DATA_PTR)xvimage->xvimage->data;
if (img_data->BufType == XV_BUF_TYPE_DMABUF) {
_add_displaying_buffer(xvimagesink, img_data, xvimage->current_buffer);
}
if (is_exist) {
- GST_WARNING("set display mode %d", set_mode);
+ GST_DEBUG("set display mode %d", set_mode);
atom_output = XInternAtom(xcontext->disp,
"_USER_WM_PORT_ATTRIBUTE_OUTPUT", False);
ret = XvSetPortAttribute(xcontext->disp, xcontext->xv_port_id,
return;
}
+
static void _add_displaying_buffer(GstXvImageSink *xvimagesink, XV_DATA_PTR img_data, GstBuffer *buffer)
{
int i = 0;
xvimagesink->displaying_buffers[i].dmabuf_fd[j] = img_data->dmabuf_fd[j];
xvimagesink->displaying_buffers[i].gem_handle[j] = img_data->gem_handle[j];
xvimagesink->displaying_buffers[i].bo[j] = img_data->bo[j];
- xvimagesink->displaying_buffers[i].vaddr[j] = img_data->vaddr[j];
}
/* set buffer info */
xvimagesink->displaying_buffers[i].gem_name[1],
xvimagesink->displaying_buffers[i].gem_name[2]);
} else {
- GST_DEBUG_OBJECT(xvimagesink, "add idx %d, buf %p, fd [%u %u %u], handle [%u %u %u], name [%u %u %u], vaddr [%p, %p, %p]",
+ GST_DEBUG_OBJECT(xvimagesink, "add idx %d, buf %p, fd [%u %u %u], handle [%u %u %u], name [%u %u %u]",
i, xvimagesink->displaying_buffers[i].buffer,
xvimagesink->displaying_buffers[i].dmabuf_fd[0],
xvimagesink->displaying_buffers[i].dmabuf_fd[1],
xvimagesink->displaying_buffers[i].gem_handle[2],
xvimagesink->displaying_buffers[i].gem_name[0],
xvimagesink->displaying_buffers[i].gem_name[1],
- xvimagesink->displaying_buffers[i].gem_name[2],
- xvimagesink->displaying_buffers[i].vaddr[0],
- xvimagesink->displaying_buffers[i].vaddr[1],
- xvimagesink->displaying_buffers[i].vaddr[2]);
+ xvimagesink->displaying_buffers[i].gem_name[2]);
}
/* set last added buffer index */
static void _remove_displaying_buffer(GstXvImageSink *xvimagesink, unsigned int *gem_name)
{
- int i = 0;
- int j = 0;
+ int i = 0;
+ int j = 0;
- gboolean enable_last_buffer = FALSE;
+ if (!xvimagesink || !gem_name) {
+ GST_ERROR_OBJECT(xvimagesink, "handle is NULL %p, %p", xvimagesink, gem_name);
+ return;
+ }
- if (!xvimagesink || !gem_name) {
- GST_ERROR_OBJECT(xvimagesink, "handle is NULL %p, %p", xvimagesink, gem_name);
- return;
- }
+ /* lock display buffer mutex */
+ g_mutex_lock(xvimagesink->display_buffer_lock);
- /* lock display buffer mutex */
- g_mutex_lock(xvimagesink->display_buffer_lock);
+ if (xvimagesink->displaying_buffer_count == 0) {
+ GST_WARNING_OBJECT(xvimagesink, "there is no displaying buffer");
+ /* unlock display buffer mutex */
+ g_mutex_unlock(xvimagesink->display_buffer_lock);
+ return;
+ }
- if (xvimagesink->displaying_buffer_count == 0) {
- GST_WARNING_OBJECT(xvimagesink, "there is no displaying buffer");
- /* unlock display buffer mutex */
- g_mutex_unlock(xvimagesink->display_buffer_lock);
- return;
- }
+ GST_DEBUG_OBJECT(xvimagesink, "gem name [%u %u %u], displaying buffer count %d",
+ gem_name[0], gem_name[1], gem_name[2],
+ xvimagesink->displaying_buffer_count);
- GST_DEBUG_OBJECT(xvimagesink, "gem name [%u %u %u], displaying buffer count %d",
- gem_name[0], gem_name[1], gem_name[2],
- xvimagesink->displaying_buffer_count);
+ for (i = 0 ; i < DISPLAYING_BUFFERS_MAX_NUM ; i++) {
+ if (xvimagesink->displaying_buffers[i].gem_name[0] == gem_name[0] &&
+ xvimagesink->displaying_buffers[i].gem_name[1] == gem_name[1] &&
+ xvimagesink->displaying_buffers[i].gem_name[2] == gem_name[2]) {
+ struct timeval current_time;
- for (i = 0 ; i < DISPLAYING_BUFFERS_MAX_NUM ; i++) {
- if (xvimagesink->displaying_buffers[i].gem_name[0] == gem_name[0] &&
- xvimagesink->displaying_buffers[i].gem_name[1] == gem_name[1] &&
- xvimagesink->displaying_buffers[i].gem_name[2] == gem_name[2]) {
- struct timeval current_time;
-
- /* get current time to calculate displaying time */
- gettimeofday(¤t_time, NULL);
-
- GST_DEBUG_OBJECT(xvimagesink, "buffer return time %8d us",
- (current_time.tv_sec - xvimagesink->request_time[i].tv_sec)*1000000 + \
- (current_time.tv_usec - xvimagesink->request_time[i].tv_usec));
-
- if (xvimagesink->displayed_buffer_count < _CHECK_DISPLAYED_BUFFER_COUNT) {
- xvimagesink->displayed_buffer_count++;
- GST_WARNING_OBJECT(xvimagesink, "cnt %d - remove idx %d, buf %p, handle [%u %u %u], name [%u %u %u]",
- xvimagesink->displayed_buffer_count,
- i, xvimagesink->displaying_buffers[i].buffer,
- xvimagesink->displaying_buffers[i].gem_handle[0],
- xvimagesink->displaying_buffers[i].gem_handle[1],
- xvimagesink->displaying_buffers[i].gem_handle[2],
- xvimagesink->displaying_buffers[i].gem_name[0],
- xvimagesink->displaying_buffers[i].gem_name[1],
- xvimagesink->displaying_buffers[i].gem_name[2]);
- } else {
- GST_DEBUG_OBJECT(xvimagesink, "remove idx %d, buf %p, handle [%u %u %u], name [%u %u %u]",
- i, xvimagesink->displaying_buffers[i].buffer,
- xvimagesink->displaying_buffers[i].gem_handle[0],
- xvimagesink->displaying_buffers[i].gem_handle[1],
- xvimagesink->displaying_buffers[i].gem_handle[2],
- xvimagesink->displaying_buffers[i].gem_name[0],
- xvimagesink->displaying_buffers[i].gem_name[1],
- xvimagesink->displaying_buffers[i].gem_name[2]);
- }
+ /* get current time to calculate displaying time */
+ gettimeofday(¤t_time, NULL);
+
+ GST_DEBUG_OBJECT(xvimagesink, "buffer return time %8d us",
+ (current_time.tv_sec - xvimagesink->request_time[i].tv_sec)*1000000 + \
+ (current_time.tv_usec - xvimagesink->request_time[i].tv_usec));
+
+ if (xvimagesink->displayed_buffer_count < _CHECK_DISPLAYED_BUFFER_COUNT) {
+ xvimagesink->displayed_buffer_count++;
+ GST_WARNING_OBJECT(xvimagesink, "cnt %d - remove idx %d, buf %p, handle [%u %u %u], name [%u %u %u]",
+ xvimagesink->displayed_buffer_count,
+ i, xvimagesink->displaying_buffers[i].buffer,
+ xvimagesink->displaying_buffers[i].gem_handle[0],
+ xvimagesink->displaying_buffers[i].gem_handle[1],
+ xvimagesink->displaying_buffers[i].gem_handle[2],
+ xvimagesink->displaying_buffers[i].gem_name[0],
+ xvimagesink->displaying_buffers[i].gem_name[1],
+ xvimagesink->displaying_buffers[i].gem_name[2]);
+ } else {
+ GST_DEBUG_OBJECT(xvimagesink, "remove idx %d, buf %p, handle [%u %u %u], name [%u %u %u]",
+ i, xvimagesink->displaying_buffers[i].buffer,
+ xvimagesink->displaying_buffers[i].gem_handle[0],
+ xvimagesink->displaying_buffers[i].gem_handle[1],
+ xvimagesink->displaying_buffers[i].gem_handle[2],
+ xvimagesink->displaying_buffers[i].gem_name[0],
+ xvimagesink->displaying_buffers[i].gem_name[1],
+ xvimagesink->displaying_buffers[i].gem_name[2]);
+ }
+
+ /* decrease displaying buffer count */
+ xvimagesink->displaying_buffer_count--;
+
+ /* decrease ref count */
+ xvimagesink->displaying_buffers[i].ref_count--;
+
+ if (xvimagesink->displaying_buffers[i].ref_count > 0) {
+ GST_WARNING("ref count not zero[%d], skip close gem handle",
+ xvimagesink->displaying_buffers[i].ref_count);
+ break;
+ }
+
+ /* release flush buffer */
+ if (xvimagesink->flush_buffer) {
+ if (xvimagesink->flush_buffer->gem_name[0] == gem_name[0] &&
+ xvimagesink->flush_buffer->gem_name[1] == gem_name[1] &&
+ xvimagesink->flush_buffer->gem_name[2] == gem_name[2]) {
+ _release_flush_buffer(xvimagesink);
+ }
+ }
+
+ for (j = 0 ; j < XV_BUF_PLANE_NUM ; j++) {
+ if (xvimagesink->displaying_buffers[i].gem_handle[j] > 0) {
+ drm_close_gem(xvimagesink, &(xvimagesink->displaying_buffers[i].gem_handle[j]));
+ }
+ xvimagesink->displaying_buffers[i].gem_name[j] = 0;
+ xvimagesink->displaying_buffers[i].dmabuf_fd[j] = 0;
+ xvimagesink->displaying_buffers[i].bo[j] = NULL;
+ }
+
+ /* reset last_added_buffer_index */
+ if (xvimagesink->displaying_buffer_count < 1) {
+ xvimagesink->last_added_buffer_index = -1;
+ GST_DEBUG_OBJECT(xvimagesink, "displaying_buffer_count %d",
+ xvimagesink->displaying_buffer_count);
+ }
+
+ if (xvimagesink->displaying_buffers[i].buffer) {
+ gst_buffer_unref(xvimagesink->displaying_buffers[i].buffer);
+ xvimagesink->displaying_buffers[i].buffer = NULL;
+ } else {
+ GST_WARNING("no buffer to unref");
+ }
+ break;
+ }
+ }
+
+ /* unlock display buffer mutex */
+ g_mutex_unlock(xvimagesink->display_buffer_lock);
+
+ return;
+}
+
+
+static int _is_connected_to_external_display(GstXvImageSink *xvimagesink)
+{
+ Atom type_ret = 0;
+ int i = 0;
+ int ret = 0;
+ int size_ret = 0;
+ unsigned long num_ret = 0;
+ unsigned long bytes = 0;
+ unsigned char *prop_ret = NULL;
+ unsigned int data = 0;
+ int (*handler) (Display *, XErrorEvent *) = NULL;
+ Atom atom_output_external;
+
+ atom_output_external = XInternAtom(xvimagesink->xcontext->disp,
+ "XV_OUTPUT_EXTERNAL", False);
+ if (atom_output_external != None) {
+ /* set error handler */
+ error_caught = FALSE;
+ handler = XSetErrorHandler(gst_xvimagesink_handle_xerror);
- /* decrease displaying buffer count */
- xvimagesink->displaying_buffer_count--;
+ ret = XGetWindowProperty(xvimagesink->xcontext->disp,
+ xvimagesink->xwindow->win,
+ atom_output_external, 0, 0x7fffffff,
+ False, XA_CARDINAL, &type_ret, &size_ret,
+ &num_ret, &bytes, &prop_ret);
+ XSync(xvimagesink->xcontext->disp, FALSE);
+ if (ret != Success || error_caught) {
+ GST_WARNING_OBJECT(xvimagesink, "XGetWindowProperty failed");
+ if (prop_ret) {
+ XFree(prop_ret);
+ }
+ if (error_caught) {
+ GST_WARNING_OBJECT(xvimagesink, "error caught in XGetWindowProperty()");
+ }
+ if (handler) {
+ error_caught = FALSE;
+ XSetErrorHandler (handler);
+ }
+ return False;
+ }
- /* decrease ref count */
- xvimagesink->displaying_buffers[i].ref_count--;
+ if (handler) {
+ error_caught = FALSE;
+ XSetErrorHandler (handler);
+ }
- if (xvimagesink->displaying_buffers[i].ref_count > 0) {
- GST_WARNING("ref count not zero[%d], skip close gem handle",
- xvimagesink->displaying_buffers[i].ref_count);
- break;
+ if (!num_ret) {
+ GST_WARNING_OBJECT(xvimagesink, "XGetWindowProperty num_ret failed");
+ if (prop_ret) {
+ XFree(prop_ret);
}
+ return False;
+ }
- /* release flush buffer */
- if (xvimagesink->flush_buffer) {
- if (xvimagesink->flush_buffer->gem_name[0] == gem_name[0] &&
- xvimagesink->flush_buffer->gem_name[1] == gem_name[1] &&
- xvimagesink->flush_buffer->gem_name[2] == gem_name[2]) {
- _release_flush_buffer(xvimagesink);
+ if (prop_ret) {
+ switch (size_ret) {
+ case 8:
+ for (i = 0 ; i < num_ret ; i++) {
+ (&data)[i] = prop_ret[i];
}
- }
-
- for (j = 0 ; j < XV_BUF_PLANE_NUM ; j++) {
- if (xvimagesink->displaying_buffers[i].gem_handle[j] > 0) {
- drm_close_gem(xvimagesink, &(xvimagesink->displaying_buffers[i].gem_handle[j]));
+ break;
+ case 16:
+ for (i = 0 ; i < num_ret ; i++) {
+ ((unsigned short *)&data)[i] = ((unsigned short *)prop_ret)[i];
}
- xvimagesink->displaying_buffers[i].gem_name[j] = 0;
- xvimagesink->displaying_buffers[i].dmabuf_fd[j] = 0;
- xvimagesink->displaying_buffers[i].bo[j] = NULL;
- }
-
- /* reset last_added_buffer_index */
- if (xvimagesink->displaying_buffer_count < 1) {
- xvimagesink->last_added_buffer_index = -1;
- GST_DEBUG_OBJECT(xvimagesink, "displaying_buffer_count %d",
- xvimagesink->displaying_buffer_count);
- g_object_get(G_OBJECT(xvimagesink), "enable-last-buffer", &enable_last_buffer, NULL);
- if(!enable_last_buffer) {
- if (xvimagesink->cur_image) {
- GST_LOG_OBJECT (xvimagesink, "unreffing %p", xvimagesink->cur_image);
- gst_buffer_unref (GST_BUFFER_CAST (xvimagesink->cur_image));
- xvimagesink->cur_image = NULL;
- }
+ break;
+ case 32:
+ for (i = 0 ; i < num_ret ; i++) {
+ ((unsigned int *)&data)[i] = ((unsigned long *)prop_ret)[i];
}
+ break;
}
+ XFree(prop_ret);
+ prop_ret = NULL;
- if (xvimagesink->displaying_buffers[i].buffer) {
- gst_buffer_unref(xvimagesink->displaying_buffers[i].buffer);
- xvimagesink->displaying_buffers[i].buffer = NULL;
- } else {
- GST_WARNING("no buffer to unref");
- }
- break;
+ GST_WARNING_OBJECT(xvimagesink, "external display %d", data);
+
+ return (int)data;
+ } else {
+ GST_WARNING_OBJECT(xvimagesink, "prop_ret is NULL");
+ return False;
}
+ } else {
+ GST_WARNING_OBJECT(xvimagesink, "get XV_OUTPUT_EXTERNAL atom failed");
}
- /* unlock display buffer mutex */
- g_mutex_unlock(xvimagesink->display_buffer_lock);
-
- return;
-}
-
-
-static int _is_connected_to_external_display(GstXvImageSink *xvimagesink)
-{
- Atom type_ret = 0;
- int i = 0;
- int ret = 0;
- int size_ret = 0;
- unsigned long num_ret = 0;
- unsigned long bytes = 0;
- unsigned char *prop_ret = NULL;
- unsigned int data = 0;
- Atom atom_output_external;
-
- atom_output_external = XInternAtom(xvimagesink->xcontext->disp,
- "XV_OUTPUT_EXTERNAL", False);
- if (atom_output_external != None) {
- ret = XGetWindowProperty(xvimagesink->xcontext->disp,
- xvimagesink->xwindow->win,
- atom_output_external, 0, 0x7fffffff,
- False, XA_CARDINAL, &type_ret, &size_ret,
- &num_ret, &bytes, &prop_ret);
- if (ret != Success) {
- GST_WARNING_OBJECT(xvimagesink, "XGetWindowProperty failed");
- if (prop_ret) {
- XFree(prop_ret);
- }
- return False;
- }
-
- if (!num_ret) {
- GST_WARNING_OBJECT(xvimagesink, "XGetWindowProperty num_ret failed");
- if (prop_ret) {
- XFree(prop_ret);
- }
- return False;
- }
-
- if (prop_ret) {
- switch (size_ret) {
- case 8:
- for (i = 0 ; i < num_ret ; i++) {
- (&data)[i] = prop_ret[i];
- }
- break;
- case 16:
- for (i = 0 ; i < num_ret ; i++) {
- ((unsigned short *)&data)[i] = ((unsigned short *)prop_ret)[i];
- }
- break;
- case 32:
- for (i = 0 ; i < num_ret ; i++) {
- ((unsigned int *)&data)[i] = ((unsigned long *)prop_ret)[i];
- }
- break;
- }
- XFree(prop_ret);
- prop_ret = NULL;
-
- GST_WARNING_OBJECT(xvimagesink, "external display %d", data);
-
- return (int)data;
- } else {
- GST_WARNING_OBJECT(xvimagesink, "prop_ret is NULL");
- return False;
- }
- } else {
- GST_WARNING_OBJECT(xvimagesink, "get XV_OUTPUT_EXTERNAL atom failed");
- }
-
- return False;
+ return False;
}
#endif /* GST_EXT_XV_ENHANCEMENT */
XGCValues values;
#ifdef GST_EXT_XV_ENHANCEMENT
XSetWindowAttributes win_attr;
- XWindowAttributes root_attr;
+ XWindowAttributes root_attr = {0 , };
#endif /* GST_EXT_XV_ENHANCEMENT */
g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), NULL);
/* Make window manager not to change window size as Full screen */
win_attr.override_redirect = True;
-
if(!xvimagesink->is_pixmap)
XChangeWindowAttributes(xvimagesink->xcontext->disp, xwindow->win, CWOverrideRedirect, &win_attr);
#else /* GST_EXT_XV_ENHANCEMENT */
if (xvimagesink->handle_events) {
Atom wm_delete;
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+ XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xcontext->root, StructureNotifyMask | SubstructureNotifyMask);
+ XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
+ StructureNotifyMask | PointerMotionMask | KeyPressMask |
+ KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PropertyChangeMask);
+#else
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
StructureNotifyMask | PointerMotionMask | KeyPressMask |
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
+#endif
+
/* Tell the window manager we'd like delete client messages instead of
* being killed */
{
#ifdef GST_EXT_XV_ENHANCEMENT
Window root_window, child_window;
- XWindowAttributes root_attr;
+ XWindowAttributes root_attr = {0 , };
int cur_win_x = 0;
int cur_win_y = 0;
xvimagesink->render_rect.w = cur_win_width;
xvimagesink->render_rect.h = cur_win_height;
}
+ if (xvimagesink->scr_w != xvimagesink->xwindow->width ||
+ xvimagesink->scr_h != xvimagesink->xwindow->height) {
+ xvimagesink->is_multi_window = TRUE;
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "multiwindow-active", xvimagesink->is_multi_window);
+ GST_INFO_OBJECT(xvimagesink, "It may be multi-window scenario");
+ } else {
+ xvimagesink->is_multi_window = FALSE;
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "multiwindow-active", xvimagesink->is_multi_window);
+ GST_INFO_OBJECT(xvimagesink, "It may be full-window scenario");
+ }
GST_LOG_OBJECT(xvimagesink, "screen size %dx%d, current window geometry %d,%d,%dx%d, render_rect %d,%d,%dx%d",
xvimagesink->scr_w, xvimagesink->scr_h,
gst_xvimagesink_xwindow_clear (GstXvImageSink * xvimagesink,
GstXWindow * xwindow)
{
+#ifdef GST_EXT_XV_ENHANCEMENT
+ if (xvimagesink->is_subpicture_format)
+ return;
+#endif
g_return_if_fail (xwindow != NULL);
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
#ifdef GST_EXT_XV_ENHANCEMENT
GST_LOG("check x event");
+ Atom sc_status_atom = XInternAtom (xvimagesink->xcontext->disp, STR_ATOM_SCRNCONF_STATUS, FALSE);
+ Atom external_atom = XInternAtom (xvimagesink->xcontext->disp, "XV_OUTPUT_EXTERNAL", FALSE);
#endif /* GST_EXT_XV_ENHANCEMENT */
/* Handle Interaction, produces navigation events */
g_mutex_lock (xvimagesink->flow_lock);
g_mutex_lock (xvimagesink->x_lock);
}
-
/* Handle Expose */
while (XCheckWindowEvent (xvimagesink->xcontext->disp,
xvimagesink->xwindow->win, ExposureMask | StructureNotifyMask, &e)) {
/* Handle Display events */
while (XPending (xvimagesink->xcontext->disp)) {
XNextEvent (xvimagesink->xcontext->disp, &e);
-
switch (e.type) {
case ClientMessage:{
#ifdef GST_EXT_XV_ENHANCEMENT
XClientMessageEvent *cme = (XClientMessageEvent *)&e;
Atom buffer_atom = XInternAtom(xvimagesink->xcontext->disp, "XV_RETURN_BUFFER", False);
+ Atom qp_state_atom = XInternAtom(xvimagesink->xcontext->disp, "_E_ILLUME_QUICKPANEL_STATE", False);
+ Atom qp_on_atom = XInternAtom(xvimagesink->xcontext->disp, "_E_ILLUME_QUICKPANEL_ON", False);
+ Atom qp_off_atom = XInternAtom(xvimagesink->xcontext->disp, "_E_ILLUME_QUICKPANEL_OFF", False);
#endif /* GST_EXT_XV_ENHANCEMENT */
Atom wm_delete;
_remove_displaying_buffer(xvimagesink, gem_name);
break;
+ } else if (cme->message_type == sc_status_atom) {
+ int stat = cme->data.s[0];
+ if (stat == UTILX_SCRNCONF_STATUS_NULL) {
+ GST_WARNING ("get UTILX_SCRNCONF_STATUS_NULL event\n");
+ check_hdmi_connected(xvimagesink);
+ } else if (stat == UTILX_SCRNCONF_STATUS_CONNECT) {
+ GST_WARNING ("get UTILX_SCRNCONF_STATUS_CONNECT event\n");
+ check_hdmi_connected(xvimagesink);
+ } else if (stat == UTILX_SCRNCONF_STATUS_ACTIVE) {
+ GST_WARNING ("get UTILX_SCRNCONF_STATUS_ACTIVE event\n");
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "display-status", DISPLAY_STATUS_HDMI_ACTIVE);
+ check_hdmi_connected(xvimagesink);
+ } else {
+ GST_INFO ("Wrong status\n");
+ }
+ break;
+ } else if (cme->message_type == qp_state_atom) {
+ if ((Atom) cme->data.l[0] == qp_on_atom) {
+ /* quick panel on */
+ GST_WARNING_OBJECT(xvimagesink, "quick panel is ON");
+ xvimagesink->is_quick_panel_on = TRUE;
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "quick-panel-on", TRUE);
+ } else if ((Atom) cme->data.l[0] == qp_off_atom) {
+ /* quick panel off */
+ GST_WARNING_OBJECT(xvimagesink, "quick panel is OFF");
+ xvimagesink->is_quick_panel_on = FALSE;
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "quick-panel-on", FALSE);
+ }
+ break;
}
#endif /* GST_EXT_XV_ENHANCEMENT */
GST_WARNING_OBJECT(xvimagesink, "current window is FULLY HIDED");
+ xvimagesink->is_hided = TRUE;
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "hided-window", TRUE);
if (!_is_connected_to_external_display(xvimagesink)) {
-#if 0
- atom_stream = XInternAtom(xvimagesink->xcontext->disp,
- "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False);
-
- GST_WARNING_OBJECT(xvimagesink, "call STREAM_OFF");
-
- xvimagesink->is_hided = TRUE;
- atom_stream = XInternAtom(xvimagesink->xcontext->disp,
- "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False);
- if (atom_stream != None) {
- if (XvSetPortAttribute(xvimagesink->xcontext->disp,
- xvimagesink->xcontext->xv_port_id,
- atom_stream, 0) != Success) {
- GST_WARNING_OBJECT(xvimagesink, "STREAM OFF failed");
- }
-
- } else {
- GST_WARNING_OBJECT(xvimagesink, "atom_stream is NONE");
- }
-#endif
- xvimagesink->is_hided = TRUE;
+ GST_WARNING_OBJECT(xvimagesink, "no external display, calling XvStopVideo()");
XvStopVideo(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, xvimagesink->xwindow->win);
XSync(xvimagesink->xcontext->disp, FALSE);
} else {
- GST_WARNING_OBJECT(xvimagesink, "external display is enabled. skip STREAM_OFF");
+ if (GST_STATE(xvimagesink) == GST_STATE_PLAYING || xvimagesink->keep_external_fullscreen_prev) {
+ GST_WARNING_OBJECT(xvimagesink, "external display is enabled. skip XvStopVideo()");
+ } else {
+ GST_WARNING_OBJECT(xvimagesink, "external display is enabled, but not in the middle of playing, calling XvStopVideo()");
+ XvStopVideo(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, xvimagesink->xwindow->win);
+ XSync(xvimagesink->xcontext->disp, FALSE);
+ }
}
} else {
GST_INFO_OBJECT(xvimagesink, "current window is SHOWN");
g_mutex_unlock(xvimagesink->flow_lock);
xvimagesink->is_hided = FALSE;
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "hided-window", FALSE);
gst_xvimagesink_expose(GST_X_OVERLAY(xvimagesink));
g_mutex_lock(xvimagesink->flow_lock);
}
}
break;
+
+ case PropertyNotify:
+ {
+ XPropertyEvent *noti = (XPropertyEvent *)&e;
+ if(xvimagesink->xwindow) {
+ if (noti->window == xvimagesink->xwindow->win && noti->atom == external_atom) {
+ int value = 0;
+ get_window_prop_card32_property (xvimagesink->xcontext->disp,
+ xvimagesink->xwindow->win,
+ external_atom, XA_CARDINAL,
+ (unsigned int*)&value, 1);
+ if (value) {
+ // If value is 1, video will be displayed only on external display.
+ // video won't be displayed on LCD.
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "display-status", DISPLAY_STATUS_UNKNOWN_ACTIVE);
+ if(xvimagesink->external_width==0 && xvimagesink->external_height==0) {
+ xvimagesink->external_width = 1920;
+ xvimagesink->external_height = 1080;
+ GST_WARNING("connected unknown external display");
+ }
+ } else {
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "display-status", DISPLAY_STATUS_NULL); //NULL
+ if(xvimagesink->external_width!=0 || xvimagesink->external_height!=0) {
+ xvimagesink->external_width = 0;
+ xvimagesink->external_height = 0;
+ GST_WARNING("disconnected external display");
+ }
+ }
+
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "external-resolution", xvimagesink->external_width, xvimagesink->external_height);
+ GST_INFO ("external device : %s\n", (value)?"on":"off");
+ }
+ }
+ break;
+ }
+
#endif /* GST_EXT_XV_ENHANCEMENT */
default:
break;
}
}
-
g_mutex_unlock (xvimagesink->x_lock);
g_mutex_unlock (xvimagesink->flow_lock);
}
+#ifdef GST_EXT_XV_ENHANCEMENT
+static int
+get_window_prop_card32_property (Display* dpy, Window win, Atom atom, Atom type,
+ unsigned int *val, unsigned int len)
+{
+ unsigned char* prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ unsigned int i;
+ int num;
+ int ret;
+ int (*handler) (Display *, XErrorEvent *) = NULL;
+
+ prop_ret = NULL;
+
+ /* set error handler */
+ error_caught = FALSE;
+ handler = XSetErrorHandler(gst_xvimagesink_handle_xerror);
+
+ ret = XGetWindowProperty(dpy, win, atom, 0, 0x7fffffff, False,
+ type, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret);
+ XSync(dpy, FALSE);
+ if (ret != Success || error_caught) {
+ GST_WARNING("XGetWindowProperty failed [%d, %d]", ret, error_caught);
+ if (handler) {
+ error_caught = FALSE;
+ XSetErrorHandler (handler);
+ }
+ return -1;
+ }
+
+ if (handler) {
+ error_caught = FALSE;
+ XSetErrorHandler(handler);
+ }
+
+ if (type_ret != type || format_ret != 32)
+ num = -1;
+ else if (num_ret == 0 || !prop_ret)
+ num = 0;
+ else
+ {
+ if (num_ret < len)
+ len = num_ret;
+ for (i = 0; i < len; i++)
+ val[i] = ((unsigned long *)prop_ret)[i];
+ num = len;
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+static void check_hdmi_connected(GstXvImageSink *xvimagesink)
+{
+ char *str_output = NULL;
+ char str_status[10] = {0, };
+ char *str_resolution = NULL;
+ char str_dispmode[10] = {0, };
+ int external[2];
+ int cnt = 0;
+ char** list = NULL;
+ char** walk = NULL;
+
+ UtilxScrnConf *scrnconf = utilx_scrnconf_allocate();
+ if (!scrnconf)
+ {
+ GST_WARNING ("fail to allocate scrnconf");
+ return;
+ }
+ utilx_scrnconf_get_info (xvimagesink->xcontext->disp, scrnconf);
+
+ str_output = scrnconf->str_output;
+
+ if (scrnconf->status == UTILX_SCRNCONF_STATUS_CONNECT)
+ {
+ strcpy (str_status, "CONNECT");
+ }
+ else if (scrnconf->status == UTILX_SCRNCONF_STATUS_ACTIVE)
+ {
+ strcpy (str_status, "ACTIVE");
+
+ list = g_strsplit(scrnconf->str_resolution, "x", 2);
+
+ if (!list)
+ {
+ if (scrnconf)
+ utilx_scrnconf_free (scrnconf);
+ return;
+ }
+ for(walk = list; *walk; walk++)
+ {
+ external[cnt++] = atoi(*walk);
+ }
+ if (cnt!=2) {
+ GST_WARNING("data error");
+ if(scrnconf)
+ utilx_scrnconf_free (scrnconf);
+ g_strfreev(list);
+ return;
+ } else {
+ xvimagesink->external_width = external[0];
+ xvimagesink->external_height = external[1];
+ g_strfreev(list);
+ }
+ GST_INFO("external display : %d * %d", xvimagesink->external_width, xvimagesink->external_height);
+ g_signal_emit_by_name(G_OBJECT (xvimagesink), "external-resolution", xvimagesink->external_width, xvimagesink->external_height);
+ }
+ else
+ {
+ strcpy (str_status, "null");
+ }
+
+ str_resolution = scrnconf->str_resolution;
+
+ if (scrnconf->dispmode == UTILX_SCRNCONF_DISPMODE_CLONE)
+ {
+ strcpy (str_dispmode, "CLONE");
+ }
+ else if (scrnconf->dispmode == UTILX_SCRNCONF_DISPMODE_EXTENDED)
+ {
+ strcpy (str_dispmode, "EXTENDED");
+ }
+ else
+ {
+ strcpy (str_dispmode, "null");
+ }
+
+ GST_INFO ("[Display status] : %s, %s, %s, %s\n", str_output, str_status, str_resolution, str_dispmode);
+
+ if(scrnconf)
+ utilx_scrnconf_free (scrnconf);
+
+}
+
+static gboolean
+check_supportable_port_attr(GstXvImageSink * xvimagesink, gchar* attr_name)
+{
+ int i = 0;
+ int count = 0;
+
+ XvAttribute *attr = XvQueryPortAttributes(xvimagesink->xcontext->disp,
+ xvimagesink->xcontext->xv_port_id, &count);
+ if (attr) {
+ for (i = 0 ; i < count ; i++) {
+ if (!strcmp(attr[i].name, attr_name)) {
+ GST_INFO("%s[index %d] found", attr_name, i);
+ XFree(attr);
+ return TRUE;
+ }
+ }
+ XFree(attr);
+ } else {
+ GST_WARNING("XvQueryPortAttributes disp:%d, port_id:%d failed",
+ xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id);
+ }
+ return FALSE;
+}
+#endif //GST_EXT_XV_ENHANCEMENT
static void
gst_lookup_xv_port_from_adaptor (GstXContext * xcontext,
}
}
+#ifdef GST_EXT_XV_ENHANCEMENT
+static void
+gst_lookup_xv_port_for_subtitle (GstXContext * xcontext,
+ XvAdaptorInfo * adaptors, guint adaptor_no, guint nb_adaptors)
+{
+ int i;
+ if (!adaptors)
+ return;
+ for (i = 0; i < nb_adaptors; i++)
+ {
+ int min, max;
+ if (!(adaptors[i].type & XvOutputMask) ||
+ !(adaptors[i].type & XvStillMask))
+ continue;
+ min = adaptors[i].base_id;
+ max = adaptors[i].base_id + adaptors[i].num_ports;
+ for (adaptors[adaptor_no].num_ports = min; adaptors[adaptor_no].num_ports < max ; adaptors[adaptor_no].num_ports++)
+ {
+ if (XvGrabPort (xcontext->disp, adaptors[adaptor_no].num_ports, 0) == Success)
+ {
+ GST_INFO ("========================================");
+ GST_INFO ("XvGrabPort success : %ld", adaptors[adaptor_no].num_ports);
+ GST_INFO ("========================================");
+ xcontext->xv_port_id = adaptors[adaptor_no].num_ports;
+ return;
+ }
+ GST_WARNING ("fail : grab port(%ld)\n", adaptors[adaptor_no].num_ports);
+ usleep(10000);
+ }
+ }
+}
+#endif
+
+
/* This function generates a caps with all supported format by the first
Xv grabable port we find. We store each one of the supported formats in a
format list and append the format to a newly created caps that we return
if (xvimagesink->adaptor_no >= 0 &&
xvimagesink->adaptor_no < xcontext->nb_adaptors) {
/* Find xv port from user defined adaptor */
- gst_lookup_xv_port_from_adaptor (xcontext, adaptors,
- xvimagesink->adaptor_no);
+#ifdef GST_EXT_XV_ENHANCEMENT
+ if(!xvimagesink->subpicture)
+#endif
+ gst_lookup_xv_port_from_adaptor (xcontext, adaptors, xvimagesink->adaptor_no);
+#ifdef GST_EXT_XV_ENHANCEMENT
+ else
+ gst_lookup_xv_port_for_subtitle (xcontext, adaptors, xvimagesink->adaptor_no, xcontext->nb_adaptors);
+#endif
}
if (!xcontext->xv_port_id) {
/* Now search for an adaptor that supports XvImageMask */
for (i = 0; i < xcontext->nb_adaptors && !xcontext->xv_port_id; i++) {
- gst_lookup_xv_port_from_adaptor (xcontext, adaptors, i);
+#ifdef GST_EXT_XV_ENHANCEMENT
+ if(!xvimagesink->subpicture)
+#endif
+ gst_lookup_xv_port_from_adaptor (xcontext, adaptors, i);
+#ifdef GST_EXT_XV_ENHANCEMENT
+ else
+ gst_lookup_xv_port_for_subtitle (xcontext, adaptors, i, xcontext->nb_adaptors);
+#endif
xvimagesink->adaptor_no = i;
}
}
}
XvFreeEncodingInfo (encodings);
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+if (!xvimagesink->subpicture) {
+#endif
/* We get all image formats supported by our port */
formats = XvListImageFormats (xcontext->disp,
xcontext->xv_port_id, &nb_formats);
("No supported format found"));
return NULL;
}
+#ifdef GST_EXT_XV_ENHANCEMENT
+} //subpicture
+#endif
return caps;
}
{1, 1}, /* regular screen */
{16, 15}, /* PAL TV */
{11, 10}, /* 525 line Rec.601 video */
+#ifdef GST_EXT_XV_ENHANCEMENT
+ {44, 46}, /* Gear S Curved Display */
+#endif
{54, 59}, /* 625 line Rec.601 video */
{64, 45}, /* 1280x1024 on 16:9 display */
{5, 3}, /* 1280x1024 on 4:3 display */
g_mutex_lock (xvimagesink->x_lock);
xcontext->disp = XOpenDisplay (xvimagesink->display_name);
-
if (!xcontext->disp) {
g_mutex_unlock (xvimagesink->x_lock);
g_free (xcontext);
xcontext->caps = gst_xvimagesink_get_xv_support (xvimagesink, xcontext);
- if (!xcontext->caps) {
+ if (!xcontext->caps
+#ifdef GST_EXT_XV_ENHANCEMENT
+ && !xvimagesink->subpicture
+#endif
+ ) {
#ifdef GST_EXT_XV_ENHANCEMENT
{
int i = 0;
return NULL;
}
#ifdef HAVE_XSHM
- /* Search for XShm extension support */
- if (XShmQueryExtension (xcontext->disp) &&
- gst_xvimagesink_check_xshm_calls (xcontext)) {
- xcontext->use_xshm = TRUE;
- GST_DEBUG ("xvimagesink is using XShm extension");
- } else
+#ifdef GST_EXT_XV_ENHANCEMENT
+ if (!xvimagesink->subpicture) {
+#endif //GST_EXT_XV_ENHANCEMENT
+ /* Search for XShm extension support */
+ if (XShmQueryExtension (xcontext->disp) &&
+ gst_xvimagesink_check_xshm_calls (xcontext)) {
+ xcontext->use_xshm = TRUE;
+ GST_DEBUG ("xvimagesink is using XShm extension");
+ } else
#endif /* HAVE_XSHM */
- {
- xcontext->use_xshm = FALSE;
- GST_DEBUG ("xvimagesink is not using XShm extension");
- }
-
- xv_attr = XvQueryPortAttributes (xcontext->disp,
- xcontext->xv_port_id, &N_attr);
+ {
+ xcontext->use_xshm = FALSE;
+ GST_DEBUG ("xvimagesink is not using XShm extension");
+ }
+ xv_attr = XvQueryPortAttributes (xcontext->disp,
+ xcontext->xv_port_id, &N_attr);
+#ifdef GST_EXT_XV_ENHANCEMENT
+ }
+#endif //GST_EXT_XV_ENHANCEMENT
/* Generate the channels list */
for (i = 0; i < (sizeof (channels) / sizeof (char *)); i++) {
}
}
}
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+ if (!xvimagesink->subpicture) {
+#endif
if (xv_attr)
XFree (xv_attr);
-
#ifdef GST_EXT_XV_ENHANCEMENT
- set_display_mode(xcontext, xvimagesink->display_mode);
- set_csc_range(xcontext, xvimagesink->csc_range);
+ }
+ if(!xvimagesink->subpicture) {
+ set_display_mode(xvimagesink->xcontext, xvimagesink->display_mode);
+ set_csc_range(xcontext, xvimagesink->csc_range);
+ }
#endif /* GST_EXT_XV_ENHANCEMENT */
g_mutex_unlock (xvimagesink->x_lock);
GST_OBJECT_UNLOCK (xvimagesink);
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+ if (!xvimagesink->subpicture) {
+#endif
formats_list = xcontext->formats_list;
while (formats_list) {
g_list_free (xcontext->formats_list);
channels_list = xcontext->channels_list;
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+ }
+#endif
while (channels_list) {
GstColorBalanceChannel *channel = channels_list->data;
}
#endif
XCloseDisplay (xcontext->disp);
-
g_mutex_unlock (xvimagesink->x_lock);
g_free (xcontext);
GstXvImageSink *xvimagesink;
xvimagesink = GST_XVIMAGESINK (bsink);
-
- if (xvimagesink->xcontext)
+ if (xvimagesink->xcontext
+#ifdef GST_EXT_XV_ENHANCEMENT
+ && !xvimagesink->subpicture
+#endif
+) {
return gst_caps_ref (xvimagesink->xcontext->caps);
-
+ }
return
gst_caps_copy (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD
(xvimagesink)));
const GValue *fps;
guint num, den;
#ifdef GST_EXT_XV_ENHANCEMENT
- gboolean enable_last_buffer;
+ gboolean subtitle;
gchar *str_in = gst_caps_to_string(caps);
if(str_in == NULL) {
GST_ERROR("gst_caps_to_string() returns NULL...");
"In setcaps. Possible caps %" GST_PTR_FORMAT ", setting caps %"
GST_PTR_FORMAT, xvimagesink->xcontext->caps, caps);
- if (!gst_caps_can_intersect (xvimagesink->xcontext->caps, caps))
+ if (!gst_caps_can_intersect (xvimagesink->xcontext->caps, caps)
+#ifdef GST_EXT_XV_ENHANCEMENT
+ && !xvimagesink->subpicture
+#endif
+ )
goto incompatible_caps;
structure = gst_caps_get_structure (caps, 0);
ret &= gst_structure_get_int (structure, "height", &video_height);
fps = gst_structure_get_value (structure, "framerate");
ret &= (fps != NULL);
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+ if(gst_structure_get_boolean (structure, "subtitle", &subtitle) && xvimagesink->subpicture)
+ {
+ xvimagesink->is_subpicture_format = TRUE;
+ GST_LOG("It is type of subpicture and subtitle.");
+ }
+#endif
if (!ret)
goto incomplete_caps;
xvimagesink->aligned_width = video_width;
xvimagesink->aligned_height = video_height;
+#ifdef GST_EXT_ENABLE_HEVC
/*get combine prop of hevc*/
if(gst_structure_get_int (structure, "yuvcombine", &(xvimagesink->need_combine_data)))
{
/*Not need to combine data, just directly copy*/
xvimagesink->need_combine_data = 0;
}
-
+#endif
_remove_last_buffer(xvimagesink);
#endif /* GST_EXT_XV_ENHANCEMENT */
xvimagesink->video_width = video_width;
xvimagesink->video_height = video_height;
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+ if (!xvimagesink->subpicture) {
+#endif
im_format = gst_xvimagesink_get_format_from_caps (xvimagesink, caps);
if (im_format == -1)
goto invalid_format;
-
+#ifdef GST_EXT_XV_ENHANCEMENT
+ }
+#endif
/* get aspect ratio from caps if it's present, and
* convert video width and height to a display width and height
* using wd / hd = wv / hv * PARv / PARd */
} else {
g_mutex_unlock (xvimagesink->flow_lock);
}
+#ifdef GST_EXT_XV_ENHANCEMENT
+if (!xvimagesink->is_subpicture_format) {
+#endif
+ /* Creating our window and our image with the display size in pixels */
+ if (GST_VIDEO_SINK_WIDTH (xvimagesink) <= 0 ||
+ GST_VIDEO_SINK_HEIGHT (xvimagesink) <= 0)
+ goto no_display_size;
- /* Creating our window and our image with the display size in pixels */
- if (GST_VIDEO_SINK_WIDTH (xvimagesink) <= 0 ||
- GST_VIDEO_SINK_HEIGHT (xvimagesink) <= 0)
- goto no_display_size;
-
- g_mutex_lock (xvimagesink->flow_lock);
+ g_mutex_lock (xvimagesink->flow_lock);
#ifdef GST_EXT_XV_ENHANCEMENT
- if (!xvimagesink->xwindow && !xvimagesink->get_pixmap_cb) {
- GST_DEBUG_OBJECT (xvimagesink, "xwindow is null and not multi-pixmaps usage case");
+ if (!xvimagesink->xwindow && !xvimagesink->get_pixmap_cb) {
+ GST_DEBUG_OBJECT (xvimagesink, "xwindow is null and not multi-pixmaps usage case");
#else
- if (!xvimagesink->xwindow) {
+ if (!xvimagesink->xwindow) {
#endif
- xvimagesink->xwindow = gst_xvimagesink_xwindow_new (xvimagesink,
- GST_VIDEO_SINK_WIDTH (xvimagesink),
- GST_VIDEO_SINK_HEIGHT (xvimagesink));
+ xvimagesink->xwindow = gst_xvimagesink_xwindow_new (xvimagesink,
+ GST_VIDEO_SINK_WIDTH (xvimagesink),
+ GST_VIDEO_SINK_HEIGHT (xvimagesink));
+ }
}
/* After a resize, we want to redraw the borders in case the new frame size
if ((xvimagesink->xvimage) &&
((im_format != xvimagesink->xvimage->im_format) ||
(video_width != xvimagesink->xvimage->width) ||
- (video_height != xvimagesink->xvimage->height))) {
+ (video_height != xvimagesink->xvimage->height)) &&
+ (!xvimagesink->subpicture)) {
GST_DEBUG_OBJECT (xvimagesink,
"old format %" GST_FOURCC_FORMAT ", new format %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (xvimagesink->xvimage->im_format),
xvimagesink->xvimage = NULL;
}
+#ifdef GST_EXT_XV_ENHANCEMENT
+ /* In case of starting player with connecting external display, we have to check status.
+ * It will be unconditionally executed. */
+ if(!xvimagesink->is_subpicture_format)
+ check_hdmi_connected(xvimagesink);
+#endif
g_mutex_unlock (xvimagesink->flow_lock);
return TRUE;
("Error calculating the output display ratio of the video."));
return FALSE;
}
+#ifdef GST_EXT_XV_ENHANCEMENT
}
+#endif
static GstStateChangeReturn
gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
#ifdef GST_EXT_XV_ENHANCEMENT
- GST_WARNING("PAUSED_TO_PLAYING start");
-#if 0 /* This is removed in Xorg */
- g_mutex_lock (xvimagesink->x_lock);
- atom_preemption = XInternAtom( xvimagesink->xcontext->disp,
- "_USER_WM_PORT_ATTRIBUTE_PREEMPTION", False );
- if (atom_preemption != None) {
- if (XvSetPortAttribute(xvimagesink->xcontext->disp,
- xvimagesink->xcontext->xv_port_id,
- atom_preemption, 1 ) != Success) {
- GST_ERROR_OBJECT(xvimagesink, "%d: XvSetPortAttribute: preemption failed.\n", atom_preemption);
- }
- XSync (xvimagesink->xcontext->disp, FALSE);
- }
- g_mutex_unlock (xvimagesink->x_lock);
-#endif
+ if(vconf_set_int(VCONFKEY_XV_STATE, (xvimagesink->eos_received << 2) | XV_STATUS_PLAYING))
+ GST_WARNING("vconf set fail");
GST_WARNING("PAUSED_TO_PLAYING done");
+ xvimagesink->is_during_seek = FALSE;
+ xvimagesink->keep_external_fullscreen_prev = FALSE;
#endif /* GST_EXT_XV_ENHANCEMENT */
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
g_mutex_lock (xvimagesink->pool_lock);
xvimagesink->pool_invalid = TRUE;
g_mutex_unlock (xvimagesink->pool_lock);
+#ifdef GST_EXT_XV_ENHANCEMENT
+#endif /* GST_EXT_XV_ENHANCEMENT */
break;
default:
break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
#ifdef GST_EXT_XV_ENHANCEMENT
GST_WARNING("PLAYING_TO_PAUSED start");
-#if 0 /* This is removed in Xorg */
- g_mutex_lock (xvimagesink->x_lock);
- atom_preemption = XInternAtom( xvimagesink->xcontext->disp,
- "_USER_WM_PORT_ATTRIBUTE_PREEMPTION", False );
- if (atom_preemption != None) {
- if (XvSetPortAttribute(xvimagesink->xcontext->disp,
- xvimagesink->xcontext->xv_port_id,
- atom_preemption, 0 ) != Success) {
- GST_ERROR_OBJECT(xvimagesink, "%d: XvSetPortAttribute: preemption failed.\n", atom_preemption);
- }
- XSync (xvimagesink->xcontext->disp, FALSE);
- }
- g_mutex_unlock (xvimagesink->x_lock);
-#endif
+ g_mutex_lock (xvimagesink->flow_lock);
/* init displayed buffer count */
xvimagesink->displayed_buffer_count = 0;
+ g_mutex_lock (xvimagesink->x_lock);
+ if ((xvimagesink->is_hided || xvimagesink->is_quick_panel_on || xvimagesink->is_multi_window) && _is_connected_to_external_display(xvimagesink) && !xvimagesink->keep_external_fullscreen_prev) {
+ GST_WARNING_OBJECT(xvimagesink, "release external display mode");
+ XvStopVideo (xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id,
+ xvimagesink->xwindow->win);
+ XSync(xvimagesink->xcontext->disp, FALSE);
+ xvimagesink->skip_frame_due_to_external_dev = TRUE;
+ }
+ if((xvimagesink->is_hided_subpicture || xvimagesink->is_quick_panel_on_subpicture || xvimagesink->is_multi_window_subpicture)
+ && xvimagesink->is_subpicture_format && xvimagesink->pixmap_for_subpicture) {
+ GST_WARNING_OBJECT(xvimagesink, "calling XvStopVideo() for %d port [pixmap : %p]", xvimagesink->xcontext->xv_port_id, xvimagesink->pixmap_for_subpicture);
+ XvStopVideo(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, xvimagesink->pixmap_for_subpicture);
+ XSync(xvimagesink->xcontext->disp, FALSE);
+ }
+ g_mutex_unlock (xvimagesink->x_lock);
+ g_mutex_unlock (xvimagesink->flow_lock);
+ if(vconf_set_int(VCONFKEY_XV_STATE, (xvimagesink->eos_received << 2) | XV_STATUS_PAUSED))
+ GST_WARNING("vconf set fail");
GST_WARNING("PLAYING_TO_PAUSED done");
#endif /* GST_EXT_XV_ENHANCEMENT */
break;
!xvimagesink->get_pixmap_cb) {
if (gst_xvimagesink_make_flush_buffer(xvimagesink)) {
int i = 0;
- int is_existed = FALSE;
XV_DATA_PTR img_data = (XV_DATA_PTR) xvimagesink->xvimage->xvimage->data;
memset(img_data, 0x0, sizeof(XV_DATA));
XV_INIT_DATA(img_data);
GST_VIDEO_SINK_WIDTH (xvimagesink) = 0;
GST_VIDEO_SINK_HEIGHT (xvimagesink) = 0;
#ifdef GST_EXT_XV_ENHANCEMENT
- /* close drm */
- drm_fini(xvimagesink);
-
- /* init displaying_buffer_count */
- xvimagesink->displaying_buffer_count = 0;
-
GST_WARNING("PAUSED_TO_READY done");
#endif /* GST_EXT_XV_ENHANCEMENT */
break;
#endif /* GST_EXT_XV_ENHANCEMENT */
gst_xvimagesink_reset (xvimagesink);
#ifdef GST_EXT_XV_ENHANCEMENT
+ /* close drm */
+ drm_fini(xvimagesink);
+ /* init displaying_buffer_count */
+ xvimagesink->displaying_buffer_count = 0;
GST_WARNING("READY_TO_NULL done");
#endif /* GST_EXT_XV_ENHANCEMENT */
break;
}
}
-static void
-gst_xvimagesink_generate_YUV420_black_frame(int width, int height, unsigned char *buf, unsigned int *buf_size)
-{
- int i;
- int y_len = 0;
- int yuv_len = 0;
-
- y_len = width * height;
- yuv_len = (width * height * 3) >> 1;
-
- for (i = 0; i < y_len; i++)
- {
- buf[i] = 0x00;
- }
-
- for (; i < yuv_len ; i++)
- {
- buf[i] = 0x80;
- }
-
- *buf_size = yuv_len;
- GST_DEBUG("Black frame generated end");
- return;
-}
-
+#ifdef GST_EXT_ENABLE_HEVC
static void
gst_xvimagesink_combine_i420_scmn_data(GstXvImageSink *xvimagesink, GstBuffer *buf)
{
unsigned int outsize = 0;
unsigned char *temp_outbuf = xvimagesink->xvimage->xvimage->data;
+ int cnt = 0, j = 0;
+ unsigned char *temp_imgb;
SCMN_IMGB *imgb = NULL;
int stride, w, h, i;
GST_DEBUG("Begin");
- if(GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_LAST))
- {
- /*Gerate Black Frame data*/
- GST_DEBUG("General black frame ");
- gst_xvimagesink_generate_YUV420_black_frame(xvimagesink->xvimage->width, xvimagesink->xvimage->height, xvimagesink->xvimage->xvimage->data, &(xvimagesink->xvimage->size));
-
- GST_BUFFER_FLAG_UNSET(buf, GST_BUFFER_FLAG_LAST);
- return;
- }
-
imgb = (SCMN_IMGB *)GST_BUFFER_DATA(buf);
if(imgb == NULL || imgb->a[0] == NULL)
{
GST_DEBUG("End");
}
-
+#endif
#ifdef GST_EXT_XV_ENHANCEMENT
static gboolean gst_xvimagesink_make_flush_buffer(GstXvImageSink *xvimagesink)
GstXvImageFlushBuffer *flush_buffer = NULL;
GstXvImageDisplayingBuffer *display_buffer = NULL;
tbm_bo bo = NULL;
- tbm_bo temp_bo = NULL;
int size = 0;
int i = 0;
int ret = 0;
xvimagesink->last_added_buffer_index);
for (i = 0 ; i < XV_BUF_PLANE_NUM ; i++) {
- if (display_buffer->bo[i] || display_buffer->dmabuf_fd[i] > 0) {
+ if (display_buffer->bo[i]) {
tbm_bo_handle vaddr_src;
tbm_bo_handle vaddr_dst;
- /* get bo/fd size */
- if (display_buffer->bo[i]) {
- size = tbm_bo_size(display_buffer->bo[i]);
- } else if (display_buffer->dmabuf_fd[i] > 0 && display_buffer->gem_name[i] > 0) {
- temp_bo = tbm_bo_import(xvimagesink->bufmgr, display_buffer->gem_name[i]);
- if (temp_bo) {
- size = tbm_bo_size(temp_bo);
- tbm_bo_unref(temp_bo);
- temp_bo = NULL;
- } else {
- GST_ERROR_OBJECT(xvimagesink, "failed to import bo - name %u", display_buffer->gem_name[i]);
- }
- } else {
- GST_ERROR_OBJECT(xvimagesink, "bo %p, gem handle %u, name %u",
- display_buffer->bo[i],
- display_buffer->gem_handle[i],
- display_buffer->gem_name[i]);
- }
+ /* get bo size */
+ size = tbm_bo_size(display_buffer->bo[i]);
/* alloc bo */
- bo = tbm_bo_alloc(xvimagesink->bufmgr, size, TBM_BO_NONCACHABLE);
+ bo = tbm_bo_alloc(xvimagesink->bufmgr, size, TBM_BO_DEFAULT);
if (bo == NULL) {
GST_ERROR_OBJECT(xvimagesink, "bo alloc[%d] failed", size);
goto FLUSH_BUFFER_FAILED;
flush_buffer->bo[i] = bo;
/* get virtual address */
- if (display_buffer->bo[i]) {
- vaddr_src = tbm_bo_get_handle(display_buffer->bo[i], TBM_DEVICE_CPU);
- } else if (display_buffer->vaddr[i]) {
- vaddr_src.ptr = display_buffer->vaddr[i];
- } else {
- vaddr_src.ptr = NULL;
- }
- vaddr_dst = tbm_bo_get_handle(bo, TBM_DEVICE_CPU);
+ vaddr_src = tbm_bo_map(display_buffer->bo[i], TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE);
+ vaddr_dst = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE);
if (vaddr_src.ptr == NULL || vaddr_dst.ptr == NULL) {
GST_WARNING_OBJECT(xvimagesink, "get vaddr failed src %p, dst %p",
vaddr_src.ptr, vaddr_dst.ptr);
+ if (vaddr_src.ptr) {
+ tbm_bo_unmap(display_buffer->bo[i]);
+ }
+ if (vaddr_dst.ptr) {
+ tbm_bo_unmap(bo);
+ }
goto FLUSH_BUFFER_FAILED;
}
/* copy buffer */
memcpy(vaddr_dst.ptr, vaddr_src.ptr, size);
+ tbm_bo_unmap(display_buffer->bo[i]);
+ tbm_bo_unmap(bo);
+
GST_WARNING_OBJECT(xvimagesink, "[%d] copy done", i);
xvimagesink->flush_buffer = flush_buffer;
return ret;
FLUSH_BUFFER_FAILED:
- if (temp_bo) {
- tbm_bo_unref(temp_bo);
- temp_bo = NULL;
- }
-
if (flush_buffer) {
for (i = 0 ; i < XV_BUF_PLANE_NUM ; i++) {
if (flush_buffer->bo[i]) {
SCMN_IMGB *scmn_imgb = NULL;
gint format = 0;
gboolean ret = FALSE;
+ int res = -1;
+ int (*handler) (Display *, XErrorEvent *) = NULL;
+ Atom atom_overlay;
#endif /* GST_EXT_XV_ENHANCEMENT */
xvimagesink = GST_XVIMAGESINK (vsink);
/* if we have one... */
#ifdef GST_EXT_XV_ENHANCEMENT
g_mutex_lock (xvimagesink->flow_lock);
+ if (xvimagesink->skip_frame_due_to_external_dev) {
+ GST_WARNING_OBJECT( xvimagesink, "skip_frame_due_to_external_dev is TRUE. so skip show frame..." );
+ xvimagesink->skip_frame_due_to_external_dev = FALSE;
+ g_mutex_unlock (xvimagesink->flow_lock);
+ return GST_FLOW_OK;
+ }
+
#endif /* GST_EXT_XV_ENHANCEMENT */
- if (!xvimagesink->xvimage) {
- GST_DEBUG_OBJECT (xvimagesink, "creating our xvimage");
+ if (!xvimagesink->xvimage
+#ifdef GST_EXT_XV_ENHANCEMENT
+ && !xvimagesink->is_subpicture_format
+#endif
+ ) {
+ GST_DEBUG_OBJECT (xvimagesink, "creating our xvimage");
#ifdef GST_EXT_XV_ENHANCEMENT
format = gst_xvimagesink_get_format_from_caps(xvimagesink, GST_BUFFER_CAPS(buf));
img_data->CrBuf = (unsigned int)scmn_imgb->p[2];
img_data->BufType = XV_BUF_TYPE_LEGACY;
- /* set virtual address */
- img_data->vaddr[0] = scmn_imgb->a[0];
- img_data->vaddr[1] = scmn_imgb->a[1];
- img_data->vaddr[2] = scmn_imgb->a[2];
-
GST_DEBUG("YBuf[0x%x], CbBuf[0x%x], CrBuf[0x%x]",
img_data->YBuf, img_data->CbBuf, img_data->CrBuf );
} else if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_FD ||
GST_DEBUG("TBM bo %p %p %p", img_data->bo[0], img_data->bo[1], img_data->bo[2]);
}
- /* set virtual address */
- img_data->vaddr[0] = scmn_imgb->a[0];
- img_data->vaddr[1] = scmn_imgb->a[1];
- img_data->vaddr[2] = scmn_imgb->a[2];
-
/* check secure contents path */
if (scmn_imgb->tz_enable) {
if (xvimagesink->secure_path != SECURE_PATH_ON) {
do_set_secure = TRUE;
}
}
+ static gboolean is_exist = FALSE;
+ gchar *attr_name = g_strdup("_USER_WM_PORT_ATTRIBUTE_SECURE");
+ is_exist = check_supportable_port_attr(xvimagesink, attr_name);
+ g_free(attr_name);
- if (do_set_secure) {
+ if (do_set_secure && is_exist) {
Atom atom_secure = None;
g_mutex_lock (xvimagesink->x_lock);
atom_secure = XInternAtom(xvimagesink->xcontext->disp, "_USER_WM_PORT_ATTRIBUTE_SECURE", False);
g_mutex_unlock (xvimagesink->x_lock);
}
- if (xvimagesink->drm_level) {
+ is_exist = FALSE;
+ attr_name = g_strdup("_USER_WM_PORT_ATTRIBUTE_DRM_LEVEL");
+ is_exist = check_supportable_port_attr(xvimagesink, attr_name);
+ g_free(attr_name);
+
+
+ if (xvimagesink->drm_level && is_exist) {
Atom atom_drm = None;
g_mutex_lock (xvimagesink->x_lock);
atom_drm = XInternAtom( xvimagesink->xcontext->disp,
/* set current buffer */
xvimagesink->xvimage->current_buffer = buf;
- } else if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_FLUSH_BUFFER && !xvimagesink->get_pixmap_cb) {
+ } else if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_FLUSH_BUFFER) {
/* Flush Buffer, we are going to push a new buffer for recieving return buffer event from X */
GST_WARNING_OBJECT(xvimagesink, "BUF_SHARE_METHOD_FLUSH_BUFFER case");
if (gst_xvimagesink_make_flush_buffer(xvimagesink)) {
g_mutex_unlock (xvimagesink->flow_lock);
return GST_FLOW_OK;
}
+ } else if (xvimagesink->is_subpicture_format) {
+ GC gc;
+ xvimagesink->pixmap_for_subpicture = (Pixmap)GST_BUFFER_DATA(buf);
+ if(!xvimagesink->pixmap_for_subpicture) {
+ GST_ERROR("no pixmap");
+ g_mutex_unlock (xvimagesink->flow_lock);
+ return GST_FLOW_OK;
+ }
+ if(xvimagesink->video_width!=xvimagesink->external_width || xvimagesink->video_height!=xvimagesink->external_height) {
+ GST_ERROR("pixmap's size and current resolution are different");
+ g_mutex_unlock (xvimagesink->flow_lock);
+ return GST_FLOW_OK;
+ }
+ gc = XCreateGC (xvimagesink->xcontext->disp, xvimagesink->pixmap_for_subpicture, 0, 0);
+
+ GST_WARNING_OBJECT(xvimagesink, "xvimagesink pixmap ID : %p, port : %ld, GC : %p", xvimagesink->pixmap_for_subpicture,
+ xvimagesink->xcontext->xv_port_id, gc);
+
+ /* set error handler */
+ error_caught = FALSE;
+ handler = XSetErrorHandler(gst_xvimagesink_handle_xerror);
+
+ if(!xvimagesink->set_overlay_for_subpicture_just_once)
+ {
+ GST_LOG("setting attribute overlay");
+ atom_overlay = XInternAtom (xvimagesink->xcontext->disp, "_USER_WM_PORT_ATTRIBUTE_OVERLAY", FALSE);
+ XvSetPortAttribute (xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_overlay, 1);
+ XSync (xvimagesink->xcontext->disp, FALSE);
+ xvimagesink->set_overlay_for_subpicture_just_once = TRUE;
+ }
+ res = XvGetStill(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id,
+ xvimagesink->pixmap_for_subpicture, gc, 0, 0, xvimagesink->external_width, xvimagesink->external_height,
+ 0, 0, xvimagesink->external_width, xvimagesink->external_height);
+ XSync (xvimagesink->xcontext->disp, FALSE);
+
+ GST_WARNING_OBJECT(xvimagesink, "BUFFER TS=%" GST_TIME_FORMAT ", DUR=%" GST_TIME_FORMAT ", SIZE=%d\n",
+ GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buf)),
+ GST_TIME_ARGS(GST_BUFFER_DURATION(buf)),
+ GST_BUFFER_SIZE(buf));
+ if(gc) {
+ GST_DEBUG("FreeGC");
+ XFreeGC (xvimagesink->xcontext->disp, gc);
+ }
+ if (error_caught)
+ GST_WARNING_OBJECT(xvimagesink, "XvGetStill error");
+ else
+ GST_WARNING_OBJECT(xvimagesink, "XvGetStill %s ==> (width : %d, height : %d)", res == 0 ? "SUCCESS" : "FAIL", xvimagesink->external_width, xvimagesink->external_height);
+
+ /* Reset error handler */
+ if (handler) {
+ error_caught = FALSE;
+ XSetErrorHandler (handler);
+ }
} else {
GST_DEBUG("Normal format activated. fourcc = %d", xvimagesink->xvimage->im_format);
+#ifdef GST_EXT_ENABLE_HEVC
if(xvimagesink->need_combine_data == 1)
{
gst_xvimagesink_combine_i420_scmn_data(xvimagesink, buf);
}
else
+#endif
{
memcpy (xvimagesink->xvimage->xvimage->data,
GST_BUFFER_DATA (buf),
g_mutex_unlock (xvimagesink->flow_lock);
ret = gst_xvimagesink_xvimage_put(xvimagesink, xvimagesink->xvimage);
- if (!ret) {
+ if (!ret && !xvimagesink->is_subpicture_format) {
goto no_window;
}
#else /* GST_EXT_XV_ENHANCEMENT */
gst_xvimagesink_event (GstBaseSink * sink, GstEvent * event)
{
GstXvImageSink *xvimagesink = GST_XVIMAGESINK (sink);
+ if(GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)
+ {
+ if(vconf_set_int(VCONFKEY_XV_STATE, (xvimagesink->eos_received << 2) | XV_STATUS_SEEK))
+ GST_WARNING("vconf set fail");
+ }
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_TAG:{
break;
}
#ifdef GST_EXT_XV_ENHANCEMENT
+ case GST_EVENT_FLUSH_START:
+ GST_DEBUG_OBJECT (xvimagesink, "flush start");
+ break;
+ case GST_EVENT_FLUSH_STOP:
+ GST_DEBUG_OBJECT (xvimagesink, "flush stop");
+ xvimagesink->is_during_seek = TRUE;
+ break;
case GST_EVENT_CUSTOM_DOWNSTREAM:
{
const GstStructure *st = NULL;
GST_INFO_OBJECT (xvimagesink, "got a event for DRM playready");
xvimagesink->drm_level = DRM_LEVEL_1;
if (xvimagesink->drm_level && xvimagesink->xcontext) {
- Atom atom_drm = None;
- g_mutex_lock (xvimagesink->x_lock);
- atom_drm = XInternAtom( xvimagesink->xcontext->disp,
- "_USER_WM_PORT_ATTRIBUTE_DRM_LEVEL", False);
- if (atom_drm != None) {
- GST_INFO_OBJECT(xvimagesink, "DRM LEVEL -> 1");
- if (XvSetPortAttribute(xvimagesink->xcontext->disp,
- xvimagesink->xcontext->xv_port_id,
- atom_drm, xvimagesink->drm_level ) != Success) {
- GST_WARNING_OBJECT( xvimagesink, "Set DRM LEVEL 1 failed" );
+ static gboolean is_exist = FALSE;
+ gchar *attr_name = g_strdup("_USER_WM_PORT_ATTRIBUTE_DRM_LEVEL");
+ is_exist = check_supportable_port_attr(xvimagesink, attr_name);
+ g_free(attr_name);
+
+ if(is_exist)
+ {
+ Atom atom_drm = None;
+ g_mutex_lock (xvimagesink->x_lock);
+ atom_drm = XInternAtom( xvimagesink->xcontext->disp,
+ "_USER_WM_PORT_ATTRIBUTE_DRM_LEVEL", False);
+ if (atom_drm != None) {
+ GST_INFO_OBJECT(xvimagesink, "DRM LEVEL -> 1");
+ if (XvSetPortAttribute(xvimagesink->xcontext->disp,
+ xvimagesink->xcontext->xv_port_id,
+ atom_drm, xvimagesink->drm_level ) != Success) {
+ GST_WARNING_OBJECT( xvimagesink, "Set DRM LEVEL 1 failed" );
+ }
+ XSync (xvimagesink->xcontext->disp, FALSE);
+ xvimagesink->drm_level = DRM_LEVEL_0;
}
- XSync (xvimagesink->xcontext->disp, FALSE);
- xvimagesink->drm_level = DRM_LEVEL_0;
+ g_mutex_unlock (xvimagesink->x_lock);
}
- g_mutex_unlock (xvimagesink->x_lock);
}
}
}
break;
}
+ case GST_EVENT_EOS:
+ xvimagesink->eos_received = TRUE;
+ GST_DEBUG_OBJECT(xvimagesink, "got eos");
+ break;
+ case GST_EVENT_NEWSEGMENT:
+ xvimagesink->eos_received = FALSE;
+ GST_DEBUG_OBJECT(xvimagesink, "got newsegment event");
+ break;
#endif
default:
break;
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
+ if (xvimagesink->subpicture)
+ return;
+
/* If the element has not initialized the X11 context try to do so */
if (!xvimagesink->xcontext && !(xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink))) {
/* we have thrown a GST_ELEMENT_ERROR now */
xvimagesink->render_rect.h = attr.height;
}
if (xvimagesink->handle_events) {
+#ifdef GST_EXT_XV_ENHANCEMENT
+ XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xcontext->root, StructureNotifyMask | SubstructureNotifyMask);
+ XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
+ StructureNotifyMask | PointerMotionMask | KeyPressMask |
+ KeyReleaseMask | PropertyChangeMask);
+#else
XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
StructureNotifyMask | PointerMotionMask | KeyPressMask |
KeyReleaseMask);
- }
+#endif
+ }
#ifdef GST_EXT_XV_ENHANCEMENT
/* Setting an error handler to catch failure */
error_caught = FALSE;
GST_INFO_OBJECT(xvimagesink, "Overlay window exposed. update it");
#endif /* GST_EXT_XV_ENHANCEMENT */
gst_xvimagesink_xvimage_put (xvimagesink, NULL);
-
}
static void
if (handle_events) {
if (xvimagesink->xwindow->internal) {
+#ifdef GST_EXT_XV_ENHANCEMENT
+ XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xcontext->root, StructureNotifyMask | SubstructureNotifyMask);
+#endif
XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xwindow->win,
#ifdef GST_EXT_XV_ENHANCEMENT
- ExposureMask | StructureNotifyMask | PointerMotionMask | VisibilityChangeMask |
+ ExposureMask | StructureNotifyMask | PointerMotionMask | VisibilityChangeMask | PropertyChangeMask |
#else /* GST_EXT_XV_ENHANCEMENT */
ExposureMask | StructureNotifyMask | PointerMotionMask |
#endif /* GST_EXT_XV_ENHANCEMENT */
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
} else {
+#ifdef GST_EXT_XV_ENHANCEMENT
+ XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xcontext->root, StructureNotifyMask | SubstructureNotifyMask);
+#endif
XSelectInput (xvimagesink->xcontext->disp, xvimagesink->xwindow->win,
#ifdef GST_EXT_XV_ENHANCEMENT
- ExposureMask | StructureNotifyMask | PointerMotionMask | VisibilityChangeMask |
+ ExposureMask | StructureNotifyMask | PointerMotionMask | VisibilityChangeMask | PropertyChangeMask |
#else /* GST_EXT_XV_ENHANCEMENT */
ExposureMask | StructureNotifyMask | PointerMotionMask |
#endif /* GST_EXT_XV_ENHANCEMENT */
case PROP_DISPLAY_MODE:
{
int set_mode = g_value_get_enum (value);
-
g_mutex_lock(xvimagesink->flow_lock);
- g_mutex_lock(xvimagesink->x_lock);
-
- if (xvimagesink->display_mode != set_mode) {
- if (xvimagesink->xcontext) {
- /* set display mode */
- if (set_display_mode(xvimagesink->xcontext, set_mode)) {
- xvimagesink->display_mode = set_mode;
+ xvimagesink->display_mode = set_mode;
+ if(!xvimagesink->get_pixmap_cb && !xvimagesink->subpicture) {
+ if(xvimagesink->display_mode==DISPLAY_MODE_PRI_VIDEO_OFF_AND_SEC_VIDEO_FULL_SCREEN) {
+ if(!xvimagesink->is_multi_window || (GST_STATE(xvimagesink) == GST_STATE_PLAYING)) {
+ set_display_mode(xvimagesink->xcontext, xvimagesink->display_mode);
} else {
- GST_WARNING_OBJECT(xvimagesink, "display mode[%d] set failed.", set_mode);
+ GST_WARNING_OBJECT(xvimagesink, "display-mode will be set later. just save value now(%d)", xvimagesink->display_mode);
+ }
+ } else if(xvimagesink->display_mode==DISPLAY_MODE_PRI_VIDEO_ON_AND_SEC_VIDEO_CLONE){
+ if(xvimagesink->is_multi_window && (GST_STATE(xvimagesink) != GST_STATE_PLAYING)) {
+ set_display_mode(xvimagesink->xcontext, xvimagesink->display_mode);
+ } else {
+ GST_WARNING_OBJECT(xvimagesink, "display-mode will be set later. just save value now(%d)", xvimagesink->display_mode);
}
} else {
- /* "xcontext" is not created yet. It will be applied when xcontext is created. */
- GST_INFO_OBJECT(xvimagesink, "xcontext is NULL. display-mode will be set later.");
- xvimagesink->display_mode = set_mode;
+ GST_WARNING_OBJECT(xvimagesink, "unsupported format(%d)", xvimagesink->display_mode);
}
- } else {
- GST_INFO_OBJECT(xvimagesink, "skip display mode %d, because current mode is same", set_mode);
}
-
- g_mutex_unlock(xvimagesink->x_lock);
g_mutex_unlock(xvimagesink->flow_lock);
}
break;
g_mutex_lock(xvimagesink->x_lock);
if (xvimagesink->csc_range != set_range) {
- if (xvimagesink->xcontext) {
+ if (xvimagesink->xcontext && !xvimagesink->subpicture) {
/* set color space range */
if (set_csc_range(xvimagesink->xcontext, set_range)) {
xvimagesink->csc_range = set_range;
GST_INFO_OBJECT(xvimagesink, "xcontext is NULL. color space range will be set later.");
xvimagesink->csc_range = set_range;
}
+ } else if (xvimagesink->subpicture) {
+ GST_WARNING("skip to set csc range, because it is subpicture format.");
} else {
GST_INFO_OBJECT(xvimagesink, "skip to set csc range %d, because current is same", set_range);
}
case PROP_DISPLAY_GEOMETRY_METHOD:
xvimagesink->display_geometry_method = g_value_get_enum (value);
GST_LOG("Overlay geometry changed. update it");
- if (GST_STATE(xvimagesink) == GST_STATE_PAUSED) {
+ if (GST_STATE(xvimagesink) == GST_STATE_PAUSED || xvimagesink->eos_received) {
gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage);
}
break;
break;
case PROP_ROTATE_ANGLE:
xvimagesink->rotate_angle = g_value_get_enum (value);
- if (GST_STATE(xvimagesink) == GST_STATE_PAUSED) {
+ if (GST_STATE(xvimagesink) == GST_STATE_PAUSED || xvimagesink->eos_received) {
gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage);
}
break;
xvimagesink->visible = g_value_get_boolean (value);
}
} else if (!xvimagesink->visible && (g_value_get_boolean(value) == TRUE)) {
+ xvimagesink->visible = g_value_get_boolean (value);
g_mutex_unlock( xvimagesink->x_lock );
g_mutex_unlock( xvimagesink->flow_lock );
- xvimagesink->visible = g_value_get_boolean (value);
gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage);
g_mutex_lock( xvimagesink->flow_lock );
g_mutex_lock( xvimagesink->x_lock );
break;
case PROP_ZOOM_POS_Y:
xvimagesink->zoom_pos_y = g_value_get_int (value);
+ if (GST_STATE(xvimagesink) == GST_STATE_PAUSED || xvimagesink->eos_received) {
+ gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage);
+ }
+ break;
+ case PROP_ORIENTATION:
+ xvimagesink->orientation = g_value_get_enum (value);
+ GST_INFO("Orientation(%d) is changed", xvimagesink->orientation);
break;
case PROP_DST_ROI_MODE:
xvimagesink->dst_roi_mode = g_value_get_enum (value);
GST_INFO("Overlay geometry(%d) for ROI is changed", xvimagesink->dst_roi_mode);
break;
- case PROP_DST_ROI_ORIENTATION:
- xvimagesink->dst_roi_orientation = g_value_get_enum (value);
- GST_INFO("Orientation(%d) of ROI is changed", xvimagesink->dst_roi_orientation);
- break;
case PROP_DST_ROI_X:
xvimagesink->dst_roi.x = g_value_get_int (value);
break;
}
break;
}
+ case PROP_SUBPICTURE:
+ xvimagesink->subpicture = g_value_get_boolean (value);
+ break;
+ case PROP_EXTERNAL_WIDTH:
+ {
+ xvimagesink->external_width = g_value_get_int (value);
+ GST_LOG("[set property] xvimagesink->external_width : %d", xvimagesink->external_width);
+ break;
+ }
+ case PROP_EXTERNAL_HEIGHT:
+ {
+ xvimagesink->external_height = g_value_get_int (value);
+ GST_LOG("[set property] xvimagesink->external_height : %d", xvimagesink->external_height);
+ break;
+ }
case PROP_ENABLE_FLUSH_BUFFER:
xvimagesink->enable_flush_buffer = g_value_get_boolean(value);
break;
case PROP_PIXMAP:
xvimagesink->is_pixmap = g_value_get_boolean(value);
break;
+ case PROP_HIDED_WINDOW:
+ {
+ xvimagesink->is_hided_subpicture = g_value_get_boolean(value);
+ GST_WARNING_OBJECT(xvimagesink, "update hided_window %d", xvimagesink->is_hided_subpicture);
+ break;
+ }
+ case PROP_QUICKPANEL_ON:
+ {
+ xvimagesink->is_quick_panel_on_subpicture = g_value_get_boolean(value);
+ GST_WARNING_OBJECT(xvimagesink, "update quick panel status %d", xvimagesink->is_quick_panel_on_subpicture);
+ break;
+ }
+ case PROP_MULTIWINDOW_ACTIVE:
+ {
+ xvimagesink->is_multi_window_subpicture = g_value_get_boolean(value);
+ GST_WARNING_OBJECT(xvimagesink, "update multi-window status %d", xvimagesink->is_multi_window_subpicture);
+ break;
+ }
+ case PROP_KEEP_EXTERNAL_FULLSCREEN_POST:
+ {
+ xvimagesink->keep_external_fullscreen_post = g_value_get_boolean(value);
+ GST_WARNING_OBJECT(xvimagesink, "set property %d for setting _USER_WM_PORT_ATTRIBUTE_KEEP_EXT", xvimagesink->keep_external_fullscreen_post);
+ if(xvimagesink->keep_external_fullscreen_post) {
+ Atom atom_keep_ext;
+ atom_keep_ext = XInternAtom (xvimagesink->xcontext->disp, "_USER_WM_PORT_ATTRIBUTE_KEEP_EXT", False);
+ if(XvSetPortAttribute (xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, atom_keep_ext , 1) != Success)
+ {
+ GST_WARNING("set atom_keep_ext fail");
+ }
+ }
+ break;
+ }
+ case PROP_KEEP_EXTERNAL_FULLSCREEN_PREV:
+ {
+ xvimagesink->keep_external_fullscreen_prev = g_value_get_boolean(value);
+ GST_WARNING_OBJECT(xvimagesink, "set property %d for keeping external display to full screen", xvimagesink->keep_external_fullscreen_prev);
+ break;
+ }
+
#endif /* GST_EXT_XV_ENHANCEMENT */
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
case PROP_ZOOM_POS_Y:
g_value_set_int (value, xvimagesink->zoom_pos_y);
break;
+ case PROP_ORIENTATION:
+ g_value_set_enum (value, xvimagesink->orientation);
+ break;
case PROP_DST_ROI_MODE:
g_value_set_enum (value, xvimagesink->dst_roi_mode);
break;
- case PROP_DST_ROI_ORIENTATION:
- g_value_set_enum (value, xvimagesink->dst_roi_orientation);
- break;
case PROP_DST_ROI_X:
g_value_set_int (value, xvimagesink->dst_roi.x);
break;
case PROP_PIXMAP_CB_USER_DATA:
g_value_set_pointer (value, xvimagesink->get_pixmap_cb_user_data);
break;
+ case PROP_SUBPICTURE:
+ g_value_set_boolean (value, xvimagesink->subpicture);
+ break;
+ case PROP_EXTERNAL_WIDTH:
+ g_value_set_int (value, xvimagesink->external_width);
+ break;
+ case PROP_EXTERNAL_HEIGHT:
+ g_value_set_int (value, xvimagesink->external_height);
+ break;
case PROP_ENABLE_FLUSH_BUFFER:
g_value_set_boolean(value, xvimagesink->enable_flush_buffer);
break;
case PROP_PIXMAP:
g_value_set_boolean(value, xvimagesink->is_pixmap);
break;
-
+ case PROP_HIDED_WINDOW:
+ g_value_set_boolean(value, xvimagesink->is_hided_subpicture);
+ break;
+ case PROP_QUICKPANEL_ON:
+ g_value_set_boolean(value, xvimagesink->is_quick_panel_on_subpicture);
+ break;
+ case PROP_MULTIWINDOW_ACTIVE:
+ g_value_set_boolean(value, xvimagesink->is_multi_window_subpicture);
+ break;
+ case PROP_KEEP_EXTERNAL_FULLSCREEN_POST:
+ g_value_set_boolean(value, xvimagesink->keep_external_fullscreen_post);
+ break;
+ case PROP_KEEP_EXTERNAL_FULLSCREEN_PREV:
+ g_value_set_boolean(value, xvimagesink->keep_external_fullscreen_prev);
+ break;
#endif /* GST_EXT_XV_ENHANCEMENT */
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
gst_buffer_unref (GST_BUFFER_CAST (xvimagesink->xvimage));
xvimagesink->xvimage = NULL;
}
-#ifdef GST_EXT_XV_ENHANCEMENT
- if (xvimagesink->last_image) {
- gst_buffer_unref (GST_BUFFER_CAST (xvimagesink->last_image));
- xvimagesink->last_image = NULL;
- }
-#endif /* GST_EXT_XV_ENHANCEMENT */
gst_xvimagesink_imagepool_clear (xvimagesink);
xvimagesink->xwindow = NULL;
}
#ifdef GST_EXT_XV_ENHANCEMENT
+ if(xvimagesink->is_subpicture_format && xvimagesink->pixmap_for_subpicture) {
+ GST_INFO("calling XvStopVideo() for %d port [pixmap : %p]", xvimagesink->xcontext->xv_port_id, xvimagesink->pixmap_for_subpicture);
+ XvStopVideo(xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, xvimagesink->pixmap_for_subpicture);
+ xvimagesink->pixmap_for_subpicture = 0;
+ }
+
if (xvimagesink->get_pixmap_cb) {
int i = 0;
if (xvimagesink->xpixmap[0] && xvimagesink->xpixmap[0]->pixmap) {
xvimagesink->xwindow = NULL;
xvimagesink->xvimage = NULL;
xvimagesink->cur_image = NULL;
-#ifdef GST_EXT_XV_ENHANCEMENT
- xvimagesink->last_image = NULL;
-#endif /* GST_EXT_XV_ENHANCEMENT */
xvimagesink->hue = xvimagesink->saturation = 0;
xvimagesink->contrast = xvimagesink->brightness = 0;
#ifdef GST_EXT_XV_ENHANCEMENT
xvimagesink->xid_updated = FALSE;
- xvimagesink->display_mode = DISPLAY_MODE_DEFAULT;
+ xvimagesink->display_mode = DISPLAY_MODE_PRI_VIDEO_ON_AND_SEC_VIDEO_CLONE;
xvimagesink->csc_range = CSC_RANGE_NARROW;
xvimagesink->display_geometry_method = DEF_DISPLAY_GEOMETRY_METHOD;
xvimagesink->flip = DEF_DISPLAY_FLIP;
xvimagesink->zoom_pos_y = -1;
xvimagesink->rotation = -1;
xvimagesink->dst_roi_mode = DEF_ROI_DISPLAY_GEOMETRY_METHOD;
- xvimagesink->dst_roi_orientation = DEGREE_0;
+ xvimagesink->orientation = DEGREE_0;
xvimagesink->dst_roi.x = 0;
xvimagesink->dst_roi.y = 0;
xvimagesink->dst_roi.w = 0;
xvimagesink->aligned_height = 0;
xvimagesink->stop_video = FALSE;
xvimagesink->is_hided = FALSE;
+ xvimagesink->is_quick_panel_on = FALSE;
+ xvimagesink->is_multi_window = FALSE;
xvimagesink->drm_fd = -1;
xvimagesink->current_pixmap_idx = -1;
xvimagesink->get_pixmap_cb = NULL;
xvimagesink->bufmgr = NULL;
xvimagesink->flush_buffer = NULL;
xvimagesink->enable_flush_buffer = TRUE;
+ xvimagesink->pixmap_for_subpicture = 0;
+ xvimagesink->is_subpicture_format = FALSE;
+ xvimagesink->set_overlay_for_subpicture_just_once = FALSE;
+ xvimagesink->subpicture = FALSE;
+ xvimagesink->external_width = 0;
+ xvimagesink->external_height = 0;
+ xvimagesink->skip_frame_due_to_external_dev = FALSE;
+ xvimagesink->is_hided_subpicture = FALSE;
+ xvimagesink->is_quick_panel_on_subpicture = FALSE;
+ xvimagesink->is_multi_window_subpicture = FALSE;
+ xvimagesink->keep_external_fullscreen_post = FALSE;
+ xvimagesink->keep_external_fullscreen_prev = FALSE;
if(!XInitThreads())
GST_WARNING("FAIL to call XInitThreads()");
+ if(vconf_set_int(VCONFKEY_XV_STATE, (xvimagesink->eos_received << 2) | XV_STATUS_NULL))
+ GST_WARNING("vconf set fail");
#endif /* GST_EXT_XV_ENHANCEMENT */
}
g_param_spec_string ("device-name", "Adaptor name",
"The name of the video adaptor", NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_EXTERNAL_WIDTH,
+ g_param_spec_int ("external-width", "external width",
+ "width of external display", 0, G_MAXINT,
+ 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_EXTERNAL_HEIGHT,
+ g_param_spec_int ("external-height", "external height",
+ "height of external display", 0, G_MAXINT,
+ 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstXvImageSink:handle-expose
*
g_object_class_install_property(gobject_class, PROP_DISPLAY_MODE,
g_param_spec_enum("display-mode", "Display Mode",
"Display device setting",
- GST_TYPE_XVIMAGESINK_DISPLAY_MODE, DISPLAY_MODE_DEFAULT,
+ GST_TYPE_XVIMAGESINK_DISPLAY_MODE, DISPLAY_MODE_PRI_VIDEO_ON_AND_SEC_VIDEO_CLONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
- * GstXvImageSink:dst-roi-orientation
+ * GstXvImageSink:orientation
*
* Orientation information which will be used for ROI/ZOOM
*/
- g_object_class_install_property(gobject_class, PROP_DST_ROI_ORIENTATION,
- g_param_spec_enum("dst-roi-orientation", "Orientation information used for ROI/ZOOM",
+ g_object_class_install_property(gobject_class, PROP_ORIENTATION,
+ g_param_spec_enum("orientation", "Orientation information used for ROI/ZOOM",
"Orientation information for display",
GST_TYPE_XVIMAGESINK_ROTATE_ANGLE, DEGREE_0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_param_spec_pointer("pixmap-id-callback-userdata", "Pixmap-Id-Callback-Userdata",
"pointer of user data of callback function for getting pixmap id", G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_SUBPICTURE,
+ g_param_spec_boolean ("subpicture", "Subpicture",
+ "identifier of player for supporting subpicture", FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
/**
* GstXvImageSink:src-crop-x
*
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
+ * GstXvImageSink:hided-window
+ *
+ * check window status for hiding subtitle
+ */
+ g_object_class_install_property (gobject_class, PROP_HIDED_WINDOW,
+ g_param_spec_boolean("hided-window", "Hided window",
+ "check window status for hiding subtitle",
+ FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GstXvImageSink:quick-panel-on
+ *
+ * check quick-panel status for hiding subtitle
+ */
+ g_object_class_install_property (gobject_class, PROP_QUICKPANEL_ON,
+ g_param_spec_boolean("quick-panel-on", "Quick panel On",
+ "check quick-panel status for hiding subtitle",
+ FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GstXvImageSink:multiwindow-activated
+ *
+ * check multiwindow-activated status for hiding subtitle
+ */
+ g_object_class_install_property (gobject_class, PROP_MULTIWINDOW_ACTIVE,
+ g_param_spec_boolean("multiwindow-active", "Multiwindow Activate",
+ "check multiwindow status for hiding subtitle",
+ FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GstXvImageSink:keep-external-fullscreen-post
+ *
+ * keep video-only mode for special case, it is set immediately.
+ */
+ g_object_class_install_property (gobject_class, PROP_KEEP_EXTERNAL_FULLSCREEN_POST,
+ g_param_spec_boolean("keep-external-fullscreen-post", "Keep external display to full screen",
+ "set video-only mode forcedly for special case",
+ FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GstXvImageSink:keep-external-fullscreen-prev
+ *
+ * keep video-only mode for special case, it is set in advance.
+ */
+ g_object_class_install_property (gobject_class, PROP_KEEP_EXTERNAL_FULLSCREEN_PREV,
+ g_param_spec_boolean("keep-external-fullscreen-prev", "Keep external display to full screen",
+ "set video-only mode forcedly for special case",
+ FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
* GstXvImageSink::frame-render-error
*/
gst_xvimagesink_signals[SIGNAL_FRAME_RENDER_ERROR] = g_signal_new (
G_TYPE_BOOLEAN,
1,
G_TYPE_POINTER);
+ /**
+ * GstXvImageSink::display-status
+ */
+ gst_xvimagesink_signals[SIGNAL_DISPLAY_STATUS] = g_signal_new (
+ "display-status",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ /**
+ * GstXvImageSink::external-resolution
+ */
+ gst_xvimagesink_signals[SIGNAL_EXTERNAL_RESOLUTION] = g_signal_new (
+ "external-resolution",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL,
+ NULL,
+ gst_marshal_VOID__INT_INT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+ /**
+ * GstXvImageSink::hided-window
+ */
+ gst_xvimagesink_signals[SIGNAL_WINDOW_STATUS] = g_signal_new (
+ "hided-window",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_BOOLEAN);
+
+ /**
+ * GstXvImageSink::quick-panel-on
+ */
+ gst_xvimagesink_signals[SIGNAL_QUICKPANEL_STATUS] = g_signal_new (
+ "quick-panel-on",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_BOOLEAN);
+
+ /**
+ * GstXvImageSink::multiwindow-active
+ */
+ gst_xvimagesink_signals[SIGNAL_MULTIWINDOW_STATUS] = g_signal_new (
+ "multiwindow-active",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_BOOLEAN);
#endif /* GST_EXT_XV_ENHANCEMENT */
"xvimagesink",
"XFree86 video output plugin using Xv extension",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
+
+