forked from enlightenment/efl
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
This commit is contained in:
parent
68eba4817a
commit
1a16a4f10b
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue