summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-07-19 10:44:23 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-07-19 11:07:47 +0900
commit1a16a4f10b1c15c17a78d50538059d667974084a (patch)
treeffc7f1a3b1295d492c62e281b6f52c3cdeaf8fee
parent68eba4817a631214d7249c3e6ea3a833dfa84cc7 (diff)
downloadefl-1a16a4f10b1c15c17a78d50538059d667974084a.tar.gz
emtoion gst1 - workaround gst break between 1.10 and 1.12
so emotion was using a much older (pre 1.0) buffer map mechanism for getting video data. a new frame map api was added to gst in 1.0 but we didnt use it. gst broke the old buffer direct mapping for some codecs paths between 1.10 and 1.12. since we were using a very old method/api this broke us. this also happens to fix some vaapi issues (except where the buffer is simply never mappable ever). so this is kind of a fix (updating us to as more modern api) and a workaround. @fix
-rw-r--r--src/modules/emotion/gstreamer1/emotion_alloc.c11
-rw-r--r--src/modules/emotion/gstreamer1/emotion_convert.c66
-rw-r--r--src/modules/emotion/gstreamer1/emotion_gstreamer.h12
-rw-r--r--src/modules/emotion/gstreamer1/emotion_sink.c103
4 files changed, 150 insertions, 42 deletions
diff --git a/src/modules/emotion/gstreamer1/emotion_alloc.c b/src/modules/emotion/gstreamer1/emotion_alloc.c
index ea85e6cc4a..26a1ec3064 100644
--- a/src/modules/emotion/gstreamer1/emotion_alloc.c
+++ b/src/modules/emotion/gstreamer1/emotion_alloc.c
@@ -6,7 +6,7 @@
Emotion_Gstreamer_Buffer *
emotion_gstreamer_buffer_alloc(EmotionVideoSink *sink,
- GstBuffer *buffer,
+ GstBuffer *buffer,
GstVideoInfo *info,
Evas_Colorspace eformat,
int eheight,
@@ -16,16 +16,19 @@ emotion_gstreamer_buffer_alloc(EmotionVideoSink *sink,
if (!sink->priv->emotion_object) return NULL;
- send = malloc(sizeof (Emotion_Gstreamer_Buffer));
+ send = calloc(1, sizeof(Emotion_Gstreamer_Buffer));
if (!send) return NULL;
send->sink = gst_object_ref(sink);
send->frame = gst_buffer_ref(buffer);
send->info = *info;
+ if (gst_video_frame_map(&(send->vframe), info, buffer, GST_MAP_READ))
+ send->vfmapped = EINA_TRUE;
+ else
+ send->vfmapped = EINA_FALSE;
send->eformat = eformat;
send->eheight = eheight;
send->func = func;
-
return send;
}
@@ -39,7 +42,7 @@ emotion_gstreamer_buffer_free(Emotion_Gstreamer_Buffer *send)
Emotion_Gstreamer_Message *
emotion_gstreamer_message_alloc(Emotion_Gstreamer *ev,
- GstMessage *msg)
+ GstMessage *msg)
{
Emotion_Gstreamer_Message *send;
diff --git a/src/modules/emotion/gstreamer1/emotion_convert.c b/src/modules/emotion/gstreamer1/emotion_convert.c
index 97203f8890..8ee4399966 100644
--- a/src/modules/emotion/gstreamer1/emotion_convert.c
+++ b/src/modules/emotion/gstreamer1/emotion_convert.c
@@ -6,7 +6,8 @@
static inline void
_evas_video_bgrx_step(unsigned char *evas_data, const unsigned char *gst_data,
- unsigned int w, unsigned int h EINA_UNUSED, unsigned int output_height, unsigned int step)
+ unsigned int w, unsigned int h EINA_UNUSED,
+ unsigned int output_height, unsigned int step)
{
unsigned int x, y;
@@ -25,7 +26,9 @@ _evas_video_bgrx_step(unsigned char *evas_data, const unsigned char *gst_data,
}
static void
-_evas_video_bgr(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height, Emotion_Convert_Info *info EINA_UNUSED)
+_evas_video_bgr(unsigned char *evas_data, const unsigned char *gst_data,
+ unsigned int w, unsigned int h, unsigned int output_height,
+ Emotion_Convert_Info *info EINA_UNUSED)
{
// XXX: need to check offset and stride that gst provide and what they
// mean with a non-planar format like bgra
@@ -33,7 +36,9 @@ _evas_video_bgr(unsigned char *evas_data, const unsigned char *gst_data, unsigne
}
static void
-_evas_video_bgrx(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height, Emotion_Convert_Info *info EINA_UNUSED)
+_evas_video_bgrx(unsigned char *evas_data, const unsigned char *gst_data,
+ unsigned int w, unsigned int h, unsigned int output_height,
+ Emotion_Convert_Info *info EINA_UNUSED)
{
// XXX: need to check offset and stride that gst provide and what they
// mean with a non-planar format like bgra
@@ -41,7 +46,10 @@ _evas_video_bgrx(unsigned char *evas_data, const unsigned char *gst_data, unsign
}
static void
-_evas_video_bgra(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h EINA_UNUSED, unsigned int output_height, Emotion_Convert_Info *info EINA_UNUSED)
+_evas_video_bgra(unsigned char *evas_data, const unsigned char *gst_data,
+ unsigned int w, unsigned int h EINA_UNUSED,
+ unsigned int output_height,
+ Emotion_Convert_Info *info EINA_UNUSED)
{
unsigned int x, y;
@@ -65,51 +73,70 @@ _evas_video_bgra(unsigned char *evas_data, const unsigned char *gst_data, unsign
}
static void
-_evas_video_i420(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w EINA_UNUSED, unsigned int h EINA_UNUSED, unsigned int output_height, Emotion_Convert_Info *info EINA_UNUSED)
+_evas_video_i420(unsigned char *evas_data,
+ const unsigned char *gst_data EINA_UNUSED,
+ unsigned int w EINA_UNUSED, unsigned int h EINA_UNUSED,
+ unsigned int output_height,
+ Emotion_Convert_Info *info)
{
const unsigned char **rows, *ptr;
unsigned int i, j, jump, rh;
+ if (info->bpp[0] != 1) ERR("Plane 0 bpp != 1");
+ if (info->bpp[1] != 1) ERR("Plane 1 bpp != 1");
+ if (info->bpp[2] != 1) ERR("Plane 2 bpp != 1");
+
rh = output_height;
rows = (const unsigned char **)evas_data;
- ptr = gst_data + info->plane_offset[0];
+ ptr = info->plane_ptr[0];
jump = info->stride[0];
for (i = 0; i < rh; i++, ptr += jump) rows[i] = ptr;
- ptr = gst_data + info->plane_offset[1];
+ ptr = info->plane_ptr[1];
jump = info->stride[1];
for (j = 0; j < (rh / 2); j++, i++, ptr += jump) rows[i] = ptr;
- ptr = gst_data + info->plane_offset[2];
+ ptr = info->plane_ptr[2];
jump = info->stride[2];
for (j = 0; j < (rh / 2); j++, i++, ptr += jump) rows[i] = ptr;
}
static void
-_evas_video_yv12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w EINA_UNUSED, unsigned int h EINA_UNUSED, unsigned int output_height, Emotion_Convert_Info *info EINA_UNUSED)
+_evas_video_yv12(unsigned char *evas_data,
+ const unsigned char *gst_data EINA_UNUSED,
+ unsigned int w EINA_UNUSED, unsigned int h EINA_UNUSED,
+ unsigned int output_height,
+ Emotion_Convert_Info *info)
{
const unsigned char **rows, *ptr;
unsigned int i, j, jump, rh;
+ if (info->bpp[0] != 1) ERR("Plane 0 bpp != 1");
+ if (info->bpp[1] != 1) ERR("Plane 1 bpp != 1");
+ if (info->bpp[2] != 1) ERR("Plane 2 bpp != 1");
+
rh = output_height;
rows = (const unsigned char **)evas_data;
- ptr = gst_data + info->plane_offset[0];
+ ptr = info->plane_ptr[0];
jump = info->stride[0];
for (i = 0; i < rh; i++, ptr += jump) rows[i] = ptr;
- ptr = gst_data + info->plane_offset[2];
+ ptr = info->plane_ptr[1];
jump = info->stride[1];
for (j = 0; j < (rh / 2); j++, i++, ptr += jump) rows[i] = ptr;
- ptr = gst_data + info->plane_offset[1];
+ ptr = info->plane_ptr[2];
jump = info->stride[2];
for (j = 0; j < (rh / 2); j++, i++, ptr += jump) rows[i] = ptr;
}
static void
-_evas_video_yuy2(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h EINA_UNUSED, unsigned int output_height, Emotion_Convert_Info *info EINA_UNUSED)
+_evas_video_yuy2(unsigned char *evas_data, const unsigned char *gst_data,
+ unsigned int w, unsigned int h EINA_UNUSED,
+ unsigned int output_height,
+ Emotion_Convert_Info *info EINA_UNUSED)
{
const unsigned char **rows;
unsigned int i, stride;
@@ -124,19 +151,26 @@ _evas_video_yuy2(unsigned char *evas_data, const unsigned char *gst_data, unsign
}
static void
-_evas_video_nv12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w EINA_UNUSED, unsigned int h EINA_UNUSED, unsigned int output_height, Emotion_Convert_Info *info)
+_evas_video_nv12(unsigned char *evas_data,
+ const unsigned char *gst_data EINA_UNUSED,
+ unsigned int w EINA_UNUSED, unsigned int h EINA_UNUSED,
+ unsigned int output_height, Emotion_Convert_Info *info)
{
const unsigned char **rows, *ptr;
unsigned int i, j, jump, rh;
+ if (info->bpp[0] != 1) ERR("Plane 0 bpp != 1");
+ // XXX: not sure this should be 1 but 2 bytes per pixel... no?
+ //if (info->bpp[1] != 1) ERR("Plane 1 bpp != 1");
+
rh = output_height;
rows = (const unsigned char **)evas_data;
- ptr = gst_data + info->plane_offset[0];
+ ptr = info->plane_ptr[0];
jump = info->stride[0];
for (i = 0; i < rh; i++, ptr += jump) rows[i] = ptr;
- ptr = gst_data + info->plane_offset[1];
+ ptr = info->plane_ptr[1];
jump = info->stride[1];
for (j = 0; j < (rh / 2); j++, i++, ptr += jump) rows[i] = ptr;
}
diff --git a/src/modules/emotion/gstreamer1/emotion_gstreamer.h b/src/modules/emotion/gstreamer1/emotion_gstreamer.h
index d31c3dd519..2469ef28d4 100644
--- a/src/modules/emotion/gstreamer1/emotion_gstreamer.h
+++ b/src/modules/emotion/gstreamer1/emotion_gstreamer.h
@@ -39,8 +39,9 @@ typedef struct _Emotion_Gstreamer_Message Emotion_Gstreamer_Message;
struct _Emotion_Convert_Info
{
+ unsigned int bpp[4];
unsigned int stride[4];
- unsigned int plane_offset[4];
+ unsigned char *plane_ptr[4];
};
struct _Emotion_Gstreamer_Metadata
@@ -121,6 +122,8 @@ struct _EmotionVideoSinkPrivate {
GstBuffer *last_buffer;
GstMapInfo map_info;
+ GstVideoFrame last_vframe;
+
int frames;
int flapse;
double rtime;
@@ -136,18 +139,19 @@ struct _EmotionVideoSinkPrivate {
// Protected by the buffer mutex
Eina_Bool unlocked : 1;
Eina_Bool mapped : 1;
+ Eina_Bool vfmapped : 1;
};
struct _Emotion_Gstreamer_Buffer
{
+ GstVideoFrame vframe;
EmotionVideoSink *sink;
-
GstBuffer *frame;
-
GstVideoInfo info;
+ Evas_Video_Convert_Cb func;
Evas_Colorspace eformat;
int eheight;
- Evas_Video_Convert_Cb func;
+ Eina_Bool vfmapped : 1;
};
struct _Emotion_Gstreamer_Message
diff --git a/src/modules/emotion/gstreamer1/emotion_sink.c b/src/modules/emotion/gstreamer1/emotion_sink.c
index a6ccf5bb43..eaa7d77b6d 100644
--- a/src/modules/emotion/gstreamer1/emotion_sink.c
+++ b/src/modules/emotion/gstreamer1/emotion_sink.c
@@ -137,15 +137,28 @@ emotion_video_sink_dispose(GObject* object)
sink = EMOTION_VIDEO_SINK(object);
priv = sink->priv;
- if ((priv->mapped) && (priv->last_buffer))
+ if (priv->vfmapped)
{
if (priv->evas_object)
{
evas_object_image_size_set(priv->evas_object, 1, 1);
evas_object_image_data_set(priv->evas_object, NULL);
}
- gst_buffer_unmap(priv->last_buffer, &(priv->map_info));
- priv->mapped = EINA_FALSE;
+ gst_video_frame_unmap(&(priv->last_vframe));
+ priv->vfmapped = EINA_FALSE;
+ }
+ else
+ {
+ if ((priv->mapped) && (priv->last_buffer))
+ {
+ if (priv->evas_object)
+ {
+ evas_object_image_size_set(priv->evas_object, 1, 1);
+ evas_object_image_data_set(priv->evas_object, NULL);
+ }
+ gst_buffer_unmap(priv->last_buffer, &(priv->map_info));
+ priv->mapped = EINA_FALSE;
+ }
}
if (priv->last_buffer)
{
@@ -231,6 +244,16 @@ emotion_video_sink_stop(GstBaseSink* base_sink)
INF("sink stop");
eina_lock_take(&priv->m);
+ if (priv->vfmapped)
+ {
+ if (priv->evas_object)
+ {
+ evas_object_image_size_set(priv->evas_object, 1, 1);
+ evas_object_image_data_set(priv->evas_object, NULL);
+ }
+ gst_video_frame_unmap(&(priv->last_vframe));
+ priv->vfmapped = EINA_FALSE;
+ }
if (priv->last_buffer)
{
if (priv->evas_object)
@@ -401,10 +424,13 @@ emotion_video_sink_main_render(void *data)
buffer = gst_buffer_ref(send->frame);
- if (!gst_buffer_map(buffer, &map, GST_MAP_READ))
+ if (!send->vfmapped)
{
- ERR("Cannot map video buffer for read.\n");
- goto exit_point;
+ if (!gst_buffer_map(buffer, &map, GST_MAP_READ))
+ {
+ ERR("Cannot map video buffer for read.\n");
+ goto exit_point;
+ }
}
INF("sink main render [%i, %i] (source height: %i)", send->info.width, send->eheight, send->info.height);
@@ -434,14 +460,39 @@ emotion_video_sink_main_render(void *data)
info.plane_offset[2] = send->info.offset[2];
info.plane_offset[3] = send->info.offset[3];
*/
- info.stride[0] = send->info.stride[0];
- info.stride[1] = send->info.stride[1];
- info.stride[2] = send->info.stride[2];
- info.stride[3] = send->info.stride[3];
- info.plane_offset[0] = send->info.offset[0];
- info.plane_offset[1] = send->info.offset[1];
- info.plane_offset[2] = send->info.offset[2];
- info.plane_offset[3] = send->info.offset[3];
+ if (send->vfmapped)
+ {
+ GstVideoFrame *vframe = &(send->vframe);
+
+ map.data = GST_VIDEO_FRAME_PLANE_DATA(vframe, 0);
+ info.bpp[0] = GST_VIDEO_FRAME_COMP_PSTRIDE(vframe, 0);
+ info.bpp[1] = GST_VIDEO_FRAME_COMP_PSTRIDE(vframe, 1);
+ info.bpp[2] = GST_VIDEO_FRAME_COMP_PSTRIDE(vframe, 2);
+ info.bpp[3] = GST_VIDEO_FRAME_COMP_PSTRIDE(vframe, 3);
+ info.stride[0] = GST_VIDEO_FRAME_COMP_STRIDE(vframe, 0);
+ info.stride[1] = GST_VIDEO_FRAME_COMP_STRIDE(vframe, 1);
+ info.stride[2] = GST_VIDEO_FRAME_COMP_STRIDE(vframe, 2);
+ info.stride[3] = GST_VIDEO_FRAME_COMP_STRIDE(vframe, 3);
+ info.plane_ptr[0] = GST_VIDEO_FRAME_PLANE_DATA(vframe, 0);
+ info.plane_ptr[1] = GST_VIDEO_FRAME_PLANE_DATA(vframe, 1);
+ info.plane_ptr[2] = GST_VIDEO_FRAME_PLANE_DATA(vframe, 2);
+ info.plane_ptr[3] = GST_VIDEO_FRAME_PLANE_DATA(vframe, 3);
+ }
+ else
+ {
+ info.bpp[0] = 1;
+ info.bpp[1] = 1;
+ info.bpp[2] = 1;
+ info.bpp[3] = 1;
+ info.stride[0] = send->info.stride[0];
+ info.stride[1] = send->info.stride[1];
+ info.stride[2] = send->info.stride[2];
+ info.stride[3] = send->info.stride[3];
+ info.plane_ptr[0] = ((unsigned char *)map.data) + send->info.offset[0];
+ info.plane_ptr[1] = ((unsigned char *)map.data) + send->info.offset[1];
+ info.plane_ptr[2] = ((unsigned char *)map.data) + send->info.offset[2];
+ info.plane_ptr[3] = ((unsigned char *)map.data) + send->info.offset[3];
+ }
if (send->func)
send->func(evas_data, map.data, send->info.width, send->info.height, send->eheight, &info);
@@ -459,10 +510,26 @@ emotion_video_sink_main_render(void *data)
_emotion_frame_resize(priv->emotion_object, send->info.width, send->eheight, ratio);
- if ((priv->mapped) && (priv->last_buffer))
- gst_buffer_unmap(priv->last_buffer, &(priv->map_info));
- priv->map_info = map;
- priv->mapped = EINA_TRUE;
+ if (priv->vfmapped)
+ {
+ gst_video_frame_unmap(&(priv->last_vframe));
+ }
+ else
+ {
+ if ((priv->mapped) && (priv->last_buffer))
+ gst_buffer_unmap(priv->last_buffer, &(priv->map_info));
+ }
+ if (send->vfmapped)
+ {
+ priv->last_vframe = send->vframe;
+ priv->vfmapped = EINA_TRUE;
+ }
+ else
+ {
+ priv->vfmapped = EINA_FALSE;
+ priv->map_info = map;
+ priv->mapped = EINA_TRUE;
+ }
if (priv->last_buffer) gst_buffer_unref(priv->last_buffer);
priv->last_buffer = buffer;