mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
Fix row strides for I420 (fixes #163159)
Original commit message from CVS: Fix row strides for I420 (fixes #163159)
This commit is contained in:
parent
02af9df0f7
commit
b43e960650
2 changed files with 88 additions and 95 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2005-01-19 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
|
* gst/videobox/gstvideobox.c: (gst_video_box_copy_plane_i420),
|
||||||
|
(gst_video_box_i420), (gst_video_box_chain):
|
||||||
|
Fix row strides for I420 (fixes #163159)
|
||||||
|
|
||||||
2005-01-19 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
2005-01-19 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
* gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_parse_packhead):
|
* gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_parse_packhead):
|
||||||
|
|
|
@ -84,13 +84,6 @@ GST_ELEMENT_DETAILS ("video box filter",
|
||||||
"Wim Taymans <wim@fluendo.com>");
|
"Wim Taymans <wim@fluendo.com>");
|
||||||
|
|
||||||
|
|
||||||
/* VideoBox signals and args */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
/* FILL ME */
|
|
||||||
LAST_SIGNAL
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DEFAULT_LEFT 0
|
#define DEFAULT_LEFT 0
|
||||||
#define DEFAULT_RIGHT 0
|
#define DEFAULT_RIGHT 0
|
||||||
#define DEFAULT_TOP 0
|
#define DEFAULT_TOP 0
|
||||||
|
@ -397,18 +390,55 @@ gst_video_box_sink_link (GstPad * pad, const GstCaps * caps)
|
||||||
return GST_PAD_LINK_OK;
|
return GST_PAD_LINK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GST_VIDEO_I420_Y_OFFSET(width,height) (0)
|
#define ROUND_UP_2(x) (((x)+1)&~1)
|
||||||
#define GST_VIDEO_I420_U_OFFSET(width,height) ((width)*(height))
|
#define ROUND_UP_4(x) (((x)+3)&~3)
|
||||||
#define GST_VIDEO_I420_V_OFFSET(width,height) ((width)*(height) + ((width/2)*(height/2)))
|
#define ROUND_UP_8(x) (((x)+7)&~7)
|
||||||
|
|
||||||
#define GST_VIDEO_I420_Y_ROWSTRIDE(width) (width)
|
/* see gst-plugins/gst/games/gstvideoimage.c, paint_setup_I420() */
|
||||||
#define GST_VIDEO_I420_U_ROWSTRIDE(width) ((width)/2)
|
#define GST_VIDEO_I420_Y_ROWSTRIDE(width) (ROUND_UP_4(width))
|
||||||
#define GST_VIDEO_I420_V_ROWSTRIDE(width) ((width)/2)
|
#define GST_VIDEO_I420_U_ROWSTRIDE(width) (ROUND_UP_8(width)/2)
|
||||||
|
#define GST_VIDEO_I420_V_ROWSTRIDE(width) ((ROUND_UP_8(GST_VIDEO_I420_Y_ROWSTRIDE(width)))/2)
|
||||||
|
|
||||||
|
#define GST_VIDEO_I420_Y_OFFSET(w,h) (0)
|
||||||
|
#define GST_VIDEO_I420_U_OFFSET(w,h) (GST_VIDEO_I420_Y_OFFSET(w,h)+(GST_VIDEO_I420_Y_ROWSTRIDE(w)*ROUND_UP_2(h)))
|
||||||
|
#define GST_VIDEO_I420_V_OFFSET(w,h) (GST_VIDEO_I420_U_OFFSET(w,h)+(GST_VIDEO_I420_U_ROWSTRIDE(w)*ROUND_UP_2(h)/2))
|
||||||
|
|
||||||
|
#define GST_VIDEO_I420_SIZE(w,h) (GST_VIDEO_I420_V_OFFSET(w,h)+(GST_VIDEO_I420_V_ROWSTRIDE(w)*ROUND_UP_2(h)/2))
|
||||||
|
|
||||||
static int yuv_colors_Y[] = { 16, 150, 29 };
|
static int yuv_colors_Y[] = { 16, 150, 29 };
|
||||||
static int yuv_colors_U[] = { 128, 46, 255 };
|
static int yuv_colors_U[] = { 128, 46, 255 };
|
||||||
static int yuv_colors_V[] = { 128, 21, 107 };
|
static int yuv_colors_V[] = { 128, 21, 107 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_video_box_copy_plane_i420 (GstVideoBox * video_box, guint8 * src,
|
||||||
|
guint8 * dest, gint br, gint bl, gint bt, gint bb, gint src_crop_width,
|
||||||
|
gint src_crop_height, gint src_stride, gint dest_width, gint dest_stride,
|
||||||
|
guint8 fill_color)
|
||||||
|
{
|
||||||
|
gint j;
|
||||||
|
|
||||||
|
/* top border */
|
||||||
|
for (j = 0; j < bt; j++) {
|
||||||
|
memset (dest, fill_color, dest_width);
|
||||||
|
dest += dest_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy and add left and right border */
|
||||||
|
for (j = 0; j < src_crop_height; j++) {
|
||||||
|
memset (dest, fill_color, bl);
|
||||||
|
memcpy (dest + bl, src, src_crop_width);
|
||||||
|
memset (dest + bl + src_crop_width, fill_color, br);
|
||||||
|
dest += dest_stride;
|
||||||
|
src += src_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bottom border */
|
||||||
|
for (j = 0; j < bb; j++) {
|
||||||
|
memset (dest, fill_color, dest_width);
|
||||||
|
dest += dest_stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_video_box_i420 (GstVideoBox * video_box, guint8 * src, guint8 * dest)
|
gst_video_box_i420 (GstVideoBox * video_box, guint8 * src, guint8 * dest)
|
||||||
{
|
{
|
||||||
|
@ -416,10 +446,9 @@ gst_video_box_i420 (GstVideoBox * video_box, guint8 * src, guint8 * dest)
|
||||||
guint8 *destY, *destU, *destV;
|
guint8 *destY, *destU, *destV;
|
||||||
gint crop_width, crop_height;
|
gint crop_width, crop_height;
|
||||||
gint out_width, out_height;
|
gint out_width, out_height;
|
||||||
gint src_stride;
|
gint src_width, src_height;
|
||||||
|
gint src_stride, dest_stride;
|
||||||
gint br, bl, bt, bb;
|
gint br, bl, bt, bb;
|
||||||
gint j;
|
|
||||||
gint color1, color2;
|
|
||||||
|
|
||||||
br = video_box->border_right;
|
br = video_box->border_right;
|
||||||
bl = video_box->border_left;
|
bl = video_box->border_left;
|
||||||
|
@ -429,97 +458,55 @@ gst_video_box_i420 (GstVideoBox * video_box, guint8 * src, guint8 * dest)
|
||||||
out_width = video_box->out_width;
|
out_width = video_box->out_width;
|
||||||
out_height = video_box->out_height;
|
out_height = video_box->out_height;
|
||||||
|
|
||||||
|
src_width = video_box->in_width;
|
||||||
|
src_height = video_box->in_height;
|
||||||
|
|
||||||
|
crop_width = src_width - (video_box->crop_left + video_box->crop_right);
|
||||||
|
crop_height = src_height - (video_box->crop_top + video_box->crop_bottom);
|
||||||
|
|
||||||
|
/* Y plane */
|
||||||
|
src_stride = GST_VIDEO_I420_Y_ROWSTRIDE (src_width);
|
||||||
|
dest_stride = GST_VIDEO_I420_Y_ROWSTRIDE (out_width);
|
||||||
|
|
||||||
destY = dest + GST_VIDEO_I420_Y_OFFSET (out_width, out_height);
|
destY = dest + GST_VIDEO_I420_Y_OFFSET (out_width, out_height);
|
||||||
|
|
||||||
srcY =
|
srcY = src + GST_VIDEO_I420_Y_OFFSET (src_width, src_height);
|
||||||
src + GST_VIDEO_I420_Y_OFFSET (video_box->in_width, video_box->in_height);
|
|
||||||
src_stride = GST_VIDEO_I420_Y_ROWSTRIDE (video_box->in_width);
|
|
||||||
|
|
||||||
crop_width =
|
|
||||||
video_box->in_width - (video_box->crop_left + video_box->crop_right);
|
|
||||||
crop_height =
|
|
||||||
video_box->in_height - (video_box->crop_top + video_box->crop_bottom);
|
|
||||||
|
|
||||||
srcY += src_stride * video_box->crop_top + video_box->crop_left;
|
srcY += src_stride * video_box->crop_top + video_box->crop_left;
|
||||||
|
|
||||||
color1 = yuv_colors_Y[video_box->fill_type];
|
gst_video_box_copy_plane_i420 (video_box, srcY, destY, br, bl, bt, bb,
|
||||||
|
crop_width, crop_height, src_stride, out_width, dest_stride,
|
||||||
|
yuv_colors_Y[video_box->fill_type]);
|
||||||
|
|
||||||
/* copy Y plane first */
|
/* U plane */
|
||||||
for (j = 0; j < bt; j++) {
|
src_stride = GST_VIDEO_I420_U_ROWSTRIDE (src_width);
|
||||||
memset (destY, color1, out_width);
|
dest_stride = GST_VIDEO_I420_U_ROWSTRIDE (out_width);
|
||||||
destY += out_width;
|
|
||||||
}
|
|
||||||
for (j = 0; j < crop_height; j++) {
|
|
||||||
memset (destY, color1, bl);
|
|
||||||
destY += bl;
|
|
||||||
memcpy (destY, srcY, crop_width);
|
|
||||||
destY += crop_width;
|
|
||||||
memset (destY, color1, br);
|
|
||||||
destY += br;
|
|
||||||
srcY += src_stride;
|
|
||||||
}
|
|
||||||
for (j = 0; j < bb; j++) {
|
|
||||||
memset (destY, color1, out_width);
|
|
||||||
destY += out_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
src_stride = GST_VIDEO_I420_U_ROWSTRIDE (video_box->in_width);
|
|
||||||
|
|
||||||
destU = dest + GST_VIDEO_I420_U_OFFSET (out_width, out_height);
|
destU = dest + GST_VIDEO_I420_U_OFFSET (out_width, out_height);
|
||||||
|
|
||||||
|
srcU = src + GST_VIDEO_I420_U_OFFSET (src_width, src_height);
|
||||||
|
srcU += src_stride * (video_box->crop_top / 2) + (video_box->crop_left / 2);
|
||||||
|
|
||||||
|
gst_video_box_copy_plane_i420 (video_box, srcU, destU, br / 2, bl / 2, bt / 2,
|
||||||
|
bb / 2, crop_width / 2, crop_height / 2, src_stride, out_width / 2,
|
||||||
|
dest_stride, yuv_colors_U[video_box->fill_type]);
|
||||||
|
|
||||||
|
/* V plane */
|
||||||
|
src_stride = GST_VIDEO_I420_V_ROWSTRIDE (src_width);
|
||||||
|
dest_stride = GST_VIDEO_I420_V_ROWSTRIDE (out_width);
|
||||||
|
|
||||||
destV = dest + GST_VIDEO_I420_V_OFFSET (out_width, out_height);
|
destV = dest + GST_VIDEO_I420_V_OFFSET (out_width, out_height);
|
||||||
|
|
||||||
crop_width /= 2;
|
srcV = src + GST_VIDEO_I420_V_OFFSET (src_width, src_height);
|
||||||
crop_height /= 2;
|
|
||||||
out_width /= 2;
|
|
||||||
out_height /= 2;
|
|
||||||
bb /= 2;
|
|
||||||
bt /= 2;
|
|
||||||
br /= 2;
|
|
||||||
bl /= 2;
|
|
||||||
|
|
||||||
srcU =
|
|
||||||
src + GST_VIDEO_I420_U_OFFSET (video_box->in_width, video_box->in_height);
|
|
||||||
srcV =
|
|
||||||
src + GST_VIDEO_I420_V_OFFSET (video_box->in_width, video_box->in_height);
|
|
||||||
srcU += src_stride * (video_box->crop_top / 2) + (video_box->crop_left / 2);
|
|
||||||
srcV += src_stride * (video_box->crop_top / 2) + (video_box->crop_left / 2);
|
srcV += src_stride * (video_box->crop_top / 2) + (video_box->crop_left / 2);
|
||||||
|
|
||||||
color1 = yuv_colors_U[video_box->fill_type];
|
gst_video_box_copy_plane_i420 (video_box, srcV, destV, br / 2, bl / 2, bt / 2,
|
||||||
color2 = yuv_colors_V[video_box->fill_type];
|
bb / 2, crop_width / 2, crop_height / 2, src_stride, out_width / 2,
|
||||||
|
dest_stride, yuv_colors_V[video_box->fill_type]);
|
||||||
for (j = 0; j < bt; j++) {
|
|
||||||
memset (destU, color1, out_width);
|
|
||||||
memset (destV, color2, out_width);
|
|
||||||
destU += out_width;
|
|
||||||
destV += out_width;
|
|
||||||
}
|
|
||||||
for (j = 0; j < crop_height; j++) {
|
|
||||||
memset (destU, color1, bl);
|
|
||||||
destU += bl;
|
|
||||||
/* copy U plane */
|
|
||||||
memcpy (destU, srcU, crop_width);
|
|
||||||
destU += crop_width;
|
|
||||||
memset (destU, color1, br);
|
|
||||||
destU += br;
|
|
||||||
srcU += src_stride;
|
|
||||||
|
|
||||||
memset (destV, color2, bl);
|
|
||||||
destV += bl;
|
|
||||||
/* copy V plane */
|
|
||||||
memcpy (destV, srcV, crop_width);
|
|
||||||
destV += crop_width;
|
|
||||||
memset (destV, color2, br);
|
|
||||||
destV += br;
|
|
||||||
srcV += src_stride;
|
|
||||||
}
|
|
||||||
for (j = 0; j < bb; j++) {
|
|
||||||
memset (destU, color1, out_width);
|
|
||||||
memset (destV, color2, out_width);
|
|
||||||
destU += out_width;
|
|
||||||
destV += out_width;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note the source image is always I420, we
|
||||||
|
* are converting to AYUV on the fly here */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
|
gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
|
||||||
{
|
{
|
||||||
|
@ -685,7 +672,7 @@ gst_video_box_chain (GstPad * pad, GstData * _data)
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (outbuf));
|
GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (outbuf));
|
||||||
} else {
|
} else {
|
||||||
outbuf = gst_pad_alloc_buffer (video_box->srcpad,
|
outbuf = gst_pad_alloc_buffer (video_box->srcpad,
|
||||||
GST_BUFFER_OFFSET_NONE, (new_width * new_height * 3) / 2);
|
GST_BUFFER_OFFSET_NONE, GST_VIDEO_I420_SIZE (new_width, new_height));
|
||||||
|
|
||||||
gst_video_box_i420 (video_box,
|
gst_video_box_i420 (video_box,
|
||||||
GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (outbuf));
|
GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (outbuf));
|
||||||
|
|
Loading…
Reference in a new issue