示例#1
0
AudioSamples AudioDecoderContext::decode(const Packet &inPacket, size_t offset, OptionalErrorCode ec)
{
    clear_if(ec);

    AudioSamples outSamples;

    int gotFrame = 0;
    auto st = decodeCommon(outSamples, inPacket, offset, gotFrame, avcodec_decode_audio_legacy);
    if (get<1>(st))
    {
        throws_if(ec, get<0>(st), *get<1>(st));
        return AudioSamples();
    }

    if (!gotFrame)
    {
        outSamples.setComplete(false);
    }

    // Fix channels layout
    if (outSamples.channelsCount() && !outSamples.channelsLayout())
        av_frame_set_channel_layout(outSamples.raw(), av_get_default_channel_layout(outSamples.channelsCount()));

    return outSamples;
}
示例#2
0
bool AudioResampler::pop(AudioSamples &dst, bool getall, error_code &ec)
{
    clear_if(ec);

    if (!m_raw) {
        fflog(AV_LOG_ERROR, "SwrContext does not inited\n");
        throws_if(ec, Errors::ResamplerNotInited);
        return false;
    }

    if (dst.sampleRate() != dstSampleRate() ||
        dst.sampleFormat() != dstSampleFormat() ||
        dst.channelsCount() != dstChannels() ||
        dst.channelsLayout() != dstChannelLayout())
    {
        throws_if(ec, Errors::ResamplerOutputChanges);
        return false;
    }

    auto result = swr_get_delay(m_raw, m_dstRate);
    //clog << "  delay [pop]: " << result << endl;

    // Need more data
    if (result < dst.samplesCount() && getall == false)
    {
        return false;
    }

    auto sts = swr_convert_frame(m_raw, dst.raw(), nullptr);
    if (sts < 0)
    {
        throws_if(ec, sts, ffmpeg_category());
        return false;
    }

    dst.setTimeBase(Rational(1, m_dstRate));
    dst.setStreamIndex(m_streamIndex);
    dst.setComplete(true);

    // Ugly PTS handling. More clean one can be done by user code
    if (!m_nextPts.isValid()) {
        m_nextPts = Timestamp(0, dst.timeBase());
    }
    dst.setPts(m_nextPts);
    m_nextPts = dst.pts() + Timestamp{dst.samplesCount(), dst.timeBase()};

    //result = swr_get_delay(m_raw, m_dstRate);
    //clog << "  delay [pop]: " << result << endl;

    // When no data, samples count sets to zero
    return dst.samplesCount() ? true : false;
}
示例#3
0
void AudioResampler::push(const AudioSamples &src, error_code &ec)
{
    if (!m_raw)
    {
        fflog(AV_LOG_ERROR, "SwrContext does not inited\n");
        throws_if(ec, Errors::ResamplerNotInited);
        return;
    }

    // Null samples is allowed
    if (src)
    {
        if (src.sampleRate() != srcSampleRate() ||
            src.sampleFormat() != srcSampleFormat() ||
            src.channelsCount() != srcChannels() ||
            src.channelsLayout() != srcChannelLayout())
        {
            throws_if(ec, Errors::ResamplerInputChanges);
            return;
        }
    }

    auto sts = swr_convert_frame(m_raw, nullptr, src.raw());
    if (sts < 0)
    {
        fflog(AV_LOG_DEBUG, "Src is null: %d, payload: %p\n", src.isNull(), src.data());
        throws_if(ec, sts, ffmpeg_category());
        return;
    }

    // TODO: need protection if we still work in scheme: One Resampler Per Channel
    m_streamIndex = src.streamIndex();

    // Need to restore PTS in output frames
    if (m_prevPts > src.pts()) // Reset case
        m_nextPts = Timestamp();
    m_prevPts     = src.pts();

    //auto result = swr_get_delay(m_raw, m_dstRate);
    //clog << "  delay [push]: " << result << endl;
}