static void qsv_frames_uninit(AVHWFramesContext *ctx) { QSVFramesContext *s = ctx->internal->priv; if (s->session_download) { MFXVideoVPP_Close(s->session_download); MFXClose(s->session_download); } s->session_download = NULL; s->session_download_init = 0; if (s->session_upload) { MFXVideoVPP_Close(s->session_upload); MFXClose(s->session_upload); } s->session_upload = NULL; s->session_upload_init = 0; #if HAVE_PTHREADS pthread_mutex_destroy(&s->session_lock); pthread_cond_destroy(&s->session_cond); #endif av_freep(&s->mem_ids); av_freep(&s->surface_ptrs); av_freep(&s->surfaces_internal); av_buffer_unref(&s->child_frames_ref); }
int ff_qsv_decode_close(QSVContext *q) { QSVFrame *cur = q->work_frames; if (q->session) MFXVideoDECODE_Close(q->session); while (q->async_fifo && av_fifo_size(q->async_fifo)) { QSVFrame *out_frame; mfxSyncPoint *sync; av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL); av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL); av_freep(&sync); } while (cur) { q->work_frames = cur->next; av_frame_free(&cur->frame); av_freep(&cur); cur = q->work_frames; } av_fifo_free(q->async_fifo); q->async_fifo = NULL; av_parser_close(q->parser); avcodec_free_context(&q->avctx_internal); if (q->internal_session) MFXClose(q->internal_session); return 0; }
static void qsv_device_free(AVHWDeviceContext *ctx) { AVQSVDeviceContext *hwctx = ctx->hwctx; QSVDevicePriv *priv = ctx->user_opaque; if (hwctx->session) MFXClose(hwctx->session); av_buffer_unref(&priv->child_device_ctx); av_freep(&priv); }
static void qsv_frames_uninit(AVHWFramesContext *ctx) { QSVFramesContext *s = ctx->internal->priv; if (s->session_download) { MFXVideoVPP_Close(s->session_download); MFXClose(s->session_download); } s->session_download = NULL; if (s->session_upload) { MFXVideoVPP_Close(s->session_upload); MFXClose(s->session_upload); } s->session_upload = NULL; av_freep(&s->mem_ids); av_freep(&s->surface_ptrs); av_freep(&s->surfaces_internal); av_buffer_unref(&s->child_frames_ref); }
bool obs_module_load(void) { mfxIMPL impl = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D11; mfxVersion ver = {{0 , 1}}; mfxSession session; mfxStatus sts; sts = MFXInit(impl, &ver, &session); if (sts == MFX_ERR_NONE) { obs_register_encoder(&obs_qsv_encoder); MFXClose(session); } else { impl = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D9; sts = MFXInit(impl, &ver, &session); if (sts == MFX_ERR_NONE) { obs_register_encoder(&obs_qsv_encoder); MFXClose(session); } } return true; }
int ff_qsv_decode_close(QSVContext *q) { QSVFrame *cur = q->work_frames; while (cur) { q->work_frames = cur->next; av_frame_free(&cur->frame); av_freep(&cur); cur = q->work_frames; } if (q->internal_session) MFXClose(q->internal_session); return 0; }
static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session, AVBufferRef *hw_frames_ref) { int ret; if (session) { q->session = session; } else if (hw_frames_ref) { if (q->internal_session) { MFXClose(q->internal_session); q->internal_session = NULL; } av_buffer_unref(&q->frames_ctx.hw_frames_ctx); q->frames_ctx.hw_frames_ctx = av_buffer_ref(hw_frames_ref); if (!q->frames_ctx.hw_frames_ctx) return AVERROR(ENOMEM); ret = ff_qsv_init_session_hwcontext(avctx, &q->internal_session, &q->frames_ctx, q->load_plugins, q->iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY); if (ret < 0) { av_buffer_unref(&q->frames_ctx.hw_frames_ctx); return ret; } q->session = q->internal_session; } else { if (!q->internal_session) { ret = ff_qsv_init_internal_session(avctx, &q->internal_session, q->load_plugins); if (ret < 0) return ret; } q->session = q->internal_session; } /* make sure the decoder is uninitialized */ MFXVideoDECODE_Close(q->session); return 0; }
static void qsvscale_uninit(AVFilterContext *ctx) { QSVScaleContext *s = ctx->priv; if (s->session) { MFXClose(s->session); s->session = NULL; } av_freep(&s->mem_ids_in); av_freep(&s->mem_ids_out); s->nb_mem_ids_in = 0; s->nb_mem_ids_out = 0; av_freep(&s->surface_ptrs_in); av_freep(&s->surface_ptrs_out); s->nb_surface_ptrs_in = 0; s->nb_surface_ptrs_out = 0; }
int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q) { QSVFrame *cur; MFXVideoENCODE_Close(q->session); if (q->internal_session) MFXClose(q->internal_session); q->session = NULL; q->internal_session = NULL; cur = q->work_frames; while (cur) { q->work_frames = cur->next; av_frame_free(&cur->frame); av_freep(&cur); cur = q->work_frames; } av_frame_free(&avctx->coded_frame); return 0; }
int ff_qsv_decode_close(QSVContext *q) { QSVFrame *cur = q->work_frames; while (cur) { q->work_frames = cur->next; av_frame_free(&cur->frame); av_freep(&cur); cur = q->work_frames; } av_fifo_free(q->async_fifo); q->async_fifo = NULL; av_parser_close(q->parser); avcodec_free_context(&q->avctx_internal); if (q->internal_session) MFXClose(q->internal_session); return 0; }
void CDecMSDKMVC::DestroyDecoder(bool bFull) { if (m_bDecodeReady) { MFXVideoDECODE_Close(m_mfxSession); m_bDecodeReady = FALSE; } { CAutoLock lock(&m_BufferCritSec); for (int i = 0; i < ASYNC_QUEUE_SIZE; i++) { ReleaseBuffer(&m_pOutputQueue[i]->surface); } memset(m_pOutputQueue, 0, sizeof(m_pOutputQueue)); for (auto it = m_BufferQueue.begin(); it != m_BufferQueue.end(); it++) { if (!(*it)->queued) { av_freep(&(*it)->surface.Data.Y); delete (*it); } } m_BufferQueue.clear(); } // delete MVC sequence buffers SAFE_DELETE(m_mfxExtMVCSeq.View); SAFE_DELETE(m_mfxExtMVCSeq.ViewId); SAFE_DELETE(m_mfxExtMVCSeq.OP); SAFE_DELETE(m_pAnnexBConverter); if (bFull) { if (m_mfxSession) { MFXClose(m_mfxSession); m_mfxSession = nullptr; } } }
IntelH264Decoder::~IntelH264Decoder() { MFXClose(Session); Session = nullptr; }
static int qsv_init_internal_session(AVHWFramesContext *ctx, mfxSession *session, int upload) { QSVFramesContext *s = ctx->internal->priv; AVQSVFramesContext *frames_hwctx = ctx->hwctx; QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv; int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); mfxFrameAllocator frame_allocator = { .pthis = ctx, .Alloc = frame_alloc, .Lock = frame_lock, .Unlock = frame_unlock, .GetHDL = frame_get_hdl, .Free = frame_free, }; mfxVideoParam par; mfxStatus err; err = MFXInit(device_priv->impl, &device_priv->ver, session); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n"); return AVERROR_UNKNOWN; } if (device_priv->handle) { err = MFXVideoCORE_SetHandle(*session, device_priv->handle_type, device_priv->handle); if (err != MFX_ERR_NONE) return AVERROR_UNKNOWN; } if (!opaque) { err = MFXVideoCORE_SetFrameAllocator(*session, &frame_allocator); if (err != MFX_ERR_NONE) return AVERROR_UNKNOWN; } memset(&par, 0, sizeof(par)); if (opaque) { par.ExtParam = s->ext_buffers; par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers); par.IOPattern = upload ? MFX_IOPATTERN_OUT_OPAQUE_MEMORY : MFX_IOPATTERN_IN_OPAQUE_MEMORY; } else { par.IOPattern = upload ? MFX_IOPATTERN_OUT_VIDEO_MEMORY : MFX_IOPATTERN_IN_VIDEO_MEMORY; } par.IOPattern |= upload ? MFX_IOPATTERN_IN_SYSTEM_MEMORY : MFX_IOPATTERN_OUT_SYSTEM_MEMORY; par.AsyncDepth = 1; par.vpp.In = frames_hwctx->surfaces[0].Info; /* Apparently VPP requires the frame rate to be set to some value, otherwise * init will fail (probably for the framerate conversion filter). Since we * are only doing data upload/download here, we just invent an arbitrary * value */ par.vpp.In.FrameRateExtN = 25; par.vpp.In.FrameRateExtD = 1; par.vpp.Out = par.vpp.In; err = MFXVideoVPP_Init(*session, &par); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session." "Surface upload/download will not be possible\n"); MFXClose(*session); *session = NULL; } return 0; }
static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, mfxIMPL implementation, AVHWDeviceContext *child_device_ctx, int flags) { AVQSVDeviceContext *hwctx = ctx->hwctx; mfxVersion ver = { { 3, 1 } }; mfxHDL handle; mfxHandleType handle_type; mfxStatus err; int ret; switch (child_device_ctx->type) { #if CONFIG_VAAPI case AV_HWDEVICE_TYPE_VAAPI: { AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx; handle_type = MFX_HANDLE_VA_DISPLAY; handle = (mfxHDL)child_device_hwctx->display; } break; #endif #if CONFIG_DXVA2 case AV_HWDEVICE_TYPE_DXVA2: { AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx; handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; handle = (mfxHDL)child_device_hwctx->devmgr; } break; #endif default: ret = AVERROR(ENOSYS); goto fail; } err = MFXInit(implementation, &ver, &hwctx->session); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " "%d.\n", err); ret = AVERROR_UNKNOWN; goto fail; } err = MFXQueryVersion(hwctx->session, &ver); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: %d.\n", err); ret = AVERROR_UNKNOWN; goto fail; } av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: API version is %d.%d, implementation version is %d.%d\n", MFX_VERSION_MAJOR, MFX_VERSION_MINOR, ver.Major, ver.Minor); MFXClose(hwctx->session); err = MFXInit(implementation, &ver, &hwctx->session); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: %d.\n", err); ret = AVERROR_UNKNOWN; goto fail; } err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error setting child device handle: " "%d\n", err); ret = AVERROR_UNKNOWN; goto fail; } ret = MFXQueryVersion(hwctx->session,&ver); if (ret == MFX_ERR_NONE) { av_log(ctx, AV_LOG_VERBOSE, "MFX compile/runtime API: %d.%d/%d.%d\n", MFX_VERSION_MAJOR, MFX_VERSION_MINOR, ver.Major, ver.Minor); } return 0; fail: if (hwctx->session) MFXClose(hwctx->session); return ret; }
int main(int argc, const char *argv[], bool bUsePrefix) { std::auto_ptr<MFX_DISP_HANDLE> allocatedHandle; MFX_DISP_HANDLE *pHandle; mfxIMPL impl = MFX_IMPL_AUTO; mfxVersion ver = {0, 0}; int i; if ((2 == argc) && ('?' == argv[1][0])) { printf("USAGE: %s -[s|h] [-v<version>]\n", argv[0]); printf("Where:\n"); printf(" -s - use MFX_IMPL_SOFTWARE dispatching type (optional).\n"); printf(" -h - use MFX_IMPL_HARDWARE dispatching type (optional).\n"); printf(" -ha - use MFX_IMPL_HARDWARE_ANY dispatching type (optional).\n"); printf(" -h2 - use MFX_IMPL_HARDWARE2 dispatching type (optional).\n"); printf(" -h3 - use MFX_IMPL_HARDWARE2 dispatching type (optional).\n"); printf(" -h4 - use MFX_IMPL_HARDWARE2 dispatching type (optional).\n"); printf(" -v - use specified API version (optional).\n"); printf(" <version> can be required in X.Y format\n"); return -1; } // parse parameters for (i = 1; i < argc; i += 1) { if ('-' == argv[i][0]) { switch (argv[i][1]) { // use MFX_IMPL_SOFTWARE dispatching type case 's': case 'S': impl = MFX_IMPL_SOFTWARE; break; // use MFX_IMPL_HARDWARE dispatching type case 'h': case 'H': { switch (argv[i][2]) { case 'a':impl = MFX_IMPL_HARDWARE_ANY;break; case '2':impl = MFX_IMPL_HARDWARE2;break; case '3':impl = MFX_IMPL_HARDWARE3;break; case '4':impl = MFX_IMPL_HARDWARE4;break; default :impl = MFX_IMPL_HARDWARE;break; } break; } // read specified API version case 'v': case 'V': { int x = 2; // read major version while (('0' <= argv[i][x]) && ('9' >= argv[i][x])) { ver.Major = ver.Major * 10 + (argv[i][x] - '0'); x += 1; } // skip delimiter if (argv[i][x]) { x += 1; } // read minor version while (('0' <= argv[i][x]) && ('9' >= argv[i][x])) { ver.Minor = ver.Minor * 10 + (argv[i][x] - '0'); x += 1; } } break; default: DISPATCHER_LOG_ERROR(("unknown parameter %s. Specify ? flag for help.\n", argv[i])); break; } } else { DISPATCHER_LOG_ERROR(("unknown parameter %s. Specify ? flag for help.\n", argv[i])); } } DISPATCHER_LOG_INFO(("current platform: %s\n", cPlatform)); DISPATCHER_LOG_INFO(("implementation: %s\n", DispatcherLog_GetMFXImplString(impl).c_str())); sdk_library library; if (bUsePrefix) { if (MFX_ERR_NONE == DISPATCHER_EXPOSED_PREFIX(MFXInit)(impl, ver.Version?&ver:NULL, (mfxSession*)&pHandle)) { DISPATCHER_EXPOSED_PREFIX(MFXClose)((mfxSession)pHandle); } } else { if (MFX_ERR_NONE == MFXInit(impl, ver.Version?&ver:NULL, (mfxSession*)&pHandle)) { MFXClose((mfxSession)pHandle); } } DISPATCHER_LOG_INFO(("DISPRESULT: platform=%-5s impl=%-21s ver=%d.%d : %s\n" , cPlatform , DispatcherLog_GetMFXImplString(impl).c_str() , ver.Major , ver.Minor , library.GetPath().empty()? "NOT FOUND" : library.GetPath().c_str())); return 0; } // int main(int argc, const char *argv[])
int hb_qsv_info_init() { static int init_done = 0; if (init_done) return (hb_qsv_info == NULL); init_done = 1; hb_qsv_info = calloc(1, sizeof(*hb_qsv_info)); if (hb_qsv_info == NULL) { hb_error("hb_qsv_info_init: alloc failure"); return -1; } mfxSession session; qsv_minimum_version.Major = HB_QSV_MINVERSION_MAJOR; qsv_minimum_version.Minor = HB_QSV_MINVERSION_MINOR; // check for software fallback if (MFXInit(MFX_IMPL_SOFTWARE, &qsv_minimum_version, &session) == MFX_ERR_NONE) { qsv_software_available = 1; preferred_implementation = MFX_IMPL_SOFTWARE; // our minimum is supported, but query the actual version MFXQueryVersion(session, &qsv_software_version); MFXClose(session); } // check for actual hardware support if (MFXInit(MFX_IMPL_HARDWARE_ANY|MFX_IMPL_VIA_ANY, &qsv_minimum_version, &session) == MFX_ERR_NONE) { qsv_hardware_available = 1; preferred_implementation = MFX_IMPL_HARDWARE_ANY|MFX_IMPL_VIA_ANY; // our minimum is supported, but query the actual version MFXQueryVersion(session, &qsv_hardware_version); MFXClose(session); } // check for version-specific or hardware-specific capabilities // we only use software as a fallback, so check hardware first if (qsv_hardware_available) { if (HB_CHECK_MFX_VERSION(qsv_hardware_version, 1, 6)) { hb_qsv_info->capabilities |= HB_QSV_CAP_OPTION2_BRC; hb_qsv_info->capabilities |= HB_QSV_CAP_MSDK_API_1_6; } if (hb_get_cpu_platform() == HB_CPU_PLATFORM_INTEL_HSW) { if (HB_CHECK_MFX_VERSION(qsv_hardware_version, 1, 7)) { hb_qsv_info->capabilities |= HB_QSV_CAP_OPTION2_TRELLIS; hb_qsv_info->capabilities |= HB_QSV_CAP_OPTION2_LOOKAHEAD; } hb_qsv_info->capabilities |= HB_QSV_CAP_H264_BPYRAMID; } } else if (qsv_software_available) { if (HB_CHECK_MFX_VERSION(qsv_software_version, 1, 6)) { hb_qsv_info->capabilities |= HB_QSV_CAP_MSDK_API_1_6; hb_qsv_info->capabilities |= HB_QSV_CAP_H264_BPYRAMID; } } // note: we pass a pointer to MFXInit but it never gets modified // let's make sure of it just to be safe though if (qsv_minimum_version.Major != HB_QSV_MINVERSION_MAJOR || qsv_minimum_version.Minor != HB_QSV_MINVERSION_MINOR) { hb_error("hb_qsv_info_init: minimum version (%d.%d) was modified", qsv_minimum_version.Major, qsv_minimum_version.Minor); } // success return 0; }