Skip to content
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

Connecting to Nvidia Shield - error with scrcpy 2.0 #3801

Closed
cpo-ux opened this issue Mar 12, 2023 · 20 comments
Closed

Connecting to Nvidia Shield - error with scrcpy 2.0 #3801

cpo-ux opened this issue Mar 12, 2023 · 20 comments

Comments

@cpo-ux
Copy link

cpo-ux commented Mar 12, 2023

Environment:
OS: Win 10 Pro x64 22H2
scrcpy version: 2.0
Installation method: Windows release
device model: NVIDIA SHIELD Model P2897 year: 2017
Android version: 11

Hi,

Version 1.25 works fine so I'll stay with it for now however I thought I'd try the latest version of scrcpy 2.0 and it doesn't work; I get the following, below.

C:\MorePrograms1\scrcpy-win64_2.0>scrcpy
scrcpy 2.0 https://github.com/Genymobile/scrcpy
C:\MorePrograms1\scrcpy-win64_2.0\scrcpy-server: 1 file pushed, 0 skipped. 42.6 MB/s (52867 bytes in 0.001s)
[server] INFO: Device: NVIDIA SHIELD Android TV (Android 11)
[server] ERROR: Exception on thread Thread[Thread-4,5,main]
java.lang.IllegalArgumentException: Failed to initialize audio/opus, error 0xfffffffe
at android.media.MediaCodec.native_setup(Native Method)
at android.media.MediaCodec.(MediaCodec.java:2117)
at android.media.MediaCodec.createEncoderByType(MediaCodec.java:2042)
at com.genymobile.scrcpy.AudioEncoder.createMediaCodec(AudioEncoder.java:278)
at com.genymobile.scrcpy.AudioEncoder.encode(AudioEncoder.java:174)
at com.genymobile.scrcpy.AudioEncoder.lambda$start$0$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:120)
at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda0.run(Unknown Source:2)
at java.lang.Thread.run(Thread.java:923)
[server] ERROR: Exception on thread Thread[main,5,main]
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.createPackageContext(java.lang.String, int)' on a null object reference
at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
at android.media.MediaCodec.isSupported(MediaCodec.java:1892)
at android.media.MediaCodec.checkAppForAutoFrc(MediaCodec.java:1922)
at android.media.MediaCodec.configureCodecParams(MediaCodec.java:2084)
at android.media.MediaCodec.(MediaCodec.java:2118)
at android.media.MediaCodec.createEncoderByType(MediaCodec.java:2042)
at com.genymobile.scrcpy.ScreenEncoder.createMediaCodec(ScreenEncoder.java:209)
at com.genymobile.scrcpy.ScreenEncoder.streamScreen(ScreenEncoder.java:64)
at com.genymobile.scrcpy.Server.scrcpy(Server.java:133)
at com.genymobile.scrcpy.Server.main(Server.java:381)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:399)
INFO: Renderer: direct3d
ERROR: Demuxer 'audio': stream disabled due to connection error
ERROR: Demuxer 'video': stream disabled due to connection error
ERROR: Demuxer error
WARN: Killing the server...

===================
I also tried different codecs and encoders with the instructions from here but no luck and got this error because there's something wrong with the command for the encoder:

C:\MorePrograms1\scrcpy-win64_2.0>scrcpy --list-encoders
scrcpy 2.0 https://github.com/Genymobile/scrcpy
C:\MorePrograms1\scrcpy-win64_2.0\scrcpy-server: 1 file pushed, 0 skipped. 34.9 MB/s (52867 bytes in 0.001s)
[server] INFO: List of video encoders:
--video-codec=h264 --video-encoder='OMX.Nvidia.h264.encoder'
--video-codec=h264 --video-encoder='OMX.google.h264.encoder'
--video-codec=h265 --video-encoder='OMX.Nvidia.h265.encoder'
[server] INFO: List of audio encoders:
--audio-codec=aac --audio-encoder='OMX.google.aac.encoder'

C:\MorePrograms1\scrcpy-win64_2.0>scrcpy --video-codec=h265 --video-encoder='OMX.Nvidia.h265.encoder'
scrcpy 2.0 https://github.com/Genymobile/scrcpy
C:\MorePrograms1\scrcpy-win64_2.0\scrcpy-server: 1 file pushed, 0 skipped. 38.8 MB/s (52867 bytes in 0.001s)
[server] INFO: Device: NVIDIA SHIELD Android TV (Android 11)
[server] ERROR: Audio encoding error
java.io.IOException: android.system.ErrnoException: write failed: EBADF (Bad file descriptor)
at com.genymobile.scrcpy.IO.writeFully(IO.java:33)
at com.genymobile.scrcpy.IO.writeFully(IO.java:40)
at com.genymobile.scrcpy.Streamer.writeDisableStream(Streamer.java:61)
at com.genymobile.scrcpy.AudioEncoder.encode(AudioEncoder.java:224)
at com.genymobile.scrcpy.AudioEncoder.lambda$start$0$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:120)
at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda0.run(Unknown Source:2)
at java.lang.Thread.run(Thread.java:923)
Caused by: android.system.ErrnoException: write failed: EBADF (Bad file descriptor)
at libcore.io.Linux.writeBytes(Native Method)
at libcore.io.Linux.write(Linux.java:285)
at libcore.io.ForwardingOs.write(ForwardingOs.java:239)
at libcore.io.BlockGuardOs.write(BlockGuardOs.java:412)
at android.system.Os.write(Os.java:727)
at com.genymobile.scrcpy.IO.writeFully(IO.java:25)
... 6 more
[server] ERROR: Exception on thread Thread[main,5,main]
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.createPackageContext(java.lang.String, int)' on a null object reference
at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
at android.media.MediaCodec.isSupported(MediaCodec.java:1892)
at android.media.MediaCodec.checkForSecureDecoder(MediaCodec.java:1936)
at android.media.MediaCodec.createByCodecName(MediaCodec.java:2058)
at com.genymobile.scrcpy.ScreenEncoder.createMediaCodec(ScreenEncoder.java:203)
at com.genymobile.scrcpy.ScreenEncoder.streamScreen(ScreenEncoder.java:64)
at com.genymobile.scrcpy.Server.scrcpy(Server.java:133)
at com.genymobile.scrcpy.Server.main(Server.java:381)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:399)
INFO: Renderer: direct3d
ERROR: Demuxer 'audio': stream disabled due to connection error
ERROR: Demuxer 'video': stream disabled due to connection error
ERROR: Demuxer error

============
Not sure what else to try...

@rom1v
Copy link
Collaborator

rom1v commented Mar 12, 2023

Could you please try with scrcpy --no-audio?

@cpo-ux
Copy link
Author

cpo-ux commented Mar 12, 2023

Hi rom1v,

That works, thanks :)

scrcpy --no-audio

@rom1v
Copy link
Collaborator

rom1v commented Mar 12, 2023

OK so the FakeContext to make audio works seems to break your video. (cc @yume-chan for information)

@jkr4m3r
Copy link

jkr4m3r commented Mar 12, 2023

Came to post about this issue, can verify on My Shield Pro 2019 also.

@yume-chan
Copy link
Contributor

[server] INFO: List of audio encoders:
--audio-codec=aac --audio-encoder='OMX.google.aac.encoder'

There is no opus encoder, can you try scrcpy --audio-codec=aac --audio-encoder='OMX.google.aac.encoder'?

Also what will happen if you run scrcpy --no-audio --video-codec=h265 --video-encoder='OMX.Nvidia.h265.encoder'?

I imagine if there was no Context by default it will throw the same error?

@cpo-ux
Copy link
Author

cpo-ux commented Mar 13, 2023

scrcpy --audio-codec=aac --audio-encoder='OMX.google.aac.encoder'
above results in no go, see details below

scrcpy --no-audio --video-codec=h265 --video-encoder='OMX.Nvidia.h265.encoder'
above works fine, see details below.

"I imagine if there was no Context by default it will throw the same error?"
Do you mean just running scrcpy by itself? If that's what you mean, then see below.

See details below.

C:\MorePrograms1\scrcpy-win64>scrcpy --audio-codec=aac --audio-encoder='OMX.google.aac.encoder'
scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
C:\MorePrograms1\scrcpy-win64\scrcpy-server: 1 file pushed, 0 skipped. 58.6 MB/s (52867 bytes in 0.001s)
[server] INFO: Device: NVIDIA SHIELD Android TV (Android 11)
[server] ERROR: Exception on thread Thread[Thread-4,5,main]
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.createPackageContext(java.lang.String, int)' on a null object reference
        at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
        at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
        at android.media.MediaCodec.isSupported(MediaCodec.java:1892)
        at android.media.MediaCodec.checkForSecureDecoder(MediaCodec.java:1936)
        at android.media.MediaCodec.createByCodecName(MediaCodec.java:2058)
        at com.genymobile.scrcpy.AudioEncoder.createMediaCodec(AudioEncoder.java:272)
        at com.genymobile.scrcpy.AudioEncoder.encode(AudioEncoder.java:174)
        at com.genymobile.scrcpy.AudioEncoder.lambda$start$0$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:120)
        at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda0.run(Unknown Source:2)
        at java.lang.Thread.run(Thread.java:923)
[server] ERROR: Exception on thread Thread[main,5,main]
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.createPackageContext(java.lang.String, int)' on a null object reference
        at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
        at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
        at android.media.MediaCodec.isSupported(MediaCodec.java:1892)
        at android.media.MediaCodec.checkAppForAutoFrc(MediaCodec.java:1922)
        at android.media.MediaCodec.configureCodecParams(MediaCodec.java:2084)
        at android.media.MediaCodec.<init>(MediaCodec.java:2118)
        at android.media.MediaCodec.createEncoderByType(MediaCodec.java:2042)
        at com.genymobile.scrcpy.ScreenEncoder.createMediaCodec(ScreenEncoder.java:209)
        at com.genymobile.scrcpy.ScreenEncoder.streamScreen(ScreenEncoder.java:64)
        at com.genymobile.scrcpy.Server.scrcpy(Server.java:133)
        at com.genymobile.scrcpy.Server.main(Server.java:381)
        at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
        at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:399)
INFO: Renderer: direct3d
WARN: Demuxer 'audio': stream explicitly disabled by the device
ERROR: Demuxer 'video': stream disabled due to connection error
ERROR: Demuxer error
WARN: Killing the server...
===========================
C:\MorePrograms1\scrcpy-win64>scrcpy --no-audio --video-codec=h265 --video-encoder='OMX.Nvidia.h265.encoder'
scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
C:\MorePrograms1\scrcpy-win64\scrcpy-server: 1 file pushed, 0 skipped. 59.2 MB/s (52867 bytes in 0.001s)
[server] INFO: Device: NVIDIA SHIELD Android TV (Android 11)
INFO: Renderer: direct3d
INFO: Initial texture: 1920x1080
WARN: Killing the server...
==========================
C:\MorePrograms1\scrcpy-win64>scrcpy
scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
C:\MorePrograms1\scrcpy-win64\scrcpy-server: 1 file pushed, 0 skipped. 62.1 MB/s (52867 bytes in 0.001s)
[server] INFO: Device: NVIDIA SHIELD Android TV (Android 11)
[server] ERROR: Exception on thread Thread[Thread-4,5,main]
java.lang.IllegalArgumentException: Failed to initialize audio/opus, error 0xfffffffe
        at android.media.MediaCodec.native_setup(Native Method)
        at android.media.MediaCodec.<init>(MediaCodec.java:2117)
        at android.media.MediaCodec.createEncoderByType(MediaCodec.java:2042)
        at com.genymobile.scrcpy.AudioEncoder.createMediaCodec(AudioEncoder.java:278)
        at com.genymobile.scrcpy.AudioEncoder.encode(AudioEncoder.java:174)
        at com.genymobile.scrcpy.AudioEncoder.lambda$start$0$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:120)
        at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda0.run(Unknown Source:2)
        at java.lang.Thread.run(Thread.java:923)
[server] ERROR: Exception on thread Thread[main,5,main]
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.createPackageContext(java.lang.String, int)' on a null object reference
        at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
        at android.content.ContextWrapper.createPackageContext(ContextWrapper.java:927)
        at android.media.MediaCodec.isSupported(MediaCodec.java:1892)
        at android.media.MediaCodec.checkAppForAutoFrc(MediaCodec.java:1922)
        at android.media.MediaCodec.configureCodecParams(MediaCodec.java:2084)
        at android.media.MediaCodec.<init>(MediaCodec.java:2118)
        at android.media.MediaCodec.createEncoderByType(MediaCodec.java:2042)
        at com.genymobile.scrcpy.ScreenEncoder.createMediaCodec(ScreenEncoder.java:209)
        at com.genymobile.scrcpy.ScreenEncoder.streamScreen(ScreenEncoder.java:64)
        at com.genymobile.scrcpy.Server.scrcpy(Server.java:133)
        at com.genymobile.scrcpy.Server.main(Server.java:381)
        at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
        at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:399)
INFO: Renderer: direct3d
ERROR: Demuxer 'video': stream disabled due to connection error
WARN: Demuxer 'audio': stream explicitly disabled by the device
ERROR: Demuxer error
WARN: Killing the server...
============================

@yume-chan
Copy link
Contributor

@rom1v Scrcpy server process doesn't have any associated Application or Context instances before fillAppInfo(), right? I think the code added by Nvidia guarded against empty Context, so it works before.

Without knowing exactly what the code is doing, it's impossible to know which methods need to be patched. @cpo-ux can you pull out the /system/framework/framework.jar file from your system and upload here?

@cpo-ux
Copy link
Author

cpo-ux commented Mar 14, 2023

@yume-chan Was my first time doing this so took me a while to figure out... In the end I gave up on ADB shell stuff and used: https://github.com/Alex4SSB/ADB-Explorer] I am assuming there's no personal info in this file I'm uploading :) File is at google drive link here: https://drive.google.com/file/d/1YPcyASPUFspoayYGoUNQQo63fQmUmk0V/view?usp=sharing

@yume-chan
Copy link
Contributor

yume-chan commented Mar 14, 2023

Was my first time doing this so took me a while to figure out

adb pull /system/framework/framework.jar /path/on/your/pc

I am assuming there's no personal info

This is the Java part of your Android system.

image

I was right that it guarded against empty Context, but when Context exists, it invokes multiple methods including createPackageContext, getApplicationContext, getSystemService. Looking at the code it's related to some App certification program by Nvidia.

These definitely requires a real App Context, I don't think it's possible to emulate them in FakeContext.

Maybe I need to check how App Context was initialized... Or try to hook the framework API calls...

@farmerbb
Copy link

Also running into this issue on my Nvidia Shield running Android 11, and can report that scrcpy --no-audio works just fine to resolve the error.

rom1v added a commit that referenced this issue Mar 14, 2023
There were several workarounds applied in a single method. Some of them
are specific to Meizu phones, but cause issues on other devices.

Split the method to be able to only fill the app context for audio
capture without applying the Meizu workarounds.

Fixes #3801 <#3801>
@rom1v
Copy link
Collaborator

rom1v commented Mar 14, 2023

Audio requires an app context, but it seems that the workarounds which makes Nvidia Shield fail are unrelated workarounds for Meizu phones. So let's try to split them: 3582592

Please test (replace this binary in the v2.0 release):

  • scrcpy-server SHA-256: 4f40f140ddf14f62c0ff47c47071471a4d3adef827126388b5cd064c7b919d8d

@farmerbb
Copy link

Audio requires an app context, but it seems that the workarounds which makes Nvidia Shield fail are unrelated workarounds for Meizu phones. So let's try to split them: 3582592

Please test (replace this binary in the v2.0 release):

  • scrcpy-server SHA-256: 4f40f140ddf14f62c0ff47c47071471a4d3adef827126388b5cd064c7b919d8d

That scrcpy-server binary works. I still get the Failed to initialize audio/opus, error 0xfffffffe error (which is expected) but video streaming works now on my Shield without using the --no-audio argument.

@rom1v
Copy link
Collaborator

rom1v commented Mar 14, 2023

I still get the Failed to initialize audio/opus, error 0xfffffffe error

scrcpy --list-encoders
scrcpy --audio-codec=aac

@farmerbb
Copy link

scrcpy --list-encoders
scrcpy --audio-codec=aac

Thanks! Audio streaming works now on the Shield using the AAC codec.

rom1v added a commit that referenced this issue Mar 14, 2023
There were several workarounds applied in a single method. Some of them
are specific to Meizu phones, but cause issues on other devices.

Split the method to be able to only fill the app context for audio
capture without applying the Meizu workarounds.

Fixes #3801 <#3801>
@rom1v
Copy link
Collaborator

rom1v commented Mar 14, 2023

👌 Merged into dev: 6ba99a6

@rom1v rom1v closed this as completed Mar 14, 2023
@jkr4m3r
Copy link

jkr4m3r commented Mar 14, 2023

FWIW,

Audio requires an app context, but it seems that the workarounds which makes Nvidia Shield fail are unrelated workarounds for Meizu phones. So let's try to split them: 3582592

Please test (replace this binary in the v2.0 release):

* [`scrcpy-server`](https://tmp.rom1v.com/scrcpy/3801/1/scrcpy-server) `SHA-256: 4f40f140ddf14f62c0ff47c47071471a4d3adef827126388b5cd064c7b919d8d`

This works for me on my Shield Pro, many thanks!

@Anatoly-Vinnikov
Copy link

Audio requires an app context, but it seems that the workarounds which makes Nvidia Shield fail are unrelated workarounds for Meizu phones. So let's try to split them: 3582592

Please test (replace this binary in the v2.0 release):

  • scrcpy-server SHA-256: 4f40f140ddf14f62c0ff47c47071471a4d3adef827126388b5cd064c7b919d8d

This also works on my meizu m3 note. Thanks a lot!

@Alistair1231
Copy link

will this change be merged into the next release, or will this always stay as a manual fix?

Audio requires an app context, but it seems that the workarounds which makes Nvidia Shield fail are unrelated workarounds for Meizu phones. So let's try to split them: 3582592

Please test (replace this binary in the v2.0 release):

* [`scrcpy-server`](https://tmp.rom1v.com/scrcpy/3801/1/scrcpy-server) `SHA-256: 4f40f140ddf14f62c0ff47c47071471a4d3adef827126388b5cd064c7b919d8d`

This works, but in case someone else is wondering why it doesn't work, no Bluetooth headset can be connected.

@rom1v
Copy link
Collaborator

rom1v commented May 25, 2023

will this change be merged into the next release, or will this always stay as a manual fix?

It is already merged into the dev branch (6ba99a6), so it will be in the next release.

@Alistair1231
Copy link

perfect, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants