Skip to content

Most visited

Recently visited

navigation
BasicMediaDecoder / src / com.example.android.basicmediadecoder /

MainActivity.java

1
/*
2
 * Copyright (C) 2013 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
 
17
package com.example.android.basicmediadecoder;
18
 
19
 
20
import android.animation.TimeAnimator;
21
import android.app.Activity;
22
import android.media.MediaCodec;
23
import android.media.MediaExtractor;
24
import android.net.Uri;
25
import android.os.Bundle;
26
import android.view.Menu;
27
import android.view.MenuInflater;
28
import android.view.MenuItem;
29
import android.view.Surface;
30
import android.view.TextureView;
31
import android.view.View;
32
import android.widget.TextView;
33
 
34
import com.example.android.common.media.MediaCodecWrapper;
35
 
36
import java.io.IOException;
37
 
38
/**
39
 * This activity uses a {@link android.view.TextureView} to render the frames of a video decoded using
40
 * {@link android.media.MediaCodec} API.
41
 */
42
public class MainActivity extends Activity {
43
 
44
    private TextureView mPlaybackView;
45
    private TimeAnimator mTimeAnimator = new TimeAnimator();
46
 
47
    // A utility that wraps up the underlying input and output buffer processing operations
48
    // into an east to use API.
49
    private MediaCodecWrapper mCodecWrapper;
50
    private MediaExtractor mExtractor = new MediaExtractor();
51
    TextView mAttribView = null;
52
 
53
 
54
    /**
55
     * Called when the activity is first created.
56
     */
57
    @Override
58
    public void onCreate(Bundle savedInstanceState) {
59
        super.onCreate(savedInstanceState);
60
        setContentView(R.layout.sample_main);
61
        mPlaybackView = (TextureView) findViewById(R.id.PlaybackView);
62
        mAttribView =  (TextView)findViewById(R.id.AttribView);
63
 
64
    }
65
 
66
    @Override
67
    public boolean onCreateOptionsMenu(Menu menu) {
68
        MenuInflater inflater = getMenuInflater();
69
        inflater.inflate(R.menu.action_menu, menu);
70
        return true;
71
    }
72
 
73
    @Override
74
    protected void onPause() {
75
        super.onPause();
76
        if(mTimeAnimator != null && mTimeAnimator.isRunning()) {
77
            mTimeAnimator.end();
78
        }
79
 
80
        if (mCodecWrapper != null ) {
81
            mCodecWrapper.stopAndRelease();
82
            mExtractor.release();
83
        }
84
    }
85
 
86
    @Override
87
    public boolean onOptionsItemSelected(MenuItem item) {
88
        if (item.getItemId() == R.id.menu_play) {
89
            mAttribView.setVisibility(View.VISIBLE);
90
            startPlayback();
91
            item.setEnabled(false);
92
        }
93
        return true;
94
    }
95
 
96
 
97
    public void startPlayback() {
98
 
99
        // Construct a URI that points to the video resource that we want to play
100
        Uri videoUri = Uri.parse("android.resource://"
101
                + getPackageName() + "/"
102
                + R.raw.vid_bigbuckbunny);
103
 
104
        try {
105
 
107
            mExtractor.setDataSource(this, videoUri, null);
108
            int nTracks = mExtractor.getTrackCount();
109
 
110
            // Begin by unselecting all of the tracks in the extractor, so we won't see
111
            // any tracks that we haven't explicitly selected.
112
            for (int i = 0; i < nTracks; ++i) {
113
                mExtractor.unselectTrack(i);
114
            }
115
 
116
 
117
            // Find the first video track in the stream. In a real-world application
118
            // it's possible that the stream would contain multiple tracks, but this
119
            // sample assumes that we just want to play the first one.
120
            for (int i = 0; i < nTracks; ++i) {
121
                // Try to create a video codec for this track. This call will return null if the
122
                // track is not a video track, or not a recognized video format. Once it returns
123
                // a valid MediaCodecWrapper, we can break out of the loop.
124
                mCodecWrapper = MediaCodecWrapper.fromVideoFormat(mExtractor.getTrackFormat(i),
125
                        new Surface(mPlaybackView.getSurfaceTexture()));
126
                if (mCodecWrapper != null) {
127
                    mExtractor.selectTrack(i);
128
                    break;
129
                }
130
            }
132
 
133
 
134
 
135
 
136
            // By using a {@link TimeAnimator}, we can sync our media rendering commands with
137
            // the system display frame rendering. The animator ticks as the {@link Choreographer}
138
            // recieves VSYNC events.
139
            mTimeAnimator.setTimeListener(new TimeAnimator.TimeListener() {
140
                @Override
141
                public void onTimeUpdate(final TimeAnimator animation,
142
                                         final long totalTime,
143
                                         final long deltaTime) {
144
 
145
                    boolean isEos = ((mExtractor.getSampleFlags() & MediaCodec
146
                            .BUFFER_FLAG_END_OF_STREAM) == MediaCodec.BUFFER_FLAG_END_OF_STREAM);
147
 
149
                    if (!isEos) {
150
                        // Try to submit the sample to the codec and if successful advance the
151
                        // extractor to the next available sample to read.
152
                        boolean result = mCodecWrapper.writeSample(mExtractor, false,
153
                                mExtractor.getSampleTime(), mExtractor.getSampleFlags());
154
 
155
                        if (result) {
156
                            // Advancing the extractor is a blocking operation and it MUST be
157
                            // executed outside the main thread in real applications.
158
                            mExtractor.advance();
159
                        }
160
                    }
162
 
163
                    // Examine the sample at the head of the queue to see if its ready to be
164
                    // rendered and is not zero sized End-of-Stream record.
165
                    MediaCodec.BufferInfo out_bufferInfo = new MediaCodec.BufferInfo();
166
                    mCodecWrapper.peekSample(out_bufferInfo);
167
 
169
                    if (out_bufferInfo.size <= 0 && isEos) {
170
                        mTimeAnimator.end();
171
                        mCodecWrapper.stopAndRelease();
172
                        mExtractor.release();
173
                    } else if (out_bufferInfo.presentationTimeUs / 1000 < totalTime) {
174
                        // Pop the sample off the queue and send it to {@link Surface}
175
                        mCodecWrapper.popSample(true);
176
                    }
178
 
179
                }
180
            });
181
 
182
            // We're all set. Kick off the animator to process buffers and render video frames as
183
            // they become available
184
            mTimeAnimator.start();
185
        } catch (IOException e) {
186
            e.printStackTrace();
187
        }
188
    }
189
}
This site uses cookies to store your preferences for site-specific language and display options.

Hooray!

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a one-minute survey?
Help us improve Android tools and documentation.