mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
accel: cleanup
Change-Id: I3a4a95855d178844d82b2606e4ed48ad3a1a5114
This commit is contained in:
@ -282,31 +282,29 @@ MediaDecoder::setupStream()
|
||||
if (enableAccel_) {
|
||||
auto APIs = video::HardwareAccel::getCompatibleAccel(decoderCtx_->codec_id,
|
||||
decoderCtx_->width, decoderCtx_->height, CODEC_DECODER);
|
||||
if (!APIs.empty()) {
|
||||
for (const auto& it : APIs) {
|
||||
accel_ = std::make_unique<video::HardwareAccel>(it); // save accel
|
||||
auto ret = accel_->initAPI(false, nullptr);
|
||||
if (ret < 0) {
|
||||
accel_ = nullptr;
|
||||
continue;
|
||||
}
|
||||
if(prepareDecoderContext() < 0)
|
||||
return -1; // failed
|
||||
accel_->setDetails(decoderCtx_);
|
||||
decoderCtx_->opaque = accel_.get();
|
||||
decoderCtx_->pix_fmt = accel_->getFormat();
|
||||
if (avcodec_open2(decoderCtx_, inputDecoder_, &options_) < 0) {
|
||||
// Failed to open codec
|
||||
JAMI_WARN("Fail to open hardware decoder for %s with %s ", avcodec_get_name(decoderCtx_->codec_id), it.getName().c_str());
|
||||
avcodec_free_context(&decoderCtx_);
|
||||
decoderCtx_ = nullptr;
|
||||
accel_.reset();
|
||||
continue;
|
||||
} else {
|
||||
// Succeed to open codec
|
||||
JAMI_WARN("Using hardware decoding for %s with %s ", avcodec_get_name(decoderCtx_->codec_id), it.getName().c_str());
|
||||
break;
|
||||
}
|
||||
for (const auto& it : APIs) {
|
||||
accel_ = std::make_unique<video::HardwareAccel>(it); // save accel
|
||||
auto ret = accel_->initAPI(false, nullptr);
|
||||
if (ret < 0) {
|
||||
accel_ = nullptr;
|
||||
continue;
|
||||
}
|
||||
if(prepareDecoderContext() < 0)
|
||||
return -1; // failed
|
||||
accel_->setDetails(decoderCtx_);
|
||||
decoderCtx_->opaque = accel_.get();
|
||||
decoderCtx_->pix_fmt = accel_->getFormat();
|
||||
if (avcodec_open2(decoderCtx_, inputDecoder_, &options_) < 0) {
|
||||
// Failed to open codec
|
||||
JAMI_WARN("Fail to open hardware decoder for %s with %s ", avcodec_get_name(decoderCtx_->codec_id), it.getName().c_str());
|
||||
avcodec_free_context(&decoderCtx_);
|
||||
decoderCtx_ = nullptr;
|
||||
accel_.reset();
|
||||
continue;
|
||||
} else {
|
||||
// Succeed to open codec
|
||||
JAMI_WARN("Using hardware decoding for %s with %s ", avcodec_get_name(decoderCtx_->codec_id), it.getName().c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,41 +210,38 @@ MediaEncoder::initStream(const SystemCodecInfo& systemCodecInfo, AVBufferRef* fr
|
||||
if (enableAccel_ && mediaType == AVMEDIA_TYPE_VIDEO) {
|
||||
auto APIs = video::HardwareAccel::getCompatibleAccel(static_cast<AVCodecID>(systemCodecInfo.avcodecId),
|
||||
videoOpts_.width, videoOpts_.height, CODEC_ENCODER);
|
||||
|
||||
if (APIs.size() > 0) {
|
||||
for (const auto& it : APIs) {
|
||||
accel_ = std::make_unique<video::HardwareAccel>(it); // save accel
|
||||
// Init codec need accel_ to init encoderCtx accelerated
|
||||
encoderCtx = initCodec(mediaType, static_cast<AVCodecID>(systemCodecInfo.avcodecId), SystemCodecInfo::DEFAULT_VIDEO_BITRATE);
|
||||
encoderCtx->opaque = accel_.get();
|
||||
// Check if pixel format from encoder match pixel format from decoder frame context
|
||||
// if it mismatch, it means that we are using two different hardware API (nvenc and vaapi for example)
|
||||
// in this case we don't want link the APIs
|
||||
if (framesCtx) {
|
||||
auto hw = reinterpret_cast<AVHWFramesContext*>(framesCtx->data);
|
||||
if (encoderCtx->pix_fmt != hw->format)
|
||||
linkableHW_ = false;
|
||||
}
|
||||
auto ret = accel_->initAPI(linkableHW_, framesCtx);
|
||||
if (ret < 0) {
|
||||
accel_.reset();
|
||||
encoderCtx = nullptr;
|
||||
continue;
|
||||
}
|
||||
accel_->setDetails(encoderCtx);
|
||||
if (avcodec_open2(encoderCtx, outputCodec_, &options_) < 0) {
|
||||
// Failed to open codec
|
||||
JAMI_WARN("Fail to open hardware encoder %s with %s ", avcodec_get_name(static_cast<AVCodecID>(systemCodecInfo.avcodecId)), it.getName().c_str());
|
||||
avcodec_free_context(&encoderCtx);
|
||||
encoderCtx = nullptr;
|
||||
accel_ = nullptr;
|
||||
continue;
|
||||
} else {
|
||||
// Succeed to open codec
|
||||
JAMI_WARN("Using hardware encoding for %s with %s ", avcodec_get_name(static_cast<AVCodecID>(systemCodecInfo.avcodecId)), it.getName().c_str());
|
||||
encoders_.push_back(encoderCtx);
|
||||
break;
|
||||
}
|
||||
for (const auto& it : APIs) {
|
||||
accel_ = std::make_unique<video::HardwareAccel>(it); // save accel
|
||||
// Init codec need accel_ to init encoderCtx accelerated
|
||||
encoderCtx = initCodec(mediaType, static_cast<AVCodecID>(systemCodecInfo.avcodecId), SystemCodecInfo::DEFAULT_VIDEO_BITRATE);
|
||||
encoderCtx->opaque = accel_.get();
|
||||
// Check if pixel format from encoder match pixel format from decoder frame context
|
||||
// if it mismatch, it means that we are using two different hardware API (nvenc and vaapi for example)
|
||||
// in this case we don't want link the APIs
|
||||
if (framesCtx) {
|
||||
auto hw = reinterpret_cast<AVHWFramesContext*>(framesCtx->data);
|
||||
if (encoderCtx->pix_fmt != hw->format)
|
||||
linkableHW_ = false;
|
||||
}
|
||||
auto ret = accel_->initAPI(linkableHW_, framesCtx);
|
||||
if (ret < 0) {
|
||||
accel_.reset();
|
||||
encoderCtx = nullptr;
|
||||
continue;
|
||||
}
|
||||
accel_->setDetails(encoderCtx);
|
||||
if (avcodec_open2(encoderCtx, outputCodec_, &options_) < 0) {
|
||||
// Failed to open codec
|
||||
JAMI_WARN("Fail to open hardware encoder %s with %s ", avcodec_get_name(static_cast<AVCodecID>(systemCodecInfo.avcodecId)), it.getName().c_str());
|
||||
avcodec_free_context(&encoderCtx);
|
||||
encoderCtx = nullptr;
|
||||
accel_ = nullptr;
|
||||
continue;
|
||||
} else {
|
||||
// Succeed to open codec
|
||||
JAMI_WARN("Using hardware encoding for %s with %s ", avcodec_get_name(static_cast<AVCodecID>(systemCodecInfo.avcodecId)), it.getName().c_str());
|
||||
encoders_.push_back(encoderCtx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -990,51 +987,50 @@ MediaEncoder::testH265Accel()
|
||||
|
||||
std::unique_ptr<video::HardwareAccel> accel;
|
||||
|
||||
if (APIs.size() > 0) {
|
||||
for (const auto& it : APIs) {
|
||||
accel = std::make_unique<video::HardwareAccel>(it); // save accel
|
||||
// Init codec need accel to init encoderCtx accelerated
|
||||
auto outputCodec = avcodec_find_encoder_by_name(accel->getCodecName().c_str());
|
||||
for (const auto& it : APIs) {
|
||||
accel = std::make_unique<video::HardwareAccel>(it); // save accel
|
||||
// Init codec need accel to init encoderCtx accelerated
|
||||
auto outputCodec = avcodec_find_encoder_by_name(accel->getCodecName().c_str());
|
||||
|
||||
AVCodecContext* encoderCtx = avcodec_alloc_context3(outputCodec);
|
||||
encoderCtx->thread_count = std::min(std::thread::hardware_concurrency(), 16u);
|
||||
encoderCtx->width = 1280;
|
||||
encoderCtx->height = 720;
|
||||
AVRational framerate;
|
||||
framerate.num = 30;
|
||||
framerate.den = 1;
|
||||
encoderCtx->time_base = av_inv_q(framerate);
|
||||
encoderCtx->pix_fmt = accel->getFormat();
|
||||
encoderCtx->profile = FF_PROFILE_HEVC_MAIN;
|
||||
encoderCtx->opaque = accel.get();
|
||||
AVCodecContext* encoderCtx = avcodec_alloc_context3(outputCodec);
|
||||
encoderCtx->thread_count = std::min(std::thread::hardware_concurrency(), 16u);
|
||||
encoderCtx->width = 1280;
|
||||
encoderCtx->height = 720;
|
||||
AVRational framerate;
|
||||
framerate.num = 30;
|
||||
framerate.den = 1;
|
||||
encoderCtx->time_base = av_inv_q(framerate);
|
||||
encoderCtx->pix_fmt = accel->getFormat();
|
||||
encoderCtx->profile = FF_PROFILE_HEVC_MAIN;
|
||||
encoderCtx->opaque = accel.get();
|
||||
|
||||
auto br = SystemCodecInfo::DEFAULT_VIDEO_BITRATE;
|
||||
av_opt_set_int(encoderCtx, "b", br * 1000, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(encoderCtx, "maxrate", br * 1000, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(encoderCtx, "minrate", br * 1000, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(encoderCtx, "bufsize", br * 500, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(encoderCtx, "crf", -1, AV_OPT_SEARCH_CHILDREN);
|
||||
auto br = SystemCodecInfo::DEFAULT_VIDEO_BITRATE;
|
||||
av_opt_set_int(encoderCtx, "b", br * 1000, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(encoderCtx, "maxrate", br * 1000, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(encoderCtx, "minrate", br * 1000, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(encoderCtx, "bufsize", br * 500, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(encoderCtx, "crf", -1, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
auto ret = accel->initAPI(false, nullptr);
|
||||
if (ret < 0) {
|
||||
accel = nullptr;
|
||||
encoderCtx = nullptr;
|
||||
continue;
|
||||
}
|
||||
accel->setDetails(encoderCtx);
|
||||
if (avcodec_open2(encoderCtx, outputCodec, nullptr) < 0) {
|
||||
// Failed to open codec
|
||||
avcodec_free_context(&encoderCtx);
|
||||
encoderCtx = nullptr;
|
||||
accel = nullptr;
|
||||
continue;
|
||||
} else {
|
||||
// Succeed to open codec
|
||||
avcodec_free_context(&encoderCtx);
|
||||
encoderCtx = nullptr;
|
||||
accel = nullptr;
|
||||
return it.getName();
|
||||
}
|
||||
auto ret = accel->initAPI(false, nullptr);
|
||||
if (ret < 0) {
|
||||
accel.reset();;
|
||||
encoderCtx = nullptr;
|
||||
continue;
|
||||
}
|
||||
accel->setDetails(encoderCtx);
|
||||
if (avcodec_open2(encoderCtx, outputCodec, nullptr) < 0) {
|
||||
// Failed to open codec
|
||||
JAMI_WARN("Fail to open hardware encoder H265 with %s ", it.getName().c_str());
|
||||
avcodec_free_context(&encoderCtx);
|
||||
encoderCtx = nullptr;
|
||||
accel = nullptr;
|
||||
continue;
|
||||
} else {
|
||||
// Succeed to open codec
|
||||
avcodec_free_context(&encoderCtx);
|
||||
encoderCtx = nullptr;
|
||||
accel = nullptr;
|
||||
return it.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ getFormatCb(AVCodecContext* codecCtx, const AVPixelFormat* formats)
|
||||
}
|
||||
|
||||
int
|
||||
HardwareAccel::test_device(const char* name,
|
||||
HardwareAccel::init_device(const char* name,
|
||||
const char* device, int flags)
|
||||
{
|
||||
const AVHWDeviceContext* dev = nullptr;
|
||||
@ -121,7 +121,7 @@ HardwareAccel::test_device(const char* name,
|
||||
}
|
||||
|
||||
int
|
||||
HardwareAccel::test_device_type(std::string& dev)
|
||||
HardwareAccel::init_device_type(std::string& dev)
|
||||
{
|
||||
AVHWDeviceType check;
|
||||
const char* name;
|
||||
@ -142,28 +142,28 @@ HardwareAccel::test_device_type(std::string& dev)
|
||||
|
||||
JAMI_WARN("-- Starting %s test for %s with default device.", (type_ == CODEC_ENCODER) ? "encoding" : "decoding", name);
|
||||
if (name_ == "qsv")
|
||||
err = test_device(name, "auto", 0);
|
||||
err = init_device(name, "auto", 0);
|
||||
else
|
||||
err = test_device(name, nullptr, 0);
|
||||
err = init_device(name, nullptr, 0);
|
||||
if (err == 0) {
|
||||
JAMI_DBG("-- Test passed for %s with default device.", name);
|
||||
JAMI_DBG("-- Init passed for %s with default device.", name);
|
||||
dev = "default";
|
||||
return 0;
|
||||
} else {
|
||||
JAMI_DBG("-- Test failed for %s with default device.", name);
|
||||
JAMI_DBG("-- Init failed for %s with default device.", name);
|
||||
}
|
||||
|
||||
for (const auto& device : possible_devices_) {
|
||||
JAMI_WARN("-- Starting %s test for %s with device %s.", (type_ == CODEC_ENCODER) ? "encoding" : "decoding", name, device.c_str());
|
||||
err = test_device(name, device.c_str(), 0);
|
||||
JAMI_WARN("-- Init %s for %s with device %s.", (type_ == CODEC_ENCODER) ? "encoding" : "decoding", name, device.c_str());
|
||||
err = init_device(name, device.c_str(), 0);
|
||||
if (err == 0) {
|
||||
JAMI_DBG("-- Test passed for %s with device %s.",
|
||||
JAMI_DBG("-- Init passed for %s with device %s.",
|
||||
name, device.c_str());
|
||||
dev = device;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
JAMI_DBG("-- Test failed for %s with device %s.",
|
||||
JAMI_DBG("-- Init failed for %s with device %s.",
|
||||
name, device.c_str());
|
||||
}
|
||||
}
|
||||
@ -329,7 +329,7 @@ HardwareAccel::initAPI(bool linkable, AVBufferRef* framesCtx)
|
||||
{
|
||||
const auto& codecName = getCodecName();
|
||||
std::string device;
|
||||
auto ret = test_device_type(device);
|
||||
auto ret = init_device_type(device);
|
||||
if(ret == 0) {
|
||||
bool link = false;
|
||||
if (linkable && framesCtx)
|
||||
|
@ -158,8 +158,8 @@ private:
|
||||
AVBufferRef* deviceCtx_ {nullptr};
|
||||
AVBufferRef* framesCtx_ {nullptr};
|
||||
|
||||
int test_device(const char* name, const char* device, int flags);
|
||||
int test_device_type(std::string& dev);
|
||||
int init_device(const char* name, const char* device, int flags);
|
||||
int init_device_type(std::string& dev);
|
||||
|
||||
std::set<std::string> possible_devices_;
|
||||
};
|
||||
|
Reference in New Issue
Block a user