ここから取得したコードを使用して、Android MediaCodec を試しています: https://code.google.com/p/android-source-browsing.platform--cts
コード「android-source-browsing.platform--cts/tests/tests/media/src/android/media/cts/DecoderTest.java」を実行しようとすると、次のエラーが発生しました。
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
lib_k3_avi_extractor.so、lib_k3_mov_extractor.so などのライブラリが私のデバイスにないようです。ここに私の質問があります: これらのライブラリは何ですか? それらは何のため?それらがデバイスにないのはなぜですか? 私はこれらのライブラリをグーグルで検索しましたが、奇妙なことに、検索ではまったく何も見つかりませんでした。
エラーを生成した Java コードを以下に示します。ログ情報を追加するための小さな変更が加えられています。
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);
}