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 < numTracks; ++i) { 3807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Map%lt;String, Object> 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, ...) >= 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