I'm experimenting with Android MediaCodec, with the code I got from here: https://code.google.com/p/android-source-browsing.platform--cts
When I tried to run the code "android-source-browsing.platform--cts/tests/tests/media/src/android/media/cts/DecoderTest.java", I got these errors:
D/android.media.cts.DecoderTest(6615): decode(): master = 2131034134
D/android.media.cts.DecoderTest(6615): decode(): masterFd = {AssetFileDescriptor: {ParcelFileDescriptor: FileDescriptor[50]} start=1781867 len=529200}
D/android.media.cts.DecoderTest(6615): decode(): masterLength = 529200
D/android.media.cts.DecoderTest(6615): decode(): is = android.content.res.AssetFileDescriptor$AutoCloseInputStream@417592a0
D/android.media.cts.DecoderTest(6615): decode(): bis = java.io.BufferedInputStream@41759368
I/ExtractorLoader(6615): Register extractor from [lib_k3_avi_extractor.so]
E/ExtractorLoader(6615): Open [lib_k3_mov_extractor.so] failed!
E/ExtractorLoader(6615): Open [lib_k3_flv_extractor.so] failed!
I/ExtractorLoader(6615): Register extractor from [lib_k3_m2ts_extractor.so]
E/ExtractorLoader(6615): Open [lib_k3_asf_extractor.so] failed!
E/ExtractorLoader(6615): Open [lib_k3_generic_audio_extractor.so] failed!
D/android.media.cts.DecoderTest(6615): decode(): testAssetFd = {AssetFileDescriptor: {ParcelFileDescriptor: FileDescriptor[50]} start=1591735 len=49318}
D/android.media.cts.DecoderTest(6615): decode(): testFd = FileDescriptor[50]
D/android.media.cts.DecoderTest(6615): decode(): trackCount = 1
D/android.media.cts.DecoderTest(6615): decode(): fileLength = 49318
D/android.media.cts.DecoderTest(6615): decode(): format = {durationUs=3056326, encoder-padding=1908, channel-count=2, encoder-delay=576, mime=audio/mpeg, sample-rate=44100}
D/android.media.cts.DecoderTest(6615): decode(): mime = audio/mpeg
Apparently the libraries lib_k3_avi_extractor.so, lib_k3_mov_extractor.so, etc, are not in my device. Here are my questions: What are these libraries? What are they for? Why are they not in the device? I googled for these libraries, but strangely the search came up with absolutely nothing.
The Java code that generated the errors is listed below, with my minor changes to add the log information:
private void decode(int testinput, int master, float maxerror) throws IOException {
// read master file into memory
AssetFileDescriptor masterFd = mResources.openRawResourceFd(master);
long masterLength = masterFd.getLength(); //in bytes?
short[] masterBuffer = new short[(int)(masterLength/2)];
InputStream is = masterFd.createInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
Log.d(TAG, "decode(): master = " + master);
Log.d(TAG, "decode(): masterFd = " + masterFd);
Log.d(TAG, "decode(): masterLength = " + masterLength);
Log.d(TAG, "decode(): is = " + is);
Log.d(TAG, "decode(): bis = " + bis);
for (int i = 0; i < masterBuffer.length; i++) {
int lo = bis.read();
int hi = bis.read();
if (hi >= 128) {
hi -= 256;
}
int sample = hi * 256 + lo;
masterBuffer[i] = (short) sample;
}
bis.close();
MediaExtractor extractor;
MediaCodec codec;
ByteBuffer[] codecInputBuffers;
ByteBuffer[] codecOutputBuffers;
AssetFileDescriptor testAssetFd = mResources.openRawResourceFd(testinput);
FileDescriptor testFd = testAssetFd.getFileDescriptor();
extractor = new MediaExtractor();
extractor.setDataSource(testFd, testAssetFd.getStartOffset(), testAssetFd.getLength());
//assertEquals("wrong number of tracks", 1, extractor.getTrackCount());
MediaFormat format = extractor.getTrackFormat(0);
String mime = format.getString(MediaFormat.KEY_MIME);
//assertTrue("not an audio file", mime.startsWith("audio/"));
Log.d(TAG, "decode(): testAssetFd = " + testAssetFd);
Log.d(TAG, "decode(): testFd = " + testFd);
Log.d(TAG, "decode(): trackCount = " + extractor.getTrackCount());
Log.d(TAG, "decode(): fileLength = " + testAssetFd.getLength());
Log.d(TAG, "decode(): format = " + format);
Log.d(TAG, "decode(): mime = " + mime);
codec = MediaCodec.createDecoderByType(mime);
codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
codec.start();
codecInputBuffers = codec.getInputBuffers();
codecOutputBuffers = codec.getOutputBuffers();
extractor.selectTrack(0);
// start decoding
int numBytesDecoded = 0;
int maxdelta = 0;
long totalErrorSquared = 0;
final long kTimeOutUs = 5000;
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
boolean sawInputEOS = false;
boolean sawOutputEOS = false;
while (!sawOutputEOS) {
if (!sawInputEOS) {
// transfer control of input buffer from codec to Java code
int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
if (inputBufIndex >= 0) {
ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
// fill input buffer with data
int sampleSize = extractor.readSampleData(dstBuf, 0 /* offset */);
long presentationTimeUs = 0;
if (sampleSize < 0) {
Log.d(TAG, "saw input EOS.");
sawInputEOS = true;
sampleSize = 0;
} else {
presentationTimeUs = extractor.getSampleTime();
}
// let the codec control input buffer again
codec.queueInputBuffer(
inputBufIndex,
0 /* offset */,
sampleSize,
presentationTimeUs,
sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
if (!sawInputEOS) {
extractor.advance();
}
}
}
int res = codec.dequeueOutputBuffer(info, kTimeOutUs);
if (res >= 0) {
int outputBufIndex = res;
ByteBuffer buf = codecOutputBuffers[outputBufIndex];
// check the waveform matches within the specified max error
for (int i = 0; i < info.size; i += 2) {
short sample = buf.getShort(i);
int idx = (numBytesDecoded + i) / 2;
//assertTrue("decoder returned too much data", idx < masterBuffer.length);
short mastersample = masterBuffer[idx];
int d = sample - mastersample;
totalErrorSquared += d * d;
}
numBytesDecoded += info.size;
codec.releaseOutputBuffer(outputBufIndex, false /* render */);
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
Log.d(TAG, "saw output EOS.");
sawOutputEOS = true;
}
} else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
codecOutputBuffers = codec.getOutputBuffers();
Log.d(TAG, "output buffers have changed.");
} else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat oformat = codec.getOutputFormat();
Log.d(TAG, "output format has changed to " + oformat);
}
}
codec.stop();
codec.release();
testAssetFd.close();
masterFd.close();
//assertEquals("wrong data size", masterLength, numBytesDecoded);
long avgErrorSquared = (totalErrorSquared / (numBytesDecoded / 2));
double rmse = Math.sqrt(avgErrorSquared);
//assertTrue("decoding error too big: " + rmse, rmse <= maxerror);
}