linphone-developers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Linphone-developers] NullPointerException on drawing on org.linphone.me


From: David Lindemann
Subject: [Linphone-developers] NullPointerException on drawing on org.linphone.mediastream.video.display.GL2JNIView
Date: Mon, 8 Sep 2014 14:12:34 -0400

Hello, 

***This issue only happens when I debug my app ****
I am trying to make a custom app using liblinphone sdk. The first steps I am taking are to get a simple video call going. I am however, running into some issues with displaying the video on the GL2JNIView. The main activity does a sip register which is successful. The linphone core object is made available and persisted through a service. The user can then click a button which initiates a call and then switches to VideoActivity. After onResume method of VideoActivity is reached it encounters the following exception. 

java.lang.NullPointerException
at android.opengl.GLSurfaceView.surfaceCreated(GLSurfaceView.java:523)
        at android.view.SurfaceView.updateWindow(SurfaceView.java:569)
at android.view.SurfaceView.access$000(SurfaceView.java:86)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:174)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:680)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1929)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1040)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4498)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:725)
  at android.os.Handler.dispatchMessage(Handler.java:92)
  at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)

The layout is copied from linphone app itself and is as follows:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/video_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <org.linphone.mediastream.video.display.GL2JNIView
        android:id="@+id/videoSurface"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:rotation="0"
        android:visibility="visible" />
<SurfaceView
   android:id="@+id/videoCaptureSurface"
   android:layout_width="120dp"
   android:layout_height="145dp"
   android:layout_alignParentBottom="true"
   android:layout_alignParentRight="true" />

</RelativeLayout>

The manifest has the following permissions:

<uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

   
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="17" />

VideoActivity has the following:

public class VideoActivity extends Activity implements VideoServiceNotifier {
private SurfaceView sView;
 
private SurfaceView captureView;
 
private AndroidVideoWindowImpl aVideoWindowImpl;
//private boolean zoomed = false;
 
private LinphoneCore core;
 
private VideoServiceNotifier notifier;

@SuppressWarnings("unused")
private boolean bound = false;
 

private VideoService service;
 

private ServiceConnection con = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName name, IBinder service2) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
            VideoBinder binder = (VideoBinder) service2;
            service = binder.getService();
            bound = true;
            service.setNotifier(notifier);
            setupCallOnMainThread();
}

@Override
public void onServiceDisconnected(ComponentName name) {
bound = false;
}
};
 

private void setupCallOnMainThread() {
runOnUiThread(new Runnable() {
@Override
public void run() {
setupCall();
}
});
}
 
@SuppressLint("NewApi") @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video);
 
VideoUncaughtExceptionHandler handler = VideoUncaughtExceptionHandler.getInstance(this);
Thread.setDefaultUncaughtExceptionHandler(handler);
 
/*
     * Note that if a stopped service still has ServiceConnection objects 
     * bound to it with the BIND_AUTO_CREATE set, it will not be destroyed 
     * until all of these bindings are removed. See the Service documentation 
     * for more details on a service's lifecycle.
    */
 
 
notifier = this;
Intent intent = new Intent(this, VideoService.class);
this.bindService(intent, con, Context.BIND_AUTO_CREATE);  
}
 
 

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) {
end();
return true;
}
return false;
}
 
public void end() {
core.terminateAllCalls();
service.unregister();
this.unbindService(con);
Intent main = new Intent(this, MainActivity.class);
startActivity(main);
finish();
}

private void setupCall() {
this.core = service.getCore();
sView = (SurfaceView) findViewById(R.id.videoSurface);
captureView = (SurfaceView) findViewById(R.id.videoCaptureSurface);
setRotation();
 
 
aVideoWindowImpl = new AndroidVideoWindowImpl(sView, captureView);
fixZOrder(sView, captureView);
 
 
aVideoWindowImpl.setListener(new AndroidVideoWindowImpl.VideoWindowListener() {
@Override
public void onVideoRenderingSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) {
core.setVideoWindow(vw);
//surface.setRotation(180);
Log.v("Singletons", "Current Stream Rotation is: " + Double.toString(surface.getRotation()));
sView = surface;
setRotation();
}
@Override
public void onVideoRenderingSurfaceDestroyed(AndroidVideoWindowImpl vw) {
if(core != null) {
core.setVideoWindow(null);
}
}
@Override
public void onVideoPreviewSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) {
core.setDeviceRotation(0);
captureView = surface;
vw.update();
//Log.v("Singletons", "Orientation: " + Integer.toString(info.orientation));
Log.v("Singletons", "Current Rotation is: " + Double.toString(captureView.getRotation()));
core.setPreviewWindow(captureView);
setRotation();
}
@Override
public void onVideoPreviewSurfaceDestroyed(AndroidVideoWindowImpl sv) {
core.setPreviewWindow(null);
}
});
aVideoWindowImpl.init();
}

@Override
public void onResume() {
super.onResume();
if (sView != null) {
((GLSurfaceView) sView).onResume();
}
if (aVideoWindowImpl != null) {
synchronized (aVideoWindowImpl) {
core.setVideoWindow(aVideoWindowImpl);
}
}
setContentView(R.layout.video);
sView = (SurfaceView) findViewById(R.id.videoSurface);
captureView = (SurfaceView) findViewById(R.id.videoCaptureSurface);
}
@Override
public void onPause() {
if (this.aVideoWindowImpl != null) {
synchronized (this.aVideoWindowImpl) {
/*
* this call will destroy native opengl renderer which is used by
* androidVideoWindowImpl
*/
core.setVideoWindow(null);
}
}
if (this.sView != null) {
((GLSurfaceView) sView).onPause();
}
super.onPause();
}
 
private void setRotation() {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_0:
rotation = 0;
break;
case Surface.ROTATION_90:
rotation = 90;
break;
case Surface.ROTATION_180:
rotation = 180;
break;
case Surface.ROTATION_270:
rotation = 270;
break;
}
core.setDeviceRotation(rotation);
}
@Override
public void onDestroy() {
sView = null;
captureView = null;
if(aVideoWindowImpl != null) {
aVideoWindowImpl.release();
aVideoWindowImpl = null;
}
super.onDestroy();
}
 
private void fixZOrder(SurfaceView video, SurfaceView preview) {
video.setZOrderOnTop(false);
preview.setZOrderOnTop(true);
preview.setZOrderMediaOverlay(true);
}

@Override
public void onRegister() {
// TODO Auto-generated method stub
}

@Override
public void onUnregister() {
// TODO Auto-generated method stub
}

@Override
public void onCall(LinphoneCore core) {
// TODO Auto-generated method stub
}

@Override
public void onTryingToRegister() {
// TODO Auto-generated method stub
}

}

This has been a real head scratcher, since I do not have access to the part of the code where this is breaking. Any help is greatly appreciated.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]