p26001-store-acs-soc-fw-app/video/core/VideoDecoder.cpp
2026-09-28 21:33:04 +08:00

125 lines
3.8 KiB
C++

/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "VideoDecoder.h"
#include "Logger.h"
#include "Demuxer.h"
namespace Video
{
namespace Core
{
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
VideoDecodeHandler::VideoDecodeHandler(const std::string& name, CodecID codecID, VideoComponent::Ptr pPrevious)
: _name(name), _pPrevious(pPrevious)
{
}
VideoDecodeHandler::~VideoDecodeHandler()
{
}
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
VideoDecoder::VideoDecoder(const std::string& name): VideoComponent(name)
{
}
VideoDecoder::~VideoDecoder()
{
}
void VideoDecoder::start()
{
_task.run(
[this](std::atomic<bool>& isCancelled) -> void
{
VideoDecodeHandler::Ptr pHandler;
while (!isCancelled)
{
try
{
Frame::Ptr pFrame = nullptr;
do
{
if (pHandler.isNull())
{
pFrame = pHandler->read();
if (!pFrame.isNull())
break;
}
Packet::Ptr pPacket = readPacket(1000);
if (serialCodeWatcher().isChanged(pPacket->serialCode(), true))
{
auto pPrevious = previousComponents().first();
auto pDemuxer = pPrevious.cast<Demuxer>();
if (pDemuxer)
{
auto pEncoder = pDemuxer->videoEncoder();
pEncoder->config().copyTo(config());
serialCodeManager().increment();
pHandler = VideoDecodeHandler::create(pEncoder->getCodecID(), pEncoder);
}
else
throw Poco::NotImplementedException(
Poco::format("Unsupported previous component: %s", pPrevious->name()));
}
pHandler->write(pPacket);
pFrame = pHandler->read();
} while (false);
if (!pFrame)
continue;
postToNextComponents(sharedFromThis(), pFrame, MediaType::VIDEO);
}
catch (Poco::Exception& e)
{
logger().error("%s: %s", name(), e.displayText());
Poco::Thread::sleep(1000);
}
catch (std::exception& e)
{
logger().error("%s: %s", name(), std::string(e.what()));
Poco::Thread::sleep(1000);
}
}
});
}
void VideoDecoder::stop()
{
_task.cancel();
}
Packet::Ptr VideoDecoder::readPacket(uint32_t timeout)
{
if (packetQueues().empty())
throw Poco::NotFoundException("Packet queues is empty.");
return packetQueues().first()->dequeue(timeout);
}
void VideoDecoder::onLink(Core::Component::Ptr pPrevious)
{
packetQueues().add(pPrevious, name(), MediaType::VIDEO);
}
void VideoDecoder::onUnlink(Core::Component::Ptr pPrevious)
{
packetQueues().remove(pPrevious);
}
}
}