Skip to content

Commit

Permalink
add setting for default audio backend and improve selection logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ammen99 committed Jun 29, 2024
1 parent e08cede commit 19211c4
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 20 deletions.
1 change: 1 addition & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#define DEFAULT_CODEC "@default_codec@"
#define DEFAULT_PIX_FMT "@default_pix_fmt@"
#define DEFAULT_AUDIO_BACKEND "@default_audio_backend@"
#define DEFAULT_AUDIO_CODEC "@default_audio_codec@"
#define DEFAULT_AUDIO_SAMPLE_RATE @default_audio_sample_rate@
#define DEFAULT_CONTAINER_FORMAT "@default_container_format@"
Expand Down
4 changes: 4 additions & 0 deletions manpage/wf-recorder.1
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
.Op Fl p, -codec-param Op Ar option_param=option_value
.Op Fl v, -version
.Op Fl x, -pixel-format
.Op Fl -audio-backend Ar audio_backend
.Op Fl C, -audio-codec Ar output_audio_codec
.Op Fl P, -audio-codec-param Op Ar option_param=option_value
.Op Fl R, -sample-rate Ar sample_rate
Expand Down Expand Up @@ -147,6 +148,9 @@ Set the output pixel format.
List available formats using
.Dl $ ffmpeg -pix_fmts
.Pp
.It Fl -audio-backend Ar audio_backend
Specifies the audio backend to be used when -a is set.
.Pp
.It Fl C , -audio-codec Ar output_audio_codec
Specifies the codec of the audio.
.Pp
Expand Down
86 changes: 72 additions & 14 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,67 @@ project_sources = ['src/frame-writer.cpp', 'src/main.cpp', 'src/averr.c']
wayland_client = dependency('wayland-client', version: '>=1.20')
wayland_protos = dependency('wayland-protocols', version: '>=1.14')

pulse = dependency('libpulse-simple', required : get_option('pulse'))
pipewire = dependency('libpipewire-0.3', required : get_option('pipewire'))

if pipewire.found()
conf_data.set('HAVE_PIPEWIRE', true)
project_sources += 'src/pipewire.cpp'
endif
if pulse.found()
conf_data.set('HAVE_PULSE', true)
project_sources += 'src/pulse.cpp'
endif
if pipewire.found() or pulse.found()
audio_backends = {
'pulse': {
'dependency': dependency('libpulse-simple', required: false),
'sources': ['src/pulse.cpp'],
'define': 'HAVE_PULSE'
},
'pipewire': {
'dependency': dependency('libpipewire-0.3', required: false),
'sources': ['src/pipewire.cpp'],
'define': 'HAVE_PIPEWIRE'
}
}

default_audio_backend = get_option('default_audio_backend')
message('Using default audio backend: @0@'.format(default_audio_backend))
have_audio = false
audio_deps = []

foreach backend_name, backend_data : audio_backends
if default_audio_backend == backend_name and not backend_data['dependency'].found()
error('Default audio backend set to @0@, but @1@ dependency was not found!'.format(backend_name, backend_data['dependency'].name()))
endif

if default_audio_backend == backend_name and get_option(backend_name).disabled()
error('Default audio backend set to @0@, but @1@ support is disabled!'.format(backend_name, backend_name))
endif

if get_option(backend_name).enabled() and not backend_data['dependency'].found()
error('@0@ support is enabled, but @1@ dependency was not found!'.format(backend_name, backend_data['dependency'].name()))
endif

if backend_data['dependency'].found() and not get_option(backend_name).disabled()
conf_data.set(backend_data['define'], true)
project_sources += backend_data['sources']
audio_deps += backend_data['dependency']
have_audio = true
else
conf_data.set(backend_data['define'], false)
endif
endforeach

if have_audio
conf_data.set('HAVE_AUDIO', true)
project_sources += 'src/audio.cpp'

if default_audio_backend == 'auto'
if conf_data.get('HAVE_PULSE')
default_audio_backend = 'pulse'
else
foreach backend_name, backend_data : audio_backends
if conf_data.get(backend_data['define'])
default_audio_backend = backend_name
break
endif
endforeach
endif
endif
endif

conf_data.set('default_audio_backend', default_audio_backend)

libavutil = dependency('libavutil')
libavcodec = dependency('libavcodec')
libavformat = dependency('libavformat')
Expand All @@ -87,9 +132,22 @@ subdir('proto')
dependencies = [
wayland_client, wayland_protos,
libavutil, libavcodec, libavformat, libavdevice, libavfilter,
wf_protos, threads, pipewire, pulse, swr, gbm, drm
]
wf_protos, threads, swr, gbm, drm
] + audio_deps

executable('wf-recorder', project_sources,
dependencies: dependencies,
install: true)

summary = [
'',
'----------------',
'wf-recorder @0@'.format(meson.project_version()),
'----------------',
'Default audio backend: @0@'.format(default_audio_backend),
]

foreach backend_name, backend_data : audio_backends
summary += [' - @0@: @1@'.format(backend_name, conf_data.get(backend_data['define']))]
endforeach
message('\n'.join(summary))
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ option('default_container_format', type: 'string', value: 'mkv', description: 'C
option('fallback_audio_sample_fmt', type: 'string', value: 's16', description: 'Fallback audio sample format that will be used if wf-recorder cannot determine the sample formats supported by a codec')
option('pulse', type: 'feature', value: 'auto', description: 'Enable Pulseaudio')
option('pipewire', type: 'feature', value: 'auto', description: 'Enable PipeWire')
option('default_audio_backend', type: 'combo', choices: ['auto', 'pulse', 'pipewire'], value: 'auto', description: 'Default audio backend')
14 changes: 8 additions & 6 deletions src/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
AudioReader *AudioReader::create(AudioReaderParams params)
{
#ifdef HAVE_PIPEWIRE
if (getenv("WF_RECORDER_PIPEWIRE")) {
if (params.audio_backend == "pipewire") {
AudioReader *pw = new PipeWireReader;
pw->params = params;
if (pw->init())
Expand All @@ -21,11 +21,13 @@ AudioReader *AudioReader::create(AudioReaderParams params)
}
#endif
#ifdef HAVE_PULSE
AudioReader *pa = new PulseReader;
pa->params = params;
if (pa->init())
return pa;
delete pa;
if (params.audio_backend == "pulse") {
AudioReader *pa = new PulseReader;
pa->params = params;
if (pa->init())
return pa;
delete pa;
}
#endif
return nullptr;
}
4 changes: 4 additions & 0 deletions src/audio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@

#include <stdlib.h>
#include <stdint.h>
#include "config.h"
#include <string>

struct AudioReaderParams
{
size_t audio_frame_size;
uint32_t sample_rate;
/* Can be NULL */
char *audio_source;

std::string audio_backend = DEFAULT_AUDIO_BACKEND;
};

class AudioReader
Expand Down
8 changes: 8 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,9 @@ Use Ctrl+C to stop.)");
-B. --buffrate This option is used to specify the buffers expected framerate. this
may help when encoders are expecting specific or limited framerate.
--audio-backend Specifies the audio backend among the available backends, for ex.
--audio-backend=pipewire
-C, --audio-codec Specifies the codec of the audio. These can be found by running:
ffmpeg -encoders
Expand Down Expand Up @@ -1010,6 +1013,7 @@ int main(int argc, char *argv[])
{ "codec-param", required_argument, NULL, 'p' },
{ "framerate", required_argument, NULL, 'r' },
{ "pixel-format", required_argument, NULL, 'x' },
{ "audio-backend", required_argument, NULL, '*' },
{ "audio-codec", required_argument, NULL, 'C' },
{ "audio-codec-param", required_argument, NULL, 'P' },
{ "sample-rate", required_argument, NULL, 'R' },
Expand Down Expand Up @@ -1131,6 +1135,10 @@ int main(int argc, char *argv[])
force_overwrite = true;
break;

case '*':
audioParams.audio_backend = optarg;
break;

default:
printf("Unsupported command line argument %s\n", optarg);
}
Expand Down

0 comments on commit 19211c4

Please sign in to comment.