整理代码
This commit is contained in:
commit
c7b4e178ec
364 changed files with 59691 additions and 0 deletions
136
video/hisi/mpp5/AudioEncoder.cpp
Normal file
136
video/hisi/mpp5/AudioEncoder.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "AudioEncoder.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "Util.h"
|
||||
#include "util/Math.h"
|
||||
#include <hi_mpi_audio.h>
|
||||
extern "C"
|
||||
{
|
||||
#include "audio-adp/audio_aac_adp.h"
|
||||
}
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
AudioEncoder::AudioEncoder(Core::CodecID codecID)
|
||||
: MPPChannel((uint32_t)HI_ID_AENC, 0, ResourceManager::allocAENCChannelID()),
|
||||
Core::AudioEncoder(Poco::format("MPP5::AENC#%u(%s)", channelID(), Core::codecIDToString(codecID)), codecID)
|
||||
{
|
||||
}
|
||||
|
||||
AudioEncoder::~AudioEncoder()
|
||||
{
|
||||
ResourceManager::freeAENCChannelID(channelID());
|
||||
}
|
||||
|
||||
void AudioEncoder::initialize()
|
||||
{
|
||||
hi_aenc_chn_attr attr;
|
||||
hi_aenc_attr_aac aac;
|
||||
switch (getCodecID())
|
||||
{
|
||||
case Core::CodecID::AAC:
|
||||
setFrameSize(1024);
|
||||
setSampleFormat(Core::SampleFormat::S16P);
|
||||
|
||||
attr.value = &aac;
|
||||
attr.type = HI_PT_AAC;
|
||||
|
||||
aac.aac_type = HI_AAC_TYPE_AACLC;
|
||||
aac.band_width = 0;
|
||||
aac.transport_type = HI_AAC_TRANSPORT_TYPE_ADTS;
|
||||
aac.sample_rate = (hi_audio_sample_rate)getSampleRate();
|
||||
aac.bit_rate = (hi_aac_bps)getBitrate();
|
||||
aac.bit_width = Util::getBitWidth(getSampleFormat());
|
||||
aac.snd_mode = Util::getSndMode(getChannelLayout());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::BugcheckException(
|
||||
Poco::format("%s: Not implemented codec-id: %s", name(), Core::codecIDToString(getCodecID())), -EINVAL);
|
||||
}
|
||||
|
||||
attr.buf_size = 30;
|
||||
attr.point_num_per_frame = getFrameSize();
|
||||
auto rc = hi_mpi_aenc_create_chn(channelID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Create channel FAIL: %#x", name(), (uint32_t)rc), rc);
|
||||
|
||||
_fd = hi_mpi_aenc_get_fd(channelID());
|
||||
|
||||
_frame.bit_width = Util::getBitWidth(getSampleFormat());
|
||||
_frame.snd_mode = Util::getSndMode(getChannelLayout());
|
||||
}
|
||||
|
||||
void AudioEncoder::deinitialize()
|
||||
{
|
||||
hi_mpi_aenc_destroy_chn(channelID());
|
||||
}
|
||||
|
||||
Core::Packet::Ptr AudioEncoder::encode()
|
||||
{
|
||||
auto pIn = readFrame();
|
||||
_frame.virt_addr[0] = pIn->data[0].get();
|
||||
_frame.virt_addr[1] = pIn->data[1].get();
|
||||
_frame.time_stamp = pIn->timestamp;
|
||||
_frame.len = pIn->length;
|
||||
auto rc = hi_mpi_aenc_send_frame(channelID(), &_frame, nullptr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Write frame FAIL: %#x!", name(), (uint32_t)rc), rc);
|
||||
|
||||
struct timeval tm = {
|
||||
.tv_sec = 1,
|
||||
.tv_usec = 0,
|
||||
};
|
||||
|
||||
fd_set read_fds;
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(_fd, &read_fds);
|
||||
|
||||
rc = select(_fd + 1, &read_fds, NULL, NULL, &tm);
|
||||
if (rc < 0)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Read stream FAIL: %s", name(), std::string(strerror(rc))),
|
||||
rc);
|
||||
else if (0 == rc)
|
||||
throw Poco::TimeoutException(Poco::format("%s: Read encoder stream timeout!", name()), rc);
|
||||
|
||||
hi_audio_stream stream;
|
||||
rc = hi_mpi_aenc_get_stream(channelID(), &stream, 1000);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Get encoder stream FAIL: %#x", name(), (uint32_t)rc), rc);
|
||||
|
||||
uint8_t* pData = new uint8_t[stream.len];
|
||||
memcpy(pData, stream.stream, stream.len);
|
||||
Core::Packet::Ptr pPacket =
|
||||
new Core::Packet(serialCodeManager().code(), 0, pData, stream.len, stream.time_stamp, stream.time_stamp);
|
||||
hi_mpi_aenc_release_stream(channelID(), &stream);
|
||||
|
||||
return pPacket;
|
||||
}
|
||||
|
||||
void AudioEncoder::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
Core::AudioEncoder::onConfigChanged(names);
|
||||
}
|
||||
|
||||
void AudioEncoder::initModule()
|
||||
{
|
||||
hi_mpi_aenc_aac_init();
|
||||
}
|
||||
|
||||
void AudioEncoder::deinitModule()
|
||||
{
|
||||
hi_mpi_aenc_aac_deinit();
|
||||
}
|
||||
}
|
||||
}
|
||||
43
video/hisi/mpp5/AudioEncoder.h
Normal file
43
video/hisi/mpp5/AudioEncoder.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef D8737294_8E5E_4514_9AD1_CFD956F0E262
|
||||
#define D8737294_8E5E_4514_9AD1_CFD956F0E262
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "MPPChannel.h"
|
||||
#include "../core/AudioEncoder.h"
|
||||
#include <hi_common_aio.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class AudioEncoder: public MPPChannel, public Core::AudioEncoder
|
||||
{
|
||||
public:
|
||||
AudioEncoder(Core::CodecID codecID);
|
||||
~AudioEncoder();
|
||||
|
||||
protected:
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
Core::Packet::Ptr encode() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
|
||||
private:
|
||||
int _fd;
|
||||
hi_audio_frame _frame;
|
||||
|
||||
public:
|
||||
static void initModule();
|
||||
static void deinitModule();
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
125
video/hisi/mpp5/AudioInput.cpp
Normal file
125
video/hisi/mpp5/AudioInput.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "AudioInput.h"
|
||||
#include "Util.h"
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
AudioInput::AudioInput(uint32_t deviceID)
|
||||
: Core::AbstractAudioInput(Poco::format("MPP5::AI#%u", deviceID)), MPPChannel((uint32_t)HI_ID_AI, deviceID, 0)
|
||||
{
|
||||
setSampleRate(48000);
|
||||
setFrameSize(1024);
|
||||
setSampleFormat(Core::SampleFormat::S16P);
|
||||
}
|
||||
|
||||
AudioInput::~AudioInput()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioInput::start()
|
||||
{
|
||||
hi_aio_attr attr;
|
||||
attr.sample_rate = (hi_audio_sample_rate)getSampleRate();
|
||||
attr.bit_width = Util::getBitWidth(getSampleFormat());
|
||||
attr.work_mode = HI_AIO_MODE_I2S_SLAVE;
|
||||
attr.i2s_type = HI_AIO_I2STYPE_EXTERN;
|
||||
attr.snd_mode = HI_AUDIO_SOUND_MODE_STEREO;
|
||||
attr.expand_flag = 0;
|
||||
attr.frame_num = 8;
|
||||
attr.point_num_per_frame = getFrameSize();
|
||||
attr.chn_cnt = 2;
|
||||
|
||||
attr.clk_share = 0;
|
||||
int32_t rc = hi_mpi_ai_set_pub_attr(deviceID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: set PUB-ATTR FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
rc = hi_mpi_ai_enable(deviceID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: enable FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_ai_enable_chn(deviceID(), channelID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: enable channel FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
hi_ai_chn_param param;
|
||||
param.usr_frame_depth = 8;
|
||||
hi_mpi_ai_set_chn_param(deviceID(), channelID(), ¶m);
|
||||
|
||||
run();
|
||||
}
|
||||
|
||||
void AudioInput::stop()
|
||||
{
|
||||
cancel();
|
||||
|
||||
hi_mpi_ai_disable_chn(deviceID(), channelID());
|
||||
hi_mpi_ai_disable(deviceID());
|
||||
}
|
||||
|
||||
void AudioInput::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
if (!started())
|
||||
return;
|
||||
|
||||
auto code = serialCodeManager().code();
|
||||
if (names.exists(_SampleRate))
|
||||
serialCodeManager().put(_SampleRate, getSampleRate());
|
||||
|
||||
if (names.exists(_FrameSize))
|
||||
serialCodeManager().put(_FrameSize, getFrameSize());
|
||||
|
||||
if (code != serialCodeManager().code())
|
||||
{
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
|
||||
AbstractAudioInput::onConfigChanged(names);
|
||||
}
|
||||
|
||||
Core::Frame::Ptr AudioInput::readFrame()
|
||||
{
|
||||
hi_audio_frame frame;
|
||||
hi_aec_frame aecFrame;
|
||||
|
||||
int rc = hi_mpi_ai_get_frame(deviceID(), 0, &frame, &aecFrame, 1000);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::TimeoutException(Poco::format("%s: Get frame error: %u(%#x)!", name(), (uint32_t)rc, (uint32_t)rc));
|
||||
|
||||
Core::Frame::Ptr pFrame = nullptr;
|
||||
if (frame.len > 0)
|
||||
{
|
||||
pFrame = new Core::Frame;
|
||||
pFrame->data[0] = new uint8_t[frame.len];
|
||||
memcpy(pFrame->data[0], frame.virt_addr[0], frame.len);
|
||||
pFrame->data[1] = new uint8_t[frame.len];
|
||||
memcpy(pFrame->data[1], frame.virt_addr[1], frame.len);
|
||||
pFrame->length = frame.len;
|
||||
pFrame->timestamp = frame.time_stamp;
|
||||
}
|
||||
|
||||
hi_mpi_ai_release_frame(deviceID(), 0, &frame, &aecFrame);
|
||||
_traffic++;
|
||||
return pFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
video/hisi/mpp5/AudioInput.h
Normal file
40
video/hisi/mpp5/AudioInput.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef C7DEE8B3_9816_4937_B2A6_0591DEF0ED45
|
||||
#define C7DEE8B3_9816_4937_B2A6_0591DEF0ED45
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "MPPChannel.h"
|
||||
#include "../../core/AbstractAudioInput.h"
|
||||
#include "util/Task.h"
|
||||
#include <hi_common.h>
|
||||
#include <hi_mpi_audio.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class AudioInput: public Core::AbstractAudioInput, public MPPChannel
|
||||
{
|
||||
public:
|
||||
using Ptr = Poco::AutoPtr<AudioInput>;
|
||||
|
||||
public:
|
||||
AudioInput(uint32_t deviceID);
|
||||
~AudioInput();
|
||||
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
Core::Frame::Ptr readFrame() override;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
122
video/hisi/mpp5/HDMIAudioOutput.cpp
Normal file
122
video/hisi/mpp5/HDMIAudioOutput.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "HDMIAudioOutput.h"
|
||||
#include "Util.h"
|
||||
#include "util/Math.h"
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CONSTANTS
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#define AO_DEV_ID 1
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
HDMIAudioOutput::HDMIAudioOutput(const std::string& arg)
|
||||
: Core::AudioOutput("MPP5::AudioOutput(" + arg + ")"), MPPChannel((uint32_t)HI_ID_AO, AO_DEV_ID, 0)
|
||||
{
|
||||
setSampleRate(48000);
|
||||
setSampleFormat(Core::SampleFormat::S16P);
|
||||
setChannelLayout(Core::ChannelLayout::STEREO);
|
||||
setFrameSize(1024);
|
||||
}
|
||||
|
||||
HDMIAudioOutput::~HDMIAudioOutput()
|
||||
{
|
||||
}
|
||||
|
||||
void HDMIAudioOutput::initialize()
|
||||
{
|
||||
_bitWidth = Util::getBitWidth(getSampleFormat());
|
||||
_sndMode = Util::getSndMode(getChannelLayout());
|
||||
|
||||
hi_aio_attr attr;
|
||||
attr.sample_rate = (hi_audio_sample_rate)getSampleRate();
|
||||
attr.bit_width = _bitWidth;
|
||||
attr.work_mode = HI_AIO_MODE_I2S_MASTER;
|
||||
attr.i2s_type = HI_AIO_I2STYPE_INNERHDMI;
|
||||
attr.snd_mode = _sndMode;
|
||||
attr.expand_flag = 0;
|
||||
attr.frame_num = 8;
|
||||
attr.point_num_per_frame = getFrameSize();
|
||||
attr.chn_cnt = Core::channelLayoutChannels(getChannelLayout());
|
||||
|
||||
attr.clk_share = 0;
|
||||
|
||||
int rc = hi_mpi_ao_set_pub_attr(deviceID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Configure pub-attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_ao_enable(deviceID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Enable FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_ao_set_volume(deviceID(), getVolumeValue());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Configure volume FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
rc = hi_mpi_ao_enable_chn(deviceID(), channelID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Enable CHM#%u FAIL: %d(%#x)", name(), channelID(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
void HDMIAudioOutput::deinitialize()
|
||||
{
|
||||
hi_mpi_ao_disable_chn(deviceID(), channelID());
|
||||
hi_mpi_ao_disable(deviceID());
|
||||
}
|
||||
|
||||
void HDMIAudioOutput::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
if (!started())
|
||||
return;
|
||||
|
||||
int rc = hi_mpi_ao_set_volume(deviceID(), getVolumeValue());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Configure volume FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
}
|
||||
|
||||
void HDMIAudioOutput::writeFrame(Core::Frame::Ptr pFrame)
|
||||
{
|
||||
hi_audio_frame frame = {};
|
||||
frame.bit_width = HI_AUDIO_BIT_WIDTH_16;
|
||||
frame.len = pFrame->length;
|
||||
frame.time_stamp = pFrame->timestamp;
|
||||
frame.snd_mode = HI_AUDIO_SOUND_MODE_MONO;
|
||||
frame.virt_addr[0] = pFrame->data[0].get();
|
||||
if (HI_AUDIO_SOUND_MODE_STEREO == _sndMode)
|
||||
frame.virt_addr[1] = pFrame->data[1].get();
|
||||
int rc = hi_mpi_ao_send_frame(deviceID(), channelID(), &frame, 100);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Send frame FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
int HDMIAudioOutput::getVolumeValue()
|
||||
{
|
||||
auto lineMapping = [](int inputMin, int inputMax, int outMin, int outMax, int input) -> int
|
||||
{ return (input - inputMin) * (outMax - outMin) / (inputMax - inputMin) + outMin; };
|
||||
|
||||
int gain = ::Util::Math::clamp(getGain(), -100, 100);
|
||||
if (gain < 0)
|
||||
return lineMapping(-100, -1, -121, -1, gain);
|
||||
|
||||
return lineMapping(0, 100, 0, 6, gain);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
video/hisi/mpp5/HDMIAudioOutput.h
Normal file
41
video/hisi/mpp5/HDMIAudioOutput.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef CCC7E17D_FF7C_44B5_8DCC_BFCE92AAFC87
|
||||
#define CCC7E17D_FF7C_44B5_8DCC_BFCE92AAFC87
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "../core/AudioOutput.h"
|
||||
#include "MPPChannel.h"
|
||||
#include <hi_mpi_audio.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class HDMIAudioOutput: public Core::AudioOutput, public MPPChannel
|
||||
{
|
||||
public:
|
||||
HDMIAudioOutput(const std::string& arg);
|
||||
~HDMIAudioOutput();
|
||||
|
||||
protected:
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
void writeFrame(Core::Frame::Ptr pFrame) override;
|
||||
|
||||
int getVolumeValue();
|
||||
|
||||
private:
|
||||
hi_audio_bit_width _bitWidth;
|
||||
hi_audio_snd_mode _sndMode;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
403
video/hisi/mpp5/HDMIVideoOutput.cpp
Normal file
403
video/hisi/mpp5/HDMIVideoOutput.cpp
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "HDMIVideoOutput.h"
|
||||
#include "Logger.h"
|
||||
#include "util/Math.h"
|
||||
#include <array>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CONSTANTS
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#define VO_DEVICE_ID 0
|
||||
|
||||
#define VIDEO_LAYER_ID 0
|
||||
|
||||
#define HDMI_ID HI_HDMI_ID_0
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* TYPEDEFS
|
||||
*******************************************************************************
|
||||
*/
|
||||
struct TimingDesc
|
||||
{
|
||||
std::string desc;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t frameRate;
|
||||
hi_vo_intf_sync intf;
|
||||
hi_hdmi_video_format format;
|
||||
};
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*******************************************************************************
|
||||
*/
|
||||
static const std::array<TimingDesc, 27> timingDescTable = {{
|
||||
{"3840x2160P30", 3840, 2160, 30, HI_VO_OUT_3840x2160_30, HI_HDMI_VIDEO_FORMAT_3840X2160P_30},
|
||||
{"2560x1600P60", 2560, 1600, 60, HI_VO_OUT_2560x1600_60, HI_HDMI_VIDEO_FORMAT_2560x1600_60},
|
||||
{"2560x1440P60", 2560, 1440, 60, HI_VO_OUT_2560x1440_60, HI_HDMI_VIDEO_FORMAT_2560x1440_60},
|
||||
{"2560x1440P30", 2560, 1440, 30, HI_VO_OUT_2560x1440_30, HI_HDMI_VIDEO_FORMAT_2560x1440_30},
|
||||
{"1920x1080P60", 1920, 1080, 60, HI_VO_OUT_1080P60, HI_HDMI_VIDEO_FORMAT_1080P_60},
|
||||
{"1920x1080I60", 1920, 1080, 60, HI_VO_OUT_1080I60, HI_HDMI_VIDEO_FORMAT_1080i_60},
|
||||
{"1920x1080P50", 1920, 1080, 50, HI_VO_OUT_1080P50, HI_HDMI_VIDEO_FORMAT_1080P_50},
|
||||
{"1920x1080I50", 1920, 1080, 50, HI_VO_OUT_1080I50, HI_HDMI_VIDEO_FORMAT_1080i_50},
|
||||
{"1920x1080P30", 1920, 1080, 30, HI_VO_OUT_1080P30, HI_HDMI_VIDEO_FORMAT_1080P_30},
|
||||
{"1920x1080P25", 1920, 1080, 25, HI_VO_OUT_1080P25, HI_HDMI_VIDEO_FORMAT_1080P_25},
|
||||
{"1920x1080P24", 1920, 1080, 24, HI_VO_OUT_1080P24, HI_HDMI_VIDEO_FORMAT_1080P_24},
|
||||
{"1280x720P60", 1280, 720, 60, HI_VO_OUT_720P60, HI_HDMI_VIDEO_FORMAT_720P_60},
|
||||
{"1280x720P50", 1280, 720, 50, HI_VO_OUT_720P50, HI_HDMI_VIDEO_FORMAT_720P_50},
|
||||
{"720x576P50", 720, 576, 50, HI_VO_OUT_576P50, HI_HDMI_VIDEO_FORMAT_576P_50},
|
||||
{"720x480P50", 720, 480, 60, HI_VO_OUT_480P60, HI_HDMI_VIDEO_FORMAT_480P_60},
|
||||
{"1920x2160P30", 1920, 2160, 30, HI_VO_OUT_1920x2160_30, HI_HDMI_VIDEO_FORMAT_1920x2160_30},
|
||||
{"1920x1200P60", 1920, 1200, 60, HI_VO_OUT_1920x1200_60, HI_HDMI_VIDEO_FORMAT_VESA_1920X1200_60},
|
||||
{"1680x1050P60", 1680, 1050, 60, HI_VO_OUT_1680x1050_60, HI_HDMI_VIDEO_FORMAT_VESA_1680X1050_60},
|
||||
{"1600x1200P60", 1600, 1200, 60, HI_VO_OUT_1600x1200_60, HI_HDMI_VIDEO_FORMAT_VESA_1600X1200_60},
|
||||
{"1440x900P60", 1440, 900, 60, HI_VO_OUT_1440x900_60, HI_HDMI_VIDEO_FORMAT_VESA_1440X900_60},
|
||||
{"1366x768P60", 1366, 768, 60, HI_VO_OUT_1366x768_60, HI_HDMI_VIDEO_FORMAT_VESA_1366X768_60},
|
||||
{"1280x1024P60", 1280, 1024, 60, HI_VO_OUT_1280x1024_60, HI_HDMI_VIDEO_FORMAT_VESA_1280X1024_60},
|
||||
{"1280x800P60", 1280, 800, 60, HI_VO_OUT_1280x800_60, HI_HDMI_VIDEO_FORMAT_VESA_1280X800_60},
|
||||
{"1024x768P60", 1024, 768, 60, HI_VO_OUT_1024x768_60, HI_HDMI_VIDEO_FORMAT_VESA_1024X768_60},
|
||||
{"800x600P60", 800, 600, 60, HI_VO_OUT_800x600_60, HI_HDMI_VIDEO_FORMAT_VESA_800X600_60},
|
||||
}};
|
||||
|
||||
const TimingDesc& defaultTime = timingDescTable[4];
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
static const TimingDesc& getTimingDesc(const std::string& desc)
|
||||
{
|
||||
for (const auto& t : timingDescTable)
|
||||
{
|
||||
if (t.desc == desc)
|
||||
return t;
|
||||
}
|
||||
|
||||
logger().warning("HDMIVideoOutput: Could NOT found '%s', using %s", desc, defaultTime.desc);
|
||||
return defaultTime;
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
HDMIVideoOutput::HDMIVideoOutput(const std::string& name)
|
||||
: Core::VideoOutput(name + "(MPP5::HDMI)"), MPPChannel((uint32_t)HI_ID_VO, VO_DEVICE_ID, 0)
|
||||
{
|
||||
hi_mpi_hdmi_init();
|
||||
stopOutput();
|
||||
}
|
||||
|
||||
HDMIVideoOutput::~HDMIVideoOutput()
|
||||
{
|
||||
stopOutput();
|
||||
hi_mpi_hdmi_deinit();
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::start()
|
||||
{
|
||||
hi_mpi_hdmi_open(HDMI_ID);
|
||||
|
||||
onHotPlug();
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::stop()
|
||||
{
|
||||
onNoPlug();
|
||||
|
||||
hi_mpi_hdmi_close(HDMI_ID);
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
if (!getHDMIStarted())
|
||||
return;
|
||||
|
||||
if (names.exists(_Timing))
|
||||
{
|
||||
try
|
||||
{
|
||||
stopOutput();
|
||||
startOutput();
|
||||
}
|
||||
catch (Poco::Exception& e)
|
||||
{
|
||||
logger().error(e.displayText());
|
||||
stopOutput();
|
||||
}
|
||||
}
|
||||
|
||||
if (names.exists(_Mode))
|
||||
{
|
||||
hi_mpi_hdmi_stop(HDMI_ID);
|
||||
|
||||
hi_hdmi_attr attr;
|
||||
|
||||
int rc = hi_mpi_hdmi_get_attr(HDMI_ID, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
logger().error("%s: get HDMI attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc);
|
||||
|
||||
attr.hdmi_en = getUsingHDMIMode();
|
||||
rc = hi_mpi_hdmi_set_attr(HDMI_ID, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
logger().error("%s: set HDMI attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc);
|
||||
|
||||
rc = hi_mpi_hdmi_start(HDMI_ID);
|
||||
if (rc != HI_SUCCESS)
|
||||
logger().error("%s: start HDMI FAIL: %d(%#x)", name(), rc, (uint32_t)rc);
|
||||
}
|
||||
|
||||
if (names.exists(_Luma) || names.exists(_Contrast) || names.exists(_Hue) || names.exists(_Saturation) ||
|
||||
names.exists(_ColorType))
|
||||
{
|
||||
hi_vo_hdmi_param param;
|
||||
|
||||
if (names.exists(_ColorType))
|
||||
hi_mpi_hdmi_stop(HDMI_ID);
|
||||
|
||||
hi_mpi_vo_get_hdmi_param(deviceID(), ¶m);
|
||||
|
||||
if (names.exists(_ColorType))
|
||||
param.csc.csc_matrix = getCSCMatrix();
|
||||
|
||||
param.csc.luma = ::Util::Math::clamp(getLuma(), 0, 100);
|
||||
param.csc.contrast = ::Util::Math::clamp(getContrast(), 0, 100);
|
||||
param.csc.hue = ::Util::Math::clamp(getHue(), 0, 100);
|
||||
param.csc.saturation = ::Util::Math::clamp(getSaturation(), 0, 100);
|
||||
hi_mpi_vo_set_hdmi_param(deviceID(), ¶m);
|
||||
|
||||
if (names.exists(_ColorType))
|
||||
hi_mpi_hdmi_start(HDMI_ID);
|
||||
}
|
||||
|
||||
if (names.exists(_Mirror))
|
||||
hi_mpi_vo_set_chn_mirror(VIDEO_LAYER_ID, channelID(), getMirror() ? HI_VO_MIRROR_HOR : HI_VO_MIRROR_NONE);
|
||||
|
||||
if (names.exists(_Rotation))
|
||||
hi_mpi_vo_set_chn_rotation(VIDEO_LAYER_ID, channelID(), getRotationValue());
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::onLink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
MPPChannel::doLink(pPrevious);
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::onUnlink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
MPPChannel::doUnlink(pPrevious);
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::onHotPlug()
|
||||
{
|
||||
logger().debug("%s: HDMI HOTPLUG", name());
|
||||
setPluged(true);
|
||||
|
||||
try
|
||||
{
|
||||
startOutput();
|
||||
}
|
||||
catch (Poco::Exception& e)
|
||||
{
|
||||
logger().error(e.displayText());
|
||||
}
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::onNoPlug()
|
||||
{
|
||||
logger().debug("%s: HDMI NOPLUG", name());
|
||||
setPluged(false);
|
||||
stopOutput();
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::onEDIDFail()
|
||||
{
|
||||
logger().debug("EDID FAIL");
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::startOutput()
|
||||
{
|
||||
const TimingDesc& timing = getTimingDesc(getTiming());
|
||||
|
||||
hi_vo_pub_attr attr;
|
||||
attr.bg_color = 0x000000;
|
||||
attr.intf_type = HI_VO_INTF_HDMI;
|
||||
attr.intf_sync = timing.intf;
|
||||
int rc = hi_mpi_vo_set_pub_attr(deviceID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: set-pub FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vo_enable(deviceID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: enable VO FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
{
|
||||
hi_vo_video_layer_attr attr;
|
||||
|
||||
attr.display_rect.x = 0;
|
||||
attr.display_rect.y = 0;
|
||||
attr.display_rect.width = timing.width;
|
||||
attr.display_rect.height = timing.height;
|
||||
attr.img_size.width = timing.width;
|
||||
attr.img_size.height = timing.height;
|
||||
attr.display_frame_rate = timing.frameRate;
|
||||
attr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
|
||||
|
||||
attr.double_frame_en = HI_FALSE;
|
||||
attr.cluster_mode_en = HI_FALSE;
|
||||
attr.dst_dynamic_range = HI_DYNAMIC_RANGE_SDR8;
|
||||
attr.display_buf_len = 4;
|
||||
|
||||
attr.partition_mode = HI_VO_PARTITION_MODE_SINGLE;
|
||||
attr.compress_mode = HI_COMPRESS_MODE_NONE;
|
||||
rc = hi_mpi_vo_set_video_layer_attr(VIDEO_LAYER_ID, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: set video layer attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vo_enable_video_layer(VIDEO_LAYER_ID);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: enable video layer FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
{
|
||||
hi_vo_chn_attr attr;
|
||||
attr.priority = 0;
|
||||
attr.rect.x = 0;
|
||||
attr.rect.y = 0;
|
||||
attr.rect.width = timing.width;
|
||||
attr.rect.height = timing.height;
|
||||
attr.deflicker_en = HI_FALSE;
|
||||
rc = hi_mpi_vo_set_chn_attr(VIDEO_LAYER_ID, channelID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: set chn attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
rc = hi_mpi_vo_enable_chn(VIDEO_LAYER_ID, channelID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: enable FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
hi_mpi_vo_set_chn_mirror(VIDEO_LAYER_ID, channelID(), getMirror() ? HI_VO_MIRROR_HOR : HI_VO_MIRROR_NONE);
|
||||
hi_mpi_vo_set_chn_rotation(VIDEO_LAYER_ID, channelID(), getRotationValue());
|
||||
}
|
||||
|
||||
{
|
||||
hi_hdmi_attr attr;
|
||||
rc = hi_mpi_hdmi_get_attr(HDMI_ID, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: get HDMI attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
attr.hdmi_en = getUsingHDMIMode();
|
||||
attr.video_format = timing.format;
|
||||
attr.deep_color_mode = HI_HDMI_DEEP_COLOR_24BIT;
|
||||
attr.audio_en = attr.hdmi_en ? HI_TRUE : HI_FALSE;
|
||||
attr.sample_rate = HI_HDMI_SAMPLE_RATE_48K;
|
||||
attr.bit_depth = HI_HDMI_BIT_DEPTH_16;
|
||||
attr.auth_mode_en = HI_TRUE;
|
||||
attr.deep_color_adapt_en = HI_TRUE;
|
||||
rc = hi_mpi_hdmi_set_attr(HDMI_ID, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: set HDMI attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
hi_vo_hdmi_param param;
|
||||
hi_mpi_vo_get_hdmi_param(deviceID(), ¶m);
|
||||
param.csc.csc_matrix = getCSCMatrix();
|
||||
param.csc.luma = ::Util::Math::clamp(getLuma(), 0, 100);
|
||||
param.csc.contrast = ::Util::Math::clamp(getContrast(), 0, 100);
|
||||
param.csc.hue = ::Util::Math::clamp(getHue(), 0, 100);
|
||||
param.csc.saturation = ::Util::Math::clamp(getSaturation(), 0, 100);
|
||||
hi_mpi_vo_set_hdmi_param(deviceID(), ¶m);
|
||||
|
||||
rc = hi_mpi_hdmi_start(HDMI_ID);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: start HDMI FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
}
|
||||
|
||||
setHDMIStarted(true);
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::stopOutput()
|
||||
{
|
||||
hi_mpi_hdmi_stop(HDMI_ID);
|
||||
|
||||
hi_mpi_vo_disable_chn(VIDEO_LAYER_ID, channelID());
|
||||
|
||||
hi_mpi_vo_disable_video_layer(VIDEO_LAYER_ID);
|
||||
|
||||
hi_mpi_vo_disable(VO_DEVICE_ID);
|
||||
|
||||
setHDMIStarted(false);
|
||||
}
|
||||
|
||||
hi_bool HDMIVideoOutput::getUsingHDMIMode()
|
||||
{
|
||||
return getMode() == Core::VideoOutput::Mode::HDMI ? HI_TRUE : HI_FALSE;
|
||||
}
|
||||
|
||||
hi_vo_csc_matrix HDMIVideoOutput::getCSCMatrix()
|
||||
{
|
||||
if (getMode() == Core::VideoOutput::Mode::DVI || getColorType() == Core::VideoOutput::ColorType::RGB)
|
||||
return HI_VO_CSC_MATRIX_BT709LIMIT_TO_RGBFULL;
|
||||
|
||||
return HI_VO_CSC_MATRIX_BT709LIMIT_TO_BT709FULL;
|
||||
}
|
||||
|
||||
hi_rotation HDMIVideoOutput::getRotationValue()
|
||||
{
|
||||
switch (getRotation())
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return HI_ROTATION_0;
|
||||
|
||||
case 90:
|
||||
return HI_ROTATION_90;
|
||||
|
||||
case 180:
|
||||
return HI_ROTATION_180;
|
||||
|
||||
case 270:
|
||||
return HI_ROTATION_270;
|
||||
}
|
||||
}
|
||||
|
||||
void HDMIVideoOutput::eventCallback(hi_hdmi_event_type event, td_void* p)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case HI_HDMI_EVENT_HOTPLUG:
|
||||
static_cast<HDMIVideoOutput*>(p)->onHotPlug();
|
||||
break;
|
||||
|
||||
case HI_HDMI_EVENT_NO_PLUG:
|
||||
static_cast<HDMIVideoOutput*>(p)->onNoPlug();
|
||||
break;
|
||||
|
||||
case HI_HDMI_EVENT_EDID_FAIL:
|
||||
static_cast<HDMIVideoOutput*>(p)->onEDIDFail();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
video/hisi/mpp5/HDMIVideoOutput.h
Normal file
53
video/hisi/mpp5/HDMIVideoOutput.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef AB83CB54_F14E_4C1B_B2AE_6AF47090444C
|
||||
#define AB83CB54_F14E_4C1B_B2AE_6AF47090444C
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "../../core/VideoOutput.h"
|
||||
#include "MPPChannel.h"
|
||||
#include <hi_mpi_hdmi.h>
|
||||
#include <hi_mpi_vo.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class HDMIVideoOutput: public Core::VideoOutput, MPPChannel
|
||||
{
|
||||
public:
|
||||
HDMIVideoOutput(const std::string& name);
|
||||
~HDMIVideoOutput();
|
||||
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
void onLink(Core::Component::Ptr pPrevious) override;
|
||||
void onUnlink(Core::Component::Ptr pPrevious) override;
|
||||
|
||||
void onHotPlug();
|
||||
void onNoPlug();
|
||||
void onEDIDFail();
|
||||
|
||||
void startOutput();
|
||||
void stopOutput();
|
||||
|
||||
hi_bool getUsingHDMIMode();
|
||||
hi_vo_csc_matrix getCSCMatrix();
|
||||
hi_rotation getRotationValue();
|
||||
|
||||
PROPERTY_DECLARE(Pluged, bool, false, protected, protected)
|
||||
PROPERTY_DECLARE(HDMIStarted, bool, false, protected, protected)
|
||||
|
||||
static void eventCallback(hi_hdmi_event_type event, td_void* p);
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
498
video/hisi/mpp5/IVE.cpp
Normal file
498
video/hisi/mpp5/IVE.cpp
Normal file
|
|
@ -0,0 +1,498 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "IVE.h"
|
||||
#include "Logger.h"
|
||||
#include "util/Math.h"
|
||||
#include <hi_mpi_sys.h>
|
||||
#include <hi_mpi_vb.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CONSTANTS
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#define HI__IVE_IMAGE_CHN_ONE 1
|
||||
#define HI__IVE_IMAGE_CHN_TWO 2
|
||||
#define HI__IVE_IMAGE_CHN_THREE 3
|
||||
#define HI__IVE_IMAGE_CHN_FOUR 4
|
||||
#define HI__IVE_MAX_CCL_REGION_NUM 254
|
||||
#define HI__IVE_DIV_TWO 2
|
||||
#define HI_SAMPLE_POINT_IDX_ZERO 0
|
||||
#define HI_SAMPLE_POINT_IDX_ONE 1
|
||||
#define HI_SAMPLE_POINT_IDX_TWO 2
|
||||
#define HI_SAMPLE_POINT_IDX_THREE 3
|
||||
|
||||
#define HI_SAMPLE_RESIZE_MAX_TILE_METRIC_8BIT 2032
|
||||
#define HI_SAMPLE_RESIZE_MAX_TILE_METRIC_16BIT 1016
|
||||
#define HI_SAMPLE_RESIZE_TILE_ADJUST 2
|
||||
#define HI_SAMPLE_RESIZE_ASSIST_UNIT_SIZE 48
|
||||
#define HI_SAMPLE_RESIZE_CBCR_NUM_2 2
|
||||
#define HI_SAMPLE_RESIZE_CBCR_NUM_3 3
|
||||
|
||||
#define HI_IVE_ALIGN 16
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* MACROS
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define _convert_ptr_to_addr(type, addr) ((type)(hi_uintptr_t)(addr))
|
||||
#define _convert_addr_to_ptr(type, addr) ((type*)(hi_uintptr_t)(addr))
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* TYPEDEFS
|
||||
*******************************************************************************
|
||||
*/
|
||||
struct _img_loop_info
|
||||
{
|
||||
uint32_t ele_size;
|
||||
uint32_t loop_c;
|
||||
uint32_t loop_h[HI_SVP_IMG_ADDR_NUM];
|
||||
};
|
||||
typedef struct _img_loop_info _img_loop_info_t;
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
static void _ive_get_loop_info(const hi_svp_img* img, _img_loop_info_t* loop_info)
|
||||
{
|
||||
loop_info->ele_size = 1;
|
||||
loop_info->loop_c = 1;
|
||||
loop_info->loop_h[0] = img->height;
|
||||
switch (img->type)
|
||||
{
|
||||
case HI_SVP_IMG_TYPE_U8C1:
|
||||
case HI_SVP_IMG_TYPE_S8C1:
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_YUV420SP:
|
||||
loop_info->ele_size = 1;
|
||||
loop_info->loop_c = HI__IVE_IMAGE_CHN_TWO;
|
||||
loop_info->loop_h[1] = img->height / HI__IVE_DIV_TWO;
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_YUV422SP:
|
||||
loop_info->loop_c = HI__IVE_IMAGE_CHN_TWO;
|
||||
loop_info->loop_h[1] = img->height;
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_U8C3_PACKAGE:
|
||||
loop_info->ele_size = (uint32_t)(sizeof(uint8_t) + sizeof(uint16_t));
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_U8C3_PLANAR:
|
||||
loop_info->loop_c = HI__IVE_IMAGE_CHN_THREE;
|
||||
loop_info->loop_h[1] = img->height;
|
||||
loop_info->loop_h[HI__IVE_IMAGE_CHN_TWO] = img->height;
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_S16C1:
|
||||
case HI_SVP_IMG_TYPE_U16C1:
|
||||
loop_info->ele_size = (uint32_t)sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_U32C1:
|
||||
case HI_SVP_IMG_TYPE_S32C1:
|
||||
loop_info->ele_size = (uint32_t)sizeof(uint32_t);
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_S64C1:
|
||||
case HI_SVP_IMG_TYPE_U64C1:
|
||||
loop_info->ele_size = (uint32_t)sizeof(uint64_t);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define HI_SAMPLE_ADDR_IDX_ZERO 0
|
||||
#define HI_SAMPLE_ADDR_IDX_ONE 1
|
||||
#define HI_SAMPLE_ADDR_IDX_TWO 2
|
||||
#define HI_MAX_LOOP_IMG_H 3
|
||||
|
||||
static int _ive_set_image_addr(hi_svp_img* img, const _img_loop_info_t* loop_info, hi_bool is_mmz_cached)
|
||||
{
|
||||
uint32_t c;
|
||||
int size = 0;
|
||||
int rc;
|
||||
hi_void* virt_addr = HI_NULL;
|
||||
|
||||
for (c = 0; (c < loop_info->loop_c) && (c < HI_MAX_LOOP_IMG_H) && (c < HI_SVP_IMG_STRIDE_NUM); c++)
|
||||
{
|
||||
size += img->stride[0] * loop_info->loop_h[c] * loop_info->ele_size;
|
||||
img->stride[c] = img->stride[0];
|
||||
}
|
||||
|
||||
if (is_mmz_cached)
|
||||
{
|
||||
rc = hi_mpi_sys_mmz_alloc_cached((hi_phys_addr_t*)&img->phys_addr[0], (hi_void**)&virt_addr, HI_NULL, HI_NULL,
|
||||
size);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = hi_mpi_sys_mmz_alloc((hi_phys_addr_t*)&img->phys_addr[0], (hi_void**)&virt_addr, HI_NULL, HI_NULL, size);
|
||||
}
|
||||
|
||||
if (rc != HI_SUCCESS)
|
||||
{
|
||||
logger().error("IVE: mmz malloc FAIL: %d(%08X)", rc, (uint32_t)rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
img->virt_addr[HI_SAMPLE_ADDR_IDX_ZERO] = _convert_ptr_to_addr(uint64_t, virt_addr);
|
||||
|
||||
if (img->type != HI_SVP_IMG_TYPE_U8C3_PACKAGE)
|
||||
{
|
||||
for (c = 1; (c < loop_info->loop_c) && (c < HI_MAX_LOOP_IMG_H) && (c < HI_SVP_IMG_STRIDE_NUM); c++)
|
||||
{
|
||||
img->phys_addr[c] = img->phys_addr[c - 1] + img->stride[c - 1] * img->height;
|
||||
img->virt_addr[c] = img->virt_addr[c - 1] + img->stride[c - 1] * img->height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
img->virt_addr[HI_SAMPLE_ADDR_IDX_ONE] = img->virt_addr[HI_SAMPLE_ADDR_IDX_ZERO] + 1;
|
||||
img->virt_addr[HI_SAMPLE_ADDR_IDX_TWO] = img->virt_addr[HI_SAMPLE_ADDR_IDX_ONE] + 1;
|
||||
img->phys_addr[HI_SAMPLE_ADDR_IDX_ONE] = img->phys_addr[HI_SAMPLE_ADDR_IDX_ZERO] + 1;
|
||||
img->phys_addr[HI_SAMPLE_ADDR_IDX_TWO] = img->phys_addr[HI_SAMPLE_ADDR_IDX_ONE] + 1;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int _ive_img_init(hi_svp_img* img, hi_svp_img_type type, uint32_t width, uint32_t height)
|
||||
{
|
||||
int rc = 0;
|
||||
_img_loop_info_t loop_info;
|
||||
|
||||
img->type = type;
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
img->stride[0] = Util::Math::alignup(width, HI_IVE_ALIGN);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case HI_SVP_IMG_TYPE_U8C1:
|
||||
case HI_SVP_IMG_TYPE_S8C1:
|
||||
case HI_SVP_IMG_TYPE_YUV420SP:
|
||||
case HI_SVP_IMG_TYPE_YUV422SP:
|
||||
case HI_SVP_IMG_TYPE_S16C1:
|
||||
case HI_SVP_IMG_TYPE_U16C1:
|
||||
case HI_SVP_IMG_TYPE_U8C3_PACKAGE:
|
||||
case HI_SVP_IMG_TYPE_S32C1:
|
||||
case HI_SVP_IMG_TYPE_U32C1:
|
||||
case HI_SVP_IMG_TYPE_S64C1:
|
||||
case HI_SVP_IMG_TYPE_U64C1:
|
||||
_ive_get_loop_info(img, &loop_info);
|
||||
rc = _ive_set_image_addr(img, &loop_info, HI_FALSE);
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_YUV420P:
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_YUV422P:
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_S8C2_PACKAGE:
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_S8C2_PLANAR:
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_U8C3_PLANAR:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static uint32_t _ive_resize_get_tile_metric(uint32_t src_metric, uint32_t dst_metric, hi_svp_img_type img_type)
|
||||
{
|
||||
int tmp_metric = HI_SAMPLE_RESIZE_MAX_TILE_METRIC_8BIT;
|
||||
uint32_t src_tile_num, scale, dst_tmp_tile, src_tmp_tile, tile_remainder;
|
||||
switch (img_type)
|
||||
{
|
||||
case HI_SVP_IMG_TYPE_YUV420SP:
|
||||
case HI_SVP_IMG_TYPE_YUV422SP:
|
||||
case HI_SVP_IMG_TYPE_U8C3_PLANAR:
|
||||
case HI_SVP_IMG_TYPE_U8C1:
|
||||
case HI_SVP_IMG_TYPE_S8C1:
|
||||
tmp_metric = HI_SAMPLE_RESIZE_MAX_TILE_METRIC_8BIT;
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_U16C1:
|
||||
case HI_SVP_IMG_TYPE_S16C1:
|
||||
|
||||
tmp_metric = HI_SAMPLE_RESIZE_MAX_TILE_METRIC_16BIT;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
scale = (src_metric / dst_metric) + ((src_metric % dst_metric == 0) ? 0 : 1);
|
||||
if (dst_metric < src_metric)
|
||||
{
|
||||
src_tile_num = (src_metric / tmp_metric) + ((src_metric % tmp_metric == 0) ? 0 : 1);
|
||||
dst_tmp_tile = dst_metric / src_tile_num;
|
||||
src_tmp_tile = src_metric / src_tile_num + ((src_metric % src_tile_num == 0) ? 0 : 1);
|
||||
tile_remainder = (tmp_metric - src_tmp_tile) / scale;
|
||||
tmp_metric = (dst_tmp_tile + tile_remainder) & ~0x1;
|
||||
if (tile_remainder == 0)
|
||||
{
|
||||
tmp_metric -= HI_SAMPLE_RESIZE_TILE_ADJUST;
|
||||
}
|
||||
}
|
||||
else if (dst_metric == src_metric || scale == 1)
|
||||
{
|
||||
tmp_metric -= HI_SAMPLE_RESIZE_TILE_ADJUST;
|
||||
}
|
||||
return (uint32_t)tmp_metric;
|
||||
}
|
||||
|
||||
static uint32_t _ive_resize_get_tile_num(uint32_t width, uint32_t height, uint32_t tile_w, uint32_t tile_h)
|
||||
{
|
||||
uint32_t x_num, y_num;
|
||||
if ((tile_w == 0) || (tile_h == 0))
|
||||
return 0;
|
||||
|
||||
x_num = (width / tile_w) + ((width % tile_w) == 0 ? 0 : 1);
|
||||
y_num = (height / tile_h) + ((height % tile_h) == 0 ? 0 : 1);
|
||||
return (x_num * y_num);
|
||||
}
|
||||
|
||||
#define HI_SAMPLE_RESIZE_CBCR_NUM_2 2
|
||||
static uint32_t _ive_resize_get_yuv420sp_tile_num(uint32_t src_width, uint32_t dst_width, uint32_t src_height,
|
||||
uint32_t dst_height)
|
||||
{
|
||||
uint32_t j, tile_width, tile_height;
|
||||
uint32_t num = 0;
|
||||
|
||||
tile_width = _ive_resize_get_tile_metric(src_width, dst_width, HI_SVP_IMG_TYPE_YUV420SP);
|
||||
for (j = 0; j < HI_SAMPLE_RESIZE_CBCR_NUM_2; j++)
|
||||
{
|
||||
tile_height = _ive_resize_get_tile_metric(src_height >> j, dst_height >> j, HI_SVP_IMG_TYPE_YUV420SP);
|
||||
num += _ive_resize_get_tile_num(dst_width, dst_height >> j, tile_width, tile_height);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static uint32_t _ive_resize_get_yuv422sp_tile_num(uint32_t src_width, uint32_t dst_width, uint32_t src_height,
|
||||
uint32_t dst_height)
|
||||
{
|
||||
uint32_t j, tile_width, tile_height;
|
||||
uint32_t num = 0;
|
||||
|
||||
tile_width = _ive_resize_get_tile_metric(src_width, dst_width, HI_SVP_IMG_TYPE_YUV422SP);
|
||||
tile_height = _ive_resize_get_tile_metric(src_height, dst_height, HI_SVP_IMG_TYPE_YUV422SP);
|
||||
|
||||
for (j = 0; j < HI_SAMPLE_RESIZE_CBCR_NUM_2; j++)
|
||||
num += _ive_resize_get_tile_num(dst_width, dst_height, tile_width, tile_height);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static uint32_t _ive_resize_get_u8c3_planar_tile_num(uint32_t src_width, uint32_t dst_width, uint32_t src_height,
|
||||
uint32_t dst_height)
|
||||
{
|
||||
uint32_t j, tile_width, tile_height;
|
||||
uint32_t num = 0;
|
||||
|
||||
tile_width = _ive_resize_get_tile_metric(src_width, dst_width, HI_SVP_IMG_TYPE_U8C3_PLANAR);
|
||||
tile_height = _ive_resize_get_tile_metric(src_height, dst_height, HI_SVP_IMG_TYPE_U8C3_PLANAR);
|
||||
for (j = 0; j < HI_SAMPLE_RESIZE_CBCR_NUM_3; j++)
|
||||
num += _ive_resize_get_tile_num(dst_width, dst_height, tile_width, tile_height);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static uint32_t _ive_resize_get_u8c1_tile_num(uint32_t src_width, uint32_t dst_width, uint32_t src_height,
|
||||
uint32_t dst_height)
|
||||
{
|
||||
uint32_t tile_width, tile_height;
|
||||
uint32_t num = 0;
|
||||
|
||||
tile_width = _ive_resize_get_tile_metric(src_width, dst_width, HI_SVP_IMG_TYPE_U8C1);
|
||||
tile_height = _ive_resize_get_tile_metric(src_height, dst_height, HI_SVP_IMG_TYPE_U8C1);
|
||||
num = _ive_resize_get_tile_num(dst_width, dst_height, tile_width, tile_height);
|
||||
return num;
|
||||
}
|
||||
|
||||
static uint32_t _ive_resize_get_u16c1_tile_num(uint32_t src_width, uint32_t dst_width, uint32_t src_height,
|
||||
uint32_t dst_height)
|
||||
{
|
||||
uint32_t tile_width, tile_height;
|
||||
uint32_t num = 0;
|
||||
|
||||
tile_width = _ive_resize_get_tile_metric(src_width, dst_width, HI_SVP_IMG_TYPE_U16C1);
|
||||
tile_height = _ive_resize_get_tile_metric(src_height, dst_height, HI_SVP_IMG_TYPE_U16C1);
|
||||
num = _ive_resize_get_tile_num(dst_width, dst_height, tile_width, tile_height);
|
||||
return num;
|
||||
}
|
||||
|
||||
static int _ive_resize_get_assist_buf_size(const hi_svp_src_img src[], const hi_svp_dst_img dst[], int count)
|
||||
{
|
||||
int i;
|
||||
int num = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
switch (src[i].type)
|
||||
{
|
||||
case HI_SVP_IMG_TYPE_YUV420SP:
|
||||
num += _ive_resize_get_yuv420sp_tile_num(src[i].width, dst[i].width, src[i].height, dst[i].height);
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_YUV422SP:
|
||||
num += _ive_resize_get_yuv422sp_tile_num(src[i].width, dst[i].width, src[i].height, dst[i].height);
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_U8C3_PLANAR:
|
||||
num += _ive_resize_get_u8c3_planar_tile_num(src[i].width, dst[i].width, src[i].height, dst[i].height);
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_U8C1:
|
||||
case HI_SVP_IMG_TYPE_S8C1:
|
||||
num += _ive_resize_get_u8c1_tile_num(src[i].width, dst[i].width, src[i].height, dst[i].height);
|
||||
break;
|
||||
|
||||
case HI_SVP_IMG_TYPE_U16C1:
|
||||
case HI_SVP_IMG_TYPE_S16C1:
|
||||
num += _ive_resize_get_u16c1_tile_num(src[i].width, dst[i].width, src[i].height, dst[i].height);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return num * HI_SAMPLE_RESIZE_ASSIST_UNIT_SIZE;
|
||||
}
|
||||
|
||||
static int _ive_mem_info_init(hi_svp_mem_info* mem_info, hi_u32 size)
|
||||
{
|
||||
int rc = HI_ERR_IVE_NULL_PTR;
|
||||
hi_void* virt_addr = HI_NULL;
|
||||
|
||||
mem_info->size = size;
|
||||
rc = hi_mpi_sys_mmz_alloc((hi_phys_addr_t*)&mem_info->phys_addr, (hi_void**)&virt_addr, HI_NULL, HI_NULL, size);
|
||||
if (rc != HI_SUCCESS)
|
||||
return rc;
|
||||
|
||||
mem_info->virt_addr = _convert_ptr_to_addr(uint64_t, virt_addr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _ive_img_load(hi_svp_img* img, uint8_t* pData)
|
||||
{
|
||||
uint8_t* ptr_tmp = HI_NULL;
|
||||
uint16_t c, h;
|
||||
int rc = 0;
|
||||
_img_loop_info_t loop_info = {0};
|
||||
int index = 0;
|
||||
|
||||
_ive_get_loop_info(img, &loop_info);
|
||||
for (c = 0; (c < loop_info.loop_c) && (c < HI_SVP_IMG_STRIDE_NUM) && (c < HI_SVP_IMG_ADDR_NUM); c++)
|
||||
{
|
||||
ptr_tmp = _convert_addr_to_ptr(uint8_t, img->virt_addr[c]);
|
||||
if (!ptr_tmp)
|
||||
{
|
||||
rc = HI_ERR_IVE_BAD_ADDR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (h = 0; h < loop_info.loop_h[c]; h++)
|
||||
{
|
||||
int bytes = img->width * loop_info.ele_size;
|
||||
memcpy(ptr_tmp, &pData[index], bytes);
|
||||
index += bytes;
|
||||
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _ive_img_store(hi_svp_img* img, uint8_t* pBuffer)
|
||||
{
|
||||
uint16_t c, h;
|
||||
uint8_t* ptr_tmp = HI_NULL;
|
||||
int rc = 0;
|
||||
_img_loop_info_t loop_info = {0};
|
||||
int index = 0;
|
||||
|
||||
if (img->phys_addr == 0 || img->virt_addr == 0)
|
||||
return HI_ERR_BAD_ADDR;
|
||||
|
||||
_ive_get_loop_info(img, &loop_info);
|
||||
for (c = 0; (c < loop_info.loop_c) && (c < HI_SVP_IMG_STRIDE_NUM) && (c < HI_SVP_IMG_ADDR_NUM); c++)
|
||||
{
|
||||
ptr_tmp = _convert_addr_to_ptr(uint8_t, img->virt_addr[c]);
|
||||
if (!ptr_tmp)
|
||||
{
|
||||
rc = HI_ERR_IVE_BAD_ADDR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (h = 0; h < loop_info.loop_h[c]; h++)
|
||||
{
|
||||
int bytes = img->width * loop_info.ele_size;
|
||||
memcpy(&pBuffer[index], ptr_tmp, bytes);
|
||||
index += bytes;
|
||||
|
||||
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define _mmz_free(phys, virt) \
|
||||
do \
|
||||
{ \
|
||||
if (((phys) != 0) && ((virt) != 0)) \
|
||||
{ \
|
||||
hi_mpi_sys_mmz_free((hi_phys_addr_t)(phys), (hi_void*)(hi_uintptr_t)(virt)); \
|
||||
(phys) = 0; \
|
||||
(virt) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void _ive_img_free(hi_svp_img* img)
|
||||
{
|
||||
_mmz_free(img->phys_addr[0], img->virt_addr[0]);
|
||||
}
|
||||
|
||||
static void _ive_mem_info_free(hi_svp_mem_info* info)
|
||||
{
|
||||
_mmz_free(info->phys_addr, info->virt_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
VideoFrame::Ptr MPP5::IVE::resize(VideoFrame::Ptr from, uint32_t width, uint32_t height)
|
||||
{
|
||||
return VideoFrame::Ptr();
|
||||
}
|
||||
}
|
||||
}
|
||||
27
video/hisi/mpp5/IVE.h
Normal file
27
video/hisi/mpp5/IVE.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef F479D816_531D_4084_A289_1B5C5A2A6CE7
|
||||
#define F479D816_531D_4084_A289_1B5C5A2A6CE7
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "VideoFrame.h"
|
||||
#include <hi_mpi_ive.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class IVE
|
||||
{
|
||||
public:
|
||||
VideoFrame::Ptr resize(VideoFrame::Ptr from, uint32_t width, uint32_t height);
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
135
video/hisi/mpp5/MPPChannel.cpp
Normal file
135
video/hisi/mpp5/MPPChannel.cpp
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "MPPChannel.h"
|
||||
#include "Logger.h"
|
||||
#include <hi_common.h>
|
||||
#include <hi_mpi_sys.h>
|
||||
#include <Poco/Format.h>
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* MACROS
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define HI_MPP_CHN_DECLARE(name, ref) \
|
||||
hi_mpp_chn name \
|
||||
{ \
|
||||
(hi_mod_id)(ref).moduleID(), (hi_s32)(ref).deviceID(), (hi_s32)(ref).channelID(), \
|
||||
}
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
static const char* moduleNames[] = {
|
||||
"CMPI", "VB", "SYS",
|
||||
"RGN", "CHNL", "VDEC",
|
||||
"AVS", "VPSS", "VENC",
|
||||
"SVP", "H264E", "JPEGE",
|
||||
"UNKNOWN", "H265E", "JPEGD",
|
||||
"VO", "VI", "DIS",
|
||||
"VALG", "RC", "AIO",
|
||||
"AI", "AO", "AENC",
|
||||
"ADEC", "VPU", "PCIV",
|
||||
"PCIVFMW", "ISP", "IVE",
|
||||
"USER", "UNKNOWN", "UNKNOWN",
|
||||
"PROC", "LOG", "VFMW",
|
||||
"UNKNOWN", "GDC", "PHOTO",
|
||||
"FB", "HDMI", "VOIE",
|
||||
"TDE", "HDR", "PRORES",
|
||||
"VGS", "UNKNOWN", "FD",
|
||||
"OD", "UNKNOWN", "LPR",
|
||||
"SVP_NNIE", "SVP_DSP", "DPU_RECT",
|
||||
"DPU_MATCH", "MOTIONSENSOR", "MOTIONFUSION",
|
||||
"GYRODIS", "PM", "SVP_ALG",
|
||||
"IVP", "MCF", "SVP_MAU",
|
||||
"VDA", "VPP", "KCF",
|
||||
"PQP", "NPUDEV", "AICPU",
|
||||
"NPUDFX", "TSFW", "CIPHER",
|
||||
"KLAD", "KEYSLOT", "OTP",
|
||||
"VDEC_ADAPT", "DCC", "VDEC_SERVER",
|
||||
"VFMW_MDC", "VB_LOG", "MCF_CALIBRATION",
|
||||
"SVP_NPU", "HNR", "SNAP",
|
||||
"LOG_MDC", "UVC", "FISHEYE_CALIBRATION",
|
||||
};
|
||||
|
||||
MPPChannel::MPPChannel(uint32_t moduleID, uint32_t deviceID, uint32_t channelID)
|
||||
: _moduleID(moduleID), _deviceID(deviceID), _channelID(channelID)
|
||||
{
|
||||
}
|
||||
|
||||
std::string MPPChannel::toString() const
|
||||
{
|
||||
const char* name = "UNKNOWN";
|
||||
if (moduleID() < HI_ID_FISHEYE_CALIBRATION)
|
||||
name = moduleNames[moduleID()];
|
||||
|
||||
return Poco::format("%s(%u:%u)", std::string(name), deviceID(), channelID());
|
||||
}
|
||||
|
||||
void MPPChannel::bind(const MPPChannel& next)
|
||||
{
|
||||
HI_MPP_CHN_DECLARE(from, *this);
|
||||
HI_MPP_CHN_DECLARE(to, next);
|
||||
|
||||
int rc = hi_mpi_sys_bind(&from, &to);
|
||||
if (rc < 0)
|
||||
logger().error("Bind: %s -> %s: %#x", this->toString(), next.toString(), (uint32_t)rc);
|
||||
else
|
||||
logger().debug("Bind: %s -> %s SUCCESS", this->toString(), next.toString());
|
||||
}
|
||||
|
||||
void MPPChannel::unbind(const MPPChannel& next)
|
||||
{
|
||||
HI_MPP_CHN_DECLARE(from, *this);
|
||||
HI_MPP_CHN_DECLARE(to, next);
|
||||
|
||||
int rc = hi_mpi_sys_unbind(&from, &to);
|
||||
if (rc < 0)
|
||||
logger().error("Unbind: %s -> %s: %#x", this->toString(), next.toString(), (uint32_t)rc);
|
||||
else
|
||||
logger().debug("Unbind: %s -> %s SUCCESS", this->toString(), next.toString());
|
||||
}
|
||||
|
||||
void MPPChannel::doLink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
auto pFrom = dynamic_cast<MPPChannel*>(pPrevious.get());
|
||||
if (pFrom)
|
||||
{
|
||||
pFrom->bind(*this);
|
||||
return;
|
||||
}
|
||||
|
||||
logger().error("MPPChannel: dolink FAIL: %s is not 'MPPChannel'", pPrevious->name());
|
||||
}
|
||||
|
||||
void MPPChannel::doUnlink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
auto pFrom = dynamic_cast<MPPChannel*>(pPrevious.get());
|
||||
if (pFrom)
|
||||
{
|
||||
pFrom->unbind(*this);
|
||||
return;
|
||||
}
|
||||
|
||||
logger().error("MPPChannel: doUnlink FAIL: %s is not 'MPPChannel'", pPrevious->name());
|
||||
}
|
||||
|
||||
hi_mpp_chn MPPChannel::raw()
|
||||
{
|
||||
return hi_mpp_chn{
|
||||
(hi_mod_id)moduleID(),
|
||||
(hi_s32)deviceID(),
|
||||
(hi_s32)channelID(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
70
video/hisi/mpp5/MPPChannel.h
Normal file
70
video/hisi/mpp5/MPPChannel.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#ifndef EEDA2366_7E77_49AC_8716_526A3A63113F
|
||||
#define EEDA2366_7E77_49AC_8716_526A3A63113F
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include <string>
|
||||
#include "../core/Component.h"
|
||||
#include <hi_mpi_sys.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class MPPChannel
|
||||
{
|
||||
public:
|
||||
MPPChannel(uint32_t moduleID, uint32_t deviceID, uint32_t channelID);
|
||||
|
||||
public:
|
||||
bool operator<(const MPPChannel& other) const;
|
||||
|
||||
uint32_t moduleID() const;
|
||||
uint32_t deviceID() const;
|
||||
uint32_t channelID() const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
virtual void bind(const MPPChannel& next);
|
||||
virtual void unbind(const MPPChannel& next);
|
||||
|
||||
void doLink(Core::Component::Ptr pPrevious);
|
||||
void doUnlink(Core::Component::Ptr pPrevious);
|
||||
|
||||
hi_mpp_chn raw();
|
||||
|
||||
private:
|
||||
uint32_t _moduleID;
|
||||
uint32_t _deviceID;
|
||||
uint32_t _channelID;
|
||||
};
|
||||
|
||||
inline bool MPPChannel::operator<(const MPPChannel& other) const
|
||||
{
|
||||
return moduleID() < other.moduleID() || deviceID() < other.deviceID() || channelID() < other.channelID();
|
||||
}
|
||||
|
||||
inline uint32_t MPPChannel::moduleID() const
|
||||
{
|
||||
return _moduleID;
|
||||
}
|
||||
|
||||
inline uint32_t MPPChannel::deviceID() const
|
||||
{
|
||||
return _deviceID;
|
||||
}
|
||||
|
||||
inline uint32_t MPPChannel::channelID() const
|
||||
{
|
||||
return _channelID;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
18
video/hisi/mpp5/Notifications.cpp
Normal file
18
video/hisi/mpp5/Notifications.cpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "Notifications.h"
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
}
|
||||
}
|
||||
24
video/hisi/mpp5/Notifications.h
Normal file
24
video/hisi/mpp5/Notifications.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef DF1404E9_430D_4F31_989F_4C5EB4BE26D4
|
||||
#define DF1404E9_430D_4F31_989F_4C5EB4BE26D4
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "../../core/Component.h"
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class VideoDecoderResetNotification: public Core::Component::Notification
|
||||
{
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
75
video/hisi/mpp5/ResourceManager.cpp
Normal file
75
video/hisi/mpp5/ResourceManager.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "ResourceManager.h"
|
||||
#include <hi_mpi_vpss.h>
|
||||
#include <hi_mpi_venc.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
Util::HandlesManager<uint32_t> ResourceManager::_vpssGroupIDManager(HI_VPSS_MAX_GRP_NUM);
|
||||
Util::HandlesManager<uint32_t> ResourceManager::_vencChannelIDManager(HI_VENC_MAX_CHN_NUM);
|
||||
Util::HandlesManager<uint32_t> ResourceManager::_vdecChannelIDManager(HI_VDEC_MAX_CHN_NUM);
|
||||
Util::HandlesManager<uint32_t> ResourceManager::_aencChannelIDManager(HI_AENC_MAX_CHN_NUM);
|
||||
Util::HandlesManager<uint32_t> ResourceManager::_rgnHandleManager(HI_RGN_HANDLE_MAX);
|
||||
|
||||
uint32_t ResourceManager::allocVPSSGroupID()
|
||||
{
|
||||
return _vpssGroupIDManager.allocHandle();
|
||||
}
|
||||
|
||||
void ResourceManager::freeVPSSGroupID(uint32_t id)
|
||||
{
|
||||
_vpssGroupIDManager.freeHandle(id);
|
||||
}
|
||||
|
||||
uint32_t ResourceManager::allocVENCChannelID()
|
||||
{
|
||||
return _vencChannelIDManager.allocHandle();
|
||||
}
|
||||
|
||||
void ResourceManager::freeVENCChannelID(uint32_t id)
|
||||
{
|
||||
_vencChannelIDManager.freeHandle(id);
|
||||
}
|
||||
|
||||
uint32_t ResourceManager::allocVDECChannelID()
|
||||
{
|
||||
return _vdecChannelIDManager.allocHandle();
|
||||
}
|
||||
|
||||
void ResourceManager::freeVDECChannelID(uint32_t id)
|
||||
{
|
||||
_vdecChannelIDManager.freeHandle(id);
|
||||
}
|
||||
|
||||
uint32_t ResourceManager::allocAENCChannelID()
|
||||
{
|
||||
return _aencChannelIDManager.allocHandle();
|
||||
}
|
||||
|
||||
void ResourceManager::freeAENCChannelID(uint32_t id)
|
||||
{
|
||||
_aencChannelIDManager.freeHandle(id);
|
||||
}
|
||||
|
||||
uint32_t ResourceManager::allocRGNHandle()
|
||||
{
|
||||
return _rgnHandleManager.allocHandle();
|
||||
}
|
||||
|
||||
void ResourceManager::freeRGNHandle(uint32_t handle)
|
||||
{
|
||||
_rgnHandleManager.freeHandle(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
60
video/hisi/mpp5/ResourceManager.h
Normal file
60
video/hisi/mpp5/ResourceManager.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef CAE4D712_1E71_4191_9693_2F31854D9087
|
||||
#define CAE4D712_1E71_4191_9693_2F31854D9087
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "util/HandlesManager.h"
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CONSTANTS
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define NO_SIGNAL_YUV_PATH "/customer/no-signal-1080.yvu422sp"
|
||||
#define NO_SIGNAL_YUV_FORMAT HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422
|
||||
#define NO_SIGNAL_YUV_WIDTH 1920
|
||||
#define NO_SIGNAL_YUV_HEIGHT 1080
|
||||
|
||||
#define NO_SIGNAL_JPEG_PATH "/customer/no-signal-1080.jpg"
|
||||
#define NO_SIGNAL_JPEG_WIDTH 1920
|
||||
#define NO_SIGNAL_JPEG_HEIGHT 1080
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class ResourceManager
|
||||
{
|
||||
public:
|
||||
static uint32_t allocVPSSGroupID();
|
||||
static void freeVPSSGroupID(uint32_t id);
|
||||
|
||||
static uint32_t allocVENCChannelID();
|
||||
static void freeVENCChannelID(uint32_t id);
|
||||
|
||||
static uint32_t allocVDECChannelID();
|
||||
static void freeVDECChannelID(uint32_t id);
|
||||
|
||||
static uint32_t allocAENCChannelID();
|
||||
static void freeAENCChannelID(uint32_t id);
|
||||
|
||||
static uint32_t allocRGNHandle();
|
||||
static void freeRGNHandle(uint32_t handle);
|
||||
|
||||
private:
|
||||
static Util::HandlesManager<uint32_t> _vpssGroupIDManager;
|
||||
static Util::HandlesManager<uint32_t> _vencChannelIDManager;
|
||||
static Util::HandlesManager<uint32_t> _vdecChannelIDManager;
|
||||
static Util::HandlesManager<uint32_t> _aencChannelIDManager;
|
||||
static Util::HandlesManager<uint32_t> _rgnHandleManager;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
110
video/hisi/mpp5/System.cpp
Normal file
110
video/hisi/mpp5/System.cpp
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "System.h"
|
||||
#include "Logger.h"
|
||||
#include <hi_buffer.h>
|
||||
#include <hi_common.h>
|
||||
#include <hi_mpi_tde.h>
|
||||
#include <hi_mpi_sys.h>
|
||||
#include <hi_mpi_vb.h>
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CONSTANTS
|
||||
*******************************************************************************
|
||||
*/
|
||||
#ifndef INPUT_IMAGE_WIDTH_MAX
|
||||
#define INPUT_IMAGE_WIDTH_MAX 3840
|
||||
#endif
|
||||
#ifndef INPUT_IMAGE_HEIGHT_MAX
|
||||
#define INPUT_IMAGE_HEIGHT_MAX 2160
|
||||
#endif
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
System::System()
|
||||
{
|
||||
hi_mpi_sys_exit();
|
||||
hi_mpi_vb_exit();
|
||||
|
||||
hi_vb_cfg vbcfg;
|
||||
memset(&vbcfg, 0, sizeof(vbcfg));
|
||||
vbcfg.max_pool_cnt = 16;
|
||||
|
||||
hi_pic_buf_attr attr;
|
||||
attr.width = INPUT_IMAGE_WIDTH_MAX;
|
||||
attr.height = INPUT_IMAGE_HEIGHT_MAX;
|
||||
attr.align = HI_DEFAULT_ALIGN;
|
||||
attr.bit_width = OT_DATA_BIT_WIDTH_8;
|
||||
attr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
|
||||
attr.compress_mode = HI_COMPRESS_MODE_FRAME;
|
||||
uint32_t size = hi_common_get_pic_buf_size(&attr);
|
||||
|
||||
sprintf(vbcfg.common_pool[0].mmz_name, "%s", "anonymous");
|
||||
vbcfg.common_pool[0].remap_mode = OT_VB_REMAP_MODE_NONE;
|
||||
vbcfg.common_pool[0].blk_cnt = 32;
|
||||
vbcfg.common_pool[0].blk_size = size;
|
||||
|
||||
attr.width = 1920;
|
||||
attr.height = 1080;
|
||||
attr.align = HI_DEFAULT_ALIGN;
|
||||
attr.bit_width = OT_DATA_BIT_WIDTH_8;
|
||||
attr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
|
||||
attr.compress_mode = HI_COMPRESS_MODE_FRAME;
|
||||
size = hi_common_get_pic_buf_size(&attr);
|
||||
|
||||
sprintf(vbcfg.common_pool[1].mmz_name, "%s", "anonymous");
|
||||
vbcfg.common_pool[1].remap_mode = OT_VB_REMAP_MODE_NONE;
|
||||
vbcfg.common_pool[1].blk_cnt = 32;
|
||||
vbcfg.common_pool[1].blk_size = size;
|
||||
|
||||
int rc = hi_mpi_vb_set_cfg(&vbcfg);
|
||||
if (rc != HI_SUCCESS)
|
||||
{
|
||||
logger().error("VB Set config FAIL: %#x", (uint32_t)rc);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = hi_mpi_vb_init();
|
||||
if (rc != HI_SUCCESS)
|
||||
{
|
||||
logger().error("VB Initialize FAIL: %#x", (uint32_t)rc);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = hi_mpi_sys_init();
|
||||
if (rc != HI_SUCCESS)
|
||||
{
|
||||
logger().error("SYS Initialize FAIL: %#x", (uint32_t)rc);
|
||||
return;
|
||||
}
|
||||
|
||||
hi_mpi_sys_init_pts_base(0);
|
||||
hi_tde_open();
|
||||
}
|
||||
|
||||
System::~System()
|
||||
{
|
||||
hi_tde_close();
|
||||
hi_mpi_sys_exit();
|
||||
hi_mpi_vb_exit();
|
||||
}
|
||||
|
||||
uint64_t System::getTimestamp()
|
||||
{
|
||||
hi_u64 now;
|
||||
hi_mpi_sys_get_cur_pts(&now);
|
||||
return now;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
video/hisi/mpp5/System.h
Normal file
31
video/hisi/mpp5/System.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef D30EB83D_9A50_4F5F_8549_B0B9F16AE7AD
|
||||
#define D30EB83D_9A50_4F5F_8549_B0B9F16AE7AD
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "../../core/System.h"
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class System: public Core::System
|
||||
{
|
||||
public:
|
||||
System();
|
||||
~System();
|
||||
|
||||
protected:
|
||||
uint64_t getTimestamp() override;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
100
video/hisi/mpp5/Util.cpp
Normal file
100
video/hisi/mpp5/Util.cpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "Util.h"
|
||||
#include <Poco/Exception.h>
|
||||
#include <Poco/Format.h>
|
||||
#include <array>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* TYPEDEFS
|
||||
*******************************************************************************
|
||||
*/
|
||||
struct CodecIDMapItem
|
||||
{
|
||||
Core::CodecID id;
|
||||
hi_payload_type pt;
|
||||
};
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*******************************************************************************
|
||||
*/
|
||||
static const std::array<CodecIDMapItem, 7> codecMap = {{
|
||||
{Core::CodecID::H264, HI_PT_H264},
|
||||
{Core::CodecID::H265, HI_PT_H265},
|
||||
{Core::CodecID::MJPEG, HI_PT_MJPEG},
|
||||
{Core::CodecID::MP3, HI_PT_MP3},
|
||||
{Core::CodecID::AAC, HI_PT_AAC},
|
||||
{Core::CodecID::G711A, HI_PT_G711A},
|
||||
{Core::CodecID::G711U, HI_PT_G711U},
|
||||
}};
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* FUNCTIONS
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
static hi_payload_type findPayloadType(Core::CodecID id)
|
||||
{
|
||||
for (const auto& m : codecMap)
|
||||
{
|
||||
if (id == m.id)
|
||||
return m.pt;
|
||||
}
|
||||
|
||||
throw Poco::NotFoundException(Poco::format("Video::MPP5: Can't find %s in codec-map", Core::codecIDToString(id)));
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
hi_audio_bit_width Util::getBitWidth(Core::SampleFormat format)
|
||||
{
|
||||
if (16 == Core::sampleFormatBitWidth(format))
|
||||
return HI_AUDIO_BIT_WIDTH_16;
|
||||
|
||||
throw Poco::InvalidArgumentException("MPP5: Only support 16 bit-width", -EINVAL);
|
||||
}
|
||||
|
||||
hi_audio_snd_mode Util::getSndMode(Core::ChannelLayout layout)
|
||||
{
|
||||
if (Core::ChannelLayout::STEREO == layout)
|
||||
return HI_AUDIO_SOUND_MODE_STEREO;
|
||||
|
||||
return HI_AUDIO_SOUND_MODE_MONO;
|
||||
}
|
||||
|
||||
hi_payload_type Util::getPayloadType(Core::CodecID id)
|
||||
{
|
||||
return findPayloadType(id);
|
||||
}
|
||||
|
||||
uint32_t Util::getChannelId(const std::string& name)
|
||||
{
|
||||
if (name.find("NET0") != std::string::npos)
|
||||
return 2;
|
||||
else if (name.find("NET1") != std::string::npos)
|
||||
return 3;
|
||||
else if (name.find("NET2") != std::string::npos)
|
||||
return 4;
|
||||
else if (name.find("NET3") != std::string::npos)
|
||||
return 5;
|
||||
else if (name.find("USB") != std::string::npos)
|
||||
return 6;
|
||||
else if (name.find("File") != std::string::npos)
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
video/hisi/mpp5/Util.h
Normal file
32
video/hisi/mpp5/Util.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef CFE2FF99_0E17_46AD_B839_023CAED87EE5
|
||||
#define CFE2FF99_0E17_46AD_B839_023CAED87EE5
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "../../core/SampleFormat.h"
|
||||
#include "../../core/CodecID.h"
|
||||
#include <hi_common_aio.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class Util
|
||||
{
|
||||
public:
|
||||
static hi_audio_bit_width getBitWidth(Core::SampleFormat format);
|
||||
static hi_audio_snd_mode getSndMode(Core::ChannelLayout layout);
|
||||
|
||||
static hi_payload_type getPayloadType(Core::CodecID id);
|
||||
static uint32_t getChannelId(const std::string& name);
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
1000
video/hisi/mpp5/VideoDecoder.cpp
Normal file
1000
video/hisi/mpp5/VideoDecoder.cpp
Normal file
File diff suppressed because it is too large
Load diff
123
video/hisi/mpp5/VideoDecoder.h
Normal file
123
video/hisi/mpp5/VideoDecoder.h
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#ifndef CF63EDDC_B464_4F43_9D68_4B200F07DD82
|
||||
#define CF63EDDC_B464_4F43_9D68_4B200F07DD82
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "MPPChannel.h"
|
||||
#include "VideoFrame.h"
|
||||
#include "../../core/VideoDecoder.h"
|
||||
#include "../../core/CodecCapabilityManager.h"
|
||||
#include "../../core/FrameSynchronizer.h"
|
||||
#include <functional>
|
||||
#include "util/Broadcast.h"
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class VideoDecoder: public MPPChannel,
|
||||
public Core::VideoDecoder
|
||||
{
|
||||
private:
|
||||
class Pipe: public MPPChannel
|
||||
{
|
||||
public:
|
||||
Pipe(const std::string& name, uint32_t id);
|
||||
~Pipe();
|
||||
|
||||
public:
|
||||
void start(uint32_t width, uint32_t height);
|
||||
void stop();
|
||||
void write(VideoFrame& frame, uint64_t pts, uint32_t timeref, bool isFrozen, hi_video_frame_info& frameX);
|
||||
|
||||
uint32_t groupID() const;
|
||||
const std::string& name() const;
|
||||
|
||||
const uint32_t width();
|
||||
const uint32_t height();
|
||||
|
||||
private:
|
||||
const std::string _name;
|
||||
uint32_t _width;
|
||||
uint32_t _height;
|
||||
};
|
||||
|
||||
enum class PostTaskControl
|
||||
{
|
||||
RUNNING,
|
||||
EXIT,
|
||||
INSTANT_EXIT,
|
||||
};
|
||||
|
||||
public:
|
||||
VideoDecoder(const std::string& name);
|
||||
~VideoDecoder();
|
||||
void reset() override;
|
||||
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
|
||||
Core::Frame::Ptr decode() override;
|
||||
|
||||
void bind(const MPPChannel& next) override;
|
||||
void unbind(const MPPChannel& next) override;
|
||||
|
||||
void sendUserFrame(VideoFrame::Ptr pFrame, uint64_t duration, uint32_t& timeref);
|
||||
void runSendUserFrame(VideoFrame::Ptr pFrame, std::function<bool(void)> condition);
|
||||
void runSignalLost(std::atomic<bool>& isCancelled);
|
||||
void runFault(std::atomic<bool>& isCancelled);
|
||||
Core::Packet::Ptr runExceptionProcedure(std::atomic<bool>& isCancelled);
|
||||
bool handleSerialCode(const Core::SerialCode& code);
|
||||
void handlePreviousChanged();
|
||||
void decodePacket(Core::Packet::Ptr pPacket, std::atomic<bool>& isCancelled);
|
||||
void createDecoder(uint32_t width, uint32_t height, uint32_t frameRate, Core::CodecID codecID);
|
||||
void releaseDecoder(bool instant = false);
|
||||
Core::Packet::Ptr tryReadPacket(uint32_t timeout, bool shuldLog);
|
||||
void releaseCapabilityHandle();
|
||||
void frameCopy(hi_video_frame_info& from, hi_video_frame_info& to);
|
||||
void frameRelease(hi_video_frame_info& frame);
|
||||
bool saveSingleFrame(hi_video_frame_info& frame, const std::string& dir_path);
|
||||
bool loadVideoFrame(const std::string& dir_path, hi_video_frame_info& frame);
|
||||
|
||||
private:
|
||||
Core::CodecCapabilityManager::Handle _handle;
|
||||
Pipe _pipe;
|
||||
::Util::Task _postTask;
|
||||
std::atomic<PostTaskControl> _postTaskControl;
|
||||
uint32_t _frameTimeRef = 2;
|
||||
Core::FrameSynchronizer _synchronizer;
|
||||
const uint32_t _channelId;
|
||||
hi_video_frame_info _frameX;
|
||||
bool _frozenPlay;
|
||||
bool _firstPic;
|
||||
bool _buttonPressed;
|
||||
bool _lastStatus;
|
||||
|
||||
bool _catchUpEnabled;
|
||||
bool _isCatchingUp;
|
||||
void updateCatchUpState();
|
||||
|
||||
PROPERTY_DECLARE(UsingCapability, Core::CodecID, Core::CodecID::NB, private, private)
|
||||
|
||||
public:
|
||||
static void initModule();
|
||||
static void deinitModule();
|
||||
|
||||
private:
|
||||
static Core::CodecCapabilityManager _vdhCapabilityManager;
|
||||
static Core::CodecCapabilityManager _jpgdCapabilityManager;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
682
video/hisi/mpp5/VideoEncoder.cpp
Normal file
682
video/hisi/mpp5/VideoEncoder.cpp
Normal file
|
|
@ -0,0 +1,682 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "VideoEncoder.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "Logger.h"
|
||||
#include "util/Math.h"
|
||||
#include <errno.h>
|
||||
|
||||
using namespace Util;
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CONSTANTS
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define MIN_ALIGN 2
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* MACROS
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define __set_basic(attr, gop, sfr, dfr) \
|
||||
attr.gop = (gop); \
|
||||
attr.src_frame_rate = (sfr); \
|
||||
attr.dst_frame_rate = (dfr);
|
||||
|
||||
#define __set_cbr(attr, gop, st, sfr, dfr, br) \
|
||||
__set_basic(attr, gop, sfr, dfr) attr.stats_time = (st); \
|
||||
attr.bit_rate = (br);
|
||||
|
||||
#define __set_vbr(attr, gop, st, sfr, dfr, br) \
|
||||
__set_basic(attr, gop, sfr, dfr) attr.stats_time = (st); \
|
||||
attr.max_bit_rate = (br);
|
||||
|
||||
#define __set_avbr __set_vbr
|
||||
|
||||
#define __set_qvbr(attr, gop, st, sfr, dfr, br) \
|
||||
__set_basic(attr, gop, sfr, dfr) attr.stats_time = (st); \
|
||||
attr.target_bit_rate = (br);
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
VideoEncoder::Preprocessor::Preprocessor(const std::string& name, uint32_t id)
|
||||
: MPPChannel((uint32_t)HI_ID_VPSS, id, 0), _name(Poco::format("%s(VPSS#%u)", name, id))
|
||||
{
|
||||
}
|
||||
|
||||
VideoEncoder::Preprocessor::~Preprocessor()
|
||||
{
|
||||
}
|
||||
|
||||
void VideoEncoder::Preprocessor::start(uint32_t iwidth, uint32_t iheight, uint32_t owidth, uint32_t oheight)
|
||||
{
|
||||
hi_vpss_grp_attr attr = {};
|
||||
attr.nr_en = HI_FALSE;
|
||||
attr.ie_en = HI_FALSE;
|
||||
attr.dci_en = HI_FALSE;
|
||||
attr.buf_share_en = HI_FALSE;
|
||||
attr.buf_share_chn = 0;
|
||||
attr.mcf_en = HI_FALSE;
|
||||
attr.max_width = iwidth;
|
||||
attr.max_height = iheight;
|
||||
attr.max_dei_width = iwidth;
|
||||
attr.max_dei_height = iheight;
|
||||
attr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
attr.dynamic_range = HI_DYNAMIC_RANGE_SDR8;
|
||||
attr.frame_rate.src_frame_rate = -1;
|
||||
attr.frame_rate.dst_frame_rate = -1;
|
||||
attr.dei_mode = HI_VPSS_DEI_MODE_OFF;
|
||||
|
||||
int rc = hi_mpi_vpss_create_grp(groupID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Create group FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
hi_mpi_vpss_reset_grp(groupID());
|
||||
rc = hi_mpi_vpss_start_grp(groupID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Start group FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
hi_vpss_chn_attr chnAttr = {};
|
||||
chnAttr.chn_mode = HI_VPSS_CHN_MODE_USER;
|
||||
|
||||
chnAttr.width = owidth;
|
||||
chnAttr.height = oheight;
|
||||
chnAttr.video_format = HI_VIDEO_FORMAT_LINEAR;
|
||||
chnAttr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
chnAttr.dynamic_range = HI_DYNAMIC_RANGE_SDR8;
|
||||
chnAttr.compress_mode = HI_COMPRESS_MODE_NONE;
|
||||
|
||||
chnAttr.frame_rate.src_frame_rate = -1;
|
||||
chnAttr.frame_rate.dst_frame_rate = -1;
|
||||
chnAttr.mirror_en = HI_FALSE;
|
||||
chnAttr.flip_en = HI_FALSE;
|
||||
chnAttr.depth = 0;
|
||||
chnAttr.aspect_ratio.mode = HI_ASPECT_RATIO_NONE;
|
||||
rc = hi_mpi_vpss_set_chn_attr(groupID(), channelID(), &chnAttr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Set channel#%u attr FAIL: %d(%#x)", name(), channelID(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vpss_enable_chn(groupID(), channelID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Enable channel#%u FAIL: %d(%#x)", name(), channelID(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
void VideoEncoder::Preprocessor::stop()
|
||||
{
|
||||
int rc = hi_mpi_vpss_disable_chn(groupID(), channelID());
|
||||
if (rc != HI_SUCCESS)
|
||||
logger().error("%s: Disable channel#%u FAIL: %d(%#x)", name(), channelID(), rc, (uint32_t)rc);
|
||||
|
||||
rc = hi_mpi_vpss_stop_grp(groupID());
|
||||
if (rc != HI_SUCCESS)
|
||||
logger().error("%s: Stop group FAIL: %d(%#x)", name(), rc, (uint32_t)rc);
|
||||
|
||||
rc = hi_mpi_vpss_destroy_grp(groupID());
|
||||
if (rc != HI_SUCCESS)
|
||||
logger().error("%s: Destroy group FAIL: %d(%#x)", name(), rc, (uint32_t)rc);
|
||||
}
|
||||
|
||||
uint32_t VideoEncoder::Preprocessor::groupID() const
|
||||
{
|
||||
return deviceID();
|
||||
}
|
||||
|
||||
const std::string& VideoEncoder::Preprocessor::name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
Core::CodecCapabilityManager VideoEncoder::_capabilityManager(1920 * 1080 * 30 * 4 + 720 * 480 * 30 * 4);
|
||||
|
||||
VideoEncoder::VideoEncoder(Core::CodecID codecID)
|
||||
: MPPChannel((uint32_t)HI_ID_VENC, 0, ResourceManager::allocVENCChannelID()),
|
||||
Core::VideoEncoder(Poco::format("MPP5::VENC#%u(%s)", channelID(), Core::codecIDToString(codecID)), codecID),
|
||||
_handle(Core::CodecCapabilityManager::INVALID_HANDLE), _preprocessor(name(), ResourceManager::allocVPSSGroupID())
|
||||
{
|
||||
registerNotificationHandle<Core::ParameterChangedNotification>(*this,
|
||||
&VideoEncoder::handlePreviousParameterChanged);
|
||||
}
|
||||
|
||||
VideoEncoder::~VideoEncoder()
|
||||
{
|
||||
ResourceManager::freeVPSSGroupID(_preprocessor.groupID());
|
||||
ResourceManager::freeVENCChannelID(channelID());
|
||||
releaseCapabilityHandle();
|
||||
}
|
||||
|
||||
void VideoEncoder::start()
|
||||
{
|
||||
if (previousComponents().size() == 0)
|
||||
throw Poco::BugcheckException(Poco::format("%s: No previous component", name()));
|
||||
|
||||
auto pPrevious = previousComponents().first().cast<VideoComponent>();
|
||||
if (!pPrevious)
|
||||
throw Poco::BugcheckException(Poco::format("%s: First previous component '%s' convert to 'VideoComponent' FAIL",
|
||||
name(), previousComponents().first()->name()));
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
getEncodeResolution(pPrevious, width, height);
|
||||
_preprocessor.start(pPrevious->getWidth(), pPrevious->getHeight(), width, height);
|
||||
|
||||
hi_venc_chn_attr attr = {};
|
||||
|
||||
attr.venc_attr.max_pic_width = width;
|
||||
|
||||
attr.venc_attr.max_pic_height = height;
|
||||
|
||||
attr.venc_attr.pic_width = width;
|
||||
|
||||
attr.venc_attr.pic_height = height;
|
||||
|
||||
attr.venc_attr.buf_size =
|
||||
Util::Math::alignup(attr.venc_attr.max_pic_width * attr.venc_attr.max_pic_height * 3 / 2, 64);
|
||||
|
||||
attr.venc_attr.is_by_frame = HI_TRUE;
|
||||
|
||||
switch (getCodecID())
|
||||
{
|
||||
default:
|
||||
case Core::CodecID::H264:
|
||||
attr.venc_attr.type = HI_PT_H264;
|
||||
|
||||
switch (getCodecProfile())
|
||||
{
|
||||
case Core::CodecProfile::H264_BASELINE:
|
||||
attr.venc_attr.profile = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
case Core::CodecProfile::H264_MAIN:
|
||||
attr.venc_attr.profile = 1;
|
||||
break;
|
||||
|
||||
case Core::CodecProfile::H264_HIGH:
|
||||
attr.venc_attr.profile = 2;
|
||||
break;
|
||||
|
||||
case Core::CodecProfile::H264_SVC_T:
|
||||
attr.venc_attr.profile = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
attr.venc_attr.h264_attr.rcn_ref_share_buf_en = HI_FALSE;
|
||||
|
||||
attr.venc_attr.h264_attr.frame_buf_ratio = 100;
|
||||
break;
|
||||
|
||||
case Core::CodecID::H265:
|
||||
attr.venc_attr.type = HI_PT_H265;
|
||||
|
||||
switch (getCodecProfile())
|
||||
{
|
||||
default:
|
||||
case Core::CodecProfile::H265_MAIN:
|
||||
attr.venc_attr.profile = 0;
|
||||
break;
|
||||
|
||||
case Core::CodecProfile::H265_MAIN_10:
|
||||
attr.venc_attr.profile = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
attr.venc_attr.h265_attr.rcn_ref_share_buf_en = HI_FALSE;
|
||||
|
||||
attr.venc_attr.h265_attr.frame_buf_ratio = 100;
|
||||
}
|
||||
|
||||
setChnAttrRateControl(attr, getCodecID(), getBitrateControl(), getSuitableGOP(), getSuitableSFR(), getSuitableDFR(),
|
||||
getSuitableBitrate());
|
||||
setChnAttrGOPMode(attr, getGOPMode(), getSuitableGOP());
|
||||
|
||||
int rc = hi_mpi_venc_create_chn(channelID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Create channel FAIL: %#x", name(), (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_venc_reset_chn(channelID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Reset channel recv FAIL: %#x", name(), (uint32_t)rc), rc);
|
||||
|
||||
hi_venc_start_param param;
|
||||
|
||||
param.recv_pic_num = -1;
|
||||
rc = hi_mpi_venc_start_chn(channelID(), ¶m);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Start channel recv FAIL: %#x", name(), (uint32_t)rc), rc);
|
||||
|
||||
task().run(
|
||||
[this](std::atomic<bool>& isCancelled) -> void
|
||||
{
|
||||
while (!isCancelled)
|
||||
{
|
||||
try
|
||||
{
|
||||
postToNextComponents(sharedFromThis(), readPacket(1000), Core::MediaType::VIDEO);
|
||||
}
|
||||
catch (Poco::Exception& e)
|
||||
{
|
||||
logger().error("%s: %s", name(), e.displayText());
|
||||
Poco::Thread::sleep(1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void VideoEncoder::stop()
|
||||
{
|
||||
task().cancel();
|
||||
|
||||
hi_mpi_venc_stop_chn(channelID());
|
||||
hi_mpi_venc_reset_chn(channelID());
|
||||
hi_mpi_venc_destroy_chn(channelID());
|
||||
|
||||
_preprocessor.stop();
|
||||
}
|
||||
|
||||
void VideoEncoder::initialize()
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
getEncodeResolution(getPrevious(), width, height);
|
||||
|
||||
setWidth(width);
|
||||
setHeight(height);
|
||||
}
|
||||
|
||||
void VideoEncoder::deinitialize()
|
||||
{
|
||||
releaseCapabilityHandle();
|
||||
}
|
||||
|
||||
void VideoEncoder::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
if (!started())
|
||||
return;
|
||||
|
||||
if (names.exists(_CodecProfile) || names.exists(_Width) || names.exists(_Height) || names.exists(_FrameRate))
|
||||
{
|
||||
serialCodeManager().put(_Width, getWidth());
|
||||
serialCodeManager().put(_Height, getHeight());
|
||||
|
||||
stop();
|
||||
deinitialize();
|
||||
initialize();
|
||||
start();
|
||||
return;
|
||||
}
|
||||
|
||||
hi_venc_chn_attr attr;
|
||||
hi_mpi_venc_get_chn_attr(channelID(), &attr);
|
||||
if (names.exists(_GOPMode) || names.exists(_GOP) || names.exists(_BitrateControl) || names.exists(_Bitrate))
|
||||
{
|
||||
setChnAttrGOPMode(attr, getGOPMode(), getGOP());
|
||||
setChnAttrRateControl(attr, getCodecID(), getBitrateControl(), getSuitableGOP(), getSuitableSFR(),
|
||||
getSuitableDFR(), getSuitableBitrate());
|
||||
}
|
||||
hi_mpi_venc_set_chn_attr(channelID(), &attr);
|
||||
}
|
||||
|
||||
void VideoEncoder::onLink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
_preprocessor.doLink(pPrevious);
|
||||
_preprocessor.bind(*this);
|
||||
}
|
||||
|
||||
void VideoEncoder::onUnlink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
_preprocessor.doUnlink(pPrevious);
|
||||
_preprocessor.unbind(*this);
|
||||
}
|
||||
|
||||
void VideoEncoder::handlePreviousParameterChanged(const Poco::AutoPtr<Core::ParameterChangedNotification>& pNotication)
|
||||
{
|
||||
if (!started())
|
||||
return;
|
||||
|
||||
const auto& parameters = pNotication->parameters();
|
||||
auto pPrevious = getPrevious();
|
||||
if (parameters.exists(_Width) || parameters.exists(_Height))
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
getEncodeResolution(pPrevious, width, height);
|
||||
|
||||
if (getWidth() == width && getHeight() == height)
|
||||
{
|
||||
_preprocessor.stop();
|
||||
_preprocessor.start(pPrevious->getWidth(), pPrevious->getHeight(), width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
setWidth(width);
|
||||
setHeight(height);
|
||||
commit();
|
||||
}
|
||||
}
|
||||
|
||||
if (parameters.exists(_FrameRate))
|
||||
{
|
||||
hi_venc_chn_attr attr;
|
||||
hi_mpi_venc_get_chn_attr(channelID(), &attr);
|
||||
setChnAttrRateControl(attr, getCodecID(), getBitrateControl(), getSuitableGOP(), getSuitableSFR(),
|
||||
getSuitableDFR(), getSuitableBitrate());
|
||||
hi_mpi_venc_set_chn_attr(channelID(), &attr);
|
||||
}
|
||||
}
|
||||
|
||||
Core::VideoComponent::Ptr VideoEncoder::getPrevious()
|
||||
{
|
||||
auto pPrevious = previousComponents().first().cast<VideoComponent>();
|
||||
if (!pPrevious)
|
||||
throw Poco::BugcheckException(Poco::format("%s: First previous component '%s' convert to 'VideoComponent' FAIL",
|
||||
name(), previousComponents().first()->name()));
|
||||
|
||||
return pPrevious;
|
||||
}
|
||||
|
||||
int VideoEncoder::getSuitableGOP()
|
||||
{
|
||||
return Math::clamp(getGOP(), 1, 65535);
|
||||
}
|
||||
|
||||
int VideoEncoder::getSuitableSFR()
|
||||
{
|
||||
return Math::clamp(getPrevious()->getFrameRate(), HI_VENC_MIN_INPUT_FRAME_RATE, HI_VENC_MAX_INPUT_FRAME_RATE);
|
||||
}
|
||||
|
||||
int VideoEncoder::getSuitableDFR()
|
||||
{
|
||||
return Math::clamp(Math::min(getFrameRate(), getSuitableSFR()), HI_VENC_MIN_INPUT_FRAME_RATE,
|
||||
HI_VENC_MAX_INPUT_FRAME_RATE);
|
||||
;
|
||||
}
|
||||
|
||||
uint32_t VideoEncoder::getSuitableBitrate()
|
||||
{
|
||||
return Math::clamp(getBitrate() / 1000, (int64_t)HI_VENC_MIN_BITRATE, (int64_t)HI_VENC_MAX_BITRATE);
|
||||
}
|
||||
|
||||
void VideoEncoder::getEncodeResolution(Core::VideoComponent::Ptr pPrevious, uint32_t& width, uint32_t& height)
|
||||
{
|
||||
if (getAdaptable() && !pPrevious.isNull())
|
||||
{
|
||||
width = pPrevious->getWidth();
|
||||
height = pPrevious->getHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
width = getWidth();
|
||||
height = getHeight();
|
||||
}
|
||||
|
||||
width = Math::alignup(Math::clamp(width, (uint32_t)HI_VENC_H264_MIN_WIDTH, (uint32_t)HI_VENC_H264_MAX_WIDTH),
|
||||
MIN_ALIGN);
|
||||
height = Math::alignup(Math::clamp(height, (uint32_t)HI_VENC_H264_MIN_HEIGHT, (uint32_t)HI_VENC_H264_MAX_HEIGHT),
|
||||
MIN_ALIGN);
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
width = 1920;
|
||||
height = 1080;
|
||||
}
|
||||
}
|
||||
|
||||
Core::Packet::Ptr VideoEncoder::readPacket(uint32_t timeout)
|
||||
{
|
||||
static const int PACKET_DATA_SIZE_MAX = (1024 * 1024 * 2);
|
||||
|
||||
Core::Packet::Ptr pPacket = nullptr;
|
||||
|
||||
const long tvsec = timeout / 1000;
|
||||
const long tvusec = 0;
|
||||
|
||||
int fd = hi_mpi_venc_get_fd(channelID());
|
||||
while (true)
|
||||
{
|
||||
struct timeval tm = {
|
||||
.tv_sec = tvsec,
|
||||
.tv_usec = tvusec,
|
||||
};
|
||||
|
||||
fd_set read_fds;
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(fd, &read_fds);
|
||||
|
||||
int rc = select(fd + 1, &read_fds, NULL, NULL, &tm);
|
||||
if (rc < 0)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Read stream FAIL: %s", name(), std::string(strerror(rc))), rc);
|
||||
else if (0 == rc)
|
||||
throw Poco::TimeoutException(Poco::format("%s: Read encoder stream timeout!", name()), rc);
|
||||
|
||||
if (!FD_ISSET(fd, &read_fds))
|
||||
continue;
|
||||
|
||||
hi_venc_chn_status status;
|
||||
hi_mpi_venc_query_status(channelID(), &status);
|
||||
|
||||
hi_venc_stream stream;
|
||||
stream.pack = (hi_venc_pack*)malloc(sizeof(hi_venc_pack) * status.cur_packs);
|
||||
if (!stream.pack)
|
||||
continue;
|
||||
|
||||
stream.pack_cnt = status.cur_packs;
|
||||
rc = hi_mpi_venc_get_stream(channelID(), &stream, timeout);
|
||||
if (rc != HI_SUCCESS)
|
||||
{
|
||||
free(stream.pack);
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Get encoder stream FAIL: %#x", name(), (uint32_t)rc),
|
||||
rc);
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
uint8_t* pBuffer = new uint8_t[PACKET_DATA_SIZE_MAX];
|
||||
if (!pBuffer)
|
||||
{
|
||||
free(stream.pack);
|
||||
throw Poco::OutOfMemoryException(Poco::format("%s: Alloc memory for encoded data: FAIL", name()), 0);
|
||||
}
|
||||
|
||||
uint32_t length = 0;
|
||||
uint32_t flags = Core::Packet::FLAG_IS_VIDEO;
|
||||
for (uint32_t i = 0; i < stream.pack_cnt; i++)
|
||||
{
|
||||
hi_venc_pack* pack = &stream.pack[i];
|
||||
uint32_t chucksize = pack->len - pack->offset;
|
||||
if (chucksize < PACKET_DATA_SIZE_MAX - length)
|
||||
{
|
||||
memcpy(&pBuffer[length], pack->addr + pack->offset, chucksize);
|
||||
length += chucksize;
|
||||
}
|
||||
else
|
||||
logger().error("%s: Buffer size(%d) is insufficient to hold the encoded data!", PACKET_DATA_SIZE_MAX);
|
||||
|
||||
if (pack->is_frame_end)
|
||||
{
|
||||
switch (getCodecID())
|
||||
{
|
||||
default:
|
||||
case Core::CodecID::H264:
|
||||
if (stream.h264_info.ref_type == HI_VENC_BASE_IDR_SLICE)
|
||||
flags |= Core::Packet::FLAG_IS_KEY;
|
||||
break;
|
||||
|
||||
case Core::CodecID::H265:
|
||||
if (stream.h265_info.ref_type == HI_VENC_BASE_IDR_SLICE)
|
||||
flags |= Core::Packet::FLAG_IS_KEY;
|
||||
break;
|
||||
}
|
||||
|
||||
pPacket = new Core::Packet(serialCodeManager().code(), flags, pBuffer, length, pack->pts, pack->pts);
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = hi_mpi_venc_release_stream(channelID(), &stream);
|
||||
free(stream.pack);
|
||||
stream.pack = NULL;
|
||||
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
|
||||
return pPacket;
|
||||
}
|
||||
|
||||
void VideoEncoder::setChnAttrGOPMode(hi_venc_chn_attr& attr, const Core::GOPMode mode, int gop)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case Core::GOPMode::NORMAL_P:
|
||||
attr.gop_attr.gop_mode = HI_VENC_GOP_MODE_NORMAL_P;
|
||||
|
||||
attr.gop_attr.normal_p.ip_qp_delta = 2;
|
||||
break;
|
||||
|
||||
case Core::GOPMode::SMART_P:
|
||||
attr.gop_attr.gop_mode = HI_VENC_GOP_MODE_SMART_P;
|
||||
|
||||
attr.gop_attr.smart_p.bg_interval = gop;
|
||||
|
||||
attr.gop_attr.smart_p.bg_qp_delta = 4;
|
||||
|
||||
attr.gop_attr.smart_p.vi_qp_delta = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::InvalidArgumentException(
|
||||
Poco::format("%s: Invalid gop-mode: %s", name(), Core::gopModeToString(getGOPMode())), -1);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoEncoder::setChnAttrRateControl(hi_venc_chn_attr& attr, Core::CodecID codec, Core::BitrateControl bc, int gop,
|
||||
int sfr, int dfr, uint32_t bitrate)
|
||||
{
|
||||
logger().debug("%s: confiure: %s, %s, GOP:%d, sfr:%d, dfr:%d, %uKbps", name(), Core::codecIDToString(codec),
|
||||
Core::bitrateControlToString(bc), gop, sfr, dfr, bitrate);
|
||||
if (Core::CodecID::H264 == codec)
|
||||
{
|
||||
switch (bc)
|
||||
{
|
||||
case Core::BitrateControl::CBR:
|
||||
attr.rc_attr.rc_mode = HI_VENC_RC_MODE_H264_CBR;
|
||||
__set_cbr(attr.rc_attr.h264_cbr, gop, 1, sfr, dfr, bitrate);
|
||||
break;
|
||||
|
||||
case Core::BitrateControl::VBR:
|
||||
attr.rc_attr.rc_mode = HI_VENC_RC_MODE_H264_VBR;
|
||||
__set_vbr(attr.rc_attr.h264_vbr, gop, 1, sfr, dfr, bitrate);
|
||||
break;
|
||||
|
||||
case Core::BitrateControl::AVBR:
|
||||
attr.rc_attr.rc_mode = HI_VENC_RC_MODE_H264_AVBR;
|
||||
__set_avbr(attr.rc_attr.h264_avbr, gop, 1, sfr, dfr, bitrate);
|
||||
break;
|
||||
|
||||
case Core::BitrateControl::QVBR:
|
||||
attr.rc_attr.rc_mode = HI_VENC_RC_MODE_H264_QVBR;
|
||||
__set_qvbr(attr.rc_attr.h264_qvbr, gop, 1, sfr, dfr, bitrate);
|
||||
break;
|
||||
|
||||
case Core::BitrateControl::CVBR:
|
||||
case Core::BitrateControl::FIXQP:
|
||||
case Core::BitrateControl::QPMAP:
|
||||
default:
|
||||
throw Poco::NotImplementedException(Poco::format("%s: Not implemented H.264 bitrate-control: %s", name(),
|
||||
Core::bitrateControlToString(getBitrateControl())),
|
||||
-1);
|
||||
}
|
||||
}
|
||||
else if (Core::CodecID::H265 == codec)
|
||||
{
|
||||
switch (bc)
|
||||
{
|
||||
case Core::BitrateControl::CBR:
|
||||
attr.rc_attr.rc_mode = HI_VENC_RC_MODE_H265_CBR;
|
||||
__set_cbr(attr.rc_attr.h265_cbr, gop, 1, sfr, dfr, bitrate);
|
||||
break;
|
||||
|
||||
case Core::BitrateControl::VBR:
|
||||
attr.rc_attr.rc_mode = HI_VENC_RC_MODE_H265_VBR;
|
||||
__set_vbr(attr.rc_attr.h265_vbr, gop, 1, sfr, dfr, bitrate);
|
||||
break;
|
||||
|
||||
case Core::BitrateControl::AVBR:
|
||||
attr.rc_attr.rc_mode = HI_VENC_RC_MODE_H265_AVBR;
|
||||
__set_avbr(attr.rc_attr.h265_avbr, gop, 1, sfr, dfr, bitrate);
|
||||
break;
|
||||
|
||||
case Core::BitrateControl::QVBR:
|
||||
attr.rc_attr.rc_mode = HI_VENC_RC_MODE_H265_QVBR;
|
||||
__set_qvbr(attr.rc_attr.h265_qvbr, gop, 1, sfr, dfr, bitrate);
|
||||
break;
|
||||
|
||||
case Core::BitrateControl::CVBR:
|
||||
case Core::BitrateControl::FIXQP:
|
||||
case Core::BitrateControl::QPMAP:
|
||||
default:
|
||||
throw Poco::NotImplementedException(Poco::format("%s: Not implemented H.265 bitrate-control: %s", name(),
|
||||
Core::bitrateControlToString(getBitrateControl())),
|
||||
-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VideoEncoder::releaseCapabilityHandle()
|
||||
{
|
||||
}
|
||||
|
||||
void VideoEncoder::initModule()
|
||||
{
|
||||
hi_venc_mod_param param = {};
|
||||
|
||||
param.mod_type = HI_VENC_MOD_H264;
|
||||
param.h264_mod_param.one_stream_buf = 0;
|
||||
param.h264_mod_param.mini_buf_mode = 0;
|
||||
param.h264_mod_param.low_power_mode = 0;
|
||||
param.h264_mod_param.vb_src = HI_VB_SRC_PRIVATE;
|
||||
param.h264_mod_param.qp_hist_en = HI_FALSE;
|
||||
param.h264_mod_param.max_user_data_len = 1024;
|
||||
int rc = hi_mpi_venc_set_mod_param(¶m);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("MPP5::VENC: Set module H264 param FAIL: %u(%#x)", (uint32_t)rc, (uint32_t)rc));
|
||||
|
||||
param.mod_type = HI_VENC_MOD_H265;
|
||||
param.h265_mod_param.one_stream_buf = 0;
|
||||
param.h265_mod_param.mini_buf_mode = 0;
|
||||
param.h265_mod_param.low_power_mode = 0;
|
||||
param.h265_mod_param.vb_src = HI_VB_SRC_PRIVATE;
|
||||
param.h265_mod_param.qp_hist_en = HI_FALSE;
|
||||
param.h265_mod_param.max_user_data_len = 32768;
|
||||
rc = hi_mpi_venc_set_mod_param(¶m);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("MPP5::VENC: Set module H265 param FAIL: %u(%#x)", (uint32_t)rc, (uint32_t)rc));
|
||||
}
|
||||
|
||||
void VideoEncoder::deinitModule()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
91
video/hisi/mpp5/VideoEncoder.h
Normal file
91
video/hisi/mpp5/VideoEncoder.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#ifndef F3099295_0B78_4FE9_A07D_1748943D2805
|
||||
#define F3099295_0B78_4FE9_A07D_1748943D2805
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "MPPChannel.h"
|
||||
#include "../core/VideoEncoder.h"
|
||||
#include "../core/CodecCapabilityManager.h"
|
||||
#include "../../core/Notifications.h"
|
||||
#include "util/HandlesManager.h"
|
||||
#include <hi_mpi_venc.h>
|
||||
#include <hi_mpi_vpss.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class VideoEncoder: public MPPChannel, public Core::VideoEncoder
|
||||
{
|
||||
private:
|
||||
class Preprocessor: public MPPChannel
|
||||
{
|
||||
public:
|
||||
using Ptr = Poco::SharedPtr<Preprocessor>;
|
||||
|
||||
public:
|
||||
Preprocessor(const std::string& name, uint32_t id);
|
||||
~Preprocessor();
|
||||
|
||||
public:
|
||||
void start(uint32_t iwidth, uint32_t iheight, uint32_t owidth, uint32_t oheight);
|
||||
void stop();
|
||||
|
||||
uint32_t groupID() const;
|
||||
const std::string& name() const;
|
||||
|
||||
private:
|
||||
const std::string _name;
|
||||
};
|
||||
|
||||
public:
|
||||
VideoEncoder(Core::CodecID codecID);
|
||||
~VideoEncoder();
|
||||
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
void onLink(Core::Component::Ptr pPrevious) override;
|
||||
void onUnlink(Core::Component::Ptr pPrevious) override;
|
||||
|
||||
void handlePreviousParameterChanged(const Poco::AutoPtr<Core::ParameterChangedNotification>& pNotication);
|
||||
|
||||
Core::VideoComponent::Ptr getPrevious();
|
||||
int getSuitableGOP();
|
||||
int getSuitableSFR();
|
||||
int getSuitableDFR();
|
||||
uint32_t getSuitableBitrate();
|
||||
void getEncodeResolution(Core::VideoComponent::Ptr pPrevious, uint32_t& width, uint32_t& height);
|
||||
|
||||
void setChnAttrGOPMode(hi_venc_chn_attr& attr, Core::GOPMode mode, int gop);
|
||||
void setChnAttrRateControl(hi_venc_chn_attr& attr, Core::CodecID codec, Core::BitrateControl bc, int gop, int sfr,
|
||||
int dfr, uint32_t bitrate);
|
||||
Core::Packet::Ptr readPacket(uint32_t timeout);
|
||||
|
||||
void releaseCapabilityHandle();
|
||||
|
||||
private:
|
||||
Core::CodecCapabilityManager::Handle _handle;
|
||||
Preprocessor _preprocessor;
|
||||
|
||||
public:
|
||||
static void initModule();
|
||||
static void deinitModule();
|
||||
|
||||
private:
|
||||
static Core::CodecCapabilityManager _capabilityManager;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
194
video/hisi/mpp5/VideoFrame.cpp
Normal file
194
video/hisi/mpp5/VideoFrame.cpp
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "VideoFrame.h"
|
||||
#include "util/Math.h"
|
||||
#include <hi_mpi_sys.h>
|
||||
#include <hi_mpi_vdec.h>
|
||||
#include <Poco/Format.h>
|
||||
#include <Poco/FileStream.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CONSTANTS
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define POOL_ID 0
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
VideoFrame::VideoFrame(hi_video_frame_info* pInfo, uint32_t size, uint8_t* pVirAddr, uint32_t phyAddr, uint32_t handle,
|
||||
uint32_t chn)
|
||||
: _pInfo(pInfo), _size(size), _pVirAddr(pVirAddr), _phyAddr(phyAddr), _handle(handle), _chn(chn)
|
||||
{
|
||||
}
|
||||
|
||||
VideoFrame::~VideoFrame()
|
||||
{
|
||||
if (!_pInfo)
|
||||
return;
|
||||
|
||||
switch (_pInfo->mod_id)
|
||||
{
|
||||
case HI_ID_USER:
|
||||
if (_pVirAddr)
|
||||
{
|
||||
hi_mpi_sys_munmap(_pVirAddr, _size);
|
||||
hi_mpi_vb_release_blk(_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
case HI_ID_VDEC:
|
||||
hi_mpi_vdec_release_frame(_chn, _pInfo);
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout << Poco::format("error: VideoFrame: Unsupported mod id: %d", (int)_pInfo->mod_id) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
free(_pInfo);
|
||||
}
|
||||
|
||||
VideoFrame::Ptr VideoFrame::create(hi_pixel_format format, uint32_t width, uint32_t height, const uint8_t* pData)
|
||||
{
|
||||
uint32_t stride = Util::Math::alignup(width, 16);
|
||||
uint32_t imagesz, lumasz, chromasz;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420:
|
||||
case HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420:
|
||||
imagesz = stride * Util::Math::alignup(height, 16) * 3 / 2;
|
||||
lumasz = stride * height;
|
||||
chromasz = lumasz >> 1;
|
||||
break;
|
||||
|
||||
case HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422:
|
||||
case HI_PIXEL_FORMAT_YUV_SEMIPLANAR_422:
|
||||
imagesz = stride * Util::Math::alignup(height, 16) * 2;
|
||||
lumasz = stride * height;
|
||||
chromasz = lumasz;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::NotImplementedException("Unsupported pixel format");
|
||||
}
|
||||
|
||||
hi_vb_blk handle = hi_mpi_vb_get_blk(POOL_ID, imagesz, "anonymous");
|
||||
if (HI_VB_INVALID_HANDLE == handle)
|
||||
throw Poco::RuntimeException(
|
||||
Poco::format("VideoFrame: Failed to get VB block: %u bytes @POOL#%d", imagesz, (int)POOL_ID));
|
||||
|
||||
hi_phys_addr_t phyAddr = hi_mpi_vb_handle_to_phys_addr(handle);
|
||||
|
||||
if (!phyAddr)
|
||||
throw Poco::RuntimeException("VideoFrame: Failed to get VB block phys-addr");
|
||||
|
||||
uint8_t* pVirAddr = (uint8_t*)hi_mpi_sys_mmap(phyAddr, imagesz);
|
||||
if (!pVirAddr)
|
||||
throw Poco::RuntimeException("VideoFrame: Failed to map VB block");
|
||||
|
||||
hi_video_frame_info* pInfo = (hi_video_frame_info*)malloc(sizeof(hi_video_frame_info));
|
||||
if (!pInfo)
|
||||
throw Poco::OutOfMemoryException("VideoFrame: Failed to allocate frame info");
|
||||
|
||||
memset(pInfo, 0, sizeof(*pInfo));
|
||||
pInfo->mod_id = HI_ID_USER;
|
||||
pInfo->pool_id = POOL_ID;
|
||||
hi_video_frame* pVideoFrame = &pInfo->video_frame;
|
||||
|
||||
pVideoFrame->width = width;
|
||||
pVideoFrame->height = height;
|
||||
pVideoFrame->field = HI_VIDEO_FIELD_FRAME;
|
||||
pVideoFrame->pixel_format = (hi_pixel_format)format;
|
||||
pVideoFrame->video_format = HI_VIDEO_FORMAT_LINEAR;
|
||||
pVideoFrame->compress_mode = HI_COMPRESS_MODE_NONE;
|
||||
pVideoFrame->dynamic_range = HI_DYNAMIC_RANGE_SDR8;
|
||||
pVideoFrame->color_gamut = HI_COLOR_GAMUT_BT601;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420:
|
||||
case HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420:
|
||||
pVideoFrame->stride[0] = stride;
|
||||
pVideoFrame->stride[1] = stride;
|
||||
|
||||
pVideoFrame->phys_addr[0] = phyAddr;
|
||||
pVideoFrame->phys_addr[1] = (phyAddr + lumasz);
|
||||
|
||||
pVideoFrame->virt_addr[0] = (hi_void*)pVirAddr;
|
||||
pVideoFrame->virt_addr[1] = (hi_void*)(pVirAddr + lumasz);
|
||||
|
||||
pVideoFrame->time_ref = 0;
|
||||
pVideoFrame->pts = 0;
|
||||
pVideoFrame->frame_flag = 0;
|
||||
|
||||
memcpy(pVideoFrame->virt_addr[0], pData, lumasz);
|
||||
memcpy(pVideoFrame->virt_addr[1], pData + lumasz, chromasz);
|
||||
break;
|
||||
|
||||
case HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422:
|
||||
case HI_PIXEL_FORMAT_YUV_SEMIPLANAR_422:
|
||||
pVideoFrame->stride[0] = stride;
|
||||
pVideoFrame->stride[1] = stride;
|
||||
|
||||
pVideoFrame->phys_addr[0] = phyAddr;
|
||||
pVideoFrame->phys_addr[1] = (phyAddr + lumasz);
|
||||
|
||||
pVideoFrame->virt_addr[0] = (hi_void*)pVirAddr;
|
||||
pVideoFrame->virt_addr[1] = (hi_void*)(pVirAddr + lumasz);
|
||||
|
||||
pVideoFrame->time_ref = 0;
|
||||
pVideoFrame->pts = 0;
|
||||
pVideoFrame->frame_flag = 0;
|
||||
|
||||
memcpy(pVideoFrame->virt_addr[0], pData, lumasz);
|
||||
memcpy(pVideoFrame->virt_addr[1], pData + lumasz, chromasz);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::NotImplementedException("VideoFrame: Unsupported pixel format");
|
||||
}
|
||||
|
||||
return new VideoFrame(pInfo, imagesz, pVirAddr, phyAddr, handle, 0);
|
||||
}
|
||||
|
||||
VideoFrame::Ptr VideoFrame::create(hi_pixel_format format, uint32_t width, uint32_t height, const std::string& path)
|
||||
{
|
||||
uint32_t size;
|
||||
Poco::SharedPtr<uint8_t> pData;
|
||||
|
||||
try
|
||||
{
|
||||
Poco::FileInputStream fist(path);
|
||||
|
||||
fist.seekg(0, fist.end);
|
||||
size = fist.tellg();
|
||||
fist.seekg(0, fist.beg);
|
||||
|
||||
pData = new uint8_t[size];
|
||||
fist.read((char*)pData.get(), size);
|
||||
fist.close();
|
||||
}
|
||||
catch (Poco::Exception& e)
|
||||
{
|
||||
size = width * height * 3;
|
||||
pData = new uint8_t[size];
|
||||
}
|
||||
|
||||
return create(format, width, height, pData);
|
||||
}
|
||||
}
|
||||
}
|
||||
73
video/hisi/mpp5/VideoFrame.h
Normal file
73
video/hisi/mpp5/VideoFrame.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef B9B55BBA_D4EA_459D_AB14_BEB06E1FB74A
|
||||
#define B9B55BBA_D4EA_459D_AB14_BEB06E1FB74A
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include <hi_mpi_ive.h>
|
||||
#include <hi_mpi_vb.h>
|
||||
#include <Poco/SharedPtr.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class VideoFrame
|
||||
{
|
||||
public:
|
||||
using Ptr = Poco::SharedPtr<VideoFrame>;
|
||||
|
||||
private:
|
||||
VideoFrame(hi_video_frame_info* pInfo, uint32_t size, uint8_t* pVirAddr, uint32_t phyAddr, uint32_t handle,
|
||||
uint32_t chn);
|
||||
|
||||
public:
|
||||
~VideoFrame();
|
||||
|
||||
public:
|
||||
const hi_video_frame_info* info() const;
|
||||
const uint32_t width() const;
|
||||
const uint32_t height() const;
|
||||
const hi_pixel_format pixelFormat() const;
|
||||
|
||||
private:
|
||||
hi_video_frame_info* _pInfo;
|
||||
uint32_t _size;
|
||||
uint8_t* _pVirAddr;
|
||||
uint32_t _phyAddr;
|
||||
uint32_t _handle;
|
||||
uint32_t _chn;
|
||||
|
||||
public:
|
||||
static Ptr create(hi_pixel_format format, uint32_t width, uint32_t height, const uint8_t* pData);
|
||||
static Ptr create(hi_pixel_format format, uint32_t width, uint32_t height, const std::string& path);
|
||||
};
|
||||
|
||||
inline const hi_video_frame_info* VideoFrame::info() const
|
||||
{
|
||||
return _pInfo;
|
||||
}
|
||||
|
||||
inline const uint32_t VideoFrame::width() const
|
||||
{
|
||||
return _pInfo->video_frame.width;
|
||||
}
|
||||
|
||||
inline const uint32_t VideoFrame::height() const
|
||||
{
|
||||
return _pInfo->video_frame.height;
|
||||
}
|
||||
|
||||
inline const hi_pixel_format VideoFrame::pixelFormat() const
|
||||
{
|
||||
return _pInfo->video_frame.pixel_format;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
202
video/hisi/mpp5/VideoInput.cpp
Normal file
202
video/hisi/mpp5/VideoInput.cpp
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "VideoInput.h"
|
||||
#include "IVE.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "../../core/Notifications.h"
|
||||
#include "Application.h"
|
||||
#include "Logger.h"
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
VideoFrame::Ptr VideoInput::_pUserVideoFrame = nullptr;
|
||||
|
||||
VideoInput::VideoInput(uint32_t deviceID, uint32_t channelID, bool dataReverseEnable)
|
||||
: Core::VideoComponent(Poco::format("MPP5::VI#%u", deviceID)), MPPChannel((uint32_t)HI_ID_VI, deviceID, channelID),
|
||||
_dataReverseEnable(dataReverseEnable), _channelId(deviceID == 2 ? 0 : 1)
|
||||
{
|
||||
setWidth(1920);
|
||||
setHeight(1080);
|
||||
setFrameRate(30);
|
||||
|
||||
setVideoScanMode(Core::VideoScanMode::PROGRESSIVE);
|
||||
}
|
||||
|
||||
VideoInput::~VideoInput()
|
||||
{
|
||||
}
|
||||
|
||||
void VideoInput::start()
|
||||
{
|
||||
uint32_t width = getWidth();
|
||||
uint32_t height = getHeight();
|
||||
|
||||
hi_vi_dev_attr devAttr;
|
||||
devAttr.intf_mode = HI_VI_MODE_BT1120_STANDARD;
|
||||
devAttr.work_mode = HI_VI_WORK_MODE_MULTIPLEX_1;
|
||||
devAttr.component_mask[0] = 0x00000ff0;
|
||||
devAttr.component_mask[1] = 0x000ff000;
|
||||
devAttr.clk_edge = HI_VI_CLK_EDGE_SINGLE_UP;
|
||||
devAttr.data_seq = HI_VI_IN_DATA_VUVU;
|
||||
|
||||
devAttr.sync_cfg.vsync = HI_VI_VSYNC_PULSE;
|
||||
devAttr.sync_cfg.vsync_neg = HI_VI_VSYNC_NEG_LOW;
|
||||
devAttr.sync_cfg.hsync = HI_VI_HSYNC_VALID_SIG;
|
||||
devAttr.sync_cfg.hsync_neg = HI_VI_HSYNC_NEG_HIGH;
|
||||
devAttr.sync_cfg.vsync_valid = HI_VI_VSYNC_VALID_SIG;
|
||||
devAttr.sync_cfg.vsync_valid_neg = HI_VI_VSYNC_VALID_NEG_HIGH;
|
||||
|
||||
devAttr.sync_cfg.timing_blank.hsync_hfb = 0;
|
||||
devAttr.sync_cfg.timing_blank.hsync_act = width;
|
||||
devAttr.sync_cfg.timing_blank.hsync_hbb = 0;
|
||||
devAttr.sync_cfg.timing_blank.vsync_vfb = 0;
|
||||
devAttr.sync_cfg.timing_blank.vsync_vact = height;
|
||||
devAttr.sync_cfg.timing_blank.vsync_vbb = 0;
|
||||
devAttr.sync_cfg.timing_blank.vsync_vbfb = 0;
|
||||
devAttr.sync_cfg.timing_blank.vsync_vbact = 0;
|
||||
devAttr.sync_cfg.timing_blank.vsync_vbbb = 0;
|
||||
|
||||
devAttr.data_reverse_en = (hi_bool)_dataReverseEnable;
|
||||
devAttr.mixed_capture_en = HI_FALSE;
|
||||
|
||||
auto rc = hi_mpi_vi_set_dev_attr(deviceID(), &devAttr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Set attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vi_enable_dev(deviceID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Enable FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
hi_vi_chn_attr chnAttr;
|
||||
chnAttr.capture_rect.x = 0;
|
||||
chnAttr.capture_rect.y = 0;
|
||||
chnAttr.capture_rect.width = width;
|
||||
chnAttr.capture_rect.height = height;
|
||||
chnAttr.dst_size.width = width;
|
||||
chnAttr.dst_size.height = height;
|
||||
chnAttr.capture_select = HI_VI_CAPTURE_SELECT_BOTH;
|
||||
chnAttr.scan_mode = getVIScanMode();
|
||||
chnAttr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
|
||||
chnAttr.mirror_en = HI_FALSE;
|
||||
chnAttr.flip_en = HI_FALSE;
|
||||
chnAttr.compress_mode = HI_COMPRESS_MODE_NONE;
|
||||
chnAttr.src_frame_rate = -1;
|
||||
chnAttr.dst_frame_rate = -1;
|
||||
|
||||
auto channel = channelID();
|
||||
rc = hi_mpi_vi_set_chn_attr(channel, &chnAttr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Configure channel FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vi_set_frame_depth(channel, 4);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Configure frame depth FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vi_enable_chn(channel);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Enable channel FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
enableUserPic(getSignalLost());
|
||||
}
|
||||
|
||||
void VideoInput::stop()
|
||||
{
|
||||
enableUserPic(false);
|
||||
hi_mpi_vi_disable_chn(channelID());
|
||||
hi_mpi_vi_disable_dev(deviceID());
|
||||
}
|
||||
|
||||
void VideoInput::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
if (!started())
|
||||
return;
|
||||
|
||||
notifyNextComponents(sharedFromThis(), new Core::ParameterChangedNotification(names));
|
||||
|
||||
if (names.exists(_Width) || names.exists(_Height))
|
||||
{
|
||||
stop();
|
||||
start();
|
||||
return;
|
||||
}
|
||||
|
||||
if (names.exists(_VideoScanMode))
|
||||
{
|
||||
hi_vi_chn_attr attr;
|
||||
hi_mpi_vi_get_chn_attr(channelID(), &attr);
|
||||
attr.scan_mode = getVIScanMode();
|
||||
int rc = hi_mpi_vi_set_chn_attr(channelID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Configure channel FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
if (names.exists(_SignalLost))
|
||||
enableUserPic(getSignalLost());
|
||||
}
|
||||
|
||||
uint32_t VideoInput::traffic()
|
||||
{
|
||||
hi_vi_chn_status s;
|
||||
return hi_mpi_vi_query(channelID(), &s) == HI_SUCCESS ? s.interrupt_cnt : 0;
|
||||
}
|
||||
|
||||
void VideoInput::enableUserPic(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
hi_mpi_vi_enable_user_pic(channelID());
|
||||
else
|
||||
hi_mpi_vi_disable_user_pic(channelID());
|
||||
}
|
||||
|
||||
hi_vi_scan_mode VideoInput::getVIScanMode()
|
||||
{
|
||||
return getVideoScanMode() == Core::VideoScanMode::PROGRESSIVE ? HI_VI_SCAN_PROGRESSIVE : HI_VI_SCAN_INTERLACED;
|
||||
}
|
||||
|
||||
void VideoInput::initModule()
|
||||
{
|
||||
hi_vi_mod_param param;
|
||||
hi_mpi_vi_get_mod_param(¶m);
|
||||
param.yc_reverse = 0;
|
||||
hi_mpi_vi_set_mod_param(¶m);
|
||||
|
||||
if (!_pUserVideoFrame)
|
||||
_pUserVideoFrame =
|
||||
VideoFrame::create(NO_SIGNAL_YUV_FORMAT, NO_SIGNAL_YUV_WIDTH, NO_SIGNAL_YUV_HEIGHT, NO_SIGNAL_YUV_PATH);
|
||||
|
||||
hi_vi_user_pic_attr attr = {};
|
||||
|
||||
attr.pub_en = HI_TRUE;
|
||||
attr.user_pic_mode = HI_VI_USER_PIC_MODE_PIC;
|
||||
attr.user_pic_info.user_pic_frame_info.mod_id = HI_ID_VI;
|
||||
attr.user_pic_info.user_pic_frame_info.pool_id = 0;
|
||||
attr.user_pic_info.user_pic_frame_info = *_pUserVideoFrame->info();
|
||||
int rc = hi_mpi_vi_set_user_pic(0, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("MPP::VI: Set user pic FAIL: %d(%#x)", rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
void VideoInput::deinitModule()
|
||||
{
|
||||
_pUserVideoFrame.reset();
|
||||
}
|
||||
|
||||
void VideoInput::reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
55
video/hisi/mpp5/VideoInput.h
Normal file
55
video/hisi/mpp5/VideoInput.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef FA05C272_A837_4EE6_A95D_55486BEA1F99
|
||||
#define FA05C272_A837_4EE6_A95D_55486BEA1F99
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "../../core/VideoComponent.h"
|
||||
#include "MPPChannel.h"
|
||||
#include "VideoFrame.h"
|
||||
#include <hi_mpi_vi.h>
|
||||
#include "util/Broadcast.h"
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class VideoInput: public Core::VideoComponent, public MPPChannel
|
||||
{
|
||||
public:
|
||||
using Ptr = Poco::AutoPtr<VideoInput>;
|
||||
|
||||
public:
|
||||
VideoInput(uint32_t deviceID, uint32_t channelID, bool dataReverseEnable);
|
||||
~VideoInput();
|
||||
void reset() override;
|
||||
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
uint32_t traffic() override;
|
||||
|
||||
void enableUserPic(bool enable);
|
||||
hi_vi_scan_mode getVIScanMode();
|
||||
|
||||
private:
|
||||
bool _dataReverseEnable;
|
||||
const uint32_t _channelId;
|
||||
|
||||
public:
|
||||
static void initModule();
|
||||
static void deinitModule();
|
||||
|
||||
private:
|
||||
static VideoFrame::Ptr _pUserVideoFrame;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
295
video/hisi/mpp5/VideoMixer.cpp
Normal file
295
video/hisi/mpp5/VideoMixer.cpp
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "VideoMixer.h"
|
||||
#include "util/Math.h"
|
||||
#include <hi_mpi_vo.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CONSTANTS
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#define WIDTH 1920
|
||||
#define HEIGHT 1080
|
||||
#define FRAMTE_RATE 60
|
||||
|
||||
#define VO_DEVICE_ID 1
|
||||
|
||||
#define VIDEO_LAYER_ID 1
|
||||
|
||||
#define VO_WBC_ID 0
|
||||
|
||||
#define VO_MAX_CHN_NUM (HI_VO_MAX_CHN_NUM - 1)
|
||||
#define VO_CHN_PLACEHOLDER_ID (VO_MAX_CHN_NUM - 1)
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
VideoMixer::Channel::Channel(VideoMixer::Ptr pMixer, uint32_t id)
|
||||
: MPPChannel((uint32_t)HI_ID_VO, VIDEO_LAYER_ID, id), Core::VideoMixer::Channel("MPP5::VHD1", pMixer, id)
|
||||
{
|
||||
}
|
||||
|
||||
VideoMixer::Channel::~Channel()
|
||||
{
|
||||
}
|
||||
|
||||
void VideoMixer::Channel::start()
|
||||
{
|
||||
if (mixer().cast<VideoMixer>()->started())
|
||||
activate();
|
||||
}
|
||||
|
||||
void VideoMixer::Channel::stop()
|
||||
{
|
||||
if (getActivated())
|
||||
deactivate();
|
||||
}
|
||||
|
||||
void VideoMixer::Channel::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
Core::VideoMixer::Channel::onConfigChanged(names);
|
||||
|
||||
if (!started())
|
||||
return;
|
||||
|
||||
if (names.exists(_Attach))
|
||||
{
|
||||
if (!getAttach())
|
||||
deactivate();
|
||||
else if (mixer().cast<VideoMixer>()->started())
|
||||
activate();
|
||||
}
|
||||
|
||||
if ((names.exists(_Region) || names.exists(_ZOrder)) && getActivated())
|
||||
configureChannel();
|
||||
}
|
||||
|
||||
void VideoMixer::Channel::onLink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
MPPChannel::doLink(pPrevious);
|
||||
}
|
||||
|
||||
void VideoMixer::Channel::onUnlink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
MPPChannel::doUnlink(pPrevious);
|
||||
}
|
||||
|
||||
void VideoMixer::Channel::activate()
|
||||
{
|
||||
configureChannel();
|
||||
|
||||
int rc = hi_mpi_vo_enable_chn(VIDEO_LAYER_ID, channelID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: enable FAIL: %d(%#x)", mixer()->name() + "/" + name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
setActivated(true);
|
||||
}
|
||||
|
||||
void VideoMixer::Channel::deactivate()
|
||||
{
|
||||
hi_mpi_vo_disable_chn(VIDEO_LAYER_ID, channelID());
|
||||
setActivated(false);
|
||||
}
|
||||
|
||||
void VideoMixer::Channel::configureChannel()
|
||||
{
|
||||
const auto region = getRegion();
|
||||
hi_vo_chn_attr attr;
|
||||
|
||||
attr.priority = ::Util::Math::clamp(getZOrder(), 0, VO_MAX_CHN_NUM - 2) + 1;
|
||||
|
||||
attr.rect.x =
|
||||
::Util::Math::aligndown(::Util::Math::clamp(static_cast<int>(std::round(region.x * WIDTH)), 0, WIDTH - 32), 2);
|
||||
attr.rect.y = ::Util::Math::aligndown(
|
||||
::Util::Math::clamp(static_cast<int>(std::round(region.y * HEIGHT)), 0, HEIGHT - 32), 2);
|
||||
|
||||
attr.rect.width = ::Util::Math::aligndown(
|
||||
::Util::Math::clamp(static_cast<int>(std::round(region.width * WIDTH)), 32, WIDTH - attr.rect.x), 2);
|
||||
attr.rect.height = ::Util::Math::aligndown(
|
||||
::Util::Math::clamp(static_cast<int>(std::round(region.height * HEIGHT)), 32, HEIGHT - attr.rect.y), 2);
|
||||
;
|
||||
attr.deflicker_en = HI_FALSE;
|
||||
int rc = hi_mpi_vo_set_chn_attr(VIDEO_LAYER_ID, channelID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: set chn attr FAIL: %d(%#x)", mixer()->name() + "/" + name(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
VideoMixer::VideoMixer(const std::string& name)
|
||||
: MPPChannel((uint32_t)HI_ID_VO, VO_DEVICE_ID, 0), Core::VideoMixer(Poco::format("%s(MPP5::VO::DHD1)", name))
|
||||
{
|
||||
setWidth(WIDTH);
|
||||
setHeight(HEIGHT);
|
||||
setFrameRate(FRAMTE_RATE);
|
||||
setSignalLost(false);
|
||||
}
|
||||
|
||||
VideoMixer::~VideoMixer()
|
||||
{
|
||||
}
|
||||
|
||||
void VideoMixer::start()
|
||||
{
|
||||
int rc = hi_mpi_vo_enable(deviceID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: enable VO FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
{
|
||||
hi_vo_video_layer_attr attr;
|
||||
|
||||
attr.display_rect.x = 0;
|
||||
attr.display_rect.y = 0;
|
||||
attr.display_rect.width = WIDTH;
|
||||
attr.display_rect.height = HEIGHT;
|
||||
attr.img_size.width = WIDTH;
|
||||
attr.img_size.height = HEIGHT;
|
||||
attr.display_frame_rate = FRAMTE_RATE;
|
||||
attr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
|
||||
|
||||
attr.double_frame_en = HI_FALSE;
|
||||
attr.cluster_mode_en = HI_FALSE;
|
||||
attr.dst_dynamic_range = HI_DYNAMIC_RANGE_SDR8;
|
||||
attr.display_buf_len = 4;
|
||||
|
||||
attr.partition_mode = HI_VO_PARTITION_MODE_SINGLE;
|
||||
attr.compress_mode = HI_COMPRESS_MODE_NONE;
|
||||
rc = hi_mpi_vo_set_video_layer_attr(VIDEO_LAYER_ID, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: set video layer attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vo_enable_video_layer(VIDEO_LAYER_ID);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: enable video layer FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
{
|
||||
hi_vo_wbc_src src;
|
||||
src.src_type = HI_VO_WBC_SRC_VIDEO;
|
||||
|
||||
src.src_id = VIDEO_LAYER_ID;
|
||||
rc = hi_mpi_vo_set_wbc_src(VO_WBC_ID, &src);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: set WBC src FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
rc = hi_mpi_vo_set_wbc_mode(VO_WBC_ID, HI_VO_WBC_MODE_NORM);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: set WBC mode FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
hi_vo_wbc_attr attr;
|
||||
attr.target_size.width = WIDTH;
|
||||
attr.target_size.height = HEIGHT;
|
||||
attr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
|
||||
attr.frame_rate = -1;
|
||||
attr.dynamic_range = HI_DYNAMIC_RANGE_SDR8;
|
||||
attr.compress_mode = HI_COMPRESS_MODE_NONE;
|
||||
|
||||
rc = hi_mpi_vo_set_wbc_attr(VO_WBC_ID, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: set WBC attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
rc = hi_mpi_vo_enable_wbc(VO_WBC_ID);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: enable WBC FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
}
|
||||
|
||||
foreachChannel<Channel>(
|
||||
[](Channel::Ptr pChannel) -> void
|
||||
{
|
||||
if (pChannel->getAttach())
|
||||
pChannel->activate();
|
||||
});
|
||||
|
||||
{
|
||||
hi_vo_chn_attr attr;
|
||||
attr.priority = 0;
|
||||
attr.rect.x = 0;
|
||||
attr.rect.y = 0;
|
||||
attr.rect.width = 32;
|
||||
attr.rect.height = 32;
|
||||
attr.deflicker_en = HI_FALSE;
|
||||
hi_mpi_vo_set_chn_attr(VIDEO_LAYER_ID, VO_CHN_PLACEHOLDER_ID, &attr);
|
||||
hi_mpi_vo_enable_chn(VIDEO_LAYER_ID, VO_CHN_PLACEHOLDER_ID);
|
||||
}
|
||||
|
||||
Core::VideoMixer::start();
|
||||
}
|
||||
|
||||
void VideoMixer::stop()
|
||||
{
|
||||
hi_mpi_vo_disable_chn(VIDEO_LAYER_ID, VO_CHN_PLACEHOLDER_ID);
|
||||
foreachChannel<Channel>(
|
||||
[this](Channel::Ptr pChannel) -> void
|
||||
{
|
||||
if (pChannel->getActivated())
|
||||
pChannel->deactivate();
|
||||
});
|
||||
|
||||
Core::VideoMixer::stop();
|
||||
int rc = hi_mpi_vo_disable_wbc(VO_WBC_ID);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: disable WBC FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vo_disable_video_layer(VIDEO_LAYER_ID);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: disable video layer FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
rc = hi_mpi_vo_disable(VO_DEVICE_ID);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: disable VO FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
void VideoMixer::initialize()
|
||||
{
|
||||
hi_vo_pub_attr attr;
|
||||
attr.bg_color = 0x000000;
|
||||
attr.intf_type = HI_VO_INTF_BT1120;
|
||||
attr.intf_sync = HI_VO_OUT_1080P60;
|
||||
int rc = hi_mpi_vo_set_pub_attr(deviceID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: set-pub FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
void VideoMixer::deinitialize()
|
||||
{
|
||||
}
|
||||
|
||||
void VideoMixer::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
}
|
||||
|
||||
Core::VideoMixer::Channel::Ptr VideoMixer::createChannel(uint32_t id)
|
||||
{
|
||||
if (id >= VO_CHN_PLACEHOLDER_ID)
|
||||
throw Poco::InvalidArgumentException(
|
||||
Poco::format("%s: channel id %u overrage: [0,%u]", name(), id, (uint32_t)(VO_CHN_PLACEHOLDER_ID - 1)),
|
||||
-EINVAL);
|
||||
|
||||
return new Channel(Ptr(this, true), id);
|
||||
}
|
||||
}
|
||||
}
|
||||
68
video/hisi/mpp5/VideoMixer.h
Normal file
68
video/hisi/mpp5/VideoMixer.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#ifndef B351F133_EBBC_42F5_9C48_5BA22D16BB53
|
||||
#define B351F133_EBBC_42F5_9C48_5BA22D16BB53
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "MPPChannel.h"
|
||||
#include "../../core/VideoMixer.h"
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class VideoMixer: public MPPChannel, public Core::VideoMixer
|
||||
{
|
||||
public:
|
||||
class Channel: public MPPChannel, public Core::VideoMixer::Channel
|
||||
{
|
||||
public:
|
||||
using Ptr = Poco::AutoPtr<Channel>;
|
||||
|
||||
protected:
|
||||
Channel(VideoMixer::Ptr, uint32_t id);
|
||||
|
||||
public:
|
||||
~Channel();
|
||||
|
||||
protected:
|
||||
virtual void start() override;
|
||||
virtual void stop() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
void onLink(Core::Component::Ptr pPrevious) override;
|
||||
void onUnlink(Core::Component::Ptr pPrevious) override;
|
||||
|
||||
void activate();
|
||||
void deactivate();
|
||||
|
||||
PROPERTY_DECLARE(Activated, bool, false, protected, protected)
|
||||
|
||||
void configureChannel();
|
||||
|
||||
friend class VideoMixer;
|
||||
};
|
||||
|
||||
public:
|
||||
VideoMixer(const std::string& name);
|
||||
~VideoMixer();
|
||||
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
|
||||
Core::VideoMixer::Channel::Ptr createChannel(uint32_t id) override;
|
||||
|
||||
friend class Channel;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
317
video/hisi/mpp5/VideoOverlay.cpp
Normal file
317
video/hisi/mpp5/VideoOverlay.cpp
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "VideoOverlay.h"
|
||||
#include "MPPChannel.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "util/Math.h"
|
||||
#include "Logger.h"
|
||||
#include <hi_mpi_tde.h>
|
||||
#include <hi_mpi_sys.h>
|
||||
#include <hi_mpi_vb.h>
|
||||
#include <Poco/Exception.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
VideoOverlay::VideoOverlay(Core::VideoOverlayType type, const std::string& name, const Core::Rect& region)
|
||||
: Core::VideoOverlay(type, name, region), _handle(ResourceManager::allocRGNHandle()), _imagePhyAddr(0),
|
||||
_pImageVirAddr(nullptr)
|
||||
{
|
||||
hi_rgn_attr attr = {};
|
||||
switch (type)
|
||||
{
|
||||
case Core::VideoOverlayType::CANVAS:
|
||||
attr.type = HI_RGN_OVERLAY;
|
||||
attr.attr.overlay.pixel_format = HI_PIXEL_FORMAT_ARGB_8888;
|
||||
_bytesPerPixel = 4;
|
||||
attr.attr.overlay.size.width = ::Util::Math::alignup(region.width, 2);
|
||||
attr.attr.overlay.size.height = ::Util::Math::alignup(region.height, 2);
|
||||
attr.attr.overlay.bg_color = 0;
|
||||
attr.attr.overlay.canvas_num = 2;
|
||||
break;
|
||||
|
||||
case Core::VideoOverlayType::MOSAIC:
|
||||
attr.type = HI_RGN_MOSAIC;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::LogicException(name + ": Unimplemented type: " + std::to_string((int)type));
|
||||
}
|
||||
|
||||
int rc = hi_mpi_rgn_create(_handle, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidArgumentException(Poco::format("%s: Create FAIL: %#x", name, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
VideoOverlay::~VideoOverlay()
|
||||
{
|
||||
_timer.cancel(true);
|
||||
if (_pImageVirAddr != nullptr && _imagePhyAddr != 0)
|
||||
hi_mpi_sys_mmz_free(_imagePhyAddr, _pImageVirAddr);
|
||||
|
||||
Core::VideoComponent::Ptr o = target();
|
||||
auto chn = dynamic_cast<MPPChannel*>(o.get())->raw();
|
||||
hi_mpi_rgn_detach_from_chn(_handle, &chn);
|
||||
hi_mpi_rgn_destroy(_handle);
|
||||
ResourceManager::freeRGNHandle(_handle);
|
||||
}
|
||||
|
||||
void VideoOverlay::render(Core::Image::Ptr pImage)
|
||||
{
|
||||
hi_rgn_canvas_info info;
|
||||
hi_mpi_rgn_get_canvas_info(_handle, &info);
|
||||
|
||||
uint32_t height = ::Util::Math::min((uint32_t)pImage->height(), (uint32_t)region().height);
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
{
|
||||
int i = 0;
|
||||
Core::Color color;
|
||||
uint8_t* pLine = (uint8_t*)info.virt_addr + y * info.stride;
|
||||
cimg_forX(*pImage, x)
|
||||
{
|
||||
if (x >= region().width)
|
||||
continue;
|
||||
|
||||
pImage->getPixel(x, y, color);
|
||||
color.toARGB8888Pixel(&pLine[i]);
|
||||
i += _bytesPerPixel;
|
||||
}
|
||||
}
|
||||
hi_mpi_rgn_update_canvas(_handle);
|
||||
}
|
||||
|
||||
void VideoOverlay::scrollRender(Core::Image::Ptr pImage, int hscroll)
|
||||
{
|
||||
const int W = (int)region().width;
|
||||
const int H = (int)::Util::Math::min((uint32_t)pImage->height(), (uint32_t)region().height);
|
||||
const int textWidth = (int)pImage->width();
|
||||
|
||||
const int winW = (int)::Util::Math::min((uint32_t)W, 4096u);
|
||||
const int period = 2 * W + textWidth;
|
||||
|
||||
const uint32_t stride = ::Util::Math::alignup((uint32_t)winW * _bytesPerPixel, 8);
|
||||
int rc = hi_mpi_sys_mmz_alloc(&_imagePhyAddr, (void**)&_pImageVirAddr, nullptr, nullptr, (uint32_t)H * stride);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::OutOfMemoryException(Poco::format("%s: Alloc MMZ FAIL: %#x", name(), (uint32_t)rc), rc);
|
||||
|
||||
_pTextImage = pImage;
|
||||
_textWidth = textWidth;
|
||||
_winW = winW;
|
||||
_winH = H;
|
||||
_stride = stride;
|
||||
_period = period;
|
||||
|
||||
if (hscroll > 0)
|
||||
_progressX = 0;
|
||||
else
|
||||
_progressX = period - W;
|
||||
|
||||
const int movePixels = hscroll;
|
||||
const long interval = 30;
|
||||
_timer.schedule(Poco::Util::Timer::func(
|
||||
[this, W, movePixels]()
|
||||
{
|
||||
const int H = _winH;
|
||||
const int winW = _winW;
|
||||
const int textW = _textWidth;
|
||||
const uint32_t stride = _stride;
|
||||
const int period = _period;
|
||||
|
||||
::memset(_pImageVirAddr, 0, (uint32_t)H * stride);
|
||||
|
||||
int startStrip = (_progressX > W) ? _progressX : W;
|
||||
int endStrip = ((_progressX + winW) < (W + textW)) ? (_progressX + winW) : (W + textW);
|
||||
if (startStrip < endStrip)
|
||||
{
|
||||
int textStart = startStrip - W;
|
||||
int winStart = startStrip - _progressX;
|
||||
int count = endStrip - startStrip;
|
||||
for (int y = 0; y < H; y++)
|
||||
{
|
||||
uint8_t* pWin =
|
||||
_pImageVirAddr + (uint32_t)y * stride + (uint32_t)winStart * _bytesPerPixel;
|
||||
Core::Color color;
|
||||
for (int x = 0; x < count; x++)
|
||||
{
|
||||
_pTextImage->getPixel(textStart + x, y, color);
|
||||
color.toARGB8888Pixel(&pWin[x * (int)_bytesPerPixel]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hi_tde_surface srcSurface = {};
|
||||
srcSurface.phys_addr = _imagePhyAddr;
|
||||
srcSurface.color_format = HI_TDE_COLOR_FORMAT_ARGB8888;
|
||||
srcSurface.height = (uint32_t)H;
|
||||
srcSurface.width = (uint32_t)winW;
|
||||
srcSurface.stride = stride;
|
||||
srcSurface.is_ycbcr_clut = HI_FALSE;
|
||||
srcSurface.alpha_max_is_255 = HI_TRUE;
|
||||
srcSurface.support_alpha_ex_1555 = HI_FALSE;
|
||||
srcSurface.alpha0 = 0XFF;
|
||||
srcSurface.alpha1 = 0XFF;
|
||||
|
||||
hi_rgn_canvas_info info;
|
||||
hi_mpi_rgn_get_canvas_info(_handle, &info);
|
||||
|
||||
const uint32_t dstW = ::Util::Math::min((uint32_t)region().width, 4096u);
|
||||
const uint32_t dstH = ::Util::Math::min((uint32_t)region().height, 4096u);
|
||||
|
||||
hi_tde_surface dstSurface = {};
|
||||
dstSurface.phys_addr = info.phys_addr;
|
||||
dstSurface.color_format = HI_TDE_COLOR_FORMAT_ARGB8888;
|
||||
dstSurface.height = dstH;
|
||||
dstSurface.width = dstW;
|
||||
dstSurface.stride = info.stride;
|
||||
dstSurface.is_ycbcr_clut = HI_FALSE;
|
||||
dstSurface.support_alpha_ex_1555 = HI_FALSE;
|
||||
dstSurface.alpha_max_is_255 = HI_TRUE;
|
||||
dstSurface.alpha0 = 0XFF;
|
||||
dstSurface.alpha1 = 0XFF;
|
||||
|
||||
hi_tde_rect srcRect;
|
||||
srcRect.pos_x = 0;
|
||||
srcRect.pos_y = 0;
|
||||
srcRect.width = (uint32_t)winW;
|
||||
srcRect.height = (uint32_t)H;
|
||||
|
||||
hi_tde_rect dstRect;
|
||||
dstRect.pos_x = 0;
|
||||
dstRect.pos_y = 0;
|
||||
dstRect.width = (uint32_t)winW;
|
||||
dstRect.height = (uint32_t)H;
|
||||
|
||||
hi_s32 handle = hi_tde_begin_job();
|
||||
hi_tde_single_src src;
|
||||
src.src_surface = (hi_tde_surface*)&srcSurface;
|
||||
src.dst_surface = (hi_tde_surface*)&dstSurface;
|
||||
src.src_rect = (hi_tde_rect*)&srcRect;
|
||||
src.dst_rect = (hi_tde_rect*)&dstRect;
|
||||
int rc = hi_tde_quick_copy(handle, &src);
|
||||
if (rc != HI_SUCCESS)
|
||||
{
|
||||
logger().error("%s: TDE quick copy FAIL: %#x", name(), (uint32_t)rc);
|
||||
_timer.cancel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
hi_tde_end_job(handle, HI_FALSE, HI_TRUE, 10);
|
||||
hi_mpi_rgn_update_canvas(_handle);
|
||||
|
||||
_progressX += movePixels;
|
||||
if (movePixels > 0)
|
||||
{
|
||||
if (_progressX >= period - W)
|
||||
_progressX = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_progressX <= 0)
|
||||
_progressX = period - W;
|
||||
}
|
||||
}),
|
||||
interval, interval);
|
||||
}
|
||||
|
||||
void VideoOverlay::attach(Core::VideoComponent::Ptr pVideoComponent)
|
||||
{
|
||||
Core::VideoOverlay::attach(pVideoComponent);
|
||||
|
||||
hi_rgn_chn_attr attr = {};
|
||||
attr.is_show = HI_TRUE;
|
||||
switch (type())
|
||||
{
|
||||
case Core::VideoOverlayType::CANVAS:
|
||||
attr.type = HI_RGN_OVERLAY;
|
||||
attr.attr.overlay_chn.point.x = ::Util::Math::alignup(region().x, 2);
|
||||
attr.attr.overlay_chn.point.y = ::Util::Math::alignup(region().y, 2);
|
||||
attr.attr.overlay_chn.fg_alpha = 0;
|
||||
attr.attr.overlay_chn.bg_alpha = 0;
|
||||
attr.attr.overlay_chn.layer = getLayer();
|
||||
attr.attr.overlay_chn.qp_info.enable = HI_FALSE;
|
||||
attr.attr.overlay_chn.qp_info.is_abs_qp = HI_FALSE;
|
||||
attr.attr.overlay_chn.qp_info.qp_val = 0;
|
||||
attr.attr.overlay_chn.dst = HI_RGN_ATTACH_JPEG_MAIN;
|
||||
break;
|
||||
|
||||
case Core::VideoOverlayType::MOSAIC:
|
||||
attr.type = HI_RGN_MOSAIC;
|
||||
attr.attr.mosaic_chn.rect.x = ::Util::Math::alignup(region().x, 4);
|
||||
;
|
||||
attr.attr.mosaic_chn.rect.y = ::Util::Math::alignup(region().y, 2);
|
||||
attr.attr.mosaic_chn.rect.width = ::Util::Math::alignup(region().width, 4);
|
||||
attr.attr.mosaic_chn.rect.height = ::Util::Math::alignup(region().height, 2);
|
||||
attr.attr.mosaic_chn.blk_size = getBlockSize();
|
||||
attr.attr.mosaic_chn.layer = getLayer();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Poco::LogicException(name() + ": Unimplemented type: " + std::to_string((int)type()));
|
||||
}
|
||||
|
||||
auto t = target();
|
||||
auto pChannel = dynamic_cast<MPPChannel*>(t.get());
|
||||
if (!pChannel)
|
||||
throw Poco::LogicException(name() + ": Unsupported target: " + target()->name());
|
||||
|
||||
auto chn = pChannel->raw();
|
||||
int rc = hi_mpi_rgn_attach_to_chn(_handle, &chn, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidArgumentException(Poco::format("%s: Attach FAIL: %#x", name(), (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
void VideoOverlay::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
if (names.exists(_ZOrder))
|
||||
{
|
||||
auto t = target();
|
||||
auto pChannel = dynamic_cast<MPPChannel*>(t.get());
|
||||
auto chn = pChannel->raw();
|
||||
hi_rgn_chn_attr attr;
|
||||
hi_mpi_rgn_get_display_attr(_handle, &chn, &attr);
|
||||
|
||||
switch (attr.type)
|
||||
{
|
||||
case HI_RGN_OVERLAY:
|
||||
attr.attr.overlay_chn.layer = getZOrder();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hi_mpi_rgn_set_display_attr(_handle, &chn, &attr);
|
||||
}
|
||||
}
|
||||
|
||||
hi_mosaic_blk_size VideoOverlay::getBlockSize()
|
||||
{
|
||||
switch (getBlock())
|
||||
{
|
||||
default:
|
||||
|
||||
case 8:
|
||||
return HI_MOSAIC_BLK_SIZE_8;
|
||||
case 16:
|
||||
return HI_MOSAIC_BLK_SIZE_16;
|
||||
case 32:
|
||||
return HI_MOSAIC_BLK_SIZE_32;
|
||||
}
|
||||
}
|
||||
|
||||
hi_u32 VideoOverlay::getLayer()
|
||||
{
|
||||
return ::Util::Math::clamp(getZOrder(), 0, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
video/hisi/mpp5/VideoOverlay.h
Normal file
53
video/hisi/mpp5/VideoOverlay.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef ECE73282_2093_4767_B1C9_C38188A584FF
|
||||
#define ECE73282_2093_4767_B1C9_C38188A584FF
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "../../core/VideoOverlay.h"
|
||||
#include <hi_mpi_region.h>
|
||||
#include <Poco/Util/Timer.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class VideoOverlay: public Core::VideoOverlay
|
||||
{
|
||||
public:
|
||||
VideoOverlay(Core::VideoOverlayType type, const std::string& name, const Core::Rect& region);
|
||||
~VideoOverlay();
|
||||
|
||||
void render(Core::Image::Ptr pImage) override;
|
||||
void scrollRender(Core::Image::Ptr pImage, int hscroll) override;
|
||||
void attach(Core::VideoComponent::Ptr pVideoComponent) override;
|
||||
|
||||
protected:
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
hi_mosaic_blk_size getBlockSize();
|
||||
hi_u32 getLayer();
|
||||
|
||||
private:
|
||||
hi_rgn_handle _handle;
|
||||
unsigned _bytesPerPixel;
|
||||
uint32_t _imagePhyAddr;
|
||||
uint8_t* _pImageVirAddr;
|
||||
Poco::Util::Timer _timer;
|
||||
int _progressX;
|
||||
|
||||
Core::Image::Ptr _pTextImage;
|
||||
int _textWidth;
|
||||
int _winW;
|
||||
int _winH;
|
||||
uint32_t _stride;
|
||||
int _period;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
289
video/hisi/mpp5/VideoProcessor.cpp
Normal file
289
video/hisi/mpp5/VideoProcessor.cpp
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "VideoProcessor.h"
|
||||
#include "Logger.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "VideoInput.h"
|
||||
#include "util/Math.h"
|
||||
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DEFINE
|
||||
*******************************************************************************
|
||||
*/
|
||||
VideoProcessor::VideoProcessor()
|
||||
: MPPChannel((uint32_t)HI_ID_VPSS, ResourceManager::allocVPSSGroupID(), 0),
|
||||
Core::VideoProcessor(Poco::format("VideoProcessor(VPSS#%u)", deviceID()))
|
||||
{
|
||||
registerNotificationHandle<Core::ParameterChangedNotification>(*this,
|
||||
&VideoProcessor::handlePreviousParameterChanged);
|
||||
}
|
||||
|
||||
VideoProcessor::~VideoProcessor()
|
||||
{
|
||||
ResourceManager::freeVPSSGroupID(deviceID());
|
||||
}
|
||||
|
||||
void VideoProcessor::start()
|
||||
{
|
||||
auto pPrevious = previousComponents().first().cast<VideoComponent>();
|
||||
if (!pPrevious)
|
||||
throw Poco::BugcheckException(Poco::format("%s: First previous component '%s' convert to 'VideoComponent' FAIL",
|
||||
name(), previousComponents().first()->name()));
|
||||
|
||||
setWidth(pPrevious->getWidth());
|
||||
setHeight(pPrevious->getHeight());
|
||||
setVideoScanMode(pPrevious->getVideoScanMode());
|
||||
|
||||
uint32_t width = getWidth();
|
||||
uint32_t height = getHeight();
|
||||
|
||||
hi_vpss_grp_attr attr = {};
|
||||
attr.nr_en = HI_FALSE;
|
||||
attr.ie_en = HI_FALSE;
|
||||
attr.dci_en = HI_FALSE;
|
||||
attr.buf_share_en = HI_FALSE;
|
||||
attr.buf_share_chn = 0;
|
||||
attr.mcf_en = HI_FALSE;
|
||||
attr.max_width = width;
|
||||
attr.max_height = height;
|
||||
attr.max_dei_width = width;
|
||||
attr.max_dei_height = height;
|
||||
attr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
|
||||
attr.dynamic_range = HI_DYNAMIC_RANGE_SDR8;
|
||||
attr.frame_rate.src_frame_rate = -1;
|
||||
attr.frame_rate.dst_frame_rate = -1;
|
||||
|
||||
if (!pPrevious.cast<VideoInput>().isNull() && getVideoScanMode() == Core::VideoScanMode::INTERLACED)
|
||||
{
|
||||
attr.dei_mode = HI_VPSS_DEI_MODE_AUTO;
|
||||
setFrameRate(pPrevious->getFrameRate() / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
attr.dei_mode = HI_VPSS_DEI_MODE_OFF;
|
||||
setFrameRate(pPrevious->getFrameRate());
|
||||
}
|
||||
|
||||
int rc = hi_mpi_vpss_create_grp(groupID(), &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Create group FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
||||
rc);
|
||||
|
||||
hi_mpi_vpss_reset_grp(groupID());
|
||||
rc = hi_mpi_vpss_start_grp(groupID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(Poco::format("%s: Start group FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
||||
|
||||
bool isPreviousMJPEG = false;
|
||||
uint32_t direction = 0;
|
||||
hi_vpss_chn_attr chnAttr = {};
|
||||
chnAttr.chn_mode = HI_VPSS_CHN_MODE_USER;
|
||||
|
||||
chnAttr.width = width;
|
||||
chnAttr.height = height;
|
||||
chnAttr.video_format = HI_VIDEO_FORMAT_LINEAR;
|
||||
chnAttr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
chnAttr.dynamic_range = HI_DYNAMIC_RANGE_SDR8;
|
||||
chnAttr.compress_mode = HI_COMPRESS_MODE_NONE;
|
||||
|
||||
chnAttr.frame_rate.src_frame_rate = -1;
|
||||
chnAttr.frame_rate.dst_frame_rate = -1;
|
||||
chnAttr.mirror_en = (hi_bool)getMirror();
|
||||
chnAttr.flip_en = (hi_bool)getFlip();
|
||||
chnAttr.depth = 0;
|
||||
setVPSSVideoDirection(isPreviousMJPEG && direction, &chnAttr);
|
||||
|
||||
rc = hi_mpi_vpss_set_chn_attr(groupID(), channelID(), &chnAttr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Set channel#%u attr FAIL: %d(%#x)", name(), channelID(), rc, (uint32_t)rc), rc);
|
||||
|
||||
setVPSSChannelRotation(getRotation(), channelID());
|
||||
setVPSSGroupCrop(getCrop());
|
||||
|
||||
rc = hi_mpi_vpss_enable_chn(groupID(), channelID());
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Enable channel#%u FAIL: %d(%#x)", name(), channelID(), rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
void VideoProcessor::stop()
|
||||
{
|
||||
hi_mpi_vpss_disable_chn(groupID(), channelID());
|
||||
hi_mpi_vpss_stop_grp(groupID());
|
||||
hi_mpi_vpss_destroy_grp(groupID());
|
||||
}
|
||||
|
||||
void VideoProcessor::onConfigChanged(ParameterNames& names)
|
||||
{
|
||||
if (!started())
|
||||
return;
|
||||
|
||||
if (names.exists(_Width) || names.exists(_Height))
|
||||
{
|
||||
stop();
|
||||
start();
|
||||
publishEvent(Core::Component::Event::IMAGE_SIZE_CHANGED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (names.exists(_Rotation))
|
||||
setVPSSChannelRotation(getRotation(), channelID());
|
||||
|
||||
if (names.exists(_Crop))
|
||||
setVPSSGroupCrop(getCrop());
|
||||
|
||||
if (names.exists(_Mirror) || names.exists(_Flip))
|
||||
{
|
||||
hi_vpss_chn_attr attr;
|
||||
hi_mpi_vpss_get_chn_attr(groupID(), channelID(), &attr);
|
||||
attr.mirror_en = (hi_bool)getMirror();
|
||||
attr.flip_en = (hi_bool)getFlip();
|
||||
hi_mpi_vpss_set_chn_attr(groupID(), channelID(), &attr);
|
||||
}
|
||||
|
||||
if (names.exists(_VideoDirection))
|
||||
{
|
||||
hi_vpss_chn_attr attr;
|
||||
hi_mpi_vpss_get_chn_attr(groupID(), channelID(), &attr);
|
||||
setVPSSVideoDirection(attr.aspect_ratio.mode == HI_ASPECT_RATIO_NONE, &attr);
|
||||
hi_mpi_vpss_set_chn_attr(groupID(), channelID(), &attr);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoProcessor::onLink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
MPPChannel::doLink(pPrevious);
|
||||
}
|
||||
|
||||
void VideoProcessor::onUnlink(Core::Component::Ptr pPrevious)
|
||||
{
|
||||
MPPChannel::doUnlink(pPrevious);
|
||||
}
|
||||
|
||||
void VideoProcessor::handlePreviousParameterChanged(
|
||||
const Poco::AutoPtr<Core::ParameterChangedNotification>& pNotication)
|
||||
{
|
||||
auto pPrevious = previousComponents().first().cast<VideoComponent>();
|
||||
if (!pPrevious)
|
||||
throw Poco::BugcheckException(Poco::format("%s: First previous component '%s' convert to 'VideoComponent' FAIL",
|
||||
name(), previousComponents().first()->name()));
|
||||
|
||||
auto parameters = pNotication->parameters();
|
||||
if (parameters.exists(_Width))
|
||||
setWidth(pPrevious->getWidth());
|
||||
|
||||
if (parameters.exists(_Height))
|
||||
setHeight(pPrevious->getHeight());
|
||||
|
||||
if (parameters.exists(_FrameRate))
|
||||
setFrameRate(pPrevious->getFrameRate());
|
||||
|
||||
if (parameters.exists(_VideoScanMode))
|
||||
{
|
||||
setVideoScanMode(pPrevious->getVideoScanMode());
|
||||
if (started())
|
||||
{
|
||||
hi_vpss_grp_attr attr;
|
||||
hi_mpi_vpss_get_grp_attr(groupID(), &attr);
|
||||
if (!pPrevious.cast<VideoInput>().isNull() && getVideoScanMode() == Core::VideoScanMode::INTERLACED)
|
||||
{
|
||||
attr.dei_mode = HI_VPSS_DEI_MODE_AUTO;
|
||||
setFrameRate(pPrevious->getFrameRate() / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
attr.dei_mode = HI_VPSS_DEI_MODE_OFF;
|
||||
setFrameRate(pPrevious->getFrameRate());
|
||||
}
|
||||
hi_mpi_vpss_set_grp_attr(groupID(), &attr);
|
||||
}
|
||||
|
||||
parameters.insert(_FrameRate);
|
||||
}
|
||||
|
||||
commit();
|
||||
notifyNextComponents(sharedFromThis(), new Core::ParameterChangedNotification(parameters));
|
||||
}
|
||||
|
||||
void VideoProcessor::setVPSSGroupCrop(const Core::Rect& rect)
|
||||
{
|
||||
int x = Util::Math::clamp(rect.x, 0, HI_VPSS_MAX_IMG_WIDTH - 1);
|
||||
int y = Util::Math::clamp(rect.y, 0, HI_VPSS_MAX_IMG_HEIGHT - 1);
|
||||
int width = Util::Math::clamp(rect.width, HI_VPSS_MIN_IMG_WIDTH,
|
||||
Util::Math::max(HI_VPSS_MIN_IMG_WIDTH, HI_VPSS_MAX_IMG_WIDTH - rect.x));
|
||||
int height = Util::Math::clamp(rect.height, HI_VPSS_MIN_IMG_HEIGHT,
|
||||
Util::Math::max(HI_VPSS_MIN_IMG_HEIGHT, HI_VPSS_MAX_IMG_HEIGHT - rect.y));
|
||||
|
||||
hi_vpss_crop_info crop = {};
|
||||
crop.enable = (hi_bool) !(rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0);
|
||||
crop.crop_mode = HI_COORD_ABS;
|
||||
crop.crop_rect.x = x;
|
||||
crop.crop_rect.y = y;
|
||||
crop.crop_rect.width = width;
|
||||
crop.crop_rect.height = height;
|
||||
hi_mpi_vpss_set_grp_crop(groupID(), &crop);
|
||||
}
|
||||
|
||||
void VideoProcessor::setVPSSChannelRotation(int rotation, uint32_t channelID)
|
||||
{
|
||||
hi_rotation_attr attr;
|
||||
attr.enable = HI_TRUE;
|
||||
attr.rotation_type = HI_ROTATION_ANG_FIXED;
|
||||
switch (rotation)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
attr.enable = HI_FALSE;
|
||||
attr.rotation_fixed = HI_ROTATION_0;
|
||||
break;
|
||||
|
||||
case 90:
|
||||
attr.rotation_fixed = HI_ROTATION_90;
|
||||
break;
|
||||
|
||||
case 180:
|
||||
attr.rotation_fixed = HI_ROTATION_180;
|
||||
break;
|
||||
|
||||
case 270:
|
||||
attr.rotation_fixed = HI_ROTATION_270;
|
||||
break;
|
||||
}
|
||||
|
||||
int rc = hi_mpi_vpss_set_chn_rotation(groupID(), channelID, &attr);
|
||||
if (rc != HI_SUCCESS)
|
||||
throw Poco::InvalidAccessException(
|
||||
Poco::format("%s: Set channel#%u rotation FAIL: %d(%#x)", name(), channelID, rc, (uint32_t)rc), rc);
|
||||
}
|
||||
|
||||
void VideoProcessor::setVPSSVideoDirection(int direction, hi_vpss_chn_attr* attr)
|
||||
{
|
||||
if (!attr)
|
||||
return;
|
||||
|
||||
if (direction)
|
||||
{
|
||||
uint32_t width = getWidth();
|
||||
uint32_t height = getHeight();
|
||||
attr->aspect_ratio.mode = HI_ASPECT_RATIO_MANUAL;
|
||||
attr->aspect_ratio.bg_color = 0x000000;
|
||||
attr->aspect_ratio.video_rect.width = height * height / width;
|
||||
attr->aspect_ratio.video_rect.height = height;
|
||||
attr->aspect_ratio.video_rect.x = (width - attr->aspect_ratio.video_rect.width) / 2;
|
||||
attr->aspect_ratio.video_rect.y = 0;
|
||||
}
|
||||
else
|
||||
attr->aspect_ratio.mode = HI_ASPECT_RATIO_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
49
video/hisi/mpp5/VideoProcessor.h
Normal file
49
video/hisi/mpp5/VideoProcessor.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef FD7AD900_2C3C_41D7_A5C2_6B4F2B79CE9E
|
||||
#define FD7AD900_2C3C_41D7_A5C2_6B4F2B79CE9E
|
||||
/*
|
||||
*******************************************************************************
|
||||
* INCLUDE
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "MPPChannel.h"
|
||||
#include "../core/VideoProcessor.h"
|
||||
#include "../../core/Notifications.h"
|
||||
#include <hi_mpi_vpss.h>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
namespace MPP5
|
||||
{
|
||||
/*
|
||||
*******************************************************************************
|
||||
* CLASS DECLARE
|
||||
*******************************************************************************
|
||||
*/
|
||||
class VideoProcessor: public MPPChannel, public Core::VideoProcessor
|
||||
{
|
||||
public:
|
||||
VideoProcessor();
|
||||
~VideoProcessor();
|
||||
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void onConfigChanged(ParameterNames& names) override;
|
||||
void onLink(Core::Component::Ptr pPrevious) override;
|
||||
void onUnlink(Core::Component::Ptr pPrevious) override;
|
||||
|
||||
void handlePreviousParameterChanged(const Poco::AutoPtr<Core::ParameterChangedNotification>& pNotication);
|
||||
|
||||
uint32_t groupID();
|
||||
void setVPSSGroupCrop(const Core::Rect& rect);
|
||||
void setVPSSChannelRotation(int rotation, uint32_t channelID);
|
||||
void setVPSSVideoDirection(int direction, hi_vpss_chn_attr* attr);
|
||||
};
|
||||
|
||||
inline uint32_t VideoProcessor::groupID()
|
||||
{
|
||||
return deviceID();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
1586
video/hisi/mpp5/audio-adp/audio_aac_adp.c
Executable file
1586
video/hisi/mpp5/audio-adp/audio_aac_adp.c
Executable file
File diff suppressed because it is too large
Load diff
107
video/hisi/mpp5/audio-adp/audio_aac_adp.h
Executable file
107
video/hisi/mpp5/audio-adp/audio_aac_adp.h
Executable file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef AUDIO_AAC_ADP_H
|
||||
#define AUDIO_AAC_ADP_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hi_mpi_audio.h"
|
||||
#include "hi_common_aenc.h"
|
||||
#include "hi_common_adec.h"
|
||||
#include "hi_common_aio.h"
|
||||
#include "hi_aacdec.h"
|
||||
#include "hi_aacenc.h"
|
||||
|
||||
/* samples per frame for AACLC and aacPlus */
|
||||
#define AACLD_SAMPLES_PER_FRAME 512
|
||||
#define AACLC_SAMPLES_PER_FRAME 1024
|
||||
#define AACPLUS_SAMPLES_PER_FRAME 2048
|
||||
|
||||
/* max length of AAC stream by bytes */
|
||||
#define MAX_AAC_MAINBUF_SIZE (768 * 2)
|
||||
|
||||
typedef enum {
|
||||
HI_AAC_TYPE_AACLC = 0, /* AAC LC */
|
||||
HI_AAC_TYPE_EAAC = 1, /* EAAC(HEAAC or AAC+ or aac_plus_v1) */
|
||||
HI_AAC_TYPE_EAACPLUS = 2, /* EAAC+(AAC++ or aac_plus_v2) */
|
||||
HI_AAC_TYPE_AACLD = 3,
|
||||
HI_AAC_TYPE_AACELD = 4,
|
||||
HI_AAC_TYPE_BUTT,
|
||||
} hi_aac_type;
|
||||
|
||||
typedef enum {
|
||||
HI_AAC_BPS_8K = 8000,
|
||||
HI_AAC_BPS_16K = 16000,
|
||||
HI_AAC_BPS_22K = 22000,
|
||||
HI_AAC_BPS_24K = 24000,
|
||||
HI_AAC_BPS_32K = 32000,
|
||||
HI_AAC_BPS_48K = 48000,
|
||||
HI_AAC_BPS_64K = 64000,
|
||||
HI_AAC_BPS_96K = 96000,
|
||||
HI_AAC_BPS_128K = 128000,
|
||||
HI_AAC_BPS_256K = 256000,
|
||||
HI_AAC_BPS_320K = 320000,
|
||||
HI_AAC_BPS_BUTT
|
||||
} hi_aac_bps;
|
||||
|
||||
typedef enum {
|
||||
HI_AAC_TRANSPORT_TYPE_ADTS = 0,
|
||||
HI_AAC_TRANSPORT_TYPE_LOAS = 1,
|
||||
HI_AAC_TRANSPORT_TYPE_LATM_MCP1 = 2,
|
||||
HI_AAC_TRANSPORT_TYPE_BUTT
|
||||
} hi_aac_transport_type;
|
||||
|
||||
typedef struct {
|
||||
hi_s32 sample_rate; /* sample rate */
|
||||
hi_s32 bit_rate; /* bitrate */
|
||||
hi_s32 profile; /* profile */
|
||||
hi_s32 tns_used; /* TNS tools */
|
||||
hi_s32 pns_used; /* PNS tools */
|
||||
hi_s32 chn_num; /* channel num */
|
||||
} aacdec_frame_info;
|
||||
|
||||
/*
|
||||
* AAC commendatory parameter:
|
||||
* sampling rate(HZ) LC bit_rate(kbit/s) EAAC bit_rate (kbit/s) EAAC+ bit_rate (kbit/s)
|
||||
* 48000 128 48 32,24
|
||||
* 44100 128 48 32,24
|
||||
* 32000 96 22 16
|
||||
* 24000 64
|
||||
* 22050 64
|
||||
* 16000 48
|
||||
*/
|
||||
typedef struct {
|
||||
hi_aac_type aac_type; /* AAC profile type */
|
||||
hi_aac_bps bit_rate; /* AAC bitrate(LC:16~320, EAAC:24~128, EAAC+:16~64, AACLD:16~320, AACELD:32~320) */
|
||||
hi_audio_sample_rate sample_rate; /* AAC sample rate(LC:8~48, EAAC:16~48, EAAC+:16~48, AACLD:8~48, AACELD:8~48) */
|
||||
hi_audio_bit_width bit_width; /* AAC bit width (only support 16bit) */
|
||||
hi_audio_snd_mode snd_mode; /* sound mode of inferent audio frame */
|
||||
hi_aac_transport_type transport_type;
|
||||
hi_s16 band_width; /* targeted audio bandwidth in hz (0 or 1000~smp_rate/2), the default is 0 */
|
||||
} hi_aenc_attr_aac;
|
||||
|
||||
typedef struct {
|
||||
hi_aac_encoder *aac_state;
|
||||
hi_aenc_attr_aac aac_attr;
|
||||
} aenc_aac_encoder;
|
||||
|
||||
typedef struct {
|
||||
hi_aac_transport_type transport_type;
|
||||
} hi_adec_attr_aac;
|
||||
|
||||
typedef struct {
|
||||
hi_aac_decoder aac_state;
|
||||
hi_adec_attr_aac aac_attr;
|
||||
} adec_aac_decoder;
|
||||
|
||||
hi_s32 hi_mpi_aenc_aac_init(hi_void);
|
||||
|
||||
hi_s32 hi_mpi_aenc_aac_deinit(hi_void);
|
||||
|
||||
hi_s32 hi_mpi_adec_aac_init(hi_void);
|
||||
|
||||
hi_s32 hi_mpi_adec_aac_deinit(hi_void);
|
||||
|
||||
#endif
|
||||
88
video/hisi/mpp5/audio-adp/audio_dl_adp.c
Executable file
88
video/hisi/mpp5/audio-adp/audio_dl_adp.c
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "audio_dl_adp.h"
|
||||
#include <stdio.h>
|
||||
#ifndef __LITEOS__
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <los_ld_elflib.h>
|
||||
#endif
|
||||
|
||||
hi_s32 audio_dlpath(hi_char *lib_path)
|
||||
{
|
||||
#ifndef __LITEOS__
|
||||
(hi_void)lib_path;
|
||||
#else
|
||||
if (LOS_PathAdd(lib_path) != HI_SUCCESS) {
|
||||
printf("add path %s failed!\n", lib_path);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
hi_s32 audio_dlopen(hi_void **lib_handle, hi_char *lib_name)
|
||||
{
|
||||
if ((lib_handle == HI_NULL) || (lib_name == HI_NULL)) {
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
*lib_handle = HI_NULL;
|
||||
#ifndef __LITEOS__
|
||||
*lib_handle = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
|
||||
#else
|
||||
*lib_handle = LOS_SoLoad(lib_name);
|
||||
#endif
|
||||
|
||||
if (*lib_handle == HI_NULL) {
|
||||
printf("dlopen %s failed!\n", lib_name);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
hi_s32 audio_dlsym(hi_void **func_handle, hi_void *lib_handle, hi_char *func_name)
|
||||
{
|
||||
if (lib_handle == HI_NULL) {
|
||||
printf("LibHandle is empty!");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
*func_handle = HI_NULL;
|
||||
#ifndef __LITEOS__
|
||||
*func_handle = dlsym(lib_handle, func_name);
|
||||
#else
|
||||
*func_handle = LOS_FindSymByName(lib_handle, func_name);
|
||||
#endif
|
||||
|
||||
if (*func_handle == HI_NULL) {
|
||||
#ifndef __LITEOS__
|
||||
printf("dlsym %s fail, error msg is %s!\n", func_name, dlerror());
|
||||
#else
|
||||
printf("dlsym %s fail!\n", func_name);
|
||||
#endif
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
hi_s32 audio_dlclose(hi_void *lib_handle)
|
||||
{
|
||||
if (lib_handle == HI_NULL) {
|
||||
printf("LibHandle is empty!");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
#ifndef __LITEOS__
|
||||
dlclose(lib_handle);
|
||||
#else
|
||||
LOS_ModuleUnload(lib_handle);
|
||||
#endif
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
18
video/hisi/mpp5/audio-adp/audio_dl_adp.h
Executable file
18
video/hisi/mpp5/audio-adp/audio_dl_adp.h
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __AUDIO_DL_ADP_H__
|
||||
#define __AUDIO_DL_ADP_H__
|
||||
|
||||
#include "hi_type.h"
|
||||
|
||||
hi_s32 audio_dlpath(hi_char *lib_path);
|
||||
|
||||
hi_s32 audio_dlopen(hi_void **lib_handle, hi_char *lib_name);
|
||||
|
||||
hi_s32 audio_dlsym(hi_void **func_handle, hi_void *lib_handle, hi_char *func_name);
|
||||
|
||||
hi_s32 audio_dlclose(hi_void *lib_handle);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue