zxing: update to support version 1.1.1

Support new API in 1.1.1
Update the supported input video format.
Update tests to use parse_launch

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2037>
This commit is contained in:
Stéphane Cerveau 2021-02-25 14:09:50 +01:00 committed by GStreamer Marge Bot
parent b0a9ba4ccf
commit 451c875d40
3 changed files with 61 additions and 29 deletions

View file

@ -36,6 +36,9 @@
* * #GstSample `frame`: the frame in which the barcode message was detected, if * * #GstSample `frame`: the frame in which the barcode message was detected, if
* the .#GstZXing:attach-frame property was set to %TRUE (Since 1.18) * the .#GstZXing:attach-frame property was set to %TRUE (Since 1.18)
* *
* This element is based on the c++ implementation of zxing which can found
* at https://github.com/nu-book/zxing-cpp.
*
* ## Example launch lines * ## Example launch lines
* |[ * |[
* gst-launch-1.0 -m v4l2src ! videoconvert ! zxing ! videoconvert ! xvimagesink * gst-launch-1.0 -m v4l2src ! videoconvert ! zxing ! videoconvert ! xvimagesink
@ -137,9 +140,8 @@ gst_barcode_format_get_type (void)
return barcode_format_type; return barcode_format_type;
} }
#define ZXING_YUV_CAPS \ #define ZXING_YUV_CAPS \
"{ Y800, I420, YV12, NV12, NV21, Y41B, Y42B, YUV9, YVU9 }" "{ARGB, xRGB, Y444, Y42B, I420, Y41B, YUV9, YV12}"
static GstStaticPadTemplate gst_zxing_src_template = static GstStaticPadTemplate gst_zxing_src_template =
@ -171,13 +173,16 @@ struct _GstZXing
gboolean attach_frame; gboolean attach_frame;
gboolean rotate; gboolean rotate;
gboolean faster; gboolean faster;
guint format; ImageFormat image_format;
guint barcode_format;
}; };
static void gst_zxing_set_property (GObject * object, guint prop_id, static void gst_zxing_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_zxing_get_property (GObject * object, guint prop_id, static void gst_zxing_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_zxing_set_info (GstVideoFilter * vfilter, GstCaps * in,
GstVideoInfo * in_info, GstCaps * out, GstVideoInfo * out_info);
static GstFlowReturn gst_zxing_transform_frame_ip (GstVideoFilter * vfilter, static GstFlowReturn gst_zxing_transform_frame_ip (GstVideoFilter * vfilter,
GstVideoFrame * frame); GstVideoFrame * frame);
@ -239,6 +244,8 @@ gst_zxing_class_init (GstZXingClass * g_class)
vfilter_class->transform_frame_ip = vfilter_class->transform_frame_ip =
GST_DEBUG_FUNCPTR (gst_zxing_transform_frame_ip); GST_DEBUG_FUNCPTR (gst_zxing_transform_frame_ip);
vfilter_class->set_info =
GST_DEBUG_FUNCPTR (gst_zxing_set_info);
} }
static void static void
@ -248,7 +255,8 @@ gst_zxing_init (GstZXing * zxing)
zxing->attach_frame = DEFAULT_ATTACH_FRAME; zxing->attach_frame = DEFAULT_ATTACH_FRAME;
zxing->rotate = DEFAULT_TRY_ROTATE; zxing->rotate = DEFAULT_TRY_ROTATE;
zxing->faster = DEFAULT_TRY_FASTER; zxing->faster = DEFAULT_TRY_FASTER;
zxing->format = BARCODE_FORMAT_ALL; zxing->image_format = ImageFormat::None;
zxing->barcode_format = BARCODE_FORMAT_ALL;
} }
static void static void
@ -274,7 +282,7 @@ gst_zxing_set_property (GObject * object, guint prop_id, const GValue * value,
zxing->faster = g_value_get_boolean (value); zxing->faster = g_value_get_boolean (value);
break; break;
case PROP_FORMAT: case PROP_FORMAT:
zxing->format = g_value_get_enum (value); zxing->barcode_format = g_value_get_enum (value);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -305,7 +313,7 @@ gst_zxing_get_property (GObject * object, guint prop_id, GValue * value,
g_value_set_boolean (value, zxing->faster); g_value_set_boolean (value, zxing->faster);
break; break;
case PROP_FORMAT: case PROP_FORMAT:
g_value_set_enum (value, zxing->format); g_value_set_enum (value, zxing->barcode_format);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -313,12 +321,42 @@ gst_zxing_get_property (GObject * object, guint prop_id, GValue * value,
} }
} }
static gboolean
gst_zxing_set_info (GstVideoFilter * vfilter, GstCaps * in,
GstVideoInfo * in_info, GstCaps * out, GstVideoInfo * out_info)
{
GstZXing *zxing = GST_ZXING (vfilter);
switch (in_info->finfo->format) {
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_xRGB:
zxing->image_format = ImageFormat::XRGB;
break;
case GST_VIDEO_FORMAT_Y444:
case GST_VIDEO_FORMAT_Y42B:
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_Y41B:
case GST_VIDEO_FORMAT_YUV9:
case GST_VIDEO_FORMAT_YV12:
zxing->image_format = ImageFormat::Lum;
break;
default:
zxing->image_format = ImageFormat::None;
GST_WARNING_OBJECT (zxing, "This format is not supported %s", gst_video_format_to_string(in_info->finfo->format));
}
return TRUE;
}
static GstFlowReturn static GstFlowReturn
gst_zxing_transform_frame_ip (GstVideoFilter * vfilter, GstVideoFrame * frame) gst_zxing_transform_frame_ip (GstVideoFilter * vfilter, GstVideoFrame * frame)
{ {
GstZXing *zxing = GST_ZXING (vfilter); GstZXing *zxing = GST_ZXING (vfilter);
gpointer data; gpointer data;
gint height, width; gint height, width;
DecodeHints hints;
hints.setTryRotate(zxing->rotate);
hints.setTryHarder(!zxing->faster);
hints.setFormats(BarcodeFormatFromString (barcode_formats[zxing->barcode_format].value_name));
/* all formats we support start with an 8-bit Y plane. zxing doesn't need /* all formats we support start with an 8-bit Y plane. zxing doesn't need
* to know about the chroma plane(s) */ * to know about the chroma plane(s) */
@ -326,10 +364,7 @@ gst_zxing_transform_frame_ip (GstVideoFilter * vfilter, GstVideoFrame * frame)
width = GST_VIDEO_FRAME_WIDTH (frame); width = GST_VIDEO_FRAME_WIDTH (frame);
height = GST_VIDEO_FRAME_HEIGHT (frame); height = GST_VIDEO_FRAME_HEIGHT (frame);
/*Init a grayscale source */ auto result = ReadBarcode ({(unsigned char *)data, width, height, zxing->image_format}, hints);
auto result = ReadBarcode (width, height, (unsigned char *) data, width,
{ BarcodeFormatFromString (barcode_formats[zxing->format].value_name) },
zxing->rotate, !zxing->faster);
if (result.isValid ()) { if (result.isValid ()) {
GST_DEBUG_OBJECT (zxing, "Symbol found. Text: %s Format: %s", GST_DEBUG_OBJECT (zxing, "Symbol found. Text: %s Format: %s",
TextUtfEncoding::ToUtf8 (result.text ()).c_str (), TextUtfEncoding::ToUtf8 (result.text ()).c_str (),

View file

@ -2,7 +2,7 @@ zxing_sources = [
'gstzxing.cpp', 'gstzxing.cpp',
'gstzxingplugin.c', 'gstzxingplugin.c',
] ]
zxing_dep = dependency('zxing', version : '>= 0.9', required : get_option('zxing')) zxing_dep = dependency('zxing', version : '>= 1.1.1', required : get_option('zxing'))
if zxing_dep.found() if zxing_dep.found()
gstzxing = library('gstzxing', gstzxing = library('gstzxing',
zxing_sources, zxing_sources,

View file

@ -21,27 +21,24 @@
#include <gst/check/gstcheck.h> #include <gst/check/gstcheck.h>
static GstElement * static GstElement *
setup_pipeline (void) setup_pipeline (const gchar * in_format)
{ {
GstElement *pipeline, *src, *dec, *csp, *zxing, *sink; GstElement *pipeline;
gchar *path; gchar *path;
gchar *pipeline_str;
pipeline = gst_pipeline_new ("pipeline");
src = gst_element_factory_make ("filesrc", NULL);
/* Test file must have size < 4096 otherwise pngparse will be necessary before pngdec. */
dec = gst_element_factory_make ("pngdec", NULL);
csp = gst_element_factory_make ("videoconvert", NULL);
zxing = gst_element_factory_make ("zxing", "zxing");
sink = gst_element_factory_make ("fakesink", NULL);
path = g_build_filename (GST_TEST_FILES_PATH, "barcode.png", NULL); path = g_build_filename (GST_TEST_FILES_PATH, "barcode.png", NULL);
GST_LOG ("reading file '%s'", path); GST_LOG ("reading file '%s'", path);
g_object_set (src, "location", path, NULL);
g_free (path);
gst_bin_add_many (GST_BIN (pipeline), src, dec, csp, zxing, sink, NULL); pipeline_str =
fail_unless (gst_element_link_many (src, dec, csp, zxing, sink, NULL)); g_strdup_printf ("filesrc location=%s ! "
"pngdec ! videoconvert ! video/x-raw,format=%s ! zxing name=zxing"
" ! fakesink", path, in_format);
GST_LOG ("Running pipeline: %s", pipeline_str);
pipeline = gst_parse_launch (pipeline_str, NULL);
fail_unless (pipeline != NULL);
g_free (pipeline_str);
g_free (path);
return pipeline; return pipeline;
} }
@ -83,7 +80,7 @@ GST_START_TEST (test_still_image)
GstElement *pipeline; GstElement *pipeline;
const gchar *type, *symbol; const gchar *type, *symbol;
pipeline = setup_pipeline (); pipeline = setup_pipeline ("ARGB");
fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING), fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
GST_STATE_CHANGE_ASYNC); GST_STATE_CHANGE_ASYNC);
@ -101,7 +98,7 @@ GST_START_TEST (test_still_image)
fail_unless (gst_structure_has_field (s, "type")); fail_unless (gst_structure_has_field (s, "type"));
fail_unless (gst_structure_has_field (s, "symbol")); fail_unless (gst_structure_has_field (s, "symbol"));
type = gst_structure_get_string (s, "type"); type = gst_structure_get_string (s, "type");
fail_unless_equals_string (type, "EAN_13"); fail_unless_equals_string (type, "EAN-13");
symbol = gst_structure_get_string (s, "symbol"); symbol = gst_structure_get_string (s, "symbol");
fail_unless_equals_string (symbol, "9876543210128"); fail_unless_equals_string (symbol, "9876543210128");
@ -123,7 +120,7 @@ GST_START_TEST (test_still_image_with_sample)
GstElement *pipeline; GstElement *pipeline;
GstSample *sample; GstSample *sample;
pipeline = setup_pipeline (); pipeline = setup_pipeline ("ARGB");
gst_child_proxy_set ((GstChildProxy *) pipeline, "zxing::attach-frame", TRUE, gst_child_proxy_set ((GstChildProxy *) pipeline, "zxing::attach-frame", TRUE,
NULL); NULL);