51#pragma GCC diagnostic push
52#pragma GCC diagnostic ignored "-Wtype-limits"
54#include <MagickWand/MagickWand.h>
56#pragma GCC diagnostic warning "-Wignored-qualifiers"
57#include <wand/magick_wand.h>
59#pragma GCC diagnostic pop
107#define MARGIN_X_DIV 60
108#define MARGIN_Y_DIV 60
114 atexit(MagickWandTerminus);
123 if (strlen(config) == 0 || strcmp(config,
"help") == 0) {
124 char desc[] =
TBOLD(
"text")
" video postprocess takes as a parameter text to be drawed. "
125 "Colons in text must be escaped with a backslash (see Examples). Spaces may be escaped or the whole argument should be enclosed by quotation marks.\n";
132 "\t-p text:x=100:y=100:h=20:t=text\n"
133 "\t-p \"text:Video stream from location XY\"\n"
134 "\t-p \"text:Text can also contains escaped colons - \\:\"\n")
139 s = calloc(1,
sizeof *s);
142 char *config_copy = strdup(config);
144 char *tmp = config_copy, *
item, *save_ptr;
145 while ((
item = strtok_r(tmp,
":", &save_ptr))) {
146 if (strstr(
item,
"x=") != NULL) {
148 }
else if (strstr(
item,
"y=") != NULL) {
150 }
else if (strstr(
item,
"h=") != NULL) {
152 }
else if (strstr(
item,
"t=") != NULL) {
163 if(!s->
text || strlen(s->
text) == 0){
201 DestroyDrawingWand(s->
dw);
217 const char *color_outline;
218 const char *colorspace;
221 color_outline =
"#FFFFFFFF";
225 color_outline =
"#FFFFFFFF";
229 color_outline =
"#EB8080FF";
236 s->
dw = NewDrawingWand();
238 MagickBooleanType
status = DrawSetFont(s->
dw,
"helvetica");
239 if(
status != MagickTrue) {
244 PixelWand *pw = NewPixelWand();
245 PixelSetColor(pw, color);
246 DrawSetFillColor(s->
dw, pw);
247 PixelSetColor(pw, color_outline);
248 DrawSetStrokeColor(s->
dw, pw);
249 DestroyPixelWand(pw);
256 if(
status != MagickTrue) {
264 assert(
status == MagickTrue &&
"[text vo_pp.] MagickSetDepth failed");
266 PixelWand *transparent_bg = NewPixelWand();
268 PixelSetColor(transparent_bg,
"#00000000");
271 MagickNewImage(s->
wand_text, 1, 1, transparent_bg);
274 double *metrics = MagickQueryFontMetrics(s->
wand_text, s->
dw, s->
text);
279 double descender = metrics[3];
297 "Perhaps the text contains invalid characters?\n");
301 DestroyPixelWand(transparent_bg);
327 assert(stripe != NULL &&
"Malloc failed");
334 if (y + s->
margin_y >= im_height_px)
338 memcpy(stripe + (y) * dst_linesize,
347 assert(
status == MagickTrue &&
"[text vo_pp.] MagickSetSize failed -- ");
350 if (
status != MagickTrue) {
361 if (
status != MagickTrue) {
370 assert(
data != NULL &&
"[text vo_pp.] MagickGetImageBlob failed!");
383 if (y + s->
margin_y >= im_height_px) {
388 data + y * dst_linesize,
432 DestroyDrawingWand(s->
dw);
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct video_desc video_desc_from_frame(const struct video_frame *frame)
Returns struct video_desc from video frame.
int vc_get_linesize(unsigned int width, codec_t codec)
struct video_frame * vf_alloc_desc_data(struct video_desc desc)
#define CAPTURE_FILTER_ABI_VERSION
int color_printf(const char *format,...)
void log_msg(int level, const char *format,...)
void bug_msg(int level, const char *format,...)
prints the error with the advice to report the bug
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_WARNING
less severe errors
@ DISPLAY_PROPERTY_VIDEO_MERGED
monolithic framebuffer
@ LIBRARY_CLASS_VIDEO_POSTPROCESS
@ LIBRARY_CLASS_CAPTURE_FILTER
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
void replace_all(char *in, const char *from, const char *to)
Replaces all occurencies of 'from' to 'to' in string 'in'.
struct video_desc saved_desc
char * data
Raw tile data. Pointer must be at least 4B aligned.
unsigned int data_len
length of the data
unsigned int width
width of every tile (!)
unsigned int height
height of every tile (!)
void(* dispose)(struct video_frame *)
Struct video_frame represents a video frame and contains video description.
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
struct video_frame_callbacks callbacks
@ RGB
RGB 8-bit (packed into 24-bit word)
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
@ RGBA
RGBA 8-bit, big-endian.
char * wrap_paragraph(char *text)
This is an umbrella header for video functions.
bool video_desc_eq(struct video_desc a, struct video_desc b)
Compares two video descriptions.
#define VIDEO_FRAME_DISPOSE(frame)
static const struct capture_filter_info capture_filter_text_info
static bool text_postprocess(void *state, struct video_frame *in, struct video_frame *out, int req_pitch)
static const struct vo_postprocess_info vo_pp_text_info
static void text_done(void *state)
static void * text_init(const char *config)
static bool text_postprocess_reconfigure(void *state, struct video_desc desc)
static int cf_text_init(struct module *parent, const char *cfg, void **state)
static pthread_once_t vo_postprocess_text_initialized
static struct video_frame * cf_text_filter(void *state, struct video_frame *f)
static void text_get_out_desc(void *state, struct video_desc *out, int *in_display_mode, int *out_frames)
static bool text_get_property(void *state, int property, void *val, size_t *len)
static struct video_frame * text_getf(void *state)
#define VO_PP_ABI_VERSION