/* ******************************************************************************* * INCLUDE ******************************************************************************* */ #include "AudioEncoder.h" #include "ResourceManager.h" #include "Util.h" #include "util/Math.h" #include 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(); } } }