119 const std::string& name,
129 , swFormat_(swFormat)
131 , dynBitrate_(dynBitrate)
150 JAMI_DBG() <<
"Found compatible hardware format for "
162HardwareAccel::init_device(
const char* name,
const char* device,
int flags)
170 JAMI_DBG(
"Failed to create %s device: %d.\n", name,
err);
176 if (
dev->type != hwType_) {
177 JAMI_DBG(
"Device created as type %d has type %d.", hwType_,
dev->type);
181 JAMI_DBG(
"Device type %s successfully created.", name);
187HardwareAccel::init_device_type(std::string&
dev)
195 JAMI_DBG(
"No name available for device type %d.", hwType_);
200 if (
check != hwType_) {
201 JAMI_DBG(
"Type %d maps to name %s maps to type %d.", hwType_, name,
check);
205 JAMI_WARN(
"-- Starting %s init for %s with default device.",
210 err = init_device(name,
"auto", 0);
212 err = init_device(name,
nullptr, 0);
214 JAMI_DBG(
"-- Init passed for %s with default device.", name);
220 JAMI_DBG(
"-- Init failed for %s with default device.", name);
224 for (
auto& device : *possible_devices_) {
227 JAMI_WARN(
"-- Init %s for %s with device %s.",
231 err = init_device(name, device.first.c_str(), 0);
233 JAMI_DBG(
"-- Init passed for %s with device %s.", name, device.first.c_str());
239 JAMI_DBG(
"-- Init failed for %s with device %s.", name, device.first.c_str());
256std::unique_ptr<VideoFrame>
261 auto input =
frame.pointer();
262 if (input->format != format_) {
271 auto input =
frame.pointer();
272 if (input->format != swFormat_) {
279 auto framePtr = std::make_unique<VideoFrame>();
283 JAMI_ERR() <<
"Failed to allocate hardware buffer: "
289 JAMI_ERR() <<
"Failed to allocate hardware buffer: Unable to allocate memory";
301 JAMI_ERR() <<
"Invalid hardware accelerator";
320HardwareAccel::initFrame()
324 JAMI_ERR() <<
"Unable to initialize hardware frames without a valid hardware device";
333 ctx->format = format_;
334 ctx->sw_format = swFormat_;
336 ctx->height = height_;
337 ctx->initial_pool_size = 20;
340 JAMI_ERR(
"Failed to initialize hardware frame context: %s (%d)",
356 hw->sw_format = swFormat_;
361 if ((linked_ = (framesCtx_ !=
nullptr))) {
362 JAMI_DBG() <<
"Hardware transcoding pipeline successfully set up for"
371std::unique_ptr<VideoFrame>
374 auto input =
frame.pointer();
376 throw std::runtime_error(
"Unable to transfer null frame");
380 throw std::runtime_error(
"Unable to transfer frame with invalid format");
383 auto out = std::make_unique<VideoFrame>();
394 throw std::runtime_error(
"Unable to transfer the frame from GPU");
410 auto ret = init_device_type(device);
423std::list<HardwareAccel>
426 std::list<HardwareAccel>
l;
428 for (
auto& api : *
list) {
429 const auto&
it = std::find(api.supportedCodecs.begin(), api.supportedCodecs.end(),
id);
430 if (
it != api.supportedCodecs.end()) {
433 if (
hwtype == api.hwType) {
441 accel.height_ = height;
442 accel.width_ = width;
443 accel.possible_devices_ = &api.possible_devices;
444 l.emplace_back(std::move(
accel));
Provides an abstraction layer to the hardware acceleration APIs in FFmpeg.
bool linkHardware(AVBufferRef *framesCtx)
Links this HardwareAccel's frames context with the passed in context.
static std::list< HardwareAccel > getCompatibleAccel(AVCodecID id, int width, int height, CodecType type)
static std::unique_ptr< VideoFrame > transferToMainMemory(const VideoFrame &frame, AVPixelFormat desiredFormat)
Transfers hardware frame to main memory.
std::string getCodecName() const
Gets the name of the codec.
std::unique_ptr< VideoFrame > transfer(const VideoFrame &frame)
Transfers a frame to/from the GPU memory.
const std::string & getName() const
Name of the hardware layer/API being used.
HardwareAccel(AVCodecID id, const std::string &name, AVHWDeviceType hwType, AVPixelFormat format, AVPixelFormat swFormat, CodecType type, bool dynBitrate)
Constructs a HardwareAccel object.
void setDetails(AVCodecContext *codecCtx)
Set some extra details in the codec context.
~HardwareAccel()
Dereferences hardware contexts.
int initAPI(bool linkable, AVBufferRef *framesCtx)
AVFrameSideData * av_frame_new_side_data_from_buf(AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef *buf)
void av_buffer_unref(AVBufferRef **buf)
std::string getError(int err)
static AVPixelFormat getFormatCb(AVCodecContext *codecCtx, const AVPixelFormat *formats)
static std::list< HardwareAPI > apiListEnc
static std::list< HardwareAPI > apiListDec
void emitSignal(Args... args)
std::list< std::pair< std::string, DeviceState > > possible_devices
std::vector< AVCodecID > supportedCodecs