Если да, будет ли вывод декодера MediaFormat
из 2. c будет таким же, как для входа кодировщика MediaFormat
?
public class AudioUtil {
private static String TAG = AudioUtil.class.getSimpleName();
static final String CODEC_SPECIFIC_DATA_BUFFER_0 = "csd-0";
static final String CODEC_SPECIFIC_DATA_BUFFER_1 = "csd-1";
static final String CODEC_SPECIFIC_DATA_BUFFER_2 = "csd-2";
public void audioTestMethod(String path) throws IOException {
final MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(path);
int numTracks = extractor.getTrackCount();
int sampleRate = 0;
int channel = 0;
MediaFormat inputAudioFormat = null;
for (int i = 0; i < numTracks; ++i) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = getMimeTypeFrom(format);
if (mime.startsWith("audio/"))
{
extractor.selectTrack(i);
logCodecSpecificData(format);
sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
channel = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
inputAudioFormat = format;
break;
}
}
if(inputAudioFormat == null){
return;
}
final MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFrom(inputAudioFormat));
decoder.configure(inputAudioFormat, null, null, 0);
MediaFormat outputAudioFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, sampleRate, channel);
outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE);
//outputAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_AUDIO_BIT_RATE);
final MediaCodec encoder = MediaCodec.createEncoderByType(getMimeTypeFrom(outputAudioFormat));
encoder.configure(outputAudioFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
final long TIMEOUT_USEC = 1000;
decoder.setCallback(new MediaCodec.Callback() {
@Override
public void onInputBufferAvailable(@NonNull MediaCodec mediaCodec, int inputBufferId) {
if(!extractor.hasCacheReachedEndOfStream()){
ByteBuffer inputBuffer = decoder.getInputBuffer(inputBufferId);
inputBuffer.clear();
int size = extractor.readSampleData(inputBuffer, 0);
long presentationTime = extractor.getSampleTime();
int flags = extractor.getSampleFlags();
decoder.queueInputBuffer(inputBufferId, 0, size, presentationTime, flags);
}
else{
decoder.queueInputBuffer(inputBufferId, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
}
}
@Override
public void onOutputBufferAvailable(@NonNull MediaCodec mediaCodec, int outputBufferId, @NonNull MediaCodec.BufferInfo bufferInfo) {
boolean render = bufferInfo.size != 0;
if((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
encoder.signalEndOfInputStream();
decoder.releaseOutputBuffer(outputBufferId, render);
}
else if((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0){
decoder.releaseOutputBuffer(outputBufferId, false);
}
else{
decoder.releaseOutputBuffer(outputBufferId, render);
}
}
@Override
public void onError(@NonNull MediaCodec mediaCodec, @NonNull MediaCodec.CodecException e) {
}
@Override
public void onOutputFormatChanged(@NonNull MediaCodec mediaCodec, @NonNull MediaFormat mediaFormat) {
}
});
encoder.setCallback(new MediaCodec.Callback() {
@Override
public void onInputBufferAvailable(@NonNull MediaCodec mediaCodec, int i) {
}
@Override
public void onOutputBufferAvailable(@NonNull MediaCodec mediaCodec, int i, @NonNull MediaCodec.BufferInfo bufferInfo) {
}
@Override
public void onError(@NonNull MediaCodec mediaCodec, @NonNull MediaCodec.CodecException e) {
}
@Override
public void onOutputFormatChanged(@NonNull MediaCodec mediaCodec, @NonNull MediaFormat mediaFormat) {
}
});
decoder.start();
encoder.start();
while(!extractor.hasCacheReachedEndOfStream())
{
}
decoder.stop();
decoder.release();
//decoder = null;
encoder.start();
encoder.release();
//encoder = null;
extractor.release();
//extractor = null;
}
private String getMimeTypeFrom(MediaFormat format) {
return format.getString(MediaFormat.KEY_MIME);
}
private void logCodecSpecificData(MediaFormat format) {
ByteBuffer codecSpecificDataBuffer = format.getByteBuffer(CODEC_SPECIFIC_DATA_BUFFER_0);
for (int k = 0; k < codecSpecificDataBuffer.capacity(); ++k) {
Log.e(TAG, "csd : " + codecSpecificDataBuffer.array()[k]);
}
}
}