msdk: Reorganize context preparation code

Split it out into a separate function with early exits to make the
flow clearer, and document what the function is doing clearly.
No functional changes.
This commit is contained in:
Nirbheek Chauhan 2020-01-17 10:43:11 +05:30 committed by Haihao Xiang
parent e83d5fd8d6
commit 6834a12112
5 changed files with 146 additions and 102 deletions

View file

@ -147,7 +147,7 @@ found:
}
gboolean
gst_msdk_context_prepare (GstElement * element, GstMsdkContext ** context_ptr)
gst_msdk_context_find (GstElement * element, GstMsdkContext ** context_ptr)
{
g_return_val_if_fail (element != NULL, FALSE);
g_return_val_if_fail (context_ptr != NULL, FALSE);

View file

@ -44,7 +44,7 @@
G_BEGIN_DECLS
gboolean
gst_msdk_context_prepare (GstElement * element, GstMsdkContext ** context_ptr);
gst_msdk_context_find (GstElement * element, GstMsdkContext ** context_ptr);
gboolean
gst_msdk_context_get_context (GstContext * context, GstMsdkContext ** msdk_context);

View file

@ -702,48 +702,62 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
return GST_FLOW_OK;
}
static gboolean
gst_msdkdec_context_prepare (GstMsdkDec * thiz)
{
/* Try to find an existing context from the pipeline. This may (indirectly)
* invoke gst_msdkdec_set_context, which will set thiz->context. */
if (!gst_msdk_context_find (GST_ELEMENT_CAST (thiz), &thiz->context))
return FALSE;
/* TODO: Currently d3d allocator is not implemented.
* So decoder uses system memory by default on Windows.
*/
#ifndef _WIN32
thiz->use_video_memory = TRUE;
#else
thiz->use_video_memory = FALSE;
#endif
GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
thiz->context);
if (!gst_msdk_context_get_job_type (thiz->context) & GST_MSDK_JOB_DECODER) {
gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_DECODER);
return TRUE;
}
/* Found an existing context that's already being used as a decoder, clone
* the MFX session inside it to create a new one */
{
GstMsdkContext *parent_context, *msdk_context;
GST_INFO_OBJECT (thiz, "Creating new context %" GST_PTR_FORMAT " with "
"joined session", thiz->context);
parent_context = thiz->context;
msdk_context = gst_msdk_context_new_with_parent (parent_context);
if (!msdk_context) {
GST_ERROR_OBJECT (thiz, "Failed to create a context with parent context "
"as %" GST_PTR_FORMAT, parent_context);
return FALSE;
}
thiz->context = msdk_context;
gst_msdk_context_add_shared_async_depth (thiz->context,
gst_msdk_context_get_shared_async_depth (parent_context));
gst_object_unref (parent_context);
}
return TRUE;
}
static gboolean
gst_msdkdec_start (GstVideoDecoder * decoder)
{
GstMsdkDec *thiz = GST_MSDKDEC (decoder);
if (gst_msdk_context_prepare (GST_ELEMENT_CAST (thiz), &thiz->context)) {
GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
thiz->context);
/* TODO: Currently d3d allocator is not implemented.
* So decoder uses system memory by default on Windows.
*/
#ifndef _WIN32
thiz->use_video_memory = TRUE;
#else
thiz->use_video_memory = FALSE;
#endif
if (gst_msdk_context_get_job_type (thiz->context) & GST_MSDK_JOB_DECODER) {
GstMsdkContext *parent_context, *msdk_context;
parent_context = thiz->context;
msdk_context = gst_msdk_context_new_with_parent (parent_context);
if (!msdk_context) {
GST_ERROR_OBJECT (thiz, "Context creation failed");
return FALSE;
}
thiz->context = msdk_context;
gst_msdk_context_add_shared_async_depth (thiz->context,
gst_msdk_context_get_shared_async_depth (parent_context));
gst_object_unref (parent_context);
GST_INFO_OBJECT (thiz,
"Creating new context %" GST_PTR_FORMAT " with joined session",
thiz->context);
} else {
gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_DECODER);
}
} else {
if (!gst_msdkdec_context_prepare (thiz)) {
if (!gst_msdk_context_ensure_context (GST_ELEMENT_CAST (thiz),
thiz->hardware, GST_MSDK_JOB_DECODER))
return FALSE;

View file

@ -1597,43 +1597,58 @@ invalid_frame:
}
}
static gboolean
gst_msdkenc_context_prepare (GstMsdkEnc * thiz)
{
/* Try to find an existing context from the pipeline. This may (indirectly)
* invoke gst_msdkenc_set_context, which will set thiz->context. */
if (!gst_msdk_context_find (GST_ELEMENT_CAST (thiz), &thiz->context))
return FALSE;
GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
thiz->context);
/* Check GST_MSDK_JOB_VPP and GST_MSDK_JOB_ENCODER together to avoid sharing context
* between VPP and ENCODER
* Example:
* gst-launch-1.0 videotestsrc ! video/x-raw,format=I420 ! msdkh264enc ! \
* msdkh264dec ! msdkvpp ! video/x-raw,format=YUY2 ! fakesink
*/
if (!gst_msdk_context_get_job_type (thiz->context) & (GST_MSDK_JOB_VPP |
GST_MSDK_JOB_ENCODER)) {
gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_ENCODER);
return TRUE;
}
/* Found an existing context that's already being used as an encoder, clone
* the MFX session inside it to create a new one */
{
GstMsdkContext *parent_context, *msdk_context;
GST_INFO_OBJECT (thiz, "Creating new context %" GST_PTR_FORMAT " with "
"joined session", thiz->context);
parent_context = thiz->context;
msdk_context = gst_msdk_context_new_with_parent (parent_context);
if (!msdk_context) {
GST_ERROR_OBJECT (thiz, "Failed to create a context with parent context "
"as %" GST_PTR_FORMAT, parent_context);
return FALSE;
}
thiz->context = msdk_context;
gst_object_unref (parent_context);
}
return TRUE;
}
static gboolean
gst_msdkenc_start (GstVideoEncoder * encoder)
{
GstMsdkEnc *thiz = GST_MSDKENC (encoder);
if (gst_msdk_context_prepare (GST_ELEMENT_CAST (thiz), &thiz->context)) {
GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
thiz->context);
/* Check GST_MSDK_JOB_VPP and GST_MSDK_JOB_ENCODER together to avoid sharing context
* between VPP and ENCODER
* Example:
* gst-launch-1.0 videotestsrc ! video/x-raw,format=I420 ! msdkh264enc ! \
* msdkh264dec ! msdkvpp ! video/x-raw,format=YUY2 ! fakesink
*/
if (gst_msdk_context_get_job_type (thiz->context) & (GST_MSDK_JOB_VPP |
GST_MSDK_JOB_ENCODER)) {
GstMsdkContext *parent_context, *msdk_context;
parent_context = thiz->context;
msdk_context = gst_msdk_context_new_with_parent (parent_context);
if (!msdk_context) {
GST_ERROR_OBJECT (thiz, "Context creation failed");
return FALSE;
}
thiz->context = msdk_context;
gst_object_unref (parent_context);
GST_INFO_OBJECT (thiz,
"Creating new context %" GST_PTR_FORMAT " with joined session",
thiz->context);
} else {
gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_ENCODER);
}
} else {
if (!gst_msdkenc_context_prepare (thiz)) {
if (!gst_msdk_context_ensure_context (GST_ELEMENT_CAST (thiz),
thiz->hardware, GST_MSDK_JOB_ENCODER))
return FALSE;

View file

@ -189,42 +189,57 @@ gst_msdkvpp_add_extra_param (GstMsdkVPP * thiz, mfxExtBuffer * param)
}
}
static gboolean
gst_msdkvpp_context_prepare (GstMsdkVPP * thiz)
{
/* Try to find an existing context from the pipeline. This may (indirectly)
* invoke gst_msdkvpp_set_context, which will set thiz->context. */
if (!gst_msdk_context_find (GST_ELEMENT_CAST (thiz), &thiz->context))
return FALSE;
GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
thiz->context);
/* Check GST_MSDK_JOB_VPP and GST_MSDK_JOB_ENCODER together to avoid sharing context
* between VPP and ENCODER
* Example:
* gst-launch-1.0 videotestsrc ! msdkvpp ! video/x-raw,format=YUY2 ! msdkh264enc ! fakesink
*/
if (!gst_msdk_context_get_job_type (thiz->context) & (GST_MSDK_JOB_VPP |
GST_MSDK_JOB_ENCODER)) {
gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_VPP);
return TRUE;
}
/* Found an existing context that's already being used as VPP, so clone the
* MFX session inside it to create a new one */
{
GstMsdkContext *parent_context, *msdk_context;
GST_INFO_OBJECT (thiz, "Creating new context %" GST_PTR_FORMAT " with "
"joined session", thiz->context);
parent_context = thiz->context;
msdk_context = gst_msdk_context_new_with_parent (parent_context);
if (!msdk_context) {
GST_ERROR_OBJECT (thiz, "Failed to create a context with parent context "
"as %" GST_PTR_FORMAT, parent_context);
return FALSE;
}
thiz->context = msdk_context;
gst_object_unref (parent_context);
}
return TRUE;
}
static gboolean
ensure_context (GstBaseTransform * trans)
{
GstMsdkVPP *thiz = GST_MSDKVPP (trans);
if (gst_msdk_context_prepare (GST_ELEMENT_CAST (thiz), &thiz->context)) {
GST_INFO_OBJECT (thiz, "Found context from neighbour %" GST_PTR_FORMAT,
thiz->context);
/* Check GST_MSDK_JOB_VPP and GST_MSDK_JOB_ENCODER together to avoid sharing context
* between VPP and ENCODER
* Example:
* gst-launch-1.0 videotestsrc ! msdkvpp ! video/x-raw,format=YUY2 ! msdkh264enc ! fakesink
*/
if (gst_msdk_context_get_job_type (thiz->context) & (GST_MSDK_JOB_ENCODER |
GST_MSDK_JOB_VPP)) {
GstMsdkContext *parent_context, *msdk_context;
parent_context = thiz->context;
msdk_context = gst_msdk_context_new_with_parent (parent_context);
if (!msdk_context) {
GST_ERROR_OBJECT (thiz, "Context creation failed");
return FALSE;
}
thiz->context = msdk_context;
gst_object_unref (parent_context);
GST_INFO_OBJECT (thiz,
"Creating new context %" GST_PTR_FORMAT " with joined session",
thiz->context);
} else {
gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_VPP);
}
} else {
if (!gst_msdkvpp_context_prepare (thiz)) {
if (!gst_msdk_context_ensure_context (GST_ELEMENT_CAST (thiz),
thiz->hardware, GST_MSDK_JOB_VPP))
return FALSE;