bool SendFile::send() { if (m_stream->isOpen()) { lockMutex(); std::string data; int size = m_parent->getDataToSend(data); if (size != 0) { if (m_file.is_open()) { m_file.write(data.c_str(), size); } } unlockMutex(); m_stream->recv(200); } if (shouldStop() || !m_stream->isOpen()) { m_file.close(); return false; } return true; }
AlgorithmStatus AccumulatorAlgorithm::process() { EXEC_DEBUG("process()"); AlgorithmStatus status = acquireData(); if (status == OK) { consume(); releaseData(); return OK; } // status != SYNC_OK: we couldn't acquire a sufficient number of tokens... // if we're not yet at the end of the stream, just return and wait for more if (!shouldStop()) return status; // most likely NO_INPUT // we are at the end of the stream, we need to work with what's available int available = _inputStream->available(); EXEC_DEBUG("EOS; there are " << available << " available tokens left"); if (available > 0) { _inputStream->setAcquireSize(available); _inputStream->setReleaseSize(available); status = acquireData(); if (status != OK) { throw EssentiaException("Accumulator EOS internal scheduling error..."); } // consume our very last tokens consume(); releaseData(); } // and now the big moment we've been waiting for all the time! All the tokens // from the input stream have been consumed, it is time to output our final result finalProduce(); return FINISHED; // yes we produced something, and we're done! }
AlgorithmStatus AfterMaxToBeforeMaxEnergyRatio::process() { // TODO: can be optimized with a lookup on _pitch.available() (similar to poolstorage & vectorinput) while (_pitch.acquire(1)) { _accu.push_back(_pitch.firstToken()); _pitch.release(1); } if (!shouldStop()) return NO_INPUT; // this should go into the constructor standard::Algorithm* afterMaxToBeforeMaxEnergyRatio = standard::AlgorithmFactory::create("AfterMaxToBeforeMaxEnergyRatio"); Real ratio = 0; afterMaxToBeforeMaxEnergyRatio->input("pitch").set(_accu); afterMaxToBeforeMaxEnergyRatio->output("afterMaxToBeforeMaxEnergyRatio").set(ratio); afterMaxToBeforeMaxEnergyRatio->compute(); delete afterMaxToBeforeMaxEnergyRatio; _afterMaxToBeforeMaxEnergyRatio.push(ratio); return FINISHED; }
void ModelBaker::checkIfTexturesFinished() { // check if we're done everything we need to do for this model // and emit our finished signal if we're done if (_bakingTextures.isEmpty()) { if (shouldStop()) { // if we're checking for completion but we have errors // that means one or more of our texture baking operations failed if (_pendingErrorEmission) { setIsFinished(true); } return; } else { qCDebug(model_baking) << "Finished baking, emitting finished" << _modelURL; setIsFinished(true); } } }
void GVNS::run() { unsigned k; double deltaSatisfaction; start(); do { k = 0; bool printStep = env.setPrintSteps(false); double prevSatisfaction = instance.getTotalSatisfaction(); do { // Shaking: generate x' from N_k(x) Instance shaken = instance; neighborhoods[k]->performStep(shaken, Config::SF_RANDOM, true); // x' = VND(x') vnd.reset(shaken); vnd.run(); // check for improvement, otherwise increase GVNS neighborhood if (vnd.getInstance().getTotalSatisfaction() > instance.getTotalSatisfaction()) { instance = vnd.getInstance(); k = 0; } else { k = k + 1; } } while (k < neighborhoods.size()); deltaSatisfaction = instance.getTotalSatisfaction() - prevSatisfaction; env.setPrintSteps(printStep); env.printStepResult(instance); } while (!shouldStop(deltaSatisfaction)); }
AlgorithmStatus ChordsDescriptors::process() { // this could be implemented as a composite, but it is kept like this for // historical and demonstrations reasons while (_chords.acquire(1)) { _accu.push_back(*(std::string*)_chords.getFirstToken()); _chords.release(1); } if (!shouldStop()) return PASS; // make sure we have one value for key and scale if (!_key.acquire(1) || !_scale.acquire(1)) { return NO_INPUT; } standard::Algorithm* algo = _chordsAlgo; string key = *(string*)_key.getFirstToken(); string scale = *(string*)_scale.getFirstToken(); vector<Real> chordsHist; Real cnr, ccr; string ckey, cscale; algo->input("chords").set(_accu); algo->input("key").set(key); algo->input("scale").set(scale); algo->output("chordsHistogram").set(chordsHist); algo->output("chordsNumberRate").set(cnr); algo->output("chordsChangesRate").set(ccr); algo->output("chordsKey").set(ckey); algo->output("chordsScale").set(cscale); algo->compute(); _chordsHistogram.push(chordsHist); _chordsNumberRate.push(cnr); _chordsChangesRate.push(ccr); _chordsKey.push(ckey); _chordsScale.push(cscale); return FINISHED; }
void SegmentFetcher::afterNackReceivedCb(const Interest& origInterest, const lp::Nack& nack, const weak_ptr<SegmentFetcher>& weakSelf) { if (shouldStop(weakSelf)) return; afterSegmentNacked(); BOOST_ASSERT(m_nSegmentsInFlight > 0); m_nSegmentsInFlight--; switch (nack.getReason()) { case lp::NackReason::DUPLICATE: case lp::NackReason::CONGESTION: afterNackOrTimeout(origInterest); break; default: signalError(NACK_ERROR, "Nack Error"); break; } }
void SegmentFetcher::afterSegmentReceivedCb(const Interest& origInterest, const Data& data, const weak_ptr<SegmentFetcher>& weakSelf) { if (shouldStop(weakSelf)) return; BOOST_ASSERT(m_nSegmentsInFlight > 0); m_nSegmentsInFlight--; name::Component currentSegmentComponent = data.getName().get(-1); if (!currentSegmentComponent.isSegment()) { return signalError(DATA_HAS_NO_SEGMENT, "Data Name has no segment number"); } uint64_t currentSegment = currentSegmentComponent.toSegment(); // The first received Interest could have any segment ID std::map<uint64_t, PendingSegment>::iterator pendingSegmentIt; if (m_receivedSegments.size() > 0) { pendingSegmentIt = m_pendingSegments.find(currentSegment); } else { pendingSegmentIt = m_pendingSegments.begin(); } if (pendingSegmentIt == m_pendingSegments.end()) { return; } pendingSegmentIt->second.timeoutEvent.cancel(); afterSegmentReceived(data); m_validator.validate(data, bind(&SegmentFetcher::afterValidationSuccess, this, _1, origInterest, pendingSegmentIt, weakSelf), bind(&SegmentFetcher::afterValidationFailure, this, _1, _2, weakSelf)); }
AlgorithmStatus AudioLoader::process() { if (!parameter("filename").isConfigured()) { throw EssentiaException("AudioLoader: Trying to call process() on an AudioLoader algo which hasn't been correctly configured."); } // read frames until we get a good one do { int result = av_read_frame(_demuxCtx, &_packet); //E_DEBUG(EAlgorithm, "AudioLoader: called av_read_frame(), got result = " << result); if (result != 0) { shouldStop(true); flushPacket(); closeAudioFile(); return FINISHED; } } while (_packet.stream_index != _streamIdx); decodePacket(); copyFFmpegOutput(); return OK; }
AlgorithmStatus Key::process() { if (!shouldStop()) return PASS; const vector<vector<Real> >& hpcpKey = _pool.value<vector<vector<Real> > >("internal.hpcp"); vector<Real> hpcpAverage = meanFrames(hpcpKey); string key; string scale; Real strength; Real firstToSecondRelativeStrength; _keyAlgo->configure("profileType", "temperley"); _keyAlgo->input("pcp").set(hpcpAverage); _keyAlgo->output("key").set(key); _keyAlgo->output("scale").set(scale); _keyAlgo->output("strength").set(strength); _keyAlgo->output("firstToSecondRelativeStrength").set(firstToSecondRelativeStrength); _keyAlgo->compute(); _key.push(key); _scale.push(scale); _strength.push(strength); return FINISHED; }
void ModelBaker::handleBakedTexture() { TextureBaker* bakedTexture = qobject_cast<TextureBaker*>(sender()); qDebug() << "Handling baked texture" << bakedTexture->getTextureURL(); // make sure we haven't already run into errors, and that this is a valid texture if (bakedTexture) { if (!shouldStop()) { if (!bakedTexture->hasErrors()) { if (!_originalOutputDir.isEmpty()) { // we've been asked to make copies of the originals, so we need to make copies of this if it is a linked texture // use the path to the texture being baked to determine if this was an embedded or a linked texture // it is embeddded if the texure being baked was inside a folder with the name of the model // since that is the fake URL we provide when baking external textures if (!_modelURL.isParentOf(bakedTexture->getTextureURL())) { // for linked textures we want to save a copy of original texture beside the original model qCDebug(model_baking) << "Saving original texture for" << bakedTexture->getTextureURL(); // check if we have a relative path to use for the texture auto relativeTexturePath = texturePathRelativeToModel(_modelURL, bakedTexture->getTextureURL()); QFile originalTextureFile{ _originalOutputDir + "/" + relativeTexturePath + bakedTexture->getTextureURL().fileName() }; if (relativeTexturePath.length() > 0) { // make the folders needed by the relative path } if (originalTextureFile.open(QIODevice::WriteOnly) && originalTextureFile.write(bakedTexture->getOriginalTexture()) != -1) { qCDebug(model_baking) << "Saved original texture file" << originalTextureFile.fileName() << "for" << _modelURL; } else { handleError("Could not save original external texture " + originalTextureFile.fileName() + " for " + _modelURL.toString()); return; } } } // now that this texture has been baked and handled, we can remove that TextureBaker from our hash _bakingTextures.remove(bakedTexture->getTextureURL()); checkIfTexturesFinished(); } else { // there was an error baking this texture - add it to our list of errors _errorList.append(bakedTexture->getErrors()); // we don't emit finished yet so that the other textures can finish baking first _pendingErrorEmission = true; // now that this texture has been baked, even though it failed, we can remove that TextureBaker from our list _bakingTextures.remove(bakedTexture->getTextureURL()); // abort any other ongoing texture bakes since we know we'll end up failing for (auto& bakingTexture : _bakingTextures) { bakingTexture->abort(); } checkIfTexturesFinished(); } } else { // we have errors to attend to, so we don't do extra processing for this texture // but we do need to remove that TextureBaker from our list // and then check if we're done with all textures _bakingTextures.remove(bakedTexture->getTextureURL()); checkIfTexturesFinished(); } } }
//*************************************************************************** void Kwave::FilterPlugin::run(QStringList params) { Kwave::UndoTransactionGuard *undo_guard = 0; m_pause = false; if (!interpreteParameters(params)) m_params = params; sample_index_t first, last; QList<unsigned int> tracks; selection(&tracks, &first, &last, true); // switch to interactive mode in pre-listen mode Kwave::StreamObject::setInteractive(m_listen); // create all objects Kwave::MultiTrackReader source( (m_listen) ? Kwave::FullSnapshot : Kwave::SinglePassForward, signalManager(), tracks, first, last); Kwave::SampleSource *filter = createFilter(tracks.count()); Q_ASSERT(filter); if (m_listen) { // pre-listen mode Q_ASSERT(m_sink); } else { // normal mode, with undo undo_guard = new(std::nothrow) Kwave::UndoTransactionGuard(*this, actionName()); Q_ASSERT(undo_guard); if (!undo_guard) { if (filter) delete filter; Kwave::StreamObject::setInteractive(false); return; } m_sink = new(std::nothrow) MultiTrackWriter(signalManager(), tracks, Kwave::Overwrite, first, last); Q_ASSERT(m_sink); } if (!filter || !m_sink || m_sink->done()) { if (filter) delete filter; if (undo_guard) delete undo_guard; if (m_sink) delete m_sink; m_sink = 0; Kwave::StreamObject::setInteractive(false); return; } // set up the progress dialog when in processing (not pre-listen) mode if (!m_listen) { connect(&source, SIGNAL(progress(qreal)), this, SLOT(updateProgress(qreal)), Qt::BlockingQueuedConnection); } // force initial update of the filter settings updateFilter(filter, true); // connect them Kwave::connect(source, SIGNAL(output(Kwave::SampleArray)), *filter, SLOT(input(Kwave::SampleArray))); Kwave::connect(*filter, SIGNAL(output(Kwave::SampleArray)), *m_sink, SLOT(input(Kwave::SampleArray))); // transport the samples while (!shouldStop() && (!source.done() || m_listen)) { // process one step source.goOn(); filter->goOn(); // watch out for changed parameters when in // pre-listen mode if (m_listen && paramsChanged()) { updateFilter(filter); } if (m_listen && source.done()) { // start the next loop source.reset(); continue; } // this lets the process wait if the user pressed cancel // and the confirm_cancel dialog is active while (m_pause && !shouldStop()) sleep(1); } // cleanup if (filter) delete filter; if (m_sink) delete m_sink; m_sink = 0; if (undo_guard) delete undo_guard; m_pause = false; m_listen = false; Kwave::StreamObject::setInteractive(false); }
void ModelBaker::bakeSourceCopy() { QFile modelFile(_originalOutputModelPath); if (!modelFile.open(QIODevice::ReadOnly)) { handleError("Error opening " + _originalOutputModelPath + " for reading"); return; } hifi::ByteArray modelData = modelFile.readAll(); std::vector<hifi::ByteArray> dracoMeshes; std::vector<std::vector<hifi::ByteArray>> dracoMaterialLists; // Material order for per-mesh material lookup used by dracoMeshes { auto serializer = DependencyManager::get<ModelFormatRegistry>()->getSerializerForMediaType(modelData, _modelURL, ""); if (!serializer) { handleError("Could not recognize file type of model file " + _originalOutputModelPath); return; } hifi::VariantHash serializerMapping = _mapping; serializerMapping["combineParts"] = true; // set true so that OBJSerializer reads material info from material library serializerMapping["deduplicateIndices"] = true; // Draco compression also deduplicates, but we might as well shave it off to save on some earlier processing (currently FBXSerializer only) hfm::Model::Pointer loadedModel = serializer->read(modelData, serializerMapping, _modelURL); // Temporarily support copying the pre-parsed node from FBXSerializer, for better performance in FBXBaker // TODO: Pure HFM baking std::shared_ptr<FBXSerializer> fbxSerializer = std::dynamic_pointer_cast<FBXSerializer>(serializer); if (fbxSerializer) { qCDebug(model_baking) << "Parsing" << _modelURL; _rootNode = fbxSerializer->_rootNode; } baker::Baker baker(loadedModel, serializerMapping, _mappingURL); auto config = baker.getConfiguration(); // Enable compressed draco mesh generation config->getJobConfig("BuildDracoMesh")->setEnabled(true); // Do not permit potentially lossy modification of joint data meant for runtime ((PrepareJointsConfig*)config->getJobConfig("PrepareJoints"))->passthrough = true; // Begin hfm baking baker.run(); _hfmModel = baker.getHFMModel(); _materialMapping = baker.getMaterialMapping(); dracoMeshes = baker.getDracoMeshes(); dracoMaterialLists = baker.getDracoMaterialLists(); } // Do format-specific baking bakeProcessedSource(_hfmModel, dracoMeshes, dracoMaterialLists); if (shouldStop()) { return; } if (!_hfmModel->materials.isEmpty()) { _materialBaker = QSharedPointer<MaterialBaker>( new MaterialBaker(_modelURL.fileName(), true, _bakedOutputDir), &MaterialBaker::deleteLater ); _materialBaker->setMaterials(_hfmModel->materials, _modelURL.toString()); connect(_materialBaker.data(), &MaterialBaker::finished, this, &ModelBaker::handleFinishedMaterialBaker); _materialBaker->bake(); } else { bakeMaterialMap(); } }
void SegmentFetcher::afterValidationSuccess(const Data& data, const Interest& origInterest, std::map<uint64_t, PendingSegment>::iterator pendingSegmentIt, const weak_ptr<SegmentFetcher>& weakSelf) { if (shouldStop(weakSelf)) return; // We update the last receive time here instead of in the segment received callback so that the // transfer will not fail to terminate if we only received invalid Data packets. m_timeLastSegmentReceived = time::steady_clock::now(); m_nReceived++; // It was verified in afterSegmentReceivedCb that the last Data name component is a segment number uint64_t currentSegment = data.getName().get(-1).toSegment(); // Add measurement to RTO estimator (if not retransmission) if (pendingSegmentIt->second.state == SegmentState::FirstInterest) { m_rttEstimator.addMeasurement(m_timeLastSegmentReceived - pendingSegmentIt->second.sendTime, std::max<int64_t>(m_nSegmentsInFlight + 1, 1)); } // Remove from pending segments map m_pendingSegments.erase(pendingSegmentIt); // Copy data in segment to temporary buffer auto receivedSegmentIt = m_receivedSegments.emplace(std::piecewise_construct, std::forward_as_tuple(currentSegment), std::forward_as_tuple(data.getContent().value_size())); std::copy(data.getContent().value_begin(), data.getContent().value_end(), receivedSegmentIt.first->second.begin()); m_nBytesReceived += data.getContent().value_size(); afterSegmentValidated(data); if (data.getFinalBlock()) { if (!data.getFinalBlock()->isSegment()) { return signalError(FINALBLOCKID_NOT_SEGMENT, "Received FinalBlockId did not contain a segment component"); } if (data.getFinalBlock()->toSegment() + 1 != static_cast<uint64_t>(m_nSegments)) { m_nSegments = data.getFinalBlock()->toSegment() + 1; cancelExcessInFlightSegments(); } } if (m_receivedSegments.size() == 1) { m_versionedDataName = data.getName().getPrefix(-1); if (currentSegment == 0) { // We received the first segment in response, so we can increment the next segment number m_nextSegmentNum++; } } if (m_highData < currentSegment) { m_highData = currentSegment; } if (data.getCongestionMark() > 0 && !m_options.ignoreCongMarks) { windowDecrease(); } else { windowIncrease(); } fetchSegmentsInWindow(origInterest); }
AlgorithmStatus Trimmer::process() { EXEC_DEBUG("process()"); if ((_consumed < _startIndex) && (_consumed + _preferredSize > _startIndex)) { _input.setAcquireSize(_startIndex - _consumed); _input.setReleaseSize(_startIndex - _consumed); } if (_consumed == _startIndex) { _input.setAcquireSize(_preferredSize); _input.setReleaseSize(_preferredSize); } AlgorithmStatus status = acquireData(); if (status != OK) { // if status == NO_OUTPUT, we should temporarily stop the framecutter, // return from this function so its dependencies can process the frames, // and reschedule the framecutter to run when all this is done. if (status == NO_OUTPUT) { EXEC_DEBUG("no more output available for trimmer; mark it for rescheduling and return"); //_reschedule = true; return NO_OUTPUT; // if the buffer is full, we need to have produced something! } // if shouldStop is true, that means there is no more audio, so we need // to take what's left to fill in the output buffer if (!shouldStop()) return NO_INPUT; int available = input("signal").available(); EXEC_DEBUG("Frame could not be fully acquired. Next frame will be incomplete"); EXEC_DEBUG("There are " << available << " available tokens"); if (available == 0) { shouldStop(true); return NO_INPUT; } _input.setAcquireSize(available); _input.setReleaseSize(available); _output.setAcquireSize(available); _output.setReleaseSize(available); _preferredSize = available; return process(); } EXEC_DEBUG("data acquired"); // get the audio input and copy it to the output const vector<Real>& input = _input.tokens(); vector<Real>& output = _output.tokens(); if (_consumed >= _startIndex && _consumed < _endIndex) { assert(input.size() == output.size()); int howMany = min((long long)input.size(), _endIndex - _consumed); fastcopy(output.begin(), input.begin(), howMany); _output.setReleaseSize(howMany); } else { _output.setReleaseSize(0); } EXEC_DEBUG("produced frame"); _consumed += _input.releaseSize(); // optimization: we should also tell the parent (most of the time an // audio loader) to also stop, to avoid decoding an entire mp3 when only // 10 seconds are needed if (_consumed >= _endIndex) { // FIXME: does still still work with the new composites? shouldStop(true); const_cast<SourceBase*>(_input.source())->parent()->shouldStop(true); } EXEC_DEBUG("releasing"); releaseData(); EXEC_DEBUG("released"); return OK; }
AlgorithmStatus AudioOnsetsMarker::process() { EXEC_DEBUG("process()"); AlgorithmStatus status = acquireData(); EXEC_DEBUG("data acquired"); if (status != OK) { if (!shouldStop()) return status; int available = input("signal").available(); if (available == 0) return FINISHED; // otherwise, there's still some audio we can gobble up input("signal").setAcquireSize(available); input("signal").setReleaseSize(available); output("signal").setAcquireSize(available); output("signal").setReleaseSize(available); return CONTINUE; } const vector<Real>& input = _input.tokens(); vector<Real>& output = _output.tokens(); assert(output.size() == input.size()); Real out = 0; for (int i=0; i<int(input.size()); i++) { if (_onsetIdx >= (int)_onsets.size()) { out = 0.5*input[i]; } else { if (_processedSamples >= int(_onsets[_onsetIdx]) && _processedSamples <= int(_onsets[_onsetIdx] + _burst.size())) { // check whether next onset is closer than noise.size(): if (_onsetIdx < (int)_onsets.size()-1) { if (_processedSamples == int(_onsets[_onsetIdx+1])) { _burstIdx = 0; //cout << "onsetsmarker processing onset: " << _onsetIdx << "/" << _onsets.size() << " at " << _onsets[_onsetIdx]/_sampleRate << " processedSamples: " << _processedSamples/_sampleRate << endl; _onsetIdx++; while (_onsetIdx < (int)_onsets.size() && _processedSamples > _onsets[_onsetIdx]) { _onsetIdx++; } } } out = 0.5*(input[i]+_burst[_burstIdx++]); if (_burstIdx >= (int)_burst.size()) { _burstIdx = 0; //cout << "onsetsmarker processing onset: " << _onsetIdx << "/" << _onsets.size() << " at " << _onsets[_onsetIdx]/_sampleRate << " processedSamples: " << _processedSamples/_sampleRate << endl; _onsetIdx++; while (_onsetIdx < (int)_onsets.size() && _processedSamples > _onsets[_onsetIdx]) { _onsetIdx++; } } } else { out = 0.5*input[i]; } } output[i] = out; _processedSamples++; //cout << "onsetIdx: " << _onsetIdx << " pos: " << _onsets[_onsetIdx] << "onsetsSize: " << _onsets.size() << " processedSamples: " << _processedSamples << endl; } EXEC_DEBUG("releasing"); releaseData(); EXEC_DEBUG("released"); return OK; }
static void tryStop (char *myhostnm, struct hostLoad *myload) { static char fname[] = "tryStop"; struct jobCard *jobCard, *next; int reasons, subreasons, stopmore = FALSE; static int errCount = 0, lastTryStopTime = 0; if (now - lastTryStopTime < sbdSleepTime) { return; } lastTryStopTime = now; for (jobCard = jobQueHead->forw; jobCard != jobQueHead; jobCard = next) { next = jobCard->forw; if (jobCard->jobSpecs.numToHosts == 1) { if ((jobCard->jobSpecs.jStatus & JOB_STAT_RUN) && (now >= jobCard->jobSpecs.startTime + sbdSleepTime) && shouldStop (myload, jobCard, &reasons, &subreasons, 1, &stopmore)) { jobSuspendAction (jobCard, SIG_SUSP_LOAD, reasons, subreasons); if (stopmore) continue; else return; } } else { struct hostLoad *load; int numh; struct nameList *hostList; numh = jobCard->jobSpecs.numToHosts; hostList = lsb_compressStrList(jobCard->jobSpecs.toHosts, numh); numh = hostList->listSize; if (hostList->listSize == 1) { load = myload; } else { load = ls_loadofhosts ("-", &numh, EFFECTIVE, 0, hostList->names, hostList->listSize); } if (load == NULL) { if (errCount < 3) ls_syslog(LOG_ERR, I18N_JOB_FAIL_S_MM, fname, lsb_jobid2str(jobCard->jobSpecs.jobId), "ls_loadofhosts"); errCount++; if (lserrno == LSE_LIM_BADHOST) relife(); if (lserrno == LSE_BAD_XDR) relife(); if (lserrno == LSE_LIM_DOWN || lserrno == LSE_TIME_OUT) myStatus |= NO_LIM; continue; } else { errCount = 0; myStatus = 0; } if ((jobCard->jobSpecs.jStatus & JOB_STAT_RUN) && now >= jobCard->jobSpecs.startTime + sbdSleepTime) { if (shouldStop (load, jobCard, &reasons, &subreasons, numh, &stopmore)) { jobSuspendAction (jobCard, SIG_SUSP_LOAD, reasons, subreasons); if (stopmore) break; else return; } } } } return; }
AlgorithmStatus MetadataReader::process() { if (_filename == "" || !_newlyConfigured) return PASS; TagLib::FileRef f(_filename.c_str()); //Pool tagPool; if (f.isNull()) { // in case TagLib can't get metadata out of this file, try some basic PCM approach int pcmSampleRate = 0; int pcmChannels = 0; int pcmBitrate = 0; try { pcmMetadata(_filename, pcmSampleRate, pcmChannels, pcmBitrate); } catch (EssentiaException& e) { if (parameter("failOnError").toBool()) throw EssentiaException("MetadataReader: File does not exist or does not seem to be of a supported filetype. ", e.what()); } string ns = ""; _title.push(ns); _artist.push(ns); _album.push(ns); _comment.push(ns); _genre.push(ns); _track.push(ns); _date.push(ns); //_tagPool.push(tagPool); _duration.push(0); _bitrate.push(pcmBitrate); _sampleRate.push(pcmSampleRate); _channels.push(pcmChannels); } else { TagLib::PropertyMap tags = f.file()->properties(); _title.push(formatString(tags["TITLE"])); _artist.push(formatString(tags["ARTIST"])); _album.push(formatString(tags["ALBUM"])); _comment.push(formatString(tags["COMMENT"])); _genre.push(formatString(tags["GENRE"])); _track.push(formatString(tags["TRACKNUMBER"])); _date.push(formatString(tags["DATE"])); /* // populate tag pool for(PropertyMap::Iterator it = tags.begin(); it != tags.end(); ++it) { for(StringList::Iterator str = it->second.begin(); str != it->second.end(); ++str) { tagPool.add(it->first.to8Bit(true), str->to8Bit(true)); } } _tagPool.push(tagPool); */ _duration.push((int)f.audioProperties()->length()); int bitrate = f.audioProperties()->bitrate(); // fix for taglib incorrectly returning the bitrate for wave files string ext = toLower(_filename.substr(_filename.size()-3)); if (ext == "wav") { bitrate = bitrate * 1024 / 1000; } _bitrate.push((int)bitrate); _sampleRate.push((int)f.audioProperties()->sampleRate()); _channels.push((int)f.audioProperties()->channels()); } _newlyConfigured = false; shouldStop(true); return OK; }
void TerminalApiClient::data_tick() { // values in milliseconds const int MIN_WAIT_TIME = 20; // sleep time must be smaller or equal than the smallest period const int IO_POLL_PERIOD = 20; const int API_EVENT_POLL_PERIOD = 1000; int last_io_poll = 0; int last_event_api_poll = 0; int last_char = 0; std::string inbuf; bool enter_was_pressed = false; StateToken runstate_state_token; std::string runstate; std::vector<std::string> accounts; StateToken password_state_token; bool ask_for_password = false; std::string key_name; TerminalInput term; while(!shouldStop()) { // assuming sleep_time >> work_time // so we don't have to check the absolute time, just sleep every cycle usleep(MIN_WAIT_TIME * 1000); last_io_poll += MIN_WAIT_TIME; last_event_api_poll += MIN_WAIT_TIME; if(last_io_poll >= IO_POLL_PERIOD) { last_io_poll = 0; last_char = 0; if(term.kbhit()) { enter_was_pressed = false; last_char = term.getch(); if(last_char > 127) std::cout << "Warning: non ASCII characters probably won't work." << std::endl; if(last_char >= ' ')// space is the first printable ascii character inbuf += (char) last_char; if(last_char == '\r' || last_char == '\n') enter_was_pressed = true; else enter_was_pressed = false; // send echo if(ask_for_password) std::cout << "*"; else std::cout << (char) last_char; //std::cout << "you pressed key " << (char) last_char << " as integer: " << last_char << std::endl; } } if(last_event_api_poll >= API_EVENT_POLL_PERIOD) { last_event_api_poll = 0; if(!runstate_state_token.isNull() && !isTokenValid(runstate_state_token)) runstate_state_token = StateToken(); // must get new state with new token if(!password_state_token.isNull() && !isTokenValid(password_state_token)) password_state_token = StateToken(); } bool edge = false; if(runstate_state_token.isNull()) { edge = true; JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("runstate"); req.mPath.push("control"); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); resps.switchToDeserialisation(); resps << makeKeyValueReference("runstate", runstate); runstate_state_token = resp.mStateToken; } if(password_state_token.isNull()) { edge = true; JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("password"); req.mPath.push("control"); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); resps.switchToDeserialisation(); resps << makeKeyValueReference("want_password", ask_for_password); resps << makeKeyValueReference("key_name", key_name); password_state_token = resp.mStateToken; } if(!ask_for_password && edge && runstate == "waiting_account_select") { JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("locations"); req.mPath.push("control"); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); resps.switchToDeserialisation(); std::cout << "Type a number to select an account" << std::endl; if(!resps.hasMore()) std::cout << "Error: No Accounts. Use the Qt-GUI or the webinterface to create an account." << std::endl; int i = 0; accounts.clear(); while(resps.hasMore()) { std::string id; std::string name; std::string location; resps.getStreamToMember() << makeKeyValueReference("id", id) << makeKeyValueReference("name", name) << makeKeyValueReference("location", location); std::cout << "[" << i << "] " << name << "(" << location << ")" << std::endl; accounts.push_back(id); i++; } } if(!ask_for_password && runstate == "waiting_account_select" && last_char >= '0' && last_char <= '9' && (last_char-'0') < accounts.size()) { std::string acc = accounts[last_char-'0']; JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("login"); req.mPath.push("control"); reqs << makeKeyValueReference("id", acc); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); inbuf.clear(); } if(edge && ask_for_password) { std::cout << "Enter the password for key " << key_name << std::endl; } if(ask_for_password && enter_was_pressed && !inbuf.empty()) { std::cout << "TerminalApiClient: got a password" << std::endl; JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("password"); req.mPath.push("control"); reqs << makeKeyValueReference("password", inbuf); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); inbuf.clear(); } } }
Error FFMpegVideoProvider::Impl::entry() { mState = STATE_CAPTURING; Error rc; AVFormatContext *fmtCtx = NULL; AVCodecContext *decodeCtx = NULL, *encodeCtx = NULL; AVCodec *decoder= NULL, *encoder = NULL; SwsContext *swsCtx; AVFrame *convertedFrame = avcodec_alloc_frame(); AVPacket pkt; VBufferPtr buf; FFMpegCodecInfo encodeInfo = FFMpegInfo::findCodecInfo(mCurrentParam.currentCodec); // Open file { AVInputFormat *inputFmt = av_find_input_format(mCtx.inputFmt); AVFormatParameters ap; ::memset(&ap,0,sizeof(ap)); ap.width = 640; ap.height = 480; ap.time_base = (AVRational) {1,25}; if (av_open_input_file(&fmtCtx,mFileName.c_str(),inputFmt,0,&ap) != 0 || fmtCtx == NULL) { rc.setErrorString("Open input error"); goto open_input_file_failed; } } // Find video track { for (int i=0; i<fmtCtx->nb_streams; i++) { if (fmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { decodeCtx = fmtCtx->streams[i]->codec; break; } } if (decodeCtx == NULL) { rc.setErrorString("No video track found"); goto find_video_track_failed; } } // Find decoder { decoder = avcodec_find_decoder(decodeCtx->codec_id); if (decoder == NULL) { rc.setErrorString("Can't find decoder"); goto find_decoder_failed; } if (decodeCtx->pix_fmt == PIX_FMT_NONE ) { decodeCtx->pix_fmt = PIX_FMT_YUVJ420P; } } // Open decoder { if (avcodec_open(decodeCtx,decoder) != 0) { rc.setErrorString("Can't open decoder"); goto open_decoder_failed; } } // Find encoder { encoder = avcodec_find_encoder(encodeInfo.codecId); if (encoder == NULL) { rc.setErrorString("Can't find encoder"); goto find_encoder_failed; } encodeCtx = avcodec_alloc_context(); encodeCtx->width = mCurrentParam.currentGeometry.width; encodeCtx->height = mCurrentParam.currentGeometry.height; encodeCtx->time_base = (AVRational){mCurrentParam.currentFrameRate.num, mCurrentParam.currentFrameRate.den}; encodeCtx->pix_fmt = encodeInfo.supportedPixelFormat.front(); encodeCtx->bit_rate = 480000; encodeCtx->max_b_frames = 1; } // Open encoder { if (avcodec_open(encodeCtx, encoder) != 0) { rc.setErrorString("Open encoder failed"); goto open_encoder_failed; } } // Init swscale { swsCtx = sws_getCachedContext(NULL, decodeCtx->width, decodeCtx->height,decodeCtx->pix_fmt, encodeCtx->width,encodeCtx->height,encodeCtx->pix_fmt, SWS_FAST_BILINEAR, NULL,NULL,NULL); if (swsCtx == NULL) { rc.setErrorString("Init sws context failed"); goto init_sws_context_failed; } } // Allocate space for sws conversion { if (avpicture_alloc((AVPicture *)convertedFrame,encodeCtx->pix_fmt,encodeCtx->width,encodeCtx->height) != 0) { rc.setErrorString("Allocate space for conversion failed"); goto allocate_space_failed; } } // All init finish successfully. Notify it { mThreadError = rc; mThreadMutex.lock(); mThreadCond.signal(); mThreadMutex.unlock(); } // The mainloop while (!shouldStop()) { int got_frame = 0; AVFrame * decodedFrame = avcodec_alloc_frame(); // Get a frame of decoded picture while (!got_frame && !shouldStop()){ av_init_packet(&pkt); if (av_read_frame(fmtCtx, &pkt) != 0){ rc.setErrorString("Read frame error"); av_free_packet (&pkt); goto read_frame_error; } if ( fmtCtx->streams[pkt.stream_index]->codec != decodeCtx) { av_free_packet(&pkt); continue; } if (avcodec_decode_video2(decodeCtx,decodedFrame,&got_frame,&pkt) < 0){ rc.setErrorString("Decode video frame error"); av_free_packet (&pkt); goto decode_frame_error; } av_free_packet (&pkt); } if (!got_frame) { rc.setErrorString("Decode thread is requested to stop"); goto decode_stop; } // Do sws scale { if (sws_scale(swsCtx,decodedFrame->data,decodedFrame->linesize, 0,decodeCtx->height, convertedFrame->data, convertedFrame->linesize) < 1) { rc.setErrorString("sws scale failed"); goto sws_scale_failed; } } // Wait a buffer to encode to { mBufferMutex.lock(); while (!shouldStop() && (mBuffers.size() < 1)) { rc = mBufferCond.wait(mBufferMutex,500); if (rc.isError()) { if (rc.getErrorType() == Error::ERR_TIMEOUT) continue; else { mBufferMutex.unlock(); goto wait_buffer_error; } }else{ break; } } if (mBuffers.size() < 1) { mBufferMutex.unlock(); goto wait_buffer_error; } buf = mBuffers.front(); mBuffers.pop_front(); mBufferMutex.unlock(); } // Encode the video { int encoded = avcodec_encode_video(encodeCtx, buf->buf.getData(),buf->buf.getSize(),convertedFrame); if (encoded < 0) { rc.setErrorString("Encode video error"); goto encode_video_error; } buf->size = encoded; } encode_video_error: buf->returned = rc; buf->cond.signal(); wait_buffer_error: sws_scale_failed: decode_stop: decode_frame_error: read_frame_error: av_free(decodedFrame); if (rc.isError()) break; } // Notify all waiter(if exists) { mBufferMutex.lock(); for (std::list<VBufferPtr>::const_iterator iter = mBuffers.begin(); iter != mBuffers.end(); ++ iter) { (*iter)->mutex.lock(); (*iter)->returned = rc; (*iter)->cond.signal(); (*iter)->size = 0; (*iter)->mutex.unlock(); } mBuffers.clear(); mBufferMutex.unlock(); } allocate_space_failed: sws_freeContext(swsCtx); init_sws_context_failed: avcodec_close(encodeCtx); open_encoder_failed: av_free(encodeCtx); find_encoder_failed: avcodec_close(decodeCtx); open_decoder_failed: find_decoder_failed: find_video_track_failed: av_close_input_file(fmtCtx); open_input_file_failed: av_free(convertedFrame); mState = STATE_READY; mThreadMutex.lock(); mThreadError = rc; mThreadCond.signal(); mThreadMutex.unlock(); return rc; }
AlgorithmStatus FrameCutter::process() { bool lastFrame = false; EXEC_DEBUG("process()"); // if _streamIndex < _startIndex, we need to advance into the stream until we // arrive at _startIndex if (_streamIndex < _startIndex) { // to make sure we can skip that many, use frameSize (buffer has been resized // to be able to accomodate at least that many sample before starting processing) int skipSize = _frameSize; int howmuch = min(_startIndex - _streamIndex, skipSize); _audio.setAcquireSize(howmuch); _audio.setReleaseSize(howmuch); _frames.setAcquireSize(0); _frames.setReleaseSize(0); if (acquireData() != OK) return NO_INPUT; releaseData(); _streamIndex += howmuch; return OK; } // need to know whether we have to zero-pad on the left: ie, _startIndex < 0 int zeropadSize = 0; int acquireSize = _frameSize; int releaseSize = min(_hopSize, _frameSize); // in case hopsize > framesize int available = _audio.available(); // we need this check anyway because we might be at the very end of the stream and try to acquire 0 // for our last frame, which will unfortunately work, so just get rid of this case right now if (available == 0) return NO_INPUT; if (_startIndex < 0) { // left zero-padding and only acquire as much as _frameSize + startIndex tokens and should release zero acquireSize = _frameSize + _startIndex; releaseSize = 0; zeropadSize = -_startIndex; } // if there are not enough tokens in the stream (howmuch < available): if (acquireSize >= available) { // has to be >= in case the size of the audio fits exactly with frameSize & hopSize if (!shouldStop()) return NO_INPUT; // not end of stream -> return and wait for more data to come acquireSize = available; // need to acquire what's left releaseSize = _startIndex >= 0 ? min(available, _hopSize) : 0; // cannot release more tokens than there are available if (_startFromZero) { if (_lastFrameToEndOfFile) { if (_startIndex >= _streamIndex+available) lastFrame = true; } else lastFrame = true; } else { if (_startIndex + _frameSize/2 >= _streamIndex + available) // center of frame >= end of stream lastFrame = true; } } _frames.setAcquireSize(1); _frames.setReleaseSize(1); _audio.setAcquireSize(acquireSize); _audio.setReleaseSize(releaseSize); /* EXEC_DEBUG("zeropadSize: " << zeropadSize << "\tacquireSize: " << acquireSize << "\treleaseSize: " << releaseSize << "\tavailable: " << available << "\tlast frame: " << lastFrame << "\tstartIndex: " << _startIndex << "\tstreamIndex: " << _streamIndex); */ AlgorithmStatus status = acquireData(); EXEC_DEBUG("data acquired (audio: " << acquireSize << " - frames: 1)"); if (status != OK) { if (status == NO_INPUT) return NO_INPUT; if (status == NO_OUTPUT) return NO_OUTPUT; throw EssentiaException("FrameCutter: something weird happened."); } // some semantic description to not get mixed up between the 2 meanings // of a vector<Real> (which acts both as a stream of Real tokens at the // input and as a single vector<Real> token at the output) typedef vector<AudioSample> Frame; // get the audio input and copy it as a frame to the output const vector<AudioSample>& audio = _audio.tokens(); Frame& frame = _frames.firstToken(); frame.resize(_frameSize); // left zero-padding of the frame int idxInFrame = 0; for (; idxInFrame < zeropadSize; idxInFrame++) { frame[idxInFrame] = (Real)0.0; } fastcopy(frame.begin()+idxInFrame, audio.begin(), acquireSize); idxInFrame += acquireSize; // check if the idxInFrame is below the threshold (this would only happen // for the last frame in the stream) and if so, don't produce data if (idxInFrame < _validFrameThreshold) { E_INFO("FrameCutter: dropping incomplete frame"); // release inputs (advance to next frame), but not the output frame (we didn't produce anything) _audio.release(_audio.releaseSize()); return NO_INPUT; } // right zero-padding on the last frame for (; idxInFrame < _frameSize; idxInFrame++) { frame[idxInFrame] = (Real)0.0; } _startIndex += _hopSize; if (isSilent(frame)) { switch (_silentFrames) { case DROP: E_INFO("FrameCutter: dropping silent frame"); // release inputs (advance to next frame), but not the output frame (we didn't produce anything) _audio.release(_audio.releaseSize()); return OK; case ADD_NOISE: { vector<AudioSample> inputFrame(_frameSize, 0.0); fastcopy(&inputFrame[0]+zeropadSize, &frame[0], acquireSize); _noiseAdder->input("signal").set(inputFrame); _noiseAdder->output("signal").set(frame); _noiseAdder->compute(); break; } // otherwise, don't do nothing... case KEEP: default: ; } } EXEC_DEBUG("produced frame; releasing"); releaseData(); _streamIndex += _audio.releaseSize(); EXEC_DEBUG("released"); if (lastFrame) return PASS; return OK; }
AlgorithmStatus Resample::process() { EXEC_DEBUG("process()"); EXEC_DEBUG("Trying to acquire data"); AlgorithmStatus status = acquireData(); if (status != OK) { // FIXME: are we sure this still works? // if status == NO_OUTPUT, we should temporarily stop the resampler, // return from this function so its dependencies can process the frames, // and reschedule the framecutter to run when all this is done. if (status == NO_OUTPUT) { EXEC_DEBUG("no more output available for resampling; mark it for rescheduling and return"); //_reschedule = true; return NO_OUTPUT; // if the buffer is full, we need to have produced something! } // if shouldStop is true, that means there is no more audio, so we need // to take what's left to fill in the output, instead of waiting for more // data to come in (which would have done by returning from this function) if (!shouldStop()) return NO_INPUT; int available = input("signal").available(); EXEC_DEBUG("There are " << available << " available tokens"); if (available == 0) return NO_INPUT; input("signal").setAcquireSize(available); input("signal").setReleaseSize(available); output("signal").setAcquireSize((int)(_data.src_ratio * available + 100 + (int)_delay)); _data.end_of_input = 1; return process(); } EXEC_DEBUG("data acquired"); const vector<AudioSample>& signal = _signal.tokens(); vector<AudioSample>& resampled = _resampled.tokens(); EXEC_DEBUG("signal size:" << signal.size()); EXEC_DEBUG("resampled size:" << resampled.size()); _data.data_in = const_cast<float*>(&(signal[0])); _data.input_frames = (long)signal.size(); _data.data_out = &(resampled[0]); _data.output_frames = (long)resampled.size(); if (_data.src_ratio == 1.0) { assert(_data.output_frames >= _data.input_frames); fastcopy(_data.data_out, _data.data_in, _data.input_frames); _data.input_frames_used = _data.input_frames; _data.output_frames_gen = _data.input_frames; } else { int error = src_process(_state, &_data); if (error) { throw EssentiaException("Resample: ", src_strerror(error)); } if (_data.input_frames_used == 0) { throw EssentiaException("Resample: Internal consumption problem while resampling"); } } EXEC_DEBUG("input frames:" << _data.input_frames_used); EXEC_DEBUG("produced:" << _data.output_frames_gen); _delay += (Real)_data.input_frames_used*_data.src_ratio - (Real)_data.output_frames_gen; assert((int)resampled.size() >= _data.output_frames_gen); assert((int)signal.size() >= _data.input_frames_used); _signal.setReleaseSize(_data.input_frames_used); _resampled.setReleaseSize(_data.output_frames_gen); releaseData(); EXEC_DEBUG("released"); return OK; }
//*************************************************************************** void Kwave::RecordThread::run() { int result = 0; bool interrupted = false; unsigned int offset = 0; // read data until we receive a close signal while (!shouldStop() && !interrupted) { // dequeue a buffer from the "empty" queue if (m_empty_queue.isEmpty()) { // we had a "buffer overflow" qWarning("RecordThread::run() -> NO EMPTY BUFFER FOUND !!!"); result = -ENOBUFS; break; } QByteArray buffer = m_empty_queue.dequeue(); int len = buffer.size(); Q_ASSERT(buffer.size()); if (!len) { result = -ENOBUFS; break; } // read into the current buffer offset = 0; while (len && !interrupted && !shouldStop()) { // read raw data from the record device result = (m_device) ? m_device->read(buffer, offset) : -EBADF; if ((result < 0) && (result != -EAGAIN)) qWarning("RecordThread: read result = %d (%s)", result, strerror(-result)); if (result == -EAGAIN) { continue; } else if (result == -EBADF) { // file open has failed interrupted = true; break; } else if (result == -EINTR) { // thread was interrupted, received signal? interrupted = true; break; } else if (result < 1) { // something went wrong !? interrupted = true; qWarning("RecordThread::run(): read returned %d", result); break; } else { offset += result; len = buffer.size() - offset; Q_ASSERT(len >= 0); if (len < 0) len = 0; } } // return buffer into the empty queue and abort on errors // do not use it if (interrupted && (result < 0)) { m_empty_queue.enqueue(buffer); break; } // inform the application that there is something to dequeue m_full_queue.enqueue(buffer); emit bufferFull(); } // do not evaluate the result of the last operation if there // was the external request to stop if (shouldStop() || (interrupted && (result > 0))) result = 0; if (result) emit stopped(result); }
AlgorithmStatus Slicer::process() { EXEC_DEBUG("process()"); // 10 first, consume and release tokens until we reach the start of the first slice // 20 produce the first slice, push it, and remove it from the list of slices to be processed // 30 goto 10 // in case we already processed all slices, just gobble up data if (_sliceIdx == int(_slices.size())) { bool ok = _input.acquire(defaultPreferredSize); if (!ok) return NO_INPUT; // TODO: make a special case for end of stream? _input.release(defaultPreferredSize); return OK; } int startIndex = _slices[_sliceIdx].first; int endIndex = _slices[_sliceIdx].second; // arriving there, only consume the tokens left before we reach the beginning of the slice if ((_consumed < startIndex) && (_consumed + _input.acquireSize() > startIndex)) { _input.setAcquireSize(startIndex - _consumed); _input.setReleaseSize(startIndex - _consumed); } // we're at the beginning of a slice, grab it entirely at once if (_consumed == startIndex) { _input.setAcquireSize(endIndex - startIndex); } AlgorithmStatus status = acquireData(); if (status != OK) { // FIXME: what does this return do here, without a comment explaining why we now skip everything after it??? return status; // if shouldStop is true, that means there is no more audio, so we need to stop if (!shouldStop()) return status; EXEC_DEBUG("Slice could not be fully acquired. Creating a partial slice to " "the end of the token stream."); EXEC_DEBUG("There are " << _input.available() << " available tokens left."); // Since there is no more tokens to consume, the last slice will be // partial (not to the end of endIndex) if (_input.available() == 0) return NO_INPUT; _input.setAcquireSize(_input.available()); _input.setReleaseSize(_input.available()); status = acquireData(); // If the last of the tokens could not be acquired, abort if (status != OK) return status; } int acquired = _input.acquireSize(); EXEC_DEBUG("data acquired (in: " << acquired << ")"); // are we dropping the tokens, or are we at the beginning of a slice, in which // case we need to copy it if (_consumed != startIndex) { // we're still dropping tokens to arrive to a slice _input.release(acquired); _consumed += acquired; return OK; } // we are copying a slice, get the audio input and copy it to the output const vector<Real>& input = _input.tokens(); vector<Real>& output = _output.firstToken(); assert((int)input.size() == _input.acquireSize()); output.resize(input.size()); fastcopy(output.begin(), input.begin(), (int)output.size()); EXEC_DEBUG("produced frame"); // set release size in function of next slice to get _sliceIdx++; int toRelease = acquired; // if next slice is very close, be careful not to release too many tokens if (_sliceIdx < (int)_slices.size()) { toRelease = min(toRelease, _slices[_sliceIdx].first - _consumed); } _input.setReleaseSize(toRelease); EXEC_DEBUG("releasing"); releaseData(); _consumed += _input.releaseSize(); EXEC_DEBUG("released"); // reset acquireSize to its default value _input.setAcquireSize(defaultPreferredSize); return OK; }