Skip to content

Conversation

@brittneysclark
Copy link
Contributor

Enables a pipeline for texture-based encoding with QSV. Utilizes OBS
NV12 output for encode to avoid offloading them from GPU, which will
increase performance. The option to select old QSV pipeline still
remains and will fallback if new pipeline fails.

@Fenrirthviti
Copy link
Member

Fenrirthviti commented Mar 28, 2019

Great to see! Do you know if PR #1609 will work with this new implementation?

We are discussing ways to reduce the number of encoders shown, and rescaling output seems to be the only reason (given that this properly falls back to the old implementation) to show both.

@Gol-D-Ace
Copy link
Collaborator

Gol-D-Ace commented May 11, 2019

Gave this a quick try.

Compared to the new NVENC implementation there seems to be no fallback to the old method while using advanced output mode. There seems to be fallback in simple output mode though.
Or is simple output mode not even using the new implementation?

The log file also apparently doesn't tell which implementation gets used like with NVENC.

@YaoxinShi
Copy link

The fallback code is here:

static void *obs_qsv_create_tex(obs_data_t *settings, obs_encoder_t *encoder)
{
if (obs_nv12_tex_active()) {
return obs_qsv_create(settings, encoder);
} else {
return obs_encoder_create_rerouted(encoder, "obs_qsv11");
}
}

@Gol-D-Ace
Copy link
Collaborator

Sorry I guess I was not clear enough.
I didn't meant NV12 being available but rather OBS not running on the Intel GPU.

@YaoxinShi
Copy link

@ Gol-D-Ace
The second patch in this PR fix the issue you mention.
A GPU checking code is added during QSV plugin creation. If not on Intel GPU, it will fall back to old QSV plugin.

@brittneysclark
Copy link
Contributor Author

The continuous integration test says there are conflicts with the second commit, but I cannot see what they are. Is this something I need to address? How can I tell what the problem is?

@Fenrirthviti
Copy link
Member

There have been other changes to the same QSV files, so you need to rebase your branch against current master to resolve the conflicts.

@YaoxinShi
Copy link

Dear reviewers,

Any comments about this patch? Can it be merged to master now?

Thanks, Yaoxin

@kkartaltepe
Copy link
Collaborator

I think we generally want to avoid merge commits in PRs.

If you drop the merge commit then rebase the PR onto master with the 'theirs' merge strategy you should be mostly good. Then just go back and edit each commit with clang format. (you can do both steps during the rebase by rebasing interactive with edit mode and the 'theirs' merge strategy).

@YaoxinShi
Copy link

@kkartaltepe, from below check result, this change has no conflicts with the master branch now.

@YaoxinShi
Copy link

Hi,

Any help needed to merge this patch to master? It can help to improve and performance a lot and make 4k streaming ready for intel QSV.

Thanks, Yaoxin

@RytoEX
Copy link
Member

RytoEX commented Sep 23, 2019

@YaoxinShi
As @kkartaltepe and @Fenrirthviti said earlier, we generally want to avoid merge commits in PRs.

Rebase the commits onto the current master branch, and make sure the commits are formatted correctly with the project's clang format settings.

@Fenrirthviti
Copy link
Member

Just a reminder that this PR will still need to be re-based. It is not mergable in the current state.

Please re-base to remove the merge commits from the PR. If you need assistance with how to do this, please let us know.

@brittneysclark
Copy link
Contributor Author

@Fenrirthviti -- yes, please help! What is the best way to rebase and remove merge commits?

@RytoEX
Copy link
Member

RytoEX commented Oct 9, 2019

yes, please help! What is the best way to rebase and remove merge commits?

@brittneysclark
In your local Git repo, if you have your fork (brittneysclark/obs-studio) set as a remote named "origin" and obsproject/obs-studio set as a separate remote named "upstream" (you can check your remotes by executing git remote -v), then the following should get you to a cleaner state:

git checkout master
git fetch upstream
git pull --ff-only upstream master
git checkout qsv_texture_based_encoding
git rebase master
git push -f origin

After this, you will still have to merge your fixup commit's contents into the appropriate earlier commits.

@brittneysclark brittneysclark force-pushed the qsv_texture_based_encoding branch from d4c697f to a95417e Compare October 10, 2019 23:50
@YaoxinShi
Copy link

@RytoEX, seems the Linux build failure is an environment issue. Do you know how to solve this?

E: Failed to fetch https://packages.microsoft.com/ubuntu/16.04/prod/dists/xenial/InRelease Clearsigned file isn't valid, got 'NOSPLIT' (does the network require authentication?)

Thanks, Yaoxin

@Fenrirthviti
Copy link
Member

You can ignore those build failures, it's an issue with Azure's apt system.

@RytoEX
Copy link
Member

RytoEX commented Oct 16, 2019

@YaoxinShi @brittneysclark
Please use the prefix "obs-qsv11" for commits to the obs-qsv11 plugin.

Hopefully the CI platforms will cooperate on the next build.

@YaoxinShi
Copy link

@brittneysclark , can you help on the commit info change?

Thanks, Yaoxin

@brittneysclark brittneysclark force-pushed the qsv_texture_based_encoding branch from a95417e to a01d3cc Compare October 16, 2019 18:46
@WizardCM WizardCM added the Enhancement Improvement to existing functionality label Oct 17, 2019
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);

mfxU8 *pTemp = m_outBitstream.Data;
memcpy(&m_outBitstream, &m_pTaskPool[m_nFirstSyncTask].mfxBS,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this copy be avoided? Both m_outBitstream and m_pTaskPool[m_nFirstSyncTask].mfxBS are managed by outside MSDK so application for sure has a chance to pass m_pTaskPool[m_nFirstSyncTask].mfxBS as encoded target and avoid temporal m_outBitstream.


if (MFX_ERR_NONE < sts && !m_pTaskPool[nTaskIdx].syncp) {
// Repeat the call if warning and no output
if (MFX_WRN_DEVICE_BUSY == sts)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know code like

sts = EncodeFrameAsync();
if (MFX_WRN_DEVICE_BUSY == sts)
  MSDK_SLEEP(1);

is widely used in ffmpeg but there is a better solution. In most of the cases MFX_WRN_DEVICE_BUSY means component(decoder/vpp/encoder) "overfeeding". The best way to handle is is to check whether app has not yet handled syncPoint and if so call SyncOperation, like this

sts = EncodeFrameAsync();
if (MFX_WRN_DEVICE_BUSY == sts) {
  if (last_sync_point) {
    SyncOperation(last_sync_point);
    last_sync_point = NULL;
  } else {
  MSDK_SLEEP(1);
  }
}

In most of the cases it will avoid polling and reduce CPU usage.

mfxStatus (MFX_CDECL *Unlock) (mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr);
mfxStatus (MFX_CDECL *GetHDL) (mfxHDL pthis, mfxMemId mid, mfxHDL *handle);
mfxStatus (MFX_CDECL *Free) (mfxHDL pthis, mfxFrameAllocResponse *response);
mfxStatus (MFX_CDECL *CopyTex) (mfxHDL pthis, mfxMemId mid, mfxU32 tex_handle, mfxU64 lock_key, mfxU64 *next_key);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being a MediaSDK developer, I can say this is wrong/bad approach. mfxvideo.h is an external dependency, you can't control it. If tomorrow official MSDK API gets CopyTex function , you'll never be able to use latest MSDK headers/packages.

return false;
}

hr = factory->lpVtbl->EnumAdapters(factory, 0, &adapter);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can Intel Gfx be the 1st adapter (not zero one)?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DG1 on an AMD APU system in theory?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

@brittneysclark brittneysclark force-pushed the qsv_texture_based_encoding branch from 0124f3e to 7486230 Compare March 10, 2020 16:37
@brittneysclark brittneysclark force-pushed the qsv_texture_based_encoding branch from 7486230 to ffc1b23 Compare March 16, 2020 18:00
@jp9000
Copy link
Member

jp9000 commented Apr 15, 2020

When I made the new NVENC implementation, the biggest mistake was splitting it to "(new)". Instead, it should have just fell back automatically internally. I've provided a patch for you to try out which treats it more seamlessly so the user just gets the best option whenever available without having to configure it:

diff --git a/plugins/obs-qsv11/obs-qsv11.c b/plugins/obs-qsv11/obs-qsv11.c
index 0eb4a3925..f11095820 100644
--- a/plugins/obs-qsv11/obs-qsv11.c
+++ b/plugins/obs-qsv11/obs-qsv11.c
@@ -112,12 +112,6 @@ static const char *obs_qsv_getname(void *type_data)
 	return "QuickSync H.264";
 }
 
-static const char *obs_qsv_getname_tex(void *type_data)
-{
-	UNUSED_PARAMETER(type_data);
-	return "QuickSync H.264 (new)";
-}
-
 static void obs_qsv_stop(void *data);
 
 static void clear_data(struct obs_qsv *obsqsv)
@@ -657,17 +651,23 @@ static void *obs_qsv_create_tex(obs_data_t *settings, obs_encoder_t *encoder)
 	if (!is_intel_gpu_primary()) {
 		blog(LOG_INFO,
 		     ">>> app not on intel GPU, fall back to old qsv encoder");
-		return obs_encoder_create_rerouted(encoder, "obs_qsv11");
+		return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
 	}
 
-	if (obs_nv12_tex_active()) {
-		blog(LOG_INFO, ">>> new qsv encoder");
-		return obs_qsv_create(settings, encoder);
-	} else {
+	if (!obs_nv12_tex_active()) {
 		blog(LOG_INFO,
 		     ">>> nv12 tex not active, fall back to old qsv encoder");
-		return obs_encoder_create_rerouted(encoder, "obs_qsv11");
+		return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
+	}
+
+	if (obs_encoder_scaling_enabled(encoder)) {
+		blog(LOG_INFO,
+		     ">>> encoder scaling active, fall back to old qsv encoder");
+		return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
 	}
+
+	blog(LOG_INFO, ">>> new qsv encoder");
+	return obs_qsv_create(settings, encoder);
 }
 
 static bool obs_qsv_extra_data(void *data, uint8_t **extra_data, size_t *size)
@@ -924,7 +924,7 @@ static bool obs_qsv_encode_tex(void *data, uint32_t handle, int64_t pts,
 }
 
 struct obs_encoder_info obs_qsv_encoder = {
-	.id = "obs_qsv11",
+	.id = "obs_qsv11_soft",
 	.type = OBS_ENCODER_VIDEO,
 	.codec = "h264",
 	.get_name = obs_qsv_getname,
@@ -937,21 +937,22 @@ struct obs_encoder_info obs_qsv_encoder = {
 	.get_extra_data = obs_qsv_extra_data,
 	.get_sei_data = obs_qsv_sei,
 	.get_video_info = obs_qsv_video_info,
-	.caps = OBS_ENCODER_CAP_DYN_BITRATE,
+	.caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
 };
 
 struct obs_encoder_info obs_qsv_encoder_tex = {
-	.id = "obs_qsv11_tex",
+	.id = "obs_qsv11",
 	.type = OBS_ENCODER_VIDEO,
 	.codec = "h264",
-	.get_name = obs_qsv_getname_tex,
+	.get_name = obs_qsv_getname,
 	.create = obs_qsv_create_tex,
 	.destroy = obs_qsv_destroy,
-	.caps = OBS_ENCODER_CAP_PASS_TEXTURE,
+	.caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE,
 	.encode_texture = obs_qsv_encode_tex,
 	.update = obs_qsv_update,
 	.get_properties = obs_qsv_props,
 	.get_defaults = obs_qsv_defaults,
 	.get_extra_data = obs_qsv_extra_data,
 	.get_sei_data = obs_qsv_sei,
-	.get_video_info = obs_qsv_video_info};
+	.get_video_info = obs_qsv_video_info,
+};

Could you try this out and let me know if this is okay? You'll notice "(new)" no longer shows up, instead it automatically tries to use texture-based encoding if available, otherwise just falls back automatically.

@jp9000
Copy link
Member

jp9000 commented Apr 15, 2020

Oh, and one thing I noticed is that you left out OBS_ENCODER_CAP_DYN_BITRATE from your new structure. I don't think that was intended so I added it back in. If that was intended, let me know.

@YaoxinShi
Copy link

@jp9000
Thanks for the comments. I have tried above modification on 3 Intel platforms and it works well.
-- Yaoxin

Enables a pipeline for texture-based encoding with QSV. Utilizes OBS
NV12 output for encode to avoid offloading them from GPU, which will
increase performance. The option to select old QSV pipeline still
remains and will fallback if new pipeline fails.
@jp9000 jp9000 force-pushed the qsv_texture_based_encoding branch from ffc1b23 to cc896b6 Compare April 17, 2020 16:07
@jp9000 jp9000 merged commit 05b6626 into obsproject:master Apr 18, 2020
jp9000 added a commit that referenced this pull request Apr 26, 2020
…d_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
prateekshadas pushed a commit to caffeinetv/obs-studio that referenced this pull request Dec 3, 2020
…xture_based_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
prateekshadas pushed a commit to caffeinetv/obs-studio that referenced this pull request Dec 3, 2020
…xture_based_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
prateekshadas pushed a commit to caffeinetv/obs-studio that referenced this pull request Mar 2, 2021
…xture_based_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
prateekshadas pushed a commit to caffeinetv/obs-studio that referenced this pull request Mar 2, 2021
…xture_based_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
prateekshadas pushed a commit to caffeinetv/obs-studio that referenced this pull request Mar 2, 2021
…xture_based_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
prateekshadas pushed a commit to caffeinetv/obs-studio that referenced this pull request Jan 18, 2022
…xture_based_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
prateekshadas pushed a commit to caffeinetv/obs-studio that referenced this pull request Jan 26, 2022
…xture_based_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
prateekshadas pushed a commit to caffeinetv/obs-studio that referenced this pull request Jan 27, 2022
…xture_based_encoding"

This reverts commit 05b6626, reversing
changes made to 01df98b.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Improvement to existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants