| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Copyright 2013 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <sample> |
| <name>BasicMediaDecoder</name> |
| <group>Media</group> |
| <package>com.example.android.basicmediadecoder</package> |
| |
| <!-- change minSdk if needed--> |
| <minSdk>17</minSdk> |
| |
| <strings> |
| <intro> |
| <![CDATA[ |
| This activity uses a TextureView to render the frames of a video decoded using the |
| MediaCodec API. |
| ]]> |
| </intro> |
| </strings> |
| |
| <template src="base"/> |
| <common src="media"/> |
| |
| <metadata> |
| <status>PUBLISHED</status> |
| <categories>Media</categories> |
| <technologies>Android</technologies> |
| <languages>Java</languages> |
| <solutions>Mobile</solutions> |
| <level>ADVANCED</level> |
| <icon>screenshots/icon-web.png</icon> |
| <screenshots> |
| <img>screenshots/1-launch.png</img> |
| <img>screenshots/2-play-video.png</img> |
| </screenshots> |
| <api_refs> |
| <android>android.media.MediaCodec</android> |
| <android>android.media.MediaExtractor</android> |
| <android>android.animation.TimeAnimator</android> |
| </api_refs> |
| |
| <description> |
| This sample shows how to use the MediaCoder to decode a video, |
| use a TimeAnimator to sync the rendering commands with the system |
| display frame rendering and finally render it to a TextureView. |
| </description> |
| |
| <intro> |
| <![CDATA[ |
| [MediaCodec][1] was introduced in API 16, and can be used for low level (decoding/encoding) operations. |
| In the same API was also introduced [TimeAnimator][2], which can be used to synchronise animation frames. |
| Finally, [MediaExtractor][3] provides a simple way to extract demuxed media data from a data source. |
| |
| The main steps are described below: |
| |
| 1. Create a layout with a [TextureView][4] for your activity. |
| 2. Initialise a MediaExtractor instance with `new MediaExtractor()` and a TimeAnimator instance with |
| `new TimeAnimator()`. |
| 3. To start video playback, call `setDataSource(this, videoUri, null)` on your MediaExtractor instance, |
| where `videoUri` is the URI of your video source. |
| 4. On your MediaExtractor instance, call `getTrackCount()` to know how many tracks you have in your streams. |
| They may not all be video tracks. Deselect all tracks by calling `unselectTrack(i)` where `i` is |
| the index of the track. |
| 5. Get the mime type of a track by calling `getTrackFormat(i).getString(MediaFormat.KEY_MIME)` |
| on your MediaExtractor instance, where `i` is the index of your selected track. |
| If the mime type contains "video/", then this is a video track so you can select it, using `selectTrack(i)` |
| on your MediaExtractor instance. |
| 6. Create a MediaCodec instance by calling `MediaCodec.createDecoderByType(mimeType)`. |
| 7. Configure your MediaCodec instance with `configure(trackFormat, textureView, null, 0)`, |
| where `trackFormat` is obtained by calling `getTrackFormat(i)` on your MediaExtractor instance. |
| 8. Set a TimeListener on your TimeAnimation instance, and override its `onTimeUpdate(final TimeAnimator animation, |
| final long totalTime, final long deltaTime)` method. |
| 9. In `onTimeUpdate`, check if the media track has reached the end of stream, using `getSampleFlags()` |
| on your MediaExtractor instance and looking for `MediaCodec.BUFFER_FLAG_END_OF_STREAM` flag. |
| 10. Still in `onTimeUpdate`, assuming this isn't the end of the sample, write the media sample to your |
| MediaDecoder instance, using `queueInputBuffer(index, 0, size, presentationTimeUs, flags)` method. |
| You will need to set up your buffers, refer to [MediaCodec][1] documentation for details. |
| 11. After writing the media sample, you need to advance the sample, calling `advance()` on your |
| TimeExtractor instance (this is a blocking operation and should be done outside the main thread). |
| 12. Finally, you can release and render the media sample by calling |
| `dequeueOutputBuffer(info, timeout)` and `releaseOutputBuffer(i, true)`, refer to [MediaCodec][1] |
| documentation for details. |
| 13. In `onPause()` or if you have reached the end of the stream, call `end()` on your TimeAnimation instance, |
| then call `stop()` and `release()` on your MediaCodec instance, and finally, call `release()` on your |
| MediaExtractor instance. |
| |
| [1]: http://developer.android.com/reference/android/media/MediaCodec.html |
| [2]: http://developer.android.com/reference/android/animation/TimeAnimator.html |
| [3]: http://developer.android.com/reference/android/media/MediaExtractor.html |
| [4]: http://developer.android.com/reference/android/view/TextureView.html |
| ]]> |
| </intro> |
| </metadata> |
| </sample> |