Skip to content
Snippets Groups Projects
Commit 9a36c366 authored by Philippe Gorley's avatar Philippe Gorley Committed by Philippe Gorley
Browse files

accel: update vaapi


Most of the logic for vaapi has been moved to lavc, so update Ring
to reflect these changes. This also removes a compilation warning
related to a deprecated struct.

Change-Id: I16e444c49fb358184f20c7211365c6ac95fc03a1
Reviewed-by: default avatarGuillaume Roguez <guillaume.roguez@savoirfairelinux.com>
parent 8c9e75af
Branches
Tags
No related merge requests found
...@@ -104,92 +104,13 @@ VaapiAccel::checkAvailability() ...@@ -104,92 +104,13 @@ VaapiAccel::checkAvailability()
bool bool
VaapiAccel::init() VaapiAccel::init()
{ {
vaProfile_ = VAProfileNone;
vaEntryPoint_ = VAEntrypointVLD;
using ProfileMap = std::map<int, VAProfile>;
ProfileMap h264 = {
{ FF_PROFILE_H264_CONSTRAINED_BASELINE, VAProfileH264ConstrainedBaseline },
{ FF_PROFILE_H264_BASELINE, VAProfileH264Baseline },
{ FF_PROFILE_H264_MAIN, VAProfileH264Main },
{ FF_PROFILE_H264_HIGH, VAProfileH264High }
};
ProfileMap mpeg4 = {
{ FF_PROFILE_MPEG4_SIMPLE, VAProfileMPEG4Simple },
{ FF_PROFILE_MPEG4_ADVANCED_SIMPLE, VAProfileMPEG4AdvancedSimple },
{ FF_PROFILE_MPEG4_MAIN, VAProfileMPEG4Main }
};
ProfileMap h263 = {
{ FF_PROFILE_UNKNOWN, VAProfileH263Baseline }
};
std::map<int, ProfileMap> profileMap = {
{ AV_CODEC_ID_H264, h264 },
{ AV_CODEC_ID_MPEG4, mpeg4 },
{ AV_CODEC_ID_H263, h263 },
{ AV_CODEC_ID_H263P, h263 }
};
auto device = reinterpret_cast<AVHWDeviceContext*>(deviceBufferRef_->data);
vaConfig_ = VA_INVALID_ID;
vaContext_ = VA_INVALID_ID;
auto hardwareContext = static_cast<AVVAAPIDeviceContext*>(device->hwctx);
int numProfiles = vaMaxNumProfiles(hardwareContext->display);
auto profiles = std::vector<VAProfile>(numProfiles);
auto status = vaQueryConfigProfiles(hardwareContext->display, profiles.data(), &numProfiles);
if (status != VA_STATUS_SUCCESS) {
RING_ERR("Failed to query profiles: %s", vaErrorStr(status));
return false;
}
VAProfile codecProfile = VAProfileNone;
auto itOuter = profileMap.find(codecCtx_->codec_id);
if (itOuter != profileMap.end()) {
auto innerMap = itOuter->second;
auto itInner = innerMap.find(codecCtx_->profile);
if (itInner != innerMap.end()) {
codecProfile = itInner->second;
}
}
auto iter = std::find_if(std::begin(profiles),
std::end(profiles),
[codecProfile](const VAProfile& p){ return p == codecProfile; });
if (iter == std::end(profiles)) {
RING_ERR("VAAPI does not support selected codec");
return false;
}
vaProfile_ = *iter;
status = vaCreateConfig(hardwareContext->display, vaProfile_, vaEntryPoint_, 0, 0, &vaConfig_);
if (status != VA_STATUS_SUCCESS) {
RING_ERR("Failed to create VAAPI configuration: %s", vaErrorStr(status));
return false;
}
auto hardwareConfig = static_cast<AVVAAPIHWConfig*>(av_hwdevice_hwconfig_alloc(deviceBufferRef_.get()));
hardwareConfig->config_id = vaConfig_;
auto constraints = av_hwdevice_get_hwframe_constraints(deviceBufferRef_.get(), hardwareConfig);
if (width_ < constraints->min_width
|| width_ > constraints->max_width
|| height_ < constraints->min_height
|| height_ > constraints->max_height) {
av_hwframe_constraints_free(&constraints);
av_freep(&hardwareConfig);
RING_ERR("Hardware does not support image size with VAAPI: %dx%d", width_, height_);
return false;
}
int numSurfaces = 16; // based on codec instead? int numSurfaces = 16; // based on codec instead?
if (codecCtx_->active_thread_type & FF_THREAD_FRAME) if (codecCtx_->active_thread_type & FF_THREAD_FRAME)
numSurfaces += codecCtx_->thread_count; // need extra surface per thread numSurfaces += codecCtx_->thread_count; // need extra surface per thread
framesBufferRef_.reset(av_hwframe_ctx_alloc(deviceBufferRef_.get())); framesBufferRef_.reset(av_hwframe_ctx_alloc(deviceBufferRef_.get()));
auto frames = reinterpret_cast<AVHWFramesContext*>(framesBufferRef_->data); auto frames = reinterpret_cast<AVHWFramesContext*>(framesBufferRef_->data);
frames->format = AV_PIX_FMT_VAAPI; frames->format = format_;
frames->sw_format = AV_PIX_FMT_YUV420P; frames->sw_format = AV_PIX_FMT_YUV420P;
frames->width = width_; frames->width = width_;
frames->height = height_; frames->height = height_;
...@@ -200,20 +121,9 @@ VaapiAccel::init() ...@@ -200,20 +121,9 @@ VaapiAccel::init()
return false; return false;
} }
auto framesContext = static_cast<AVVAAPIFramesContext*>(frames->hwctx); codecCtx_->hw_frames_ctx = av_buffer_ref(framesBufferRef_.get());
status = vaCreateContext(hardwareContext->display, vaConfig_, width_, height_,
VA_PROGRESSIVE, framesContext->surface_ids, framesContext->nb_surfaces, &vaContext_);
if (status != VA_STATUS_SUCCESS) {
RING_ERR("Failed to create VAAPI context: %s", vaErrorStr(status));
return false;
}
RING_DBG("VAAPI decoder initialized via device: %s", deviceName_.c_str()); RING_DBG("VAAPI decoder initialized via device: %s", deviceName_.c_str());
ffmpegAccelCtx_.display = hardwareContext->display;
ffmpegAccelCtx_.config_id = vaConfig_;
ffmpegAccelCtx_.context_id = vaContext_;
codecCtx_->hwaccel_context = (void*)&ffmpegAccelCtx_;
return true; return true;
} }
......
...@@ -71,13 +71,6 @@ class VaapiAccel : public HardwareAccel { ...@@ -71,13 +71,6 @@ class VaapiAccel : public HardwareAccel {
AVBufferRefPtr deviceBufferRef_; AVBufferRefPtr deviceBufferRef_;
AVBufferRefPtr framesBufferRef_; AVBufferRefPtr framesBufferRef_;
VAProfile vaProfile_ = VAProfileNone;
VAEntrypoint vaEntryPoint_ = VAEntrypointVLD;
VAConfigID vaConfig_ = -1;
VAContextID vaContext_ = -1;
struct vaapi_context ffmpegAccelCtx_ = {};
std::string deviceName_; std::string deviceName_;
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment