3

I'm trying to stream a video to a custom TextureView. The Video is shown in fullscreen mode. The layout is the same for portrait mode and landscape mode:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root_layout"
    tools:context=".SampleActivity">

    <com.my.package.MyCustomTextureView
        android:id="@+id/texture_custom"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:keepScreenOn="true" />

    ...
</RelativeLayout>

The Activity in the Manifest is set to handle the orientation changes itself:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".SampleActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:label="@string/app_name"
        android:theme="@style/FullscreenTheme" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

When the orientation changes, the Activity seems to find the correct size:

public class SampleActivity extends FragmentActivity {

    ....

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        RelativeLayout root = (RelativeLayout) findViewById(R.id.root_layout);
        MyCustomTextureView view = (MyCustomTextureView) findViewById(R.id.texture_custom);

        Log.d(TAG, "onConfigurationChanged newConfig: " + newConfig.screenWidthDp + "x" + newConfig.screenHeightDp + " root: "+root.getWidth() + "x" + root.getHeight() + " view: " + view.getWidth() + "x" + view.getHeight());

        ....

    }
}

Activity log output, when I pass from portrait to landscape (note: this is before the layout change):

09-29 15:30:28.975  22303-22303/com.my.package D/com.my.package.SampleActivity onConfigurationChanged newConfig: 598x335 root: 1080x1920 view: 1080x1920

...but the Custom Texture View is receiving the wrong values:

public class MyCustomTextureView extends TextureView implements TextureView.SurfaceTextureListener {

    ....

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {

        Log.v(TAG, "onSurfaceTextureSizeChanged params: " + width + "x" + height + ", old values " + mMyWidth + "x" + mMyHeight + ", method values: " + getWidth() + "x" + getHeight());

    }

    ....
}

TextureView log output, when I pass from portrait to landscape:

09-29 15:30:29.037  22303-22303/com.my.package V/com.my.package.MyCustomTextureView﹕ onSurfaceTextureSizeChanged params: 1080x1080, old values 1080x1920, method values: 1080x1080

If I go back to portrait mode, it seems to retrieve the correct size once again:

Activity:

09-29 15:30:45.019  22303-22303/com.my.package D/com.my.package.SampleActivity onConfigurationChanged newConfig: 360x567 layout: 1920x1080 view: 1080x1080

TextureView:

09-29 15:30:45.096  22303-22303/com.my.package V/com.my.package.MyCustomTextureView onSurfaceTextureSizeChanged params: 1080x1920, old values 1080x1920, method values: 1080x1920

What am I doing wrong?

fadden
  • 51,356
  • 5
  • 116
  • 166
ocramot
  • 1,361
  • 28
  • 55

2 Answers2

0

...ok, I found the solution myself, by intensive trial and error. Mostly error.

Anyway, I still have no idea why is it having this behaviour. If you have any idea, feel free to comment and enlighten me :D (and help anyone else that might have a similar problem).

The Idea came to me after reading Mark G.'s question. I simply added a line to the onConfigurationChanged function:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    RelativeLayout root = (RelativeLayout) findViewById(R.id.root_layout);
    MyCustomTextureView myView = (MyCustomTextureView) findViewById(R.id.texture_custom);

    Log.d(TAG, "onConfigurationChanged newConfig: " + newConfig.screenWidthDp + "x" + newConfig.screenHeightDp + " root: "+root.getWidth() + "x" + root.getHeight() + " view: " + myView.getWidth() + "x" + myView.getHeight());

    myView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));

    ....

}

With this change, when I pass from 1080x1920 to 1920x1080, I get the correct values in the onSurfaceTextureSizeChanged function, instead of 1080x1080. Same thing when I pass from 1920x1080 to 1080x1920.

...no, don't ask me why do I have to put this manually. I have no idea.

For the sake of being completely sure, I tried to put that line directly in the onSurfaceTextureSizeChanged function, instead of in onConfigurationChanged :

@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {

    Log.v(TAG, "onSurfaceTextureSizeChanged params: " + width + "x" + height + ", old values " + mMyWidth + "x" + mMyHeight + ", method values: " + getWidth() + "x" + getHeight());

    setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));

}

...that didn't work. Once again, I ave no idea why. It MIGHT be because 1080x1080 is not the erroneous size of the TextureView, but the erroneous size of the root RelativeLayout itself.

Community
  • 1
  • 1
ocramot
  • 1,361
  • 28
  • 55
0

I had similar problem using Camera2 implementation. I used AutoFitTextureView implementation of TextureView as preview from camera, and want to adjust to correct ratio. My problem income from different implementations of methods and propagate to onSurfaceTextureSizeChanged. [1]com.google.android.cameraview.CameraView#onMeasure(..) -> [2]com.google.android.cameraview.AutoFitTextureView#onMeasure(..) -> [3]onSurfaceTextureSizeChanged(..)

Problem where in different if [1] than in [2]. I replaced in [1]:

if (height < width * ratio.getY() / ratio.getX()) {

to

if (!(height < width * ratio.getY() / ratio.getX())) {

because [2] had if based on width not height

 if (width < height * mRatioWidth / mRatioHeight) {

Verify if methods onMeasure(..) are implemented correctly.

Damian JK
  • 479
  • 1
  • 3
  • 9