add mix_num_inputs variable to config file

closes #1581
closes 1557

Change-Id: Ic8ac6b956e83a4d64695e0ded6e70b8ffe67b36f
pull/1621/head
Denial 3 years ago committed by Richard Fuchs
parent 40a1741fc1
commit 7480ae8198

@ -19,6 +19,7 @@
#include "epoll.h" #include "epoll.h"
#include "inotify.h" #include "inotify.h"
#include "metafile.h" #include "metafile.h"
#include "mix.h"
#include "garbage.h" #include "garbage.h"
#include "auxlib.h" #include "auxlib.h"
#include "decoder.h" #include "decoder.h"
@ -38,6 +39,7 @@ char *output_dir = NULL;
static char *output_format = NULL; static char *output_format = NULL;
int output_mixed; int output_mixed;
enum mix_method mix_method; enum mix_method mix_method;
int mix_num_inputs = MIX_MAX_INPUTS;
int output_single; int output_single;
int output_enabled = 1; int output_enabled = 1;
mode_t output_chmod; mode_t output_chmod;
@ -190,6 +192,7 @@ static void options(int *argc, char ***argv) {
{ "mp3-bitrate", 0, 0, G_OPTION_ARG_INT, &mp3_bitrate, "Bits per second for MP3 encoding", "INT" }, { "mp3-bitrate", 0, 0, G_OPTION_ARG_INT, &mp3_bitrate, "Bits per second for MP3 encoding", "INT" },
{ "output-mixed", 0, 0, G_OPTION_ARG_NONE, &output_mixed, "Mix participating sources into a single output",NULL }, { "output-mixed", 0, 0, G_OPTION_ARG_NONE, &output_mixed, "Mix participating sources into a single output",NULL },
{ "mix-method", 0, 0, G_OPTION_ARG_STRING, &mix_method_str,"How to mix multiple sources", "direct|channels"}, { "mix-method", 0, 0, G_OPTION_ARG_STRING, &mix_method_str,"How to mix multiple sources", "direct|channels"},
{ "mix-num-inputs", 0, 0, G_OPTION_ARG_INT, &mix_num_inputs, "Number of channels for recordings", "INT" },
{ "output-single", 0, 0, G_OPTION_ARG_NONE, &output_single, "Create one output file for each source",NULL }, { "output-single", 0, 0, G_OPTION_ARG_NONE, &output_single, "Create one output file for each source",NULL },
{ "output-chmod", 0, 0, G_OPTION_ARG_STRING, &chmod_mode, "File mode for recordings", "OCTAL" }, { "output-chmod", 0, 0, G_OPTION_ARG_STRING, &chmod_mode, "File mode for recordings", "OCTAL" },
{ "output-chmod-dir", 0, 0, G_OPTION_ARG_STRING, &chmod_dir_mode,"Directory mode for recordings", "OCTAL" }, { "output-chmod-dir", 0, 0, G_OPTION_ARG_STRING, &chmod_dir_mode,"Directory mode for recordings", "OCTAL" },
@ -256,6 +259,9 @@ static void options(int *argc, char ***argv) {
else else
die("Invalid 'mix-method' option"); die("Invalid 'mix-method' option");
if (mix_num_inputs <= 0 && mix_num_inputs > MIX_MAX_INPUTS)
die("Invalid mix_num_inputs value, it must be between 1 and %d", MIX_MAX_INPUTS);
if ((output_storage & OUTPUT_STORAGE_FILE) && !strcmp(output_dir, spool_dir)) if ((output_storage & OUTPUT_STORAGE_FILE) && !strcmp(output_dir, spool_dir))
die("The spool-dir cannot be the same as the output-dir"); die("The spool-dir cannot be the same as the output-dir");

@ -24,6 +24,7 @@ extern char *spool_dir;
extern char *output_dir; extern char *output_dir;
extern int output_mixed; extern int output_mixed;
extern enum mix_method mix_method; extern enum mix_method mix_method;
extern int mix_num_inputs;
extern int output_single; extern int output_single;
extern int output_enabled; extern int output_enabled;
extern mode_t output_chmod; extern mode_t output_chmod;

@ -83,7 +83,7 @@ static void meta_stream_interface(metafile_t *mf, unsigned long snum, char *cont
if (!mf->mix) { if (!mf->mix) {
mf->mix_out = output_new(output_dir, mf->parent, "mix", "mix"); mf->mix_out = output_new(output_dir, mf->parent, "mix", "mix");
if (mix_method == MM_CHANNELS) if (mix_method == MM_CHANNELS)
mf->mix_out->channel_mult = MIX_NUM_INPUTS; mf->mix_out->channel_mult = mix_num_inputs;
mf->mix = mix_new(); mf->mix = mix_new();
db_do_stream(mf, mf->mix_out, "mixed", NULL, 0); db_do_stream(mf, mf->mix_out, "mixed", NULL, 0);
} }

@ -22,12 +22,12 @@ struct mix_s {
out_format; out_format;
AVFilterGraph *graph; AVFilterGraph *graph;
AVFilterContext *src_ctxs[MIX_NUM_INPUTS]; AVFilterContext *src_ctxs[MIX_MAX_INPUTS];
uint64_t pts_offs[MIX_NUM_INPUTS]; // initialized at first input seen uint64_t pts_offs[MIX_MAX_INPUTS]; // initialized at first input seen
uint64_t in_pts[MIX_NUM_INPUTS]; // running counter of next expected adjusted pts uint64_t in_pts[MIX_MAX_INPUTS]; // running counter of next expected adjusted pts
struct timeval last_use[MIX_NUM_INPUTS]; // to recycle old mix inputs struct timeval last_use[MIX_MAX_INPUTS]; // to recycle old mix inputs
void *input_ref[MIX_NUM_INPUTS]; // to avoid collisions in case of idx re-use void *input_ref[MIX_MAX_INPUTS]; // to avoid collisions in case of idx re-use
CH_LAYOUT_T channel_layout[MIX_NUM_INPUTS]; CH_LAYOUT_T channel_layout[MIX_MAX_INPUTS];
AVFilterContext *amix_ctx; AVFilterContext *amix_ctx;
AVFilterContext *sink_ctx; AVFilterContext *sink_ctx;
unsigned int next_idx; unsigned int next_idx;
@ -50,7 +50,7 @@ static void mix_shutdown(mix_t *mix) {
avfilter_free(mix->sink_ctx); avfilter_free(mix->sink_ctx);
mix->sink_ctx = NULL; mix->sink_ctx = NULL;
for (unsigned int i = 0; i < MIX_NUM_INPUTS; i++) { for (unsigned int i = 0; i < mix_num_inputs; i++) {
if (mix->src_ctxs[i]) if (mix->src_ctxs[i])
avfilter_free(mix->src_ctxs[i]); avfilter_free(mix->src_ctxs[i]);
mix->src_ctxs[i] = NULL; mix->src_ctxs[i] = NULL;
@ -83,7 +83,7 @@ static void mix_input_reset(mix_t *mix, unsigned int idx) {
unsigned int mix_get_index(mix_t *mix, void *ptr) { unsigned int mix_get_index(mix_t *mix, void *ptr) {
unsigned int next = mix->next_idx++; unsigned int next = mix->next_idx++;
if (next < MIX_NUM_INPUTS) { if (next < mix_num_inputs) {
// must be unused // must be unused
mix->input_ref[next] = ptr; mix->input_ref[next] = ptr;
return next; return next;
@ -92,7 +92,7 @@ unsigned int mix_get_index(mix_t *mix, void *ptr) {
// too many inputs - find one to re-use // too many inputs - find one to re-use
struct timeval earliest = {0,}; struct timeval earliest = {0,};
next = 0; next = 0;
for (unsigned int i = 0; i < MIX_NUM_INPUTS; i++) { for (unsigned int i = 0; i < mix_num_inputs; i++) {
if (earliest.tv_sec == 0 || timeval_cmp(&earliest, &mix->last_use[i]) > 0) { if (earliest.tv_sec == 0 || timeval_cmp(&earliest, &mix->last_use[i]) > 0) {
next = i; next = i;
earliest = mix->last_use[i]; earliest = mix->last_use[i];
@ -135,7 +135,7 @@ int mix_config(mix_t *mix, const format_t *format) {
if (!flt) if (!flt)
goto err; goto err;
snprintf(args, sizeof(args), "inputs=%lu", (unsigned long) MIX_NUM_INPUTS); snprintf(args, sizeof(args), "inputs=%lu", (unsigned long) mix_num_inputs);
err = "failed to create amix/amerge filter context"; err = "failed to create amix/amerge filter context";
if (avfilter_graph_create_filter(&mix->amix_ctx, flt, NULL, args, NULL, mix->graph)) if (avfilter_graph_create_filter(&mix->amix_ctx, flt, NULL, args, NULL, mix->graph))
goto err; goto err;
@ -148,9 +148,9 @@ int mix_config(mix_t *mix, const format_t *format) {
CH_LAYOUT_T channel_layout, ext_layout; CH_LAYOUT_T channel_layout, ext_layout;
DEF_CH_LAYOUT(&channel_layout, mix->in_format.channels); DEF_CH_LAYOUT(&channel_layout, mix->in_format.channels);
DEF_CH_LAYOUT(&ext_layout, mix->in_format.channels * MIX_NUM_INPUTS); DEF_CH_LAYOUT(&ext_layout, mix->in_format.channels * mix_num_inputs);
for (unsigned int i = 0; i < MIX_NUM_INPUTS; i++) { for (unsigned int i = 0; i < mix_num_inputs; i++) {
dbg("init input ctx %i", i); dbg("init input ctx %i", i);
CH_LAYOUT_T ch_layout = channel_layout; CH_LAYOUT_T ch_layout = channel_layout;
@ -203,7 +203,7 @@ int mix_config(mix_t *mix, const format_t *format) {
mix->out_format = mix->in_format; mix->out_format = mix->in_format;
if (mix_method == MM_CHANNELS) if (mix_method == MM_CHANNELS)
mix->out_format.channels *= MIX_NUM_INPUTS; mix->out_format.channels *= mix_num_inputs;
return 0; return 0;
@ -220,7 +220,7 @@ mix_t *mix_new() {
format_init(&mix->out_format); format_init(&mix->out_format);
mix->sink_frame = av_frame_alloc(); mix->sink_frame = av_frame_alloc();
for (unsigned int i = 0; i < MIX_NUM_INPUTS; i++) for (unsigned int i = 0; i < mix_num_inputs; i++)
mix->pts_offs[i] = (uint64_t) -1LL; mix->pts_offs[i] = (uint64_t) -1LL;
return mix; return mix;
@ -272,7 +272,7 @@ static void mix_silence_fill(mix_t *mix) {
if (mix->out_pts < mix->in_format.clockrate) if (mix->out_pts < mix->in_format.clockrate)
return; return;
for (unsigned int i = 0; i < MIX_NUM_INPUTS; i++) { for (unsigned int i = 0; i < mix_num_inputs; i++) {
// check the pts of each input and give them max 0.5 second of delay. // check the pts of each input and give them max 0.5 second of delay.
// if they fall behind too much, fill input with silence. otherwise // if they fall behind too much, fill input with silence. otherwise
// output stalls and won't produce media // output stalls and won't produce media
@ -285,7 +285,7 @@ int mix_add(mix_t *mix, AVFrame *frame, unsigned int idx, void *ptr, output_t *o
const char *err; const char *err;
err = "index out of range"; err = "index out of range";
if (idx >= MIX_NUM_INPUTS) if (idx >= mix_num_inputs)
goto err; goto err;
err = "mixer not initialized"; err = "mixer not initialized";

@ -4,13 +4,10 @@
#include "types.h" #include "types.h"
#include <libavutil/frame.h> #include <libavutil/frame.h>
#define MIX_MAX_INPUTS 4
#define MIX_NUM_INPUTS 4
mix_t *mix_new(void); mix_t *mix_new(void);
void mix_destroy(mix_t *mix); void mix_destroy(mix_t *mix);
int mix_config(mix_t *, const format_t *format); int mix_config(mix_t *, const format_t *format);
int mix_add(mix_t *mix, AVFrame *frame, unsigned int idx, void *, output_t *output); int mix_add(mix_t *mix, AVFrame *frame, unsigned int idx, void *, output_t *output);
unsigned int mix_get_index(mix_t *, void *); unsigned int mix_get_index(mix_t *, void *);

@ -259,6 +259,10 @@ input is mono audio, then the mixed output file would contain 4 audio channels.
This mixing method requires an output file format which supports these kinds of This mixing method requires an output file format which supports these kinds of
multi-channel audio formats (e.g. B<wav>). multi-channel audio formats (e.g. B<wav>).
=item B<--mix-num-inputs=>I<INT>
Change the number of recording channel in the output file. The value is between 1 to 4 (e.g. B<4>, which is also the default value).
=item B<--output-chmod=>I<INT> =item B<--output-chmod=>I<INT>
Change the file permissions of recording files to the given mode. Must be given Change the file permissions of recording files to the given mode. Must be given

Loading…
Cancel
Save