emotion - gstreamer1 - fix yuv import funcs to use gst stride + offset
so our yuv import funcs for gstreamer 1.x engine were ignoring the plane offsets and strides provided by gstreamer. though this nicely shows that these numbers provided are actually wrong - at least in the testing with vaapi back-ends with gst. so this fixes emotions' badness but there is still badness in gst apparently. the numbers provided if used are just simply wrong for teh image data. commented code in the src to show how to "Fix it up" by forcing some alignment of content to get it to work. @fix
This commit is contained in:
parent
d87a65e825
commit
a85494a5b2
|
@ -8,8 +8,7 @@ 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 x;
|
||||
unsigned int y;
|
||||
unsigned int x, y;
|
||||
|
||||
for (y = 0; y < output_height; ++y)
|
||||
{
|
||||
|
@ -26,23 +25,28 @@ _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)
|
||||
_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
|
||||
_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(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
|
||||
_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 EINA_UNUSED, unsigned int output_height)
|
||||
_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;
|
||||
unsigned int y;
|
||||
unsigned int x, y;
|
||||
|
||||
// XXX: need to check offset and stride that gst provide and what they
|
||||
// mean with a non-planar format like bgra
|
||||
for (y = 0; y < output_height; ++y)
|
||||
{
|
||||
unsigned char alpha;
|
||||
|
@ -61,90 +65,80 @@ _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, unsigned int h, unsigned int output_height)
|
||||
_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)
|
||||
{
|
||||
const unsigned char **rows;
|
||||
unsigned int i, j;
|
||||
unsigned int rh;
|
||||
unsigned int stride_y, stride_uv;
|
||||
const unsigned char **rows, *ptr;
|
||||
unsigned int i, j, jump, rh;
|
||||
|
||||
rh = output_height;
|
||||
|
||||
rows = (const unsigned char **)evas_data;
|
||||
|
||||
stride_y = GST_ROUND_UP_4(w);
|
||||
stride_uv = GST_ROUND_UP_8(w) / 2;
|
||||
ptr = gst_data + info->plane_offset[0];
|
||||
jump = info->stride[0];
|
||||
for (i = 0; i < rh; i++, ptr += jump) rows[i] = ptr;
|
||||
|
||||
for (i = 0; i < rh; i++)
|
||||
rows[i] = &gst_data[i * stride_y];
|
||||
ptr = gst_data + info->plane_offset[1];
|
||||
jump = info->stride[1];
|
||||
for (j = 0; j < (rh / 2); j++, i++, ptr += jump) rows[i] = ptr;
|
||||
|
||||
for (j = 0; j < (rh / 2); j++, i++)
|
||||
rows[i] = &gst_data[h * stride_y + j * stride_uv];
|
||||
|
||||
for (j = 0; j < (rh / 2); j++, i++)
|
||||
rows[i] = &gst_data[h * stride_y +
|
||||
(rh / 2) * stride_uv +
|
||||
j * stride_uv];
|
||||
ptr = gst_data + info->plane_offset[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, unsigned int h, unsigned int output_height)
|
||||
_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)
|
||||
{
|
||||
const unsigned char **rows;
|
||||
unsigned int i, j;
|
||||
unsigned int rh;
|
||||
unsigned int stride_y, stride_uv;
|
||||
const unsigned char **rows, *ptr;
|
||||
unsigned int i, j, jump, rh;
|
||||
|
||||
rh = output_height;
|
||||
|
||||
rows = (const unsigned char **)evas_data;
|
||||
|
||||
stride_y = GST_ROUND_UP_4(w);
|
||||
stride_uv = GST_ROUND_UP_8(w) / 2;
|
||||
ptr = gst_data + info->plane_offset[0];
|
||||
jump = info->stride[0];
|
||||
for (i = 0; i < rh; i++, ptr += jump) rows[i] = ptr;
|
||||
|
||||
for (i = 0; i < rh; i++)
|
||||
rows[i] = &gst_data[i * stride_y];
|
||||
ptr = gst_data + info->plane_offset[2];
|
||||
jump = info->stride[1];
|
||||
for (j = 0; j < (rh / 2); j++, i++, ptr += jump) rows[i] = ptr;
|
||||
|
||||
for (j = 0; j < (rh / 2); j++, i++)
|
||||
rows[i] = &gst_data[h * stride_y +
|
||||
(rh / 2) * stride_uv +
|
||||
j * stride_uv];
|
||||
|
||||
for (j = 0; j < (rh / 2); j++, i++)
|
||||
rows[i] = &gst_data[h * stride_y + j * stride_uv];
|
||||
ptr = gst_data + info->plane_offset[1];
|
||||
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)
|
||||
_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;
|
||||
unsigned int stride;
|
||||
unsigned int i, stride;
|
||||
|
||||
// XXX: need to check offset and stride that gst provide and what they
|
||||
// mean with a non-planar format like yuy2
|
||||
rows = (const unsigned char **)evas_data;
|
||||
|
||||
stride = GST_ROUND_UP_4(w * 2);
|
||||
|
||||
for (i = 0; i < output_height; i++)
|
||||
rows[i] = &gst_data[i * stride];
|
||||
for (i = 0; i < output_height; i++) rows[i] = &gst_data[i * stride];
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_video_nv12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h EINA_UNUSED, unsigned int output_height)
|
||||
_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)
|
||||
{
|
||||
const unsigned char **rows;
|
||||
unsigned int i, j;
|
||||
unsigned int rh;
|
||||
const unsigned char **rows, *ptr;
|
||||
unsigned int i, j, jump, rh;
|
||||
|
||||
rh = output_height;
|
||||
|
||||
rows = (const unsigned char **)evas_data;
|
||||
|
||||
for (i = 0; i < rh; i++)
|
||||
rows[i] = &gst_data[i * w];
|
||||
ptr = gst_data + info->plane_offset[0];
|
||||
jump = info->stride[0];
|
||||
for (i = 0; i < rh; i++, ptr += jump) rows[i] = ptr;
|
||||
|
||||
for (j = 0; j < (rh / 2); j++, i++)
|
||||
rows[i] = &gst_data[rh * w + j * w];
|
||||
ptr = gst_data + info->plane_offset[1];
|
||||
jump = info->stride[1];
|
||||
for (j = 0; j < (rh / 2); j++, i++, ptr += jump) rows[i] = ptr;
|
||||
}
|
||||
|
||||
const ColorSpace_Format_Convertion colorspace_format_convertion[] = {
|
||||
|
|
|
@ -20,11 +20,14 @@
|
|||
|
||||
#include "emotion_modules.h"
|
||||
|
||||
typedef struct _Emotion_Convert_Info Emotion_Convert_Info;
|
||||
|
||||
typedef void (*Evas_Video_Convert_Cb)(unsigned char *evas_data,
|
||||
const unsigned char *gst_data,
|
||||
unsigned int w,
|
||||
unsigned int h,
|
||||
unsigned int output_height);
|
||||
unsigned int output_height,
|
||||
Emotion_Convert_Info *info);
|
||||
|
||||
typedef struct _EmotionVideoSinkPrivate EmotionVideoSinkPrivate;
|
||||
typedef struct _EmotionVideoSink EmotionVideoSink;
|
||||
|
@ -34,6 +37,12 @@ typedef struct _Emotion_Gstreamer_Metadata Emotion_Gstreamer_Metadata;
|
|||
typedef struct _Emotion_Gstreamer_Buffer Emotion_Gstreamer_Buffer;
|
||||
typedef struct _Emotion_Gstreamer_Message Emotion_Gstreamer_Message;
|
||||
|
||||
struct _Emotion_Convert_Info
|
||||
{
|
||||
unsigned int stride[4];
|
||||
unsigned int plane_offset[4];
|
||||
};
|
||||
|
||||
struct _Emotion_Gstreamer_Metadata
|
||||
{
|
||||
char *title;
|
||||
|
|
|
@ -366,6 +366,7 @@ emotion_video_sink_main_render(void *data)
|
|||
GstMapInfo map;
|
||||
unsigned char *evas_data;
|
||||
double ratio;
|
||||
Emotion_Convert_Info info;
|
||||
|
||||
send = data;
|
||||
|
||||
|
@ -401,7 +402,10 @@ emotion_video_sink_main_render(void *data)
|
|||
buffer = gst_buffer_ref(send->frame);
|
||||
|
||||
if (!gst_buffer_map(buffer, &map, GST_MAP_READ))
|
||||
goto exit_point;
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -409,12 +413,38 @@ emotion_video_sink_main_render(void *data)
|
|||
evas_object_image_colorspace_set(priv->evas_object, send->eformat);
|
||||
evas_object_image_size_set(priv->evas_object, send->info.width, send->eheight);
|
||||
|
||||
// XXX: need to handle GstVideoCropMeta to get video cropping right
|
||||
|
||||
evas_data = evas_object_image_data_get(priv->evas_object, 1);
|
||||
|
||||
// XXX: need to handle GstVideoCropMeta to get video cropping right
|
||||
// XXX: can't get crop meta from buffer (always null)
|
||||
// GstVideoCropMeta *meta;
|
||||
// meta = gst_buffer_get_video_crop_meta(buffer);
|
||||
// printf("META: %p\n", meta);
|
||||
|
||||
/* this just is a demo of broken vaapi back-end values for stride and
|
||||
* plane offset - the below is what i needed to fix them up for a few videos
|
||||
*/
|
||||
/*
|
||||
info.stride[0] = 64 * ((send->info.stride[0] + 63) / 64);
|
||||
info.stride[1] = 64 * ((send->info.stride[1] + 63) / 64);
|
||||
info.stride[2] = 64 * ((send->info.stride[2] + 63) / 64);
|
||||
info.stride[3] = 64 * ((send->info.stride[3] + 63) / 64);
|
||||
info.plane_offset[0] = send->info.offset[0];
|
||||
info.plane_offset[1] = (((send->info.height + 15) / 16) * 16) * info.stride[1];
|
||||
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->func)
|
||||
send->func(evas_data, map.data, send->info.width, send->info.height, send->eheight);
|
||||
send->func(evas_data, map.data, send->info.width, send->info.height, send->eheight, &info);
|
||||
else
|
||||
WRN("No way to decode %x colorspace !", send->eformat);
|
||||
|
||||
|
|
Loading…
Reference in New Issue