diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index aac6ce6..5e6f462 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -214,6 +214,73 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
     return 0;
 }
 
+int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
+                               AVBufferRef *device_ref, const char *load_plugins)
+{
+    static const mfxHandleType handle_types[] = {
+        MFX_HANDLE_VA_DISPLAY,
+        MFX_HANDLE_D3D9_DEVICE_MANAGER,
+        MFX_HANDLE_D3D11_DEVICE,
+    };
+    AVHWDeviceContext    *device_ctx = (AVHWDeviceContext*)device_ref->data;
+    AVQSVDeviceContext *device_hwctx = device_ctx->hwctx;
+    mfxSession        parent_session = device_hwctx->session;
+
+    mfxSession    session;
+    mfxVersion    ver;
+    mfxIMPL       impl;
+    mfxHDL        handle = NULL;
+    mfxHandleType handle_type;
+    mfxStatus err;
+
+    int i, ret;
+
+    err = MFXQueryIMPL(parent_session, &impl);
+    if (err == MFX_ERR_NONE)
+        err = MFXQueryVersion(parent_session, &ver);
+    if (err != MFX_ERR_NONE) {
+        av_log(avctx, AV_LOG_ERROR, "Error querying the session attributes\n");
+        return ff_qsv_error(err);
+    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) {
+        err = MFXVideoCORE_GetHandle(parent_session, handle_types[i], &handle);
+        if (err == MFX_ERR_NONE) {
+            handle_type = handle_types[i];
+            break;
+        }
+        handle = NULL;
+    }
+    if (!handle) {
+        av_log(avctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved "
+               "from the session\n");
+    }
+
+    err = MFXInit(impl, &ver, &session);
+    if (err != MFX_ERR_NONE) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Error initializing a child MFX session: %d\n", err);
+        return ff_qsv_error(err);
+    }
+
+    if (handle) {
+        err = MFXVideoCORE_SetHandle(session, handle_type, handle);
+        if (err != MFX_ERR_NONE) {
+            av_log(avctx, AV_LOG_ERROR, "Error setting a HW handle: %d\n", err);
+            return ff_qsv_error(err);
+        }
+    }
+
+    ret = qsv_load_plugins(session, load_plugins, avctx);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Error loading plugins\n");
+        return ret;
+    }
+
+    *psession = session;
+    return 0;
+}
+
 static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
                                  mfxFrameAllocResponse *resp)
 {
@@ -265,11 +332,6 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession,
                                   QSVFramesContext *qsv_frames_ctx,
                                   const char *load_plugins, int opaque)
 {
-    static const mfxHandleType handle_types[] = {
-        MFX_HANDLE_VA_DISPLAY,
-        MFX_HANDLE_D3D9_DEVICE_MANAGER,
-        MFX_HANDLE_D3D11_DEVICE,
-    };
     mfxFrameAllocator frame_allocator = {
         .pthis  = qsv_frames_ctx,
         .Alloc  = qsv_frame_alloc,
@@ -281,59 +343,16 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession,
 
     AVHWFramesContext    *frames_ctx = (AVHWFramesContext*)qsv_frames_ctx->hw_frames_ctx->data;
     AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
-    AVQSVDeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
-    mfxSession        parent_session = device_hwctx->session;
 
     mfxSession    session;
-    mfxVersion    ver;
-    mfxIMPL       impl;
-    mfxHDL        handle = NULL;
-    mfxHandleType handle_type;
     mfxStatus err;
 
     int i, ret;
 
-    err = MFXQueryIMPL(parent_session, &impl);
-    if (err == MFX_ERR_NONE)
-        err = MFXQueryVersion(parent_session, &ver);
-    if (err != MFX_ERR_NONE) {
-        av_log(avctx, AV_LOG_ERROR, "Error querying the session attributes\n");
-        return ff_qsv_error(err);
-    }
-
-    for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) {
-        err = MFXVideoCORE_GetHandle(parent_session, handle_types[i], &handle);
-        if (err == MFX_ERR_NONE) {
-            handle_type = handle_types[i];
-            break;
-        }
-        handle = NULL;
-    }
-    if (!handle) {
-        av_log(avctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved "
-               "from the session\n");
-    }
-
-    err = MFXInit(impl, &ver, &session);
-    if (err != MFX_ERR_NONE) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Error initializing a child MFX session: %d\n", err);
-        return ff_qsv_error(err);
-    }
-
-    if (handle) {
-        err = MFXVideoCORE_SetHandle(session, handle_type, handle);
-        if (err != MFX_ERR_NONE) {
-            av_log(avctx, AV_LOG_ERROR, "Error setting a HW handle: %d\n", err);
-            return ff_qsv_error(err);
-        }
-    }
-
-    ret = qsv_load_plugins(session, load_plugins, avctx);
-    if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error loading plugins\n");
+    ret = ff_qsv_init_session_device(avctx, &session,
+                                     frames_ctx->device_ref, load_plugins);
+    if (ret < 0)
         return ret;
-    }
 
     if (!opaque) {
         av_freep(&qsv_frames_ctx->mids);
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 5d2a216..e32148c 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -70,6 +70,9 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc);
 int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
                                  const char *load_plugins);
 
+int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *session,
+                               AVBufferRef *device_ref, const char *load_plugins);
+
 int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *session,
                                   QSVFramesContext *qsv_frames_ctx,
                                   const char *load_plugins, int opaque);
