diff options
Diffstat (limited to 'gst/videosignal/gstvideomark.c')
-rw-r--r-- | gst/videosignal/gstvideomark.c | 520 |
1 files changed, 256 insertions, 264 deletions
diff --git a/gst/videosignal/gstvideomark.c b/gst/videosignal/gstvideomark.c index ccee60b93..32db3bf22 100644 --- a/gst/videosignal/gstvideomark.c +++ b/gst/videosignal/gstvideomark.c @@ -13,10 +13,9 @@ * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. */ - /** * SECTION:element-videomark * @see_also: #GstVideoDetect @@ -48,23 +47,31 @@ #include "config.h" #endif +#include <gst/gst.h> +#include <gst/video/video.h> +#include <gst/video/gstvideofilter.h> #include "gstvideomark.h" -#include <string.h> -#include <math.h> +GST_DEBUG_CATEGORY_STATIC (gst_video_mark_debug_category); +#define GST_CAT_DEFAULT gst_video_mark_debug_category -#include <gst/video/video.h> +/* prototypes */ -/* GstVideoMark signals and args */ -#define DEFAULT_PATTERN_WIDTH 4 -#define DEFAULT_PATTERN_HEIGHT 16 -#define DEFAULT_PATTERN_COUNT 4 -#define DEFAULT_PATTERN_DATA_COUNT 5 -#define DEFAULT_PATTERN_DATA 10 -#define DEFAULT_ENABLED TRUE -#define DEFAULT_LEFT_OFFSET 0 -#define DEFAULT_BOTTOM_OFFSET 0 +static void gst_video_mark_set_property (GObject * object, + guint property_id, const GValue * value, GParamSpec * pspec); +static void gst_video_mark_get_property (GObject * object, + guint property_id, GValue * value, GParamSpec * pspec); +static void gst_video_mark_dispose (GObject * object); +static void gst_video_mark_finalize (GObject * object); + +static gboolean gst_video_mark_start (GstBaseTransform * trans); +static gboolean gst_video_mark_stop (GstBaseTransform * trans); +static gboolean gst_video_mark_set_info (GstVideoFilter * filter, + GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps, + GstVideoInfo * out_info); +static GstFlowReturn gst_video_mark_transform_frame_ip (GstVideoFilter * filter, + GstVideoFrame * frame); enum { @@ -74,173 +81,119 @@ enum PROP_PATTERN_COUNT, PROP_PATTERN_DATA_COUNT, PROP_PATTERN_DATA, - PROP_PATTERN_DATA_64, PROP_ENABLED, PROP_LEFT_OFFSET, PROP_BOTTOM_OFFSET }; -GST_DEBUG_CATEGORY_STATIC (video_mark_debug); -#define GST_CAT_DEFAULT video_mark_debug - -static GstStaticPadTemplate gst_video_mark_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV - ("{ I420, YV12, Y41B, Y42B, Y444, YUY2, UYVY, AYUV, YVYU }")) - ); - -static GstStaticPadTemplate gst_video_mark_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV - ("{ I420, YV12, Y41B, Y42B, Y444, YUY2, UYVY, AYUV, YVYU }")) - ); - -static GstVideoFilterClass *parent_class = NULL; - -static gboolean -gst_video_mark_set_caps (GstBaseTransform * btrans, GstCaps * incaps, - GstCaps * outcaps) -{ - GstVideoMark *vf; - GstStructure *in_s; - guint32 fourcc; - gboolean ret; +#define DEFAULT_PATTERN_WIDTH 4 +#define DEFAULT_PATTERN_HEIGHT 16 +#define DEFAULT_PATTERN_COUNT 4 +#define DEFAULT_PATTERN_DATA_COUNT 5 +#define DEFAULT_PATTERN_DATA 10 +#define DEFAULT_ENABLED TRUE +#define DEFAULT_LEFT_OFFSET 0 +#define DEFAULT_BOTTOM_OFFSET 0 - vf = GST_VIDEO_MARK (btrans); +/* pad templates */ - in_s = gst_caps_get_structure (incaps, 0); +#define VIDEO_CAPS \ + GST_VIDEO_CAPS_MAKE( \ + "{ I420, YV12, Y41B, Y42B, Y444, YUY2, UYVY, AYUV, YVYU }") - ret = gst_structure_get_int (in_s, "width", &vf->width); - ret &= gst_structure_get_int (in_s, "height", &vf->height); - ret &= gst_structure_get_fourcc (in_s, "format", &fourcc); - if (ret) - vf->format = gst_video_format_from_fourcc (fourcc); +/* class initialization */ - return ret; -} +G_DEFINE_TYPE_WITH_CODE (GstVideoMark, gst_video_mark, GST_TYPE_VIDEO_FILTER, + GST_DEBUG_CATEGORY_INIT (gst_video_mark_debug_category, "videomark", 0, + "debug category for videomark element")); static void -gst_video_mark_draw_box (GstVideoMark * videomark, guint8 * data, - gint width, gint height, gint row_stride, gint pixel_stride, guint8 color) +gst_video_mark_class_init (GstVideoMarkClass * klass) { - gint i, j; - - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { - data[pixel_stride * j] = color; - } - data += row_stride; - } -} - -static GstFlowReturn -gst_video_mark_yuv (GstVideoMark * videomark, GstBuffer * buffer) -{ - GstVideoFormat format; - gint i, pw, ph, row_stride, pixel_stride, offset; - gint width, height, req_width, req_height; - guint8 *d, *data; - guint64 pattern_shift; - guint8 color; - - data = GST_BUFFER_DATA (buffer); - - format = videomark->format; - width = videomark->width; - height = videomark->height; - - pw = videomark->pattern_width; - ph = videomark->pattern_height; - row_stride = gst_video_format_get_row_stride (format, 0, width); - pixel_stride = gst_video_format_get_pixel_stride (format, 0); - offset = gst_video_format_get_component_offset (format, 0, width, height); - - req_width = - (videomark->pattern_count + videomark->pattern_data_count) * pw + - videomark->left_offset; - req_height = videomark->bottom_offset + ph; - if (req_width > width || req_height > height) { - GST_ELEMENT_ERROR (videomark, STREAM, WRONG_TYPE, (NULL), - ("videomark pattern doesn't fit video, need at least %ix%i (stream has %ix%i)", - req_width, req_height, width, height)); - return GST_FLOW_ERROR; - } - - /* draw the bottom left pixels */ - for (i = 0; i < videomark->pattern_count; i++) { - d = data + offset; - /* move to start of bottom left */ - d += row_stride * (height - ph - videomark->bottom_offset) + - pixel_stride * videomark->left_offset; - /* move to i-th pattern */ - d += pixel_stride * pw * i; - - if (i & 1) - /* odd pixels must be white */ - color = 255; - else - color = 0; - - /* draw box of width * height */ - gst_video_mark_draw_box (videomark, d, pw, ph, row_stride, pixel_stride, - color); - } - - pattern_shift = G_GUINT64_CONSTANT (1) << (videomark->pattern_data_count - 1); - - /* get the data of the pattern */ - for (i = 0; i < videomark->pattern_data_count; i++) { - d = data + offset; - /* move to start of bottom left, adjust for offsets */ - d += row_stride * (height - ph - videomark->bottom_offset) + - pixel_stride * videomark->left_offset; - /* move after the fixed pattern */ - d += pixel_stride * videomark->pattern_count * pw; - /* move to i-th pattern data */ - d += pixel_stride * pw * i; - - if (videomark->pattern_data & pattern_shift) - color = 255; - else - color = 0; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstBaseTransformClass *base_transform_class = + GST_BASE_TRANSFORM_CLASS (klass); + GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS (klass); + + gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + gst_caps_from_string (VIDEO_CAPS))); + gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, + gst_caps_from_string (VIDEO_CAPS))); + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "Video marker", "Filter/Effect/Video", + "Marks a video signal with a pattern", "Wim Taymans <wim@fluendo.com>"); - gst_video_mark_draw_box (videomark, d, pw, ph, row_stride, pixel_stride, - color); + gobject_class->set_property = gst_video_mark_set_property; + gobject_class->get_property = gst_video_mark_get_property; + gobject_class->dispose = gst_video_mark_dispose; + gobject_class->finalize = gst_video_mark_finalize; + base_transform_class->start = GST_DEBUG_FUNCPTR (gst_video_mark_start); + base_transform_class->stop = GST_DEBUG_FUNCPTR (gst_video_mark_stop); + video_filter_class->set_info = GST_DEBUG_FUNCPTR (gst_video_mark_set_info); + video_filter_class->transform_frame_ip = + GST_DEBUG_FUNCPTR (gst_video_mark_transform_frame_ip); - pattern_shift >>= 1; - } + g_object_class_install_property (gobject_class, PROP_PATTERN_WIDTH, + g_param_spec_int ("pattern-width", "Pattern width", + "The width of the pattern markers", 1, G_MAXINT, + DEFAULT_PATTERN_WIDTH, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PATTERN_HEIGHT, + g_param_spec_int ("pattern-height", "Pattern height", + "The height of the pattern markers", 1, G_MAXINT, + DEFAULT_PATTERN_HEIGHT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PATTERN_COUNT, + g_param_spec_int ("pattern-count", "Pattern count", + "The number of pattern markers", 0, G_MAXINT, + DEFAULT_PATTERN_COUNT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PATTERN_DATA_COUNT, + g_param_spec_int ("pattern-data-count", "Pattern data count", + "The number of extra data pattern markers", 0, 64, + DEFAULT_PATTERN_DATA_COUNT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PATTERN_DATA, + g_param_spec_uint64 ("pattern-data", "Pattern data", + "The extra data pattern markers", 0, G_MAXUINT64, + DEFAULT_PATTERN_DATA, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_ENABLED, + g_param_spec_boolean ("enabled", "Enabled", + "Enable or disable the filter", + DEFAULT_ENABLED, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_LEFT_OFFSET, + g_param_spec_int ("left-offset", "Left Offset", + "The offset from the left border where the pattern starts", 0, + G_MAXINT, DEFAULT_LEFT_OFFSET, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_BOTTOM_OFFSET, + g_param_spec_int ("bottom-offset", "Bottom Offset", + "The offset from the bottom border where the pattern starts", 0, + G_MAXINT, DEFAULT_BOTTOM_OFFSET, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - return GST_FLOW_OK; } -static GstFlowReturn -gst_video_mark_transform_ip (GstBaseTransform * trans, GstBuffer * buf) +static void +gst_video_mark_init (GstVideoMark * videomark) { - GstVideoMark *videomark; - GstFlowReturn ret = GST_FLOW_OK; - - videomark = GST_VIDEO_MARK (trans); - - if (videomark->enabled) - return gst_video_mark_yuv (videomark, buf); - - return ret; } -static void -gst_video_mark_set_property (GObject * object, guint prop_id, +void +gst_video_mark_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { - GstVideoMark *videomark; + GstVideoMark *videomark = GST_VIDEO_MARK (object); - videomark = GST_VIDEO_MARK (object); + GST_DEBUG_OBJECT (videomark, "set_property"); - switch (prop_id) { + switch (property_id) { case PROP_PATTERN_WIDTH: videomark->pattern_width = g_value_get_int (value); break; @@ -253,11 +206,8 @@ gst_video_mark_set_property (GObject * object, guint prop_id, case PROP_PATTERN_DATA_COUNT: videomark->pattern_data_count = g_value_get_int (value); break; - case PROP_PATTERN_DATA_64: - videomark->pattern_data = g_value_get_uint64 (value); - break; case PROP_PATTERN_DATA: - videomark->pattern_data = g_value_get_int (value); + videomark->pattern_data = g_value_get_uint64 (value); break; case PROP_ENABLED: videomark->enabled = g_value_get_boolean (value); @@ -269,20 +219,20 @@ gst_video_mark_set_property (GObject * object, guint prop_id, videomark->bottom_offset = g_value_get_int (value); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } -static void -gst_video_mark_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) +void +gst_video_mark_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) { - GstVideoMark *videomark; + GstVideoMark *videomark = GST_VIDEO_MARK (object); - videomark = GST_VIDEO_MARK (object); + GST_DEBUG_OBJECT (videomark, "get_property"); - switch (prop_id) { + switch (property_id) { case PROP_PATTERN_WIDTH: g_value_set_int (value, videomark->pattern_width); break; @@ -295,11 +245,8 @@ gst_video_mark_get_property (GObject * object, guint prop_id, GValue * value, case PROP_PATTERN_DATA_COUNT: g_value_set_int (value, videomark->pattern_data_count); break; - case PROP_PATTERN_DATA_64: - g_value_set_uint64 (value, videomark->pattern_data); - break; case PROP_PATTERN_DATA: - g_value_set_int (value, MIN (videomark->pattern_data, G_MAXINT)); + g_value_set_uint64 (value, videomark->pattern_data); break; case PROP_ENABLED: g_value_set_boolean (value, videomark->enabled); @@ -311,121 +258,166 @@ gst_video_mark_get_property (GObject * object, guint prop_id, GValue * value, g_value_set_int (value, videomark->bottom_offset); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } -static void -gst_video_mark_base_init (gpointer g_class) +void +gst_video_mark_dispose (GObject * object) { - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + GstVideoMark *videomark = GST_VIDEO_MARK (object); - gst_element_class_set_static_metadata (element_class, "Video marker", - "Filter/Effect/Video", - "Marks a video signal with a pattern", "Wim Taymans <wim@fluendo.com>"); + GST_DEBUG_OBJECT (videomark, "dispose"); + + /* clean up as possible. may be called multiple times */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_video_mark_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_video_mark_src_template)); + G_OBJECT_CLASS (gst_video_mark_parent_class)->dispose (object); } -static void -gst_video_mark_class_init (gpointer klass, gpointer class_data) +void +gst_video_mark_finalize (GObject * object) { - GObjectClass *gobject_class; - GstBaseTransformClass *trans_class; + GstVideoMark *videomark = GST_VIDEO_MARK (object); - gobject_class = (GObjectClass *) klass; - trans_class = (GstBaseTransformClass *) klass; + GST_DEBUG_OBJECT (videomark, "finalize"); - parent_class = g_type_class_peek_parent (klass); + /* clean up object here */ - gobject_class->set_property = gst_video_mark_set_property; - gobject_class->get_property = gst_video_mark_get_property; + G_OBJECT_CLASS (gst_video_mark_parent_class)->finalize (object); +} - g_object_class_install_property (gobject_class, PROP_PATTERN_WIDTH, - g_param_spec_int ("pattern-width", "Pattern width", - "The width of the pattern markers", 1, G_MAXINT, - DEFAULT_PATTERN_WIDTH, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PATTERN_HEIGHT, - g_param_spec_int ("pattern-height", "Pattern height", - "The height of the pattern markers", 1, G_MAXINT, - DEFAULT_PATTERN_HEIGHT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PATTERN_COUNT, - g_param_spec_int ("pattern-count", "Pattern count", - "The number of pattern markers", 0, G_MAXINT, - DEFAULT_PATTERN_COUNT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PATTERN_DATA_COUNT, - g_param_spec_int ("pattern-data-count", "Pattern data count", - "The number of extra data pattern markers", 0, 64, - DEFAULT_PATTERN_DATA_COUNT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PATTERN_DATA_64, - g_param_spec_uint64 ("pattern-data-uint64", "Pattern data", - "The extra data pattern markers", 0, G_MAXUINT64, - DEFAULT_PATTERN_DATA, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PATTERN_DATA, - g_param_spec_int ("pattern-data", "Pattern data", - "The extra data pattern markers", 0, G_MAXINT, - DEFAULT_PATTERN_DATA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_ENABLED, - g_param_spec_boolean ("enabled", "Enabled", - "Enable or disable the filter", - DEFAULT_ENABLED, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_LEFT_OFFSET, - g_param_spec_int ("left-offset", "Left Offset", - "The offset from the left border where the pattern starts", 0, - G_MAXINT, DEFAULT_LEFT_OFFSET, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_BOTTOM_OFFSET, - g_param_spec_int ("bottom-offset", "Bottom Offset", - "The offset from the bottom border where the pattern starts", 0, - G_MAXINT, DEFAULT_BOTTOM_OFFSET, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); +static gboolean +gst_video_mark_start (GstBaseTransform * trans) +{ + GstVideoMark *videomark = GST_VIDEO_MARK (trans); - trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_video_mark_set_caps); - trans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_video_mark_transform_ip); + GST_DEBUG_OBJECT (videomark, "start"); - GST_DEBUG_CATEGORY_INIT (video_mark_debug, "videomark", 0, "Video mark"); + return TRUE; } -static void -gst_video_mark_init (GTypeInstance * instance, gpointer g_class) +static gboolean +gst_video_mark_stop (GstBaseTransform * trans) { - GstVideoMark *videomark; + GstVideoMark *videomark = GST_VIDEO_MARK (trans); - videomark = GST_VIDEO_MARK (instance); + GST_DEBUG_OBJECT (videomark, "stop"); - GST_DEBUG_OBJECT (videomark, "gst_video_mark_init"); + return TRUE; } -GType -gst_video_mark_get_type (void) +static gboolean +gst_video_mark_set_info (GstVideoFilter * filter, GstCaps * incaps, + GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info) +{ + GstVideoMark *videomark = GST_VIDEO_MARK (filter); + + GST_DEBUG_OBJECT (videomark, "set_info"); + + return TRUE; +} + +static void +gst_video_mark_draw_box (GstVideoMark * videomark, guint8 * data, + gint width, gint height, gint row_stride, gint pixel_stride, guint8 color) { - static GType video_mark_type = 0; - - if (!video_mark_type) { - static const GTypeInfo video_mark_info = { - sizeof (GstVideoMarkClass), - gst_video_mark_base_init, - NULL, - gst_video_mark_class_init, - NULL, - NULL, - sizeof (GstVideoMark), - 0, - gst_video_mark_init, - }; - - video_mark_type = g_type_register_static (GST_TYPE_VIDEO_FILTER, - "GstVideoMark", &video_mark_info, 0); + gint i, j; + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + data[pixel_stride * j] = color; + } + data += row_stride; } - return video_mark_type; +} + +static GstFlowReturn +gst_video_mark_yuv (GstVideoMark * videomark, GstVideoFrame * frame) +{ + gint i, pw, ph, row_stride, pixel_stride; + gint width, height, req_width, req_height; + guint8 *d; + guint64 pattern_shift; + guint8 color; + + width = frame->info.width; + height = frame->info.height; + + pw = videomark->pattern_width; + ph = videomark->pattern_height; + row_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); + pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0); + + req_width = + (videomark->pattern_count + videomark->pattern_data_count) * pw + + videomark->left_offset; + req_height = videomark->bottom_offset + ph; + if (req_width > width || req_height > height) { + GST_ELEMENT_ERROR (videomark, STREAM, WRONG_TYPE, (NULL), + ("videomark pattern doesn't fit video, need at least %ix%i (stream has %ix%i)", + req_width, req_height, width, height)); + return GST_FLOW_ERROR; + } + + /* draw the bottom left pixels */ + for (i = 0; i < videomark->pattern_count; i++) { + d = GST_VIDEO_FRAME_COMP_DATA (frame, 0); + /* move to start of bottom left */ + d += row_stride * (height - ph - videomark->bottom_offset) + + pixel_stride * videomark->left_offset; + /* move to i-th pattern */ + d += pixel_stride * pw * i; + + if (i & 1) + /* odd pixels must be white */ + color = 255; + else + color = 0; + + /* draw box of width * height */ + gst_video_mark_draw_box (videomark, d, pw, ph, row_stride, pixel_stride, + color); + } + + pattern_shift = G_GUINT64_CONSTANT (1) << (videomark->pattern_data_count - 1); + + /* get the data of the pattern */ + for (i = 0; i < videomark->pattern_data_count; i++) { + d = GST_VIDEO_FRAME_COMP_DATA (frame, 0); + /* move to start of bottom left, adjust for offsets */ + d += row_stride * (height - ph - videomark->bottom_offset) + + pixel_stride * videomark->left_offset; + /* move after the fixed pattern */ + d += pixel_stride * videomark->pattern_count * pw; + /* move to i-th pattern data */ + d += pixel_stride * pw * i; + + if (videomark->pattern_data & pattern_shift) + color = 255; + else + color = 0; + + gst_video_mark_draw_box (videomark, d, pw, ph, row_stride, pixel_stride, + color); + + pattern_shift >>= 1; + } + + return GST_FLOW_OK; +} + + +static GstFlowReturn +gst_video_mark_transform_frame_ip (GstVideoFilter * filter, + GstVideoFrame * frame) +{ + GstVideoMark *videomark = GST_VIDEO_MARK (filter); + + GST_DEBUG_OBJECT (videomark, "transform_frame_ip"); + + if (videomark->enabled) + return gst_video_mark_yuv (videomark, frame); + + return GST_FLOW_OK; } |