-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unity Video Capture backend #56
Conversation
Looks great! Do you mind if I commit to your branch and fix up the remaining issues? |
By all means! I'm trying to fix it too. |
If the if (RegGetValueW(HKEY_CLASSES_ROOT, guid, L"", RRF_RT_REG_SZ, NULL, &str, &size) != ERROR_SUCCESS) return false; with the following: HKEY key;
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, guid, 0, KEY_READ, &key) != ERROR_SUCCESS) return false;
if (RegQueryValueExW(key, L"", NULL, NULL, (LPBYTE)str, &size) != ERROR_SUCCESS) return false; I don’t know which one is better if both work though. |
I did the following changes:
I'll do some more testing etc. later today, also it has to be added to CI.
|
Note that |
You're right, didn't think of that. It may make sense to remove the numeric case altogether for now since it becomes ambiguous if multiple backends do the same. It probably makes more sense for each backend to expose all available devices and then let the user choose, based on some criteria, but that's out of scope in this PR. |
OK, let’s remove it then. |
I've added the proper pixel format conversions now and it looks fine for me. Could you give it a try? If it doesn't look right for you, then your frames are probably not in RGBA channel order. This would be fully opaque red: |
I just stumbled upon these: |
I updated the README and added a new sample which sends transparent gif frames to the cam. I included some instructions on how to configure OBS to capture in RGBA. |
@@ -58,7 +58,7 @@ struct SharedImageMemory | |||
callback(m_pSharedBuf->width, m_pSharedBuf->height, m_pSharedBuf->stride, (EFormat)m_pSharedBuf->format, (EResizeMode)m_pSharedBuf->resizemode, (EMirrorMode)m_pSharedBuf->mirrormode, m_pSharedBuf->timeout, m_pSharedBuf->data, callback_data); | |||
ReleaseMutex(m_hMutex); //unlock mutex | |||
|
|||
return RECEIVERES_NEWFRAME; | |||
return (IsNewFrame ? RECEIVERES_NEWFRAME : RECEIVERES_OLDFRAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this line, the timeout should be set to a large enough number (previously I set it to 100000000) in milliseconds or the frame will be cleared immediately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just don't want the frame being cleared even after a day, but that's up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the receiver, so there's no point changing any code in it as it won't be used by pyvirtualcam but rather by the filter DLL that you install. I'll have a look at the timeout value on the sender side, it's a fair point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah.. the timeout definitely needs to be higher, otherwise low framerates also lead to interruptions. I've changed it to 1 day.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The receive method is used here and this is the only place which prints "Unity has stopped sending image data". That's OK if you think 1 day is enough (though I want to keep the frame forever).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The receive method is only used in the filter. I can remove the receive method in the backend and everything would compile fine. Do you see? Any change in that method does not have an effect on our side. The shared.inl is a header which gets pulled in both by the receiver (filter) and sender (us). Some code is only used by one of both.
What's your use case for keeping a frame longer than a day? I'm happy to make the timeout longer but would like to understand a bit more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The timeout is of type int
(signed 32 bit) and since it's in milliseconds the maximum you can get is something like 24 days.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to the maximum now :)
d03b9a6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, no special reason – just think that I am a perfectionist.
Anyway, the point is that this is actually a feature written in README.md of UnityCapture. So I am opening an issue to due with it.
schellingb/UnityCapture#18
Sorry for letting you wait. I am in a different time zone from you. |
I found an issue when using multiple cameras which requires a fix upstream schellingb/UnityCapture#17. |
So should all of them be changed to wide-characters now? This is a minor problem though. |
Sure, I won't have time for it though. So far, all the virtual cameras didn't need it as the names are all ascii. And I have a feeling that probably no one is using custom names for unity capture. Do you have a use case? |
I think so too. Actually I don't need it either, so let's just put it aside. |
(Discussion: #51)
Many of the files are rewrote for this pull request. Just as you said, I'm not including the install scripts though the
shared.inl
is necessary. And I'm finally not going to touch theUnityCaptureFilter.cpp
file.Looking at the source code of
UnityCaptureFilter.cpp
:name #index
except for index 0, which is namedname
. Yes, the default value ofname
isUnity Video Capture
, but it can be changed by the user by the install script argumentUnityCaptureName
. The number of devices installed is specified by the argumentUnityCaptureDevices
with the default value 1. All devices have different CLSID in the format5C2CD55C-92AD-4999-8666-912BD3E700XX
.With the above information:
device
parameter by the following condition:device
is missing, we iterate through 0 to 74 to check for the first device registered;device
is a number-like string from0
to74
, the index is used;device
is assumed to be the device name; we iterate through 0 to 74 to check ifdevice
matches the name given by the register key; or an error is fired if there are no matches.device()
function returns the device name given by the register key, not necessaryUnity Video Capture
.A few more things to notice:
RegGetValueW
method.argb
tobgra
inimage_formats.h
due to consistency, but of course you can if you want.uint32_t
are changed toint32_t
, though only theargb_to_argb
method has actual use to negative numbers.std::wstring
instead ofstd::string
.fps
parameter is not used currently.shared.inl
file insetup.py
.Please let me know if there's anything unclear or forgotten.