|
|
|
@ -45,6 +45,7 @@ import java.util.Arrays;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
|
|
|
|
|
import static org.junit.Assert.assertTrue;
|
|
|
|
|
import static org.junit.Assert.assertEquals;
|
|
|
|
|
|
|
|
|
|
@RunWith(Parameterized.class)
|
|
|
|
|
public class EncoderTest {
|
|
|
|
@ -99,174 +100,148 @@ public class EncoderTest {
|
|
|
|
|
int sampleRate = 0;
|
|
|
|
|
int numChannels = 0;
|
|
|
|
|
File inputFile = new File(mInputFilePath + mInputFile);
|
|
|
|
|
if (inputFile.exists()) {
|
|
|
|
|
FileInputStream fileInput = new FileInputStream(inputFile);
|
|
|
|
|
FileDescriptor fileDescriptor = fileInput.getFD();
|
|
|
|
|
Extractor extractor = new Extractor();
|
|
|
|
|
int trackCount = extractor.setUpExtractor(fileDescriptor);
|
|
|
|
|
if (trackCount <= 0) {
|
|
|
|
|
Log.e(TAG, "Extraction failed. No tracks for file: " + mInputFile);
|
|
|
|
|
return;
|
|
|
|
|
assertTrue("Cannot find " + mInputFile + " in directory " + mInputFilePath,
|
|
|
|
|
inputFile.exists());
|
|
|
|
|
FileInputStream fileInput = new FileInputStream(inputFile);
|
|
|
|
|
FileDescriptor fileDescriptor = fileInput.getFD();
|
|
|
|
|
Extractor extractor = new Extractor();
|
|
|
|
|
int trackCount = extractor.setUpExtractor(fileDescriptor);
|
|
|
|
|
assertTrue("Extraction failed. No tracks for file: " + mInputFile, (trackCount > 0));
|
|
|
|
|
ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
|
|
|
|
|
ArrayList<MediaCodec.BufferInfo> frameInfo = new ArrayList<>();
|
|
|
|
|
for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
|
|
|
|
|
extractor.selectExtractorTrack(currentTrack);
|
|
|
|
|
MediaFormat format = extractor.getFormat(currentTrack);
|
|
|
|
|
// Get samples from extractor
|
|
|
|
|
int sampleSize;
|
|
|
|
|
do {
|
|
|
|
|
sampleSize = extractor.getFrameSample();
|
|
|
|
|
MediaCodec.BufferInfo bufInfo = new MediaCodec.BufferInfo();
|
|
|
|
|
MediaCodec.BufferInfo info = extractor.getBufferInfo();
|
|
|
|
|
ByteBuffer dataBuffer = ByteBuffer.allocate(info.size);
|
|
|
|
|
dataBuffer.put(extractor.getFrameBuffer().array(), 0, info.size);
|
|
|
|
|
bufInfo.set(info.offset, info.size, info.presentationTimeUs, info.flags);
|
|
|
|
|
inputBuffer.add(dataBuffer);
|
|
|
|
|
frameInfo.add(bufInfo);
|
|
|
|
|
if (DEBUG) {
|
|
|
|
|
Log.d(TAG, "Extracted bufInfo: flag = " + bufInfo.flags + " timestamp = " +
|
|
|
|
|
bufInfo.presentationTimeUs + " size = " + bufInfo.size);
|
|
|
|
|
}
|
|
|
|
|
} while (sampleSize > 0);
|
|
|
|
|
int tid = android.os.Process.myTid();
|
|
|
|
|
File decodedFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
|
|
|
|
|
FileOutputStream decodeOutputStream = new FileOutputStream(decodedFile);
|
|
|
|
|
Decoder decoder = new Decoder();
|
|
|
|
|
decoder.setupDecoder(decodeOutputStream);
|
|
|
|
|
status = decoder.decode(inputBuffer, frameInfo, false, format, "");
|
|
|
|
|
assertEquals("Decoder returned error " + status + " for file: " + mInputFile, 0,
|
|
|
|
|
status);
|
|
|
|
|
decoder.deInitCodec();
|
|
|
|
|
extractor.unselectExtractorTrack(currentTrack);
|
|
|
|
|
inputBuffer.clear();
|
|
|
|
|
frameInfo.clear();
|
|
|
|
|
if (decodeOutputStream != null) {
|
|
|
|
|
decodeOutputStream.close();
|
|
|
|
|
}
|
|
|
|
|
ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
|
|
|
|
|
ArrayList<MediaCodec.BufferInfo> frameInfo = new ArrayList<>();
|
|
|
|
|
for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
|
|
|
|
|
extractor.selectExtractorTrack(currentTrack);
|
|
|
|
|
MediaFormat format = extractor.getFormat(currentTrack);
|
|
|
|
|
// Get samples from extractor
|
|
|
|
|
int sampleSize;
|
|
|
|
|
do {
|
|
|
|
|
sampleSize = extractor.getFrameSample();
|
|
|
|
|
MediaCodec.BufferInfo bufInfo = new MediaCodec.BufferInfo();
|
|
|
|
|
MediaCodec.BufferInfo info = extractor.getBufferInfo();
|
|
|
|
|
ByteBuffer dataBuffer = ByteBuffer.allocate(info.size);
|
|
|
|
|
dataBuffer.put(extractor.getFrameBuffer().array(), 0, info.size);
|
|
|
|
|
bufInfo.set(info.offset, info.size, info.presentationTimeUs, info.flags);
|
|
|
|
|
inputBuffer.add(dataBuffer);
|
|
|
|
|
frameInfo.add(bufInfo);
|
|
|
|
|
String mime = format.getString(MediaFormat.KEY_MIME);
|
|
|
|
|
ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
|
|
|
|
|
assertTrue("No suitable codecs found for file: " + mInputFile + " track : " +
|
|
|
|
|
currentTrack + " mime: " + mime, (mediaCodecs.size() > 0));
|
|
|
|
|
Boolean[] encodeMode = {true, false};
|
|
|
|
|
/* Encoding the decoder's output */
|
|
|
|
|
for (Boolean asyncMode : encodeMode) {
|
|
|
|
|
for (String codecName : mediaCodecs) {
|
|
|
|
|
FileOutputStream encodeOutputStream = null;
|
|
|
|
|
if (WRITE_OUTPUT) {
|
|
|
|
|
File outEncodeFile = new File(mOutputFilePath + "encoder.out");
|
|
|
|
|
if (outEncodeFile.exists()) {
|
|
|
|
|
assertTrue(" Unable to delete existing file" + outEncodeFile.toString(),
|
|
|
|
|
outEncodeFile.delete());
|
|
|
|
|
}
|
|
|
|
|
assertTrue("Unable to create file to write encoder output: " +
|
|
|
|
|
outEncodeFile.toString(), outEncodeFile.createNewFile());
|
|
|
|
|
encodeOutputStream = new FileOutputStream(outEncodeFile);
|
|
|
|
|
}
|
|
|
|
|
File rawFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
|
|
|
|
|
assertTrue("Cannot open file to write decoded output", rawFile.exists());
|
|
|
|
|
if (DEBUG) {
|
|
|
|
|
Log.d(TAG, "Extracted bufInfo: flag = " + bufInfo.flags + " timestamp = " +
|
|
|
|
|
bufInfo.presentationTimeUs + " size = " + bufInfo.size);
|
|
|
|
|
Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
|
|
|
|
|
}
|
|
|
|
|
} while (sampleSize > 0);
|
|
|
|
|
int tid = android.os.Process.myTid();
|
|
|
|
|
File decodedFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
|
|
|
|
|
FileOutputStream decodeOutputStream = new FileOutputStream(decodedFile);
|
|
|
|
|
Decoder decoder = new Decoder();
|
|
|
|
|
decoder.setupDecoder(decodeOutputStream);
|
|
|
|
|
status = decoder.decode(inputBuffer, frameInfo, false, format, "");
|
|
|
|
|
if (status == 0) {
|
|
|
|
|
Log.i(TAG, "Decoding complete.");
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "Decode returned error. Encoding did not take place." + status);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
decoder.deInitCodec();
|
|
|
|
|
extractor.unselectExtractorTrack(currentTrack);
|
|
|
|
|
inputBuffer.clear();
|
|
|
|
|
frameInfo.clear();
|
|
|
|
|
if (decodeOutputStream != null) {
|
|
|
|
|
decodeOutputStream.close();
|
|
|
|
|
}
|
|
|
|
|
String mime = format.getString(MediaFormat.KEY_MIME);
|
|
|
|
|
ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
|
|
|
|
|
if (mediaCodecs.size() <= 0) {
|
|
|
|
|
Log.e(TAG, "No suitable codecs found for file: " + mInputFile + " track : " +
|
|
|
|
|
currentTrack + " mime: " + mime);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Boolean[] encodeMode = {true, false};
|
|
|
|
|
/* Encoding the decoder's output */
|
|
|
|
|
for (Boolean asyncMode : encodeMode) {
|
|
|
|
|
for (String codecName : mediaCodecs) {
|
|
|
|
|
FileOutputStream encodeOutputStream = null;
|
|
|
|
|
if (WRITE_OUTPUT) {
|
|
|
|
|
File outEncodeFile = new File(mOutputFilePath + "encoder.out");
|
|
|
|
|
if (outEncodeFile.exists()) {
|
|
|
|
|
if (!outEncodeFile.delete()) {
|
|
|
|
|
Log.e(TAG, "Unable to delete existing file" +
|
|
|
|
|
decodedFile.toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (outEncodeFile.createNewFile()) {
|
|
|
|
|
encodeOutputStream = new FileOutputStream(outEncodeFile);
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "Unable to create file to write encoder output: " +
|
|
|
|
|
outEncodeFile.toString());
|
|
|
|
|
}
|
|
|
|
|
FileInputStream eleStream = new FileInputStream(rawFile);
|
|
|
|
|
if (mime.startsWith("video/")) {
|
|
|
|
|
width = format.getInteger(MediaFormat.KEY_WIDTH);
|
|
|
|
|
height = format.getInteger(MediaFormat.KEY_HEIGHT);
|
|
|
|
|
if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
|
|
|
|
|
frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
|
|
|
|
|
} else if (frameRate <= 0) {
|
|
|
|
|
frameRate = ENCODE_DEFAULT_FRAME_RATE;
|
|
|
|
|
}
|
|
|
|
|
File rawFile =
|
|
|
|
|
new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
|
|
|
|
|
if (rawFile.exists()) {
|
|
|
|
|
if (DEBUG) {
|
|
|
|
|
Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
|
|
|
|
|
}
|
|
|
|
|
FileInputStream eleStream = new FileInputStream(rawFile);
|
|
|
|
|
if (mime.startsWith("video/")) {
|
|
|
|
|
width = format.getInteger(MediaFormat.KEY_WIDTH);
|
|
|
|
|
height = format.getInteger(MediaFormat.KEY_HEIGHT);
|
|
|
|
|
if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
|
|
|
|
|
frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
|
|
|
|
|
} else if (frameRate <= 0) {
|
|
|
|
|
frameRate = ENCODE_DEFAULT_FRAME_RATE;
|
|
|
|
|
}
|
|
|
|
|
if (format.containsKey(MediaFormat.KEY_BIT_RATE)) {
|
|
|
|
|
bitRate = format.getInteger(MediaFormat.KEY_BIT_RATE);
|
|
|
|
|
} else if (bitRate <= 0) {
|
|
|
|
|
if (mime.contains("video/3gpp") ||
|
|
|
|
|
mime.contains("video/mp4v-es")) {
|
|
|
|
|
bitRate = ENCODE_MIN_BIT_RATE;
|
|
|
|
|
} else {
|
|
|
|
|
bitRate = ENCODE_DEFAULT_BIT_RATE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (format.containsKey(MediaFormat.KEY_PROFILE)) {
|
|
|
|
|
profile = format.getInteger(MediaFormat.KEY_PROFILE);
|
|
|
|
|
}
|
|
|
|
|
if (format.containsKey(MediaFormat.KEY_PROFILE)) {
|
|
|
|
|
level = format.getInteger(MediaFormat.KEY_LEVEL);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
|
|
|
|
|
numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
|
|
|
|
|
bitRate = sampleRate * numChannels * 16;
|
|
|
|
|
}
|
|
|
|
|
/*Setup Encode Format*/
|
|
|
|
|
MediaFormat encodeFormat;
|
|
|
|
|
if (mime.startsWith("video/")) {
|
|
|
|
|
frameSize = width * height * 3 / 2;
|
|
|
|
|
encodeFormat = MediaFormat.createVideoFormat(mime, width, height);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_PROFILE, profile);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_LEVEL, level);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, frameSize);
|
|
|
|
|
if (format.containsKey(MediaFormat.KEY_BIT_RATE)) {
|
|
|
|
|
bitRate = format.getInteger(MediaFormat.KEY_BIT_RATE);
|
|
|
|
|
} else if (bitRate <= 0) {
|
|
|
|
|
if (mime.contains("video/3gpp") || mime.contains("video/mp4v-es")) {
|
|
|
|
|
bitRate = ENCODE_MIN_BIT_RATE;
|
|
|
|
|
} else {
|
|
|
|
|
encodeFormat = MediaFormat
|
|
|
|
|
.createAudioFormat(mime, sampleRate, numChannels);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
|
|
|
|
|
frameSize = 4096;
|
|
|
|
|
}
|
|
|
|
|
Encoder encoder = new Encoder();
|
|
|
|
|
encoder.setupEncoder(encodeOutputStream, eleStream);
|
|
|
|
|
status = encoder.encode(codecName, encodeFormat, mime, frameRate,
|
|
|
|
|
sampleRate, frameSize, asyncMode);
|
|
|
|
|
encoder.deInitEncoder();
|
|
|
|
|
if (status == 0) {
|
|
|
|
|
encoder.dumpStatistics(mInputFile + "with " + codecName + " for " +
|
|
|
|
|
"aSyncMode = " + asyncMode, extractor.getClipDuration());
|
|
|
|
|
Log.i(TAG, "Encoding complete for file: " + mInputFile +
|
|
|
|
|
" with codec: " + codecName + " for aSyncMode = " +
|
|
|
|
|
asyncMode);
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG,
|
|
|
|
|
codecName + " encoder returned error " + status + " for " +
|
|
|
|
|
"file:" + " " + mInputFile);
|
|
|
|
|
}
|
|
|
|
|
encoder.resetEncoder();
|
|
|
|
|
eleStream.close();
|
|
|
|
|
if (encodeOutputStream != null) {
|
|
|
|
|
encodeOutputStream.close();
|
|
|
|
|
bitRate = ENCODE_DEFAULT_BIT_RATE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (format.containsKey(MediaFormat.KEY_PROFILE)) {
|
|
|
|
|
profile = format.getInteger(MediaFormat.KEY_PROFILE);
|
|
|
|
|
}
|
|
|
|
|
if (format.containsKey(MediaFormat.KEY_PROFILE)) {
|
|
|
|
|
level = format.getInteger(MediaFormat.KEY_LEVEL);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
|
|
|
|
|
numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
|
|
|
|
|
bitRate = sampleRate * numChannels * 16;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//Cleanup temporary input file
|
|
|
|
|
if (decodedFile.exists()) {
|
|
|
|
|
if (decodedFile.delete()) {
|
|
|
|
|
Log.i(TAG, "Successfully deleted decoded file");
|
|
|
|
|
/*Setup Encode Format*/
|
|
|
|
|
MediaFormat encodeFormat;
|
|
|
|
|
if (mime.startsWith("video/")) {
|
|
|
|
|
frameSize = width * height * 3 / 2;
|
|
|
|
|
encodeFormat = MediaFormat.createVideoFormat(mime, width, height);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_PROFILE, profile);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_LEVEL, level);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, frameSize);
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "Unable to delete decoded file");
|
|
|
|
|
encodeFormat = MediaFormat.createAudioFormat(mime, sampleRate, numChannels);
|
|
|
|
|
encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
|
|
|
|
|
frameSize = 4096;
|
|
|
|
|
}
|
|
|
|
|
Encoder encoder = new Encoder();
|
|
|
|
|
encoder.setupEncoder(encodeOutputStream, eleStream);
|
|
|
|
|
status = encoder.encode(codecName, encodeFormat, mime, frameRate, sampleRate,
|
|
|
|
|
frameSize, asyncMode);
|
|
|
|
|
encoder.deInitEncoder();
|
|
|
|
|
assertEquals(
|
|
|
|
|
codecName + " encoder returned error " + status + " for " + "file:" +
|
|
|
|
|
" " + mInputFile, 0, status);
|
|
|
|
|
encoder.dumpStatistics(
|
|
|
|
|
mInputFile + "with " + codecName + " for " + "aSyncMode = " + asyncMode,
|
|
|
|
|
extractor.getClipDuration());
|
|
|
|
|
Log.i(TAG, "Encoding complete for file: " + mInputFile + " with codec: " +
|
|
|
|
|
codecName + " for aSyncMode = " + asyncMode);
|
|
|
|
|
encoder.resetEncoder();
|
|
|
|
|
eleStream.close();
|
|
|
|
|
if (encodeOutputStream != null) {
|
|
|
|
|
encodeOutputStream.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
extractor.deinitExtractor();
|
|
|
|
|
fileInput.close();
|
|
|
|
|
} else {
|
|
|
|
|
Log.w(TAG, "Warning: Test Skipped. Cannot find " + mInputFile + " in directory " +
|
|
|
|
|
mInputFilePath);
|
|
|
|
|
//Cleanup temporary input file
|
|
|
|
|
if (decodedFile.exists()) {
|
|
|
|
|
assertTrue(" Unable to delete decoded file" + decodedFile.toString(),
|
|
|
|
|
decodedFile.delete());
|
|
|
|
|
Log.i(TAG, "Successfully deleted decoded file");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
extractor.deinitExtractor();
|
|
|
|
|
fileInput.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@ -274,7 +249,6 @@ public class EncoderTest {
|
|
|
|
|
File inputFile = new File(mInputFilePath + mInputFile);
|
|
|
|
|
assertTrue("Cannot find " + mInputFile + " in directory " + mInputFilePath,
|
|
|
|
|
inputFile.exists());
|
|
|
|
|
int status = -1;
|
|
|
|
|
int tid = android.os.Process.myTid();
|
|
|
|
|
final String mDecodedFile = mContext.getFilesDir() + "/decoder_" + tid + ".out";
|
|
|
|
|
FileInputStream fileInput = new FileInputStream(inputFile);
|
|
|
|
@ -290,20 +264,18 @@ public class EncoderTest {
|
|
|
|
|
// Encoding the decoder's output
|
|
|
|
|
for (String codecName : mediaCodecs) {
|
|
|
|
|
Native nativeEncoder = new Native();
|
|
|
|
|
status = nativeEncoder.Encode(mInputFilePath, mInputFile, mDecodedFile, codecName);
|
|
|
|
|
assertTrue(
|
|
|
|
|
codecName + " encoder returned error " + status + " for file:" + mInputFile,
|
|
|
|
|
status == 0);
|
|
|
|
|
int status =
|
|
|
|
|
nativeEncoder.Encode(mInputFilePath, mInputFile, mDecodedFile, codecName);
|
|
|
|
|
assertEquals(
|
|
|
|
|
codecName + " encoder returned error " + status + " for " + "file:" + " " +
|
|
|
|
|
mInputFile, 0, status);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
File decodedFile = new File(mDecodedFile);
|
|
|
|
|
// Cleanup temporary input file
|
|
|
|
|
if (decodedFile.exists()) {
|
|
|
|
|
if (decodedFile.delete()) {
|
|
|
|
|
Log.i(TAG, "Successfully deleted - " + mDecodedFile);
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "Unable to delete - " + mDecodedFile);
|
|
|
|
|
}
|
|
|
|
|
assertTrue("Unable to delete - " + mDecodedFile, decodedFile.delete());
|
|
|
|
|
Log.i(TAG, "Successfully deleted - " + mDecodedFile);
|
|
|
|
|
}
|
|
|
|
|
fileInput.close();
|
|
|
|
|
}
|
|
|
|
|