I am rendering a video on a SurfaceView in my android app, and I want to resize the surface to match the video size. I do this by setting a new Layout like so:
FrameLayout.LayoutParams videoLayout = new FrameLayout.LayoutParams(width, height);
videoLayout.leftMargin = x;
videoLayout.topMargin = y;
view.setLayoutParams(videoLayout);
Seems to work fine on other android tv boxes but on nVidia Shield the screen goes black. It only works if width and height match the actual resolution, for anything other it's just black.
Also works if I render on a TextureView, but then I take a big performance hit.
Also tried with setFixedSize, same outcome.
view.getHolder().setFixedSize(width, height);
Related
I have a custom VideoView, I'm overriding onMeasure method to make video fill the screen, while keeping proportions of the video file.
Everything works fine, but with some videos, it has a strange behaviour:
I put an interrupt point in onMeasure method and run in debug mode.
When video loads, it fills the screen as expected, but after some seconds, exactly when the mouse pointer disappears, the video resizes to its original size, not filling the screen, and without passing again over the interrupt point (onMeasure method is not called).
If I move the mouse again, the video fills the screen until the pointer disappears.
I'm using Android 4.4.4.
In case someone has the same problem, I'll post what I did:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
FrameLayout fralayout = (FrameLayout) findViewById(R.id.framelayoutparent);
FrameLayout.LayoutParams lpFraParams = (FrameLayout.LayoutParams) fralayout.getLayoutParams();
lpFraParams.width = metrics.widthPixels-1;
lpFraParams.height = metrics.heightPixels-1;
fralayout.setLayoutParams(lpFraParams);
Previously I didn't substract one pixel to width and height, substracting one pixel did the trick. This FrameLayout is the parent of the VideoView.
I don't understand why it had that behaviour.
I am making a simple platformer in Unity. This is what it looks like in the editor:
You see, it is set to be in landscape in a 16 by 9 ratio. This is just fine.
Now, a few days ago, I updated my JDK to the newest version. Before, my game looked just like that on my Samsung S8. It was centered with black pillars to the left and right of it, since the screen isn't 16:9. This was great.
Now after updating, this is what it now looks like:
I am not sure why Unity does this.
Clearly, the game is now cut off on the top and lower ends so that it keeps its ratio. But this isn't what I want. I want my black pillars back to have everything be on screen and not partly be off screen.
I solved this problem with next steps:
PlayerSettings/Aspect Ratio Mode = Legasy(1.86)
PlayerSettings/Supported Aspect Ratios = 16:9 only
Canvas Scaler/UI Scale Mode = Scale With Screen Size
Canvas Scaler/Reference Resolution = any resolution for aspect ratio = 16:9 (1920; 1080)
Canvas Scaler/Match = 1 (for scale based on height)
All Cameras/Background = full black
Fix the resolution and aspect ratio issues directly: add a canvas scaler to the root canvas gameobject.
Canvas Scaler
Basically, force fixed width and let the height vary based on aspect ratio. Make sure all UI is properly anchored from the top or bottom to handle that variation.
On my Moto E, I want my preview to be full screen hence i have set the texture view's dimension to be full screen i.e. 540*960by overriding onMeasure, but using camera2 api the closest match of preview size that i am getting is 768*432 which is of the same aspect ratio. Google sample suggests that "Initially, output stream images from the Camera2 API will be rotated to the native device orientation from the sensor's orientation, and the TextureView will default to scaling these buffers to fill it's view bounds. If the aspect ratios and relative orientations are correct, this is fine." But even when in native orientation I am getting stretched previews. Even if I setTransform to Identity matrix, I don't know how the preview is still scaled automatically to fill the whole screen.
I also encountered this problem and solved it like this:
re-set surfaceview params (width and heigth).
ViewTreeObserver observer = mSurfaceView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
FrameLayout.LayoutParams surfaceParams = (FrameLayout.LayoutParams) mSurfaceView.getLayoutParams();
surfaceParams.height = screenHeight;
surfaceParams.width = screenWidth;
mSurfaceView.setLayoutParams(surfaceParams);
mSurfaceView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
I am using the Intel Inde library for media (specifically this example: https://github.com/INDExOS/media-for-mobile/blob/master/Android/samples/apps/src/com/intel/inde/mp/samples/CameraCapturerActivity.java)
My goal is to set up a full screen preview in portrait mode and record videos in portrait mode. Everything works great in landscape mode(full screen preview and recording). However in portrait mode I can't stretch the preview to fill the screen vertically (even though I set the surface view to max size). The largest size I get is a square image preview. I have tried making the surface view larger then the screen, but still stuck with a square preview and recording.
This is what my preview screen currently looks like:
http://imgur.com/XUznvF1
Here is my code:
public void createCamera()
{
Camera camera = Camera.open();
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> supportedResolutions = camera.getParameters().getSupportedPreviewSizes();
parameters.setPreviewSize(supportedResolutions.get(0).width,
supportedResolutions.get(0).height);
camera.setDisplayOrientation(90);
camera.setParameters(parameters);
}
public void createPreview()
{
GLSurfaceView surfaceView = new GLSurfaceView(getActivity().getApplicationContext());
//This code is used to get display size to set surface view size
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
surfaceView.setLayoutParams(new FrameLayout.LayoutParams(width, height));
//Used to test that the surfaceview does cover the whole screen
//surfaceView.setBackgroundColor(Color.RED);
((RelativeLayout)view.findViewById(R.id.myview)).addView(surfaceView, 0);
preview = capture.createPreview(surfaceView, camera);
preview.start();
}
There is a thread on the Intel Developer site, appears to be the same issue. They have a solution, but you have to request the library update via email:
https://software.intel.com/en-us/forums/topic/542633
I think your problem is that you are setting the preview size of your camera to the first size in the list of supported sizes.
List<Camera.Size> supportedResolutions = camera.getParameters().getSupportedPreviewSizes();
parameters.setPreviewSize(supportedResolutions.get(0).width, supportedResolutions.get(0).height);
What you should do is loop through the list of supported sizes and find a size that closely matches the screen's size/resolution.
You can check this SO answer for sample code snippets
Update
The next step would be to debug it and find out why it didn't work for you. What I would do in your case would be to print out the contents of the supportedResolutions list. Since you already the have the display size, I would compare the display size to the different sizes in the supportedResolutions list and also to the size returned from the getOptimalSize method. It's possible that the getOptimalSize method didn't find an optimal size and the method may need to be tweaked to your need. I tweaked mine to get it to work.
Let me know if you need more help.
This is my final technology issue that i have to complete my 4 month of work on my app.
I will try to be simple as i can,because i need specify solution.
My problem:
In short: i need the stretch my glSurfaceView
I am using custom glsurfaceView,that implement OnMeasure method to set the actual width and height to the surface.
I set the width and height for 1280 and 720 for instance.
then i use openGL and get that pixels with glReadPixel() method to encode video
so far so good.
i add the view in that way :
this.addContentView(this.mRenderSurfaceView, BaseGameActivity.createSurfaceViewLayoutParams());
when :
protected static LayoutParams createSurfaceViewLayoutParams() {
final LayoutParams layoutParams = new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.gravity = Gravity.CENTER;
return layoutParams;
}
Thats what i tried so far:
I want the glsurface to be the actucal pixels that i set in OnMeasure,
that's mean the glReadPixel() function will get the same pixels as i set,
but,I want to scale this surface,without changing to actucal pixels.
when i try this:
this.mRenderSurfaceView.setPivotX(0.0));
this.mRenderSurfaceView.setScaleX(2.0));
It just copy the surface to another place in the screen,without any scale.
What i do wrong?
Please,I don't need to change the actual width and height of this surface.i need it as is-but i have to scale it that the user will see it bigger then the real pixel that i set with onMeasure method.
**i encode the surface to video so any change in width/height will change the pixel that i get in glReadpixel-so just scale is needed.