整理代码
This commit is contained in:
commit
c7b4e178ec
364 changed files with 59691 additions and 0 deletions
181
video/ffmpeg/AudioResample.cpp
Normal file
181
video/ffmpeg/AudioResample.cpp
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "AudioResample.h"
|
||||
#include "Util.h"
|
||||
#include <Poco/Format.h>
|
||||
#include <vector>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace FFmpeg
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
AudioResample::AudioResample(Core::ChannelLayout ilayout, Core::SampleFormat iformat, int irate,
|
||||
Core::ChannelLayout olayout, Core::SampleFormat oformat, int orate)
|
||||
: Core::AudioResample(Poco::format("FFmpeg::AudioResample(%s:%s:%d->%s:%s:%d)",
|
||||
Core::channelLayoutToString(ilayout), Core::sampleFormatName(iformat), irate,
|
||||
Core::channelLayoutToString(olayout), Core::sampleFormatName(oformat), orate),
|
||||
ilayout, iformat, irate, olayout, oformat, orate),
|
||||
_pSwrCtx(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
AudioResample::~AudioResample()
|
||||
{
|
||||
if (_pSwrCtx)
|
||||
{
|
||||
swr_close(_pSwrCtx);
|
||||
swr_free(&_pSwrCtx);
|
||||
}
|
||||
}
|
||||
|
||||
Core::Frame::Ptr AudioResample::process(Core::Frame::Ptr in)
|
||||
{
|
||||
if (!_pSwrCtx)
|
||||
{
|
||||
auto iAVLayout = Util::getChannelLayout(inLayout());
|
||||
auto oAVLayout = Util::getChannelLayout(outLayout());
|
||||
|
||||
auto iAVFormat = Util::getSampleFormat(inFormat());
|
||||
auto oAVFormat = Util::getSampleFormat(outFormat());
|
||||
|
||||
int rc = swr_alloc_set_opts2(&_pSwrCtx, &oAVLayout, oAVFormat, outRate(), &iAVLayout, iAVFormat, inRate(), 0,
|
||||
nullptr);
|
||||
if (rc < 0)
|
||||
throw Poco::InvalidArgumentException(
|
||||
Poco::format("%s: Could not allocate SwrContext: %d(%s)", name(), rc, Util::getErrorString(rc)), rc);
|
||||
|
||||
if (outLayout() == Core::ChannelLayout::L || outLayout() == Core::ChannelLayout::R)
|
||||
{
|
||||
const int inCh = iAVLayout.nb_channels;
|
||||
const int outCh = (int)oAVLayout.nb_channels;
|
||||
const int srcCh = (outLayout() == Core::ChannelLayout::L) ? 0 : inCh - 1;
|
||||
|
||||
std::vector<double> matrix(inCh * outCh, 0.0);
|
||||
matrix[srcCh] = 1.0;
|
||||
|
||||
rc = swr_set_matrix(_pSwrCtx, matrix.data(), inCh);
|
||||
if (rc < 0)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Could not set SwrContext matrix: %d(%s)", name(), rc, Util::getErrorString(rc)),
|
||||
rc);
|
||||
}
|
||||
|
||||
rc = swr_init(_pSwrCtx);
|
||||
if (rc < 0)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Could not init SwrContext: %d(%s)", name(), rc, Util::getErrorString(rc)), rc);
|
||||
|
||||
setAssignPointersMethod(_assignInPointers, inFormat(), inLayout());
|
||||
setAssignPointersMethod(_assignOutPointers, outFormat(), outLayout());
|
||||
|
||||
if (av_sample_fmt_is_planar(iAVFormat))
|
||||
_iFrameSize = in->length / av_get_bytes_per_sample(iAVFormat);
|
||||
else
|
||||
_iFrameSize = in->length / (av_get_bytes_per_sample(iAVFormat) * iAVLayout.nb_channels);
|
||||
|
||||
_oSampleSize = av_get_bytes_per_sample(oAVFormat);
|
||||
if (!av_sample_fmt_is_planar(oAVFormat))
|
||||
_oSampleSize *= oAVLayout.nb_channels;
|
||||
|
||||
_oFrameSize = av_rescale_rnd(swr_get_delay(_pSwrCtx, inRate()) + _iFrameSize, outRate(), inRate(), AV_ROUND_UP);
|
||||
const int c = Core::channelLayoutChannels(outLayout());
|
||||
if (Core::sampleFormatIsPlanar(outFormat()))
|
||||
{
|
||||
_oBytesPerChannel = av_samples_get_buffer_size(NULL, 1, _oFrameSize, oAVFormat, 1);
|
||||
switch (c)
|
||||
{
|
||||
case 1:
|
||||
_frameCreator = [this]() -> Core::Frame::Ptr
|
||||
{
|
||||
Core::Frame::Ptr pFrame = new Core::Frame;
|
||||
pFrame->length = _oBytesPerChannel;
|
||||
pFrame->data[0] = new uint8_t[_oBytesPerChannel << 1];
|
||||
return pFrame;
|
||||
};
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_frameCreator = [this]() -> Core::Frame::Ptr
|
||||
{
|
||||
Core::Frame::Ptr pFrame = new Core::Frame;
|
||||
pFrame->length = _oBytesPerChannel;
|
||||
pFrame->data[0] = new uint8_t[_oBytesPerChannel << 1];
|
||||
pFrame->data[1] = new uint8_t[_oBytesPerChannel << 1];
|
||||
return pFrame;
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::BugcheckException(Poco::format("%s: Unsupported channle-count: %d", name(), c), -EINVAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_oBytesPerChannel = av_samples_get_buffer_size(NULL, c, _oFrameSize, oAVFormat, 1);
|
||||
_frameCreator = [this]() -> Core::Frame::Ptr
|
||||
{
|
||||
Core::Frame::Ptr pFrame = new Core::Frame;
|
||||
pFrame->length = _oBytesPerChannel;
|
||||
pFrame->data[0] = new uint8_t[_oBytesPerChannel << 1];
|
||||
return pFrame;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Core::Frame::Ptr out = _frameCreator();
|
||||
out->timestamp = in->timestamp;
|
||||
|
||||
uint8_t* iptrs[Core::Frame::DATA_LINES] = {nullptr};
|
||||
uint8_t* optrs[Core::Frame::DATA_LINES] = {nullptr};
|
||||
|
||||
_assignInPointers(iptrs, in);
|
||||
_assignOutPointers(optrs, out);
|
||||
|
||||
int rc = swr_convert(_pSwrCtx, optrs, _oFrameSize, (const uint8_t**)iptrs, _iFrameSize);
|
||||
if (rc < 0)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Convert FAIL: %d(%s)", name(), rc, Util::getErrorString(rc)), rc);
|
||||
|
||||
out->length = rc * _oSampleSize;
|
||||
return out;
|
||||
}
|
||||
|
||||
void AudioResample::setAssignPointersMethod(AssignPointersMethod& method, Video::Core::SampleFormat iformat,
|
||||
Video::Core::ChannelLayout ilayout)
|
||||
{
|
||||
if (Core::sampleFormatIsPlanar(iformat))
|
||||
{
|
||||
const int c = Core::channelLayoutChannels(ilayout);
|
||||
switch (c)
|
||||
{
|
||||
case 1:
|
||||
method = [](uint8_t* ptrs[], Core::Frame::Ptr pFrame) -> void { ptrs[0] = pFrame->data[0].get(); };
|
||||
break;
|
||||
|
||||
case 2:
|
||||
method = [](uint8_t* ptrs[], Core::Frame::Ptr pFrame) -> void
|
||||
{
|
||||
ptrs[0] = pFrame->data[0].get();
|
||||
ptrs[1] = pFrame->data[1].get();
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::BugcheckException(Poco::format("%s: Unsupported channle-count: %d", name(), c), -EINVAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
method = [](uint8_t* ptrs[], Core::Frame::Ptr pFrame) -> void { ptrs[0] = pFrame->data[0].get(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue