-
Notifications
You must be signed in to change notification settings - Fork 241
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
[DRM][Playready] Initial implementation #1315
base: Omega
Are you sure you want to change the base?
Conversation
Hi, some basic initial considerations i invite you to temporary stop your development I just had a very quick look at the code without going in depth at glance i see that there are some code that dont follow our standards, suggest you to give a quick look at our guidelines: new files rules: they must have always our SPDX license:
and then no custom licenses or custom credits new files that are licensed by thirdy parties like the "Chromium" one ifdeffing like this in case not done, i also remember you that the new code must be Clang-formatted, on VS you can use CTRL+K+F shortcut keys to automatically format the selected code lines in easy way as per guidelines, no "funny" commit titles but descriptive and shorts, no censured PR titles i have a question this will works also for UWP platform? |
Thank you so much for the reply and also for telling me what's going on currently! I'll pause currently until I'm told otherwise or if there is any new information. I want to get this working and up to code guidelines. I mean, this was a very rough draft if you call cause it that, hahaha. |
Hi @TheDaChicken ! Thanks so much for your interest in this project. As @CastagnaIT mentioned I'm doing a big refactor on wvdecrypter to accomplish several things:
I'm around 50% through I think, hoping to PR and start the review process within the next 2 weeks. Your work looks very exciting! It seems like this would work on Xbox which would make a lot of users on that platform happy since Widevine could never work outside of building your own package with bundled CDM and loading in dev mode. Please monitor this repo for my progress |
I didn't even think about that! That would be great Also something interesting: This CDM allows debugging. I don't know if using the renderer to get decoded frames allows that but we'll see! EDIT: (I missed this question)
Yes. There are examples of Media Foundation being used under UWP platform. |
Thanks for your patience @TheDaChicken! The above mentioned refactor has been merged in so if you're keen please continue the development! |
All right just synced the fork and stuff, Where should I create the "MediaFoundationAdapter" aka classes for initializing MF? Does it look like the bast place would be "lib/mf"? lib/cdm/win? chromium places theirs at media/cdm/win. That way I can separate an "MFDecrypter" inheriting IDecrypter to src/decrypters/mediafoundation without so many files in the folder. |
despite "cdm" have a generic meaning, for existing "lib/cdm" folder we refer to it for widevine only, i remember you that when you add an external library to |
Oh my gosh I should have asked this aswell: I also was using cdm::SessionType etc. from cdm_library. I could use I am unsure if linking to cdm_library would be a great idea? I was creating a similar mode to CdmAdapter. |
mmh now i dont have a full background of MF but i would have expected that MF is an independent CDM, so the question is: if you start use headers of WV-CDM folder, and in the future widevine change interface or the wv interface require some refactor/rework, this will lead us to a big problem with MF, which will be broken for a long time due to possible changed headers and code, and will be needed also someone that will have time/competence to rework it
linking CDM library to MF library? as my response above, atm this sound a very bad idea side note: please note that files on "cdm" folder dont follow our code guidelines, this because come from external sources, so if you take inspiration from them, please do not copy/paste that code directly but adapt it by respecting our code guidelines |
Basically convenience-ish? I would have to expose "mfapi.h" outside lib/mfcdm unless I make my own implementation of an enum etc Because logically, it'd be great for mfcdm to be an independent piece of code w/ sources only talking to MF.
Gosh! that's true. The whole reason I am asking these questions because my main goal is to go through and make MF access painless and an "interface" similar to Widevine. That way, it is painless to read.
Yes, 100% noted. I asked to prevent repeat code when classes already technically existed? |
i agree, add its own interface in to ML library its correct in order to avoid expose propertary components of windows api's directly to the client (ISAdaptive sources) |
I feel a bit stuck again. I still feel the Widevine decrypter implementation is still a little quirky trying to work with and painful. I feel like I am going to have to repeat a bunch of code. Could/Should I open a PR for that? It's very hard since I am unsure about the codebase. Should probably wait for "Reintroduce CDM aarch64 support" though. |
i dont know exactly what you are thinking to do, but this makes me think that again you want to bring changes to widevine, maybe you are looking at things from a wrong perspective? maybe @glennguy have time to give also his opinion, |
I am talking about the WVDecrypter implementation. An example would be in "WVCencSingleSampleDecrypter." Contains same code for parsing license key & response in both android and non-android. PlayReady wouldn't need that but I am just saying as an example. If you think it's fine then it's okay. I'll just go with it. I don't wanna mess with much. I agree that cdm_library is fine and I don't think really needs to be touched. It does what it needs to do. |
ah ok now its more clear, yeah there are duplicate code between android/non-android wv implementation That's fine for now, don't worry too much about repeated/duplicated code if you are uncertain about your cleanups you think to do, you can also open an Issue thread |
I also tried a test stream:
IA tries to look for PSSH in MOOV even when PR tag was parsed. |
I saw there were conflicts on the PR. GitHub did straight things and did some weird merging. I'm never doing that again... sorry about that.
Yep, I could do Oop, okay, I'll fix that.
Take your time as well!
No problem! |
thanks for explanation,
we need also to think a way to limit this feature from the specified windows version at runtime |
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 think i will stop here for now for review, since with my old previous comment and these new ones will require a significant code changes
i have not tested it |
Yeah that is basically what I am talking about. I am confused because PRProtectionParser exists but it's not being used for anything other than printing? |
its used to extract kid, depends on the data provided with manifest |
if (!(config & DRM::IDecrypter::CONFIG_PERSISTENTSTORAGE)) | ||
{ | ||
LOG::Log(LOGERROR, "MF PlayReady requires persistent storage."); | ||
return false; | ||
} |
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.
maybe im wrong but this condition seem weird, for widevine this is not mandatory
why should be on playready? take in account that we dont allow to store encrypted content to device storage for later uses nor store license
From my testings: It would be better to check for Windows's SDK 20H2 in CMake & compiler time to include lib/mfcdm headers. MediaFoundation did exist before Windows 20H2 BUT headers didn't exist. During runtime, MF will just fail to initialize if it doesn't exist. that's okay. |
Is something like this okay? Using #if _WIN32
#include <ntverp.h>
#if VER_PRODUCTBUILD >= 1001 // Windows SDK higher than Windows 20H2
#include "mediafoundation/MFDecrypter.h"
#endif
#endif |
i see code improvements, i will take a look at weekend or next week
should be 10011 ? |
OOPS! I didn't correlate GitHub merge vs Git merge.
Yeah, I think you are right. Hmmm, maybe this is better? NTDDI_WIN10_VB is Windows 20H2. #if _WIN32
#include <SdkDdkVer.h>
#if WDK_NTDDI_VERSION >= NTDDI_WIN10_VB // Windows SDK higher than Windows 20H2
#include "mediafoundation/MFDecrypter.h"
#endif
#endif |
82af706
to
d038834
Compare
d038834
to
aec6f37
Compare
Git thinks that my local is updated.... it definitely isn't. What do you think I should do - Github automatically closed the commit because I tried resetting to the original commit- it didn't like it at all. I could reset to 315ea9b. Am unsure if that would be a great commit to hard rest too. Then add my code back. |
you have done really too much mess in your branch... to reset your branch with my branch: check if success: now you have sync the branch to last upstream changes: now try build and fix remaining things...
at the end to update your PR you need to do a forced push |
Oh my lord. Thank you so much. |
d038834
to
54b3f50
Compare
4320230
to
6168bb2
Compare
i tried test the code and i see that needs futher developments to be able to play a drm video |
Yep. The latest commit should now create an MF session. It writes MF's session message to |
52100ab
to
0c186ad
Compare
This is the current .strm file I am using now:
The MPD pssh contains an old LR_URL. If license_key is present with a URL, it uses that instead. |
Here is an update on what I've learned: I started working on MFMediaEngine. This allows decoding (if you can call it that) from created MF Samples. It's very tedious. You have to create a virtual window etc to enable output protection. All of that is in chromium & a bit in the MF EME sample. I figured out MediaEngine has 2 ways to output decoded frames. One using what's called "frame-server" and one called DirectComposition. "frame-server" outputs direct11x audio frames (which seemed like the best option originally) or MediaEngine outputs a "surface" for DirectComposition. According to Microsoft's documentation and Chromium's comment messages, protected content is only available on DirectComposition or you have to set an application cert in DirectComposition outputs only a surface, not a frame. This means it requires a bit of Kodi ends.... I don't know enough about Kodi's codebase..... that's problematic Edit: I also want to mention that direct11x audio frames can be converted to regular frames. It requires reading and allowing CPU access to the frame. Though, Chromium does output a "staging GPU frame" so the memory stays on the GPU and no CPU reads required which may reduce performance? |
i dont know if we have a certificate and if its possible have a way to pass it here
unfurnately im not able to help you on "surface" things |
Hi, thanks for your interest and efforts! Frame-server seems "easier" but it seems unlikely that Kodi could get one of the certificates to unlock that mode. I didn't see the comment in Chromium or MS doc for details. In that mode however MediaEngine behaves like a complete player (with the exception of displaying the video). I don't know what the addon interface used by ISA allows? Using mediaengine could be interesting also for protected files, not only internet streams. |
Yes, thank you haha.
It's not very clear if
In the eme sample, all I could understand was some surface handle that is gathered during a MediaEngine event. line Just now, I went through a rabbit hole on chromium and found this. It mentions d3d from direct composion. ¯\(ツ)/¯ Chromium took the Direct Composition handle and created lots of wrappers around it.
For protected content, MF needs I do want to mention that For ISA, StreamCryptoSession gets sent across to Kodi for crypto stuff for Kodi to handle it. It's used for example, Android's Mediacodec.. There is no way currently to pass anything related to MF down to Kodi easily I think.
Never thought about that! If you have any questions please let me know. I did start working on MediaEngine so I know somewhat what I am saying... it's something... |
Based on MS docs and eme sample there seem to be three ways to get video out in "rendering" mode: Kodi is written in C++ with Win32 / D3D API and MediaEngineDCompWin32Sample (same place as eme sample) is closer to what things would look like as far as video output goes. Adding the missing pieces in Kodi to accept a swap chain handle like in the sample looks doable. Kodi doesn't use Direct Show / Media Foundation like other players on Windows so it's not only the crypto (or whatever special sauce needed to unlock protected content in MF) that's needed. |
Chromium creates a virtual window only for output protection, and Chromium writes it to
Ah, I see. I'm glad it looks doable!
Yeah, I knew Kodi wouldn't have used Media Foundation at all. In my brain, it's just a weird windows api. Thank you so much for looking more into this. I really appreciated it. Hopefully, I'm providing some insight. |
i have little knownledge on how works interaction with protected content between Kodi/ISA for example for widevine case (to work on systems different from android) use kodi interface callbacks methods: AddData is used to decrypt and decode a packet of data into a frame from here seem kodi API inputstream interface require frames, |
I'm new to this and could be missing things (and MS docs don't explain very well how the pieces fit), but it looks like Media Foundation (MF) is a complete pipeline that doesn't give access to the intermediate steps. It can do everything from opening a URL to buffering, demuxing, decrypting, decoding, rendering audio & video, and it's also a player with play/pause/speed/stop type of controls. The caller has to provide a visual surface for the output, to be composited with Kodi UI. OTOH MF also provides a lot of classes that suggest that maybe it's possible to isolate some pieces. It could be that forcing software rather than hardware handling offers more options (like frame-server mode), but I didn't find clear explanations and it looks like some testing would be needed. |
Welcome to hell :D I wish I could say I didn't feel at all the same.
From what it looks like (for me), it is possible but is a pain. I mean if it helps any better, you know that chromium figured it out and uses it as a video renderer. ¯\(ツ)/¯ Edge somehow does something else too? no clue what they use at all since closed source... You can pass Samples using a custom I had to look at ffmpeg's source code for how to deal with directx11 since I don't know much before I even figured out "frame-server" could not be an option... wtf I even found
Sadly will have to go through your testing. Could figure out more things than I have which would be great. I don't know what protection looks like with Playready. I don't know if disabling hardware acceleration and somehow using software causes decrypting to not work. Funny that it would still have key access due to how this works.
During that time, I did a lot of lurking... so I know smol bit. That's really how Netflix previously worked on Windows for Widevine because it required decoding with the CDM (probably hardware decoding) and couldn't be just decrypted. I assume you already know a bit about that. I was originally thinking with "frame-server" to implement |
Description
Implement PlayReady Support using seemly new (?) MediaFoundation API CDM.
MediaFoundationCDM was added to Window's API in Windows 20H21.
Examples I am going off:
Motivation and context
PlayReady DRM content in inputstream.adaptive will improve ISA plugins long-term for Windows.
I've been hiding in the shadows & using Kodi (randomly appeared because @CastagnaIT 's netflix plugin broke), loving ISA, and am willing/wanting to try and get something working.
How has this been tested?
This requires Windows above 20H2 for testing.
The code I am started out with was tested using an external test program I wrote.
Screenshots (if appropriate):
Types of change
Checklist:
What I have
Currently, I have somewhat of a "mock cdm" class.
Current State of the PR:
And, this PR is not 100% complete, not everything I have here is set in stone. Ex: license header under source/headers files and bad file structure.
Footnotes
Important Note under README.md ↩