MediaExtractor.java revision 74a78b0f6e8c07cfc7da8f043987f6de0648bc05
188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber/*
288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Copyright (C) 2012 The Android Open Source Project
388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * you may not use this file except in compliance with the License.
688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * You may obtain a copy of the License at
788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
1088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Unless required by applicable law or agreed to in writing, software
1188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * See the License for the specific language governing permissions and
1488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * limitations under the License.
1588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber */
1688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberpackage android.media;
1888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport android.content.ContentResolver;
2007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport android.content.Context;
2107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport android.content.res.AssetFileDescriptor;
2291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huberimport android.media.MediaCodec;
2307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport android.net.Uri;
2407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport java.io.FileDescriptor;
2507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport java.io.IOException;
2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberimport java.nio.ByteBuffer;
2788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberimport java.util.Map;
2888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber/**
3007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * MediaExtractor facilitates extraction of demuxed, typically encoded,  media data
3107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * from a data source.
3207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * <p>It is generally used like this:
3307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * <pre>
3407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * MediaExtractor extractor = new MediaExtractor();
3507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.setDataSource(...);
3607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * int numTracks = extractor.countTracks();
3707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * for (int i = 0; i &lt; numTracks; ++i) {
3807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *   Map%lt;String, Object&gt; format = extractor.getTrackFormat(i);
3907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *   String mime = (String)format.get("mime");
4007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *   if (weAreInterestedInThisTrack) {
4107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *     extractor.selectTrack(i);
4207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *   }
4307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * }
4407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * ByteBuffer inputBuffer = ByteBuffer.allocate(...)
4507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * while (extractor.readSampleData(inputBuffer, ...) &gt;= 0) {
4607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *   int trackIndex = extractor.getTrackIndex();
4707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *   long presentationTimeUs = extractor.getSampleTime();
4807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *   ...
4907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *   extractor.advance();
5007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * }
5107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *
5207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.release();
5307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor = null;
5407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * </pre>
5588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber*/
568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberfinal public class MediaExtractor {
5707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    public MediaExtractor() {
5807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        native_setup();
5907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
6007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
6107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /**
6207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * Sets the data source as a content Uri.
6307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *
6407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param context the Context to use when resolving the Uri
6507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param uri the Content URI of the data you want to extract from.
6607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param headers the headers to be sent together with the request for the data
6707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     */
6807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    public final void setDataSource(
6907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            Context context, Uri uri, Map<String, String> headers)
7007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        throws IOException {
7107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        String scheme = uri.getScheme();
7207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        if(scheme == null || scheme.equals("file")) {
7307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            setDataSource(uri.getPath());
7407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            return;
7507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        }
7607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
7707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        AssetFileDescriptor fd = null;
7807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        try {
7907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            ContentResolver resolver = context.getContentResolver();
8007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            fd = resolver.openAssetFileDescriptor(uri, "r");
8107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            if (fd == null) {
8207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                return;
8307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            }
8407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            // Note: using getDeclaredLength so that our behavior is the same
8507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            // as previous versions when the content provider is returning
8607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            // a full file.
8707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            if (fd.getDeclaredLength() < 0) {
8807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                setDataSource(fd.getFileDescriptor());
8907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            } else {
9007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                setDataSource(
9107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                        fd.getFileDescriptor(),
9207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                        fd.getStartOffset(),
9307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                        fd.getDeclaredLength());
9407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            }
9507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            return;
9607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        } catch (SecurityException ex) {
9707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        } catch (IOException ex) {
9807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        } finally {
9907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            if (fd != null) {
10007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                fd.close();
10107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            }
10207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        }
10307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
10407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        setDataSource(uri.toString(), headers);
10507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
10607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
10707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /**
10807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * Sets the data source (file-path or http URL) to use.
10907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *
11007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param path the path of the file, or the http URL
11107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param headers the headers associated with the http request for the stream you want to play
11207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     */
11307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    public final void setDataSource(String path, Map<String, String> headers) {
11407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        String[] keys = null;
11507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        String[] values = null;
11607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
11707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        if (headers != null) {
11807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            keys = new String[headers.size()];
11907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            values = new String[headers.size()];
12007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
12107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            int i = 0;
12207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            for (Map.Entry<String, String> entry: headers.entrySet()) {
12307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                keys[i] = entry.getKey();
12407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                values[i] = entry.getValue();
12507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                ++i;
12607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            }
12707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        }
12807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        setDataSource(path, keys, values);
12907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
13007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
13107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    private native final void setDataSource(
13207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            String path, String[] keys, String[] values);
13307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
13407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /**
13507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * Sets the data source (file-path or http URL) to use.
13607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *
13707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param path the path of the file, or the http URL of the stream
13807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *
13907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * <p>When <code>path</code> refers to a local file, the file may actually be opened by a
14007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * process other than the calling application.  This implies that the pathname
14107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * should be an absolute path (as any other process runs with unspecified current working
14207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * directory), and that the pathname should reference a world-readable file.
14307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * As an alternative, the application could first open the file for reading,
14407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
14507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     */
14607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    public final void setDataSource(String path) {
14707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        setDataSource(path, null, null);
14807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
14907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
15007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /**
15107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * Sets the data source (FileDescriptor) to use. It is the caller's responsibility
15207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * to close the file descriptor. It is safe to do so as soon as this call returns.
15307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *
15407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param fd the FileDescriptor for the file you want to extract from.
15507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     */
15607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    public final void setDataSource(FileDescriptor fd) {
15707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        setDataSource(fd, 0, 0x7ffffffffffffffL);
15888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
16007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /**
16107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * Sets the data source (FileDescriptor) to use.  The FileDescriptor must be
16207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility
16307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * to close the file descriptor. It is safe to do so as soon as this call returns.
16407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *
16507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param fd the FileDescriptor for the file you want to extract from.
16607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param offset the offset into the file where the data to be extracted starts, in bytes
16707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     * @param length the length in bytes of the data to be extracted
16807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     */
16907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    public native final void setDataSource(
17007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber            FileDescriptor fd, long offset, long length);
17107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
17288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    @Override
17388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    protected void finalize() {
17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        native_finalize();
17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
17707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Make sure you call this when you're done to free up any resources
17807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  instead of relying on the garbage collector to do this for you at
17907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *   some point in the future.
18007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    */
18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native final void release();
18288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
18307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Count the number of tracks found in the data source.
18407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     */
18588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native int countTracks();
18607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
18707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Get the track format at the specified index.
18807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      * More detail on the representation can be found at {@link android.media.MediaCodec}
18907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    */
19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native Map<String, Object> getTrackFormat(int index);
19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
19207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and
19307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  {@link #getSampleTime} only retrieve information for the subset of tracks
19407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  selected by the call below.
19507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  Selecting the same track multiple times has no effect, the track
19607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  only selected once.
19707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  Media data will be returned in the order of their timestamps.
19807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    */
19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native void selectTrack(int index);
20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
20107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** All selected tracks seek near the requested time. The next sample
20207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  returned for each selected track will be a sync sample.
20307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    */
20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native void seekTo(long timeUs);
20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
20607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Advance to the next sample. Returns false if no more sample data
20707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  is available (end of stream).
20807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     */
20988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native boolean advance();
21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
21107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Retrieve the current encoded sample and store it in the byte buffer
21207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  starting at the given offset. Returns the sample size (or -1 if
21307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  no more samples are available).
21407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    */
21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native int readSampleData(ByteBuffer byteBuf, int offset);
21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
21707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Returns the track index the current sample originates from (or -1
21807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  if no more samples are available)
21907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    */
22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native int getSampleTrackIndex();
22188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
22207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Returns the current sample's presentation time in microseconds.
22307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  or -1 if no more samples are available.
22407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    */
22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    public native long getSampleTime();
22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2279b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    // Keep these in sync with their equivalents in NuMediaExtractor.h
22807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** The sample is a sync sample */
2299b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    public static final int SAMPLE_FLAG_SYNC      = 1;
23007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
23107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** The sample is (at least partially) encrypted, see also the documentation
23207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber     *  for {@link android.media.MediaCodec#queueSecureInputBuffer}
23307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    */
2349b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    public static final int SAMPLE_FLAG_ENCRYPTED = 2;
2359b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
23607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    /** Returns the current sample's flags. */
2379b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber    public native int getSampleFlags();
2389b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber
23991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    /** If the sample flags indicate that the current sample is at least
24091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber     *  partially encrypted, this call returns relevant information about
24191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber     *  the structure of the sample data required for decryption.
24291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber     *  @param info The android.media.MediaCodec.CryptoInfo structure
24391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber     *              to be filled in.
24491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber     *  @return true iff the sample flags contain {@link #SAMPLE_FLAG_ENCRYPTED}
24591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    */
24691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    public native boolean getSampleCryptoInfo(MediaCodec.CryptoInfo info);
24791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
24874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    /** Returns an estimate of how much data is presently cached in memory
24974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        expressed in microseconds. Returns -1 if that information is unavailable
25074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber        or not applicable (no cache).
25174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber     */
25274a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    public native long getCachedDuration();
25374a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
25474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    /** Returns true iff we are caching data and the cache has reached the
25574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber     *  end of the data stream (for now, a future seek may of course restart
25674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber     *  the fetching of data).
25774a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber     *  This API only returns a meaningful result if {link #getCachedDuration}
25874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber     *  indicates the presence of a cache, i.e. does NOT return -1.
25974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    */
26074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber    public native boolean hasCacheReachedEndOfStream();
26174a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber
26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    private static native final void native_init();
26307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    private native final void native_setup();
26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    private native final void native_finalize();
26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    static {
26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        System.loadLibrary("media_jni");
26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        native_init();
26988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
27088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
27188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    private int mNativeContext;
27288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
273