PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/media/java/android/media/MediaExtractor.java

https://bitbucket.org/Lloir/basee
Java | 320 lines | 109 code | 37 blank | 174 comment | 12 complexity | f217d5538dabc51c3d7b62ba07ff24bf MD5 | raw file
  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package android.media;
  17. import android.content.ContentResolver;
  18. import android.content.Context;
  19. import android.content.res.AssetFileDescriptor;
  20. import android.media.MediaCodec;
  21. import android.media.MediaFormat;
  22. import android.net.Uri;
  23. import java.io.FileDescriptor;
  24. import java.io.IOException;
  25. import java.nio.ByteBuffer;
  26. import java.util.Map;
  27. /**
  28. * MediaExtractor facilitates extraction of demuxed, typically encoded, media data
  29. * from a data source.
  30. * <p>It is generally used like this:
  31. * <pre>
  32. * MediaExtractor extractor = new MediaExtractor();
  33. * extractor.setDataSource(...);
  34. * int numTracks = extractor.getTrackCount();
  35. * for (int i = 0; i &lt; numTracks; ++i) {
  36. * MediaFormat format = extractor.getTrackFormat(i);
  37. * String mime = format.getString(MediaFormat.KEY_MIME);
  38. * if (weAreInterestedInThisTrack) {
  39. * extractor.selectTrack(i);
  40. * }
  41. * }
  42. * ByteBuffer inputBuffer = ByteBuffer.allocate(...)
  43. * while (extractor.readSampleData(inputBuffer, ...) &gt;= 0) {
  44. * int trackIndex = extractor.getSampleTrackIndex();
  45. * long presentationTimeUs = extractor.getSampleTime();
  46. * ...
  47. * extractor.advance();
  48. * }
  49. *
  50. * extractor.release();
  51. * extractor = null;
  52. * </pre>
  53. */
  54. final public class MediaExtractor {
  55. public MediaExtractor() {
  56. native_setup();
  57. }
  58. /**
  59. * Sets the DataSource object to be used as the data source for this extractor
  60. * {@hide}
  61. */
  62. public native final void setDataSource(DataSource source);
  63. /**
  64. * Sets the data source as a content Uri.
  65. *
  66. * @param context the Context to use when resolving the Uri
  67. * @param uri the Content URI of the data you want to extract from.
  68. * @param headers the headers to be sent together with the request for the data
  69. */
  70. public final void setDataSource(
  71. Context context, Uri uri, Map<String, String> headers)
  72. throws IOException {
  73. String scheme = uri.getScheme();
  74. if(scheme == null || scheme.equals("file")) {
  75. setDataSource(uri.getPath());
  76. return;
  77. }
  78. AssetFileDescriptor fd = null;
  79. try {
  80. ContentResolver resolver = context.getContentResolver();
  81. fd = resolver.openAssetFileDescriptor(uri, "r");
  82. if (fd == null) {
  83. return;
  84. }
  85. // Note: using getDeclaredLength so that our behavior is the same
  86. // as previous versions when the content provider is returning
  87. // a full file.
  88. if (fd.getDeclaredLength() < 0) {
  89. setDataSource(fd.getFileDescriptor());
  90. } else {
  91. setDataSource(
  92. fd.getFileDescriptor(),
  93. fd.getStartOffset(),
  94. fd.getDeclaredLength());
  95. }
  96. return;
  97. } catch (SecurityException ex) {
  98. } catch (IOException ex) {
  99. } finally {
  100. if (fd != null) {
  101. fd.close();
  102. }
  103. }
  104. setDataSource(uri.toString(), headers);
  105. }
  106. /**
  107. * Sets the data source (file-path or http URL) to use.
  108. *
  109. * @param path the path of the file, or the http URL
  110. * @param headers the headers associated with the http request for the stream you want to play
  111. */
  112. public final void setDataSource(String path, Map<String, String> headers) {
  113. String[] keys = null;
  114. String[] values = null;
  115. if (headers != null) {
  116. keys = new String[headers.size()];
  117. values = new String[headers.size()];
  118. int i = 0;
  119. for (Map.Entry<String, String> entry: headers.entrySet()) {
  120. keys[i] = entry.getKey();
  121. values[i] = entry.getValue();
  122. ++i;
  123. }
  124. }
  125. setDataSource(path, keys, values);
  126. }
  127. private native final void setDataSource(
  128. String path, String[] keys, String[] values);
  129. /**
  130. * Sets the data source (file-path or http URL) to use.
  131. *
  132. * @param path the path of the file, or the http URL of the stream
  133. *
  134. * <p>When <code>path</code> refers to a local file, the file may actually be opened by a
  135. * process other than the calling application. This implies that the pathname
  136. * should be an absolute path (as any other process runs with unspecified current working
  137. * directory), and that the pathname should reference a world-readable file.
  138. * As an alternative, the application could first open the file for reading,
  139. * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
  140. */
  141. public final void setDataSource(String path) {
  142. setDataSource(path, null, null);
  143. }
  144. /**
  145. * Sets the data source (FileDescriptor) to use. It is the caller's responsibility
  146. * to close the file descriptor. It is safe to do so as soon as this call returns.
  147. *
  148. * @param fd the FileDescriptor for the file you want to extract from.
  149. */
  150. public final void setDataSource(FileDescriptor fd) {
  151. setDataSource(fd, 0, 0x7ffffffffffffffL);
  152. }
  153. /**
  154. * Sets the data source (FileDescriptor) to use. The FileDescriptor must be
  155. * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility
  156. * to close the file descriptor. It is safe to do so as soon as this call returns.
  157. *
  158. * @param fd the FileDescriptor for the file you want to extract from.
  159. * @param offset the offset into the file where the data to be extracted starts, in bytes
  160. * @param length the length in bytes of the data to be extracted
  161. */
  162. public native final void setDataSource(
  163. FileDescriptor fd, long offset, long length);
  164. @Override
  165. protected void finalize() {
  166. native_finalize();
  167. }
  168. /**
  169. * Make sure you call this when you're done to free up any resources
  170. * instead of relying on the garbage collector to do this for you at
  171. * some point in the future.
  172. */
  173. public native final void release();
  174. /**
  175. * Count the number of tracks found in the data source.
  176. */
  177. public native final int getTrackCount();
  178. /**
  179. * Get the track format at the specified index.
  180. * More detail on the representation can be found at {@link android.media.MediaCodec}
  181. */
  182. public MediaFormat getTrackFormat(int index) {
  183. return new MediaFormat(getTrackFormatNative(index));
  184. }
  185. private native Map<String, Object> getTrackFormatNative(int index);
  186. /**
  187. * Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and
  188. * {@link #getSampleTime} only retrieve information for the subset of tracks
  189. * selected.
  190. * Selecting the same track multiple times has no effect, the track is
  191. * only selected once.
  192. */
  193. public native void selectTrack(int index);
  194. /**
  195. * Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and
  196. * {@link #getSampleTime} only retrieve information for the subset of tracks
  197. * selected.
  198. */
  199. public native void unselectTrack(int index);
  200. /**
  201. * If possible, seek to a sync sample at or before the specified time
  202. */
  203. public static final int SEEK_TO_PREVIOUS_SYNC = 0;
  204. /**
  205. * If possible, seek to a sync sample at or after the specified time
  206. */
  207. public static final int SEEK_TO_NEXT_SYNC = 1;
  208. /**
  209. * If possible, seek to the sync sample closest to the specified time
  210. */
  211. public static final int SEEK_TO_CLOSEST_SYNC = 2;
  212. /**
  213. * All selected tracks seek near the requested time according to the
  214. * specified mode.
  215. */
  216. public native void seekTo(long timeUs, int mode);
  217. /**
  218. * Advance to the next sample. Returns false if no more sample data
  219. * is available (end of stream).
  220. */
  221. public native boolean advance();
  222. /**
  223. * Retrieve the current encoded sample and store it in the byte buffer
  224. * starting at the given offset. Returns the sample size (or -1 if
  225. * no more samples are available).
  226. */
  227. public native int readSampleData(ByteBuffer byteBuf, int offset);
  228. /**
  229. * Returns the track index the current sample originates from (or -1
  230. * if no more samples are available)
  231. */
  232. public native int getSampleTrackIndex();
  233. /**
  234. * Returns the current sample's presentation time in microseconds.
  235. * or -1 if no more samples are available.
  236. */
  237. public native long getSampleTime();
  238. // Keep these in sync with their equivalents in NuMediaExtractor.h
  239. /**
  240. * The sample is a sync sample
  241. */
  242. public static final int SAMPLE_FLAG_SYNC = 1;
  243. /**
  244. * The sample is (at least partially) encrypted, see also the documentation
  245. * for {@link android.media.MediaCodec#queueSecureInputBuffer}
  246. */
  247. public static final int SAMPLE_FLAG_ENCRYPTED = 2;
  248. /**
  249. * Returns the current sample's flags.
  250. */
  251. public native int getSampleFlags();
  252. /**
  253. * If the sample flags indicate that the current sample is at least
  254. * partially encrypted, this call returns relevant information about
  255. * the structure of the sample data required for decryption.
  256. * @param info The android.media.MediaCodec.CryptoInfo structure
  257. * to be filled in.
  258. * @return true iff the sample flags contain {@link #SAMPLE_FLAG_ENCRYPTED}
  259. */
  260. public native boolean getSampleCryptoInfo(MediaCodec.CryptoInfo info);
  261. /**
  262. * Returns an estimate of how much data is presently cached in memory
  263. * expressed in microseconds. Returns -1 if that information is unavailable
  264. * or not applicable (no cache).
  265. */
  266. public native long getCachedDuration();
  267. /**
  268. * Returns true iff we are caching data and the cache has reached the
  269. * end of the data stream (for now, a future seek may of course restart
  270. * the fetching of data).
  271. * This API only returns a meaningful result if {@link #getCachedDuration}
  272. * indicates the presence of a cache, i.e. does NOT return -1.
  273. */
  274. public native boolean hasCacheReachedEndOfStream();
  275. private static native final void native_init();
  276. private native final void native_setup();
  277. private native final void native_finalize();
  278. static {
  279. System.loadLibrary("media_jni");
  280. native_init();
  281. }
  282. private int mNativeContext;
  283. }