AOSP Dual Monitor Support at Conflicting Aspect Ratios - android

I am creating an In-Vehicle Infotainment (IVI) system running Android. The development board I am using is the Rock960 from 96boards.com This board supports dual display output which is perfect because it needs to drive both the Head Unit (HU) and the Instrument Cluster (IC) in front of the driver. This is where the issue lies. The HU has a resolution of 1920x1080 and the IC has a resolution of 1280x480. Output works on both displays, but it appears very stretched on the IC due to its odd resolution.
The SoC is RK3399 from Rockchip. Here is a link to the AOSP page for this board: https://www.96boards.org/documentation/consumer/rock/build/aosp.md.html
I have tried changing the framebuffer resolution: persist.sys.framebuffer.main=1280x480 in device/rockchip/rk3399/rk3399_box/system.prop
When I do that, everything displays correctly on the IC but then the HU appears stretched.
Here is the system properties file:
#
# system.prop
#
#rild.libpath=/system/lib/libreference-ril.so
#rild.libargs=-d /dev/ttyUSB2
# Default ecclist
ro.ril.ecclist=112,911
wifi.interface=wlan0
persist.tegra.nvmmlite = 1
persist.sys.boot.check=false
ro.audio.monitorOrientation=true
#NFC
debug.nfc.fw_download=false
debug.nfc.se=false
#add Rockchip properties here
ro.rk.screenoff_time=2147483647
ro.rk.screenshot_enable=true
ro.rk.def_brightness=200
ro.rk.homepage_base=http://www.google.com/webhp?client=
{CID}&source=android-home
ro.rk.install_non_market_apps=false
sys.hwc.compose_policy=6
sys.wallpaper.rgb565=0
sf.power.control=8847360
sys.rkadb.root=0
ro.sf.fakerotation=false
ro.sf.hwrotation=0
ro.rk.MassStorage=false
ro.rk.systembar.voiceicon=true
ro.rk.systembar.tabletUI=false
ro.rk.LowBatteryBrightness=true
ro.tether.denied=false
sys.resolution.changed=false
ro.default.size=100
persist.sys.timezone=
ro.product.usbfactory=rockchip_usb
ro.support.lossless.bitstream=true
wifi.supplicant_scan_interval=15
ro.factory.tool=0
#set default lcd density for rk3399 box product
ro.sf.lcd_density=213
ro.adb.secure =0
ro.rk.statusbar=0
# set to false if not use displayd
ro.rk.displayd.enable=false
# default main framebuffer resolution
persist.sys.framebuffer.main=1920x1080
# default primary display
sys.hwc.device.primary=DP
sys.hwc.device.extend=HDMI-A
Also, any idea what ro.rk.displayd.enable is?
I expect both displays to show their content correctly according to their own resolutions. The output should not be stretched or distorted on either screen.

see HWComposer.cpp; this should be primary & external - instead of primary and extend (where extend might cause the scaling); which might already answer the question. these should be defined in /kernel/drivers/video/rockchip. adding further logging to the source code might help to understand what is even going on, when it is setting up the displays.
displayd might be an OSD display daemon, hence anything which ends with a d is usually a daemon. if this can be somehow be done with Android, while the kernel is adequately configured, see https://developer.android.com/reference/android/app/Presentation
the most easy might be to ask them (at least, compared to Chinese manuals).

Related

Does Ionic Camera Preview plugin provide a full-quality pic?

There are 2 ways (that I'm aware of) to capture images/videos from the camera in an ionic app:
Native camera app
'Camera Preview' library
The first option I know will allow users to maximise the potential of the camera (quality, megapixels etc.), but I need the flexibility of adding an overlay (basically I need the flexibility of the second option).
Question
In the docs I can only see the ability to see a 'quality' argument as part of the 'takePicture' call, how would a maximum of 100 here compare to the quality of a pic I'd have got from the native app?
I know this is called 'camera preview' but ideally I need it to be the best image quality the camera's capable of capturing (same as the native app).
https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview
Take snapshot of the camera preview. The resulting image will be the same size as specified in startCamera options. The argument quality defaults to 85 and specifies the quality/compression value: 0=max compression, 100=max quality.
CameraPreview.takePicture({width:640, height:640, quality: 100}, function(base64PictureData|filePath) {
// One simple example is if you are going to use it inside an HTML img src attribute then you would do the following:
imageSrcData = 'data:image/jpeg;base64,' + base64PictureData;
console.log(imageSrcData);
});
For More Info Check Documentations.

how to test/exercise android's screen rotation behavior?

I'd like to test android's behavior on all possible combinations of the following "inputs":
top activity's setRequestedOrientation() (15 possible values, not including SCREEN_ORIENTATION_BEHIND)
Settings.System.ACCELEROMETER_ROTATION (2 possible values)
Settings.System.USER_ROTATION (4 possible values)
device's physical orientation (queryable by OrientationEventListener) (4 possible quadrants)
Specifically, I want to see how the inputs affect the following "output":
getWindowManager().getDefaultDisplay().getRotation() (4 possible values)
So this will require testing at least all 15*2*4*4=480 possible input states.
Additionally, since rotation behavior is often dependent on the history
of the inputs (not just the current input values),
I want to test (at least) all possible transitions from one input state to an "adjacent" input state,
i.e. to an input state that differs from the given input state by one input parameter.
The number of such input state transitions is:
(number of input states) * (number of states adjacent to a given input state)
= (15*2*4*4) * ((15-1) + (2-1) + (4-1) + (4-1))
= 480 * 21
= 10080
Furthermore, sometimes output is dependent on the previous output as well as previous and current
input (e.g. SCREEN_ORIENTATION_LOCKED, SCREEN_ORIENTATION_SENSOR_LANDSCAPE).
The number of possible outputs for a given input state can be between 1 and 4,
so this multiplies the number of transitions that must be tested by up to 4:
10080 * 4 = 40320
That's a lot of transitions to test, so the testing would have to be programmatic/scripted.
Three out of the four input params are straightforward to control programmatically;
the one that's not straightforward to control is the device's physical orientation.
So, how would one go about scripting it? I can think of the following approaches.
Approach #1: Replace the (physical or emulated) device's accelerometer with a scriptable mock accelerometer
for the duration of the test. But, if I understand correctly, mock accelerometers do not exist for android.
Approach #2: Use the android emulator, and script pressing of the "rotate counterclockwise" and
"rotate clockwise" buttons using an interaction automation tool on the host machine (e.g. applescript / autohotkey / xdotool).
Any other ideas?
It turns out this is actually a duplicate of the following excellent question:
How can i simulate accelerometer in android emulator?
which has this excellent answer from #user1302884 :
Unfortunately, that question got no respect and was closed as off-topic (?!) so I won't mark this as a duplicate.
But here's the answer: no need for applescript/autohotkey/xdotool to drive the emulator's ui;
instead, telnet to the emulator and tell it which direction you want "up" to be.
telnet localhost 5554 # or whatever the port is
telnet> sensor # to get help on the sensor command
telnet> sensor get acceleration
acceleration = 0:9.81:0 # if in natural orientation
telnet> sensor get acceleration
acceleration = -9.81:0:0 # if rotated 90 degrees CW from natural orientation
telnet> sensor set orientation -1:1:0 # to set to 45 degrees CW from natural orientation
It would be nice if the emulated display would appear rotated by the specified number of degrees in response, but you can't have everything.

Android Camera2 API - Set AE-regions not working

In my Camera2 API project for Android, I want to set a region for my Exposure Calculation. Unfortunately it doesn't work. On the other side the Focus region works without any problems.
Device: Samsung S7 / Nexus 5
1.) Initial values for CONTROL_AF_MODE & CONTROL_AE_MODE
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
2.) Create the MeteringRectangle List
meteringFocusRectangleList = new MeteringRectangle[]{new MeteringRectangle(0,0,500,500,1000)};
3.) Check if it is supported by the device and set the CONTROL_AE_REGIONS (same for CONTROL_AF_REGIONS)
if (camera2SupportHandler.cameraCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE) > 0) {
camera2SupportHandler.mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, meteringFocusRectangleList);
}
4.) Tell the camera to start Exposure control
camera2SupportHandler.mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);
The CONTROL_AE_STATE is always in CONTROL_AE_STATE_SEARCHING, but doesn't use the configured regions...
After long testing & development I've found an answer.
The coordinate system - Camera 1 API VS Camera 2 API
RED = CAM1; GREEN = CAM2; As shown in the image below, the blue rect are the coordinates for a possible focus/exposure area for the Cam1. By using the Cam2 API, there must be firstly queried the max of the height and the width. Please find more info here.
Initial values for CONTROL_AF_MODE & CONTROL_AE_MODE: See in the question above.
Set the CONTROL_AE_REGIONS: See in the question above.
Set the CONTROL_AE_PRECAPTURE_TRIGGER.
// This is how to tell the camera to start AE control
CaptureRequest captureRequest = camera2SupportHandler.mPreviewRequestBuilder.build();
camera2SupportHandler.mCaptureSession.setRepeatingRequest(captureRequest, captureCallbackListener, camera2SupportHandler.mBackgroundHandler);
camera2SupportHandler.mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
camera2SupportHandler.mCaptureSession.capture(captureRequest, captureCallbackListener, camera2SupportHandler.mBackgroundHandler);
The ''captureCallbackListener'' gives feedback of the AE control (of course also for AF control)
So this configuration works for the most Android phones. Unfortunately it doesn't work for the Samsung S6/7. For this reason I've tested their Camera SDK, which can be found here.
After deep investigations I've found the config field ''SCaptureRequest.METERING_MODE''. By setting this to the value of ''SCaptureRequest.METERING_MODE_MANUAL'', the AE area works also the Samsung phones.
I'll add an example to github asap.
Recently I had the same problem and finally found a solution that helped me.
All I needed to do was to step 1 pixel from the edges of the active sensor rectangle. In your example instead of this rectangle:
meteringRectangleList = new MeteringRectangle[]{new MeteringRectangle(0,0,500,500,1000)};
I would use this:
meteringRectangleList = new MeteringRectangle[]{new MeteringRectangle(1,1,500,500,1000)};
and it started working as magic on both Samsung and Nexus 5!
(note that you should also step 1 pixel from right/bottom edges if you use maximum values there)
It seems that many vendors have poorly implemented this part of documentation
If the metering region is outside the used android.scaler.cropRegion returned in capture result metadata, the camera device will ignore the sections outside the crop region and output only the intersection rectangle as the metering region in the result metadata. If the region is entirely outside the crop region, it will be ignored and not reported in the result metadata.

Minko - Android light issue

I am working with minko and seem to be facing a light issue with Android.
I managed to compile for linux64, Android and html a modified code (based on the tutorials provided by Minko). I simply load and rotate 4 .obj files (the pirate one provided and 3 found on turbosquid for demo purposes only).
The correct result is viewed in the linux64 and html version but the Android one has a "redish" light thrown into it, although the binaries are being generated from the same c++ code.
Here are some pics to demonstrate the problem:
linux64 :
http://tinypic.com/r/qzm2s5/8
Android version :
http://tinypic.com/r/23mn0p3/8
(Couldn’t link the html version but it is close to the linux64 one.)
Here is the part of the code related to the light :
// create the spot light node
auto spotLightNode = scene::Node::create("spotLight");
// change the spot light position
//spotLightNode->addComponent(Transform::create(Matrix4x4::create()->lookAt(Vector3::zero(), Vector3::create(0.1f, 2.f, 0.f)))); //ok linux - html
spotLightNode->addComponent(Transform::create(Matrix4x4::create()->lookAt(Vector3::zero(), Vector3::create(0.1f, 8.f, 0.f))));
// create the point light component
auto spotLight = SpotLight::create(.15f, .4f); //ok linux and html
// update the spot light component attributes
spotLight->diffuse(4.5f); //ori - ok linux - html
// add the component to the spot light node
spotLightNode->addComponent(spotLight);
//sets a red color to our spot light
//spotLightNode->component<SpotLight>()->color()->setTo(2.0f, 1.0f, 1.0f);
// add the node to the root of the scene graph
rootNode->addChild(spotLightNode);
As you can notice the color()->setTo has been turned off and works for all except Android (clean and rebuild). Any idea what might be the source of the problem here ?
Any pointer would be much appreciated.
Thx.
Can you test it on other Android devices or with a more recent ROM and give us the result? LG-D855 (LG G3) is powered by an Adreno 330: those GPUs are known to have GLSL compiling deffects, especially with loops and/or structs like we use in Phong.fragment.glsl on the master branch.
The Phong.fragment.glsl on the dev branch has been heavily refactored to fix this (for directional lights only for now).
You could try the dev branch and a directional light and see if it fixes the issue. Be careful though: the dev branch introduces the beta 3, with some API changes. The biggest API change being the math API now using GLM, and the *.effect file format. The best way to go is simply to update your math code to use the new API, everything else should be straight forward.

Check if image is black

I'm running a Python script under Windows which deals with 480x800 PNG images with 32-bit depth. I need to check if the given image is fully black or not. After some searching I've found that ImageMagick could help me to achieve this but unfortunately there's no manual for such task.
So a more general question is how to check if the image consists only of one color?
Edit:
My apologies for not providing all the information about the environment from beginning. The python script is executed using Android's monkeyrunner. Since it uses it's own instance of Jython (version 2.5) it's not possible to use any modules from external libraries. Inside there's a MonkeyImage class to work with screenshots taken from the device. So I adopted #eumiro's answer for it.
import Image
im = Image.load("image.png")
diff_colors = list(set(im.getdata()))
if len(diff_colors) == 1 and diff_colors[0] == (0, 0, 0):
print "all black"
EDIT as #JonClements proposes, this will be faster and stop as soon as anything else than black is found:
import Image
im = Image.load("image.png")
if all(rgb == (0,0,0) for rgb in im.getdata()):
print "all black"
I am no expert in Python but I saw that there is a PNG module that you can use.
Load the PNG and export it to an RGB(A) array.
Checking if it is totally black should then be simple. Run through the array and make sure nothing differs from 0.
I think this should work.
Out of curiosity, why would you want to check if the image is black?

Categories

Resources