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 |