FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
zmqsend.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Stefano Sabatini
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "config.h"
22 
23 #include <zmq.h>
24 
25 #include "libavutil/mem.h"
26 #include "libavutil/bprint.h"
27 
28 #if HAVE_UNISTD_H
29 #include <unistd.h> /* getopt */
30 #endif
31 
32 #if !HAVE_GETOPT
33 #include "compat/getopt.c"
34 #endif
35 
36 /**
37  * @file
38  * zmq message sender example, meant to be used with the zmq filters
39  */
40 
41 static void usage(void)
42 {
43  printf("send message to ZMQ recipient, to use with the zmq filters\n");
44  printf("usage: zmqsend [OPTIONS]\n");
45  printf("\n"
46  "Options:\n"
47  "-b ADDRESS set bind address\n"
48  "-h print this help\n"
49  "-i INFILE set INFILE as input file, stdin if omitted\n");
50 }
51 
52 int main(int argc, char **argv)
53 {
54  AVBPrint src;
55  char c, *src_buf, *recv_buf;
56  int recv_buf_size, ret;
57  void *ctx, *socket;
58  const char *bind_address = "tcp://localhost:5555";
59  const char *infilename = NULL;
60  FILE *infile = NULL;
61  zmq_msg_t msg;
62 
63  while ((c = getopt(argc, argv, "b:hi:")) != -1) {
64  switch (c) {
65  case 'b':
66  bind_address = optarg;
67  break;
68  case 'h':
69  usage();
70  return 0;
71  case 'i':
72  infilename = optarg;
73  break;
74  case '?':
75  return 1;
76  }
77  }
78 
79  if (!infilename || !strcmp(infilename, "-")) {
80  infilename = "stdin";
81  infile = stdin;
82  } else {
83  infile = fopen(infilename, "r");
84  }
85  if (!infile) {
86  av_log(NULL, AV_LOG_ERROR,
87  "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
88  return 1;
89  }
90 
91  ctx = zmq_ctx_new();
92  if (!ctx) {
93  av_log(NULL, AV_LOG_ERROR,
94  "Could not create ZMQ context: %s\n", zmq_strerror(errno));
95  return 1;
96  }
97 
98  socket = zmq_socket(ctx, ZMQ_REQ);
99  if (!socket) {
100  av_log(ctx, AV_LOG_ERROR,
101  "Could not create ZMQ socket: %s\n", zmq_strerror(errno));
102  ret = 1;
103  goto end;
104  }
105 
106  if (zmq_connect(socket, bind_address) == -1) {
107  av_log(ctx, AV_LOG_ERROR, "Could not bind ZMQ responder to address '%s': %s\n",
108  bind_address, zmq_strerror(errno));
109  ret = 1;
110  goto end;
111  }
112 
113  /* grab the input and store it in src */
115  while ((c = fgetc(infile)) != EOF)
116  av_bprint_chars(&src, c, 1);
117  av_bprint_chars(&src, 0, 1);
118 
119  if (!av_bprint_is_complete(&src)) {
120  av_log(NULL, AV_LOG_ERROR, "Could not allocate a buffer for the source string\n");
121  av_bprint_finalize(&src, NULL);
122  ret = 1;
123  goto end;
124  }
125  av_bprint_finalize(&src, &src_buf);
126 
127  if (zmq_send(socket, src_buf, strlen(src_buf), 0) == -1) {
128  av_log(NULL, AV_LOG_ERROR, "Could not send message: %s\n", zmq_strerror(errno));
129  ret = 1;
130  goto end;
131  }
132 
133  if (zmq_msg_init(&msg) == -1) {
134  av_log(ctx, AV_LOG_ERROR,
135  "Could not initialize receiving message: %s\n", zmq_strerror(errno));
136  ret = 1;
137  goto end;
138  }
139 
140  if (zmq_msg_recv(&msg, socket, 0) == -1) {
141  av_log(ctx, AV_LOG_ERROR,
142  "Could not receive message: %s\n", zmq_strerror(errno));
143  zmq_msg_close(&msg);
144  ret = 1;
145  goto end;
146  }
147 
148  recv_buf_size = zmq_msg_size(&msg) + 1;
149  recv_buf = av_malloc(recv_buf_size);
150  if (!recv_buf) {
151  av_log(ctx, AV_LOG_ERROR,
152  "Could not allocate receiving message buffer\n");
153  zmq_msg_close(&msg);
154  ret = 1;
155  goto end;
156  }
157  memcpy(recv_buf, zmq_msg_data(&msg), recv_buf_size);
158  recv_buf[recv_buf_size-1] = 0;
159  printf("%s\n", recv_buf);
160  zmq_msg_close(&msg);
161  av_free(recv_buf);
162 
163 end:
164  zmq_close(socket);
165  zmq_ctx_destroy(ctx);
166  return ret;
167 }