|
|
@ -1,5 +1,5 @@
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
@ -39,7 +39,7 @@
|
|
|
|
namespace android {
|
|
|
|
namespace android {
|
|
|
|
|
|
|
|
|
|
|
|
class C2SoftHevcEnc::IntfImpl : public C2InterfaceHelper {
|
|
|
|
class C2SoftHevcEnc::IntfImpl : public C2InterfaceHelper {
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
|
|
|
|
explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
|
|
|
|
: C2InterfaceHelper(helper) {
|
|
|
|
: C2InterfaceHelper(helper) {
|
|
|
|
setDerivedInstance(this);
|
|
|
|
setDerivedInstance(this);
|
|
|
@ -73,6 +73,7 @@ class C2SoftHevcEnc::IntfImpl : public C2InterfaceHelper {
|
|
|
|
0u, (uint64_t)C2MemoryUsage::CPU_READ))
|
|
|
|
0u, (uint64_t)C2MemoryUsage::CPU_READ))
|
|
|
|
.build());
|
|
|
|
.build());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// matches size limits in codec library
|
|
|
|
addParameter(
|
|
|
|
addParameter(
|
|
|
|
DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
|
|
|
|
DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
|
|
|
|
.withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
|
|
|
|
.withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
|
|
|
@ -91,6 +92,7 @@ class C2SoftHevcEnc::IntfImpl : public C2InterfaceHelper {
|
|
|
|
Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
|
|
|
|
Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
|
|
|
|
.build());
|
|
|
|
.build());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// matches limits in codec library
|
|
|
|
addParameter(
|
|
|
|
addParameter(
|
|
|
|
DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
|
|
|
|
DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
|
|
|
|
.withDefault(new C2StreamBitrateInfo::output(0u, 64000))
|
|
|
|
.withDefault(new C2StreamBitrateInfo::output(0u, 64000))
|
|
|
@ -98,6 +100,7 @@ class C2SoftHevcEnc::IntfImpl : public C2InterfaceHelper {
|
|
|
|
.withSetter(BitrateSetter)
|
|
|
|
.withSetter(BitrateSetter)
|
|
|
|
.build());
|
|
|
|
.build());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// matches levels allowed within codec library
|
|
|
|
addParameter(
|
|
|
|
addParameter(
|
|
|
|
DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
|
|
|
|
DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
|
|
|
|
.withDefault(new C2StreamProfileLevelInfo::output(
|
|
|
|
.withDefault(new C2StreamProfileLevelInfo::output(
|
|
|
@ -137,7 +140,7 @@ class C2SoftHevcEnc::IntfImpl : public C2InterfaceHelper {
|
|
|
|
C2P<C2StreamBitrateInfo::output>& me) {
|
|
|
|
C2P<C2StreamBitrateInfo::output>& me) {
|
|
|
|
(void)mayBlock;
|
|
|
|
(void)mayBlock;
|
|
|
|
C2R res = C2R::Ok();
|
|
|
|
C2R res = C2R::Ok();
|
|
|
|
if (me.v.value <= 4096) {
|
|
|
|
if (me.v.value < 4096) {
|
|
|
|
me.set().value = 4096;
|
|
|
|
me.set().value = 4096;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
return res;
|
|
|
@ -278,7 +281,7 @@ class C2SoftHevcEnc::IntfImpl : public C2InterfaceHelper {
|
|
|
|
return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
|
|
|
|
return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const {
|
|
|
|
std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const {
|
|
|
|
return mSize;
|
|
|
|
return mSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const {
|
|
|
|
std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const {
|
|
|
@ -304,18 +307,21 @@ class C2SoftHevcEnc::IntfImpl : public C2InterfaceHelper {
|
|
|
|
std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
|
|
|
|
std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
|
|
|
|
std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
|
|
|
|
std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
constexpr char COMPONENT_NAME[] = "c2.android.hevc.encoder";
|
|
|
|
constexpr char COMPONENT_NAME[] = "c2.android.hevc.encoder";
|
|
|
|
|
|
|
|
|
|
|
|
static size_t GetCPUCoreCount() {
|
|
|
|
static size_t GetCPUCoreCount() {
|
|
|
|
long cpuCoreCount = 1;
|
|
|
|
long cpuCoreCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(_SC_NPROCESSORS_ONLN)
|
|
|
|
#if defined(_SC_NPROCESSORS_ONLN)
|
|
|
|
cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
|
|
|
|
cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
// _SC_NPROC_ONLN must be defined...
|
|
|
|
// _SC_NPROC_ONLN must be defined...
|
|
|
|
cpuCoreCount = sysconf(_SC_NPROC_ONLN);
|
|
|
|
cpuCoreCount = sysconf(_SC_NPROC_ONLN);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
CHECK(cpuCoreCount >= 1);
|
|
|
|
|
|
|
|
ALOGV("Number of CPU cores: %ld", cpuCoreCount);
|
|
|
|
if (cpuCoreCount < 1)
|
|
|
|
|
|
|
|
cpuCoreCount = 1;
|
|
|
|
return (size_t)cpuCoreCount;
|
|
|
|
return (size_t)cpuCoreCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -383,7 +389,7 @@ static void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
|
|
|
|
|
|
|
|
|
|
|
|
c2_status_t C2SoftHevcEnc::initEncParams() {
|
|
|
|
c2_status_t C2SoftHevcEnc::initEncParams() {
|
|
|
|
mCodecCtx = nullptr;
|
|
|
|
mCodecCtx = nullptr;
|
|
|
|
mNumCores = MIN(GetCPUCoreCount(), CODEC_MAX_CORES);
|
|
|
|
mNumCores = std::min(GetCPUCoreCount(), (size_t) CODEC_MAX_CORES);
|
|
|
|
memset(&mEncParams, 0, sizeof(ihevce_static_cfg_params_t));
|
|
|
|
memset(&mEncParams, 0, sizeof(ihevce_static_cfg_params_t));
|
|
|
|
|
|
|
|
|
|
|
|
// default configuration
|
|
|
|
// default configuration
|
|
|
@ -397,7 +403,8 @@ c2_status_t C2SoftHevcEnc::initEncParams() {
|
|
|
|
mEncParams.s_src_prms.i4_width = mSize->width;
|
|
|
|
mEncParams.s_src_prms.i4_width = mSize->width;
|
|
|
|
mEncParams.s_src_prms.i4_height = mSize->height;
|
|
|
|
mEncParams.s_src_prms.i4_height = mSize->height;
|
|
|
|
mEncParams.s_src_prms.i4_frm_rate_denom = 1000;
|
|
|
|
mEncParams.s_src_prms.i4_frm_rate_denom = 1000;
|
|
|
|
mEncParams.s_src_prms.i4_frm_rate_num = mFrameRate->value * mEncParams.s_src_prms.i4_frm_rate_denom;
|
|
|
|
mEncParams.s_src_prms.i4_frm_rate_num =
|
|
|
|
|
|
|
|
mFrameRate->value * mEncParams.s_src_prms.i4_frm_rate_denom;
|
|
|
|
mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset = IHEVCE_QUALITY_P5;
|
|
|
|
mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset = IHEVCE_QUALITY_P5;
|
|
|
|
mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0] =
|
|
|
|
mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0] =
|
|
|
|
mBitrate->value;
|
|
|
|
mBitrate->value;
|
|
|
@ -470,7 +477,7 @@ c2_status_t C2SoftHevcEnc::setEncodeArgs(ihevce_inp_buf_t* ps_encode_ip,
|
|
|
|
const C2GraphicView* const input,
|
|
|
|
const C2GraphicView* const input,
|
|
|
|
uint64_t timestamp) {
|
|
|
|
uint64_t timestamp) {
|
|
|
|
ihevce_static_cfg_params_t* params = &mEncParams;
|
|
|
|
ihevce_static_cfg_params_t* params = &mEncParams;
|
|
|
|
memset(ps_encode_ip, 0, sizeof(ihevce_inp_buf_t));
|
|
|
|
memset(ps_encode_ip, 0, sizeof(*ps_encode_ip));
|
|
|
|
|
|
|
|
|
|
|
|
if (!input) {
|
|
|
|
if (!input) {
|
|
|
|
return C2_OK;
|
|
|
|
return C2_OK;
|
|
|
@ -495,13 +502,14 @@ c2_status_t C2SoftHevcEnc::setEncodeArgs(ihevce_inp_buf_t* ps_encode_ip,
|
|
|
|
int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
|
|
|
|
int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
|
|
|
|
int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
|
|
|
|
int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t width = mSize->width;
|
|
|
|
const uint32_t width = mSize->width;
|
|
|
|
uint32_t height = mSize->height;
|
|
|
|
const uint32_t height = mSize->height;
|
|
|
|
|
|
|
|
|
|
|
|
// width and height are always even
|
|
|
|
// width and height must be even
|
|
|
|
// width and height are always even (as block size is 16x16)
|
|
|
|
if (width & 1u || height & 1u) {
|
|
|
|
CHECK_EQ((width & 1u), 0u);
|
|
|
|
ALOGW("height(%u) and width(%u) must both be even", height, width);
|
|
|
|
CHECK_EQ((height & 1u), 0u);
|
|
|
|
return C2_BAD_VALUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t yPlaneSize = width * height;
|
|
|
|
size_t yPlaneSize = width * height;
|
|
|
|
|
|
|
|
|
|
|
@ -650,6 +658,7 @@ void C2SoftHevcEnc::process(const std::unique_ptr<C2Work>& work,
|
|
|
|
if (view->error() != C2_OK) {
|
|
|
|
if (view->error() != C2_OK) {
|
|
|
|
ALOGE("graphic view map err = %d", view->error());
|
|
|
|
ALOGE("graphic view map err = %d", view->error());
|
|
|
|
mSignalledError = true;
|
|
|
|
mSignalledError = true;
|
|
|
|
|
|
|
|
work->result = C2_CORRUPTED;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -687,8 +696,8 @@ void C2SoftHevcEnc::process(const std::unique_ptr<C2Work>& work,
|
|
|
|
|
|
|
|
|
|
|
|
status = setEncodeArgs(&s_encode_ip, view.get(), timestamp);
|
|
|
|
status = setEncodeArgs(&s_encode_ip, view.get(), timestamp);
|
|
|
|
if (C2_OK != status) {
|
|
|
|
if (C2_OK != status) {
|
|
|
|
mSignalledError = true;
|
|
|
|
|
|
|
|
ALOGE("setEncodeArgs failed : 0x%x", status);
|
|
|
|
ALOGE("setEncodeArgs failed : 0x%x", status);
|
|
|
|
|
|
|
|
mSignalledError = true;
|
|
|
|
work->result = status;
|
|
|
|
work->result = status;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -761,8 +770,9 @@ class C2SoftHevcEncFactory : public C2ComponentFactory {
|
|
|
|
: mHelper(std::static_pointer_cast<C2ReflectorHelper>(
|
|
|
|
: mHelper(std::static_pointer_cast<C2ReflectorHelper>(
|
|
|
|
GetCodec2PlatformComponentStore()->getParamReflector())) {}
|
|
|
|
GetCodec2PlatformComponentStore()->getParamReflector())) {}
|
|
|
|
|
|
|
|
|
|
|
|
virtual c2_status_t createComponent(
|
|
|
|
c2_status_t createComponent(
|
|
|
|
c2_node_id_t id, std::shared_ptr<C2Component>* const component,
|
|
|
|
c2_node_id_t id,
|
|
|
|
|
|
|
|
std::shared_ptr<C2Component>* const component,
|
|
|
|
std::function<void(C2Component*)> deleter) override {
|
|
|
|
std::function<void(C2Component*)> deleter) override {
|
|
|
|
*component = std::shared_ptr<C2Component>(
|
|
|
|
*component = std::shared_ptr<C2Component>(
|
|
|
|
new C2SoftHevcEnc(
|
|
|
|
new C2SoftHevcEnc(
|
|
|
@ -772,8 +782,9 @@ class C2SoftHevcEncFactory : public C2ComponentFactory {
|
|
|
|
return C2_OK;
|
|
|
|
return C2_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual c2_status_t createInterface(
|
|
|
|
c2_status_t createInterface(
|
|
|
|
c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
|
|
|
|
c2_node_id_t id,
|
|
|
|
|
|
|
|
std::shared_ptr<C2ComponentInterface>* const interface,
|
|
|
|
std::function<void(C2ComponentInterface*)> deleter) override {
|
|
|
|
std::function<void(C2ComponentInterface*)> deleter) override {
|
|
|
|
*interface = std::shared_ptr<C2ComponentInterface>(
|
|
|
|
*interface = std::shared_ptr<C2ComponentInterface>(
|
|
|
|
new SimpleInterface<C2SoftHevcEnc::IntfImpl>(
|
|
|
|
new SimpleInterface<C2SoftHevcEnc::IntfImpl>(
|
|
|
@ -783,7 +794,7 @@ class C2SoftHevcEncFactory : public C2ComponentFactory {
|
|
|
|
return C2_OK;
|
|
|
|
return C2_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual ~C2SoftHevcEncFactory() override = default;
|
|
|
|
~C2SoftHevcEncFactory() override = default;
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
std::shared_ptr<C2ReflectorHelper> mHelper;
|
|
|
|
std::shared_ptr<C2ReflectorHelper> mHelper;
|
|
|
|