38 , format_(
Manager::instance().getRingBufferPool().getInternalAudioFormat())
39 , frameSize_(format_.sample_rate *
MS_PER_PACKET.count() / 1000)
44 frameResized(std::move(
f));
47 , loop_([] {
return true; }, [
this] { process(); }, [] {})
49 JAMI_DEBUG(
"Creating audio input with id: {}", id_);
81 decoder_->updateStartTime(
start);
86AudioInput::frameResized(std::shared_ptr<AudioFrame>&&
ptr)
88 std::shared_ptr<AudioFrame>
frame = std::move(
ptr);
89 frame->pointer()->pts = sent_samples;
90 sent_samples +=
frame->pointer()->nb_samples;
92 notify(std::static_pointer_cast<MediaFrame>(
frame));
99 decoder_->setSeekTime(
time);
104AudioInput::readFromDevice()
107 std::lock_guard
lk(resourceMutex_);
109 while (ringBuf_ && ringBuf_->isEmpty())
112 while (ringBuf_ && ringBuf_->getLength(id_) == 0)
122 std::this_thread::sleep_until(wakeUp_);
135 std::lock_guard
lk(fmtMutex_);
136 if (
bufferPool.getInternalAudioFormat() != format_)
140 if (recorderCallback_ && settingMS_.exchange(
false)) {
141 recorderCallback_(MediaStream(
"a:local", format_, sent_samples));
148AudioInput::readFromQueue()
152 if (paused_ || !decoder_->emitFrame(
true)) {
158AudioInput::readFromFile()
162 const auto ret = decoder_->decode();
170 JAMI_ERR() <<
"Failed to decode frame";
173 JAMI_ERR() <<
"Read buffer overflow detected";
182AudioInput::initDevice(
const std::string& device)
185 devOpts_.
input = device;
189 playingDevice_ =
true;
195 std::shared_ptr<MediaDemuxer>&
demuxer,
200 devOpts_.
input = path;
201 devOpts_.
name = path;
203 = std::make_unique<MediaDecoder>(
demuxer, index, [
this](std::shared_ptr<MediaFrame>&&
frame) {
207 ringBuf_->put(std::static_pointer_cast<AudioFrame>(
frame));
232 deviceGuard_.reset();
244 decoder_->flushBuffers();
249AudioInput::initFile(
const std::string& path)
257 devOpts_.
input = path;
258 devOpts_.
name = path;
261 if (!createDecoder()) {
262 JAMI_WARN() <<
"Unable to decode audio from file, switching back to default device";
263 return initDevice(
"");
269 decodingFile_ =
true;
274std::shared_future<DeviceParams>
278 std::unique_lock
lk(resourceMutex_);
282 auto oldGuard = std::move(deviceGuard_);
286 decodingFile_ =
false;
291 playingDevice_ =
false;
293 devOptsFound_ =
false;
295 std::promise<DeviceParams> p;
296 foundDevOpts_.swap(p);
298 if (resource_.empty()) {
300 foundDevOpts(devOpts_);
303 const auto pos = resource_.find(
sep);
304 if (
pos == std::string::npos)
307 const auto prefix = resource_.substr(0,
pos);
308 if ((
pos +
sep.size()) >= resource_.size())
316 ready = initDevice(
suffix);
319 foundDevOpts(devOpts_);
322 futureDevOpts_ = foundDevOpts_.get_future().share();
326 if (onSuccessfulSetup_)
328 return futureDevOpts_;
334 if (!devOptsFound_) {
335 devOptsFound_ =
true;
336 foundDevOpts_.set_value(
params);
345 settingMS_.exchange(
true);
346 recorderCallback_ =
cb;
348 decoder_->setContextCallback([
this]() {
349 if (recorderCallback_)
356AudioInput::createDecoder()
359 if (devOpts_.
input.empty()) {
360 foundDevOpts(devOpts_);
364 auto decoder = std::make_unique<MediaDecoder>([
this](std::shared_ptr<MediaFrame>&&
frame) {
366 ringBuf_->put(std::static_pointer_cast<AudioFrame>(
frame));
374 if (
decoder->openInput(devOpts_) < 0) {
375 JAMI_ERR() <<
"Unable to open input '" << devOpts_.
input <<
"'";
376 foundDevOpts(devOpts_);
380 if (
decoder->setupAudio() < 0) {
381 JAMI_ERR() <<
"Unable to setup decoder for '" << devOpts_.
input <<
"'";
382 foundDevOpts(devOpts_);
387 devOpts_.
channel = ms.nbChannels;
389 JAMI_DBG() <<
"Created audio decoder: " << ms;
392 foundDevOpts(devOpts_);
393 decoder_->setContextCallback([
this]() {
394 if (recorderCallback_)
403 std::lock_guard
lk(fmtMutex_);
411 JAMI_WARN(
"Audio Input muted [%s]", isMuted ?
"YES" :
"NO");
412 muteState_ = isMuted;
418 std::lock_guard
lk(fmtMutex_);
419 return MediaStream(
"a:local", format_, sent_samples);
425 std::lock_guard
lk(fmtMutex_);
426 auto ms =
MediaStream(name, format_, sent_samples);
Manager (controller) of daemon.
static LIBJAMI_TEST_EXPORT Manager & instance()
RingBufferPool & getRingBufferPool()
Return a pointer to the instance of the RingBufferPool.
std::unique_ptr< AudioDeviceGuard > startAudioStream(AudioDeviceType stream)
void notify(std::shared_ptr< MediaFrame > data)
Wrapper class for libswresample.
std::shared_ptr< RingBuffer > createRingBuffer(const std::string &id)
Create a new ringbuffer with a default readoffset.
void bindHalfDuplexOut(const std::string &readerBufferId, const std::string &sourceBufferId)
Attaches a reader the specified source.
std::shared_ptr< AudioFrame > getData(const std::string &ringbufferId)
static const char *const DEFAULT_ID
void flush(const std::string &ringbufferId)
void unBindHalfDuplexOut(const std::string &readerBufferId, const std::string &sourceBufferId)
Detaches a reader from the specified source.
#define JAMI_ERROR(formatstr,...)
#define JAMI_DEBUG(formatstr,...)
void fillWithSilence(AVFrame *frame)
static constexpr auto MS_PER_PACKET
void emitSignal(Args... args)
DeviceParams Parameters used by MediaDecoder and MediaEncoder to open a LibAV device/stream.
rational< double > framerate
#define jami_tracepoint(...)