FFmpeg
Loading...
Searching...
No Matches
vf_quirc.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/**
20 * @file QR decoder video filter
21 *
22 * Use libquirc library to decode the content of QR codes, and put the decoded
23 * content to metadata. See:
24 * https://github.com/dlbeer/quirc
25 */
26
27#include "libavutil/imgutils.h"
28#include "libavutil/opt.h"
29#include "avfilter.h"
30#include "filters.h"
31#include "formats.h"
32#include "video.h"
33#include <quirc.h>
34
35typedef struct QuircContext {
36 const AVClass *class;
37
38 struct quirc *quirc;
41
43{
44 QuircContext *quirc = ctx->priv;
45
46 quirc->quirc = quirc_new();
47 if (!quirc->quirc) {
48 return AVERROR(ENOMEM);
49 }
50
51 return 0;
52}
53
55{
56 QuircContext *quirc = ctx->priv;
57
58 quirc_destroy(quirc->quirc);
59}
60
61static int config_input(AVFilterLink *inlink)
62{
63 AVFilterContext *ctx = inlink->dst;
64 QuircContext *quirc = ctx->priv;
65 int err;
66
67 err = quirc_resize(quirc->quirc, inlink->w, inlink->h);
68 if (err == -1) {
69 return AVERROR(ENOMEM);
70 }
71 quirc->width = inlink->w;
72 quirc->height = inlink->h;
73
74 return 0;
75}
76
78{
79 FilterLink *inl = ff_filter_link(inlink);
80 AVFilterContext *ctx = inlink->dst;
81 AVFilterLink *outlink = ctx->outputs[0];
82 QuircContext *quirc = ctx->priv;
83 int codes_count;
84 uint8_t *image;
85
86 if (quirc->width != inlink->w || quirc->height != inlink->h) {
87 if (quirc_resize(quirc->quirc, inlink->w, inlink->h) < 0) {
89 return AVERROR(ENOMEM);
90 }
91 quirc->width = inlink->w;
92 quirc->height = inlink->h;
93 }
94
95 /* copy input image to quirc buffer */
96 image = quirc_begin(quirc->quirc, NULL, NULL);
97 av_image_copy_plane(image, inlink->w,
98 frame->data[0], frame->linesize[0], inlink->w, inlink->h);
99
100 quirc_end(quirc->quirc);
101
102 codes_count = quirc_count(quirc->quirc);
104 "Found count %d codes in image #%" PRId64 "\n", codes_count, inl->frame_count_out);
105
106 if (codes_count) {
107 int i, j;
108 AVDictionary **metadata = &frame->metadata;
109
110 av_dict_set_int(metadata, "lavfi.quirc.count", codes_count, 0);
111
112 for (i = 0; i < codes_count; i++) {
113 struct quirc_code code;
114 struct quirc_data data;
115 quirc_decode_error_t err;
116 char metadata_key[64];
117
118 quirc_extract(quirc->quirc, i, &code);
119
120 err = quirc_decode(&code, &data);
121 if (err) {
123 "Failed to decode image: %s\n", quirc_strerror(err));
124 continue;
125 }
126
127 for (j = 0; j < 4; j++) {
128 struct quirc_point corner = code.corners[j];
129
130#define SET_CORNER_METADATA(key_, value_) \
131 snprintf(metadata_key, sizeof(metadata_key)-1, \
132 "lavfi.quirc.%d.corner.%d." #key_, i, j); \
133 av_dict_set_int(metadata, metadata_key, value_, 0)
134
135 SET_CORNER_METADATA(x, corner.x);
136 SET_CORNER_METADATA(y, corner.y);
137 }
138
139 snprintf(metadata_key, sizeof(metadata_key)-1, "lavfi.quirc.%d.payload", i); \
140 av_dict_set(metadata, metadata_key, data.payload, 0);
141
143 "Found QR code at position %d,%d - %d,%d with payload: %s\n",
144 code.corners[0].x, code.corners[0].y,
145 code.corners[3].x, code.corners[3].y, data.payload);
146 }
147 }
148
149 return ff_filter_frame(outlink, frame);
150}
151
163
164static const AVClass quirc_class = {
165 .class_name = "quirc",
166 .version = LIBAVUTIL_VERSION_INT,
167 .category = AV_CLASS_CATEGORY_FILTER
168};
169
170static const AVFilterPad inputs[] = {
171 {
172 .name = "default",
173 .type = AVMEDIA_TYPE_VIDEO,
174 .filter_frame = filter_frame,
175 .config_props = config_input
176 },
177};
178
180 .p.name = "quirc",
181 .p.description = NULL_IF_CONFIG_SMALL("Decode and show QR codes content."),
182 .p.priv_class = &quirc_class,
185 .priv_size = sizeof(QuircContext),
186 .init = init,
187 .uninit = uninit,
191};
static const AVFilterPad inputs[]
Definition af_aap.c:299
static int config_input(AVFilterLink *inlink)
const FFFilter ff_vf_quirc
Definition vf_quirc.c:179
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
Main libavfilter public API header.
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
static AVFrame * frame
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition avfilter.h:196
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition avfilter.h:182
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition dict.c:177
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition imgutils.c:374
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
misc image utilities
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define FILTER_PIXFMTS_ARRAY(array)
Definition filters.h:244
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
@ AV_CLASS_CATEGORY_FILTER
Definition log.h:36
const char data[16]
Definition mxf.c:149
AVOptions.
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition pixfmt.h:96
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition pixfmt.h:106
@ AV_PIX_FMT_NV21
as above, but U and V bytes are swapped
Definition pixfmt.h:97
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition pixfmt.h:107
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition pixfmt.h:79
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition pixfmt.h:80
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition pixfmt.h:283
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition pixfmt.h:86
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition pixfmt.h:87
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition pixfmt.h:85
#define snprintf
Definition snprintf.h:34
const uint8_t * code
Definition spdifenc.c:433
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
struct quirc * quirc
Definition vf_quirc.c:38
#define av_log(a,...)
static AVFormatContext * ctx
Definition movenc.c:49
static const AVClass quirc_class
Definition vf_quirc.c:164
static int config_input(AVFilterLink *inlink)
Definition vf_quirc.c:61
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition vf_quirc.c:77
#define SET_CORNER_METADATA(key_, value_)
static av_cold void uninit(AVFilterContext *ctx)
Definition vf_quirc.c:54
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition video.c:37