private void initStream() throws IOException, IllegalArgumentException { L.v(TAG, "initStream called in state=" + state); lock.lock(); try { extractor = new MediaExtractor(); if (path != null) { extractor.setDataSource(path); } else { error("initStream"); throw new IOException(); } int trackNum = 0; final MediaFormat oFormat = extractor.getTrackFormat(trackNum); if (!oFormat.containsKey(MediaFormat.KEY_SAMPLE_RATE)) { error("initStream"); throw new IOException("No KEY_SAMPLE_RATE"); } int sampleRate = oFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE); if (!oFormat.containsKey(MediaFormat.KEY_CHANNEL_COUNT)) { error("initStream"); throw new IOException("No KEY_CHANNEL_COUNT"); } int channelCount = oFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT); if (!oFormat.containsKey(MediaFormat.KEY_MIME)) { error("initStream"); throw new IOException("No KEY_MIME"); } final String mime = oFormat.getString(MediaFormat.KEY_MIME); if (!oFormat.containsKey(MediaFormat.KEY_DURATION)) { error("initStream"); throw new IOException("No KEY_DURATION"); } duration = oFormat.getLong(MediaFormat.KEY_DURATION); L.v(TAG, "Sample rate: " + sampleRate); L.v(TAG, "Mime type: " + mime); initDevice(sampleRate, channelCount); extractor.selectTrack(trackNum); codec = MediaCodec.createDecoderByType(mime); codec.configure(oFormat, null, null, 0); } finally { lock.unlock(); } }
@Override public void prepare() throws IOException { L.v(TAG, "prepare called in state: " + state); switch (state) { case INITIALIZED: case STOPPED: initStream(); state = State.PREPARED; L.d(TAG, "State changed to: " + state); break; default: error("prepare"); } }
@Override public void pause() { L.v(TAG, "pause called"); switch (state) { case PLAYBACK_COMPLETED: state = State.PAUSED; L.d(TAG, "State changed to: " + state); stayAwake(false); break; case STARTED: case PAUSED: track.pause(); state = State.PAUSED; L.d(TAG, "State changed to: " + state); stayAwake(false); break; default: error("pause"); } }
@Override public void reset() { L.v(TAG, "reset called in state: " + state); stayAwake(false); lock.lock(); try { continuing = false; try { if (state != State.PLAYBACK_COMPLETED) { while (isDecoding) { synchronized (decoderLock) { decoderLock.notify(); decoderLock.wait(); } } } } catch (InterruptedException e) { L.e(TAG, "Interrupted in reset while waiting for decoder thread to stop.", e); } if (codec != null) { codec.release(); L.d(TAG, "releasing codec"); codec = null; } if (extractor != null) { extractor.release(); extractor = null; } if (track != null) { track.release(); track = null; } state = State.IDLE; L.d(TAG, "State changed to: " + state); } finally { lock.unlock(); } }
@Override public void start() { L.v(TAG, "start called in state:" + state); switch (state) { case PLAYBACK_COMPLETED: try { initStream(); } catch (IOException e) { e.printStackTrace(); error("start"); break; } case PREPARED: state = State.STARTED; L.d(TAG, "State changed to: " + state); continuing = true; track.play(); decode(); stayAwake(true); break; case STARTED: break; case PAUSED: state = State.STARTED; L.d(TAG, "State changed to: " + state + " with path=" + path); synchronized (decoderLock) { decoderLock.notify(); } track.play(); stayAwake(true); break; default: error("start"); break; } }