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 #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 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/android/build_info.h" | 10 #include "base/android/build_info.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 Java_MediaCodecBridge_stop(env, j_media_codec_.obj()); | 121 Java_MediaCodecBridge_stop(env, j_media_codec_.obj()); |
122 } | 122 } |
123 | 123 |
124 void MediaCodecBridge::GetOutputFormat(int* width, int* height) { | 124 void MediaCodecBridge::GetOutputFormat(int* width, int* height) { |
125 JNIEnv* env = AttachCurrentThread(); | 125 JNIEnv* env = AttachCurrentThread(); |
126 | 126 |
127 *width = Java_MediaCodecBridge_getOutputWidth(env, j_media_codec_.obj()); | 127 *width = Java_MediaCodecBridge_getOutputWidth(env, j_media_codec_.obj()); |
128 *height = Java_MediaCodecBridge_getOutputHeight(env, j_media_codec_.obj()); | 128 *height = Java_MediaCodecBridge_getOutputHeight(env, j_media_codec_.obj()); |
129 } | 129 } |
130 | 130 |
131 size_t MediaCodecBridge::QueueInputBuffer( | 131 MediaCodecStatus MediaCodecBridge::QueueInputBuffer( |
132 int index, const uint8* data, int size, | 132 int index, const uint8* data, int data_size, |
133 const base::TimeDelta& presentation_time) { | 133 const base::TimeDelta& presentation_time) { |
134 size_t size_to_copy = FillInputBuffer(index, data, size); | 134 int size_to_copy = FillInputBuffer(index, data, data_size); |
| 135 DCHECK_EQ(size_to_copy, data_size); |
135 JNIEnv* env = AttachCurrentThread(); | 136 JNIEnv* env = AttachCurrentThread(); |
136 Java_MediaCodecBridge_queueInputBuffer( | 137 return static_cast<MediaCodecStatus>(Java_MediaCodecBridge_queueInputBuffer( |
137 env, j_media_codec_.obj(), | 138 env, j_media_codec_.obj(), |
138 index, 0, size_to_copy, presentation_time.InMicroseconds(), 0); | 139 index, 0, size_to_copy, presentation_time.InMicroseconds(), 0)); |
139 return size_to_copy; | |
140 } | 140 } |
141 | 141 |
142 size_t MediaCodecBridge::QueueSecureInputBuffer( | 142 MediaCodecStatus MediaCodecBridge::QueueSecureInputBuffer( |
143 int index, const uint8* data, int data_size, const uint8* key_id, | 143 int index, const uint8* data, int data_size, const uint8* key_id, |
144 int key_id_size, const uint8* iv, int iv_size, | 144 int key_id_size, const uint8* iv, int iv_size, |
145 const SubsampleEntry* subsamples, int subsamples_size, | 145 const SubsampleEntry* subsamples, int subsamples_size, |
146 const base::TimeDelta& presentation_time) { | 146 const base::TimeDelta& presentation_time) { |
147 size_t size_to_copy = FillInputBuffer(index, data, data_size); | 147 int size_to_copy = FillInputBuffer(index, data, data_size); |
| 148 DCHECK_EQ(size_to_copy, data_size); |
148 | 149 |
149 JNIEnv* env = AttachCurrentThread(); | 150 JNIEnv* env = AttachCurrentThread(); |
150 ScopedJavaLocalRef<jbyteArray> j_key_id = | 151 ScopedJavaLocalRef<jbyteArray> j_key_id = |
151 base::android::ToJavaByteArray(env, key_id, key_id_size); | 152 base::android::ToJavaByteArray(env, key_id, key_id_size); |
152 ScopedJavaLocalRef<jbyteArray> j_iv = | 153 ScopedJavaLocalRef<jbyteArray> j_iv = |
153 base::android::ToJavaByteArray(env, iv, iv_size); | 154 base::android::ToJavaByteArray(env, iv, iv_size); |
154 scoped_ptr<jint[]> native_clear_array(new jint[subsamples_size]); | 155 scoped_ptr<jint[]> native_clear_array(new jint[subsamples_size]); |
155 scoped_ptr<jint[]> native_cypher_array(new jint[subsamples_size]); | 156 scoped_ptr<jint[]> native_cypher_array(new jint[subsamples_size]); |
156 for (int i = 0; i < subsamples_size; ++i) { | 157 for (int i = 0; i < subsamples_size; ++i) { |
157 native_clear_array[i] = subsamples[i].clear_bytes; | 158 native_clear_array[i] = subsamples[i].clear_bytes; |
158 native_cypher_array[i] = subsamples[i].cypher_bytes; | 159 native_cypher_array[i] = subsamples[i].cypher_bytes; |
159 } | 160 } |
160 ScopedJavaLocalRef<jintArray> clear_array = ToJavaIntArray( | 161 ScopedJavaLocalRef<jintArray> clear_array = ToJavaIntArray( |
161 env, native_clear_array.Pass(), subsamples_size); | 162 env, native_clear_array.Pass(), subsamples_size); |
162 ScopedJavaLocalRef<jintArray> cypher_array = ToJavaIntArray( | 163 ScopedJavaLocalRef<jintArray> cypher_array = ToJavaIntArray( |
163 env, native_cypher_array.Pass(), subsamples_size); | 164 env, native_cypher_array.Pass(), subsamples_size); |
164 | 165 |
165 Java_MediaCodecBridge_queueSecureInputBuffer( | 166 return static_cast<MediaCodecStatus>( |
166 env, j_media_codec_.obj(), index, 0, j_iv.obj(), j_key_id.obj(), | 167 Java_MediaCodecBridge_queueSecureInputBuffer( |
167 clear_array.obj(), cypher_array.obj(), subsamples_size, | 168 env, j_media_codec_.obj(), index, 0, j_iv.obj(), j_key_id.obj(), |
168 presentation_time.InMicroseconds()); | 169 clear_array.obj(), cypher_array.obj(), subsamples_size, |
169 | 170 presentation_time.InMicroseconds())); |
170 return size_to_copy; | |
171 } | 171 } |
172 | 172 |
173 void MediaCodecBridge::QueueEOS(int input_buffer_index) { | 173 void MediaCodecBridge::QueueEOS(int input_buffer_index) { |
174 JNIEnv* env = AttachCurrentThread(); | 174 JNIEnv* env = AttachCurrentThread(); |
175 Java_MediaCodecBridge_queueInputBuffer( | 175 Java_MediaCodecBridge_queueInputBuffer( |
176 env, j_media_codec_.obj(), | 176 env, j_media_codec_.obj(), |
177 input_buffer_index, 0, 0, 0, kBufferFlagEndOfStream); | 177 input_buffer_index, 0, 0, 0, kBufferFlagEndOfStream); |
178 } | 178 } |
179 | 179 |
180 MediaCodecStatus MediaCodecBridge::DequeueInputBuffer( | 180 MediaCodecStatus MediaCodecBridge::DequeueInputBuffer( |
181 const base::TimeDelta& timeout, int* index) { | 181 const base::TimeDelta& timeout, int* index) { |
182 JNIEnv* env = AttachCurrentThread(); | 182 JNIEnv* env = AttachCurrentThread(); |
183 int result = Java_MediaCodecBridge_dequeueInputBuffer( | 183 ScopedJavaLocalRef<jobject> result = Java_MediaCodecBridge_dequeueInputBuffer( |
184 env, j_media_codec_.obj(), timeout.InMicroseconds()); | 184 env, j_media_codec_.obj(), timeout.InMicroseconds()); |
185 if (result == INFO_MEDIA_CODEC_ERROR) | 185 *index = Java_DequeueInputResult_index(env, result.obj()); |
186 return MEDIA_CODEC_ERROR; | 186 return static_cast<MediaCodecStatus>( |
187 else if (result == INFO_TRY_AGAIN_LATER) | 187 Java_DequeueInputResult_status(env, result.obj())); |
188 return MEDIA_CODEC_ENQUEUE_INPUT_AGAIN_LATER; | |
189 | |
190 DCHECK_GE(result, 0); | |
191 *index = result; | |
192 return MEDIA_CODEC_OK; | |
193 } | 188 } |
194 | 189 |
195 MediaCodecStatus MediaCodecBridge::DequeueOutputBuffer( | 190 MediaCodecStatus MediaCodecBridge::DequeueOutputBuffer( |
196 const base::TimeDelta& timeout, int* index, size_t* offset, size_t* size, | 191 const base::TimeDelta& timeout, int* index, size_t* offset, size_t* size, |
197 base::TimeDelta* presentation_time, bool* end_of_stream) { | 192 base::TimeDelta* presentation_time, bool* end_of_stream) { |
198 JNIEnv* env = AttachCurrentThread(); | 193 JNIEnv* env = AttachCurrentThread(); |
199 | |
200 ScopedJavaLocalRef<jobject> result = | 194 ScopedJavaLocalRef<jobject> result = |
201 Java_MediaCodecBridge_dequeueOutputBuffer(env, j_media_codec_.obj(), | 195 Java_MediaCodecBridge_dequeueOutputBuffer(env, j_media_codec_.obj(), |
202 timeout.InMicroseconds()); | 196 timeout.InMicroseconds()); |
203 | 197 *index = Java_DequeueOutputResult_index(env, result.obj());; |
204 int j_index = Java_DequeueOutputResult_index(env, result.obj()); | |
205 switch (j_index) { | |
206 case INFO_OUTPUT_BUFFERS_CHANGED: | |
207 return MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED; | |
208 case INFO_OUTPUT_FORMAT_CHANGED: | |
209 return MEDIA_CODEC_OUTPUT_FORMAT_CHANGED; | |
210 case INFO_TRY_AGAIN_LATER: | |
211 return MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER; | |
212 case INFO_MEDIA_CODEC_ERROR: | |
213 return MEDIA_CODEC_ERROR; | |
214 } | |
215 | |
216 DCHECK_GE(j_index, 0); | |
217 *index = j_index; | |
218 *offset = base::checked_numeric_cast<size_t>( | 198 *offset = base::checked_numeric_cast<size_t>( |
219 Java_DequeueOutputResult_offset(env, result.obj())); | 199 Java_DequeueOutputResult_offset(env, result.obj())); |
220 *size = base::checked_numeric_cast<size_t>( | 200 *size = base::checked_numeric_cast<size_t>( |
221 Java_DequeueOutputResult_numBytes(env, result.obj())); | 201 Java_DequeueOutputResult_numBytes(env, result.obj())); |
222 *presentation_time = base::TimeDelta::FromMicroseconds( | 202 *presentation_time = base::TimeDelta::FromMicroseconds( |
223 Java_DequeueOutputResult_presentationTimeMicroseconds(env, result.obj())); | 203 Java_DequeueOutputResult_presentationTimeMicroseconds(env, result.obj())); |
224 int flags = Java_DequeueOutputResult_flags(env, result.obj()); | 204 int flags = Java_DequeueOutputResult_flags(env, result.obj()); |
225 *end_of_stream = flags & kBufferFlagEndOfStream; | 205 *end_of_stream = flags & kBufferFlagEndOfStream; |
226 return MEDIA_CODEC_OK; | 206 return static_cast<MediaCodecStatus>( |
| 207 Java_DequeueOutputResult_status(env, result.obj())); |
227 } | 208 } |
228 | 209 |
229 void MediaCodecBridge::ReleaseOutputBuffer(int index, bool render) { | 210 void MediaCodecBridge::ReleaseOutputBuffer(int index, bool render) { |
230 JNIEnv* env = AttachCurrentThread(); | 211 JNIEnv* env = AttachCurrentThread(); |
231 CHECK(env); | 212 CHECK(env); |
232 | 213 |
233 Java_MediaCodecBridge_releaseOutputBuffer( | 214 Java_MediaCodecBridge_releaseOutputBuffer( |
234 env, j_media_codec_.obj(), index, render); | 215 env, j_media_codec_.obj(), index, render); |
235 } | 216 } |
236 | 217 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 return true; | 277 return true; |
297 } | 278 } |
298 | 279 |
299 bool AudioCodecBridge::ConfigureMediaFormat( | 280 bool AudioCodecBridge::ConfigureMediaFormat( |
300 jobject j_format, const AudioCodec codec, const uint8* extra_data, | 281 jobject j_format, const AudioCodec codec, const uint8* extra_data, |
301 size_t extra_data_size) { | 282 size_t extra_data_size) { |
302 if (extra_data_size == 0) | 283 if (extra_data_size == 0) |
303 return true; | 284 return true; |
304 | 285 |
305 JNIEnv* env = AttachCurrentThread(); | 286 JNIEnv* env = AttachCurrentThread(); |
306 switch(codec) { | 287 switch (codec) { |
307 case kCodecVorbis: | 288 case kCodecVorbis: |
308 { | 289 { |
309 if (extra_data[0] != 2) { | 290 if (extra_data[0] != 2) { |
310 LOG(ERROR) << "Invalid number of vorbis headers before the codec " | 291 LOG(ERROR) << "Invalid number of vorbis headers before the codec " |
311 << "header: " << extra_data[0]; | 292 << "header: " << extra_data[0]; |
312 return false; | 293 return false; |
313 } | 294 } |
314 | 295 |
315 size_t header_length[2]; | 296 size_t header_length[2]; |
316 // |total_length| keeps track of the total number of bytes before the last | 297 // |total_length| keeps track of the total number of bytes before the last |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 VideoCodecBridge* VideoCodecBridge::Create(const VideoCodec codec) { | 438 VideoCodecBridge* VideoCodecBridge::Create(const VideoCodec codec) { |
458 const std::string mime = VideoCodecToMimeType(codec); | 439 const std::string mime = VideoCodecToMimeType(codec); |
459 return mime.empty() ? NULL : new VideoCodecBridge(mime); | 440 return mime.empty() ? NULL : new VideoCodecBridge(mime); |
460 } | 441 } |
461 | 442 |
462 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { | 443 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { |
463 return RegisterNativesImpl(env); | 444 return RegisterNativesImpl(env); |
464 } | 445 } |
465 | 446 |
466 } // namespace media | 447 } // namespace media |
OLD | NEW |