MediaExtractor.java revision 075e9a19ce645752f8282bc19c91b25978a7dc52
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; 29e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissenimport java.nio.ByteOrder; 30e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissenimport java.util.HashMap; 3188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberimport java.util.Map; 32e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissenimport java.util.UUID; 3388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber/** 3507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * MediaExtractor facilitates extraction of demuxed, typically encoded, media data 3607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * from a data source. 3707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * <p>It is generally used like this: 3807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * <pre> 3907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * MediaExtractor extractor = new MediaExtractor(); 4007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.setDataSource(...); 4160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * int numTracks = extractor.getTrackCount(); 4207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * for (int i = 0; i < numTracks; ++i) { 432ac3f2e285159300c62c797bb2123604773ccac7Andreas Huber * MediaFormat format = extractor.getTrackFormat(i); 442ac3f2e285159300c62c797bb2123604773ccac7Andreas Huber * String mime = format.getString(MediaFormat.KEY_MIME); 4507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * if (weAreInterestedInThisTrack) { 4607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.selectTrack(i); 4707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * } 4807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * } 4907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * ByteBuffer inputBuffer = ByteBuffer.allocate(...) 5007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * while (extractor.readSampleData(inputBuffer, ...) >= 0) { 51a242deb1de365f0ed0032a87565df1971cb6bbe2Teng-Hui Zhu * int trackIndex = extractor.getSampleTrackIndex(); 5207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * long presentationTimeUs = extractor.getSampleTime(); 5307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * ... 5407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.advance(); 5507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * } 5607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 5707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor.release(); 5807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * extractor = null; 5907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * </pre> 6060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 618240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberfinal public class MediaExtractor { 6207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public MediaExtractor() { 6307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber native_setup(); 6407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 6507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 6607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 67c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen * Sets the DataSource object to be used as the data source for this extractor 68c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen * {@hide} 69c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen */ 70a57da0dc5a5b863cdb12287699ba58f34529bd62Andreas Huber public native final void setDataSource(DataSource source) throws IOException; 71c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen 72c209a06cfdcf633f12a299245312e3ac32bff27cMarco Nelissen /** 7307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source as a content Uri. 7407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 7507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param context the Context to use when resolving the Uri 7607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param uri the Content URI of the data you want to extract from. 7707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param headers the headers to be sent together with the request for the data 7807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 7907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public final void setDataSource( 8007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber Context context, Uri uri, Map<String, String> headers) 8107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber throws IOException { 8207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber String scheme = uri.getScheme(); 8307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if(scheme == null || scheme.equals("file")) { 8407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(uri.getPath()); 8507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber return; 8607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 8707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 8807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber AssetFileDescriptor fd = null; 8907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber try { 9007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber ContentResolver resolver = context.getContentResolver(); 9107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd = resolver.openAssetFileDescriptor(uri, "r"); 9207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (fd == null) { 9307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber return; 9407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 9507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber // Note: using getDeclaredLength so that our behavior is the same 9607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber // as previous versions when the content provider is returning 9707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber // a full file. 9807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (fd.getDeclaredLength() < 0) { 9907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(fd.getFileDescriptor()); 10007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } else { 10107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource( 10207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd.getFileDescriptor(), 10307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd.getStartOffset(), 10407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd.getDeclaredLength()); 10507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 10607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber return; 10707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } catch (SecurityException ex) { 10807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } catch (IOException ex) { 10907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } finally { 11007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (fd != null) { 11107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber fd.close(); 11207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 11307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 11407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 11507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(uri.toString(), headers); 11607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 11707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 11807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 11907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source (file-path or http URL) to use. 12007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 12107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param path the path of the file, or the http URL 12207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param headers the headers associated with the http request for the stream you want to play 12307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 124a57da0dc5a5b863cdb12287699ba58f34529bd62Andreas Huber public final void setDataSource(String path, Map<String, String> headers) 125a57da0dc5a5b863cdb12287699ba58f34529bd62Andreas Huber throws IOException { 12607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber String[] keys = null; 12707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber String[] values = null; 12807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 12907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (headers != null) { 13007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber keys = new String[headers.size()]; 13107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber values = new String[headers.size()]; 13207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 13307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber int i = 0; 13407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber for (Map.Entry<String, String> entry: headers.entrySet()) { 13507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber keys[i] = entry.getKey(); 13607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber values[i] = entry.getValue(); 13707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber ++i; 13807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 13907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 14007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(path, keys, values); 14107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 14207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 14307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber private native final void setDataSource( 144a57da0dc5a5b863cdb12287699ba58f34529bd62Andreas Huber String path, String[] keys, String[] values) throws IOException; 14507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 14607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 14707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source (file-path or http URL) to use. 14807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 14907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param path the path of the file, or the http URL of the stream 15007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 15107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * <p>When <code>path</code> refers to a local file, the file may actually be opened by a 15207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * process other than the calling application. This implies that the pathname 15307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * should be an absolute path (as any other process runs with unspecified current working 15407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * directory), and that the pathname should reference a world-readable file. 15507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * As an alternative, the application could first open the file for reading, 15607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}. 15707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 158a57da0dc5a5b863cdb12287699ba58f34529bd62Andreas Huber public final void setDataSource(String path) throws IOException { 15907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(path, null, null); 16007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 16107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 16207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 16307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source (FileDescriptor) to use. It is the caller's responsibility 16407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * to close the file descriptor. It is safe to do so as soon as this call returns. 16507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 16607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param fd the FileDescriptor for the file you want to extract from. 16707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 168a57da0dc5a5b863cdb12287699ba58f34529bd62Andreas Huber public final void setDataSource(FileDescriptor fd) throws IOException { 16907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber setDataSource(fd, 0, 0x7ffffffffffffffL); 17088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 17188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber /** 17307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Sets the data source (FileDescriptor) to use. The FileDescriptor must be 17407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility 17507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * to close the file descriptor. It is safe to do so as soon as this call returns. 17607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * 17707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param fd the FileDescriptor for the file you want to extract from. 17807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param offset the offset into the file where the data to be extracted starts, in bytes 17907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * @param length the length in bytes of the data to be extracted 18007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 18107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber public native final void setDataSource( 182a57da0dc5a5b863cdb12287699ba58f34529bd62Andreas Huber FileDescriptor fd, long offset, long length) throws IOException; 18307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber @Override 18588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber protected void finalize() { 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber native_finalize(); 18788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 19060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Make sure you call this when you're done to free up any resources 19160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * instead of relying on the garbage collector to do this for you at 19260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * some point in the future. 19360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native final void release(); 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 19760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Count the number of tracks found in the data source. 19860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 19960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public native final int getTrackCount(); 20060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 20160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 202ecba2e4b953e9480b5084c04ec0cb5a8ba574b03Marco Nelissen * Get the PSSH info if present. 203ecba2e4b953e9480b5084c04ec0cb5a8ba574b03Marco Nelissen * @return a map of uuid-to-bytes, with the uuid specifying 204e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen * the crypto scheme, and the bytes being the data specific to that scheme. 205e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen */ 206e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen public Map<UUID, byte[]> getPsshInfo() { 207e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen Map<UUID, byte[]> psshMap = null; 208e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen Map<String, Object> formatMap = getFileFormatNative(); 209e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen if (formatMap != null && formatMap.containsKey("pssh")) { 210e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen ByteBuffer rawpssh = (ByteBuffer) formatMap.get("pssh"); 211e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen rawpssh.order(ByteOrder.nativeOrder()); 212e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen rawpssh.rewind(); 213e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen formatMap.remove("pssh"); 214e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen // parse the flat pssh bytebuffer into something more manageable 215e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen psshMap = new HashMap<UUID, byte[]>(); 216e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen while (rawpssh.remaining() > 0) { 217e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen rawpssh.order(ByteOrder.BIG_ENDIAN); 218e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen long msb = rawpssh.getLong(); 219e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen long lsb = rawpssh.getLong(); 220e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen UUID uuid = new UUID(msb, lsb); 221e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen rawpssh.order(ByteOrder.nativeOrder()); 222e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen int datalen = rawpssh.getInt(); 223e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen byte [] psshdata = new byte[datalen]; 224e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen rawpssh.get(psshdata); 225e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen psshMap.put(uuid, psshdata); 226e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen } 227e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen } 228e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen return psshMap; 229e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen } 230e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen 231e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen private native Map<String, Object> getFileFormatNative(); 232e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen 233e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen /** 23460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Get the track format at the specified index. 23560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * More detail on the representation can be found at {@link android.media.MediaCodec} 23660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 23760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public MediaFormat getTrackFormat(int index) { 23860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber return new MediaFormat(getTrackFormatNative(index)); 23960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 24060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 24160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber private native Map<String, Object> getTrackFormatNative(int index); 24260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 24360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 24460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and 24560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * {@link #getSampleTime} only retrieve information for the subset of tracks 24660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * selected. 24760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Selecting the same track multiple times has no effect, the track is 24860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * only selected once. 24907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native void selectTrack(int index); 25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 25360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and 25460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * {@link #getSampleTime} only retrieve information for the subset of tracks 25560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * selected. 25660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 257f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public native void unselectTrack(int index); 258f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber 25960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 26060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * If possible, seek to a sync sample at or before the specified time 26160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 262f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public static final int SEEK_TO_PREVIOUS_SYNC = 0; 26360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 26460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * If possible, seek to a sync sample at or after the specified time 26560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 266f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public static final int SEEK_TO_NEXT_SYNC = 1; 26760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 26860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * If possible, seek to the sync sample closest to the specified time 26960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 270f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public static final int SEEK_TO_CLOSEST_SYNC = 2; 271f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber 27260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 27360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * All selected tracks seek near the requested time according to the 27460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * specified mode. 27560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 276f2855b3df5994e165b29025c4c49d8e7d634c034Andreas Huber public native void seekTo(long timeUs, int mode); 27788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 27960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Advance to the next sample. Returns false if no more sample data 28060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * is available (end of stream). 28107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */ 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native boolean advance(); 28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 28560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Retrieve the current encoded sample and store it in the byte buffer 28660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * starting at the given offset. Returns the sample size (or -1 if 28760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * no more samples are available). 28860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native int readSampleData(ByteBuffer byteBuf, int offset); 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 29260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns the track index the current sample originates from (or -1 29360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * if no more samples are available) 29460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native int getSampleTrackIndex(); 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 29860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns the current sample's presentation time in microseconds. 29960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * or -1 if no more samples are available. 30060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber public native long getSampleTime(); 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3039b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber // Keep these in sync with their equivalents in NuMediaExtractor.h 30460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 30560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * The sample is a sync sample 30660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 3079b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber public static final int SAMPLE_FLAG_SYNC = 1; 30807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 30960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 31060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * The sample is (at least partially) encrypted, see also the documentation 31160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * for {@link android.media.MediaCodec#queueSecureInputBuffer} 31260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 3139b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber public static final int SAMPLE_FLAG_ENCRYPTED = 2; 3149b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber 31560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 31660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns the current sample's flags. 31760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 3189b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber public native int getSampleFlags(); 3199b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber 32060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 32160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * If the sample flags indicate that the current sample is at least 32260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * partially encrypted, this call returns relevant information about 32360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * the structure of the sample data required for decryption. 32460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * @param info The android.media.MediaCodec.CryptoInfo structure 32560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * to be filled in. 32660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * @return true iff the sample flags contain {@link #SAMPLE_FLAG_ENCRYPTED} 32760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 32891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber public native boolean getSampleCryptoInfo(MediaCodec.CryptoInfo info); 32991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 33060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 33160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns an estimate of how much data is presently cached in memory 33260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * expressed in microseconds. Returns -1 if that information is unavailable 33360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * or not applicable (no cache). 33474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber */ 33574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber public native long getCachedDuration(); 33674a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber 33760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 33860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Returns true iff we are caching data and the cache has reached the 33960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * end of the data stream (for now, a future seek may of course restart 34060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * the fetching of data). 341a45746efadd11bb7dfab026fb3c81a25fae74ca4Jeff Smith * This API only returns a meaningful result if {@link #getCachedDuration} 34260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * indicates the presence of a cache, i.e. does NOT return -1. 34360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 34474a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber public native boolean hasCacheReachedEndOfStream(); 34574a78b0f6e8c07cfc7da8f043987f6de0648bc05Andreas Huber 34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber private static native final void native_init(); 34707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber private native final void native_setup(); 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber private native final void native_finalize(); 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber static { 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber System.loadLibrary("media_jni"); 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber native_init(); 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 355075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat private long mNativeContext; 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 357