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

How to run Crankshaft in Portrait Mode #403

Open
Freundschaft opened this issue Feb 12, 2020 · 15 comments
Open

How to run Crankshaft in Portrait Mode #403

Freundschaft opened this issue Feb 12, 2020 · 15 comments
Assignees
Labels
dontclose enhancement New feature or request pre-alpha52 pre-alpha52

Comments

@Freundschaft
Copy link

Hi there,

I am helping out a friend to setup crankshaft in his car.
I got everything working in general, but his car has a special setup where the touchscreen is installed in portrait mode, not in landscape mode.
I was wondering if it is possible to run crankshaft in portrait mode, and how I would do that.

Thank you & Best Regards

@abraha2d
Copy link
Member

It looks like theoretically it can be done. https://support.google.com/androidauto/thread/8844203?hl=en. Not sure if Crankshaft supports it though, will have to do more digging.

@borconi
Copy link

borconi commented Feb 29, 2020

It can be done, the trick is to do overscan on the output.
Take the output screen display and make calculations on how much margins to add.

Here is the rough idea on how to do it (screenRatio is the actual display ratio and the remoteRatio is the ratio of the video stream):

 SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(context);
     float remoteRatio=(float)width/height;
     float screenRatio=(float)screenWidth/screenHeight;
     int modWidth[]=new int[3];
     int modHieght[]=new int[3];
     if (SP.getBoolean("overscan",true)) {
         if (screenRatio > remoteRatio) {
             modHieght[0] = Math.round(480 - (800 / (float) screenRatio))+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_top","0")));
             modHieght[1] = Math.round(720 - (1280 / (float) screenRatio))+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_top","0")));
             modHieght[2] = Math.round(1080 - (1920 / (float) screenRatio))+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_top","0")));
             modWidth[0] = 0+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_left","0")));
             modWidth[1] = 0+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_left","0")));
             modWidth[2] = 0+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_left","0")));
         } else {
             modWidth[0] = Math.round(800 - (480 * (float) screenRatio))+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_left","0")));
             modWidth[1] = Math.round(1280 - (720 * (float) screenRatio))+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_left","0")));
             modWidth[2] = Math.round(1920 - (1080 * (float) screenRatio))+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_left","0")));
             modHieght[0] = 0+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_top","0")));
             modHieght[1] = 0+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_top","0")));
             modHieght[2] = 0+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_top","0")));
       
 }
}
     Log.d("CarSetup","Crop box: "+modWidth[0]+", Screen ratio: " + screenRatio + " Screen width: " + screenWidth + ", Screen height: " +screenHeight);


......


//Video
     channelDescriptior.clear();
     AVChannelData.AVChannel.Builder avch = AVChannelData.AVChannel.newBuilder();
     avch.setStreamType(AVStreamTypeEnum.AVStreamType.Enum.VIDEO);

     avch.addVideoConfigs(VideoConfigData.VideoConfig.newBuilder().setDpi(dpi).setVideoFps(VideoFPSEnum.VideoFPS.Enum._60).setVideoResolution(VideoResolutionEnum.VideoResolution.Enum._480p).setMarginHeight(modHieght[0]).setMarginWidth(modWidth[0]));

     avch.addVideoConfigs(VideoConfigData.VideoConfig.newBuilder().setDpi(dpi).setVideoFps(VideoFPSEnum.VideoFPS.Enum._30).setVideoResolution(VideoResolutionEnum.VideoResolution.Enum._720p).setMarginHeight(modHieght[1]).setMarginWidth(modWidth[1]));

     avch.addVideoConfigs(VideoConfigData.VideoConfig.newBuilder().setDpi(dpi).setVideoFps(VideoFPSEnum.VideoFPS.Enum._30).setVideoResolution(VideoResolutionEnum.VideoResolution.Enum._1080p).setMarginHeight(modHieght[2]).setMarginWidth(modWidth[2]));

     channelDescriptior.setAvChannel(avch.build());
     channelDescriptior.setChannelId(VIDEOCHANNEL);

@abraha2d
Copy link
Member

abraha2d commented Mar 3, 2020

Hmm, so say if the screen resolution is 480x800, then AA running on the phone will send out a 1920x1080 feed, but with the interface only occupying a 480x800 part of it, or something similar?

@borconi
Copy link

borconi commented Mar 3, 2020

@abraha2d - Sorry I've updated the previous answer with more details. I'll try to explain the logic a bit better.

Let's say the screen is 600x1200 (800x480 is a standard resolution so it's easy to get confused).
This means the the actual screen ratio is 600/1200 = 0.5, if we set AA to work in 720p it will send a video feed of 1280/720=1.77 so based on above code we use this calculation:

 modWidth[1] = Math.round(1280 - (720 * (float) screenRatio))+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_left","0")));
modHieght[1] = 0+Integer.valueOf(IntegerConvertor.intval(SP.getString("margin_top","0")));

Let's try to understand it, modWidth will be 1280-720*0.5=960 and modHeight will be 0 (we are ignoring the margin_let\margin_top parameter that is a manual setting if the user wants to tweak the calculation)

So now we look at the video setup line:

avch.addVideoConfigs(VideoConfigData.VideoConfig.newBuilder().setDpi(dpi).setVideoFps(VideoFPSEnum.VideoFPS.Enum._30).setVideoResolution(VideoResolutionEnum.VideoResolution.Enum._720p).setMarginHeight(modHieght[1]).setMarginWidth(modWidth[1]));

Basically we told Android Auto to add a margin of 960px. AA will split this into 2 and will add a margin of 480px to on the left and 480px on the right, so the video send by Android will be 1280x720 but will have 2 huge black bars on the left and right, and the content in the middle will actually be 360px720px. Our screen is 1200 px tall, to so we stretch the video to match that height. This means we enlarge the video with a factor of (1200/720=1.66). Since we enlarge the whole video with 1.66 the middle box where the actual stuff is displayed will be 3601.66/720*1.66 = 600/1200
Sure we will have 2 huge black boxes on the side of the video, but since are using overscan, we show the center of the video feed and whatever is not fitting in the screen will be disregarded. With the above setting the 2 black box will be disregarded and the content will be left intact. AA will make sure to render the content correctly to fit in the small box and leave 2 margins as we requested it.

Hope this makes more sens now.

@abraha2d
Copy link
Member

That makes a lot of sense, so simple. Makes you wonder why these OEMs can't be bothered to implement something similar...

I'll try implementing this to work with crankshaft, and testing with portrait 480x800 resolution (as that's the only touchscreen I have). Maybe I'll also see how it'll work with a nice 1050x1680, but I won't be able to test touch input.

@paul591
Copy link

paul591 commented Jul 8, 2020

Hi - Does this actually scale and distort the Andriod Auto projection, or does it still appear correct?

@matt2005 matt2005 added enhancement New feature or request pre-alpha52 pre-alpha52 dontclose labels Oct 1, 2020
@rschulz29
Copy link

I stumbled across this thread and it seems to be exactly what I was looking for, but I don't know where the code belongs. Can someone point me in the direction needed to implement it?

@thomaseleff
Copy link

Hey @abraha2d, any luck with implementing this to work with crankshaft?

@borconi
Copy link

borconi commented Apr 16, 2023

AA now supports vertical screen as well, no need to do tricks....

@rschulz29
Copy link

AA now supports vertical screen as well, no need to do tricks....

Is this something new? I couldn't get portrait (vertical) to work under 2022-09-11-crankshaft-ng-66525ef? Android auto just stretched the screen. I couldn't get it to resize to a portrait resolution

@borconi
Copy link

borconi commented Apr 16, 2023 via email

@matt2005 matt2005 self-assigned this Apr 16, 2023
@thomaseleff
Copy link

Hmm interesting, have been experiencing horizontal screen compression and assumed it could be related to this thread... E.g. a 16x10 screen ratio, squeezed to 16x9. The screen displays correctly by Windows and Raspberry Pi, when configured with the correct screen information.

Is there a particular version of Android (or Android auto) where this was resolved?

@borconi
Copy link

borconi commented Apr 16, 2023 via email

@thomaseleff
Copy link

Hey @borconi , thanks for all the info. I am new to crankshaft and android, so am unsure how to resolve this myself. If there is a write up available, I'd love to take a look.

Otherwise, I appreciate the input and will live with my slightly ovular icons ha

@borconi
Copy link

borconi commented Apr 17, 2023 via email

peat-psuwit added a commit to peat-psuwit/aasdk that referenced this issue Oct 20, 2024
According to my personal testing, the old value was incorrect i.e.
_720p_p doesnt' give me portrait video. Instead, using enum values from
[1] instead which seems to correspond to my testing.

[1]: opencardev/crankshaft#403 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dontclose enhancement New feature or request pre-alpha52 pre-alpha52
Projects
None yet
Development

No branches or pull requests

7 participants