Created
October 1, 2012 15:21
-
-
Save JavaDeveloper/3812450 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.ByteBuffer; | |
import android.media.MediaCodec; | |
import android.media.MediaExtractor; | |
import android.media.MediaFormat; | |
import android.util.Log; | |
import android.view.Surface; | |
public abstract class AbstractTrackDecoder extends Thread { | |
private static final String TAG = AbstractTrackDecoder.class.getSimpleName(); | |
protected final long TIMEOUT_US = 5000; | |
protected boolean hasInputData = true; | |
protected boolean hasOutputData = true; | |
protected MediaExtractor extractor; | |
protected MediaFormat format; | |
protected String mime; | |
protected int trackNum; | |
protected MediaCodec codec; | |
protected ByteBuffer[] inputBuffers; | |
protected ByteBuffer[] outputBuffers; | |
protected MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); | |
/** | |
* Index of the current buffer(decoded data), which is the first in the | |
* buffers queue. | |
*/ | |
protected int outputBufferIndex = -1; | |
protected AbstractTrackDecoder(String path, String prefix, Surface surface) { | |
this.extractor = new MediaExtractor(); | |
this.extractor.setDataSource(path); | |
initializeCodec(extractor, prefix, surface); | |
} | |
private void initializeCodec(MediaExtractor extractor, String prefix, Surface surface) { | |
int trackCount = extractor.getTrackCount(); | |
for (int i = 0; i < trackCount; i++) { | |
format = extractor.getTrackFormat(i); | |
mime = format.getString(MediaFormat.KEY_MIME); | |
if (mime.startsWith(prefix)) { | |
trackNum = i; | |
codec = MediaCodec.createDecoderByType(mime); | |
codec.configure(format, surface, null /* crypto */, 0 /* flags */); | |
codec.start(); | |
inputBuffers = codec.getInputBuffers(); | |
outputBuffers = codec.getOutputBuffers(); | |
Log.d(TAG, "Found: " + mime); | |
break; | |
} | |
} | |
} | |
public boolean isHasRawData() { | |
return hasInputData; | |
} | |
public boolean isHasDecodedData() { | |
return hasOutputData; | |
} | |
public void cleanup() { | |
if (codec == null) { | |
return; | |
} | |
codec.stop(); | |
codec.release(); | |
codec = null; | |
} | |
public void dequeueInput() throws InterruptedException { | |
int inputBufferIndex = codec.dequeueInputBuffer(TIMEOUT_US); | |
if (inputBufferIndex >= 0) { | |
ByteBuffer dst = inputBuffers[inputBufferIndex]; | |
extractor.selectTrack(trackNum); | |
int sampleSize = extractor.readSampleData(dst, 0 /* offset */); | |
if (sampleSize >= 0) { | |
long pts = extractor.getSampleTime(); | |
codec.queueInputBuffer(inputBufferIndex, 0 /* offset */, sampleSize, pts, 0); | |
extractor.advance(); | |
} else { | |
codec.queueInputBuffer(inputBufferIndex, 0 /* offset */, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); | |
hasInputData = false; | |
Log.d(TAG, "Raw data EOS."); | |
} | |
} else { | |
// no buffer is available | |
synchronized (this) { | |
wait(); | |
} | |
} | |
} | |
public void dequeueOutput() { | |
outputBufferIndex = codec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US); | |
if (outputBufferIndex >= 0) { | |
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { | |
Log.d(TAG, "Decoded data EOS."); | |
hasOutputData = false; | |
} | |
} | |
} | |
public void systemTime(long us) { | |
if (bufferInfo.presentationTimeUs / 1000 <= us) { | |
processDecodedData(); | |
dequeueOutput(); | |
synchronized (this) { | |
notify(); | |
} | |
} | |
} | |
protected abstract void processDecodedData(); | |
@Override | |
public void run() { | |
while (true) { | |
if (hasInputData) { | |
try { | |
dequeueInput(); | |
} catch (Exception e) { | |
Log.e(TAG, "reading data", e); | |
break; | |
} | |
} | |
if (!hasOutputData) { | |
break; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment