Skip to content
Snippets Groups Projects
Select Git revision
  • fca619f7165a20ada6b372b1aca7eebd5bf67512
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • release/201811
  • release/201808
  • wip/patches_poly_2017/cedryk_doucet/abderahmane_bouziane
  • releases/beta1
  • android/release_461
  • android/release_460
  • android/release_459
  • android/release_458
  • android/release_457
  • android/release_456
  • android/release_455
  • android/release_454
  • android/release_453
  • android/release_452
  • android/release_451
  • android/release_450
  • android/release_449
  • android/release_448
  • android/release_447
  • android/release_446
  • android/release_445
  • android/release_444
  • android/release_443
  • android/release_442
38 results

BackHandlerInterface.java

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    audio_frame_resizer.cpp 3.84 KiB
    /*
     *  Copyright (C) 2018-2019 Savoir-faire Linux Inc.
     *
     *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 3 of the License, or
     *  (at your option) any later version.
     *
     *  This program is distributed in the hope that it will be useful,
     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *  GNU General Public License for more details.
     *
     *  You should have received a copy of the GNU General Public License
     *  along with this program; if not, write to the Free Software
     *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
     */
    
    #include "audio_frame_resizer.h"
    #include "libav_deps.h"
    #include "logger.h"
    
    extern "C" {
    #include <libavutil/audio_fifo.h>
    }
    
    #include <stdexcept>
    
    namespace jami {
    
    AudioFrameResizer::AudioFrameResizer(const AudioFormat& format, int size, std::function<void(std::shared_ptr<AudioFrame>&&)> cb)
        : format_(format)
        , frameSize_(size)
        , cb_(cb)
        , queue_(av_audio_fifo_alloc(format.sampleFormat, format.nb_channels, frameSize_))
    {}
    
    AudioFrameResizer::~AudioFrameResizer()
    {
        av_audio_fifo_free(queue_);
    }
    
    int
    AudioFrameResizer::samples() const
    {
        return av_audio_fifo_size(queue_);
    }
    
    int
    AudioFrameResizer::frameSize() const
    {
        return frameSize_;
    }
    
    AudioFormat
    AudioFrameResizer::format() const
    {
        return format_;
    }
    
    void
    AudioFrameResizer::setFormat(const AudioFormat& format, int size)
    {
        if (size)
            setFrameSize(size);
        if (format != format_) {
            if (auto discarded = samples())
                JAMI_WARN("Discarding %d samples", discarded);
            av_audio_fifo_free(queue_);
            format_ = format;
            queue_ = av_audio_fifo_alloc(format.sampleFormat, format.nb_channels, frameSize_);
        }
    }
    
    void
    AudioFrameResizer::setFrameSize(int frameSize)
    {
        if (frameSize_ != frameSize) {
            frameSize_ = frameSize;
            if (cb_)
                while (auto frame = dequeue())
                    cb_(std::move(frame));
        }
    }
    
    void
    AudioFrameResizer::enqueue(std::shared_ptr<AudioFrame>&& frame)
    {
        int ret = 0;
        auto f = frame->pointer();
        AudioFormat format(f->sample_rate, f->channels, (AVSampleFormat)f->format);
        if (format != format_) {
            JAMI_ERR() << "Expected " << format_ << ", but got " << AudioFormat(f->sample_rate, f->channels, (AVSampleFormat)f->format);
            setFormat(format, frameSize_);
        }
    
        auto nb_samples = samples();
        if (cb_ && nb_samples == 0 && f->nb_samples == frameSize_) {
            nextOutputPts_ = frame->pointer()->pts + frameSize_;
            cb_(std::move(frame));
            return; // return if frame was just passed through
        }
    
        // queue reallocates itself if need be
        if ((ret = av_audio_fifo_write(queue_, reinterpret_cast<void**>(f->data), f->nb_samples)) < 0) {
            JAMI_ERR() << "Audio resizer error: " << libav_utils::getError(ret);
            throw std::runtime_error("Failed to add audio to frame resizer");
        }
    
        if (nextOutputPts_ == 0)
            nextOutputPts_ = frame->pointer()->pts - nb_samples;
    
        if (cb_)
            while (auto frame = dequeue())
                cb_(std::move(frame));
    }
    
    std::shared_ptr<AudioFrame>
    AudioFrameResizer::dequeue()
    {
        if (samples() < frameSize_)
            return {};
    
        auto frame = std::make_unique<AudioFrame>(format_, frameSize_);
        int ret;
        if ((ret = av_audio_fifo_read(queue_, reinterpret_cast<void**>(frame->pointer()->data), frameSize_)) < 0) {
            JAMI_ERR() << "Could not read samples from queue: " << libav_utils::getError(ret);
            return {};
        }
        frame->pointer()->pts = nextOutputPts_;
        nextOutputPts_ += frameSize_;
        return frame;
    }
    
    } // namespace jami