[Shield Android TV Original Android Development] Koying:
2019-09-17:

- Added 8.0.0 version

2019-05-05:

- Updated 7.2.3 DTS version

2019-03-16:

- Added 7.2.3 version

- Added 7.2.3 version that also transcodes DTS, for those having a TV only supporting AC3

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

Having a non HDR enabled AVR, I became pissed to have to choose between HDR on my AC3-only TV or 5.1 on my AVR, so I hacked through the Nvidia android sources to implement on-the-fly EAC3 to AC3 conversion.

Although Nvidia does not provide the full sources to the shield, still thanks to them for making it easy to hack it.

Prerequisite

:

rooted shield, obviously. If you don't plan to do anything fancy, just stick to the rooted firmwares provided by NV itself at https://developer.nvidia.com/shield-developer-os-images

Concept

:

Netflix and Amazon are using the Android provided "AUDIO_FORMAT_E_AC3" file format, which Android transforms into IEC61937 packets suitable to be streamed to the AVR/TV.

I hacked this encoding process to transform EAC3 to AC3.

You have to set your Shield on "Surround = Always" for this to work!

Issues

:

- Not having the full sources, I had to keep code modification very localized. The only actual development is done in libaudiospdif.so

- If your TV/AVR provides more than AC3, even setting the shield surround setting to "Always" does not actually present EAC3 to Netflix. I dissassembled libaudiopolicymanagerdefault.so and did binary edit to fix this.

- EAC3 is output at 192khz, while AC3 is at 48khz. I dissassembled libaudioflinger.so and did binary edit to fix this.

- Shield ships both arm32 and aarch64 versions of those libs, but it seems only the arm32 is actually used by the system and/or the apps.

Code

:

- Nvidia provides partial sources of the Shield at https://developer.nvidia.com/shield-open-source

- The modifications to libaudiospdif are available at https://gitlab.com/koying/android_platform_system_media

- The ffmpeg version I used is the one from https://osdn.net/projects/android-x86/scm/git/external-ffmpeg

- I won't go into more details, as I'm not even sure I remember all the steps ;)

Binary edits

(vs. 7.2.2 original binaries from Shield pro)

- /system/lib/libaudiopolicymanagerdefault.so

old: 00 20 b8 f1 0e 0f 18 bf 01 20 40 ea 07 00 10 f0 01 0f
new: 00 20 b8 f1 0e 0f 18 bf 01 20 40 f0 00 00 10 f0 01 0f

- /system/lib/libaudioflinger.so

old: 00 bf fe 88 01 00 01 00 00 00 04 00 00 00 01 00 00 00 01 00 00 00 04 00 00 00 01 00 00 00
new: 00 bf fe 88 01 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00

Binary edits

(vs. 8.0.0 original binaries from Shield pro)

- /system/lib/libaudioflinger.so

old: 49 00 00 00 66 00 00 00 46 00 00 00 41 00 00 00 01 00 00 00 04 00 00 00 01 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 A0 26 6B E4 DD DD DB 11
new: 49 00 00 00 66 00 00 00 46 00 00 00 41 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 A0 26 6B E4 DD DD DB 11

For 8.0.0, go to "Device Preferences - Display & Sound - Advanced sound settings - Available formats", select "Manual" and enable "AC3" and "E-AC3" (+ DTS if your TV supports it).

Binaries

Attached. Those are certified working on Shield pro 7.x and 8.0.0.

Worst case, just revert with the backup you surely did ;)

Use with scripts similar to :

Backup:

adb pull /system/lib/libaudioflinger.so libaudioflinger.so.bak
adb pull /system/lib/libaudiopolicymanagerdefault.so libaudiopolicymanagerdefault.so.bak
adb pull /system/lib/libaudiospdif.so libaudiospdif.so.bak

Push:

adb root
adb remount

# Not for 8.0.0
adb push -p libaudiopolicymanagerdefault.so /system/lib/

adb push -p libaudioflinger.so /system/lib/
adb push -p libaudiospdif.so /system/lib/
adb push -p libavcodec.so /system/lib/
adb push -p libavformat.so /system/lib/
adb push -p libavutil.so /system/lib/
adb push -p libswresample.so /system/lib/

adb shell sync
adb reboot

Enjoy :)