Android TextureView OpenGLRenderer﹕ GL_INVALID_OPERATION - android

I have two fragments that has a TextureView to show camera preview or to play video.
after using the app for a while, playing with the screens,
i get this error in the logcat
OpenGLRenderer﹕ GL_INVALID_OPERATION
i release everything from my fragments,
all members are set to null.
#Override
public void onDestroyView() {
Logg.DEBUG(TAG, "onDestroyView");
super.onDestroyView();
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
nextButton = null;
pauseButton = null;
backButton = null;
playButton = null;
frontTextView = null;
backTextView = null;
surface = null;
videoView = null;
}
and i see the whole view become weird...
what am i missing?

Your screenshot shows situation when system OpenGL context is corrupted / broken. Please check on what thread you release your resouces. GLContext should be destroyed from exactly same thread where it was allocated. In your case it could be setSurface/setDisplay calls made from wrong thread.
If you have stable and easy steps to reproduce you can try to capture GL log using Tracer for OpenGL ES, but its slows your application a lot during capturing

Related

ExoPlayer occupying memory even after releasing

In the main activity of my app, I show a number of cards to user. when he clicks on any of them, a fragment is opened which contains a ViewPager2. The fragments inside the viewPager2 each contains an ExoPlayer and plays a related video when resumed.
When the user clicks on back button, the fragment must be closed and release all its children (including viewPager2 and its fragments, and exoPlayers). In order to release exoPlayers, I use the following code in OnDestroyView() of the viewPager2 fragments:
#Override
public void onDestroyView() {
super.onDestroyView();
try {
if (player != null && listener != null) {
player.removeListener(listener);
player.release();
player = null;
}
if (playerView != null)
playerView.setPlayer(null);
dashMediaSource = null;
progressiveMediaSource = null;
playerView = null;
listener = null;
} catch (Exception ignored) {
}
}
after that, I ran Android Studio profiler to check app heap and I noticed some objects related to exoPlayer are still in memory:
Now the question is are I making a mistake in releasing the memory and specifically exoPlayers? If not why these objects are still in RAM and how to get rid of them?

GLSurfaceView switching issue

I am having an issue with while switching GLSurfaceView. I have a GLSurfaceView (connected with Camera) and I want to move it to another view , but when I am moving it it's losing its frames and showing blackScreen after switching. and when I am reconnecting it to Camera, it starts show my Camera but with delay.
Could any one please tell me solution to move it to another parent without losing its frames (because when I am reconnecting it its showing frames with 2-3 seconds delay).
Please find code written below :
(Here VideoPanel (extends GLSurfaceView) is Frame provided by oovooSDK to show video)
final VideoPanel movingVideoView = parent1.getChildAt(0);
movingView.onPause();
parent1.removeView(movingView);
parent2.addView(movingView);
movingView.onResume();
movingView.requestRender();
for reconnecting :
application.unbindVideoPanel(videoView.userId, videoView.videoRender);
application.unbindVideoPanel(videoView.userId, videoView.videoRender);
// this methods shows delay of 2-3 seconds for binding view again
I tried following methods also
((VideoPanel) videoView.videoRender).setPreserveEGLContextOnPause(true);
// to save context when paused
((VideoPanel)videoView.videoRender).setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // to render frame again when requestRender is called
Camera is not proper release when your activity going to end.
If you are using a Surface view than release your camera in onSurfaceDestroy
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
Also recommend a release your camera if it's not ever going to use.
protected void onDestroy(){
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}

Android Live Wallpaper crashes when tap on camera

I have a live wallpaper that just draws triangles, very simple, and runs smoothly all time. After testing found that when I open the camera to take pictures the phone freezes for about 10 seconds, then the camera opens and the wallpaper crashes and the message "Unfortunately, Live Wallpaper has stopped." appears. Also found that when I open any barcode scanner app the problem raises again because the scanner uses the camera too. Seems the problem raises when the camera app runs. Any ideas what's causing it?
hi #Bullet Camera is just open ones, if it open through any other apps then, you can can not access your camera, Solution is that, where you use camera please release that after no used.
main problem is that, in your app (app in that you are using camera) , so , you release camera after used.
like following :
#Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
when you need
private void releaseCameraAndPreview() {
if (camera != null) {
camera.release();
camera = null;
}
}
or
public void stopCamera() {
if (cameraDevice != null) {
cameraDevice.stopPreview();
cameraDevice.setPreviewCallback(null);
cameraDevice.release();
cameraDevice = null;
System.out.println("in to the stop video");
}
}

Best way to pass a SurfaceView to android.media.MediaPlayer

I'm writing an app that consumes media (audio/video) and that allows users to reply and/or post new media.
My question relates to the SurfaceView used to display the videos. This SurfaceView object is shared between the MediaRecorder (recording a video) and the MediaPlayer (consuming/playing the video).
The MediaPlayer is located on its own Service, which runs on its own thread, as per the NPR example: PlaybackService.java
Since the NPR example doesn't involve video, I was not sure about how to make the MediaPlayer on the Service aware of the SurfaceView in the UI. I ended up using a static variable to solve this issue:
// MyFragmentClass.java
// CameraPreview is the sample class shown int he media section
// of the Android Developer site:
// http://developer.android.com/guide/topics/media/camera.html#camera-preview
private static CameraPreview sCameraPreview;
#Override
public void onStart() {
super.onStart();
CameraPreview cameraPreview = new CameraPreview(getActivity());
FrameLayout preview = (FrameLayout) getView().findViewById(R.id.video_preview);
preview.addView(cameraPreview);
setCameraPreview(cameraPreview); // a static setter.
// Other classes are initialized afterwards, not relevant to this question...
}
public static CameraPreview getCameraPreview() {
return sCameraPreview;
}
public static void setCameraPreview(CameraPreview cameraPreview) {
sCameraPreview = cameraPreview;
}
Here's the method on the PlaybackService that takes care of preparing a video for playback:
// Params url and isVideo were extras on an Intent that triggers
// this method
synchronized private void prepareMediaPlayer(String url, boolean isVideo) {
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnErrorListener(this);
mMediaPlayer.setOnInfoListener(this);
mMediaPlayer.setOnPreparedListener(this);
} else {
mMediaPlayer.reset();
}
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(mediaUrl);
if (isVideo) {
// this is the important line
mMediaPlayer.setDisplay(MyFragmentClass.getCameraPreview().getHolder());
mMediaPlayer.setScreenOnWhilePlaying(true);
}
mMediaPlayer.prepareAsync();
sendIntent(STATUS_PLAYBACK_PREPARED);
}
It gets the job done, but I'm wondering if there's any better way to do it, specially because I'm debugging a random bug where the shared surface is not released, and it got me thinking:
Is there a better way to make my service class aware of the Service?
Is it a good approach to have a single SurfaceView for both Recording and Playback?
Thanks!

Google GDK: Differences in calling app with voice trigger or menu affecting camera service?

I'm trying to create a Glass GDK app that uses the Camera service to show a preview. Unfortunately, I currently have a bug where a RuntimeException is thrown when trying to open a Camera using Camera.open(). I only encounter this bug when opening the activity through a voice trigger, not by selecting the app from the "launcher" menu.
Is there a difference in how an Activity is launched through this menu versus the voice trigger?
Some of the relevant code is below.
#Override
public void onCreate(Bundle savedInstanceState) {
mGestureDetector = createGestureDetector(this);
super.onCreate(savedInstanceState);
ctx = this;
act = this;
setContentView(R.layout.activity_main);
preview = new Preview(this, (SurfaceView)findViewById(R.id.surfaceView));
((FrameLayout) findViewById(R.id.preview)).addView(preview);
preview.setKeepScreenOn(true);
}
#Override
protected void onResume() {
super.onResume();
try {
if (camera == null) {
Log.d(TAG, "Opening a camera on resume.");
camera = Camera.open();
preview.setCamera(camera);
camera.startPreview();
}
} catch(java.lang.RuntimeException e) {
Log.e(TAG, e.getMessage());
}
}
#Override
protected void onPause() {
if(camera != null) {
camera.stopPreview();
preview.setCamera(null);
Log.d(TAG, "Releasing a camera on pause.");
camera.release();
camera = null;
}
super.onPause();
}
#Override
protected void onDestroy() {
if(camera != null) {
camera.stopPreview();
preview.setCamera(null);
Log.d(TAG, "Releasing a camera on destory.");
camera.release();
camera = null;
}
super.onDestroy();
}
Since it doesn't work when using the voice trigger, it sounds like a possible race condition where the microphone isn't released by the time your activity is displayed on the screen.
Can you try an approach that uses exponential back-off to capture the camera? Basically try to capture the camera and if you get an exception, try again after a short amount of time, increasing the wait time slightly for a fixed number of attempts.
Please also consider filing a bug on the issue tracker, especially if you can reliably find out how much of a delay is needed before the camera/mic can be acquired.
The problem is caused by the delay between the voice recogniser closing event and the camera open event, which is causing a memory overload.
To avoid the problem when launching the app which will be triggered with voice,
pause the app for certain time (1000 Milli seconds will do) from opening the camera soon.
In the below code I am delaying my QR scanner to open from opening for 1000 Milli seconds. This works fine for me. If you want a you can increase the time interval.
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
intent = new Intent("com.google.zxing.client.android.SCAN");
startActivityForResult(intent, 0);
}
};
// sleeper time
handler.sendEmptyMessageDelayed(0, 1000);

Categories

Resources