add mix_num_inputs variable to config file

closes #1581
closes 1557

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

@ -19,6 +19,7 @@
#include "epoll.h"
#include "inotify.h"
#include "metafile.h"
#include "mix.h"
#include "garbage.h"
#include "auxlib.h"
#include "decoder.h"
@ -38,6 +39,7 @@ char *output_dir = NULL;
static char *output_format = NULL;
int output_mixed;
enum mix_method mix_method;
int mix_num_inputs = MIX_MAX_INPUTS;
int output_single;
int output_enabled = 1;
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" },
{ "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-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-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" },
@ -256,6 +259,9 @@ static void options(int *argc, char ***argv) {
else
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))
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 int output_mixed;
extern enum mix_method mix_method;
extern int mix_num_inputs;
extern int output_single;
extern int output_enabled;
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) {
mf->mix_out = output_new(output_dir, mf->parent, "mix", "mix");
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();
db_do_stream(mf, mf->mix_out, "mixed", NULL, 0);
}

@ -22,12 +22,12 @@ struct mix_s {
out_format;
AVFilterGraph *graph;
AVFilterContext *src_ctxs[MIX_NUM_INPUTS];
uint64_t pts_offs[MIX_NUM_INPUTS]; // initialized at first input seen
uint64_t in_pts[MIX_NUM_INPUTS]; // running counter of next expected adjusted pts
struct timeval last_use[MIX_NUM_INPUTS]; // to recycle old mix inputs
void *input_ref[MIX_NUM_INPUTS]; // to avoid collisions in case of idx re-use
CH_LAYOUT_T channel_layout[MIX_NUM_INPUTS];
AVFilterContext *src_ctxs[MIX_MAX_INPUTS];
uint64_t pts_offs[MIX_MAX_INPUTS]; // initialized at first input seen
uint64_t in_pts[MIX_MAX_INPUTS]; // running counter of next expected adjusted pts
struct timeval last_use[MIX_MAX_INPUTS]; // to recycle old mix inputs
void *input_ref[MIX_MAX_INPUTS]; // to avoid collisions in case of idx re-use
CH_LAYOUT_T channel_layout[MIX_MAX_INPUTS];
AVFilterContext *amix_ctx;
AVFilterContext *sink_ctx;
unsigned int next_idx;
@ -50,7 +50,7 @@ static void mix_shutdown(mix_t *mix) {
avfilter_free(mix->sink_ctx);
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])
avfilter_free(mix->src_ctxs[i]);
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 next = mix->next_idx++;
if (next < MIX_NUM_INPUTS) {
if (next < mix_num_inputs) {
// must be unused
mix->input_ref[next] = ptr;
return next;
@ -92,7 +92,7 @@ unsigned int mix_get_index(mix_t *mix, void *ptr) {
// too many inputs - find one to re-use
struct timeval earliest = {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) {
next = i;
earliest = mix->last_use[i];
@ -135,7 +135,7 @@ int mix_config(mix_t *mix, const format_t *format) {
if (!flt)
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";
if (avfilter_graph_create_filter(&mix->amix_ctx, flt, NULL, args, NULL, mix->graph))
goto err;
@ -148,9 +148,9 @@ int mix_config(mix_t *mix, const format_t *format) {
CH_LAYOUT_T channel_layout, ext_layout;
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);
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;
if (mix_method == MM_CHANNELS)
mix->out_format.channels *= MIX_NUM_INPUTS;
mix->out_format.channels *= mix_num_inputs;
return 0;
@ -220,7 +220,7 @@ mix_t *mix_new() {
format_init(&mix->out_format);
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;
return mix;
@ -272,7 +272,7 @@ static void mix_silence_fill(mix_t *mix) {
if (mix->out_pts < mix->in_format.clockrate)
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.
// if they fall behind too much, fill input with silence. otherwise
// 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;
err = "index out of range";
if (idx >= MIX_NUM_INPUTS)
if (idx >= mix_num_inputs)
goto err;
err = "mixer not initialized";

@ -4,13 +4,10 @@
#include "types.h"
#include <libavutil/frame.h>
#define MIX_NUM_INPUTS 4
#define MIX_MAX_INPUTS 4
mix_t *mix_new(void);
void mix_destroy(mix_t *mix);
int mix_config(mix_t *, const format_t *format);
int mix_add(mix_t *mix, AVFrame *frame, unsigned int idx, void *, output_t *output);
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
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>
Change the file permissions of recording files to the given mode. Must be given

Loading…
Cancel
Save