tools: add zmqsend tool, useful to test the zmq filters
authorStefano Sabatini <stefasab@gmail.com>
Fri, 3 May 2013 16:05:18 +0000 (18:05 +0200)
committerStefano Sabatini <stefasab@gmail.com>
Tue, 14 May 2013 18:10:55 +0000 (20:10 +0200)
.gitignore
doc/filters.texi
libavfilter/Makefile
tools/zmqsend.c [new file with mode: 0644]

index 979d617..dd93958 100644 (file)
@@ -74,3 +74,4 @@
 /tools/qt-faststart
 /tools/trasher
 /tools/seek_print
+/tools/zmqsend
index f14cf6b..def2751 100644 (file)
@@ -8413,6 +8413,32 @@ will send a reply to the client, adopting the format:
 
 @var{MESSAGE} is optional.
 
+@subsection Examples
+
+Look at @file{tools/zmqsend} for an example of a zmq client which can
+be used to send commands processed by these filters.
+
+Consider the following filtergraph generated by @command{ffplay}
+@example
+ffplay -dumpgraph 1 -f lavfi "
+color=s=100x100:c=red  [l];
+color=s=100x100:c=blue [r];
+nullsrc=s=200x100, zmq [bg];
+[bg][l]   overlay      [bg+l];
+[bg+l][r] overlay=x=100 "
+@end example
+
+To change the color of the left side of the video, the following
+command can be used:
+@example
+echo Parsed_color_0 c yellow | tools/zmqsend
+@end example
+
+To change the right side:
+@example
+echo Parsed_color_1 c pink | tools/zmqsend
+@end example
+
 @c man end MULTIMEDIA FILTERS
 
 @chapter Multimedia Sources
index f070dd0..0194186 100644 (file)
@@ -238,7 +238,7 @@ OBJS-$(CONFIG_MOVIE_FILTER)                  += src_movie.o
 SKIPHEADERS-$(CONFIG_LIBVIDSTAB)             += vidstabutils.h
 SKIPHEADERS-$(CONFIG_OPENCL)                 += opencl_internal.h deshake_opencl_kernel.h unsharp_opencl_kernel.h
 
-TOOLS     = graph2dot
+TOOLS     = graph2dot zmqsend
 TESTPROGS = drawutils filtfmts formats
 
 clean::
diff --git a/tools/zmqsend.c b/tools/zmqsend.c
new file mode 100644 (file)
index 0000000..ae3c8d7
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2013 Stefano Sabatini
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <zmq.h>
+
+#include "libavutil/mem.h"
+#include "libavutil/bprint.h"
+
+#if HAVE_UNISTD_H
+#include <unistd.h>             /* getopt */
+#endif
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+/**
+ * @file
+ * zmq message sender example, meant to be used with the zmq filters
+ */
+
+static void usage(void)
+{
+    printf("send message to ZMQ recipient, to use with the zmq filters\n");
+    printf("usage: zmqsend [OPTIONS]\n");
+    printf("\n"
+           "Options:\n"
+           "-b ADDRESS        set bind address\n"
+           "-h                print this help\n"
+           "-i INFILE         set INFILE as input file, stdin if omitted\n");
+}
+
+int main(int argc, char **argv)
+{
+    AVBPrint src;
+    char c, *src_buf, *recv_buf;
+    int recv_buf_size, ret;
+    void *ctx, *socket;
+    const char *bind_address = "tcp://localhost:5555";
+    const char *infilename = NULL;
+    FILE *infile = NULL;
+    zmq_msg_t msg;
+
+    while ((c = getopt(argc, argv, "b:hi:")) != -1) {
+        switch (c) {
+        case 'b':
+            bind_address = optarg;
+            break;
+        case 'h':
+            usage();
+            return 0;
+        case 'i':
+            infilename = optarg;
+            break;
+        case '?':
+            return 1;
+        }
+    }
+
+    if (!infilename || !strcmp(infilename, "-")) {
+        infilename = "stdin";
+        infile = stdin;
+    } else {
+        infile = fopen(infilename, "r");
+    }
+    if (!infile) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
+        return 1;
+    }
+
+    ctx = zmq_ctx_new();
+    if (!ctx) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Could not create ZMQ context: %s\n", zmq_strerror(errno));
+        return 1;
+    }
+
+    socket = zmq_socket(ctx, ZMQ_REQ);
+    if (!socket) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not create ZMQ socket: %s\n", zmq_strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    if (zmq_connect(socket, bind_address) == -1) {
+        av_log(ctx, AV_LOG_ERROR, "Could not bind ZMQ responder to address '%s': %s\n",
+               bind_address, zmq_strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    /* grab the input and store it in src */
+    av_bprint_init(&src, 1, AV_BPRINT_SIZE_UNLIMITED);
+    while ((c = fgetc(infile)) != EOF)
+        av_bprint_chars(&src, c, 1);
+    av_bprint_chars(&src, 0, 1);
+
+    if (!av_bprint_is_complete(&src)) {
+        av_log(NULL, AV_LOG_ERROR, "Could not allocate a buffer for the source string\n");
+        av_bprint_finalize(&src, NULL);
+        ret = 1;
+        goto end;
+    }
+    av_bprint_finalize(&src, &src_buf);
+
+    if (zmq_send(socket, src_buf, strlen(src_buf), 0) == -1) {
+        av_log(NULL, AV_LOG_ERROR, "Could not send message: %s\n", zmq_strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    if (zmq_msg_init(&msg) == -1) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not initialize receiving message: %s\n", zmq_strerror(errno));
+        ret = 1;
+        goto end;
+    }
+
+    if (zmq_msg_recv(&msg, socket, 0) == -1) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not receive message: %s\n", zmq_strerror(errno));
+        zmq_msg_close(&msg);
+        ret = 1;
+        goto end;
+    }
+
+    recv_buf_size = zmq_msg_size(&msg) + 1;
+    recv_buf = av_malloc(recv_buf_size);
+    if (!recv_buf) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Could not allocate receiving message buffer\n");
+        zmq_msg_close(&msg);
+        ret = 1;
+        goto end;
+    }
+    memcpy(recv_buf, zmq_msg_data(&msg), recv_buf_size);
+    recv_buf[recv_buf_size-1] = 0;
+    printf("%s\n", recv_buf);
+    zmq_msg_close(&msg);
+    av_free(recv_buf);
+
+end:
+    zmq_close(socket);
+    zmq_ctx_destroy(ctx);
+    return ret;
+}