FreeSWITCH API Documentation  1.7.0
fs_encode.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2015, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Mathieu Rene <mrene@avgs.ca>
27  *
28  * fs_encode.c -- Encode a native file
29  *
30  */
31 
32 #ifndef _XOPEN_SOURCE
33 #define _XOPEN_SOURCE 600
34 #endif
35 
36 #ifndef WIN32
37 #ifdef HAVE_SETRLIMIT
38 #include <sys/resource.h>
39 #endif
40 #endif
41 
42 #include <switch.h>
43 
44 /* Picky compiler */
45 #ifdef __ICC
46 #pragma warning (disable:167)
47 #endif
48 
49 static void fs_encode_cleanup()
50 {
54 }
55 
56 int main(int argc, char *argv[])
57 {
58  int r = 1;
59  switch_bool_t verbose = SWITCH_FALSE;
60  const char *err = NULL;
61  int i;
62  char *extra_modules[100] = { 0 };
63  int extra_modules_count = 0;
64  int cmd_fail = 0;
65  const char *fmtp = "";
66  int ptime = 20;
67  const char *input, *output, *format = NULL;
68  int channels = 1;
69  int rate = 8000;
70  switch_file_handle_t fh_input = { 0 }, fh_output = { 0 };
71  switch_codec_t codec = { 0 };
72  switch_codec_t raw_codec = { 0 };
73  char buf[2048];
74  switch_size_t len = sizeof(buf)/2;
75  switch_memory_pool_t *pool = NULL;
76  int bitrate = 0;
77  int blocksize;
78  int in_asis = 0;
79  int out_asis = 0;
80  int out_flags = SWITCH_FILE_FLAG_WRITE;
81 
82  for (i = 1; i < argc; i++) {
83  if (argv[i][0] == '-') {
84  switch(argv[i][1]) {
85  case 'c':
86  i++;
87  if((SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
88  return 255;
89  }
90  strcpy(SWITCH_GLOBAL_dirs.conf_dir, argv[i]);
91  break;
92  case 'k':
93  i++;
94  if((SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
95  return 255;
96  }
97  strcpy(SWITCH_GLOBAL_dirs.log_dir, argv[i]);
98  break;
99  case 'm':
100  i++;
101  if((SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
102  return 255;
103  }
104  strcpy(SWITCH_GLOBAL_dirs.mod_dir, argv[i]);
105  break;
106  case 'l':
107  i++;
108  /* Load extra modules */
109  if (strchr(argv[i], ',')) {
110  extra_modules_count = switch_split(argv[i], ',', extra_modules);
111  } else {
112  extra_modules_count = 1;
113  extra_modules[0] = argv[i];
114  }
115  break;
116  case 'f':
117  fmtp = argv[++i];
118  break;
119  case 'p':
120  ptime = atoi(argv[++i]);
121  break;
122  case 'r':
123  rate = atoi(argv[++i]);
124  break;
125  case 'b':
126  bitrate = atoi(argv[++i]);
127  break;
128  case 'v':
129  verbose = SWITCH_TRUE;
130  break;
131  default:
132  printf("Command line option not recognized: %s\n", argv[i]);
133  cmd_fail = 1;
134  }
135  } else {
136  break;
137  }
138  }
139 
140  if (argc - i < 2 || cmd_fail) {
141  goto usage;
142  }
143 
144  input = argv[i++];
145  output = argv[i++];
146  if (zstr(input) || zstr(output) || !(format = strchr(output, '.'))) {
147  goto usage;
148  }
149 
150  format++;
151 
152  if (switch_core_init(SCF_MINIMAL, verbose, &err) != SWITCH_STATUS_SUCCESS) {
153  fprintf(stderr, "Cannot init core [%s]\n", err);
154  goto end;
155  }
156 
158  switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_TRUE, &err);
159  switch_loadable_module_load_module("", "CORE_SPEEX_MODULE", SWITCH_TRUE, &err);
160  switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_TRUE, &err);
161 
162  for (i = 0; i < extra_modules_count; i++) {
163  if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) extra_modules[i], SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
164  fprintf(stderr, "Cannot init %s [%s]\n", extra_modules[i], err);
165  goto end;
166  }
167  }
168 
169  if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_spandsp", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
170  fprintf(stderr, "Cannot init mod_spandsp [%s]\n", err);
171  goto end;
172  }
173 
174  if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_sndfile", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
175  fprintf(stderr, "Cannot init mod_sndfile [%s]\n", err);
176  goto end;
177  }
178 
179  if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_native_file", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
180  fprintf(stderr, "Cannot init mod_native_file [%s]\n", err);
181  goto end;
182  }
183 
185  if (verbose) {
186  fprintf(stderr, "Opening file %s\n", input);
187  }
188  if (switch_core_file_open(&fh_input, input, channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
189  fprintf(stderr, "Couldn't open %s\n", input);
190  goto end;
191  }
192 
193 
194  if (verbose) {
195  fprintf(stderr, "Opening file %s\n", output);
196  }
197 
198  if (switch_stristr(".wav", output)) {
199  out_asis = 0;
200  out_flags |= SWITCH_FILE_DATA_SHORT;
201  } else {
202  out_asis = 1;
203  out_flags |= SWITCH_FILE_NATIVE;
204  }
205 
206 
207  if (out_asis) {
208  if (switch_core_codec_init_with_bitrate(&codec, format, NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
209  fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", format, rate, ptime);
210  goto end;
211  }
212  } else {
213  char *p;
214 
215  if ((p = strchr(input, '.'))) {
216  p++;
217  }
218  if (!p || switch_core_codec_init_with_bitrate(&codec, p, NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
219  fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", p, rate, ptime);
220  goto end;
221  }
222 
223  if (switch_core_codec_init_with_bitrate(&raw_codec, "L16", NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
224  fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", "L16", rate, ptime);
225  goto end;
226  }
227  }
228 
229 
230 
231 
232  if (switch_core_file_open(&fh_output, output, channels, codec.implementation->actual_samples_per_second, out_flags, NULL) != SWITCH_STATUS_SUCCESS) {
233  fprintf(stderr, "Couldn't open %s\n", output);
234  goto end;
235  }
236 
237  if (switch_test_flag(&fh_input, SWITCH_FILE_NATIVE)) {
238  in_asis = 1;
239  }
240 
241 
242 
243  if (in_asis) {
244  blocksize = len = codec.implementation->encoded_bytes_per_packet;
245  } else {
246  blocksize = len = (rate*ptime)/1000;
247  }
248 
249  switch_assert(sizeof(buf) >= len * 2);
250 
251  if (verbose) {
252  fprintf(stderr, "Frame size is %d\n", blocksize);
253  }
254 
255  while (switch_core_file_read(&fh_input, buf, &len) == SWITCH_STATUS_SUCCESS) {
256  char encode_buf[2048];
257  uint32_t encoded_len = sizeof(buf);
258  uint32_t encoded_rate = rate;
259  unsigned int flags = 0;
260 
261  if (out_asis) {
262  if (switch_core_codec_encode(&codec, NULL, buf, len*2, rate, encode_buf, &encoded_len, &encoded_rate, &flags) != SWITCH_STATUS_SUCCESS) {
263  fprintf(stderr, "Codec encoder error\n");
264  goto end;
265  }
266 
267  len = encoded_len;
268  } else {
269  if (!in_asis) {
270  encoded_len = len;
271  } else if (in_asis) {
272 
274  &raw_codec,
275  buf,
276  len,
277  rate,
278  encode_buf,
279  &encoded_len,
280  &encoded_rate,
281  &flags);
282  encoded_len /= 2;
283  len = encoded_len;
284  }
285  }
286 
287 
288  if (switch_core_file_write(&fh_output, encode_buf, &len) != SWITCH_STATUS_SUCCESS) {
289  fprintf(stderr, "Write error\n");
290  goto end;
291  }
292 
293  if (len != encoded_len) {
294  printf("Short write: wrote %"SWITCH_SIZE_T_FMT"/%d bytes\n", len, encoded_len);
295  }
296 
297  len = blocksize;
298  }
299 
300  r = 0;
301 
302 end:
303 
304 
306  switch_core_codec_destroy(&raw_codec);
307 
308 
309  if (fh_input.file_interface) {
310  switch_core_file_close(&fh_input);
311  }
312 
313  if (fh_output.file_interface) {
314  switch_core_file_close(&fh_output);
315  }
316 
317  if (pool) {
319  }
320 
322 
323  //switch_core_destroy();
324 
325  return r;
326 usage:
327  printf("Usage: %s [options] input output\n\n", argv[0]);
328  printf("The output must end in the format, e.g., myfile.SPEEX\n");
329  printf("\t\t -c path\t\t Path to the FS configurations.\n");
330  printf("\t\t -k path\t\t Path to the FS log directory\n");
331  printf("\t\t -l module[,module]\t Load additional modules (comma-separated)\n");
332  printf("\t\t -m path\t\t Path to the modules.\n");
333  printf("\t\t -f format\t\t fmtp to pass to the codec\n");
334  printf("\t\t -p ptime\t\t ptime to use while encoding\n");
335  printf("\t\t -r rate\t\t sampling rate\n");
336  printf("\t\t -b bitrate\t\t codec bitrate (if supported)\n");
337  printf("\t\t -v\t\t\t verbose\n");
339  return 1;
340 }
341 
342 /* For Emacs:
343  * Local Variables:
344  * mode:c
345  * indent-tabs-mode:t
346  * tab-width:4
347  * c-basic-offset:4
348  * End:
349  * For VIM:
350  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
351  */
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
switch_status_t switch_loadable_module_load_module(char *dir, char *fname, switch_bool_t runtime, const char **err)
Load a module.
#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool)
Open a media file using file format modules.
Definition: switch_core.h:1865
switch_file_interface_t * file_interface
switch_status_t switch_core_init(_In_ switch_core_flag_t flags, _In_ switch_bool_t console, _Out_ const char **err)
Initilize the core.
switch_bool_t
Definition: switch_types.h:405
switch_status_t switch_core_codec_encode(switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
Encode data using a codec handle.
#define switch_split(_data, _delim, _array)
Definition: switch_utils.h:342
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
switch_status_t switch_core_codec_decode(switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, uint32_t encoded_data_len, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
Decode data using a codec handle.
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
switch_status_t switch_core_file_read(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Read media from a file handle.
#define zstr(x)
Definition: switch_utils.h:281
int main(int argc, char *argv[])
Definition: fs_encode.c:56
static const char usage[]
Definition: switch.c:409
const switch_codec_implementation_t * implementation
switch_byte_t switch_byte_t * buf
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
uintptr_t switch_size_t
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
switch_status_t switch_core_codec_init_with_bitrate(switch_codec_t *codec, const char *codec_name, const char *fmtp, const char *modname, uint32_t rate, int ms, int channels, uint32_t bitrate, uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool)
switch_status_t switch_core_file_write(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Write media to a file handle.
Main Library Header.
static void fs_encode_cleanup()
Definition: fs_encode.c:49
switch_status_t switch_loadable_module_init(switch_bool_t autoload)
Initilize the module backend and load all the modules.
struct apr_pool_t switch_memory_pool_t
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
const char * switch_stristr(const char *instr, const char *str)
#define switch_assert(expr)
#define SWITCH_SIZE_T_FMT