| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.media; | 5 package org.chromium.media; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.media.AudioFormat; | 8 import android.media.AudioFormat; |
| 9 import android.media.MediaCodec; | 9 import android.media.MediaCodec; |
| 10 import android.media.MediaCodec.BufferInfo; | 10 import android.media.MediaCodec.BufferInfo; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 return false; | 54 return false; |
| 55 } | 55 } |
| 56 | 56 |
| 57 if (extractor.getTrackCount() <= 0) { | 57 if (extractor.getTrackCount() <= 0) { |
| 58 encodedFD.detachFd(); | 58 encodedFD.detachFd(); |
| 59 return false; | 59 return false; |
| 60 } | 60 } |
| 61 | 61 |
| 62 MediaFormat format = extractor.getTrackFormat(0); | 62 MediaFormat format = extractor.getTrackFormat(0); |
| 63 | 63 |
| 64 int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT); | 64 // Number of channels specified in the file |
| 65 int inputChannelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
; |
| 66 |
| 67 // Number of channels the decoder will provide. (Not |
| 68 // necessarily the same as inputChannelCount. See |
| 69 // crbug.com/266006.) |
| 70 int outputChannelCount = inputChannelCount; |
| 71 |
| 65 int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE); | 72 int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE); |
| 66 String mime = format.getString(MediaFormat.KEY_MIME); | 73 String mime = format.getString(MediaFormat.KEY_MIME); |
| 67 | 74 |
| 68 long durationMicroseconds = 0; | 75 long durationMicroseconds = 0; |
| 69 if (format.containsKey(MediaFormat.KEY_DURATION)) { | 76 if (format.containsKey(MediaFormat.KEY_DURATION)) { |
| 70 try { | 77 try { |
| 71 durationMicroseconds = format.getLong(MediaFormat.KEY_DURATION); | 78 durationMicroseconds = format.getLong(MediaFormat.KEY_DURATION); |
| 72 } catch (Exception e) { | 79 } catch (Exception e) { |
| 73 Log.d(LOG_TAG, "Cannot get duration"); | 80 Log.d(LOG_TAG, "Cannot get duration"); |
| 74 } | 81 } |
| 75 } | 82 } |
| 76 | 83 |
| 77 if (DEBUG) { | 84 if (DEBUG) { |
| 78 Log.d(LOG_TAG, "Tracks: " + extractor.getTrackCount() | 85 Log.d(LOG_TAG, "Tracks: " + extractor.getTrackCount() |
| 79 + " Rate: " + sampleRate | 86 + " Rate: " + sampleRate |
| 80 + " Channels: " + channelCount | 87 + " Channels: " + inputChannelCount |
| 81 + " Mime: " + mime | 88 + " Mime: " + mime |
| 82 + " Duration: " + durationMicroseconds + " microsec"); | 89 + " Duration: " + durationMicroseconds + " microsec"); |
| 83 } | 90 } |
| 84 | 91 |
| 85 nativeInitializeDestination(nativeMediaCodecBridge, | 92 nativeInitializeDestination(nativeMediaCodecBridge, |
| 86 channelCount, | 93 inputChannelCount, |
| 87 sampleRate, | 94 sampleRate, |
| 88 durationMicroseconds); | 95 durationMicroseconds); |
| 89 | 96 |
| 90 // Create decoder | 97 // Create decoder |
| 91 MediaCodec codec = MediaCodec.createDecoderByType(mime); | 98 MediaCodec codec = MediaCodec.createDecoderByType(mime); |
| 92 codec.configure(format, null /* surface */, null /* crypto */, 0 /* flag
s */); | 99 codec.configure(format, null /* surface */, null /* crypto */, 0 /* flag
s */); |
| 93 codec.start(); | 100 codec.start(); |
| 94 | 101 |
| 95 ByteBuffer[] codecInputBuffers = codec.getInputBuffers(); | 102 ByteBuffer[] codecInputBuffers = codec.getInputBuffers(); |
| 96 ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers(); | 103 ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 } | 139 } |
| 133 | 140 |
| 134 // Output side | 141 // Output side |
| 135 MediaCodec.BufferInfo info = new BufferInfo(); | 142 MediaCodec.BufferInfo info = new BufferInfo(); |
| 136 final int outputBufIndex = codec.dequeueOutputBuffer(info, TIMEOUT_M
ICROSECONDS); | 143 final int outputBufIndex = codec.dequeueOutputBuffer(info, TIMEOUT_M
ICROSECONDS); |
| 137 | 144 |
| 138 if (outputBufIndex >= 0) { | 145 if (outputBufIndex >= 0) { |
| 139 ByteBuffer buf = codecOutputBuffers[outputBufIndex]; | 146 ByteBuffer buf = codecOutputBuffers[outputBufIndex]; |
| 140 | 147 |
| 141 if (info.size > 0) { | 148 if (info.size > 0) { |
| 142 nativeOnChunkDecoded(nativeMediaCodecBridge, buf, info.size)
; | 149 nativeOnChunkDecoded(nativeMediaCodecBridge, buf, info.size, |
| 150 inputChannelCount, outputChannelCount); |
| 143 } | 151 } |
| 144 | 152 |
| 145 buf.clear(); | 153 buf.clear(); |
| 146 codec.releaseOutputBuffer(outputBufIndex, false /* render */); | 154 codec.releaseOutputBuffer(outputBufIndex, false /* render */); |
| 147 | 155 |
| 148 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { | 156 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { |
| 149 sawOutputEOS = true; | 157 sawOutputEOS = true; |
| 150 } | 158 } |
| 151 } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{ | 159 } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{ |
| 152 codecOutputBuffers = codec.getOutputBuffers(); | 160 codecOutputBuffers = codec.getOutputBuffers(); |
| 161 } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{ |
| 162 MediaFormat newFormat = codec.getOutputFormat(); |
| 163 outputChannelCount = newFormat.getInteger(MediaFormat.KEY_CHANNE
L_COUNT); |
| 164 Log.d(LOG_TAG, "output format changed to " + newFormat); |
| 153 } | 165 } |
| 154 } | 166 } |
| 155 | 167 |
| 156 encodedFD.detachFd(); | 168 encodedFD.detachFd(); |
| 157 | 169 |
| 158 codec.stop(); | 170 codec.stop(); |
| 159 codec.release(); | 171 codec.release(); |
| 160 codec = null; | 172 codec = null; |
| 161 | 173 |
| 162 return true; | 174 return true; |
| 163 } | 175 } |
| 164 | 176 |
| 165 private static native void nativeOnChunkDecoded( | 177 private static native void nativeOnChunkDecoded( |
| 166 int nativeWebAudioMediaCodecBridge, ByteBuffer buf, int size); | 178 int nativeWebAudioMediaCodecBridge, ByteBuffer buf, int size, |
| 179 int inputChannelCount, int outputChannelCount); |
| 167 | 180 |
| 168 private static native void nativeInitializeDestination( | 181 private static native void nativeInitializeDestination( |
| 169 int nativeWebAudioMediaCodecBridge, | 182 int nativeWebAudioMediaCodecBridge, |
| 170 int channelCount, | 183 int inputChannelCount, |
| 171 int sampleRate, | 184 int sampleRate, |
| 172 long durationMicroseconds); | 185 long durationMicroseconds); |
| 173 } | 186 } |
| OLD | NEW |