static void evas_video_sink_samsung_main_render(void *data);
static void
-_evas_video_bgrx_step(unsigned char *evas_data, const unsigned char *gst_data,
- unsigned int w, unsigned int h __UNUSED__, unsigned int output_height, unsigned int step)
-{
- unsigned int x;
- unsigned int y;
-
- for (y = 0; y < output_height; ++y)
- {
- for (x = 0; x < w; x++)
- {
- evas_data[0] = gst_data[0];
- evas_data[1] = gst_data[1];
- evas_data[2] = gst_data[2];
- evas_data[3] = 255;
- gst_data += step;
- evas_data += 4;
- }
- }
-}
-
-static void
-_evas_video_bgr(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height)
-{
- _evas_video_bgrx_step(evas_data, gst_data, w, h, output_height, 3);
-}
-
-static void
-_evas_video_bgrx(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height)
-{
- _evas_video_bgrx_step(evas_data, gst_data, w, h, output_height, 4);
-}
-
-static void
-_evas_video_bgra(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h __UNUSED__, unsigned int output_height)
-{
- unsigned int x;
- unsigned int y;
-
- for (y = 0; y < output_height; ++y)
- {
- unsigned char alpha;
-
- for (x = 0; x < w; ++x)
- {
- alpha = gst_data[3];
- evas_data[0] = (gst_data[0] * alpha) / 255;
- evas_data[1] = (gst_data[1] * alpha) / 255;
- evas_data[2] = (gst_data[2] * alpha) / 255;
- evas_data[3] = alpha;
- gst_data += 4;
- evas_data += 4;
- }
- }
-}
-
-static void
-_evas_video_i420(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h __UNUSED__, unsigned int output_height)
-{
- const unsigned char **rows;
- unsigned int i, j;
- unsigned int rh;
-
- rh = output_height;
-
- rows = (const unsigned char **)evas_data;
-
- for (i = 0; i < rh; i++)
- rows[i] = &gst_data[i * w];
-
- for (j = 0; j < (rh / 2); j++, i++)
- rows[i] = &gst_data[h * w + j * (w / 2)];
-
- for (j = 0; j < (rh / 2); j++, i++)
- rows[i] = &gst_data[h * w + rh * (w / 4) + j * (w / 2)];
-}
-
-static void
-_evas_video_yv12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h __UNUSED__, unsigned int output_height)
-{
- const unsigned char **rows;
- unsigned int i, j;
- unsigned int rh;
-
- rh = output_height;
-
- rows = (const unsigned char **)evas_data;
-
- for (i = 0; i < rh; i++)
- rows[i] = &gst_data[i * w];
-
- for (j = 0; j < (rh / 2); j++, i++)
- rows[i] = &gst_data[h * w + rh * (w / 4) + j * (w / 2)];
-
- for (j = 0; j < (rh / 2); j++, i++)
- rows[i] = &gst_data[h * w + j * (w / 2)];
-}
-
-static void
-_evas_video_yuy2(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h __UNUSED__, unsigned int output_height)
-{
- const unsigned char **rows;
- unsigned int i;
-
- rows = (const unsigned char **)evas_data;
-
- for (i = 0; i < output_height; i++)
- rows[i] = &gst_data[i * w * 2];
-}
-
-static void
-_evas_video_nv12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h __UNUSED__, unsigned int output_height)
-{
- const unsigned char **rows;
- unsigned int i, j;
- unsigned int rh;
-
- rh = output_height;
-
- rows = (const unsigned char **)evas_data;
-
- for (i = 0; i < rh; i++)
- rows[i] = &gst_data[i * w];
-
- for (j = 0; j < (rh / 2); j++, i++)
- rows[i] = &gst_data[rh * w + j * w];
-}
-
-static void
-_evas_video_mt12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height __UNUSED__)
-{
- const unsigned char **rows;
- unsigned int i;
- unsigned int j;
-
- rows = (const unsigned char **)evas_data;
-
- for (i = 0; i < (h / 32) / 2; i++)
- rows[i] = &gst_data[i * w * 2 * 32];
-
- if ((h / 32) % 2)
- {
- rows[i] = &gst_data[i * w * 2 * 32];
- i++;
- }
-
- for (j = 0; j < ((h / 2) / 32) / 2; ++j, ++i)
- rows[i] = &gst_data[h * w + j * (w / 2) * 2 * 16];
-}
-
-static void
-_evas_video_st12_multiplane(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height __UNUSED__)
-{
- const GstMultiPlaneImageBuffer *mp_buf = (const GstMultiPlaneImageBuffer *) gst_data;
- const unsigned char **rows;
- unsigned int i;
- unsigned int j;
-
- rows = (const unsigned char **)evas_data;
-
- for (i = 0; i < (h / 32) / 2; i++)
- rows[i] = mp_buf->uaddr[0] + i * w * 2 * 32;
- if ((h / 32) % 2)
- {
- rows[i] = mp_buf->uaddr[0] + i * w * 2 * 32;
- i++;
- }
-
- for (j = 0; j < ((h / 2) / 16) / 2; j++, i++)
- {
- rows[i] = mp_buf->uaddr[1] + j * w * 2 * 16 * 2;
- }
- if (((h / 2) / 16) % 2)
- rows[i] = mp_buf->uaddr[1] + j * w * 2 * 16 * 2;
-}
-
-static void
-_evas_video_st12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w __UNUSED__, unsigned int h, unsigned int output_height __UNUSED__)
-{
- const SCMN_IMGB *imgb = (const SCMN_IMGB *) gst_data;
- const unsigned char **rows;
- unsigned int i, j;
-
- rows = (const unsigned char **)evas_data;
-
- for (i = 0; i < (h / 32) / 2; i++)
- rows[i] = imgb->uaddr[0] + i * imgb->stride[0] * 2 * 32;
- if ((h / 32) % 2)
- {
- rows[i] = imgb->uaddr[0] + i * imgb->stride[0] * 2 * 32;
- i++;
- }
-
- for (j = 0; j < (unsigned int) imgb->elevation[1] / 32 / 2; j++, i++)
- rows[i] = imgb->uaddr[1] + j * imgb->stride[1] * 32 * 2;
- if ((imgb->elevation[1] / 32) % 2)
- rows[i++] = imgb->uaddr[1] + j * imgb->stride[1] * 32 * 2;
-}
-
-static const struct {
- const char *name;
- guint32 fourcc;
- Evas_Colorspace eformat;
- Evas_Video_Convert_Cb func;
- Eina_Bool force_height;
-} colorspace_fourcc_convertion[] = {
- { "I420", GST_MAKE_FOURCC('I', '4', '2', '0'), EVAS_COLORSPACE_YCBCR422P601_PL, _evas_video_i420, EINA_TRUE },
- { "YV12", GST_MAKE_FOURCC('Y', 'V', '1', '2'), EVAS_COLORSPACE_YCBCR422P601_PL, _evas_video_yv12, EINA_TRUE },
- { "YUY2", GST_MAKE_FOURCC('Y', 'U', 'Y', '2'), EVAS_COLORSPACE_YCBCR422601_PL, _evas_video_yuy2, EINA_FALSE },
- { "NV12", GST_MAKE_FOURCC('N', 'V', '1', '2'), EVAS_COLORSPACE_YCBCR420NV12601_PL, _evas_video_nv12, EINA_TRUE },
- { "TM12", GST_MAKE_FOURCC('T', 'M', '1', '2'), EVAS_COLORSPACE_YCBCR420TM12601_PL, _evas_video_mt12, EINA_TRUE }
-};
-
-static const struct {
- const char *name;
- GstVideoFormat format;
- Evas_Colorspace eformat;
- Evas_Video_Convert_Cb func;
-} colorspace_format_convertion[] = {
- { "BGR", GST_VIDEO_FORMAT_BGR, EVAS_COLORSPACE_ARGB8888, _evas_video_bgr },
- { "BGRx", GST_VIDEO_FORMAT_BGRx, EVAS_COLORSPACE_ARGB8888, _evas_video_bgrx },
- { "BGRA", GST_VIDEO_FORMAT_BGRA, EVAS_COLORSPACE_ARGB8888, _evas_video_bgra }
-};
-
-static void
evas_video_sink_base_init(gpointer g_class)
{
GstElementClass* element_class;
{
priv->source_height = priv->height;
- for (i = 0; i < sizeof (colorspace_fourcc_convertion) / sizeof (colorspace_fourcc_convertion[0]); ++i)
+ for (i = 0; colorspace_fourcc_convertion[i].name != NULL; ++i)
if (fourcc == colorspace_fourcc_convertion[i].fourcc)
{
fprintf(stderr, "Found '%s'\n", colorspace_fourcc_convertion[i].name);
priv->source_height = priv->height;
- for (i = 0; i < sizeof (colorspace_format_convertion) / sizeof (colorspace_format_convertion[0]); ++i)
+ for (i = 0; colorspace_format_convertion[i].name != NULL; ++i)
if (format == colorspace_format_convertion[i].format)
{
fprintf(stderr, "Found '%s'\n", colorspace_format_convertion[i].name);
}
static void
+_update_emotion_fps(Emotion_Gstreamer_Video *ev)
+{
+ double tim;
+
+ if (!debug_fps) return ;
+
+ tim = ecore_time_get();
+ ev->frames++;
+
+ if (ev->rlapse == 0.0)
+ {
+ ev->rlapse = tim;
+ ev->flapse = ev->frames;
+ }
+ else if ((tim - ev->rlapse) >= 0.5)
+ {
+ printf("FRAME: %i, FPS: %3.1f\n",
+ ev->frames,
+ (ev->frames - ev->flapse) / (tim - ev->rlapse));
+ ev->rlapse = tim;
+ ev->flapse = ev->frames;
+ }
+}
+
+static void
evas_video_sink_samsung_main_render(void *data)
{
Emotion_Gstreamer_Buffer *send;
if (!priv || !priv->o || priv->unlocked)
goto exit_point;
+ if (send->ev->send)
+ {
+ emotion_gstreamer_buffer_free(send->ev->send);
+ send->ev->send = NULL;
+ }
+
if (!send->ev->stream && !send->force)
{
- if (send->ev->send)
- emotion_gstreamer_buffer_free(send->ev->send);
send->ev->send = send;
+ _emotion_frame_new(send->ev->obj);
goto exit_stream;
}
evas_object_geometry_get(priv->o, NULL, NULL, &w, &h);
- send->ev->fill.width = stride * w / priv->width;
- send->ev->fill.height = elevation * h / priv->height;
+ send->ev->fill.width = (double) stride / priv->width;
+ send->ev->fill.height = (double) elevation / priv->height;
evas_object_image_alpha_set(priv->o, 0);
evas_object_image_colorspace_set(priv->o, priv->eformat);
evas_object_image_size_set(priv->o, stride, elevation);
- evas_object_image_fill_set(priv->o, 0, 0, send->ev->fill.width, send->ev->fill.height);
+
+ _update_emotion_fps(send->ev);
evas_data = evas_object_image_data_get(priv->o, 1);
send->ev->play_started = 0;
}
- _emotion_frame_new(send->ev->obj);
+ if (!send->force)
+ {
+ _emotion_frame_new(send->ev->obj);
+ }
vstream = eina_list_nth(send->ev->video_streams, send->ev->video_stream_nbr - 1);
}
send->ev->ratio = (double) priv->width / (double) priv->height;
+ _emotion_frame_refill(send->ev->obj, send->ev->fill.width, send->ev->fill.height);
_emotion_frame_resize(send->ev->obj, priv->width, priv->height, send->ev->ratio);
- /* FIXME: why is last buffer not protected ? */
+ buffer = gst_buffer_ref(buffer);
+ if (send->ev->last_buffer) gst_buffer_unref(send->ev->last_buffer);
+ send->ev->last_buffer = buffer;
exit_point:
emotion_gstreamer_buffer_free(send);
if (!priv || !priv->o || priv->unlocked)
goto exit_point;
+ if (ev->send && send != ev->send)
+ {
+ emotion_gstreamer_buffer_free(ev->send);
+ ev->send = NULL;
+ }
+
if (!ev->stream && !send->force)
{
- if (ev->send)
- emotion_gstreamer_buffer_free(ev->send);
ev->send = send;
+ _emotion_frame_new(ev->obj);
evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height);
goto exit_stream;
}
ev->play_started = 0;
}
- _emotion_frame_new(ev->obj);
+ if (!send->force)
+ {
+ _emotion_frame_new(ev->obj);
+ }
gst_element_query_position(ev->pipeline, &fmt, &pos);
ev->position = (double)pos / (double)GST_SECOND;
}
static void
-_on_resize_fill(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
-{
- Emotion_Gstreamer_Video *ev = data;
-
- if (ev->samsung)
- evas_object_image_fill_set(obj, 0, 0, ev->fill.width, ev->fill.height);
-}
-
-static void
_video_resize(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__,
Evas_Coord w, Evas_Coord h)
{
Emotion_Gstreamer_Video *ev = data;
+#ifdef HAVE_ECORE_X
ecore_x_window_resize(ev->win, w, h);
+#endif
fprintf(stderr, "resize: %i, %i\n", w, h);
}
Evas_Coord x, Evas_Coord y)
{
Emotion_Gstreamer_Video *ev = data;
+#ifdef HAVE_ECORE_X
+ unsigned int pos[2];
fprintf(stderr, "move: %i, %i\n", x, y);
- ecore_x_window_move(ev->win, x, y);
+ pos[0] = x; pos[1] = y;
+ ecore_x_window_prop_card32_set(ev->win, ECORE_X_ATOM_E_VIDEO_POSITION, pos, 2);
+#endif
}
#if 0
{
Emotion_Gstreamer_Video *ev = data;
+ fprintf(stderr, "show xv\n");
+#ifdef HAVE_ECORE_X
ecore_x_window_show(ev->win);
+#endif
/* gst_pad_set_blocked_async(ev->teepad, TRUE, _block_pad_link_cb, ev); */
}
{
Emotion_Gstreamer_Video *ev = data;
+ fprintf(stderr, "hide xv\n");
+#ifdef HAVE_ECORE_X
ecore_x_window_hide(ev->win);
+#endif
/* gst_pad_set_blocked_async(ev->teepad, TRUE, _block_pad_unlink_cb, ev); */
}
static void
-_video_update_pixels(void *data, Evas_Object *obj, const Evas_Video_Surface *surface __UNUSED__)
+_video_update_pixels(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__)
{
Emotion_Gstreamer_Video *ev = data;
+ Emotion_Gstreamer_Buffer *send;
if (!ev->send) return ;
- ev->send->force = EINA_TRUE;
- evas_video_sink_main_render(ev->send);
+ send = ev->send;
+ send->force = EINA_TRUE;
ev->send = NULL;
+ evas_video_sink_main_render(send);
}
GstElement *
return NULL;
}
- evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, _on_resize_fill, ev);
-
if (!uri)
return NULL;
}
#if defined HAVE_ECORE_X && defined HAVE_XOVERLAY_H
- engines = evas_render_method_list();
+ if (window_manager_video)
+ {
+ engines = evas_render_method_list();
- engine = eina_list_nth(engines, evas_output_method_get(evas_object_evas_get(obj)) - 1);
+ engine = eina_list_nth(engines, evas_output_method_get(evas_object_evas_get(obj)) - 1);
- if (ev->priority && engine && strstr(engine, "_x11") != NULL)
- {
- Ecore_Evas *ee;
- Evas_Coord x, y, w, h;
- Ecore_X_Window win;
- Ecore_X_Window parent;
+ if (ev->priority && engine && strstr(engine, "_x11") != NULL)
+ {
+ Ecore_Evas *ee;
+ Evas_Coord x, y, w, h;
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
- evas_object_geometry_get(obj, &x, &y, &w, &h);
+ evas_object_geometry_get(obj, &x, &y, &w, &h);
- ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
+ ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
- if (w < 4) w = 4;
- if (h < 2) h = 2;
+ if (w < 4) w = 4;
+ if (h < 2) h = 2;
- /* Here we really need to have the help of the window manager, this code will change when we update E17. */
- parent = (Ecore_X_Window) ecore_evas_window_get(ee);
- fprintf(stderr, "parent: %x\n", parent);
+ /* Here we really need to have the help of the window manager, this code will change when we update E17. */
+ parent = (Ecore_X_Window) ecore_evas_window_get(ee);
+ fprintf(stderr, "parent: %x\n", parent);
- win = ecore_x_window_override_new(0, x, y, w, h);
- fprintf(stderr, "creating window: %x [%i, %i, %i, %i]\n", win, x, y, w, h);
- if (win)
- {
- ecore_x_window_show(win);
- xvsink = gst_element_factory_make("xvimagesink", NULL);
- if (xvsink)
- {
- Ecore_X_Atom atom;
-
- gst_x_overlay_set_window_handle(GST_X_OVERLAY(xvsink), win);
- ev->win = win;
-
- atom = ecore_x_atom_get("enlightenment.video");
- if (atom)
- {
- ecore_x_window_prop_card32_set(win, atom, &parent, 1);
- }
- }
- else
- {
- fprintf(stderr, "destroying win: %x\n", win);
- ecore_x_window_free(win);
- }
- }
+ win = ecore_x_window_new(0, x, y, w, h);
+ fprintf(stderr, "creating window: %x [%i, %i, %i, %i]\n", win, x, y, w, h);
+ if (win)
+ {
+ Ecore_X_Window_State state[] = { ECORE_X_WINDOW_STATE_SKIP_TASKBAR, ECORE_X_WINDOW_STATE_SKIP_PAGER };
+
+ ecore_x_netwm_window_state_set(win, state, 2);
+ ecore_x_window_hide(win);
+ xvsink = gst_element_factory_make("xvimagesink", NULL);
+ if (xvsink)
+ {
+ unsigned int pos[2];
+
+#ifdef HAVE_X_OVERLAY_SET
+ gst_x_overlay_set_window_handle(GST_X_OVERLAY(xvsink), win);
+#else
+ gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(xvsink), win);
+#endif
+ ev->win = win;
+
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_VIDEO_PARENT, &parent, 1);
+
+ pos[0] = x; pos[1] = y;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_VIDEO_POSITION, pos, 2);
+ }
+ else
+ {
+ fprintf(stderr, "destroying win: %x\n", win);
+ ecore_x_window_free(win);
+ }
+ }
+ }
+ evas_render_method_list_free(engines);
}
- evas_render_method_list_free(engines);
#else
# warning "no ecore_x or xoverlay"
#endif
g_object_set(G_OBJECT(playbin), "uri", uri, NULL);
evas_object_image_pixels_get_callback_set(obj, NULL, NULL);
- evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _on_resize_fill, ev);
ev->stream = EINA_TRUE;