Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: media/base/android/media_codec_bridge.cc

Issue 16114009: Add AAC codec specific data for MSE on android (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "media/base/android/media_codec_bridge.h" 5 #include "media/base/android/media_codec_bridge.h"
6 6
7 #include <jni.h> 7 #include <jni.h>
8 8
9 #include "base/android/build_info.h" 9 #include "base/android/build_info.h"
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 JNIEnv* env = AttachCurrentThread(); 186 JNIEnv* env = AttachCurrentThread();
187 DCHECK(AudioCodecToMimeType(codec)); 187 DCHECK(AudioCodecToMimeType(codec));
188 188
189 ScopedJavaLocalRef<jstring> j_mime = 189 ScopedJavaLocalRef<jstring> j_mime =
190 ConvertUTF8ToJavaString(env, AudioCodecToMimeType(codec)); 190 ConvertUTF8ToJavaString(env, AudioCodecToMimeType(codec));
191 ScopedJavaLocalRef<jobject> j_format( 191 ScopedJavaLocalRef<jobject> j_format(
192 Java_MediaCodecBridge_createAudioFormat( 192 Java_MediaCodecBridge_createAudioFormat(
193 env, j_mime.obj(), sample_rate, channel_count)); 193 env, j_mime.obj(), sample_rate, channel_count));
194 DCHECK(!j_format.is_null()); 194 DCHECK(!j_format.is_null());
195 195
196 if (extra_data_size > 0) { 196 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size))
197 DCHECK_EQ(kCodecVorbis, codec); 197 return false;
198 if (extra_data[0] != 2) {
199 LOG(ERROR) << "Invalid number of headers before the codec header: "
200 << extra_data[0];
201 return false;
202 }
203
204 size_t header_length[2];
205 // |total_length| keeps track of the total number of bytes before the last
206 // header.
207 size_t total_length = 1;
208 const uint8* current_pos = extra_data;
209 // Calculate the length of the first 2 headers.
210 for (int i = 0; i < 2; ++i) {
211 header_length[i] = 0;
212 while (total_length < extra_data_size) {
213 size_t size = *(++current_pos);
214 total_length += 1 + size;
215 if (total_length > 0x80000000) {
216 LOG(ERROR) << "Header size too large";
217 return false;
218 }
219 header_length[i] += size;
220 if (size < 0xFF)
221 break;
222 }
223 if (total_length >= extra_data_size) {
224 LOG(ERROR) << "Invalid header size in the extra data";
225 return false;
226 }
227 }
228 current_pos++;
229 // The first header is identification header.
230 jobject identification_header = env->NewDirectByteBuffer(
231 const_cast<uint8*>(current_pos), header_length[0]);
232 Java_MediaCodecBridge_setCodecSpecificData(
233 env, j_format.obj(), 0, identification_header);
234 // The last header is codec header.
235 jobject codec_header = env->NewDirectByteBuffer(
236 const_cast<uint8*>(extra_data + total_length),
237 extra_data_size - total_length);
238 Java_MediaCodecBridge_setCodecSpecificData(
239 env, j_format.obj(), 1, codec_header);
240 env->DeleteLocalRef(codec_header);
241 env->DeleteLocalRef(identification_header);
242 }
243 198
244 Java_MediaCodecBridge_configureAudio( 199 Java_MediaCodecBridge_configureAudio(
245 env, media_codec(), j_format.obj(), NULL, 0, play_audio); 200 env, media_codec(), j_format.obj(), NULL, 0, play_audio);
246 StartInternal(); 201 StartInternal();
247 return true; 202 return true;
248 } 203 }
249 204
205 bool AudioCodecBridge::ConfigureMediaFormat(
206 jobject j_format, const AudioCodec codec, const uint8* extra_data,
207 size_t extra_data_size) {
208 if (extra_data_size == 0)
209 return true;
210
211 JNIEnv* env = AttachCurrentThread();
212 switch(codec) {
213 case kCodecVorbis:
214 {
215 if (extra_data[0] != 2) {
216 LOG(ERROR) << "Invalid number of vorbis headers before the codec "
217 << "header: " << extra_data[0];
218 return false;
219 }
220
221 size_t header_length[2];
222 // |total_length| keeps track of the total number of bytes before the last
223 // header.
224 size_t total_length = 1;
225 const uint8* current_pos = extra_data;
226 // Calculate the length of the first 2 headers.
227 for (int i = 0; i < 2; ++i) {
228 header_length[i] = 0;
229 while (total_length < extra_data_size) {
230 size_t size = *(++current_pos);
231 total_length += 1 + size;
232 if (total_length > 0x80000000) {
233 LOG(ERROR) << "Vorbis header size too large";
234 return false;
235 }
236 header_length[i] += size;
237 if (size < 0xFF)
238 break;
239 }
240 if (total_length >= extra_data_size) {
241 LOG(ERROR) << "Invalid vorbis header size in the extra data";
242 return false;
243 }
244 }
245 current_pos++;
246 // The first header is identification header.
247 jobject identification_header = env->NewDirectByteBuffer(
248 const_cast<uint8*>(current_pos), header_length[0]);
249 Java_MediaCodecBridge_setCodecSpecificData(
250 env, j_format, 0, identification_header);
251 // The last header is codec header.
252 jobject codec_header = env->NewDirectByteBuffer(
253 const_cast<uint8*>(extra_data + total_length),
254 extra_data_size - total_length);
255 Java_MediaCodecBridge_setCodecSpecificData(
256 env, j_format, 1, codec_header);
257 env->DeleteLocalRef(codec_header);
258 env->DeleteLocalRef(identification_header);
259 break;
260 }
261 case kCodecAAC:
262 {
263 DCHECK_EQ(2u, extra_data_size);
264 jobject header = env->NewDirectByteBuffer(
265 const_cast<uint8*>(extra_data), extra_data_size);
266 Java_MediaCodecBridge_setCodecSpecificData(
267 env, j_format, 0, header);
268 // TODO(qinmin): pass an extra variable to this function to determine
269 // whether we need to call this.
270 Java_MediaCodecBridge_setFrameHasADTSHeader(env, j_format);
271 env->DeleteLocalRef(header);
272 break;
273 }
274 default:
275 LOG(ERROR) << "Invalid header encountered for codec: "
276 << AudioCodecToMimeType(codec);
277 return false;
278 }
279 return true;
280 }
281
250 void AudioCodecBridge::PlayOutputBuffer(int index, size_t size) { 282 void AudioCodecBridge::PlayOutputBuffer(int index, size_t size) {
251 DCHECK_LE(0, index); 283 DCHECK_LE(0, index);
252 int numBytes = base::checked_numeric_cast<int>(size); 284 int numBytes = base::checked_numeric_cast<int>(size);
253 JNIEnv* env = AttachCurrentThread(); 285 JNIEnv* env = AttachCurrentThread();
254 ScopedJavaLocalRef<jobject> buf = 286 ScopedJavaLocalRef<jobject> buf =
255 Java_MediaCodecBridge_getOutputBuffer(env, media_codec(), index); 287 Java_MediaCodecBridge_getOutputBuffer(env, media_codec(), index);
256 uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(buf.obj())); 288 uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(buf.obj()));
257 289
258 ScopedJavaLocalRef<jbyteArray> byte_array = 290 ScopedJavaLocalRef<jbyteArray> byte_array =
259 base::android::ToJavaByteArray(env, buffer, numBytes); 291 base::android::ToJavaByteArray(env, buffer, numBytes);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 const char* mime = VideoCodecToMimeType(codec); 323 const char* mime = VideoCodecToMimeType(codec);
292 return mime ? new VideoCodecBridge(mime) : NULL; 324 return mime ? new VideoCodecBridge(mime) : NULL;
293 } 325 }
294 326
295 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { 327 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) {
296 return RegisterNativesImpl(env); 328 return RegisterNativesImpl(env);
297 } 329 }
298 330
299 } // namespace media 331 } // namespace media
300 332
OLDNEW
« no previous file with comments | « media/base/android/media_codec_bridge.h ('k') | media/mp4/aac.h » ('j') | media/mp4/aac.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698