lock canvas fail when using MediaPlayer with Surfaceview
<p>Looking for help cause i'm stuck for a few days already with this problem and have no ideas how to solve it! I'm using extended Surfaceview defined in the code to play video mp4 file from the sd card and after the playback i want to draw bitmap on top of the MediaPlayer. I was able to play video without any problem but when i'm calling  </p>

<p><code>c = this.surfaceHolder.lockCanvas();</code></p>

<p>I'm getting Force Close with follwoing error:</p>

<p><code>E/Surface (  665): surface (identity=44) is invalid, err=-19 (No such device)
D/CallStack(  665): Surface#00  pc 00013d08  /system/lib/libsurfaceflinger_clien
t.so
D/CallStack(  665): Surface#01  pc 000140d2  /system/lib/libsurfaceflinger_clien
t.so
D/CallStack(  665): Surface#02  pc 000142d0  /system/lib/libsurfaceflinger_clien
t.so
D/CallStack(  665): Surface#03  pc 00043bb6  /system/lib/libandroid_runtime.so
E/Surface (  665): dequeueBuffer failed (No such device)
E/SurfaceHolder(  665): Exception locking surface</code></p>

<p>More details:</p>

<p>This is my extended Surface class:</p>

<pre><code>public class MainMenu extends SurfaceView implements   
SurfaceHolder.Callback {

    private static final String TAG = MainMenu.class.getSimpleName();
    private MainThread thread;    
    private VideoPlayer videPlayer;



    public MainMenu(Context context) {
        super(context);
        // TODO Auto-generated constructor stub

        getHolder().addCallback(this);

        Log.d(TAG,"Context menu called---" );

        setFocusable(true);

        Log.d(TAG,"Context menu end call---" );
    }




    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // TODO Auto-generated method stub
        Log.d(TAG, "surfaceChanged called"+holder);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        Log.d(TAG, "surfaceCreated called"+holder);

        if (holder == null){
            Log.d(TAG, "surfaceCreated called holder is null="+holder);
        }
        videPlayer = new VideoPlayer(getHolder(),this);
        videPlayer.VideoPlayerF();          
    }



    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        Log.d(TAG,"Surface is being destroyed");

        boolean retry = true;
        while (retry) {
            try {
                thread.join();
                retry = false;

            } catch (InterruptedException e) {
                // try again shutting down the thread
            }
        }
        Log.d(TAG, "Thread was shut down cleanly");

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // delegating event handling to the droid


            // check if in the lower part of the screen we exit
            if (event.getY() &gt; getHeight() - 50) {
                thread.setRunning(false);
                ((Activity)getContext()).finish();
            } else {
                Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());
            }
        } if (event.getAction() == MotionEvent.ACTION_MOVE) {
            // the gestures
            if (button_left.isTouched()) {
                // the droid was picked up and is being dragged

            }
        } if (event.getAction() == MotionEvent.ACTION_UP) {
            // touch was released

        }
        return true;
    }

    public void render(Canvas canvas){
        canvas.drawColor(Color.WHITE);
        //Will draw something here

        }

}
</code></pre>

<p>Second class, VidePlayer.</p>

<pre><code>public class VideoPlayer implements OnErrorListener,OnBufferingUpdateListener, OnCompletionListener,
MediaPlayer.OnPreparedListener, OnVideoSizeChangedListener {

    private static final String TAG = MainMenu.class.getSimpleName();

    public MediaPlayer mp;  
    public MainMenu mainMenu;
    private SurfaceHolder surfaceHolder;
    private Surface surface;


public VideoPlayer(SurfaceHolder surfaceHolder, MainMenu mainMenu) {

    Log.d(TAG, "VideoPlayer called ");
    this.surfaceHolder = surfaceHolder;
    this.mainMenu=mainMenu;

        Log.d(TAG, "VideoPlayer MediaPlayer created ");
    Log.d(TAG, "VideoPlayer MediaPlayer created Surface name" + this.surfaceHolder.getSurface());

}
public void VideoPlayerF(){

    Log.d(TAG, "VideoPlayer  VideoPlayerF called "+this.surfaceHolder);
    if (this.surfaceHolder == null){
        Log.d(TAG, "VideoPlayer  VideoPlayerF holder is null"+surfaceHolder);
    }

    try {

        String path = "/sdcard/video/sample.mp4";
        Log.d(TAG, "path: " + path);      
        mp = new MediaPlayer();
        mp.setDataSource(path);
        mp.setDisplay(this.surfaceHolder);
        mp.prepare();  
        mp.setOnErrorListener(this);
        mp.setOnBufferingUpdateListener(this);
        mp.setOnCompletionListener(this);
        mp.setOnPreparedListener(this);
        mp.setOnVideoSizeChangedListener(this);
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);


    } catch (Exception e) {

        Log.e(TAG, "error: " + e.getMessage(), e);

    }
}
public void onPrepared(MediaPlayer mp) {
    // TODO Auto-generated method stub
    Log.d(TAG, "onPrepared called");
    startVideoPlayback();   
}




@Override
public void onCompletion(MediaPlayer mp) {
    // TODO Auto-generated method stub
    Log.d(TAG, "onCompletion called Surface size" + this.surfaceHolder.getSurfaceFrame());

    if (mp != null) {   
        mp.stop();
        mp.reset();
        mp.release();
        mp=null;
        callthread();
        Log.d(TAG, "onCompletion called mp released");
        Log.d(TAG, "Prepared to send surface " + this.surfaceHolder);
        Log.d(TAG, "Prepared surface " + this.surfaceHolder.getSurface());        
    }

    return;
}




@Override
public void onBufferingUpdate(MediaPlayer arg0, int percent) {
    // TODO Auto-generated method stub
    Log.d(TAG, "onBufferingUpdate called ---&gt;   percent:" + percent);

}

public void callthread(){
    /*
     * 
     * Will start drawing here
     */


    surface=this.surfaceHolder.getSurface();
    Canvas c = new Canvas();

    if (surface.isValid()){
        Log.d(TAG, "callthread called ---&gt;   surface.isValid" + surface.isValid());
        c = this.surfaceHolder.lockCanvas();
    }else{
        Log.d(TAG, "callthread called else ---&gt;   surface.isValid" + surface.isValid());
    }

    this.mainMenu.render(c);


}


@Override
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
    Log.e(TAG, "onError---&gt;   what:" + what + "    extra:" + extra);        
            if (mediaPlayer != null) {  

                Log.e(TAG, "onError mediaPlayer != null ");

            }
            return false;
}

private void startVideoPlayback() {
    Log.v(TAG, "startVideoPlayback");
    Log.v(TAG, "Video Sizw "+  mp.getVideoHeight() +   mp.getVideoWidth());
    mp.start();

}
@Override
public void onVideoSizeChanged(MediaPlayer mp, int arg1, int arg2) {
    // TODO Auto-generated method stub
    this.surfaceHolder.setFixedSize(arg1, arg2);
    Log.d(TAG, "VideoPlayer  onVideoSizeChanged called"+arg1 + arg2);

}
}
</code></pre>

<p>This is logcat</p>

<pre><code>D/dalvikvm(  657): Debugger has detached; object registry had 1 entries
D/ling    (  665): View added==dspSizeHeight===752and dsp size 1280
D/MainMenu(  665): Context menu called---
D/MainMenu(  665): Context menu end call---
D/ling    (  665): View added
D/MainMenu(  665): surfaceCreated calledandroid.view.SurfaceView$4@40646ec8
D/MainMenu(  665): VideoPlayer called
D/MainMenu(  665): VideoPlayer MediaPlayer created
D/MainMenu(  665): VideoPlayer MediaPlayer created Surface nameSurface(name=null
, identity=44)
D/MainMenu(  665): VideoPlayer  VideoPlayerF called android.view.SurfaceView$4@4
0646ec8
D/MainMenu(  665): path: /sdcard/video/sample.mp4
I/AwesomePlayer(   34): reset
I/AwesomePlayer(   34): cancel player events
I/AwesomePlayer(   34): cancel player events
I/AwesomePlayer(   34): setDataSource_l('/sdcard/video/sample.mp4')
D/MainMenu(  665): VideoPlayer  VideoPlayerF called this.surfaceHolder=android.v
iew.SurfaceView$4@40646ec8
D/MainMenu(  665): surfaceChanged calledandroid.view.SurfaceView$4@40646ec8
I/ActivityManager(   82): Displayed com.clapp.ling/.ling: +3s729ms
D/MainMenu(  665): VideoPlayer  onVideoSizeChanged called190240
D/MainMenu(  665): onPrepared called
V/MainMenu(  665): startVideoPlayback
V/MainMenu(  665): Video Sizw 240190
D/AudioSink(   34): bufferCount (4) is too small and increased to 12
D/MainMenu(  665): surfaceChanged calledandroid.view.SurfaceView$4@40646ec8
W/AudioFlinger(   34): write blocked for 128 msecs, 34 delayed writes, thread 0x
10108
D/MainMenu(  665): VideoPlayer  onVideoSizeChanged called190240
I/AwesomePlayer(   34): we're much too late (0.85 secs), video skipping ahead
D/dalvikvm(  155): GC_EXPLICIT freed 504K, 20% free 12897K/16007K, paused 13ms+1
1ms
I/AwesomePlayer(   34): we're much too late (0.55 secs), video skipping ahead
I/AwesomePlayer(   34): we're much too late (0.50 secs), video skipping ahead
W/AudioFlinger(   34): write blocked for 94 msecs, 42 delayed writes, thread 0x1
0108
D/MainMenu(  665): onCompletion called Surface sizeRect(0, 0 - 1280, 752)
I/AwesomePlayer(   34): reset
I/AwesomePlayer(   34): cancel player events
I/AwesomePlayer(   34): video decoder shutdown completed
D/MainMenu(  665): callthread() lockCanvas
D/MainMenu(  665): callthread called ---&gt;   surface.isValidtrue
E/Surface (  665): surface (identity=44) is invalid, err=-19 (No such device)
D/CallStack(  665): Surface#00  pc 00013d08  /system/lib/libsurfaceflinger_clien
t.so
D/CallStack(  665): Surface#01  pc 000140d2  /system/lib/libsurfaceflinger_clien
t.so
D/CallStack(  665): Surface#02  pc 000142d0  /system/lib/libsurfaceflinger_clien
t.so
D/CallStack(  665): Surface#03  pc 00043bb6  /system/lib/libandroid_runtime.so
E/Surface (  665): dequeueBuffer failed (No such device)
E/SurfaceHolder(  665): Exception locking surface
E/SurfaceHolder(  665): java.lang.IllegalArgumentException
E/SurfaceHolder(  665):         at android.view.Surface.lockCanvasNative(Native
Method)
E/SurfaceHolder(  665):         at android.view.Surface.lockCanvas(Surface.java:
350)
E/SurfaceHolder(  665):         at android.view.SurfaceView$4.internalLockCanvas
(SurfaceView.java:772)
E/SurfaceHolder(  665):         at android.view.SurfaceView$4.lockCanvas(Surface
View.java:748)
E/SurfaceHolder(  665):         at com.clapp.ling.VideoPlayer.callthread(VideoPl
ayer.java:157)
E/SurfaceHolder(  665):         at com.clapp.ling.VideoPlayer.onCompletion(Video
Player.java:122)
E/SurfaceHolder(  665):         at android.media.MediaPlayer$EventHandler.handle
Message(MediaPlayer.java:1325)
E/SurfaceHolder(  665):         at android.os.Handler.dispatchMessage(Handler.ja
va:99)
E/SurfaceHolder(  665):         at android.os.Looper.loop(Looper.java:132)
E/SurfaceHolder(  665):         at android.app.ActivityThread.main(ActivityThrea
d.java:4123)
E/SurfaceHolder(  665):         at java.lang.reflect.Method.invokeNative(Native
Method)
E/SurfaceHolder(  665):         at java.lang.reflect.Method.invoke(Method.java:4
91)
E/SurfaceHolder(  665):         at com.android.internal.os.ZygoteInit$MethodAndA
rgsCaller.run(ZygoteInit.java:841)
E/SurfaceHolder(  665):         at com.android.internal.os.ZygoteInit.main(Zygot
eInit.java:599)
E/SurfaceHolder(  665):         at dalvik.system.NativeStart.main(Native Method)

D/AndroidRuntime(  665): Shutting down VM
W/dalvikvm(  665): threadid=1: thread exiting with uncaught exception (group=0x4
0014760)
E/AndroidRuntime(  665): FATAL EXCEPTION: main
E/AndroidRuntime(  665): java.lang.NullPointerException
E/AndroidRuntime(  665):        at com.clapp.ling.MainMenu.render(MainMenu.java:
201)
E/AndroidRuntime(  665):        at com.clapp.ling.VideoPlayer.callthread(VideoPl
ayer.java:162)
E/AndroidRuntime(  665):        at com.clapp.ling.VideoPlayer.onCompletion(Video
Player.java:122)
E/AndroidRuntime(  665):        at android.media.MediaPlayer$EventHandler.handle
Message(MediaPlayer.java:1325)
E/AndroidRuntime(  665):        at android.os.Handler.dispatchMessage(Handler.ja
va:99)
E/AndroidRuntime(  665):        at android.os.Looper.loop(Looper.java:132)
E/AndroidRuntime(  665):        at android.app.ActivityThread.main(ActivityThrea
d.java:4123)
E/AndroidRuntime(  665):        at java.lang.reflect.Method.invokeNative(Native
Method)
E/AndroidRuntime(  665):        at java.lang.reflect.Method.invoke(Method.java:4
91)
E/AndroidRuntime(  665):        at com.android.internal.os.ZygoteInit$MethodAndA
rgsCaller.run(ZygoteInit.java:841)
E/AndroidRuntime(  665):        at com.android.internal.os.ZygoteInit.main(Zygot
eInit.java:599)
E/AndroidRuntime(  665):        at dalvik.system.NativeStart.main(Native Method)

I/AwesomePlayer(   34): reset
I/AwesomePlayer(   34): cancel player events
I/AwesomePlayer(   34): reset
I/AwesomePlayer(   34): cancel player events
I/AwesomePlayer(   34): reset
I/AwesomePlayer(   34): cancel player events
W/ActivityManager(   82):   Force finishing activity com.clapp.ling/.ling
W/WindowManager(   82): Failure taking screenshot for (230x135) to layer 21015
W/ActivityManager(   82): Activity pause timeout for ActivityRecord{407d3060 com
.clapp.ling/.ling}
I/dalvikvm(  155): Jit: resizing JitTable from 512 to 1024
I/Process (  665): Sending signal. PID: 665 SIG: 9
I/ActivityManager(   82): Process com.clapp.ling (pid 665) has died.
E/InputDispatcher(   82): channel '40893f68 com.clapp.ling/com.clapp.ling.ling (
server)' ~ Consumer closed input channel or an error occurred.  events=0x8
E/InputDispatcher(   82): channel '40893f68 com.clapp.ling/com.clapp.ling.ling (
server)' ~ Channel is unrecoverably broken and will be disposed!
D/dalvikvm(  155): GC_CONCURRENT freed 1449K, 17% free 13383K/16007K, paused 6ms
+44ms
I/WindowManager(   82): WIN DEATH: Window{40893f68 com.clapp.ling/com.clapp.ling
.ling paused=false}
I/WindowManager(   82): WIN DEATH: Window{40c132e0 SurfaceView paused=false}
I/WindowManager(   82): WINDOW DIED Window{40893f68 com.clapp.ling/com.clapp.lin
g.ling paused=false}
W/InputManagerService(   82): Got RemoteException sending setActive(false) notif
ication to pid 665 uid 10036
D/dalvikvm(  262): GC_EXPLICIT freed 8K, 5% free 6300K/6595K, paused 7ms+7ms
D/dalvikvm(  333): GC_EXPLICIT freed 17K, 6% free 6381K/6727K, paused 7ms+10ms
D/SntpClient(   82): request time failed: java.net.SocketException: Address fami
ly not supported by protocol
</code></pre>

<p>The question is why i can't lock my canvas for drawing even if it passes the validation check </p>

<pre><code>if (surface.isValid())
</code></pre>

<p>and what should i add or override in the code to lock canvas and draw bitmap.
Your help is appreciated!</p>
