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

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

Issue 2697643003: media: Clean up MediaCodecBridge and remove subclasses (Closed)
Patch Set: Remove static initializers (thanks to dale's suggestion) Created 3 years, 10 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
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_impl.h" 5 #include "media/base/android/media_codec_bridge_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/android/build_info.h" 12 #include "base/android/build_info.h"
13 #include "base/android/jni_android.h" 13 #include "base/android/jni_android.h"
14 #include "base/android/jni_array.h" 14 #include "base/android/jni_array.h"
15 #include "base/android/jni_string.h" 15 #include "base/android/jni_string.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/ptr_util.h"
17 #include "base/numerics/safe_conversions.h" 18 #include "base/numerics/safe_conversions.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "jni/MediaCodecBridge_jni.h" 20 #include "jni/MediaCodecBridge_jni.h"
20 #include "media/base/android/media_codec_util.h" 21 #include "media/base/android/media_codec_util.h"
22 #include "media/base/audio_codecs.h"
21 #include "media/base/bit_reader.h" 23 #include "media/base/bit_reader.h"
22 #include "media/base/subsample_entry.h" 24 #include "media/base/subsample_entry.h"
25 #include "media/base/video_codecs.h"
23 26
24 using base::android::AttachCurrentThread; 27 using base::android::AttachCurrentThread;
25 using base::android::ConvertJavaStringToUTF8; 28 using base::android::ConvertJavaStringToUTF8;
26 using base::android::ConvertUTF8ToJavaString; 29 using base::android::ConvertUTF8ToJavaString;
27 using base::android::JavaIntArrayToIntVector; 30 using base::android::JavaIntArrayToIntVector;
28 using base::android::ScopedJavaLocalRef; 31 using base::android::ScopedJavaLocalRef;
29 32
30 #define RETURN_ON_ERROR(condition) \ 33 #define RETURN_ON_ERROR(condition) \
31 do { \ 34 do { \
32 if (!(condition)) { \ 35 if (!(condition)) { \
33 LOG(ERROR) << "Unable to parse AAC header: " #condition; \ 36 LOG(ERROR) << "Unable to parse AAC header: " #condition; \
34 return false; \ 37 return false; \
35 } \ 38 } \
36 } while (0) 39 } while (0)
37 40
38 namespace media { 41 namespace media {
39 namespace { 42 namespace {
40 43
41 enum { 44 enum {
42 kBufferFlagSyncFrame = 1, // BUFFER_FLAG_SYNC_FRAME 45 kBufferFlagSyncFrame = 1, // BUFFER_FLAG_SYNC_FRAME
43 kBufferFlagEndOfStream = 4, // BUFFER_FLAG_END_OF_STREAM 46 kBufferFlagEndOfStream = 4, // BUFFER_FLAG_END_OF_STREAM
44 kConfigureFlagEncode = 1, // CONFIGURE_FLAG_ENCODE 47 kConfigureFlagEncode = 1, // CONFIGURE_FLAG_ENCODE
45 }; 48 };
46 49
47 const std::string AudioCodecToAndroidMimeType(const AudioCodec& codec) {
48 switch (codec) {
49 case kCodecMP3:
50 return "audio/mpeg";
51 case kCodecVorbis:
52 return "audio/vorbis";
53 case kCodecOpus:
54 return "audio/opus";
55 case kCodecAAC:
56 return "audio/mp4a-latm";
57 case kCodecAC3:
58 return "audio/ac3";
59 case kCodecEAC3:
60 return "audio/eac3";
61 default:
62 return std::string();
63 }
64 }
65
66 const std::string VideoCodecToAndroidMimeType(const VideoCodec& codec) {
67 switch (codec) {
68 case kCodecH264:
69 return "video/avc";
70 case kCodecHEVC:
71 return "video/hevc";
72 case kCodecVP8:
73 return "video/x-vnd.on2.vp8";
74 case kCodecVP9:
75 return "video/x-vnd.on2.vp9";
76 default:
77 return std::string();
78 }
79 }
80
81 static ScopedJavaLocalRef<jintArray> 50 static ScopedJavaLocalRef<jintArray>
82 ToJavaIntArray(JNIEnv* env, std::unique_ptr<jint[]> native_array, int size) { 51 ToJavaIntArray(JNIEnv* env, std::unique_ptr<jint[]> native_array, int size) {
83 ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size)); 52 ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size));
84 env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get()); 53 env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get());
85 return j_array; 54 return j_array;
86 } 55 }
87 56
88 } // namespace 57 } // namespace
89 58
90 MediaCodecBridgeImpl::MediaCodecBridgeImpl(const std::string& mime, 59 MediaCodecBridgeImpl::MediaCodecBridgeImpl(const std::string& mime,
91 bool is_secure, 60 bool is_secure,
92 MediaCodecDirection direction, 61 MediaCodecDirection direction,
93 bool require_software_codec) { 62 bool require_software_codec) {
94 JNIEnv* env = AttachCurrentThread(); 63 JNIEnv* env = AttachCurrentThread();
95 DCHECK(!mime.empty()); 64 DCHECK(!mime.empty());
96 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 65 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
97 j_media_codec_.Reset(Java_MediaCodecBridge_create( 66 j_bridge_.Reset(Java_MediaCodecBridge_create(env, j_mime, is_secure,
98 env, j_mime, is_secure, direction, require_software_codec)); 67 static_cast<int>(direction),
68 require_software_codec));
99 } 69 }
100 70
101 MediaCodecBridgeImpl::~MediaCodecBridgeImpl() { 71 MediaCodecBridgeImpl::~MediaCodecBridgeImpl() {
102 JNIEnv* env = AttachCurrentThread(); 72 JNIEnv* env = AttachCurrentThread();
103 if (j_media_codec_.obj()) 73 if (j_bridge_.obj())
104 Java_MediaCodecBridge_release(env, j_media_codec_); 74 Java_MediaCodecBridge_release(env, j_bridge_);
105 } 75 }
106 76
107 bool MediaCodecBridgeImpl::Start() { 77 bool MediaCodecBridgeImpl::Start() {
108 JNIEnv* env = AttachCurrentThread(); 78 JNIEnv* env = AttachCurrentThread();
109 return Java_MediaCodecBridge_start(env, j_media_codec_); 79 return Java_MediaCodecBridge_start(env, j_bridge_);
110 } 80 }
111 81
112 void MediaCodecBridgeImpl::Stop() { 82 void MediaCodecBridgeImpl::Stop() {
113 JNIEnv* env = AttachCurrentThread(); 83 JNIEnv* env = AttachCurrentThread();
114 Java_MediaCodecBridge_stop(env, j_media_codec_); 84 Java_MediaCodecBridge_stop(env, j_bridge_);
115 } 85 }
116 86
117 MediaCodecStatus MediaCodecBridgeImpl::Flush() { 87 MediaCodecStatus MediaCodecBridgeImpl::Flush() {
118 JNIEnv* env = AttachCurrentThread(); 88 JNIEnv* env = AttachCurrentThread();
119 return static_cast<MediaCodecStatus>( 89 return static_cast<MediaCodecStatus>(
120 Java_MediaCodecBridge_flush(env, j_media_codec_)); 90 Java_MediaCodecBridge_flush(env, j_bridge_));
121 } 91 }
122 92
123 MediaCodecStatus MediaCodecBridgeImpl::GetOutputSize(gfx::Size* size) { 93 MediaCodecStatus MediaCodecBridgeImpl::GetOutputSize(gfx::Size* size) {
124 JNIEnv* env = AttachCurrentThread(); 94 JNIEnv* env = AttachCurrentThread();
125 ScopedJavaLocalRef<jobject> result = 95 ScopedJavaLocalRef<jobject> result =
126 Java_MediaCodecBridge_getOutputFormat(env, j_media_codec_); 96 Java_MediaCodecBridge_getOutputFormat(env, j_bridge_);
127 MediaCodecStatus status = static_cast<MediaCodecStatus>( 97 MediaCodecStatus status = static_cast<MediaCodecStatus>(
128 Java_GetOutputFormatResult_status(env, result)); 98 Java_GetOutputFormatResult_status(env, result));
129 if (status == MEDIA_CODEC_OK) { 99 if (status == MEDIA_CODEC_OK) {
130 size->SetSize(Java_GetOutputFormatResult_width(env, result), 100 size->SetSize(Java_GetOutputFormatResult_width(env, result),
131 Java_GetOutputFormatResult_height(env, result)); 101 Java_GetOutputFormatResult_height(env, result));
132 } 102 }
133 return status; 103 return status;
134 } 104 }
135 105
136 MediaCodecStatus MediaCodecBridgeImpl::GetOutputSamplingRate( 106 MediaCodecStatus MediaCodecBridgeImpl::GetOutputSamplingRate(
137 int* sampling_rate) { 107 int* sampling_rate) {
138 JNIEnv* env = AttachCurrentThread(); 108 JNIEnv* env = AttachCurrentThread();
139 ScopedJavaLocalRef<jobject> result = 109 ScopedJavaLocalRef<jobject> result =
140 Java_MediaCodecBridge_getOutputFormat(env, j_media_codec_); 110 Java_MediaCodecBridge_getOutputFormat(env, j_bridge_);
141 MediaCodecStatus status = static_cast<MediaCodecStatus>( 111 MediaCodecStatus status = static_cast<MediaCodecStatus>(
142 Java_GetOutputFormatResult_status(env, result)); 112 Java_GetOutputFormatResult_status(env, result));
143 if (status == MEDIA_CODEC_OK) 113 if (status == MEDIA_CODEC_OK)
144 *sampling_rate = Java_GetOutputFormatResult_sampleRate(env, result); 114 *sampling_rate = Java_GetOutputFormatResult_sampleRate(env, result);
145 return status; 115 return status;
146 } 116 }
147 117
148 MediaCodecStatus MediaCodecBridgeImpl::GetOutputChannelCount( 118 MediaCodecStatus MediaCodecBridgeImpl::GetOutputChannelCount(
149 int* channel_count) { 119 int* channel_count) {
150 JNIEnv* env = AttachCurrentThread(); 120 JNIEnv* env = AttachCurrentThread();
151 ScopedJavaLocalRef<jobject> result = 121 ScopedJavaLocalRef<jobject> result =
152 Java_MediaCodecBridge_getOutputFormat(env, j_media_codec_); 122 Java_MediaCodecBridge_getOutputFormat(env, j_bridge_);
153 MediaCodecStatus status = static_cast<MediaCodecStatus>( 123 MediaCodecStatus status = static_cast<MediaCodecStatus>(
154 Java_GetOutputFormatResult_status(env, result)); 124 Java_GetOutputFormatResult_status(env, result));
155 if (status == MEDIA_CODEC_OK) 125 if (status == MEDIA_CODEC_OK)
156 *channel_count = Java_GetOutputFormatResult_channelCount(env, result); 126 *channel_count = Java_GetOutputFormatResult_channelCount(env, result);
157 return status; 127 return status;
158 } 128 }
159 129
160 MediaCodecStatus MediaCodecBridgeImpl::QueueInputBuffer( 130 MediaCodecStatus MediaCodecBridgeImpl::QueueInputBuffer(
161 int index, 131 int index,
162 const uint8_t* data, 132 const uint8_t* data,
163 size_t data_size, 133 size_t data_size,
164 base::TimeDelta presentation_time) { 134 base::TimeDelta presentation_time) {
165 DVLOG(3) << __func__ << " " << index << ": " << data_size; 135 DVLOG(3) << __func__ << " " << index << ": " << data_size;
166 if (data_size > 136 if (data_size >
167 base::checked_cast<size_t>(std::numeric_limits<int32_t>::max())) { 137 base::checked_cast<size_t>(std::numeric_limits<int32_t>::max())) {
168 return MEDIA_CODEC_ERROR; 138 return MEDIA_CODEC_ERROR;
169 } 139 }
170 if (data && !FillInputBuffer(index, data, data_size)) 140 if (data && !FillInputBuffer(index, data, data_size))
171 return MEDIA_CODEC_ERROR; 141 return MEDIA_CODEC_ERROR;
172 JNIEnv* env = AttachCurrentThread(); 142 JNIEnv* env = AttachCurrentThread();
173 return static_cast<MediaCodecStatus>(Java_MediaCodecBridge_queueInputBuffer( 143 return static_cast<MediaCodecStatus>(Java_MediaCodecBridge_queueInputBuffer(
174 env, j_media_codec_, index, 0, data_size, 144 env, j_bridge_, index, 0, data_size, presentation_time.InMicroseconds(),
175 presentation_time.InMicroseconds(), 0)); 145 0));
176 } 146 }
177 147
178 MediaCodecStatus MediaCodecBridgeImpl::QueueSecureInputBuffer( 148 MediaCodecStatus MediaCodecBridgeImpl::QueueSecureInputBuffer(
179 int index, 149 int index,
180 const uint8_t* data, 150 const uint8_t* data,
181 size_t data_size, 151 size_t data_size,
182 const std::string& key_id, 152 const std::string& key_id,
183 const std::string& iv, 153 const std::string& iv,
184 const std::vector<SubsampleEntry>& subsamples, 154 const std::vector<SubsampleEntry>& subsamples,
185 const EncryptionScheme& encryption_scheme, 155 const EncryptionScheme& encryption_scheme,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } 193 }
224 } 194 }
225 195
226 ScopedJavaLocalRef<jintArray> clear_array = 196 ScopedJavaLocalRef<jintArray> clear_array =
227 ToJavaIntArray(env, std::move(native_clear_array), num_subsamples); 197 ToJavaIntArray(env, std::move(native_clear_array), num_subsamples);
228 ScopedJavaLocalRef<jintArray> cypher_array = 198 ScopedJavaLocalRef<jintArray> cypher_array =
229 ToJavaIntArray(env, std::move(native_cypher_array), num_subsamples); 199 ToJavaIntArray(env, std::move(native_cypher_array), num_subsamples);
230 200
231 return static_cast<MediaCodecStatus>( 201 return static_cast<MediaCodecStatus>(
232 Java_MediaCodecBridge_queueSecureInputBuffer( 202 Java_MediaCodecBridge_queueSecureInputBuffer(
233 env, j_media_codec_.obj(), index, 0, j_iv.obj(), j_key_id.obj(), 203 env, j_bridge_.obj(), index, 0, j_iv.obj(), j_key_id.obj(),
234 clear_array, cypher_array, num_subsamples, 204 clear_array, cypher_array, num_subsamples,
235 static_cast<int>(encryption_scheme.mode()), 205 static_cast<int>(encryption_scheme.mode()),
236 static_cast<int>(encryption_scheme.pattern().encrypt_blocks()), 206 static_cast<int>(encryption_scheme.pattern().encrypt_blocks()),
237 static_cast<int>(encryption_scheme.pattern().skip_blocks()), 207 static_cast<int>(encryption_scheme.pattern().skip_blocks()),
238 presentation_time.InMicroseconds())); 208 presentation_time.InMicroseconds()));
239 } 209 }
240 210
241 void MediaCodecBridgeImpl::QueueEOS(int input_buffer_index) { 211 void MediaCodecBridgeImpl::QueueEOS(int input_buffer_index) {
242 DVLOG(3) << __func__ << ": " << input_buffer_index; 212 DVLOG(3) << __func__ << ": " << input_buffer_index;
243 JNIEnv* env = AttachCurrentThread(); 213 JNIEnv* env = AttachCurrentThread();
244 Java_MediaCodecBridge_queueInputBuffer( 214 Java_MediaCodecBridge_queueInputBuffer(env, j_bridge_, input_buffer_index, 0,
245 env, j_media_codec_, input_buffer_index, 0, 0, 0, kBufferFlagEndOfStream); 215 0, 0, kBufferFlagEndOfStream);
246 } 216 }
247 217
248 MediaCodecStatus MediaCodecBridgeImpl::DequeueInputBuffer( 218 MediaCodecStatus MediaCodecBridgeImpl::DequeueInputBuffer(
249 base::TimeDelta timeout, 219 base::TimeDelta timeout,
250 int* index) { 220 int* index) {
251 JNIEnv* env = AttachCurrentThread(); 221 JNIEnv* env = AttachCurrentThread();
252 ScopedJavaLocalRef<jobject> result = Java_MediaCodecBridge_dequeueInputBuffer( 222 ScopedJavaLocalRef<jobject> result = Java_MediaCodecBridge_dequeueInputBuffer(
253 env, j_media_codec_, timeout.InMicroseconds()); 223 env, j_bridge_, timeout.InMicroseconds());
254 *index = Java_DequeueInputResult_index(env, result); 224 *index = Java_DequeueInputResult_index(env, result);
255 MediaCodecStatus status = static_cast<MediaCodecStatus>( 225 MediaCodecStatus status = static_cast<MediaCodecStatus>(
256 Java_DequeueInputResult_status(env, result)); 226 Java_DequeueInputResult_status(env, result));
257 DVLOG(3) << __func__ << ": status: " << status << ", index: " << *index; 227 DVLOG(3) << __func__ << ": status: " << status << ", index: " << *index;
258 return status; 228 return status;
259 } 229 }
260 230
261 MediaCodecStatus MediaCodecBridgeImpl::DequeueOutputBuffer( 231 MediaCodecStatus MediaCodecBridgeImpl::DequeueOutputBuffer(
262 base::TimeDelta timeout, 232 base::TimeDelta timeout,
263 int* index, 233 int* index,
264 size_t* offset, 234 size_t* offset,
265 size_t* size, 235 size_t* size,
266 base::TimeDelta* presentation_time, 236 base::TimeDelta* presentation_time,
267 bool* end_of_stream, 237 bool* end_of_stream,
268 bool* key_frame) { 238 bool* key_frame) {
269 JNIEnv* env = AttachCurrentThread(); 239 JNIEnv* env = AttachCurrentThread();
270 ScopedJavaLocalRef<jobject> result = 240 ScopedJavaLocalRef<jobject> result =
271 Java_MediaCodecBridge_dequeueOutputBuffer(env, j_media_codec_, 241 Java_MediaCodecBridge_dequeueOutputBuffer(env, j_bridge_,
272 timeout.InMicroseconds()); 242 timeout.InMicroseconds());
273 *index = Java_DequeueOutputResult_index(env, result); 243 *index = Java_DequeueOutputResult_index(env, result);
274 *offset = 244 *offset =
275 base::checked_cast<size_t>(Java_DequeueOutputResult_offset(env, result)); 245 base::checked_cast<size_t>(Java_DequeueOutputResult_offset(env, result));
276 *size = base::checked_cast<size_t>( 246 *size = base::checked_cast<size_t>(
277 Java_DequeueOutputResult_numBytes(env, result)); 247 Java_DequeueOutputResult_numBytes(env, result));
278 if (presentation_time) { 248 if (presentation_time) {
279 *presentation_time = base::TimeDelta::FromMicroseconds( 249 *presentation_time = base::TimeDelta::FromMicroseconds(
280 Java_DequeueOutputResult_presentationTimeMicroseconds(env, result)); 250 Java_DequeueOutputResult_presentationTimeMicroseconds(env, result));
281 } 251 }
282 int flags = Java_DequeueOutputResult_flags(env, result); 252 int flags = Java_DequeueOutputResult_flags(env, result);
283 if (end_of_stream) 253 if (end_of_stream)
284 *end_of_stream = flags & kBufferFlagEndOfStream; 254 *end_of_stream = flags & kBufferFlagEndOfStream;
285 if (key_frame) 255 if (key_frame)
286 *key_frame = flags & kBufferFlagSyncFrame; 256 *key_frame = flags & kBufferFlagSyncFrame;
287 MediaCodecStatus status = static_cast<MediaCodecStatus>( 257 MediaCodecStatus status = static_cast<MediaCodecStatus>(
288 Java_DequeueOutputResult_status(env, result)); 258 Java_DequeueOutputResult_status(env, result));
289 DVLOG(3) << __func__ << ": status: " << status << ", index: " << *index 259 DVLOG(3) << __func__ << ": status: " << status << ", index: " << *index
290 << ", offset: " << *offset << ", size: " << *size 260 << ", offset: " << *offset << ", size: " << *size
291 << ", flags: " << flags; 261 << ", flags: " << flags;
292 return status; 262 return status;
293 } 263 }
294 264
295 void MediaCodecBridgeImpl::ReleaseOutputBuffer(int index, bool render) { 265 void MediaCodecBridgeImpl::ReleaseOutputBuffer(int index, bool render) {
296 DVLOG(3) << __func__ << ": " << index; 266 DVLOG(3) << __func__ << ": " << index;
297 JNIEnv* env = AttachCurrentThread(); 267 JNIEnv* env = AttachCurrentThread();
298 Java_MediaCodecBridge_releaseOutputBuffer(env, j_media_codec_, index, render); 268 Java_MediaCodecBridge_releaseOutputBuffer(env, j_bridge_, index, render);
299 } 269 }
300 270
301 MediaCodecStatus MediaCodecBridgeImpl::GetInputBuffer(int input_buffer_index, 271 MediaCodecStatus MediaCodecBridgeImpl::GetInputBuffer(int input_buffer_index,
302 uint8_t** data, 272 uint8_t** data,
303 size_t* capacity) { 273 size_t* capacity) {
304 JNIEnv* env = AttachCurrentThread(); 274 JNIEnv* env = AttachCurrentThread();
305 ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer( 275 ScopedJavaLocalRef<jobject> j_buffer(
306 env, j_media_codec_, input_buffer_index)); 276 Java_MediaCodecBridge_getInputBuffer(env, j_bridge_, input_buffer_index));
307 if (j_buffer.is_null()) 277 if (j_buffer.is_null())
308 return MEDIA_CODEC_ERROR; 278 return MEDIA_CODEC_ERROR;
309 279
310 *data = static_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj())); 280 *data = static_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj()));
311 *capacity = 281 *capacity =
312 base::checked_cast<size_t>(env->GetDirectBufferCapacity(j_buffer.obj())); 282 base::checked_cast<size_t>(env->GetDirectBufferCapacity(j_buffer.obj()));
313 return MEDIA_CODEC_OK; 283 return MEDIA_CODEC_OK;
314 } 284 }
315 285
316 MediaCodecStatus MediaCodecBridgeImpl::CopyFromOutputBuffer(int index, 286 MediaCodecStatus MediaCodecBridgeImpl::CopyFromOutputBuffer(int index,
(...skipping 11 matching lines...) Expand all
328 return status; 298 return status;
329 } 299 }
330 300
331 MediaCodecStatus MediaCodecBridgeImpl::GetOutputBufferAddress( 301 MediaCodecStatus MediaCodecBridgeImpl::GetOutputBufferAddress(
332 int index, 302 int index,
333 size_t offset, 303 size_t offset,
334 const uint8_t** addr, 304 const uint8_t** addr,
335 size_t* capacity) { 305 size_t* capacity) {
336 JNIEnv* env = AttachCurrentThread(); 306 JNIEnv* env = AttachCurrentThread();
337 ScopedJavaLocalRef<jobject> j_buffer( 307 ScopedJavaLocalRef<jobject> j_buffer(
338 Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_, index)); 308 Java_MediaCodecBridge_getOutputBuffer(env, j_bridge_, index));
339 if (j_buffer.is_null()) 309 if (j_buffer.is_null())
340 return MEDIA_CODEC_ERROR; 310 return MEDIA_CODEC_ERROR;
341 const size_t total_capacity = env->GetDirectBufferCapacity(j_buffer.obj()); 311 const size_t total_capacity = env->GetDirectBufferCapacity(j_buffer.obj());
342 CHECK_GE(total_capacity, offset); 312 CHECK_GE(total_capacity, offset);
343 *addr = reinterpret_cast<const uint8_t*>( 313 *addr = reinterpret_cast<const uint8_t*>(
344 env->GetDirectBufferAddress(j_buffer.obj())) + 314 env->GetDirectBufferAddress(j_buffer.obj())) +
345 offset; 315 offset;
346 *capacity = total_capacity - offset; 316 *capacity = total_capacity - offset;
347 return MEDIA_CODEC_OK; 317 return MEDIA_CODEC_OK;
348 } 318 }
349 319
350 std::string MediaCodecBridgeImpl::GetName() { 320 std::string MediaCodecBridgeImpl::GetName() {
351 if (base::android::BuildInfo::GetInstance()->sdk_int() < 18) 321 if (base::android::BuildInfo::GetInstance()->sdk_int() < 18)
352 return ""; 322 return "";
353 JNIEnv* env = AttachCurrentThread(); 323 JNIEnv* env = AttachCurrentThread();
354 ScopedJavaLocalRef<jstring> j_name = 324 ScopedJavaLocalRef<jstring> j_name =
355 Java_MediaCodecBridge_getName(env, j_media_codec_); 325 Java_MediaCodecBridge_getName(env, j_bridge_);
356 return ConvertJavaStringToUTF8(env, j_name); 326 return ConvertJavaStringToUTF8(env, j_name);
357 } 327 }
358 328
329 bool MediaCodecBridgeImpl::SetSurface(jobject surface) {
330 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 23);
331 JNIEnv* env = AttachCurrentThread();
332 return Java_MediaCodecBridge_setSurface(env, j_bridge_, surface);
333 }
334
335 void MediaCodecBridgeImpl::SetVideoBitrate(int bps, int frame_rate) {
336 JNIEnv* env = AttachCurrentThread();
337 Java_MediaCodecBridge_setVideoBitrate(env, j_bridge_, bps, frame_rate);
338 }
339
340 void MediaCodecBridgeImpl::RequestKeyFrameSoon() {
341 JNIEnv* env = AttachCurrentThread();
342 Java_MediaCodecBridge_requestKeyFrameSoon(env, j_bridge_);
343 }
344
345 bool MediaCodecBridgeImpl::IsAdaptivePlaybackSupported() {
346 JNIEnv* env = AttachCurrentThread();
347 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, j_bridge_);
348 }
349
359 bool MediaCodecBridgeImpl::FillInputBuffer(int index, 350 bool MediaCodecBridgeImpl::FillInputBuffer(int index,
360 const uint8_t* data, 351 const uint8_t* data,
361 size_t size) { 352 size_t size) {
362 uint8_t* dst = nullptr; 353 uint8_t* dst = nullptr;
363 size_t capacity = 0; 354 size_t capacity = 0;
364 if (GetInputBuffer(index, &dst, &capacity) != MEDIA_CODEC_OK) { 355 if (GetInputBuffer(index, &dst, &capacity) != MEDIA_CODEC_OK) {
365 LOG(ERROR) << "GetInputBuffer failed"; 356 LOG(ERROR) << "GetInputBuffer failed";
366 return false; 357 return false;
367 } 358 }
368 CHECK(dst); 359 CHECK(dst);
369 360
370 if (size > capacity) { 361 if (size > capacity) {
371 LOG(ERROR) << "Input buffer size " << size 362 LOG(ERROR) << "Input buffer size " << size
372 << " exceeds MediaCodec input buffer capacity: " << capacity; 363 << " exceeds MediaCodec input buffer capacity: " << capacity;
373 return false; 364 return false;
374 } 365 }
375 366
376 memcpy(dst, data, size); 367 memcpy(dst, data, size);
377 return true; 368 return true;
378 } 369 }
379 370
380 // static 371 // static
381 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) { 372 std::unique_ptr<MediaCodecBridge> MediaCodecBridgeImpl::CreateAudioDecoder(
373 const AudioDecoderConfig& config,
374 jobject media_crypto) {
375 DVLOG(2) << __func__ << ": " << config.AsHumanReadableString()
376 << " media_crypto:" << media_crypto;
377
382 if (!MediaCodecUtil::IsMediaCodecAvailable()) 378 if (!MediaCodecUtil::IsMediaCodecAvailable())
383 return nullptr; 379 return nullptr;
384 380
385 const std::string mime = AudioCodecToAndroidMimeType(codec); 381 const std::string mime =
382 MediaCodecUtil::CodecToAndroidMimeType(config.codec());
386 if (mime.empty()) 383 if (mime.empty())
384 return false;
385
386 auto bridge = base::WrapUnique(new MediaCodecBridgeImpl(
387 mime, false, MediaCodecDirection::DECODER, false));
388 if (bridge->j_bridge_.is_null())
387 return nullptr; 389 return nullptr;
388 390
389 std::unique_ptr<AudioCodecBridge> bridge(new AudioCodecBridge(mime)); 391 JNIEnv* env = AttachCurrentThread();
390 if (!bridge->media_codec()) 392 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
391 return nullptr;
392 393
393 return bridge.release();
394 }
395
396 // static
397 bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) {
398 return MediaCodecUtil::IsKnownUnaccelerated(
399 AudioCodecToAndroidMimeType(codec), MEDIA_CODEC_DECODER);
400 }
401
402 AudioCodecBridge::AudioCodecBridge(const std::string& mime)
403 // Audio codec doesn't care about security level and there is no need for
404 // audio encoding yet.
405 : MediaCodecBridgeImpl(mime, false, MEDIA_CODEC_DECODER, false) {}
406
407 bool AudioCodecBridge::ConfigureAndStart(const AudioDecoderConfig& config,
408 jobject media_crypto) {
409 const int channel_count = 394 const int channel_count =
410 ChannelLayoutToChannelCount(config.channel_layout()); 395 ChannelLayoutToChannelCount(config.channel_layout());
411 const int64_t codec_delay_ns = base::Time::kNanosecondsPerSecond *
412 config.codec_delay() /
413 config.samples_per_second();
414 const int64_t seek_preroll_ns =
415 1000LL * config.seek_preroll().InMicroseconds();
416
417 return ConfigureAndStart(config.codec(), config.samples_per_second(),
418 channel_count, config.extra_data().data(),
419 config.extra_data().size(), codec_delay_ns,
420 seek_preroll_ns, media_crypto);
421 }
422
423 bool AudioCodecBridge::ConfigureAndStart(const AudioCodec& codec,
424 int sample_rate,
425 int channel_count,
426 const uint8_t* extra_data,
427 size_t extra_data_size,
428 int64_t codec_delay_ns,
429 int64_t seek_preroll_ns,
430 jobject media_crypto) {
431 DVLOG(2) << __func__ << ": "
432 << " codec:" << GetCodecName(codec)
433 << " samples_per_second:" << sample_rate
434 << " channel_count:" << channel_count
435 << " codec_delay_ns:" << codec_delay_ns
436 << " seek_preroll_ns:" << seek_preroll_ns
437 << " extra data size:" << extra_data_size
438 << " media_crypto:" << media_crypto;
439 DCHECK(media_codec());
440
441 std::string codec_string = AudioCodecToAndroidMimeType(codec);
442 if (codec_string.empty())
443 return false;
444
445 JNIEnv* env = AttachCurrentThread();
446
447 ScopedJavaLocalRef<jstring> j_mime =
448 ConvertUTF8ToJavaString(env, codec_string);
449 ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat( 396 ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat(
450 env, j_mime, sample_rate, channel_count)); 397 env, j_mime, config.samples_per_second(), channel_count));
451 DCHECK(!j_format.is_null()); 398 DCHECK(!j_format.is_null());
452 399
453 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size, 400 const int64_t codec_delay_ns = config.codec_delay() /
454 codec_delay_ns, seek_preroll_ns)) { 401 config.samples_per_second() *
402 base::Time::kNanosecondsPerSecond;
403 const int64_t seek_preroll_ns = config.seek_preroll().InMicroseconds() *
404 base::Time::kNanosecondsPerMicrosecond;
405 if (!ConfigureMediaFormatForAudio(
406 j_format.obj(), config.codec(), config.extra_data().data(),
407 config.extra_data().size(), codec_delay_ns, seek_preroll_ns)) {
455 return false; 408 return false;
456 } 409 }
457 410
458 if (!Java_MediaCodecBridge_configureAudio(env, media_codec(), j_format, 411 if (!Java_MediaCodecBridge_configureAudio(env, bridge->j_bridge_, j_format,
459 media_crypto, 0)) { 412 media_crypto, 0)) {
460 return false; 413 return false;
461 } 414 }
462 415
463 return Start(); 416 return bridge->Start() ? std::move(bridge) : nullptr;
464 } 417 }
465 418
466 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format, 419 // Parses |extra_data| and sets the appropriate fields of the given MediaFormat.
467 const AudioCodec& codec, 420
468 const uint8_t* extra_data, 421 // XXX: I'll move this to the anonymous namespace before committing this CL. I'm
469 size_t extra_data_size, 422 // leaving it here for reviewability for now.
470 int64_t codec_delay_ns, 423 bool ConfigureMediaFormatForAudio(jobject j_format,
471 int64_t seek_preroll_ns) { 424 AudioCodec codec,
425 const uint8_t* extra_data,
426 size_t extra_data_size,
427 int64_t codec_delay_ns,
428 int64_t seek_preroll_ns) {
472 if (extra_data_size == 0 && codec != kCodecOpus) 429 if (extra_data_size == 0 && codec != kCodecOpus)
473 return true; 430 return true;
474 431
475 JNIEnv* env = AttachCurrentThread(); 432 JNIEnv* env = AttachCurrentThread();
476 switch (codec) { 433 switch (codec) {
477 case kCodecVorbis: { 434 case kCodecVorbis: {
478 if (extra_data[0] != 2) { 435 if (extra_data[0] != 2) {
479 LOG(ERROR) << "Invalid number of vorbis headers before the codec " 436 LOG(ERROR) << "Invalid number of vorbis headers before the codec "
480 << "header: " << extra_data[0]; 437 << "header: " << extra_data[0];
481 return false; 438 return false;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 537
581 // csd2 - Seek Preroll 538 // csd2 - Seek Preroll
582 ScopedJavaLocalRef<jbyteArray> csd2 = base::android::ToJavaByteArray( 539 ScopedJavaLocalRef<jbyteArray> csd2 = base::android::ToJavaByteArray(
583 env, reinterpret_cast<const uint8_t*>(&seek_preroll_ns), 540 env, reinterpret_cast<const uint8_t*>(&seek_preroll_ns),
584 sizeof(int64_t)); 541 sizeof(int64_t));
585 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 2, csd2); 542 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 2, csd2);
586 break; 543 break;
587 } 544 }
588 default: 545 default:
589 LOG(ERROR) << "Invalid header encountered for codec: " 546 LOG(ERROR) << "Invalid header encountered for codec: "
590 << AudioCodecToAndroidMimeType(codec); 547 << GetCodecName(codec);
591 return false; 548 return false;
592 } 549 }
593 return true; 550 return true;
594 } 551 }
595 552
596 // static 553 // static
597 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec, 554 std::unique_ptr<MediaCodecBridge> MediaCodecBridgeImpl::CreateVideoDecoder(
598 MediaCodecDirection direction) { 555 VideoCodec codec,
599 return MediaCodecUtil::IsKnownUnaccelerated(
600 VideoCodecToAndroidMimeType(codec), direction);
601 }
602
603 // static
604 VideoCodecBridge* VideoCodecBridge::CreateDecoder(
605 const VideoCodec& codec,
606 bool is_secure, 556 bool is_secure,
607 const gfx::Size& size, 557 const gfx::Size& size,
608 jobject surface, 558 jobject surface,
609 jobject media_crypto, 559 jobject media_crypto,
610 const std::vector<uint8_t>& csd0, 560 const std::vector<uint8_t>& csd0,
611 const std::vector<uint8_t>& csd1, 561 const std::vector<uint8_t>& csd1,
612 bool allow_adaptive_playback, 562 bool allow_adaptive_playback,
613 bool require_software_codec) { 563 bool require_software_codec) {
614 if (!MediaCodecUtil::IsMediaCodecAvailable()) 564 if (!MediaCodecUtil::IsMediaCodecAvailable())
615 return nullptr; 565 return nullptr;
616 566
617 const std::string mime = VideoCodecToAndroidMimeType(codec); 567 const std::string mime = MediaCodecUtil::CodecToAndroidMimeType(codec);
618 if (mime.empty()) 568 if (mime.empty())
619 return nullptr; 569 return nullptr;
620 570
621 std::unique_ptr<VideoCodecBridge> bridge(new VideoCodecBridge( 571 std::unique_ptr<MediaCodecBridgeImpl> bridge(new MediaCodecBridgeImpl(
622 mime, is_secure, MEDIA_CODEC_DECODER, require_software_codec)); 572 mime, is_secure, MediaCodecDirection::DECODER, require_software_codec));
623 if (!bridge->media_codec()) 573 if (bridge->j_bridge_.is_null())
624 return nullptr; 574 return nullptr;
625 575
626 JNIEnv* env = AttachCurrentThread(); 576 JNIEnv* env = AttachCurrentThread();
627 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 577 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
628 ScopedJavaLocalRef<jobject> j_format( 578 ScopedJavaLocalRef<jobject> j_format(
629 Java_MediaCodecBridge_createVideoDecoderFormat(env, j_mime, size.width(), 579 Java_MediaCodecBridge_createVideoDecoderFormat(env, j_mime, size.width(),
630 size.height())); 580 size.height()));
631 DCHECK(!j_format.is_null()); 581 DCHECK(!j_format.is_null());
632 582
633 if (!csd0.empty()) { 583 if (!csd0.empty()) {
634 ScopedJavaLocalRef<jbyteArray> j_csd0 = 584 ScopedJavaLocalRef<jbyteArray> j_csd0 =
635 base::android::ToJavaByteArray(env, csd0.data(), csd0.size()); 585 base::android::ToJavaByteArray(env, csd0.data(), csd0.size());
636 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, j_csd0); 586 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, j_csd0);
637 } 587 }
638 588
639 if (!csd1.empty()) { 589 if (!csd1.empty()) {
640 ScopedJavaLocalRef<jbyteArray> j_csd1 = 590 ScopedJavaLocalRef<jbyteArray> j_csd1 =
641 base::android::ToJavaByteArray(env, csd1.data(), csd1.size()); 591 base::android::ToJavaByteArray(env, csd1.data(), csd1.size());
642 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, j_csd1); 592 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, j_csd1);
643 } 593 }
644 594
645 if (!Java_MediaCodecBridge_configureVideo(env, bridge->media_codec(), 595 if (!Java_MediaCodecBridge_configureVideo(env, bridge->j_bridge_, j_format,
646 j_format, surface, media_crypto, 0, 596 surface, media_crypto, 0,
647 allow_adaptive_playback)) { 597 allow_adaptive_playback)) {
648 return nullptr; 598 return nullptr;
649 } 599 }
650 600
651 return bridge->Start() ? bridge.release() : nullptr; 601 return bridge->Start() ? std::move(bridge) : nullptr;
652 } 602 }
653 603
654 // static 604 // static
655 VideoCodecBridge* VideoCodecBridge::CreateEncoder(const VideoCodec& codec, 605 std::unique_ptr<MediaCodecBridge> MediaCodecBridgeImpl::CreateVideoEncoder(
656 const gfx::Size& size, 606 VideoCodec codec,
657 int bit_rate, 607 const gfx::Size& size,
658 int frame_rate, 608 int bit_rate,
659 int i_frame_interval, 609 int frame_rate,
660 int color_format) { 610 int i_frame_interval,
611 int color_format) {
661 if (!MediaCodecUtil::IsMediaCodecAvailable()) 612 if (!MediaCodecUtil::IsMediaCodecAvailable())
662 return nullptr; 613 return nullptr;
663 614
664 const std::string mime = VideoCodecToAndroidMimeType(codec); 615 const std::string mime = MediaCodecUtil::CodecToAndroidMimeType(codec);
665 if (mime.empty()) 616 if (mime.empty())
666 return nullptr; 617 return nullptr;
667 618
668 std::unique_ptr<VideoCodecBridge> bridge( 619 std::unique_ptr<MediaCodecBridgeImpl> bridge(new MediaCodecBridgeImpl(
669 new VideoCodecBridge(mime, false, MEDIA_CODEC_ENCODER, false)); 620 mime, false, MediaCodecDirection::ENCODER, false));
670 if (!bridge->media_codec()) 621 if (bridge->j_bridge_.is_null())
671 return nullptr; 622 return nullptr;
672 623
673 JNIEnv* env = AttachCurrentThread(); 624 JNIEnv* env = AttachCurrentThread();
674 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 625 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
675 ScopedJavaLocalRef<jobject> j_format( 626 ScopedJavaLocalRef<jobject> j_format(
676 Java_MediaCodecBridge_createVideoEncoderFormat( 627 Java_MediaCodecBridge_createVideoEncoderFormat(
677 env, bridge->media_codec(), j_mime, size.width(), size.height(), 628 env, bridge->j_bridge_, j_mime, size.width(), size.height(), bit_rate,
678 bit_rate, frame_rate, i_frame_interval, color_format)); 629 frame_rate, i_frame_interval, color_format));
679 DCHECK(!j_format.is_null()); 630 DCHECK(!j_format.is_null());
680 if (!Java_MediaCodecBridge_configureVideo(env, bridge->media_codec(), 631 if (!Java_MediaCodecBridge_configureVideo(env, bridge->j_bridge_, j_format,
681 j_format, nullptr, nullptr, 632 nullptr, nullptr,
682 kConfigureFlagEncode, true)) { 633 kConfigureFlagEncode, true)) {
683 return nullptr; 634 return nullptr;
684 } 635 }
685 636
686 return bridge->Start() ? bridge.release() : nullptr; 637 return bridge->Start() ? std::move(bridge) : nullptr;
687 } 638 }
688 639
689 VideoCodecBridge::VideoCodecBridge(const std::string& mime,
690 bool is_secure,
691 MediaCodecDirection direction,
692 bool require_software_codec)
693 : MediaCodecBridgeImpl(mime, is_secure, direction, require_software_codec),
694 adaptive_playback_supported_for_testing_(-1) {}
695
696 bool VideoCodecBridge::SetSurface(jobject surface) {
697 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 23);
698 JNIEnv* env = AttachCurrentThread();
699 return Java_MediaCodecBridge_setSurface(env, media_codec(), surface);
700 }
701
702 void VideoCodecBridge::SetVideoBitrate(int bps, int frame_rate) {
703 JNIEnv* env = AttachCurrentThread();
704 Java_MediaCodecBridge_setVideoBitrate(env, media_codec(), bps, frame_rate);
705 }
706
707 void VideoCodecBridge::RequestKeyFrameSoon() {
708 JNIEnv* env = AttachCurrentThread();
709 Java_MediaCodecBridge_requestKeyFrameSoon(env, media_codec());
710 }
711
712 bool VideoCodecBridge::IsAdaptivePlaybackSupported(int width, int height) {
713 if (adaptive_playback_supported_for_testing_ == 0)
714 return false;
715 else if (adaptive_playback_supported_for_testing_ > 0)
716 return true;
717 JNIEnv* env = AttachCurrentThread();
718 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(),
719 width, height);
720 }
721 640
722 } // namespace media 641 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698