#include <gst/base/gstbasetransform.h>
#include <gst/video/video.h>
+#include <liboil/liboil.h>
#include <string.h>
GST_DEBUG_CATEGORY (videobox_debug);
{
static GType video_box_fill_type = 0;
static GEnumValue video_box_fill[] = {
- {VIDEO_BOX_FILL_BLACK, "0", "Black"},
- {VIDEO_BOX_FILL_GREEN, "1", "Colorkey green"},
- {VIDEO_BOX_FILL_BLUE, "2", "Colorkey blue"},
+ {VIDEO_BOX_FILL_BLACK, "Black", "black"},
+ {VIDEO_BOX_FILL_GREEN, "Colorkey green", "green"},
+ {VIDEO_BOX_FILL_BLUE, "Colorkey blue", "blue"},
{0, NULL, NULL},
};
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
-
- if (video_box->box_left == 0 && video_box->box_right == 0 &&
- video_box->box_top == 0 && video_box->box_bottom == 0)
- gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (video_box), TRUE);
- else
- gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (video_box), FALSE);
}
+
static void
gst_video_box_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
g_value_unset (&list_value);
- GST_DEBUG_OBJECT (video_box, "transformed %" GST_PTR_FORMAT
- " to %" GST_PTR_FORMAT, from, to);
+ GST_DEBUG_OBJECT (video_box, "direction %d, transformed %" GST_PTR_FORMAT
+ " to %" GST_PTR_FORMAT, direction, from, to);
return to;
}
ret &= gst_structure_get_int (structure, "height", &video_box->out_height);
ret &= gst_structure_get_fourcc (structure, "format", &fourcc);
- video_box->use_alpha = fourcc == GST_STR_FOURCC ("AYUV");
+ if (fourcc == GST_STR_FOURCC ("AYUV")) {
+ video_box->use_alpha = TRUE;
+ } else {
+ if (video_box->box_left == 0 && video_box->box_right == 0 &&
+ video_box->box_top == 0 && video_box->box_bottom == 0) {
+ gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (video_box), TRUE);
+ GST_LOG ("we are using passthrough");
+ } else {
+ gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (video_box),
+ FALSE);
+ GST_LOG ("we are not using passthrough");
+ }
+ }
return ret;
}
/* top border */
for (j = 0; j < bt; j++) {
- memset (dest, fill_color, dest_width);
+ oil_splat_u8_ns (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);
+ oil_splat_u8_ns (dest, &fill_color, bl);
+ oil_memcpy (dest + bl, src, src_crop_width);
+ oil_splat_u8_ns (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);
+ oil_splat_u8_ns (dest, &fill_color, dest_width);
dest += dest_stride;
}
}
/* Note the source image is always I420, we
* are converting to AYUV on the fly here */
-
static void
gst_video_box_ayuv (GstVideoBox * video_box, guint8 * src, guint8 * dest)
{
guint8 *srcY, *srcU, *srcV;
gint crop_width, crop_width2, crop_height;
gint out_width, out_height;
- gint src_stride, src_stride2;
+ gint src_stridey, src_strideu, src_stridev;
gint br, bl, bt, bb;
gint colorY, colorU, colorV;
gint i, j;
out_width = video_box->out_width;
out_height = video_box->out_height;
- src_stride = GST_VIDEO_I420_Y_ROWSTRIDE (video_box->in_width);
- src_stride2 = src_stride / 2;
+ src_stridey = GST_VIDEO_I420_Y_ROWSTRIDE (video_box->in_width);
+ src_strideu = GST_VIDEO_I420_U_ROWSTRIDE (video_box->in_width);
+ src_stridev = GST_VIDEO_I420_V_ROWSTRIDE (video_box->in_width);
crop_width =
video_box->in_width - (video_box->crop_left + video_box->crop_right);
srcY =
src + GST_VIDEO_I420_Y_OFFSET (video_box->in_width, video_box->in_height);
- srcY += src_stride * video_box->crop_top + video_box->crop_left;
+ srcY += src_stridey * video_box->crop_top + video_box->crop_left;
srcU =
src + GST_VIDEO_I420_U_OFFSET (video_box->in_width, video_box->in_height);
- srcU += src_stride2 * (video_box->crop_top / 2) + (video_box->crop_left / 2);
+ srcU += src_strideu * (video_box->crop_top / 2) + (video_box->crop_left / 2);
srcV =
src + GST_VIDEO_I420_V_OFFSET (video_box->in_width, video_box->in_height);
- srcV += src_stride2 * (video_box->crop_top / 2) + (video_box->crop_left / 2);
+ srcV += src_stridev * (video_box->crop_top / 2) + (video_box->crop_left / 2);
colorY = yuv_colors_Y[video_box->fill_type];
colorU = yuv_colors_U[video_box->fill_type];
colorV);
/* top border */
- for (i = 0; i < bt; i++) {
- for (j = 0; j < out_width; j++) {
- *destp++ = ayuv;
- }
+ if (bt) {
+ size_t nb_pixels = bt * out_width;
+
+ oil_splat_u32_ns (destp, &ayuv, nb_pixels);
+ destp += nb_pixels;
}
for (i = 0; i < crop_height; i++) {
/* left border */
- for (j = 0; j < bl; j++) {
- *destp++ = ayuv;
+ if (bl) {
+ oil_splat_u32_ns (destp, &ayuv, bl);
+ destp += bl;
}
dest = (guint8 *) destp;
/* center */
+ /* We can splat the alpha channel for the whole line */
+ oil_splat_u8 (dest, 4, &i_alpha, crop_width);
for (j = 0; j < crop_width2; j++) {
- *dest++ = i_alpha;
+ dest++;
*dest++ = *srcY++;
*dest++ = *srcU;
*dest++ = *srcV;
- *dest++ = i_alpha;
+ dest++;
*dest++ = *srcY++;
*dest++ = *srcU++;
*dest++ = *srcV++;
srcU -= crop_width2;
srcV -= crop_width2;
} else {
- srcU += src_stride2 - crop_width2;
- srcV += src_stride2 - crop_width2;
+ srcU += src_strideu - crop_width2;
+ srcV += src_stridev - crop_width2;
}
- srcY += src_stride - crop_width;
+ srcY += src_stridey - crop_width;
destp = (guint32 *) dest;
/* right border */
- for (j = 0; j < br; j++) {
- *destp++ = ayuv;
+ if (br) {
+ oil_splat_u32_ns (destp, &ayuv, br);
+ destp += br;
}
}
/* bottom border */
- for (i = 0; i < bb; i++) {
- for (j = 0; j < out_width; j++) {
- *destp++ = ayuv;
- }
+ if (bb) {
+ size_t nb_pixels = bb * out_width;
+
+ oil_splat_u32_ns (destp, &ayuv, nb_pixels);
+ destp += nb_pixels;
}
}
GST_VERSION_MINOR,
"videobox",
"resizes a video by adding borders or cropping",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
+ plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)