FreeSWITCH API Documentation  1.7.0
Functions
switch_core_file.c File Reference
#include <switch.h>
#include "private/switch_core_pvt.h"
+ Include dependency graph for switch_core_file.c:

Go to the source code of this file.

Functions

switch_status_t switch_core_perform_file_open (const char *file, const char *func, int line, switch_file_handle_t *fh, const char *file_path, uint32_t channels, uint32_t rate, unsigned int flags, switch_memory_pool_t *pool)
 
switch_status_t switch_core_file_read (switch_file_handle_t *fh, void *data, switch_size_t *len)
 
switch_bool_t switch_core_file_has_video (switch_file_handle_t *fh, switch_bool_t check_open)
 
switch_status_t switch_core_file_write (switch_file_handle_t *fh, void *data, switch_size_t *len)
 
switch_status_t switch_core_file_write_video (switch_file_handle_t *fh, switch_frame_t *frame)
 
switch_status_t switch_core_file_read_video (switch_file_handle_t *fh, switch_frame_t *frame, switch_video_read_flag_t flags)
 
switch_status_t switch_core_file_seek (switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
 
switch_status_t switch_core_file_set_string (switch_file_handle_t *fh, switch_audio_col_t col, const char *string)
 
switch_status_t switch_core_file_get_string (switch_file_handle_t *fh, switch_audio_col_t col, const char **string)
 
switch_status_t switch_core_file_truncate (switch_file_handle_t *fh, int64_t offset)
 
switch_status_t switch_core_file_command (switch_file_handle_t *fh, switch_file_command_t command)
 
switch_status_t switch_core_file_close (switch_file_handle_t *fh)
 

Function Documentation

switch_status_t switch_core_file_close ( switch_file_handle_t fh)

Definition at line 774 of file switch_core_file.c.

References switch_assert, switch_buffer_destroy(), switch_buffer_inuse(), switch_buffer_read(), SWITCH_CHANNEL_LOG, switch_clear_flag_locked, switch_core_destroy_memory_pool, switch_event_destroy(), SWITCH_FILE_FLAG_FREE_POOL, SWITCH_FILE_FLAG_WRITE, SWITCH_FILE_NATIVE, SWITCH_FILE_OPEN, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_mprintf(), switch_resample_destroy(), switch_safe_free, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, and UNPROTECT_INTERFACE.

775 {
776  switch_status_t status;
777 
778  switch_assert(fh != NULL);
779  switch_assert(fh->file_interface != NULL);
780 
782  return SWITCH_STATUS_FALSE;
783  }
784 
785  if (fh->pre_buffer) {
787  switch_size_t rlen, blen;
788  int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
789 
790  while ((rlen = switch_buffer_inuse(fh->pre_buffer))) {
791  if ((blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen))) {
792  if (!asis)
793  blen /= 2;
794  if (fh->channels > 1)
795  blen /= fh->channels;
796 
797  if (fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen) != SWITCH_STATUS_SUCCESS) {
798  break;
799  }
800  }
801  }
802  }
803 
805  }
806 
808  status = fh->file_interface->file_close(fh);
809 
810  if (fh->params) {
812  }
813 
814  fh->samples_in = 0;
815  fh->max_samples = 0;
816 
817  if (fh->buffer) {
819  }
820 
822 
825  }
826 
827  fh->memory_pool = NULL;
828 
829  switch_safe_free(fh->dbuf);
830 
831  if (fh->spool_path) {
832  char *command;
833 
834 #ifdef _MSC_VER
835  command = switch_mprintf("move %s %s", fh->spool_path, fh->file_path);
836 #else
837  command = switch_mprintf("/bin/mv %s %s", fh->spool_path, fh->file_path);
838 #endif
839  if (system(command) == -1) {
840  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to copy spooled file [%s] to [%s] because of a command error : %s\n", fh->spool_path, fh->file_path, command);
841  } else {
842  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Copy spooled file [%s] to [%s]\n", fh->spool_path, fh->file_path);
843  }
844  free(command);
845  }
846 
848  fh->file_interface = NULL;
849 
850  return status;
851 }
#define SWITCH_CHANNEL_LOG
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_file_interface_t * file_interface
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
switch_audio_resampler_t * resampler
switch_memory_pool_t * memory_pool
#define UNPROTECT_INTERFACE(_it)
switch_status_t(* file_close)(switch_file_handle_t *)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_buffer_t * pre_buffer
uintptr_t switch_size_t
switch_status_t(* file_write)(switch_file_handle_t *, void *data, switch_size_t *len)
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:648
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
switch_status_t switch_core_file_get_string ( switch_file_handle_t fh,
switch_audio_col_t  col,
const char **  string 
)

Definition at line 697 of file switch_core_file.c.

References switch_assert, SWITCH_FILE_OPEN, SWITCH_STATUS_FALSE, and switch_test_flag.

698 {
699  switch_assert(fh != NULL);
700  switch_assert(fh->file_interface != NULL);
701 
703  return SWITCH_STATUS_FALSE;
704  }
705 
706  if (!fh->file_interface->file_get_string) {
707  return SWITCH_STATUS_FALSE;
708  }
709 
710  return fh->file_interface->file_get_string(fh, col, string);
711 }
switch_file_interface_t * file_interface
switch_status_t(* file_get_string)(switch_file_handle_t *fh, switch_audio_col_t col, const char **string)
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
#define switch_assert(expr)
switch_status_t switch_core_file_read ( switch_file_handle_t fh,
void *  data,
switch_size_t len 
)

Definition at line 372 of file switch_core_file.c.

References switch_assert, switch_buffer_create_dynamic(), switch_buffer_inuse(), switch_buffer_read(), switch_buffer_write(), SWITCH_CHANNEL_LOG, switch_clear_flag_locked, SWITCH_FILE_BUFFER_DONE, SWITCH_FILE_DONE, SWITCH_FILE_NATIVE, SWITCH_FILE_NOMUX, SWITCH_FILE_OPEN, SWITCH_LOG_CRIT, switch_log_printf(), switch_mux_channels(), switch_resample_create, switch_resample_process(), SWITCH_RESAMPLE_QUALITY, switch_set_flag_locked, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, and switch_test_flag.

373 {
375  switch_size_t want, orig_len = *len;
376 
377  switch_assert(fh != NULL);
378  switch_assert(fh->file_interface != NULL);
379 
381  return SWITCH_STATUS_FALSE;
382  }
383 
384  top:
385 
386  if (fh->max_samples > 0 && fh->samples_in >= (switch_size_t)fh->max_samples) {
387  *len = 0;
388  return SWITCH_STATUS_FALSE;
389  }
390 
391  if (fh->buffer && switch_buffer_inuse(fh->buffer) >= *len * 2 * fh->channels) {
392  *len = switch_buffer_read(fh->buffer, data, orig_len * 2 * fh->channels) / 2 / fh->channels;
393  return *len == 0 ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
394  }
395 
398  *len = 0;
399  return SWITCH_STATUS_FALSE;
400  }
401 
402  want = *len;
403 
404  more:
405 
406  if (fh->pre_buffer) {
407  switch_size_t rlen;
408  int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
409 
411  rlen = asis ? fh->pre_buffer_datalen : fh->pre_buffer_datalen / 2 / fh->real_channels;
412 
413  if (switch_buffer_inuse(fh->pre_buffer) < rlen * 2 * fh->channels) {
414  if ((status = fh->file_interface->file_read(fh, fh->pre_buffer_data, &rlen)) == SWITCH_STATUS_BREAK) {
415  return SWITCH_STATUS_BREAK;
416  }
417 
418 
419  if (status != SWITCH_STATUS_SUCCESS || !rlen) {
421  } else {
422  fh->samples_in += rlen;
423  if (fh->real_channels != fh->channels && !switch_test_flag(fh, SWITCH_FILE_NOMUX)) {
424  switch_mux_channels((int16_t *) fh->pre_buffer_data, rlen, fh->real_channels, fh->channels);
425  }
426  switch_buffer_write(fh->pre_buffer, fh->pre_buffer_data, asis ? rlen : rlen * 2 * fh->channels);
427  }
428  }
429  }
430 
431  rlen = switch_buffer_read(fh->pre_buffer, data, asis ? *len : *len * 2 * fh->channels);
432  *len = asis ? rlen : rlen / 2 / fh->channels;
433 
434  if (*len == 0) {
436  goto top;
437  } else {
438  status = SWITCH_STATUS_SUCCESS;
439  }
440 
441  } else {
442 
443  if ((status = fh->file_interface->file_read(fh, data, len)) == SWITCH_STATUS_BREAK) {
444  return SWITCH_STATUS_BREAK;
445  }
446 
447  if (status != SWITCH_STATUS_SUCCESS || !*len) {
449  goto top;
450  }
451 
452  fh->samples_in += *len;
453 
454  if (fh->real_channels != fh->channels && !switch_test_flag(fh, SWITCH_FILE_NOMUX)) {
455  switch_mux_channels((int16_t *) data, *len, fh->real_channels, fh->channels);
456  }
457  }
458 
459  if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
460  if (!fh->resampler) {
462  fh->native_rate, fh->samplerate, (uint32_t) orig_len, SWITCH_RESAMPLE_QUALITY, fh->channels) != SWITCH_STATUS_SUCCESS) {
463  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
464  return SWITCH_STATUS_GENERR;
465  }
466  }
467 
468  switch_resample_process(fh->resampler, data, (uint32_t) *len);
469 
470  if (fh->resampler->to_len < want || fh->resampler->to_len > orig_len) {
471  if (!fh->buffer) {
472  int factor = fh->resampler->to_len * fh->samplerate / 1000;
473  switch_buffer_create_dynamic(&fh->buffer, factor, factor, 0);
474  switch_assert(fh->buffer);
475  }
476  if (!fh->dbuf || fh->dbuflen < fh->resampler->to_len * 2 * fh->channels) {
477  void *mem;
478  fh->dbuflen = fh->resampler->to_len * 2 * fh->channels;
479  mem = realloc(fh->dbuf, fh->dbuflen);
480  switch_assert(mem);
481  fh->dbuf = mem;
482  }
483  switch_assert(fh->resampler->to_len * 2 * fh->channels <= fh->dbuflen);
484  memcpy((int16_t *) fh->dbuf, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
485  switch_buffer_write(fh->buffer, fh->dbuf, fh->resampler->to_len * 2 * fh->channels);
486 
487  if (switch_buffer_inuse(fh->buffer) < want * 2 * fh->channels) {
488  *len = want;
489  goto more;
490  }
491  *len = switch_buffer_read(fh->buffer, data, orig_len * 2 * fh->channels) / 2 / fh->channels;
492  } else {
493  memcpy(data, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
494  *len = fh->resampler->to_len;
495  }
496 
497 
498  }
499 
500  return status;
501 }
#define SWITCH_CHANNEL_LOG
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
switch_file_interface_t * file_interface
#define SWITCH_RESAMPLE_QUALITY
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
switch_audio_resampler_t * resampler
switch_buffer_t * pre_buffer
uintptr_t switch_size_t
#define switch_set_flag_locked(obj, flag)
Set a flag on an arbitrary object while locked.
Definition: switch_utils.h:638
switch_status_t(* file_read)(switch_file_handle_t *, void *data, switch_size_t *len)
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:648
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_assert(expr)
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c)
uint32_t switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
Resample one float buffer into another using specifications of a given handle.
switch_status_t switch_core_file_seek ( switch_file_handle_t fh,
unsigned int *  cur_pos,
int64_t  samples,
int  whence 
)

Definition at line 630 of file switch_core_file.c.

References cur, switch_assert, switch_buffer_zero(), SWITCH_FILE_FLAG_READ, SWITCH_FILE_FLAG_WRITE, SWITCH_FILE_OPEN, SWITCH_FILE_SEEK, SWITCH_FILE_WRITE_APPEND, SWITCH_FILE_WRITE_OVER, SWITCH_SEEK_CUR, switch_set_flag_locked, SWITCH_STATUS_FALSE, and switch_test_flag.

631 {
632  switch_status_t status;
633  int ok = 1;
634 
635  switch_assert(fh != NULL);
636 
638  ok = 0;
639  } else if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
641  ok = 0;
642  }
643  } else if (!switch_test_flag(fh, SWITCH_FILE_FLAG_READ)) {
644  ok = 0;
645  }
646 
647  if (!ok) {
648  return SWITCH_STATUS_FALSE;
649  }
650 
651  if (fh->buffer) {
653  }
654 
655  if (fh->pre_buffer) {
657  }
658 
659  if (whence == SWITCH_SEEK_CUR) {
660  unsigned int cur = 0;
661 
663  fh->file_interface->file_seek(fh, &cur, fh->samples_out, SEEK_SET);
664  } else {
665  fh->file_interface->file_seek(fh, &cur, fh->offset_pos, SEEK_SET);
666  }
667  }
668 
670  status = fh->file_interface->file_seek(fh, cur_pos, samples, whence);
671 
672  fh->offset_pos = *cur_pos;
673 
675  fh->samples_out = *cur_pos;
676  }
677 
678  return status;
679 }
switch_file_interface_t * file_interface
pack cur
switch_buffer_t * pre_buffer
#define SWITCH_SEEK_CUR
Definition: switch_apr.h:699
void switch_buffer_zero(_In_ switch_buffer_t *buffer)
Remove all data from the buffer.
#define switch_set_flag_locked(obj, flag)
Set a flag on an arbitrary object while locked.
Definition: switch_utils.h:638
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
#define switch_assert(expr)
switch_status_t(* file_seek)(switch_file_handle_t *, unsigned int *cur_pos, int64_t samples, int whence)
switch_status_t switch_core_file_set_string ( switch_file_handle_t fh,
switch_audio_col_t  col,
const char *  string 
)

Definition at line 681 of file switch_core_file.c.

References switch_assert, SWITCH_FILE_OPEN, SWITCH_STATUS_FALSE, and switch_test_flag.

682 {
683  switch_assert(fh != NULL);
684  switch_assert(fh->file_interface != NULL);
685 
687  return SWITCH_STATUS_FALSE;
688  }
689 
690  if (!fh->file_interface->file_set_string) {
691  return SWITCH_STATUS_FALSE;
692  }
693 
694  return fh->file_interface->file_set_string(fh, col, string);
695 }
switch_file_interface_t * file_interface
switch_status_t(* file_set_string)(switch_file_handle_t *fh, switch_audio_col_t col, const char *string)
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
#define switch_assert(expr)
switch_status_t switch_core_file_write ( switch_file_handle_t fh,
void *  data,
switch_size_t len 
)

Definition at line 508 of file switch_core_file.c.

References switch_assert, switch_buffer_inuse(), switch_buffer_read(), switch_buffer_write(), SWITCH_CHANNEL_LOG, SWITCH_FILE_NATIVE, SWITCH_FILE_OPEN, SWITCH_LOG_CRIT, switch_log_printf(), switch_resample_create, switch_resample_process(), SWITCH_RESAMPLE_QUALITY, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, and switch_test_flag.

509 {
510  switch_size_t orig_len = *len;
511 
512  switch_assert(fh != NULL);
513  switch_assert(fh->file_interface != NULL);
514 
516  return SWITCH_STATUS_FALSE;
517  }
518 
519  if (!fh->file_interface->file_write) {
520  return SWITCH_STATUS_FALSE;
521  }
522 
523  if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
524  if (!fh->resampler) {
526  fh->native_rate,
527  fh->samplerate,
528  (uint32_t) orig_len * 2 * fh->channels, SWITCH_RESAMPLE_QUALITY, fh->channels) != SWITCH_STATUS_SUCCESS) {
529  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
530  return SWITCH_STATUS_GENERR;
531  }
532  }
533 
534  switch_resample_process(fh->resampler, data, (uint32_t) * len);
535 
536  if (fh->resampler->to_len > orig_len) {
537  if (!fh->dbuf || (fh->dbuflen < fh->resampler->to_len * 2 * fh->channels)) {
538  void *mem;
539  fh->dbuflen = fh->resampler->to_len * 2 * fh->channels;
540  mem = realloc(fh->dbuf, fh->dbuflen);
541  switch_assert(mem);
542  fh->dbuf = mem;
543  }
544  switch_assert(fh->resampler->to_len * 2 * fh->channels <= fh->dbuflen);
545  memcpy(fh->dbuf, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
546  data = fh->dbuf;
547  } else {
548  memcpy(data, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
549  }
550 
551  *len = fh->resampler->to_len;
552  }
553 
554  if (!*len) {
555  return SWITCH_STATUS_SUCCESS;
556  }
557 
558  if (fh->pre_buffer) {
559  switch_size_t rlen, blen;
561  int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
562 
563  switch_buffer_write(fh->pre_buffer, data, (asis ? *len : *len * 2) * fh->channels);
564 
565  rlen = switch_buffer_inuse(fh->pre_buffer);
566 
567  if (rlen >= fh->pre_buffer_datalen) {
568  if ((blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen))) {
569  if (!asis)
570  blen /= 2;
571  if (fh->channels > 1)
572  blen /= fh->channels;
573  if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) {
574  *len = 0;
575  }
576  }
577  }
578  fh->samples_out += orig_len;
579  return status;
580  } else {
581  switch_status_t status;
582  if ((status = fh->file_interface->file_write(fh, data, len)) == SWITCH_STATUS_SUCCESS) {
583  fh->samples_out += orig_len;
584  }
585  return status;
586  }
587 }
#define SWITCH_CHANNEL_LOG
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_file_interface_t * file_interface
#define SWITCH_RESAMPLE_QUALITY
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
switch_audio_resampler_t * resampler
switch_buffer_t * pre_buffer
uintptr_t switch_size_t
switch_status_t(* file_write)(switch_file_handle_t *, void *data, switch_size_t *len)
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_assert(expr)
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c)
uint32_t switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
Resample one float buffer into another using specifications of a given handle.
switch_status_t switch_core_file_write_video ( switch_file_handle_t fh,
switch_frame_t frame 
)

Definition at line 589 of file switch_core_file.c.

References switch_assert, SWITCH_FILE_OPEN, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, and switch_test_flag.

590 {
591  switch_assert(fh != NULL);
592  switch_assert(fh->file_interface != NULL);
593 
595  return SWITCH_STATUS_GENERR;
596  }
597 
598  if (!fh->file_interface->file_write_video) {
599  return SWITCH_STATUS_FALSE;
600  }
601 
602  return fh->file_interface->file_write_video(fh, frame);
603 
604 }
switch_file_interface_t * file_interface
switch_status_t(* file_write_video)(switch_file_handle_t *, switch_frame_t *frame)
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
#define switch_assert(expr)
switch_status_t switch_core_perform_file_open ( const char *  file,
const char *  func,
int  line,
switch_file_handle_t fh,
const char *  file_path,
uint32_t  channels,
uint32_t  rate,
unsigned int  flags,
switch_memory_pool_t pool 
)

Definition at line 39 of file switch_core_file.c.

References fail, pool, SWITCH_AUDIO_SPOOL_PATH_VARIABLE, switch_buffer_create_dynamic(), SWITCH_CHANNEL_LOG, switch_clear_flag_locked, switch_copy_string(), switch_core_alloc, switch_core_destroy_memory_pool, switch_core_get_variable_pdup(), switch_core_new_memory_pool, switch_core_sprintf(), switch_core_strdup, switch_directory_exists(), switch_event_create_brackets(), switch_event_destroy(), switch_event_get_header, SWITCH_FALSE, switch_file_exists(), SWITCH_FILE_FLAG_FREE_POOL, SWITCH_FILE_FLAG_READ, SWITCH_FILE_FLAG_VIDEO, SWITCH_FILE_FLAG_WRITE, SWITCH_FILE_NOMUX, SWITCH_FILE_OPEN, switch_goto_status, switch_loadable_module_get_file_interface(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_init(), SWITCH_MUTEX_NESTED, SWITCH_PATH_SEPARATOR, switch_set_flag, switch_set_flag_locked, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_true(), SWITCH_URL_SEPARATOR, switch_uuid_format(), SWITCH_UUID_FORMATTED_LENGTH, switch_uuid_get(), SWITCH_VIDEO_ENCODE_SPEED_DEFAULT, SWITCH_VIDEO_ENCODE_SPEED_FAST, SWITCH_VIDEO_ENCODE_SPEED_MEDIUM, SWITCH_VIDEO_ENCODE_SPEED_SLOW, SWITCH_VIDEO_PROFILE_BASELINE, SWITCH_VIDEO_PROFILE_HIGH, SWITCH_VIDEO_PROFILE_MAIN, UNPROTECT_INTERFACE, and zstr.

43 {
44  char *ext;
46  char stream_name[128] = "";
47  char *rhs = NULL;
48  const char *spool_path = NULL;
49  int is_stream = 0;
50  char *fp = NULL;
51  int to = 0;
52 
54  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Handle already open\n");
55  return SWITCH_STATUS_FALSE;
56  }
57 
58  fh->samples_in = 0;
59 
60  if (!fh->samplerate) {
61  if (!(fh->samplerate = rate)) {
62  fh->samplerate = 8000;
63  }
64  }
65 
66  if (zstr(file_path)) {
68  return SWITCH_STATUS_FALSE;
69  }
70 
71  fh->flags = flags;
72 
73  if (pool) {
74  fh->memory_pool = pool;
75  } else {
78  return status;
79  }
81  }
82 
84 
85  fh->mm.samplerate = 44100;
86  fh->mm.channels = 1;
87  fh->mm.keyint = 60;
88  fh->mm.ab = 128;
91  fh->mm.try_hardware_encoder = 1;
92 
93  if (*file_path == '{') {
94  char *timeout;
95  char *modname;
96  const char *val;
97  int tmp;
98 
99  fp = switch_core_strdup(fh->memory_pool, file_path);
100 
101  while (*fp == '{') {
102  char *parsed = NULL;
103 
104  if (switch_event_create_brackets(fp, '{', '}', ',', &fh->params, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) {
106  goto fail;
107  }
108 
109  fp = parsed;
110  }
111 
112  file_path = fp;
113 
114  if ((timeout = switch_event_get_header(fh->params, "timeout"))) {
115  if ((to = atoi(timeout)) < 1) {
116  to = 0;
117  }
118  }
119 
120  if ((modname = switch_event_get_header(fh->params, "modname"))) {
121  fh->modname = switch_core_strdup(fh->memory_pool, modname);
122  }
123 
124  if ((val = switch_event_get_header(fh->params, "samplerate"))) {
125  tmp = atoi(val);
126  if (tmp > 8000) {
127  fh->mm.samplerate = tmp;
128  }
129  }
130 
131  if ((val = switch_event_get_header(fh->params, "channels"))) {
132  tmp = atoi(val);
133  if (tmp == 1 || tmp == 2) {
134  fh->mm.channels = tmp;
135  }
136  }
137 
138  if ((val = switch_event_get_header(fh->params, "ab"))) {
139  tmp = atoi(val);
140  if (tmp > 16) {
141  fh->mm.ab = tmp;
142  }
143  }
144 
145 
146  if ((val = switch_event_get_header(fh->params, "vb"))) {
147  tmp = atoi(val);
148 
149  if (strrchr(val, 'k')) {
150  tmp *= 1024;
151  } else if (strrchr(val, 'm')) {
152  tmp *= 1048576;
153  }
154 
155  fh->mm.vb = tmp;
156  }
157 
158  if ((val = switch_event_get_header(fh->params, "vw"))) {
159  tmp = atoi(val);
160  if (tmp > 0) {
161  fh->mm.vw = tmp;
162  }
163  }
164 
165  if ((val = switch_event_get_header(fh->params, "vh"))) {
166  tmp = atoi(val);
167  if (tmp > 0) {
168  fh->mm.vh = tmp;
169  }
170  }
171 
172  if ((val = switch_event_get_header(fh->params, "try_hardware_encoder"))) {
174  }
175 
176  if ((val = switch_event_get_header(fh->params, "fps"))) {
177  float ftmp = atof(val);
178  if (ftmp > 0.0f) {
179  fh->mm.fps = ftmp;
180  }
181  }
182 
183  if ((val = switch_event_get_header(fh->params, "vbuf"))) {
184  tmp = atoi(val);
185 
186  if (strrchr(val, 'k')) {
187  tmp *= 1024;
188  } else if (strrchr(val, 'm')) {
189  tmp *= 1048576;
190  }
191 
192  if (tmp > 0 && tmp < 104857600 /*100mb*/) {
193  fh->mm.vbuf = tmp;
194  } else {
195  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid buffer size: %d\n", tmp);
196  }
197  }
198 
199  if ((val = switch_event_get_header(fh->params, "vencspd"))) {
200  if (!strcasecmp(val, "slow")) {
202  } else if (!strcasecmp(val, "medium")) {
204  } else if (!strcasecmp(val, "fast")) {
206  } else {
207  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid video encode speed: %s\n", val);
208  }
209  }
210 
211  if ((val = switch_event_get_header(fh->params, "vprofile"))) {
212  if (!strcasecmp(val, "baseline")) {
214  } else if (!strcasecmp(val, "main")) {
216  } else if (!strcasecmp(val, "high")) {
218  } else {
219  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid video profile: %s\n", val);
220  }
221  }
222  }
223 
225  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] is a directory not a file.\n", file_path);
226  status = SWITCH_STATUS_GENERR;
227  goto fail;
228  }
229 
230  if ((rhs = strstr(file_path, SWITCH_URL_SEPARATOR))) {
231  switch_copy_string(stream_name, file_path, (rhs + 1) - file_path);
232  ext = stream_name;
233  file_path = rhs + 3;
234  fh->stream_name = switch_core_strdup(fh->memory_pool, stream_name);
235  fh->file_path = switch_core_strdup(fh->memory_pool, file_path);
236  is_stream = 1;
237  } else {
238  if ((flags & SWITCH_FILE_FLAG_WRITE)) {
239 
240  if (fh->params) {
241  spool_path = switch_event_get_header(fh->params, "spool_path");
242  }
243 
244  if (!spool_path) {
246  }
247  }
248 
249  if ((ext = strrchr(file_path, '.')) == 0) {
250  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown file Format [%s]\n", file_path);
252  }
253  ext++;
254  fh->file_path = switch_core_strdup(fh->memory_pool, file_path);
255  }
256 
257 
258 
260  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid file format [%s] for [%s]!\n", ext, file_path);
262  }
263 
264  fh->file = file;
265  fh->func = func;
266  fh->line = line;
267 
270  }
271 
272  if (spool_path) {
273  char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
274  switch_uuid_t uuid;
275  switch_uuid_get(&uuid);
276  switch_uuid_format(uuid_str, &uuid);
277 
278  fh->spool_path = switch_core_sprintf(fh->memory_pool, "%s%s%s.%s", spool_path, SWITCH_PATH_SEPARATOR, uuid_str, ext);
279  } else {
280  fh->spool_path = NULL;
281  }
282 
283  if (rhs) {
284  fh->handler = switch_core_strdup(fh->memory_pool, rhs);
285  } else {
286  fh->handler = NULL;
287  }
288 
289  if (channels) {
290  fh->channels = channels;
291  } else {
292  fh->channels = 1;
293  }
294 
295  file_path = fh->spool_path ? fh->spool_path : fh->file_path;
296 
297  if ((status = fh->file_interface->file_open(fh, file_path)) != SWITCH_STATUS_SUCCESS) {
298  if (fh->spool_path) {
299  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Spool dir is set. Make sure [%s] is also a valid path\n", fh->spool_path);
300  }
302  goto fail;
303  }
304 
305  fh->real_channels = fh->channels;
306 
307  if (channels) {
308  fh->channels = channels;
309  }
310 
311  if ((flags & SWITCH_FILE_FLAG_WRITE) && !is_stream && (status = switch_file_exists(file_path, fh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
312  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] not created!\n", file_path);
313  fh->file_interface->file_close(fh);
315  goto fail;
316  }
317 
318  if (to) {
319  fh->max_samples = (fh->samplerate / 1000) * to;
320  }
321 
322 
323  if ((flags & SWITCH_FILE_FLAG_READ)) {
324  fh->native_rate = fh->samplerate;
325  } else {
326  fh->native_rate = rate;
327  }
328 
329  if (fh->samplerate && rate && fh->samplerate != rate) {
330  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "File %s sample rate %d doesn't match requested rate %d\n", file_path, fh->samplerate, rate);
331  if ((flags & SWITCH_FILE_FLAG_READ)) {
332  fh->samplerate = rate;
333  }
334  }
335 
337  fh->pre_buffer_datalen = 0;
338  }
339 
340  if (fh->pre_buffer_datalen) {
341  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Prebuffering %d bytes\n", (int)fh->pre_buffer_datalen);
344  }
345 
346 
347  if (fh->real_channels != fh->channels && (flags & SWITCH_FILE_FLAG_READ) && !(fh->flags & SWITCH_FILE_NOMUX)) {
348  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File has %d channels, muxing to %d channel%s will occur.\n", fh->real_channels, fh->channels, fh->channels == 1 ? "" : "s");
349  }
350 
352  return status;
353 
354  fail:
355 
357 
358  if (fh->params) {
360  }
361 
362  fh->samples_in = 0;
363  fh->max_samples = 0;
364 
367  }
368 
369  return status;
370 }
#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_directory_exists(const char *dirname, switch_memory_pool_t *pool)
Definition: switch_apr.c:474
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
#define SWITCH_CHANNEL_LOG
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
switch_file_interface_t * file_interface
char * switch_core_get_variable_pdup(_In_z_ const char *varname, switch_memory_pool_t *pool)
switch_status_t switch_event_create_brackets(char *data, char a, char b, char c, switch_event_t **event, char **new_data, switch_bool_t dup)
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
#define SWITCH_URL_SEPARATOR
Definition: switch_types.h:124
#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
#define fail()
Definition: tone2wav.c:70
#define SWITCH_AUDIO_SPOOL_PATH_VARIABLE
Definition: switch_types.h:126
switch_video_profile_t vprofile
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
switch_memory_pool_t * memory_pool
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t(* file_open)(switch_file_handle_t *, const char *file_path)
#define UNPROTECT_INTERFACE(_it)
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
switch_status_t(* file_close)(switch_file_handle_t *)
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_file_interface_t * switch_loadable_module_get_file_interface(const char *name, const char *modname)
Retrieve the file format interface by it's registered name.
switch_buffer_t * pre_buffer
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
#define switch_set_flag_locked(obj, flag)
Set a flag on an arbitrary object while locked.
Definition: switch_utils.h:638
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
switch_video_encode_speed_t vencspd
switch_status_t(* file_read_video)(switch_file_handle_t *, switch_frame_t *frame, switch_video_read_flag_t flags)
switch_status_t switch_file_exists(const char *filename, switch_memory_pool_t *pool)
Definition: switch_apr.c:496
void switch_uuid_format(char *buffer, const switch_uuid_t *uuid)
Definition: switch_apr.c:1055
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:648
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:256
void switch_uuid_get(switch_uuid_t *uuid)
Definition: switch_apr.c:1067
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_event_destroy(switch_event_t **event)
Destroy an event.
char * switch_core_sprintf(_In_ switch_memory_pool_t *pool, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the pool ...
#define SWITCH_UUID_FORMATTED_LENGTH
Definition: switch_apr.h:545