Page 1 of 1

Render directly on a SurfaceTexture, nothing happens

Posted: 18 Mar 2016 12:48
by malcalde
Hi All.

In our project we are using android MediaPlayer to decode mp4 to a Open GL texture (handled in JNI part) to render dynamic sky domes. We want to replace it with libvlc and extend support to -+.avi mpeg-dash,....

We clone class to change Android MediaPlayer to VLC, code compile and libVLC is initialised OK. But nothing happen in screen, not events are received, not traces in logcat ... Seems as internally not there are any thread working.

Summarizing our code

1 - Setup libVLC

Code: Select all

ArrayList<String> options = new ArrayList<String>(); libVLC = new LibVLC(options); options.add("-vvv"); // verbosity libVLC.setOnNativeCrashListener(this); mediaPlayer = new MediaPlayer(libVLC); mediaPlayer.setEventListener(this);
2 - Load movie

Code: Select all

if (mediaPath.startsWith("http")) { media = new Media(libVLC, mediaUri); this.isLoaded = (media.parse(Media.Parse.FetchNetwork) && getMediaInformation()) || (media.parse(Media.Parse.ParseNetwork) && getMediaInformation()); } else if (mediaPath.startsWith("android.resource://")) { media = new Media(libVLC, mediaUri); } else { media = new Media(libVLC, mediaPath); this.isLoaded = (media.parse(Media.Parse.FetchLocal) && getMediaInformation()) || (media.parse(Media.Parse.ParseLocal) && getMediaInformation()); }

3 - Set native texture id to SurfaceTexture

Code: Select all

surfaceTextureID = textureID; surfaceTexture = new SurfaceTexture(surfaceTextureID); surfaceTexture.setOnFrameAvailableListener(this); surface = new Surface(surfaceTexture); surfaceHolder = new SurfaceHolder() { @Override public void addCallback(Callback callback) { Log.d("[VLCVideoPlayer]","[SurfaceHolder::addCallback] Entering method"); synchronized (surfaceholder_callbacks) { if (surfaceholder_callbacks.contains(callback) == false) { surfaceholder_callbacks.add(callback); } } } @Override public void removeCallback(Callback callback) { Log.d("[VLCVideoPlayer]","[SurfaceHolder::removeCallback] Entering method"); synchronized (surfaceholder_callbacks) { surfaceholder_callbacks.remove(callback); } } @Override public Surface getSurface() { Log.d("[VLCVideoPlayer]","[SurfaceHolder::getSurface] Entering method"); return surface; } @Override public Rect getSurfaceFrame() { Log.d("[VLCVideoPlayer]","[SurfaceHolder::getSurfaceFrame] Entering method"); surfaceholder_frame.top = 0; surfaceholder_frame.bottom = 0; surfaceholder_frame.right = width; surfaceholder_frame.bottom = height; return surfaceholder_frame; } @Override public boolean isCreating() { Log.d("[VLCVideoPlayer]","[SurfaceHolder::isCreating] Entering method"); return surfaceholder_isCreating; } @Override public void setFixedSize(int width, int height) { Log.d("[VLCVideoPlayer]","[SurfaceHolder::setFixedSize] Entering method"); surfaceholder_width = width; surfaceholder_height = height; } @Override public void setFormat(int format) { Log.d("[VLCVideoPlayer]","[SurfaceHolder::setFormat] Entering method"); surfaceholder_format = (format == PixelFormat.OPAQUE)? PixelFormat.RGB_565: format; } @Override public void setKeepScreenOn(boolean screenOn) { Log.d("[VLCVideoPlayer]","[SurfaceHolder::setKeepScreenOn] Entering method"); } @Override public void setSizeFromLayout() { Log.d("[VLCVideoPlayer]","[SurfaceHolder::setSizeFromLayout] Entering method"); surfaceholder_width = 0; surfaceholder_height = 0; } @Override public void setType(int type) { Log.d("[VLCVideoPlayer]","[SurfaceHolder::setType] Entering method"); } @Override public Canvas lockCanvas() { Log.d("[VLCVideoPlayer]","[SurfaceHolder::lockCanvas] Entering method"); return lockCanvas(null); } @Override public Canvas lockCanvas(Rect dirty) { Log.d("[VLCVideoPlayer]","[SurfaceHolder::lockCanvas] Entering method"); surfaceholder_lock.lock(); { Canvas canvas = null; try { canvas = surface.lockCanvas(dirty); } catch(Exception ex) { Log.e("[VLCVideoPlayer]","[SurfaceHolder::lockCanvas] Exception locking canvas-surface", ex); } if (null != canvas) { surfaceholder_lastLockTime = SystemClock.uptimeMillis(); return canvas; } long surfaceholder_now = SystemClock.uptimeMillis(); long surfaceholder_next= surfaceholder_lastLockTime + 100; if (surfaceholder_next > surfaceholder_now) { try { Thread.sleep(surfaceholder_next - surfaceholder_now); } catch (InterruptedException ex) { Log.e("[VLCVideoPlayer]","[SurfaceHolder::lockCanvas] Exception setting thread sleep delay", ex); } surfaceholder_now = SystemClock.uptimeMillis(); } surfaceholder_lastLockTime = surfaceholder_now; } surfaceholder_lock.unlock(); return null; } @Override public void unlockCanvasAndPost(Canvas canvas) { Log.d("[VLCVideoPlayer]","[SurfaceHolder::unlockCanvasAndPost] Entering method"); surface.unlockCanvasAndPost(canvas); surfaceholder_lock.unlock(); } }; final IVLCVout outVLC = mediaPlayer.getVLCVout(); outVLC.addCallback(this); outVLC.setVideoSurface(surface, surfaceHolder); outVLC.attachViews();
4- Update texture in render loop

Code: Select all

synchronized(this) { if(isFrameNew) { if(surfaceTexture != null) surfaceTexture.updateTexImage(); isFrameNew = false; isMoviedone = false; return true; } return false; }
Anybody has any idea to found and fix this issue?

Re: Render directly on a SurfaceTexture, nothing happens

Posted: 28 Jun 2016 09:53
by Jean-Baptiste Kempf
Look at the samples.