std::shared_ptr<SipTransport> SipTransportBroker::createUdpTransport(const SipTransportDescr& d) { RETURN_IF_FAIL(d.listenerPort != 0, nullptr, "Could not determine port for this transport"); auto family = pjsip_transport_type_get_af(d.type); IpAddr listeningAddress = (d.interface == ip_utils::DEFAULT_INTERFACE) ? ip_utils::getAnyHostAddr(family) : ip_utils::getInterfaceAddr(d.interface, family); listeningAddress.setPort(d.listenerPort); RETURN_IF_FAIL(listeningAddress, nullptr, "Could not determine IP address for this transport"); pjsip_transport *transport = nullptr; pj_status_t status = listeningAddress.isIpv4() ? pjsip_udp_transport_start (endpt_, &static_cast<const pj_sockaddr_in&>(listeningAddress), nullptr, 1, &transport) : pjsip_udp_transport_start6(endpt_, &static_cast<const pj_sockaddr_in6&>(listeningAddress), nullptr, 1, &transport); if (status != PJ_SUCCESS) { RING_ERR("pjsip_udp_transport_start* failed with error %d: %s", status, sip_utils::sip_strerror(status).c_str()); RING_ERR("UDP IPv%s Transport did not start on %s", listeningAddress.isIpv4() ? "4" : "6", listeningAddress.toString(true).c_str()); return nullptr; } RING_DBG("Created UDP transport on %s : %s", d.interface.c_str(), listeningAddress.toString(true).c_str()); auto ret = std::make_shared<SipTransport>(transport); // dec ref because the refcount starts at 1 and SipTransport increments it ? // pjsip_transport_dec_ref(transport); return ret; }
int exportAccounts(std::vector<std::string> accountIDs, std::string filepath, std::string password) { if (filepath.empty() || !accountIDs.size()) { RING_ERR("Missing arguments"); return EINVAL; } std::size_t found = filepath.find_last_of(DIR_SEPARATOR_STR); auto toDir = filepath.substr(0,found); auto filename = filepath.substr(found+1); if (!fileutils::isDirectory(toDir)) { RING_ERR("%s is not a directory", toDir.c_str()); return ENOTDIR; } // Add Json::Value root; Json::Value array; for (size_t i = 0; i < accountIDs.size(); ++i) { auto detailsMap = Manager::instance().getAccountDetails(accountIDs[i]); if (detailsMap.empty()) { RING_WARN("Can't export account %s", accountIDs[i].c_str()); continue; } auto jsonAccount = accountToJsonValue(detailsMap); array.append(jsonAccount); } root["accounts"] = array; Json::FastWriter fastWriter; std::string output = fastWriter.write(root); // Compress std::vector<uint8_t> compressed; try { compressed = compress(output); } catch (const std::runtime_error& ex) { RING_ERR("Export failed: %s", ex.what()); return 1; } // Encrypt using provided password auto encrypted = dht::crypto::aesEncrypt(compressed, password); // Write try { fileutils::saveFile(toDir + DIR_SEPARATOR_STR + filename, encrypted); } catch (const std::runtime_error& ex) { RING_ERR("Export failed: %s", ex.what()); return EIO; } return 0; }
bool VideoInput::setup() { if (not attach(sink_.get())) { RING_ERR("attach sink failed"); return false; } if (!sink_->start()) RING_ERR("start sink failed"); RING_DBG("VideoInput ready to capture"); return true; }
bool ShmHolder::resizeArea(std::size_t frameSize) noexcept { // aligned on 16-byte boundary frameSize frameSize = (frameSize + 15) & ~15; if (area_ != MAP_FAILED and frameSize == area_->frameSize) return true; // full area size: +15 to take care of maximum padding size const auto areaSize = sizeof(SHMHeader) + 2 * frameSize + 15; RING_DBG("ShmHolder[%s]: new sizes: f=%zu, a=%zu", openedName_.c_str(), frameSize, areaSize); unMapShmArea(); if (::ftruncate(fd_, areaSize) < 0) { RING_ERR("ShmHolder[%s]: ftruncate(%zu) failed with errno %d", openedName_.c_str(), areaSize, errno); return false; } area_ = static_cast<SHMHeader*>(::mmap(nullptr, areaSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0)); if (area_ == MAP_FAILED) { areaSize_ = 0; RING_ERR("ShmHolder[%s]: mmap(%zu) failed with errno %d", openedName_.c_str(), areaSize, errno); return false; } areaSize_ = areaSize; if (frameSize) { SemGuardLock lk {area_->mutex}; area_->frameSize = frameSize; area_->mapSize = areaSize; // Compute aligned IO pointers // Note: we not using std::align as not implemented in 4.9 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57350 auto p = reinterpret_cast<std::uintptr_t>(area_->data); area_->writeOffset = ((p + 15) & ~15) - p; area_->readOffset = area_->writeOffset + frameSize; } return true; }
void AudioRtpSession::start(std::unique_ptr<IceSocket> rtp_sock, std::unique_ptr<IceSocket> rtcp_sock) { std::lock_guard<std::recursive_mutex> lock(mutex_); if (not send_.enabled and not receive_.enabled) { stop(); return; } try { if (rtp_sock and rtcp_sock) socketPair_.reset(new SocketPair(std::move(rtp_sock), std::move(rtcp_sock))); else socketPair_.reset(new SocketPair(getRemoteRtpUri().c_str(), receive_.addr.getPort())); if (send_.crypto and receive_.crypto) { socketPair_->createSRTP(receive_.crypto.getCryptoSuite().c_str(), receive_.crypto.getSrtpKeyInfo().c_str(), send_.crypto.getCryptoSuite().c_str(), send_.crypto.getSrtpKeyInfo().c_str()); } } catch (const std::runtime_error& e) { RING_ERR("Socket creation failed: %s", e.what()); return; } startSender(); startReceiver(); }
void AudioRtpSession::startSender() { if (not send_.enabled or send_.holding) { RING_WARN("Audio sending disabled"); if (sender_) { if (socketPair_) socketPair_->interrupt(); sender_.reset(); } return; } if (sender_) RING_WARN("Restarting audio sender"); // be sure to not send any packets before saving last RTP seq value socketPair_->stopSendOp(); if (sender_) initSeqVal_ = sender_->getLastSeqValue() + 1; try { sender_.reset(); socketPair_->stopSendOp(false); sender_.reset(new AudioSender(callID_, getRemoteRtpUri(), send_, *socketPair_, initSeqVal_, muteState_, mtu_)); } catch (const MediaEncoderException &e) { RING_ERR("%s", e.what()); send_.enabled = false; } }
void SIPCall::sendSIPInfo(const char *const body, const char *const subtype) { if (not inv or not inv->dlg) throw VoipLinkException("Couldn't get invite dialog"); pj_str_t methodName = CONST_PJ_STR("INFO"); pjsip_method method; pjsip_method_init_np(&method, &methodName); /* Create request message. */ pjsip_tx_data *tdata; if (pjsip_dlg_create_request(inv->dlg, &method, -1, &tdata) != PJ_SUCCESS) { RING_ERR("[call:%s] Could not create dialog", getCallId().c_str()); return; } /* Create "application/<subtype>" message body. */ pj_str_t content; pj_cstr(&content, body); const pj_str_t type = CONST_PJ_STR("application"); pj_str_t pj_subtype; pj_cstr(&pj_subtype, subtype); tdata->msg->body = pjsip_msg_body_create(tdata->pool, &type, &pj_subtype, &content); if (tdata->msg->body == NULL) pjsip_tx_data_dec_ref(tdata); else pjsip_dlg_send_request(inv->dlg, tdata, getSIPVoIPLink()->getModId(), NULL); }
bool AudioSender::setup(SocketPair& socketPair) { audioEncoder_.reset(new MediaEncoder); muxContext_.reset(socketPair.createIOContext(mtu_)); try { /* Encoder setup */ RING_DBG("audioEncoder_->openOutput %s", dest_.c_str()); audioEncoder_->setMuted(muteState_); audioEncoder_->openOutput(dest_.c_str(), args_); audioEncoder_->setInitSeqVal(seqVal_); audioEncoder_->setIOContext(muxContext_); audioEncoder_->startIO(); } catch (const MediaEncoderException &e) { RING_ERR("%s", e.what()); return false; } #ifdef DEBUG_SDP audioEncoder_->print_sdp(); #endif return true; }
int tapdisk_xenblkif_disconnect(const domid_t domid, const int devid) { struct td_xenblkif *blkif; blkif = tapdisk_xenblkif_find(domid, devid); if (!blkif) return -ENODEV; if (tapdisk_xenblkif_reqs_pending(blkif)) { RING_DEBUG(blkif, "disconnect from ring with %d pending requests\n", blkif->ring_size - blkif->n_reqs_free); if (td_flag_test(blkif->vbd->state, TD_VBD_PAUSED)) RING_ERR(blkif, "disconnect from ring with %d pending requests " "and the VBD paused\n", blkif->ring_size - blkif->n_reqs_free); list_move(&blkif->entry, &blkif->vbd->dead_rings); blkif->dead = true; if (blkif->ctx && blkif->port >= 0) { xc_evtchn_unbind(blkif->ctx->xce_handle, blkif->port); blkif->port = -1; } /* * FIXME shall we unmap the ring or will that lead to some fatal error * in tapdisk? IIUC if we don't unmap it we'll get errors during grant * copy. */ return 0; } else return tapdisk_xenblkif_destroy(blkif); }
void ShmHolder::renderFrame(VideoFrame& src) noexcept { const auto width = src.width(); const auto height = src.height(); const auto format = VIDEO_PIXFMT_BGRA; const auto frameSize = videoFrameSize(format, width, height); if (!resizeArea(frameSize)) { RING_ERR("ShmHolder[%s]: could not resize area", openedName_.c_str()); return; } { VideoFrame dst; VideoScaler scaler; dst.setFromMemory(area_->data + area_->writeOffset, format, width, height); scaler.scale(src, dst); } { SemGuardLock lk {area_->mutex}; ++area_->frameGen; std::swap(area_->readOffset, area_->writeOffset); ::sem_post(&area_->frameGenMutex); } }
std::shared_ptr<TlsListener> SipTransportBroker::getTlsListener(const SipTransportDescr& d, const pjsip_tls_setting* settings) { RETURN_IF_FAIL(settings, nullptr, "TLS settings not specified"); auto family = pjsip_transport_type_get_af(d.type); IpAddr listeningAddress = (d.interface == ip_utils::DEFAULT_INTERFACE) ? ip_utils::getAnyHostAddr(family) : ip_utils::getInterfaceAddr(d.interface, family); listeningAddress.setPort(d.listenerPort); RETURN_IF_FAIL(listeningAddress, nullptr, "Could not determine IP address for this transport"); RING_DBG("Creating TLS listener %s on %s...", d.toString().c_str(), listeningAddress.toString(true).c_str()); #if 0 RING_DBG(" ca_list_file : %s", settings->ca_list_file.ptr); RING_DBG(" cert_file : %s", settings->cert_file.ptr); RING_DBG(" ciphers_num : %d", settings->ciphers_num); RING_DBG(" verify server %d client %d client_cert %d", settings->verify_server, settings->verify_client, settings->require_client_cert); RING_DBG(" reuse_addr : %d", settings->reuse_addr); #endif pjsip_tpfactory *listener = nullptr; const pj_status_t status = pjsip_tls_transport_start2(endpt_, settings, listeningAddress.pjPtr(), nullptr, 1, &listener); if (status != PJ_SUCCESS) { RING_ERR("TLS listener did not start: %s", sip_utils::sip_strerror(status).c_str()); return nullptr; } return std::make_shared<TlsListener>(listener); }
bool HardwareAccel::extractData(VideoFrame& input) { try { auto inFrame = input.pointer(); if (inFrame->format != format_) { std::stringstream buf; buf << "Frame format mismatch: expected " << av_get_pix_fmt_name(format_); buf << ", got " << av_get_pix_fmt_name((AVPixelFormat)inFrame->format); throw std::runtime_error(buf.str()); } // FFmpeg requires a second frame in which to transfer the data // from the GPU buffer to the main memory auto output = std::unique_ptr<VideoFrame>(new VideoFrame()); auto outFrame = output->pointer(); outFrame->format = AV_PIX_FMT_YUV420P; extractData(input, *output); // move outFrame into inFrame so the caller receives extracted image data // but we have to delete inFrame first av_frame_unref(inFrame); av_frame_move_ref(inFrame, outFrame); } catch (const std::runtime_error& e) { fail(false); RING_ERR("%s", e.what()); return false; } succeed(); return true; }
std::vector<std::string> ip_utils::getAllIpInterfaceByName() { std::vector<std::string> ifaceList; ifaceList.push_back("default"); #ifndef _WIN32 static ifreq ifreqs[20]; ifconf ifconf; ifconf.ifc_buf = (char*) (ifreqs); ifconf.ifc_len = sizeof(ifreqs); int sock = socket(AF_INET6, SOCK_STREAM, 0); if (sock >= 0) { if (ioctl(sock, SIOCGIFCONF, &ifconf) >= 0) for (unsigned i = 0; i < ifconf.ifc_len / sizeof(ifreq); ++i) ifaceList.push_back(std::string(ifreqs[i].ifr_name)); close(sock); } #else RING_ERR("Not implemented yet. (iphlpapi.h problem)"); #endif return ifaceList; }
void AudioStream::stateChanged(pa_stream* s) { UNUSED char str[PA_SAMPLE_SPEC_SNPRINT_MAX]; switch (pa_stream_get_state(s)) { case PA_STREAM_CREATING: RING_DBG("Stream is creating..."); break; case PA_STREAM_TERMINATED: RING_DBG("Stream is terminating..."); break; case PA_STREAM_READY: RING_DBG("Stream successfully created, connected to %s", pa_stream_get_device_name(s)); //RING_DBG("maxlength %u", pa_stream_get_buffer_attr(s)->maxlength); //RING_DBG("tlength %u", pa_stream_get_buffer_attr(s)->tlength); //RING_DBG("prebuf %u", pa_stream_get_buffer_attr(s)->prebuf); //RING_DBG("minreq %u", pa_stream_get_buffer_attr(s)->minreq); //RING_DBG("fragsize %u", pa_stream_get_buffer_attr(s)->fragsize); //RING_DBG("samplespec %s", pa_sample_spec_snprint(str, sizeof(str), pa_stream_get_sample_spec(s))); break; case PA_STREAM_UNCONNECTED: RING_DBG("Stream unconnected"); break; case PA_STREAM_FAILED: default: RING_ERR("Stream failure: %s" , pa_strerror(pa_context_errno(pa_stream_get_context(s)))); break; } }
void VideoInput::createDecoder() { deleteDecoder(); switchPending_ = false; if (decOpts_.input.empty()) { foundDecOpts(decOpts_); return; } auto decoder = std::unique_ptr<MediaDecoder>(new MediaDecoder()); if (emulateRate_) decoder->emulateRate(); decoder->setInterruptCallback( [](void* data) -> int { return not static_cast<VideoInput*>(data)->isCapturing(); }, this); if (decoder->openInput(decOpts_) < 0) { RING_ERR("Could not open input \"%s\"", decOpts_.input.c_str()); foundDecOpts(decOpts_); return; } /* Data available, finish the decoding */ if (decoder->setupFromVideoData() < 0) { RING_ERR("decoder IO startup failed"); foundDecOpts(decOpts_); return; } decOpts_.width = decoder->getWidth(); decOpts_.height = decoder->getHeight(); decOpts_.framerate = decoder->getFps(); RING_DBG("created decoder with video params : size=%dX%d, fps=%lf", decOpts_.width, decOpts_.height, decOpts_.framerate.real()); decoder_ = std::move(decoder); foundDecOpts(decOpts_); /* Signal the client about readable sink */ sink_->setFrameSize(decoder_->getWidth(), decoder_->getHeight()); }
Controller::Controller() { try { upnpContext_ = getUPnPContext(); } catch (std::runtime_error& e) { RING_ERR("UPnP context error: %s", e.what()); } }
int SIPCall::SIPSessionReinvite() { // Do nothing if no invitation processed yet if (not inv or inv->invite_tsx) return PJ_SUCCESS; RING_DBG("[call:%s] Processing reINVITE (state=%s)", getCallId().c_str(), pjsip_inv_state_name(inv->state)); // Generate new ports to receive the new media stream // LibAV doesn't discriminate SSRCs and will be confused about Seq changes on a given port generateMediaPorts(); sdp_->clearIce(); auto& acc = getSIPAccount(); if (not sdp_->createOffer(acc.getActiveAccountCodecInfoList(MEDIA_AUDIO), acc.getActiveAccountCodecInfoList(acc.isVideoEnabled() ? MEDIA_VIDEO : MEDIA_NONE), acc.getSrtpKeyExchange(), getState() == CallState::HOLD)) return !PJ_SUCCESS; if (initIceTransport(true)) setupLocalSDPFromIce(); pjsip_tx_data* tdata; auto local_sdp = sdp_->getLocalSdpSession(); auto result = pjsip_inv_reinvite(inv.get(), nullptr, local_sdp, &tdata); if (result == PJ_SUCCESS) { if (!tdata) return PJ_SUCCESS; result = pjsip_inv_send_msg(inv.get(), tdata); if (result == PJ_SUCCESS) return PJ_SUCCESS; RING_ERR("[call:%s] Failed to send REINVITE msg (pjsip: %s)", getCallId().c_str(), sip_utils::sip_strerror(result).c_str()); // Canceling internals without sending (anyways the send has just failed!) pjsip_inv_cancel_reinvite(inv.get(), &tdata); } else RING_ERR("[call:%s] Failed to create REINVITE msg (pjsip: %s)", getCallId().c_str(), sip_utils::sip_strerror(result).c_str()); return !PJ_SUCCESS; }
JackLayer::~JackLayer() { stopStream(); for (auto p : out_ports_) jack_port_unregister(playbackClient_, p); for (auto p : in_ports_) jack_port_unregister(captureClient_, p); if (jack_client_close(playbackClient_)) RING_ERR("JACK client could not close"); if (jack_client_close(captureClient_)) RING_ERR("JACK client could not close"); for (auto r : out_ringbuffers_) jack_ringbuffer_free(r); for (auto r : in_ringbuffers_) jack_ringbuffer_free(r); }
void RingBuffer::storeReadOffset(size_t offset, const std::string &call_id) { ReadOffset::iterator iter = readoffsets_.find(call_id); if (iter != readoffsets_.end()) iter->second = offset; else RING_ERR("RingBuffer::storeReadOffset() failed: unknown call '%s'", call_id.c_str()); }
void AccountFactory::removeAccount(const std::string& id) { std::lock_guard<std::recursive_mutex> lock(mutex_); if (auto account = getAccount(id)) { removeAccount(*account); } else RING_ERR("No account with ID %s", id.c_str()); }
static void convertFromFloat(std::vector<float> &src, std::vector<AudioSample> &dest) { if (dest.size() != src.size()) { RING_ERR("MISMATCH"); return; } for (size_t i = 0; i < dest.size(); ++i) dest[i] = src[i] * SHRT_MAX; }
void AudioSender::process() { auto& mainBuffer = Manager::instance().getRingBufferPool(); auto mainBuffFormat = mainBuffer.getInternalAudioFormat(); // compute nb of byte to get corresponding to 1 audio frame const std::size_t samplesToGet = std::chrono::duration_cast<std::chrono::seconds>(mainBuffFormat.sample_rate * secondsPerPacket_).count(); if (mainBuffer.availableForGet(id_) < samplesToGet) { const auto wait_time = std::chrono::duration_cast<std::chrono::milliseconds>(secondsPerPacket_); if (not mainBuffer.waitForDataAvailable(id_, samplesToGet, wait_time)) return; } // get data micData_.setFormat(mainBuffFormat); micData_.resize(samplesToGet); const auto samples = mainBuffer.getData(micData_, id_); if (samples != samplesToGet) return; // down/upmix as needed auto accountAudioCodec = std::static_pointer_cast<AccountAudioCodecInfo>(args_.codec); micData_.setChannelNum(accountAudioCodec->audioformat.nb_channels, true); if (mainBuffFormat.sample_rate != accountAudioCodec->audioformat.sample_rate) { if (not resampler_) { RING_DBG("Creating audio resampler"); resampler_.reset(new Resampler(accountAudioCodec->audioformat)); } resampledData_.setFormat(accountAudioCodec->audioformat); resampledData_.resize(samplesToGet); resampler_->resample(micData_, resampledData_); Smartools::getInstance().setLocalAudioCodec(audioEncoder_->getEncoderName()); if (audioEncoder_->encode_audio(resampledData_) < 0) RING_ERR("encoding failed"); } else { if (audioEncoder_->encode_audio(micData_) < 0) RING_ERR("encoding failed"); } }
static void convertToFloat(const std::vector<AudioSample> &src, std::vector<float> &dest) { static const float INV_SHORT_MAX = 1 / (float) SHRT_MAX; if (dest.size() != src.size()) { RING_ERR("MISMATCH"); return; } for (size_t i = 0; i < dest.size(); ++i) dest[i] = src[i] * INV_SHORT_MAX; }
void Conference::add(const std::string &participant_id) { if (participants_.insert(participant_id).second) { #ifdef RING_VIDEO if (auto call = Manager::instance().callFactory.getCall<SIPCall>(participant_id)) call->getVideoRtp().enterConference(this); else RING_ERR("no call associate to participant %s", participant_id.c_str()); #endif // RING_VIDEO } }
void HardwareAccel::fail(bool forceFallback) { ++failCount_; if (failCount_ >= MAX_ACCEL_FAILURES || forceFallback) { RING_ERR("Hardware acceleration failure"); fallback_ = true; failCount_ = 0; codecCtx_->get_format = avcodec_default_get_format; codecCtx_->get_buffer2 = avcodec_default_get_buffer2; } }
JackLayer::JackLayer(const AudioPreference &p) : AudioLayer(p), captureClient_(nullptr), playbackClient_(nullptr), out_ports_(), in_ports_(), out_ringbuffers_(), in_ringbuffers_(), ringbuffer_thread_(), //workerAlive_(false), ringbuffer_thread_mutex_(), data_ready_(), playbackBuffer_(0, audioFormat_), playbackFloatBuffer_(), captureBuffer_(0, audioFormat_), captureFloatBuffer_(), hardwareBufferSize_(0), mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID)) { playbackClient_ = jack_client_open(PACKAGE_NAME, (jack_options_t) (JackNullOption | JackNoStartServer), NULL); if (!playbackClient_) throw std::runtime_error("Could not open JACK client"); captureClient_ = jack_client_open(PACKAGE_NAME, (jack_options_t) (JackNullOption | JackNoStartServer), NULL); if (!captureClient_) throw std::runtime_error("Could not open JACK client"); jack_set_process_callback(captureClient_, process_capture, this); jack_set_process_callback(playbackClient_, process_playback, this); createPorts(playbackClient_, out_ports_, true, out_ringbuffers_); createPorts(captureClient_, in_ports_, false, in_ringbuffers_); const auto playRate = jack_get_sample_rate(playbackClient_); const auto captureRate = jack_get_sample_rate(captureClient_); if (playRate != captureRate) RING_ERR("Mismatch between capture rate %u and playback rate %u", playRate, captureRate); hardwareBufferSize_ = jack_get_buffer_size(playbackClient_); auto update_buffer = [] (AudioBuffer &buf, size_t size, unsigned rate, unsigned nbChannels) { buf.setSampleRate(rate); buf.resize(size); buf.setChannelNum(nbChannels); }; update_buffer(playbackBuffer_, hardwareBufferSize_, playRate, out_ports_.size()); update_buffer(captureBuffer_, hardwareBufferSize_, captureRate, in_ports_.size()); jack_on_shutdown(playbackClient_, onShutdown, this); }
bool SinkClient::start() noexcept { if (not shm_) { try { shm_ = std::make_shared<ShmHolder>(); } catch (const std::runtime_error& e) { RING_ERR("SHMHolder ctor failure: %s", e.what()); } } return static_cast<bool>(shm_); }
void RingBufferPool::unBindCallID(const std::string& call_id1, const std::string& call_id2) { const auto& rb_call1 = getRingBuffer(call_id1); if (not rb_call1) { RING_ERR("No ringbuffer associated to call '%s'", call_id1.c_str()); return; } const auto& rb_call2 = getRingBuffer(call_id2); if (not rb_call2) { RING_ERR("No ringbuffer associated to call '%s'", call_id2.c_str()); return; } std::lock_guard<std::recursive_mutex> lk(stateLock_); removeReaderFromRingBuffer(rb_call1, call_id2); removeReaderFromRingBuffer(rb_call2, call_id1); }
void AudioReceiveThread::process() { AudioFormat mainBuffFormat = Manager::instance().getRingBufferPool().getInternalAudioFormat(); AudioFrame decodedFrame; switch (audioDecoder_->decode(decodedFrame)) { case MediaDecoder::Status::FrameFinished: audioDecoder_->writeToRingBuffer(decodedFrame, *ringbuffer_, mainBuffFormat); // Refresh the remote audio codec in the callback SmartInfo Smartools::getInstance().setRemoteAudioCodec(audioDecoder_->getDecoderName()); return; case MediaDecoder::Status::DecodeError: RING_WARN("decoding failure, trying to reset decoder..."); if (not setup()) { RING_ERR("fatal error, rx thread re-setup failed"); loop_.stop(); break; } if (not audioDecoder_->setupFromAudioData(format_)) { RING_ERR("fatal error, a-decoder setup failed"); loop_.stop(); break; } break; case MediaDecoder::Status::ReadError: RING_ERR("fatal error, read failed"); loop_.stop(); break; case MediaDecoder::Status::Success: case MediaDecoder::Status::EOFError: default: break; } }
void VideoDeviceImpl::setDeviceParams(const DeviceParams& params) { if (params.width and params.height) { auto pmt = capMap_.at(std::make_pair(params.width, params.height)); if (pmt != nullptr) { ((VIDEOINFOHEADER*) pmt->pbFormat)->AvgTimePerFrame = (FrameRate(1e7) / params.framerate).real(); if (FAILED(cInterface->streamConf_->SetFormat(pmt))) { RING_ERR("Could not set settings."); } } } }