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; 2360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberimport android.media.MediaFormat; 2407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport android.net.Uri; 25c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen 2607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport java.io.FileDescriptor; 2707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberimport java.io.IOException; 2888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberimport java.nio.ByteBuffer; 2988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberimport java.util.Map; 3088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber/** 3207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * MediaExtractor facilitates extraction of demuxed, typically encoded, media data 3307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * from a data source. 3407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * <p>It is generally used like this: 3507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * <pre> 3607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * MediaExtractor extractor = new MediaExtractor(); 3707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.setDataSource(...); 3860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * int numTracks = extractor.getTrackCount(); 3907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * for (int i = 0; i < numTracks; ++i) { 402ac3f2e285159300c62c797bb2123604773ccac7Andreas Huber * MediaFormat format = extractor.getTrackFormat(i); 412ac3f2e285159300c62c797bb2123604773ccac7Andreas Huber * String mime = format.getString(MediaFormat.KEY_MIME); 4207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * if (weAreInterestedInThisTrack) { 4307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.selectTrack(i); 4407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * } 4507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * } 4607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * ByteBuffer inputBuffer = ByteBuffer.allocate(...) 4707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * while (extractor.readSampleData(inputBuffer, ...) >= 0) { 48a242deb1de365f0ed0032a87565df1971cb6bbe2Teng-Hui Zhu * int trackIndex = extractor.getSampleTrackIndex(); 4907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * long presentationTimeUs = extractor.getSampleTime(); 5007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * ... 5107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.advance(); 5207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * } 5307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 5407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.release(); 5507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor = null; 5607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * </pre> 5760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberfinal public class MediaExtractor { 5907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public MediaExtractor() { 6007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber native_setup(); 6107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 6207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 6307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 64c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen * Sets the DataSource object to be used as the data source for this extractor 65c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen * {@hide} 66c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen */ 67c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen public native final void setDataSource(DataSource source); 68c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen 69c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen /** 7007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source as a content Uri. 7107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 7207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param context the Context to use when resolving the Uri 7307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param uri the Content URI of the data you want to extract from. 7407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param headers the headers to be sent together with the request for the data 7507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 7607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public final void setDataSource( 7707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber Context context, Uri uri, Map<String, String> headers) 7807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber throws IOException { 7907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber String scheme = uri.getScheme(); 8007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if(scheme == null || scheme.equals("file")) { 8107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(uri.getPath()); 8207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber return; 8307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 8407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 8507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber AssetFileDescriptor fd = null; 8607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber try { 8707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber ContentResolver resolver = context.getContentResolver(); 8807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd = resolver.openAssetFileDescriptor(uri, "r"); 8907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (fd == null) { 9007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber return; 9107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 9207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber // Note: using getDeclaredLength so that our behavior is the same 9307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber // as previous versions when the content provider is returning 9407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber // a full file. 9507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (fd.getDeclaredLength() < 0) { 9607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(fd.getFileDescriptor()); 9707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } else { 9807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource( 9907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd.getFileDescriptor(), 10007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd.getStartOffset(), 10107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd.getDeclaredLength()); 10207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 10307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber return; 10407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } catch (SecurityException ex) { 10507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } catch (IOException ex) { 10607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } finally { 10707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (fd != null) { 10807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd.close(); 10907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 11007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 11107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 11207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(uri.toString(), headers); 11307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 11407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 11507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 11607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source (file-path or http URL) to use. 11707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 11807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param path the path of the file, or the http URL 11907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param headers the headers associated with the http request for the stream you want to play 12007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 12107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public final void setDataSource(String path, Map<String, String> headers) { 12207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber String[] keys = null; 12307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber String[] values = null; 12407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 12507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (headers != null) { 12607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber keys = new String[headers.size()]; 12707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber values = new String[headers.size()]; 12807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 12907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber int i = 0; 13007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber for (Map.Entry<String, String> entry: headers.entrySet()) { 13107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber keys[i] = entry.getKey(); 13207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber values[i] = entry.getValue(); 13307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber ++i; 13407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 13507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 13607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(path, keys, values); 13707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 13807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 13907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber private native final void setDataSource( 14007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber String path, String[] keys, String[] values); 14107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 14207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 14307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source (file-path or http URL) to use. 14407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 14507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param path the path of the file, or the http URL of the stream 14607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 14707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * <p>When <code>path</code> refers to a local file, the file may actually be opened by a 14807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * process other than the calling application. This implies that the pathname 14907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * should be an absolute path (as any other process runs with unspecified current working 15007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * directory), and that the pathname should reference a world-readable file. 15107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * As an alternative, the application could first open the file for reading, 15207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}. 15307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 15407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public final void setDataSource(String path) { 15507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(path, null, null); 15607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 15707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 15807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 15907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source (FileDescriptor) to use. It is the caller's responsibility 16007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * to close the file descriptor. It is safe to do so as soon as this call returns. 16107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 16207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param fd the FileDescriptor for the file you want to extract from. 16307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 16407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public final void setDataSource(FileDescriptor fd) { 16507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(fd, 0, 0x7ffffffffffffffL); 16688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 16788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 16907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source (FileDescriptor) to use. The FileDescriptor must be 17007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility 17107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * to close the file descriptor. It is safe to do so as soon as this call returns. 17207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 17307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param fd the FileDescriptor for the file you want to extract from. 17407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param offset the offset into the file where the data to be extracted starts, in bytes 17507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param length the length in bytes of the data to be extracted 17607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 17707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public native final void setDataSource( 17807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber FileDescriptor fd, long offset, long length); 17907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber @Override 18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber protected void finalize() { 18288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber native_finalize(); 18388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 18660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Make sure you call this when you're done to free up any resources 18760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * instead of relying on the garbage collector to do this for you at 18860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * some point in the future. 18960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native final void release(); 19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 19360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Count the number of tracks found in the data source. 19460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 19560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public native final int getTrackCount(); 19660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 19760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 19860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Get the track format at the specified index. 19960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * More detail on the representation can be found at {@link android.media.MediaCodec} 20060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 20160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public MediaFormat getTrackFormat(int index) { 20260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber return new MediaFormat(getTrackFormatNative(index)); 20360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 20460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 20560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber private native Map<String, Object> getTrackFormatNative(int index); 20660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 20760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 20860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and 20960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * {@link #getSampleTime} only retrieve information for the subset of tracks 21060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * selected. 21160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Selecting the same track multiple times has no effect, the track is 21260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * only selected once. 21307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native void selectTrack(int index); 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 21760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and 21860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * {@link #getSampleTime} only retrieve information for the subset of tracks 21960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * selected. 22060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 221f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public native void unselectTrack(int index); 222f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber 22360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 22460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * If possible, seek to a sync sample at or before the specified time 22560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 226f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public static final int SEEK_TO_PREVIOUS_SYNC = 0; 22760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 22860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * If possible, seek to a sync sample at or after the specified time 22960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 230f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public static final int SEEK_TO_NEXT_SYNC = 1; 23160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 23260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * If possible, seek to the sync sample closest to the specified time 23360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 234f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public static final int SEEK_TO_CLOSEST_SYNC = 2; 235f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber 23660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 23760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * All selected tracks seek near the requested time according to the 23860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * specified mode. 23960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 240f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public native void seekTo(long timeUs, int mode); 24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 24360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Advance to the next sample. Returns false if no more sample data 24460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * is available (end of stream). 24507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native boolean advance(); 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 24960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Retrieve the current encoded sample and store it in the byte buffer 25060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * starting at the given offset. Returns the sample size (or -1 if 25160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * no more samples are available). 25260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native int readSampleData(ByteBuffer byteBuf, int offset); 25488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 25660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns the track index the current sample originates from (or -1 25760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * if no more samples are available) 25860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native int getSampleTrackIndex(); 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 26260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns the current sample's presentation time in microseconds. 26360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * or -1 if no more samples are available. 26460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native long getSampleTime(); 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2679b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber // Keep these in sync with their equivalents in NuMediaExtractor.h 26860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 26960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * The sample is a sync sample 27060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 2719b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber public static final int SAMPLE_FLAG_SYNC = 1; 27207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 27360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 27460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * The sample is (at least partially) encrypted, see also the documentation 27560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * for {@link android.media.MediaCodec#queueSecureInputBuffer} 27660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 2779b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber public static final int SAMPLE_FLAG_ENCRYPTED = 2; 2789b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber 27960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 28060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns the current sample's flags. 28160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 2829b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber public native int getSampleFlags(); 2839b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber 28460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 28560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * If the sample flags indicate that the current sample is at least 28660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * partially encrypted, this call returns relevant information about 28760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * the structure of the sample data required for decryption. 28860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * @param info The android.media.MediaCodec.CryptoInfo structure 28960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * to be filled in. 29060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * @return true iff the sample flags contain {@link #SAMPLE_FLAG_ENCRYPTED} 29160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 29291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber public native boolean getSampleCryptoInfo(MediaCodec.CryptoInfo info); 29391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 29460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 29560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns an estimate of how much data is presently cached in memory 29660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * expressed in microseconds. Returns -1 if that information is unavailable 29760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * or not applicable (no cache). 29874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber */ 29974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber public native long getCachedDuration(); 30074a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber 30160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 30260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns true iff we are caching data and the cache has reached the 30360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * end of the data stream (for now, a future seek may of course restart 30460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * the fetching of data). 305a45746efadd11bb7dfab026fb3c81a25fae74ca4Jeff Smith * This API only returns a meaningful result if {@link #getCachedDuration} 30660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * indicates the presence of a cache, i.e. does NOT return -1. 30760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 30874a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber public native boolean hasCacheReachedEndOfStream(); 30974a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber private static native final void native_init(); 31107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber private native final void native_setup(); 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber private native final void native_finalize(); 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber static { 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber System.loadLibrary("media_jni"); 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber native_init(); 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber private int mNativeContext; 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 321