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

feat(patch): Youtube, Loading high resolution vertical video. #1278

Closed
3 tasks done
odkrys opened this issue Mar 8, 2023 · 31 comments · Fixed by ReVanced/revanced-patches-template#3140
Closed
3 tasks done
Labels
Feature request Requesting a new feature that's not implemented yet

Comments

@odkrys
Copy link

odkrys commented Mar 8, 2023

Application

YouTube Revanced

Issue

Load a vertical video that exceeds the resolution of the device or meets the hardware acceleration capability of the device.
Resolves an issue where vertical video at 480p (480x854) resolution is maxed out on entry-level APs (which only support 1920x1080p acceleration).

Patch

Change "maxh" sent by the app to load higher resolution vertical videos.

Motivation

ReVanced/revanced-discussions#929

Acknowledgements

  • I have searched the existing issues and this is a new and no duplicate or related to another open issue.
  • I have written a short but informative title.
  • I filled out all of the requested information in this issue properly.
@odkrys odkrys added the Feature request Requesting a new feature that's not implemented yet label Mar 8, 2023
@odkrys
Copy link
Author

odkrys commented Mar 9, 2023

@oSumAtrIX
I achieved my goal today with a simple fix.
Changing "maxh" didn't solve my problem and I looked for something else.
In the media codec section, I found the part that called the device's codec capability and changed that part, and now the video is loaded with "width x width" instead of "height x width".

root@instance-20220814-1527:~/test# grep -r "getSupportedHeights" ./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37
grep: ./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/build/apk/classes.dex: binary file matches
grep: ./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/build/apk/classes4.dex: binary file matches
grep: ./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/build/apk/classes6.dex: binary file matches
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali_classes7/ynv.smali:    invoke-virtual {v0}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeights()Landroid/util/Range;
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali_classes7/ynv.smali:    invoke-virtual {v0}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeights()Landroid/util/Range;
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali/alz.smali:    const-string v6, "[VideoCaps] getSupportedHeights = "
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali/alz.smali:    invoke-virtual {v0}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeights()Landroid/util/Range;
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali/alz.smali:    const-string v10, "[VideoCaps] getSupportedHeightsFor "
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali/alz.smali:    invoke-virtual {v0, v5}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeightsFor(I)Landroid/util/Range;
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali/alz.smali:    const-string v10, "[VideoCaps] could not getSupportedHeightsFor "
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali_classes4/anf.smali:    invoke-virtual {v0}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeights()Landroid/util/Range;
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali_classes4/anf.smali:    invoke-virtual {v0, p1}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeightsFor(I)Landroid/util/Range;
./youtube-revanced_Arm64_RVF-Black_Theme_18.08.37/smali_classes6/ywo.smali:    invoke-virtual {v1}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeights()Landroid/util/Range;

I looked at the /smali_classes7/ynv.smali file.

    .line 75
    invoke-virtual {v0}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeights()Landroid/util/Range;

    move-result-object v7

    invoke-virtual {v7}, Landroid/util/Range;->getLower()Ljava/lang/Comparable;

    move-result-object v7

    check-cast v7, Ljava/lang/Integer;

    invoke-virtual {v7}, Ljava/lang/Integer;->intValue()I

    move-result v7

    .line 76
    invoke-virtual {v0}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedHeights()Landroid/util/Range;

    move-result-object v12

    invoke-virtual {v12}, Landroid/util/Range;->getUpper()Ljava/lang/Comparable;

    move-result-object v12

    check-cast v12, Ljava/lang/Integer;

    invoke-virtual {v12}, Ljava/lang/Integer;->intValue()I

    move-result v12

    .line 77
    invoke-virtual {v0}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedWidths()Landroid/util/Range;

    move-result-object v13

    invoke-virtual {v13}, Landroid/util/Range;->getLower()Ljava/lang/Comparable;

    move-result-object v13

    check-cast v13, Ljava/lang/Integer;

    invoke-virtual {v13}, Ljava/lang/Integer;->intValue()I

    move-result v13

    .line 78
    invoke-virtual {v0}, Landroid/media/MediaCodecInfo$VideoCapabilities;->getSupportedWidths()Landroid/util/Range;

    move-result-object v0

    invoke-virtual {v0}, Landroid/util/Range;->getUpper()Ljava/lang/Comparable;

And I changed two "getSupportedHeights" to "getSupportedWidths".
After installing the modified APK, I could see that the app was requesting a video in 3840x3840.
In adb logcat, "maxh" was also changed to 3840.
Now I can watch 2160p portrait video.

Hope this helps to add the patch.

@odkrys
Copy link
Author

odkrys commented Mar 9, 2023

I just converted the values to numbers.
Now everyone can bring up a list of 4K videos on any device.

    .line 75
    const/16 v7, 0x40

    .line 76
    const/16 v12, 0x1000

    .line 77
    const/16 v13, 0x40

    .line 78
    const/16 v0, 0x1000

    invoke-direct {v6, v7, v12, v13, v0}, Lzgl;-><init>(IIII)V
vprng:minh.64;maxh.4096;minw.64;maxw.4096

@oSumAtrIX
Copy link
Member

oSumAtrIX commented Mar 9, 2023

Does this also affect normal videos?

@odkrys
Copy link
Author

odkrys commented Mar 9, 2023

you mean horizontal? yes.
1920 device loads 4k horizontal and 4k portrait.
But that doesn't mean a 1080p device can play 1440p and 4k video smoothly. It just gets the list from the server.

@odkrys
Copy link
Author

odkrys commented Mar 14, 2023

hi @inotia00
inotia00/revanced-patches@ecbedb7
I've seen and tested the patch you added. I've confirmed that this option effectively changes both the width and height to 4096.
The title is for vertical, but more versatile. As I recall, the old vanced had a "Max Resolution" option.
How about using the same name?

@SodaWithoutSparkles
Copy link
Contributor

the video is loaded with "width x width" instead of "height x width"

Maybe with width x height only in portrait videos?

@johnconner122
Copy link
Contributor

hi @inotia00 inotia00@ecbedb7 I've seen and tested the patch you added. I've confirmed that this option effectively changes both the width and height to 4096.

It also shows 4k quality even if device doesn't support it!

@oSumAtrIX
Copy link
Member

It also shows 4k quality even if device doesn't support it!

Exactly the reason why YouTube pay walls high video qualities. It is useless to watch at that quality on your device.

@SodaWithoutSparkles
Copy link
Contributor

Not exactly. Sometimes it is good for anti-aliasing

@oSumAtrIX
Copy link
Member

oSumAtrIX commented Mar 28, 2023

For 99% or higher of the content which 99% of all people watch they will not need video quality above 720p.

@eldepor
Copy link

eldepor commented Oct 18, 2023

Been looking for this post for a while. I just bought a new tablet (Lenovo m10 FHD), built the latest revanced apk with the latest manager, patches and all that stuff, and shorts are all playing @ 480p. Even if I open the short as a regular video, Max resultion in quality menu is 480p. How is this possible? I can watch horizontal videos @ 1080@60 flawlessly without a single stutter on that device. Also tried installing revanced in my mom's redmi 10 phone, which is able to play 1440p videos no problem, but shorts are all of them limited to 720p. I also enabled nerd stats and noticed all videos and shorts are played with vp9 codec. While in my old rooted xiaomi redmi 3 with android 5 from 2016 the codec showing is AV1 AVC1 and I can play shorts and videos @ 1080@60 without a single problem.

Tried all settings, spoofing, qualities, changed every setting in every menu and nothing fixes this. The only thing that allowed me to play 1080p shorts is by enabling "force vp9" patch from @inotia00 fork (I guess because of the "lift-vertical-video-restriction patch"), but that only solved half of the problem: shorts max resolution available is now 1080p as it should be, BUT the quality drop issue still there: after few videos the app starts to struggle, and the shorts that I've been playing in 1080 starts to stutter, then suddenly the resultion drops to 480p again, until I close the video/short and open it again. Even with horizontal videos, after few stutters, the quality menu that showed up to 1080p res. suddenly shows only up to 480p max: 720 and 1080 literally dissappear from the menu once the quality drop is triggered or kicked by the app lol. I don't know what to do at this point, and this is happening also with the official yt app from store.
I can't believe my old 2016 android 5 (with modded revanced for android 5) can manage videos better, than those two almost new devices that can only play vp9 videos at low resultion, something must be wrong or something could be modified somewhere to avoid this, so the app never drop the resolution and just stay @ 1080p, but I don't know what could be. Hope you can help me. Thanks.

Edit: Fixed it here

@eldepor
Copy link

eldepor commented Oct 18, 2023

@oSumAtrIX @odkrys I looked at the /smali_classes7/ynv.smali file.

Where is that file? I cant find them in my yt rv apk. Thx.

Edit: I found the strings on several files, do I have to change the two "getSupportedHeights" to "getSupportedWidths" in all of them?

Edit2: Ok I changed them just in a similar file with the same structure, but with different name.

@oSumAtrIX
Copy link
Member

If you can't find it, it doesn't exist in the app you have. The name is different every version

@eldepor
Copy link

eldepor commented Oct 18, 2023

If you can't find it, it doesn't exist in the app you have. The name is different every version

Any thoughts about the case I described? Thanks

@oSumAtrIX
Copy link
Member

You are using unofficial patches

@eldepor
Copy link

eldepor commented Oct 18, 2023

You are using unofficial patches

I tried both, official and inotia´s, with same results. With the official patches cant play shorts beyond 480p (tablet) and 720p (redmi 10). Same with official yt app from store. With inotias can play in 1080 but it goes back to 480p after the minimal stutter. I tried all settings in revanced sections believe me. Both devices plays only vp9 by default in official patches too. But in a rusty android 5 theres no problem with avc1 and 1080, Cant understand.
I can capture a video of the issue if it helps.

@eldepor
Copy link

eldepor commented Oct 18, 2023

You are using unofficial patches

I tried both, official and inotia´s, with same results. With the official patches cant play shorts beyond 480p (tablet) and 720p (redmi 10). Same with official yt app from store. With inotias can play in 1080 but it goes back to 480. I tried all settings in revanced sections believe me. Both devices plays only vp9 by default in official patches too. But in a rusty android 5 theres no problem with avc1 and 1080, Cant understand. I can capture a video of the issue if it helps.

Ok I followed @odkrys steps (https://github.com/ReVanced/revanced-patches-template/issues/1278) changing the two "getSupportedHeights" to "getSupportedWidths" and looks like it fixed the issue completly (the smali file name and classes number were different in my case). Now shorts are playing in the right resolution (1080p) and are not dropped to 480p anymore, also 720p and 1080p do not dissapear from the quality dropdown menu.
Looks like loading the video with "width x width" instead of "height x width" does the job of keeping the chosen resolution instead of triggering a quality drop because of a micro stutter. Device still using vp9 tho idk why. All done with the official patches.

Would be any way to implement that at the moment of building the apk from the revanced manager instead of having to decompile it after, modify those two parameters and compile it again? Thanks

@LisoUseInAIKyrios
Copy link
Contributor

Would be any way to implement that at the moment of building the apk from the revanced manager instead of having to decompile it after, modify those two parameters and compile it again?

If you can manually edit the smali bytecode by hand, then yes it definitely can be made into a patch. Why not give a go at making a bytecode patch? It's not difficult.

@oSumAtrIX oSumAtrIX linked a pull request Oct 19, 2023 that will close this issue
1 task
@odkrys
Copy link
Author

odkrys commented Oct 19, 2023

@eldepor This feature is already implemented in revanced extended. Try activating the video codec in the options.

@eldepor
Copy link

eldepor commented Oct 19, 2023

@eldepor This feature is already implemented in revanced extended. Try activating the video codec in the options.

Hi @odkrys . If you mean video codec option from inotia00 fork, I already activated it but it just fixes half of the issue: it "unlocks" the 1080p resolution, ok, but still dropping back to 480p sometimes. What I needed is to keep videos/shorts in 1080p (forcing 1080p for wifi and data option didn't work either), I could only and only achieve that by replacing "getSupportedHeights" with "getSupportedWidths" in the smali file, and then compile the apk again. Actually I decompiled both official and extended apk's built with the manager, and they still have the "heights" strings that I had to replace with "widths" in those two lines you pointed. This is key to fix the quality drop issue.

@odkrys
Copy link
Author

odkrys commented Oct 19, 2023

hmm.. Have you also checked the “Skip dummy segment” option? If you do not enable this option, the video will play in low quality for the first 10 seconds.

@eldepor
Copy link

eldepor commented Oct 19, 2023

hmm.. Have you also checked the “Skip dummy segment” option? If you do not enable this option, the video will play in low quality for the first 10 seconds.

Yep, I already checked and tested everything, none of those options solves it. The problem is not starting in lowQ, it's just the opposite: its starting in 1080p and if the app detects a minimal struggle playing a video, a quality drop kicks in (like when you set "automatic" in preferred quality, and it changes the resolution depending on your bandwidth etc.) and then the only available resolution is 480p maximum, 720 and 1080 dissappear from the menu (bug?) so theres no way to go back to a higher quality until you close and reopen the same video/short. it stays @ 480p till the playback ends because theres no higer res. to choose.

In Shorts you can clearly see how it goes from 1080 to blurry 480p. It's as if 1080p were "too much" for the device and sets a lower resolution (weird because horizontal videos plays smoothly). Only modifying smali file does the job: no matter if there's a stutter in the playback due to bandwidth, hardware, or something, the resolution stay fixed in 1080p until it stabilizes again and keep playing, and that's what I want when I set "maximum" or 1080p quality setting, otherwise, if I would want variable quality I would choose automatic.

@odkrys
Copy link
Author

odkrys commented Oct 19, 2023

Hmm, dropping to 480p is a symptom that usually occurs when the video's specifications are higher than the device's supported specifications.
(For example, when playing a 4K 60fps video on the Snapdragon 700 series that supports up to 4K 30fps)

I'm not sure exactly where the point of the problem is, but I'm glad you found a way that works for you.

@eldepor
Copy link

eldepor commented Oct 19, 2023

Yes, you are right, and that's probably what the app is "thinking", wrongly. The problem is that I can't believe that my old rusty 2016 xiaomi running android 5 can play any short in 1080p60, while with a new Lenovo m10 FHD tablet and a Xiaomi redmi 10 with Helio G88 the maximum resolution is 480p and 720p respectively, lol. Especially when, also respectively, 1080p60 and 1440p horizontal videos are played beautifully in them, meaning the device's specifications are way more than capable to support short´s specification, 1080p60 in this case. And simply because I want the short or video to stay in the resolution I´ve previously set, despite lagging or stuttering, I dont care, and not as "automatic" when I didn't choose that setting. Something is obviously wrong.

@LisoUseInAIKyrios
Copy link
Contributor

The behavior might be bandwidth throttling by YT.

Why are old devices not seeing the same behavior? Perhaps they are excluded because many old devices don't support 2k playback, or maybe because they are a minority and were not picked out of the crowd of all devices.

@odkrys
Copy link
Author

odkrys commented Oct 19, 2023

While in my old rooted xiaomi redmi 3 with android 5 from 2016 the codec showing is AV1 and I can play shorts and videos @ 1080@60 without a single problem.

The best guess I can make is that since your redmi 3 is such an old device and only supports old APIs, the feature that checks the hardware playback capabilities currently used by youtube will not work, and will use the cpu for software playback. Other than this I have no idea how to use the av1 codec on that device.

@eldepor
Copy link

eldepor commented Oct 19, 2023

The behavior might be bandwidth throttling by YT.
Why are old devices not seeing the same behavior? Perhaps they are excluded because many old devices don't support 2k playback, or maybe because they are a minority and were not picked out of the crowd of all devices.

Yeah it's obviously YT throttling things, things that I don't want and I didn't tell it to do, that's the problem. I don't want the app to trigger anything that literally destroys the YT experience itself, like watching 480 vertical videos in a 10" tablet lol. But as said, modifying the smali file does the job, I guess I would have to decompile the apk each time because I don't know or don't have enough knowledge to do it other way, like a patch or something. Thanks anyway

the feature that checks the hardware playback capabilities currently used by youtube will not work, and will use the cpu for software playback.

Well, then I would love to have that behaviour in my app, definitely, zero limitations and good video playback performance

Other than this I have no idea how to use the av1 codec on that device.

It uses avc1 codec, sorry my bad, while vp9 in the new devices.

@odkrys
Copy link
Author

odkrys commented Oct 19, 2023

Oh, I see. Then, it may just be a small problem caused by the manufacturer setting the hardware codec information to 1920x1080.
Some manufacturers consider vertical video and set it to 1920x1920, but some manufacturers do not do that.

The only thing that allowed me to play 1080p shorts is by enabling "force vp9" patch from @inotia00 fork (I guess because of the "lift-vertical-video-restriction patch"), but that only solved half of the problem: shorts max resolution available is now 1080p as it should be, BUT the quality drop issue still there: after few videos the app starts to struggle, and the shorts that I've been playing in 1080 starts to stutter, then suddenly the resultion drops to 480p again, until I close the video/short and open it again.

In theory, there should be no difference between revanced extended's video codec option and changing the "getSupportedHeights" code, so I don't know why it's causing you the problem of lowering the video quality to 480p.

@eldepor
Copy link

eldepor commented Oct 19, 2023

Some manufacturers consider vertical video and set it to 1920x1920, but some manufacturers do not do that.

Maybe because of that?

Maybe the extended's video codec option just lifts the restriction, but 1080 vertical is still "not supported", so it goes back to "where it should be" (480) at the minimal stutter, but modifying the smali makes it "supported"? I have no idea and maybe I'm failing hard here, but looks like something related with the manufacturer's codec information as you said.

This happens especially in shorts and vertical videos, but I'm remembering a case where enabling extended video codec option allowed me to choose 1440 and 2160 that the tablet is not able to play, I selected them for testing and the struggle was real, and then same thing happened: not only drop to 480, but 2160, 1440, 1080 and 720 vanished from the quality menu.

In the redmi 10 I don't remember if the quality drop happens too or just lifting the restriction was enough, will test again later.

@eldepor
Copy link

eldepor commented Oct 19, 2023

Just a brief update: I installed official revanced with the modified smali file in the Redmi 10, now shorts are automatically played smoothly in 1080p60. Without modifying smali file, maximum resolution was 720p60. It just makes no sense, this phone is way more than capable to handle 1080p60 shorts and 1440p60 videos but for some reason the default apk it's restricting to 720, including play store official YT app. Hope this helps.

@eldepor
Copy link

eldepor commented Oct 20, 2023

So far the spoof dimensions patch completely solved the issue, so no more smali file editing and no more quality drops. Thanks a lot master!

@oSumAtrIX oSumAtrIX transferred this issue from ReVanced/revanced-patches-template Dec 14, 2023
@oSumAtrIX oSumAtrIX transferred this issue from another repository Dec 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature request Requesting a new feature that's not implemented yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants