整理代码

This commit is contained in:
蒲爽 2026-09-28 21:33:04 +08:00
commit c7b4e178ec
364 changed files with 59691 additions and 0 deletions

239
video/core/AudioDecoder.cpp Normal file
View 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;
}
}
}