public void setDataSource(MediaSource source, int videoTrackIndex, int audioTrackIndex)
            throws IOException, IllegalStateException {
        if(mCurrentState != State.IDLE) {
            throw new IllegalStateException();
        }

        releaseMediaExtractors();

        mVideoExtractor = source.getVideoExtractor();
        mAudioExtractor = source.getAudioExtractor();

        if(mVideoExtractor != null && mAudioExtractor == null) {
            mAudioExtractor = mVideoExtractor;
        }

        switch (videoTrackIndex) {
            case TRACK_INDEX_AUTO:
                mVideoTrackIndex = getTrackIndex(mVideoExtractor, "video/");
                break;
            case TRACK_INDEX_NONE:
                mVideoTrackIndex = MediaCodecDecoder.INDEX_NONE;
                break;
            default:
                mVideoTrackIndex = videoTrackIndex;
        }

        switch (audioTrackIndex) {
            case TRACK_INDEX_AUTO:
                mAudioTrackIndex = getTrackIndex(mAudioExtractor, "audio/");
                break;
            case TRACK_INDEX_NONE:
                mAudioTrackIndex = MediaCodecDecoder.INDEX_NONE;
                break;
            default:
                mAudioTrackIndex = audioTrackIndex;
        }

        // Select video track
        if(mVideoTrackIndex != MediaCodecDecoder.INDEX_NONE) {
            mVideoExtractor.selectTrack(mVideoTrackIndex);
            mVideoFormat = mVideoExtractor.getTrackFormat(mVideoTrackIndex);
            mVideoMinPTS = mVideoExtractor.getSampleTime();
            Log.d(TAG, "selected video track #" + mVideoTrackIndex + " " + mVideoFormat.toString());
        }

        // Select audio track
        if(mAudioTrackIndex != MediaCodecDecoder.INDEX_NONE) {
            mAudioExtractor.selectTrack(mAudioTrackIndex);
            mAudioFormat = mAudioExtractor.getTrackFormat(mAudioTrackIndex);
            mAudioMinPTS = mAudioExtractor.getSampleTime();
            Log.d(TAG, "selected audio track #" + mAudioTrackIndex + " " + mAudioFormat.toString());
        }

        if(mVideoTrackIndex == MediaCodecDecoder.INDEX_NONE) {
            mVideoExtractor = null;
        }

        if(mVideoTrackIndex == MediaCodecDecoder.INDEX_NONE && mAudioTrackIndex == MediaCodecDecoder.INDEX_NONE) {
            throw new IOException("invalid data source, no supported stream found");
        }
        if(mVideoTrackIndex != MediaCodecDecoder.INDEX_NONE && mPlaybackThread == null && mSurface == null) {
            Log.i(TAG, "no video output surface specified");
        }

        mCurrentState = State.INITIALIZED;
    }
Sets the media source and track indices. The track indices can either be actual track indices
that have been determined externally, {@link #TRACK_INDEX_AUTO} to automatically select
the first fitting track index, or {@link #TRACK_INDEX_NONE} to not select any track.

@param source the media source
@param videoTrackIndex a video track index or one of the TRACK_INDEX_* constants
@param audioTrackIndex an audio track index or one of the TRACK_INDEX_* constants
@throws IOException
@throws IllegalStateException
MediaPlayer/src/main/java/net/protyposis/android/mediaplayer/MediaPlayer.java