FS-10503: [mod_av] mod_av split audio to two channels #resolve

This commit is contained in:
Anthony Minessale 2017-07-14 18:35:23 -05:00
parent fd3b25d282
commit 4e5219cd27
7 changed files with 513 additions and 617 deletions

View File

@ -378,6 +378,8 @@ struct switch_file_handle {
int64_t duration;
/*! current video position, or current page in pdf */
int64_t vpos;
void *muxbuf;
switch_size_t muxlen;
};
/*! \brief Abstract interface to an asr module */

View File

@ -32,6 +32,7 @@
*/
#include <switch.h>
#include "mod_av.h"
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
@ -1534,18 +1535,9 @@ void show_codecs(switch_stream_handle_t *stream)
av_free(codecs);
}
SWITCH_STANDARD_API(av_codec_api_function)
{
show_codecs(stream);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load)
{
switch_codec_interface_t *codec_interface;
switch_api_interface_t *api_interface;
SWITCH_ADD_CODEC(codec_interface, "H264 Video");
switch_core_codec_add_video_implementation(pool, codec_interface, 99, "H264", NULL,
@ -1559,8 +1551,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load)
switch_core_codec_add_video_implementation(pool, codec_interface, 115, "H263-1998", NULL,
switch_h264_init, switch_h264_encode, switch_h264_decode, switch_h264_control, switch_h264_destroy);
SWITCH_ADD_API(api_interface, "av_codec", "av_codec information", av_codec_api_function, "");
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@
*/
#include <switch.h>
#include "mod_av.h"
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
@ -40,9 +41,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_av_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_av_shutdown);
SWITCH_MODULE_DEFINITION(mod_av, mod_av_load, mod_av_shutdown, NULL);
static struct {
int debug;
} globals;
struct mod_av_globals mod_av_globals;
typedef struct av_mutex_helper_s {
switch_mutex_t *mutex;
@ -99,7 +98,7 @@ static void log_callback(void *ptr, int level, const char *fmt, va_list vl)
switch_log_level_t switch_level = SWITCH_LOG_DEBUG;
/* naggy messages */
if ((level == AV_LOG_DEBUG || level == AV_LOG_WARNING) && !globals.debug) return;
if ((level == AV_LOG_DEBUG || level == AV_LOG_WARNING) && !mod_av_globals.debug) return;
switch(level) {
case AV_LOG_QUIET: switch_level = SWITCH_LOG_CONSOLE; break;
@ -126,6 +125,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_av_shutdown)
return SWITCH_STATUS_SUCCESS;
}
#define AV_USAGE "debug [on|off] | show <formats | codecs>"
SWITCH_STANDARD_API(av_function)
{
char *argv[2] = { 0 };
@ -134,25 +135,43 @@ SWITCH_STANDARD_API(av_function)
int ok = 0;
if (cmd) {
if (!strcmp(cmd, "show formats")) {
show_formats(stream);
ok = 1;
goto end;
} else if (!strcmp(cmd, "show codecs")) {
show_codecs(stream);
ok = 1;
goto end;
}
mycmd = strdup(cmd);
argc = switch_split(mycmd, ' ', argv);
if (argc > 0) {
if (!strcasecmp(argv[0], "debug")) {
if (argc > 1) {
int tmp = atoi(argv[1]);
if (tmp > -1) {
globals.debug = tmp;
if (switch_is_number(argv[1])) {
int tmp = atoi(argv[1]);
if (tmp > -1) {
mod_av_globals.debug = tmp;
}
} else {
mod_av_globals.debug = switch_true(argv[1]);
}
}
stream->write_function(stream, "Debug Level: %d\n", globals.debug);
stream->write_function(stream, "Debug Level: %d\n", mod_av_globals.debug);
ok++;
}
}
}
end:
if (!ok) {
stream->write_function(stream, "No input received\n");
stream->write_function(stream, "Usage %s\n", AV_USAGE);
}
switch_safe_free(mycmd);
@ -175,11 +194,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_av_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(api_interface, "av", "AV general commands", av_function, "debug [on|off]");
SWITCH_ADD_API(api_interface, "av", "AV general commands", av_function, AV_USAGE);
mod_avformat_load(module_interface, pool);
mod_avcodec_load(module_interface, pool);
switch_console_set_complete("add av debug on");
switch_console_set_complete("add av debug off");
switch_console_set_complete("add av debug 0");
switch_console_set_complete("add av debug 1");
switch_console_set_complete("add av debug 2");
switch_console_set_complete("add av show formats");
switch_console_set_complete("add av show codecs");
return SWITCH_STATUS_SUCCESS;
}

View File

@ -0,0 +1,63 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Ken Rice <krice@freeswitch.org>
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
* Raymond Chandler <intralanman@gmail.com>
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
*
*
* mod_av.h -- LibAV mod
*
*/
#ifndef MOD_AV_H
#define MOD_AV_H
struct mod_av_globals {
int debug;
};
extern struct mod_av_globals mod_av_globals;
void show_codecs(switch_stream_handle_t *stream);
void show_formats(switch_stream_handle_t *stream);
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -49,6 +49,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
int is_stream = 0;
char *fp = NULL;
int to = 0;
int force_channels = 0;
if (switch_test_flag(fh, SWITCH_FILE_OPEN)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Handle already open\n");
@ -128,10 +129,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
}
}
if ((val = switch_event_get_header(fh->params, "channels"))) {
if ((val = switch_event_get_header(fh->params, "force_channels"))) {
tmp = atoi(val);
if (tmp == 1 || tmp == 2) {
fh->mm.channels = tmp;
if (tmp >= 0 && tmp < 3) {
force_channels = tmp;
}
}
@ -298,10 +299,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
fh->handler = NULL;
}
if (channels) {
fh->channels = channels;
if (force_channels == channels) {
force_channels = 0;
}
if (force_channels && force_channels > 0 && force_channels < 3) {
fh->real_channels = channels ? channels : fh->channels;
fh->channels = force_channels;
fh->mm.channels = fh->channels;
} else {
fh->channels = 1;
if (channels) {
fh->channels = channels;
} else {
fh->channels = 1;
}
fh->mm.channels = fh->channels;
}
file_path = fh->spool_path ? fh->spool_path : fh->file_path;
@ -314,10 +328,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
goto fail;
}
fh->real_channels = fh->channels;
if (!force_channels && !fh->real_channels) {
fh->real_channels = fh->channels;
if (channels) {
fh->channels = channels;
if (channels) {
fh->channels = channels;
}
}
if ((flags & SWITCH_FILE_FLAG_WRITE) && !is_stream && (status = switch_file_exists(file_path, fh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
@ -537,6 +553,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh,
return SWITCH_STATUS_SUCCESS;
}
if (fh->real_channels != fh->channels && !switch_test_flag(fh, SWITCH_FILE_NOMUX)) {
int need = *len * 2 * fh->real_channels;
if (need > fh->muxlen) {
fh->muxbuf = realloc(fh->muxbuf, need);
switch_assert(fh->muxbuf);
fh->muxlen = need;
memcpy(fh->muxbuf, data, fh->muxlen);
data = fh->muxbuf;
}
switch_mux_channels((int16_t *) data, *len, fh->real_channels, fh->channels);
}
if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
if (!fh->resampler) {
if (switch_resample_create(&fh->resampler,
@ -572,6 +605,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh,
return SWITCH_STATUS_SUCCESS;
}
if (fh->pre_buffer) {
switch_size_t rlen, blen;
switch_status_t status = SWITCH_STATUS_SUCCESS;
@ -847,6 +881,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
fh->memory_pool = NULL;
switch_safe_free(fh->dbuf);
switch_safe_free(fh->muxbuf);
if (fh->spool_path) {
char *command;

View File

@ -2642,6 +2642,19 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t
return SWITCH_STATUS_GENERR;
}
if (fh->params) {
if ((p = switch_event_get_header(fh->params,"record_write_only")) && switch_true(p)) {
flags &= ~SMBF_READ_STREAM;
flags |= SMBF_WRITE_STREAM;
}
if ((p = switch_event_get_header(fh->params, "record_read_only")) && switch_true(p)) {
flags &= ~SMBF_WRITE_STREAM;
flags |= SMBF_READ_STREAM;
}
}
if (switch_core_file_has_video(fh, SWITCH_TRUE)) {
//switch_core_media_set_video_file(session, fh, SWITCH_RW_READ);
//switch_channel_set_flag_recursive(session->channel, CF_VIDEO_DECODED_READ);