/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.exovlc.demo; import java.util.Properties; import org.videolan.libvlc.LibVLC; import org.videolan.libvlc.LibVlcUtil; import android.app.Activity; import android.content.Context; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.ViewGroup.LayoutParams; import com.exovlc.ExoVlcUtil; import com.exovlc.VLCAudioTrackRenderer; import com.exovlc.VLCSampleExtractor; import com.exovlc.VLCSampleSource; import com.exovlc.VLCVideoSurfaceHandler; import com.exovlc.VLCVideoTrackRenderer; import com.google.android.exoplayer.ExoPlaybackException; import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.demo.player.DemoPlayer; import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilder; import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallback; /** * A {@link RendererBuilder} for VLC implementation */ public class VLCRendererBuilder implements RendererBuilder { public static final String SURFACE_VIEW_RES_ID_PROP = "surface.resource.id"; private final Context context; private final String uri; private final LibVLC vlc; private final Properties props; public VLCRendererBuilder(Context context, Uri uri) throws ExoPlaybackException { this(context, uri, null); } public VLCRendererBuilder(Context context, Uri uri, Properties props) throws ExoPlaybackException { this.context = context; this.uri = LibVLC.PathToURI(uri.toString()); this.vlc = ExoVlcUtil.getVLC(context); this.props = props; } @Override public void buildRenderers(DemoPlayer player, RendererBuilderCallback callback) { TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT]; try { VLCSampleExtractor extractor = new VLCSampleExtractor(vlc, uri); VLCSampleSource vlcsource = new VLCSampleSource(extractor); MySurfaceLayoutHandler msh = null; System.out.println("VLCRendererBuilder.buildRenderers() props = "+props); Object v = props.get(SURFACE_VIEW_RES_ID_PROP); if (v instanceof Integer) msh = new MySurfaceLayoutHandler(this.context, ((Integer) v).intValue()); if (msh == null) callback.onRenderersError(new ExoPlaybackException("property " + SURFACE_VIEW_RES_ID_PROP + " not set")); VLCVideoSurfaceHandler ivdoplayer = new VLCVideoSurfaceHandler( extractor.getLibVLC(), player.getMainHandler(), player, msh); renderers[DemoPlayer.TYPE_VIDEO] = new VLCVideoTrackRenderer(vlcsource, player.getMainHandler(), player, ivdoplayer, extractor.getLibVLC()); renderers[DemoPlayer.TYPE_AUDIO] = new VLCAudioTrackRenderer(vlcsource, player.getMainHandler(), player, extractor.getLibVLC()); } catch (ExoPlaybackException e) { e.printStackTrace(); } callback.onRenderers(null, null, renderers); } static class MySurfaceLayoutHandler implements com.exovlc.VLCVideoSurfaceHandler.SurfaceLayoutHandler { private final Context activityCtx; private SurfaceView view; private int mCurrentSize = SURFACE_BEST_FIT; private int pw, ph; private Surface mSurface; MySurfaceLayoutHandler(Context context, int sv_id) throws ExoPlaybackException { super(); this.activityCtx = context; try { view = (SurfaceView) ((Activity) activityCtx).findViewById(sv_id);// R.id.surface_view); } catch (Exception e) { e.printStackTrace(); throw new ExoPlaybackException(e); } pw = ((Activity) activityCtx).getWindow().getDecorView().getWidth(); ph = ((Activity) activityCtx).getWindow().getDecorView().getHeight(); } @Override public int getPreferedSurfaceHeight() { return ph; } @Override public int getPreferedSurfaceWidth() { return pw; } @Override public int getSurfaceFit() { return mCurrentSize; } @Override public void setNewSurface(Surface surface) { mSurface = surface; } @Override public void setSurfaceLayout(int width, int height) { LayoutParams lp = view.getLayoutParams(); lp.width = width; lp.height = height; view.setLayoutParams(lp); view.invalidate(); } private static class ConfigureSurfaceHolder { private final Surface surface; private boolean configured; private ConfigureSurfaceHolder(Surface surface) { this.surface = surface; } } @Override public SurfaceHolder getHolder() { return view.getHolder(); } @Override public int configureSurface(Surface surface, final int width, final int height, final int hal) { if (LibVlcUtil.isICSOrLater() || surface == null) return -1; if (width * height == 0) return 0; ExoVlcUtil.log(this, "configureSurface: " + width + "x" + height); final ConfigureSurfaceHolder holder = new ConfigureSurfaceHolder(surface); final Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { if (mSurface == holder.surface) { if (hal != 0) view.getHolder().setFormat(hal); view.getHolder().setFixedSize(width, height); } synchronized (holder) { holder.configured = true; holder.notifyAll(); } } }); try { synchronized (holder) { while (!holder.configured) holder.wait(); } } catch (InterruptedException e) { return 0; } return 1; } } }