public void setDataSource(MediaSource source) throws IOException { mVideoExtractor = source.getVideoExtractor(); mAudioExtractor = source.getAudioExtractor(); mVideoTrackIndex = -1; mAudioTrackIndex = -1; for (int i = 0; i < mVideoExtractor.getTrackCount(); ++i) { MediaFormat format = mVideoExtractor.getTrackFormat(i); Log.d(TAG, format.toString()); String mime = format.getString(MediaFormat.KEY_MIME); if (mVideoTrackIndex < 0 && mime.startsWith("video/")) { mVideoExtractor.selectTrack(i); mVideoTrackIndex = i; mVideoFormat = format; mVideoMinPTS = mVideoExtractor.getSampleTime(); } else if (mAudioExtractor == null && mAudioTrackIndex < 0 && mime.startsWith("audio/")) { mVideoExtractor.selectTrack(i); mAudioTrackIndex = i; mAudioFormat = format; mAudioMinPTS = mVideoExtractor.getSampleTime(); } } if (mAudioExtractor != null) { for (int i = 0; i < mAudioExtractor.getTrackCount(); ++i) { MediaFormat format = mAudioExtractor.getTrackFormat(i); Log.d(TAG, format.toString()); String mime = format.getString(MediaFormat.KEY_MIME); if (mAudioTrackIndex < 0 && mime.startsWith("audio/")) { mAudioExtractor.selectTrack(i); mAudioTrackIndex = i; mAudioFormat = format; mAudioMinPTS = mAudioExtractor.getSampleTime(); } } } if (mVideoFormat == null) { throw new IOException("no video track found"); } else { if (mAudioFormat == null) { Log.i(TAG, "no audio track found"); } if (mPlaybackThread == null) { if (mSurface == null) { Log.i(TAG, "no video output surface specified"); } mPlaybackThread = new PlaybackThread(); mPlaybackThread.start(); } } }
// Dequeue and return an output buffer index, -1 if no output // buffer available or -2 if error happened. private DecoderOutputBufferInfo dequeueOutputBuffer(int dequeueTimeoutUs) { checkOnMediaCodecThread(); try { MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); int result = mediaCodec.dequeueOutputBuffer(info, dequeueTimeoutUs); while (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED || result == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { if (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { outputBuffers = mediaCodec.getOutputBuffers(); Logging.d(TAG, "Decoder output buffers changed: " + outputBuffers.length); } else if (result == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { MediaFormat format = mediaCodec.getOutputFormat(); Logging.d(TAG, "Decoder format changed: " + format.toString()); width = format.getInteger(MediaFormat.KEY_WIDTH); height = format.getInteger(MediaFormat.KEY_HEIGHT); if (!useSurface && format.containsKey(MediaFormat.KEY_COLOR_FORMAT)) { colorFormat = format.getInteger(MediaFormat.KEY_COLOR_FORMAT); Logging.d(TAG, "Color: 0x" + Integer.toHexString(colorFormat)); // Check if new color space is supported. boolean validColorFormat = false; for (int supportedColorFormat : supportedColorList) { if (colorFormat == supportedColorFormat) { validColorFormat = true; break; } } if (!validColorFormat) { Logging.e(TAG, "Non supported color format"); return new DecoderOutputBufferInfo(-1, 0, 0, -1); } } if (format.containsKey("stride")) { stride = format.getInteger("stride"); } if (format.containsKey("slice-height")) { sliceHeight = format.getInteger("slice-height"); } Logging.d(TAG, "Frame stride and slice height: " + stride + " x " + sliceHeight); stride = Math.max(width, stride); sliceHeight = Math.max(height, sliceHeight); } result = mediaCodec.dequeueOutputBuffer(info, dequeueTimeoutUs); } if (result >= 0) { return new DecoderOutputBufferInfo(result, info.offset, info.size, info.presentationTimeUs); } return null; } catch (IllegalStateException e) { Logging.e(TAG, "dequeueOutputBuffer failed", e); return new DecoderOutputBufferInfo(-1, 0, 0, -1); } }