Android MediaCodec encoder - weird results for Samsung device - android

Edit:
Seems the issue is this device needs not multiple of 16 dimensions...but multiple of 32. Thing is, I still have no idea how to determine what quantifies as a problematic device. This does appear to use qcom (which I've seen to be problematic on Android 4.X, but this is Android 5.1.1).
I'm encoding a video in my Android app. I'm using Android MediaCodec to do so, converting RGB of each frame to YUV and passing in the pixels.
The code I use has been in place for a while, and works across any device I've come across.
A user came to me with a bug report that their MP4s were coming out weird. The device is a Samsung T337A (a Galaxy Tab 4).
Here are what MP4 exports look like:
NOTE - For whatever odd reason, it doesn't happen at all resolutions. It's confirmed to happen at 768x432 and 1280x720 but does not happen at 640x352 for example (my app makes sure all resolutions are divisible by 16 by default).
On a Nexus 5X (which uses the same semi-planar YUV format) the output works at all resolutions.
So it's something with this device, and maybe other devices I don't know about?
I've looked at all output, and it looks normal and identical to the Nexus 5X I mentioned above (which works 100% of the time).
MediaCodecInfo being used is OMX.qcom.video.encoder.avc, color format being used is 2135033992 (which is COLOR_FormatYUV420Flexible). So basically, nothing weird.
The code is a bit expansive, I'll post if necessary, but just looking for general ideas of why this happens. I'd understand if it was more common, but the same code works for a vast array of other devices, so something funky is going on...

Make sure that you use the right strides and buffer offsets values

Related

640x360(360p) Camera resolution

In my Android app, I would like to use 16:9 resolution for camera preview & transmit via WebRTC call
Wanted to go with 360p (640x360) since its common & it wont require high bitrate to transmit
I am using Camera2 API. As a best practice, I first identified the list of supported resolution on the device to check if 360p is supported or not. Once verified, I proceed to create cameraCapturesession
But this check is failing in some devices - Real Me 5 Pro, Redmi Note 7S, redmi note 7 (all running android versions >=9)
Though it seems to be a popular resolution, 360p is not available in the list of supported resolutions in these devices
List is fetched via cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(SurfaceTexture.class)
It was not available with getOutputSizes(ImageFormat.JPEG) as well
And When I force to create the cameraCaptureSession with 640*360 without verifying supported resolution, It actually worked - it was able to capture 640x360 resolution. Looks like device camera actually supported it, but not available in the list fetched from cameraCharacteristics.
I assume i cannot force this resolution without doing check - as it might not work in some device and will throw exception/crash
I thought of adding a fallback by choosing closest match for 360p - either 16:9 will have to be compromised or 1280x720 will have to be chosen - it ll require higher bitrate to transmit
I think 360p is a std resolution- Any possible reason why it is not listed as supported, but actually worked when forced?
As per my understanding of doc, SCALER_STREAM_CONFIGURATION_MAP should return exhaustive list of resolutions supported by hardware
Am I missing anything? Please suggest solution or workaround
16:9 at 640x360 is not really used much on modern mobile cameras, because it's such a low resolution. 720p is about the lowest size people want to record video at, so that gets reflected in the sizes supported.
However, 640x480 (4:3 VGA) is guaranteed to be supported, so the safe thing is to use that and crop if you want to get 16:9.
Assuming the size will work if it's not listed is very risky - it might, or might be stretched, or it might work but if you add some other output it might fall over. And all of this is going to be device-specific, so you just won't know ahead of time, and some new device may just fail. So I don't recommend it at all.

Black screen using glReadPixels(...) on Samsung s9

For app reason I need to retrieve a screenshot of the screen, or to better say only the OpenGL drawn section. In all other devices my function works and uses the OpenGL primitive: "glReadPixels(...)"
On Galazy S9 the result is a buffer completely black, I've also try to use the "glGetError()" and it returns: "GL_NO_ERROR".
Have you some idea how can I solve it?

Unity UI Masking doesn't work on Galaxy Note and Kindle Fire

I'm developing a game in Unity 5.2.2f1 and I'm using the canvas and image masking elements then building an .apk for Android. On most Android devices this works fine, but on the Galaxy Note 5 and the Kindle Fire HD, the masking doesn't take.
What's also interesting is that it DOES work on Galaxy Note and Kindle Fire HD when I use the default provided asset that is part of the unity_builtin_extra resource, but not when I use a .gif or a .png for the image asset.
Mask Works on all Android devices:
Mask only works on some Android devices:
I've also tried updating various setting like setting the cameras to forward rendering and enabling 32-bit Display Buffer (as other posts have suggested), but nothing so far has worked.
Any leads or thoughts on this would be greatly appriciated!
In the past, I encounter similar problem with the UI Mask on Linux, there is a bug reported on it.
Since they haven't fixed it, I would not be surprise if some other devices have the same problem.
If the Mask purpose is for UI, then you could use the 2D Rect Mask instead which is way more efficient, but only made for UI and has some limitation.
As you can read in the doc :
The limitations of RectMask2D control are:
It only works in 2D space
It will not properly mask elements that are not coplanar
The advantages of RectMask2D are:
It does not use the stencil buffer
No extra draw calls
No material changes
Fast performance
Either way, I'd report your issue with a small test-bed project so they can test it out and eventually write a fix for it.
In the meantime, hopefully the 2DRectMask can be a workaround!

Android setOrientationHint on HTC Phones

When using setOrientationHint for recording videos, Samsung and Motorola phones simply write this value into the Rotation Metadata.
However, it appears HTC phones do not write this value into the metadata and actually attempt to rotate the video after recording. The phones I have tried on Android 4.0.3 and lower actually rotate it 90 degrees no matter the value and the 4.0.4 phones rotate it as per the value.
Has anyone else noticed this behavior and what is the best way to fix this?
In my experience, there's nothing you can do to unify all devices. Some devices add metadata, some rotate the byte array, and some dismiss it altogether.
Another problem you have with metadata is that just as the recording devices differ, so do the playback devices, in Windows for example you might have noticed that jpeg metadata (EXIF) is ignored and all images are displayed landscape.
I would have hoped by now that the hardware manufacturers would have had certain hoops to jump through with regards to camera hardware but it seems that this is still a problem.

OpenGL Android App works on most phones but textures come up white on Xoom

My Android app has been out for several months and works fine on any number of WVGA phones like the Droid, Droid 2, Galaxy, etc.
On the Motorola Xoom, however, a small portion of the textures load with white boxes where the images should be.
Researching online the most usual cause for this appears to be not using power of two textures. This seems an unlikely explanation since they work fine on so many other devices. Also, I am using power of two textures. The one caveat there is that I'm loading a bunch of bitmaps into a 1024 by 1024 texture dynamically. The code I'm using is from a now defunct library called Rokon, the relevant texture atlas code is here: http://code.google.com/p/rokon/source/browse/trunk/src/com/stickycoding/rokon/TextureAtlas.java?r=260 -- Like I said, I'm skeptical this could be the cause since it works on so many other devices AND many of the textures I am loading this way do work fine.
But I'm not sure what else could be causing it. A memory issue seems unlikely given that amount of memory available on the Xoom compared to the other devices the app works on.
Right now I don't own a zoom, but I can replicate the issue via DeviceAnywhere (where I see white backgrounds).
Nothing of interest shows up in LogCat either.
I know this isn't much to go on, but I'm at a loss here, what kinds of potential causes should I be looking at here? Thanks in advance for any ideas.
Try using glGetError() to see if OpenGL throws any errors
Is your application 2D or 3D? When you're drawing your sprites on the screen; which method are you using?
If your texture is white during onDrawFrame that probably depends on:
An untextured quad (using VBO:s or standard Vertex Arrays) - probably not, because it works on other devices
Xoom lacks support of the draw_texture extension - if you're using 2D
Xoom lacks support of VBO:s (Vertex Buffer Objects) - probably not, almost every Android device out there supports VBO:s
Do you have any sort of texture compression implemented that Xoom doesn't support?
At runtime, use this code to get the extensions and check if they're available:
String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
boolean supportsDrawTexture = extensions.contains("GL_OES_draw_texture");
// Continue here and sooner or later you should see where Xoom lacks support
// where other devices doesn't.
Is it possible that you're falling foul of Android's automatically-resize-bitmaps behaviour? Print out the bitmap sizes as they are loaded to check, or move them to res/drawable-nodpi to avoid the behaviour entirely.
Is it possible that your texture exceeds 2048 pixels width or height? That's the maximum allowed texture size on XOOM.

Categories

Resources