整理代码
This commit is contained in:
commit
c7b4e178ec
364 changed files with 59691 additions and 0 deletions
239
video/core/AudioDecoder.cpp
Normal file
239
video/core/AudioDecoder.cpp
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "AudioDecoder.h"
|
||||
#include "Logger.h"
|
||||
#include "Demuxer.h"
|
||||
#include "System.h"
|
||||
#include <Poco/Exception.h>
|
||||
#include <Logger.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace Core
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* 追帧(catch-up)阈值配置
|
||||
* 说明:所有阈值均以"队列中待解码包个数"为单位。
|
||||
* 音频帧典型时长约 20ms(AAC),队列上限 300,约 6s 缓冲。
|
||||
*******************************************************************************
|
||||
*/
|
||||
namespace
|
||||
{
|
||||
constexpr int CATCH_UP_ENTER = 10;
|
||||
constexpr int CATCH_UP_EXIT = 2;
|
||||
|
||||
constexpr int DROP_LEVEL_1 = 6;
|
||||
constexpr int DROP_LEVEL_2 = 15;
|
||||
constexpr int DROP_LEVEL_3 = 30;
|
||||
}
|
||||
/*
|
||||
*******************************************************************************
|
||||
* * CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
AudioDecodeHandler::AudioDecodeHandler(const std::string& name, CodecID codecID, AudioComponent::Ptr pPrevious)
|
||||
: _pPrevious(pPrevious)
|
||||
{
|
||||
}
|
||||
|
||||
AudioDecodeHandler::~AudioDecodeHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioDecodeHandler::conceal(Packet::Ptr pPacket)
|
||||
{
|
||||
(void)pPacket;
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
AudioDecoder::AudioDecoder(const std::string& name)
|
||||
: AbstractAudioInput(name), _synchronizer(name + "/sync"),
|
||||
|
||||
_catchUpEnabled(name.find("NET") != std::string::npos ? true : false), _isCatchingUp(false), _dropPhase(0)
|
||||
{
|
||||
}
|
||||
|
||||
AudioDecoder::~AudioDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioDecoder::start()
|
||||
{
|
||||
run();
|
||||
}
|
||||
|
||||
void AudioDecoder::stop()
|
||||
{
|
||||
cancel();
|
||||
setTimeline(0);
|
||||
|
||||
_isCatchingUp = false;
|
||||
_dropPhase = 0;
|
||||
}
|
||||
|
||||
Frame::Ptr AudioDecoder::readFrame()
|
||||
{
|
||||
if (previousComponents().size() == 0 || packetQueues().empty())
|
||||
throw Poco::NotFoundException("No previous components");
|
||||
|
||||
updateCatchUpState();
|
||||
|
||||
Frame::Ptr pFrame = nullptr;
|
||||
|
||||
if (!_pHandler.isNull())
|
||||
{
|
||||
pFrame = _pHandler->read();
|
||||
if (!pFrame.isNull())
|
||||
{
|
||||
syncFrame(pFrame, _isCatchingUp);
|
||||
return pFrame;
|
||||
}
|
||||
}
|
||||
|
||||
while (pFrame.isNull())
|
||||
{
|
||||
Packet::Ptr pPacket;
|
||||
|
||||
try
|
||||
{
|
||||
long timeOut = _isCatchingUp ? 1 : 1000;
|
||||
pPacket = packetQueues().first()->dequeue(timeOut);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
if (packetQueues().first()->size() == 0)
|
||||
{
|
||||
if (_isCatchingUp)
|
||||
{
|
||||
_isCatchingUp = false;
|
||||
_dropPhase = 0;
|
||||
_synchronizer.reset();
|
||||
logger().information("%s: catch-up exit (queue drained)", name());
|
||||
}
|
||||
}
|
||||
setTimeline(0);
|
||||
throw;
|
||||
}
|
||||
|
||||
if (serialCodeWatcher().isChanged(pPacket->serialCode(), true))
|
||||
{
|
||||
auto pPrevious = previousComponents().first();
|
||||
auto pDemuxer = pPrevious.cast<Demuxer>();
|
||||
if (pDemuxer)
|
||||
{
|
||||
auto pEncoder = pDemuxer->audioEncoder();
|
||||
pEncoder->config().copyTo(config());
|
||||
serialCodeManager().increment();
|
||||
|
||||
_pHandler = AudioDecodeHandler::create(pEncoder->getCodecID(), pEncoder);
|
||||
|
||||
if (_catchUpEnabled)
|
||||
{
|
||||
while (packetQueues().first()->size() > 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
packetQueues().first()->dequeue(0);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
throw Poco::NotImplementedException(
|
||||
Poco::format("Unsupported previous component: %s", pPrevious->name()));
|
||||
}
|
||||
|
||||
if (_isCatchingUp && shouldDropPacket())
|
||||
{
|
||||
_pHandler->conceal(pPacket);
|
||||
continue;
|
||||
}
|
||||
|
||||
_pHandler->write(pPacket);
|
||||
pFrame = _pHandler->read();
|
||||
}
|
||||
|
||||
syncFrame(pFrame, _isCatchingUp);
|
||||
return pFrame;
|
||||
}
|
||||
|
||||
void AudioDecoder::onLink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
if (!packetQueues().empty() && packetQueues().firstComponent() != pPrevious)
|
||||
throw Poco::LogicException(name() + ": Support only one previous component, conflict with: " +
|
||||
pPrevious->name() + ", Current: " + packetQueues().firstComponent()->name());
|
||||
|
||||
packetQueues().add(pPrevious, name(), MediaType::AUDIO);
|
||||
}
|
||||
|
||||
void AudioDecoder::onUnlink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
packetQueues().remove(pPrevious);
|
||||
}
|
||||
|
||||
void AudioDecoder::syncFrame(Frame::Ptr pFrame, bool isCatchingUp)
|
||||
{
|
||||
if (!isCatchingUp)
|
||||
_synchronizer.syncFrame(pFrame->timestamp);
|
||||
setTimeline(pFrame->timestamp);
|
||||
pFrame->timestamp = System::timestamp();
|
||||
}
|
||||
|
||||
void AudioDecoder::updateCatchUpState()
|
||||
{
|
||||
if (!_catchUpEnabled)
|
||||
return;
|
||||
|
||||
const int queueSize = packetQueues().first()->size();
|
||||
|
||||
if (!_isCatchingUp && queueSize > CATCH_UP_ENTER)
|
||||
{
|
||||
_isCatchingUp = true;
|
||||
_dropPhase = 0;
|
||||
logger().information("%s: catch-up enter (queue=%d)", name(), queueSize);
|
||||
}
|
||||
else if (_isCatchingUp && queueSize <= CATCH_UP_EXIT)
|
||||
{
|
||||
_isCatchingUp = false;
|
||||
_dropPhase = 0;
|
||||
|
||||
_synchronizer.reset();
|
||||
logger().information("%s: catch-up exit (queue=%d)", name(), queueSize);
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioDecoder::shouldDropPacket()
|
||||
{
|
||||
const int queueSize = packetQueues().first()->size();
|
||||
bool drop = false;
|
||||
|
||||
if (queueSize >= DROP_LEVEL_3)
|
||||
{
|
||||
drop = (_dropPhase % 3) != 2;
|
||||
}
|
||||
else if (queueSize >= DROP_LEVEL_2)
|
||||
{
|
||||
drop = (_dropPhase % 2) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
drop = (_dropPhase % 3) == 0;
|
||||
}
|
||||
|
||||
_dropPhase++;
|
||||
return drop;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue