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

Side by Side Diff: talk/app/webrtc/java/jni/androidmediadecoder_jni.cc

Issue 1394103005: Revert "Android MediaCodecVideoDecoder: Manage lifetime of texture frames" (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fork NativeHandleImpl and disable texture capture, plus some revert rebase nits Created 5 years, 2 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 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 15 matching lines...) Expand all
26 * 26 *
27 */ 27 */
28 28
29 #include <algorithm> 29 #include <algorithm>
30 #include <vector> 30 #include <vector>
31 31
32 #include "talk/app/webrtc/java/jni/androidmediadecoder_jni.h" 32 #include "talk/app/webrtc/java/jni/androidmediadecoder_jni.h"
33 #include "talk/app/webrtc/java/jni/androidmediacodeccommon.h" 33 #include "talk/app/webrtc/java/jni/androidmediacodeccommon.h"
34 #include "talk/app/webrtc/java/jni/classreferenceholder.h" 34 #include "talk/app/webrtc/java/jni/classreferenceholder.h"
35 #include "talk/app/webrtc/java/jni/native_handle_impl.h" 35 #include "talk/app/webrtc/java/jni/native_handle_impl.h"
36 #include "talk/app/webrtc/java/jni/surfacetexturehelper_jni.h"
37 #include "webrtc/base/bind.h" 36 #include "webrtc/base/bind.h"
38 #include "webrtc/base/checks.h" 37 #include "webrtc/base/checks.h"
39 #include "webrtc/base/logging.h" 38 #include "webrtc/base/logging.h"
40 #include "webrtc/base/scoped_ref_ptr.h" 39 #include "webrtc/base/scoped_ref_ptr.h"
41 #include "webrtc/base/thread.h" 40 #include "webrtc/base/thread.h"
42 #include "webrtc/base/timeutils.h" 41 #include "webrtc/base/timeutils.h"
43 #include "webrtc/common_video/interface/i420_buffer_pool.h" 42 #include "webrtc/common_video/interface/i420_buffer_pool.h"
44 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" 43 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
45 #include "webrtc/system_wrappers/interface/logcat_trace_context.h" 44 #include "webrtc/system_wrappers/interface/logcat_trace_context.h"
46 #include "webrtc/system_wrappers/interface/tick_util.h" 45 #include "webrtc/system_wrappers/interface/tick_util.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 104
106 // Type of video codec. 105 // Type of video codec.
107 VideoCodecType codecType_; 106 VideoCodecType codecType_;
108 107
109 bool key_frame_required_; 108 bool key_frame_required_;
110 bool inited_; 109 bool inited_;
111 bool sw_fallback_required_; 110 bool sw_fallback_required_;
112 bool use_surface_; 111 bool use_surface_;
113 VideoCodec codec_; 112 VideoCodec codec_;
114 webrtc::I420BufferPool decoded_frame_pool_; 113 webrtc::I420BufferPool decoded_frame_pool_;
115 rtc::scoped_refptr<SurfaceTextureHelper> surface_texture_helper_; 114 NativeHandleImpl native_handle_;
116 DecodedImageCallback* callback_; 115 DecodedImageCallback* callback_;
117 int frames_received_; // Number of frames received by decoder. 116 int frames_received_; // Number of frames received by decoder.
118 int frames_decoded_; // Number of frames decoded by decoder. 117 int frames_decoded_; // Number of frames decoded by decoder.
119 int64_t start_time_ms_; // Start time for statistics. 118 int64_t start_time_ms_; // Start time for statistics.
120 int current_frames_; // Number of frames in the current statistics interval. 119 int current_frames_; // Number of frames in the current statistics interval.
121 int current_bytes_; // Encoded bytes in the current statistics interval. 120 int current_bytes_; // Encoded bytes in the current statistics interval.
122 int current_decoding_time_ms_; // Overall decoding time in the current second 121 int current_decoding_time_ms_; // Overall decoding time in the current second
123 uint32_t max_pending_frames_; // Maximum number of pending input frames 122 uint32_t max_pending_frames_; // Maximum number of pending input frames
124 std::vector<int32_t> timestamps_; 123 std::vector<int32_t> timestamps_;
125 std::vector<int64_t> ntp_times_ms_; 124 std::vector<int64_t> ntp_times_ms_;
(...skipping 12 matching lines...) Expand all
138 jmethodID j_dequeue_output_buffer_method_; 137 jmethodID j_dequeue_output_buffer_method_;
139 jmethodID j_return_decoded_byte_buffer_method_; 138 jmethodID j_return_decoded_byte_buffer_method_;
140 // MediaCodecVideoDecoder fields. 139 // MediaCodecVideoDecoder fields.
141 jfieldID j_input_buffers_field_; 140 jfieldID j_input_buffers_field_;
142 jfieldID j_output_buffers_field_; 141 jfieldID j_output_buffers_field_;
143 jfieldID j_color_format_field_; 142 jfieldID j_color_format_field_;
144 jfieldID j_width_field_; 143 jfieldID j_width_field_;
145 jfieldID j_height_field_; 144 jfieldID j_height_field_;
146 jfieldID j_stride_field_; 145 jfieldID j_stride_field_;
147 jfieldID j_slice_height_field_; 146 jfieldID j_slice_height_field_;
147 jfieldID j_surface_texture_field_;
148 // MediaCodecVideoDecoder.DecodedTextureBuffer fields. 148 // MediaCodecVideoDecoder.DecodedTextureBuffer fields.
149 jfieldID j_textureID_field_; 149 jfieldID j_textureID_field_;
150 jfieldID j_transform_matrix_field_; 150 jfieldID j_texture_presentation_timestamp_us_field_;
151 jfieldID j_texture_timestamp_ns_field_;
152 // MediaCodecVideoDecoder.DecodedByteBuffer fields. 151 // MediaCodecVideoDecoder.DecodedByteBuffer fields.
153 jfieldID j_info_index_field_; 152 jfieldID j_info_index_field_;
154 jfieldID j_info_offset_field_; 153 jfieldID j_info_offset_field_;
155 jfieldID j_info_size_field_; 154 jfieldID j_info_size_field_;
156 jfieldID j_info_presentation_timestamp_us_field_; 155 jfieldID j_info_presentation_timestamp_us_field_;
157 156
158 // Global references; must be deleted in Release(). 157 // Global references; must be deleted in Release().
159 std::vector<jobject> input_buffers_; 158 std::vector<jobject> input_buffers_;
159 jobject surface_texture_;
160 jobject previous_surface_texture_;
160 161
161 // Render EGL context - owned by factory, should not be allocated/destroyed 162 // Render EGL context - owned by factory, should not be allocated/destroyed
162 // by VideoDecoder. 163 // by VideoDecoder.
163 jobject render_egl_context_; 164 jobject render_egl_context_;
164 }; 165 };
165 166
166 MediaCodecVideoDecoder::MediaCodecVideoDecoder( 167 MediaCodecVideoDecoder::MediaCodecVideoDecoder(
167 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context) : 168 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context) :
168 codecType_(codecType), 169 codecType_(codecType),
169 render_egl_context_(render_egl_context), 170 render_egl_context_(render_egl_context),
170 key_frame_required_(true), 171 key_frame_required_(true),
171 inited_(false), 172 inited_(false),
172 sw_fallback_required_(false), 173 sw_fallback_required_(false),
174 surface_texture_(NULL),
175 previous_surface_texture_(NULL),
173 codec_thread_(new Thread()), 176 codec_thread_(new Thread()),
174 j_media_codec_video_decoder_class_( 177 j_media_codec_video_decoder_class_(
175 jni, 178 jni,
176 FindClass(jni, "org/webrtc/MediaCodecVideoDecoder")), 179 FindClass(jni, "org/webrtc/MediaCodecVideoDecoder")),
177 j_media_codec_video_decoder_( 180 j_media_codec_video_decoder_(
178 jni, 181 jni,
179 jni->NewObject(*j_media_codec_video_decoder_class_, 182 jni->NewObject(*j_media_codec_video_decoder_class_,
180 GetMethodID(jni, 183 GetMethodID(jni,
181 *j_media_codec_video_decoder_class_, 184 *j_media_codec_video_decoder_class_,
182 "<init>", 185 "<init>",
183 "()V"))) { 186 "()V"))) {
184 ScopedLocalRefFrame local_ref_frame(jni); 187 ScopedLocalRefFrame local_ref_frame(jni);
185 codec_thread_->SetName("MediaCodecVideoDecoder", NULL); 188 codec_thread_->SetName("MediaCodecVideoDecoder", NULL);
186 RTC_CHECK(codec_thread_->Start()) << "Failed to start MediaCodecVideoDecoder"; 189 RTC_CHECK(codec_thread_->Start()) << "Failed to start MediaCodecVideoDecoder";
187 190
188 j_init_decode_method_ = GetMethodID( 191 j_init_decode_method_ = GetMethodID(
189 jni, *j_media_codec_video_decoder_class_, "initDecode", 192 jni, *j_media_codec_video_decoder_class_, "initDecode",
190 "(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;" 193 "(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;"
191 "IILorg/webrtc/SurfaceTextureHelper;)Z"); 194 "IILandroid/opengl/EGLContext;)Z");
192 j_release_method_ = 195 j_release_method_ =
193 GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V"); 196 GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V");
194 j_dequeue_input_buffer_method_ = GetMethodID( 197 j_dequeue_input_buffer_method_ = GetMethodID(
195 jni, *j_media_codec_video_decoder_class_, "dequeueInputBuffer", "()I"); 198 jni, *j_media_codec_video_decoder_class_, "dequeueInputBuffer", "()I");
196 j_queue_input_buffer_method_ = GetMethodID( 199 j_queue_input_buffer_method_ = GetMethodID(
197 jni, *j_media_codec_video_decoder_class_, "queueInputBuffer", "(IIJ)Z"); 200 jni, *j_media_codec_video_decoder_class_, "queueInputBuffer", "(IIJ)Z");
198 j_dequeue_output_buffer_method_ = GetMethodID( 201 j_dequeue_output_buffer_method_ = GetMethodID(
199 jni, *j_media_codec_video_decoder_class_, "dequeueOutputBuffer", 202 jni, *j_media_codec_video_decoder_class_, "dequeueOutputBuffer",
200 "(I)Ljava/lang/Object;"); 203 "(I)Ljava/lang/Object;");
201 j_return_decoded_byte_buffer_method_ = 204 j_return_decoded_byte_buffer_method_ =
202 GetMethodID(jni, *j_media_codec_video_decoder_class_, 205 GetMethodID(jni, *j_media_codec_video_decoder_class_,
203 "returnDecodedByteBuffer", "(I)V"); 206 "returnDecodedByteBuffer", "(I)V");
204 207
205 j_input_buffers_field_ = GetFieldID( 208 j_input_buffers_field_ = GetFieldID(
206 jni, *j_media_codec_video_decoder_class_, 209 jni, *j_media_codec_video_decoder_class_,
207 "inputBuffers", "[Ljava/nio/ByteBuffer;"); 210 "inputBuffers", "[Ljava/nio/ByteBuffer;");
208 j_output_buffers_field_ = GetFieldID( 211 j_output_buffers_field_ = GetFieldID(
209 jni, *j_media_codec_video_decoder_class_, 212 jni, *j_media_codec_video_decoder_class_,
210 "outputBuffers", "[Ljava/nio/ByteBuffer;"); 213 "outputBuffers", "[Ljava/nio/ByteBuffer;");
211 j_color_format_field_ = GetFieldID( 214 j_color_format_field_ = GetFieldID(
212 jni, *j_media_codec_video_decoder_class_, "colorFormat", "I"); 215 jni, *j_media_codec_video_decoder_class_, "colorFormat", "I");
213 j_width_field_ = GetFieldID( 216 j_width_field_ = GetFieldID(
214 jni, *j_media_codec_video_decoder_class_, "width", "I"); 217 jni, *j_media_codec_video_decoder_class_, "width", "I");
215 j_height_field_ = GetFieldID( 218 j_height_field_ = GetFieldID(
216 jni, *j_media_codec_video_decoder_class_, "height", "I"); 219 jni, *j_media_codec_video_decoder_class_, "height", "I");
217 j_stride_field_ = GetFieldID( 220 j_stride_field_ = GetFieldID(
218 jni, *j_media_codec_video_decoder_class_, "stride", "I"); 221 jni, *j_media_codec_video_decoder_class_, "stride", "I");
219 j_slice_height_field_ = GetFieldID( 222 j_slice_height_field_ = GetFieldID(
220 jni, *j_media_codec_video_decoder_class_, "sliceHeight", "I"); 223 jni, *j_media_codec_video_decoder_class_, "sliceHeight", "I");
224 j_surface_texture_field_ = GetFieldID(
225 jni, *j_media_codec_video_decoder_class_, "surfaceTexture",
226 "Landroid/graphics/SurfaceTexture;");
221 227
222 jclass j_decoder_decoded_texture_buffer_class = FindClass(jni, 228 jclass j_decoder_decoded_texture_buffer_class = FindClass(jni,
223 "org/webrtc/MediaCodecVideoDecoder$DecodedTextureBuffer"); 229 "org/webrtc/MediaCodecVideoDecoder$DecodedTextureBuffer");
224 j_textureID_field_ = GetFieldID( 230 j_textureID_field_ = GetFieldID(
225 jni, j_decoder_decoded_texture_buffer_class, "textureID", "I"); 231 jni, j_decoder_decoded_texture_buffer_class, "textureID", "I");
226 j_transform_matrix_field_ = GetFieldID( 232 j_texture_presentation_timestamp_us_field_ =
227 jni, j_decoder_decoded_texture_buffer_class, "transformMatrix", "[F"); 233 GetFieldID(jni, j_decoder_decoded_texture_buffer_class,
228 j_texture_timestamp_ns_field_ = GetFieldID( 234 "presentationTimestampUs", "J");
229 jni, j_decoder_decoded_texture_buffer_class, "timestampNs", "J");
230 235
231 jclass j_decoder_decoded_byte_buffer_class = FindClass(jni, 236 jclass j_decoder_decoded_byte_buffer_class = FindClass(jni,
232 "org/webrtc/MediaCodecVideoDecoder$DecodedByteBuffer"); 237 "org/webrtc/MediaCodecVideoDecoder$DecodedByteBuffer");
233 j_info_index_field_ = GetFieldID( 238 j_info_index_field_ = GetFieldID(
234 jni, j_decoder_decoded_byte_buffer_class, "index", "I"); 239 jni, j_decoder_decoded_byte_buffer_class, "index", "I");
235 j_info_offset_field_ = GetFieldID( 240 j_info_offset_field_ = GetFieldID(
236 jni, j_decoder_decoded_byte_buffer_class, "offset", "I"); 241 jni, j_decoder_decoded_byte_buffer_class, "offset", "I");
237 j_info_size_field_ = GetFieldID( 242 j_info_size_field_ = GetFieldID(
238 jni, j_decoder_decoded_byte_buffer_class, "size", "I"); 243 jni, j_decoder_decoded_byte_buffer_class, "size", "I");
239 j_info_presentation_timestamp_us_field_ = GetFieldID( 244 j_info_presentation_timestamp_us_field_ = GetFieldID(
240 jni, j_decoder_decoded_byte_buffer_class, "presentationTimestampUs", "J"); 245 jni, j_decoder_decoded_byte_buffer_class, "presentationTimestampUs", "J");
241 246
242 CHECK_EXCEPTION(jni) << "MediaCodecVideoDecoder ctor failed"; 247 CHECK_EXCEPTION(jni) << "MediaCodecVideoDecoder ctor failed";
243 use_surface_ = (render_egl_context_ != NULL); 248 use_surface_ = (render_egl_context_ != NULL);
244 ALOGD << "MediaCodecVideoDecoder ctor. Use surface: " << use_surface_; 249 ALOGD << "MediaCodecVideoDecoder ctor. Use surface: " << use_surface_;
245 memset(&codec_, 0, sizeof(codec_)); 250 memset(&codec_, 0, sizeof(codec_));
246 AllowBlockingCalls(); 251 AllowBlockingCalls();
247 } 252 }
248 253
249 MediaCodecVideoDecoder::~MediaCodecVideoDecoder() { 254 MediaCodecVideoDecoder::~MediaCodecVideoDecoder() {
250 // Call Release() to ensure no more callbacks to us after we are deleted. 255 // Call Release() to ensure no more callbacks to us after we are deleted.
251 Release(); 256 Release();
257 // Delete global references.
258 JNIEnv* jni = AttachCurrentThreadIfNeeded();
259 if (previous_surface_texture_ != NULL) {
260 jni->DeleteGlobalRef(previous_surface_texture_);
261 }
262 if (surface_texture_ != NULL) {
263 jni->DeleteGlobalRef(surface_texture_);
264 }
252 } 265 }
253 266
254 int32_t MediaCodecVideoDecoder::InitDecode(const VideoCodec* inst, 267 int32_t MediaCodecVideoDecoder::InitDecode(const VideoCodec* inst,
255 int32_t numberOfCores) { 268 int32_t numberOfCores) {
256 ALOGD << "InitDecode."; 269 ALOGD << "InitDecode.";
257 if (inst == NULL) { 270 if (inst == NULL) {
258 ALOGE << "NULL VideoCodec instance"; 271 ALOGE << "NULL VideoCodec instance";
259 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 272 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
260 } 273 }
261 // Factory should guard against other codecs being used with us. 274 // Factory should guard against other codecs being used with us.
(...skipping 29 matching lines...) Expand all
291 ALOGE << "Release failure: " << ret_val << " - fallback to SW codec"; 304 ALOGE << "Release failure: " << ret_val << " - fallback to SW codec";
292 sw_fallback_required_ = true; 305 sw_fallback_required_ = true;
293 return WEBRTC_VIDEO_CODEC_ERROR; 306 return WEBRTC_VIDEO_CODEC_ERROR;
294 } 307 }
295 308
296 // Always start with a complete key frame. 309 // Always start with a complete key frame.
297 key_frame_required_ = true; 310 key_frame_required_ = true;
298 frames_received_ = 0; 311 frames_received_ = 0;
299 frames_decoded_ = 0; 312 frames_decoded_ = 0;
300 313
301 if (use_surface_) {
302 surface_texture_helper_ = new rtc::RefCountedObject<SurfaceTextureHelper>(
303 jni, render_egl_context_);
304 }
305
306 jobject j_video_codec_enum = JavaEnumFromIndex( 314 jobject j_video_codec_enum = JavaEnumFromIndex(
307 jni, "MediaCodecVideoDecoder$VideoCodecType", codecType_); 315 jni, "MediaCodecVideoDecoder$VideoCodecType", codecType_);
308 bool success = jni->CallBooleanMethod( 316 bool success = jni->CallBooleanMethod(
309 *j_media_codec_video_decoder_, 317 *j_media_codec_video_decoder_,
310 j_init_decode_method_, 318 j_init_decode_method_,
311 j_video_codec_enum, 319 j_video_codec_enum,
312 codec_.width, 320 codec_.width,
313 codec_.height, 321 codec_.height,
314 use_surface_ ? surface_texture_helper_->GetJavaSurfaceTextureHelper() 322 use_surface_ ? render_egl_context_ : nullptr);
315 : nullptr);
316 if (CheckException(jni) || !success) { 323 if (CheckException(jni) || !success) {
317 ALOGE << "Codec initialization error - fallback to SW codec."; 324 ALOGE << "Codec initialization error - fallback to SW codec.";
318 sw_fallback_required_ = true; 325 sw_fallback_required_ = true;
319 return WEBRTC_VIDEO_CODEC_ERROR; 326 return WEBRTC_VIDEO_CODEC_ERROR;
320 } 327 }
321 inited_ = true; 328 inited_ = true;
322 329
323 switch (codecType_) { 330 switch (codecType_) {
324 case kVideoCodecVP8: 331 case kVideoCodecVP8:
325 max_pending_frames_ = kMaxPendingFramesVp8; 332 max_pending_frames_ = kMaxPendingFramesVp8;
(...skipping 21 matching lines...) Expand all
347 for (size_t i = 0; i < num_input_buffers; ++i) { 354 for (size_t i = 0; i < num_input_buffers; ++i) {
348 input_buffers_[i] = 355 input_buffers_[i] =
349 jni->NewGlobalRef(jni->GetObjectArrayElement(input_buffers, i)); 356 jni->NewGlobalRef(jni->GetObjectArrayElement(input_buffers, i));
350 if (CheckException(jni)) { 357 if (CheckException(jni)) {
351 ALOGE << "NewGlobalRef error - fallback to SW codec."; 358 ALOGE << "NewGlobalRef error - fallback to SW codec.";
352 sw_fallback_required_ = true; 359 sw_fallback_required_ = true;
353 return WEBRTC_VIDEO_CODEC_ERROR; 360 return WEBRTC_VIDEO_CODEC_ERROR;
354 } 361 }
355 } 362 }
356 363
364 if (use_surface_) {
365 jobject surface_texture = GetObjectField(
366 jni, *j_media_codec_video_decoder_, j_surface_texture_field_);
367 if (previous_surface_texture_ != NULL) {
368 jni->DeleteGlobalRef(previous_surface_texture_);
369 }
370 previous_surface_texture_ = surface_texture_;
371 surface_texture_ = jni->NewGlobalRef(surface_texture);
372 }
357 codec_thread_->PostDelayed(kMediaCodecPollMs, this); 373 codec_thread_->PostDelayed(kMediaCodecPollMs, this);
358 374
359 return WEBRTC_VIDEO_CODEC_OK; 375 return WEBRTC_VIDEO_CODEC_OK;
360 } 376 }
361 377
362 int32_t MediaCodecVideoDecoder::Release() { 378 int32_t MediaCodecVideoDecoder::Release() {
363 ALOGD << "DecoderRelease request"; 379 ALOGD << "DecoderRelease request";
364 return codec_thread_->Invoke<int32_t>( 380 return codec_thread_->Invoke<int32_t>(
365 Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this)); 381 Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this));
366 } 382 }
367 383
368 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() { 384 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() {
369 if (!inited_) { 385 if (!inited_) {
370 return WEBRTC_VIDEO_CODEC_OK; 386 return WEBRTC_VIDEO_CODEC_OK;
371 } 387 }
372 CheckOnCodecThread(); 388 CheckOnCodecThread();
373 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 389 JNIEnv* jni = AttachCurrentThreadIfNeeded();
374 ALOGD << "DecoderReleaseOnCodecThread: Frames received: " << frames_received_; 390 ALOGD << "DecoderReleaseOnCodecThread: Frames received: " << frames_received_;
375 ScopedLocalRefFrame local_ref_frame(jni); 391 ScopedLocalRefFrame local_ref_frame(jni);
376 for (size_t i = 0; i < input_buffers_.size(); i++) { 392 for (size_t i = 0; i < input_buffers_.size(); i++) {
377 jni->DeleteGlobalRef(input_buffers_[i]); 393 jni->DeleteGlobalRef(input_buffers_[i]);
378 } 394 }
379 input_buffers_.clear(); 395 input_buffers_.clear();
380 jni->CallVoidMethod(*j_media_codec_video_decoder_, j_release_method_); 396 jni->CallVoidMethod(*j_media_codec_video_decoder_, j_release_method_);
381 surface_texture_helper_ = nullptr;
382 inited_ = false; 397 inited_ = false;
383 rtc::MessageQueueManager::Clear(this); 398 rtc::MessageQueueManager::Clear(this);
384 if (CheckException(jni)) { 399 if (CheckException(jni)) {
385 ALOGE << "Decoder release exception"; 400 ALOGE << "Decoder release exception";
386 return WEBRTC_VIDEO_CODEC_ERROR; 401 return WEBRTC_VIDEO_CODEC_ERROR;
387 } 402 }
388 ALOGD << "DecoderReleaseOnCodecThread done"; 403 ALOGD << "DecoderReleaseOnCodecThread done";
389 return WEBRTC_VIDEO_CODEC_OK; 404 return WEBRTC_VIDEO_CODEC_OK;
390 } 405 }
391 406
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 const EncodedImage& inputImage) { 496 const EncodedImage& inputImage) {
482 CheckOnCodecThread(); 497 CheckOnCodecThread();
483 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 498 JNIEnv* jni = AttachCurrentThreadIfNeeded();
484 ScopedLocalRefFrame local_ref_frame(jni); 499 ScopedLocalRefFrame local_ref_frame(jni);
485 500
486 // Try to drain the decoder and wait until output is not too 501 // Try to drain the decoder and wait until output is not too
487 // much behind the input. 502 // much behind the input.
488 if (frames_received_ > frames_decoded_ + max_pending_frames_) { 503 if (frames_received_ > frames_decoded_ + max_pending_frames_) {
489 ALOGV("Received: %d. Decoded: %d. Wait for output...", 504 ALOGV("Received: %d. Decoded: %d. Wait for output...",
490 frames_received_, frames_decoded_); 505 frames_received_, frames_decoded_);
491 if (!DeliverPendingOutputs(jni, kMediaCodecTimeoutMs)) { 506 if (!DeliverPendingOutputs(jni, kMediaCodecTimeoutMs * 1000)) {
492 ALOGE << "DeliverPendingOutputs error"; 507 ALOGE << "DeliverPendingOutputs error";
493 return ProcessHWErrorOnCodecThread(); 508 return ProcessHWErrorOnCodecThread();
494 } 509 }
495 if (frames_received_ > frames_decoded_ + max_pending_frames_) { 510 if (frames_received_ > frames_decoded_ + max_pending_frames_) {
496 ALOGE << "Output buffer dequeue timeout"; 511 ALOGE << "Output buffer dequeue timeout";
497 return ProcessHWErrorOnCodecThread(); 512 return ProcessHWErrorOnCodecThread();
498 } 513 }
499 } 514 }
500 515
501 // Get input buffer. 516 // Get input buffer.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 // Try to drain the decoder 559 // Try to drain the decoder
545 if (!DeliverPendingOutputs(jni, 0)) { 560 if (!DeliverPendingOutputs(jni, 0)) {
546 ALOGE << "DeliverPendingOutputs error"; 561 ALOGE << "DeliverPendingOutputs error";
547 return ProcessHWErrorOnCodecThread(); 562 return ProcessHWErrorOnCodecThread();
548 } 563 }
549 564
550 return WEBRTC_VIDEO_CODEC_OK; 565 return WEBRTC_VIDEO_CODEC_OK;
551 } 566 }
552 567
553 bool MediaCodecVideoDecoder::DeliverPendingOutputs( 568 bool MediaCodecVideoDecoder::DeliverPendingOutputs(
554 JNIEnv* jni, int dequeue_timeout_ms) { 569 JNIEnv* jni, int dequeue_timeout_us) {
555 if (frames_received_ <= frames_decoded_) { 570 if (frames_received_ <= frames_decoded_) {
556 // No need to query for output buffers - decoder is drained. 571 // No need to query for output buffers - decoder is drained.
557 return true; 572 return true;
558 } 573 }
559 // Get decoder output. 574 // Get decoder output.
560 jobject j_decoder_output_buffer = jni->CallObjectMethod( 575 jobject j_decoder_output_buffer = jni->CallObjectMethod(
561 *j_media_codec_video_decoder_, 576 *j_media_codec_video_decoder_,
562 j_dequeue_output_buffer_method_, 577 j_dequeue_output_buffer_method_,
563 dequeue_timeout_ms); 578 dequeue_timeout_us);
564 if (CheckException(jni)) { 579 if (CheckException(jni)) {
565 ALOGE << "dequeueOutputBuffer() error"; 580 ALOGE << "dequeueOutputBuffer() error";
566 return false; 581 return false;
567 } 582 }
568 if (IsNull(jni, j_decoder_output_buffer)) { 583 if (IsNull(jni, j_decoder_output_buffer)) {
569 // No decoded frame ready. 584 // No decoded frame ready.
570 return true; 585 return true;
571 } 586 }
572 587
573 // Get decoded video frame properties. 588 // Get decoded video frame properties.
574 int color_format = GetIntField(jni, *j_media_codec_video_decoder_, 589 int color_format = GetIntField(jni, *j_media_codec_video_decoder_,
575 j_color_format_field_); 590 j_color_format_field_);
576 int width = GetIntField(jni, *j_media_codec_video_decoder_, j_width_field_); 591 int width = GetIntField(jni, *j_media_codec_video_decoder_, j_width_field_);
577 int height = GetIntField(jni, *j_media_codec_video_decoder_, j_height_field_); 592 int height = GetIntField(jni, *j_media_codec_video_decoder_, j_height_field_);
578 int stride = GetIntField(jni, *j_media_codec_video_decoder_, j_stride_field_); 593 int stride = GetIntField(jni, *j_media_codec_video_decoder_, j_stride_field_);
579 int slice_height = GetIntField(jni, *j_media_codec_video_decoder_, 594 int slice_height = GetIntField(jni, *j_media_codec_video_decoder_,
580 j_slice_height_field_); 595 j_slice_height_field_);
581 596
582 rtc::scoped_refptr<webrtc::VideoFrameBuffer> frame_buffer; 597 rtc::scoped_refptr<webrtc::VideoFrameBuffer> frame_buffer;
583 long output_timestamps_ms = 0; 598 long output_timestamps_ms = 0;
584 if (use_surface_) { 599 if (use_surface_) {
585 // Extract data from Java DecodedTextureBuffer. 600 // Extract data from Java DecodedTextureBuffer.
586 const int texture_id = 601 const int texture_id =
587 GetIntField(jni, j_decoder_output_buffer, j_textureID_field_); 602 GetIntField(jni, j_decoder_output_buffer, j_textureID_field_);
588 const jfloatArray j_transform_matrix = 603 const int64_t timestamp_us =
589 reinterpret_cast<jfloatArray>(GetObjectField( 604 GetLongField(jni, j_decoder_output_buffer,
590 jni, j_decoder_output_buffer, j_transform_matrix_field_)); 605 j_texture_presentation_timestamp_us_field_);
591 const int64_t timestamp_ns = GetLongField(jni, j_decoder_output_buffer, 606 output_timestamps_ms = timestamp_us / rtc::kNumMicrosecsPerMillisec;
592 j_texture_timestamp_ns_field_);
593 output_timestamps_ms = timestamp_ns / rtc::kNumNanosecsPerMillisec;
594 // Create webrtc::VideoFrameBuffer with native texture handle. 607 // Create webrtc::VideoFrameBuffer with native texture handle.
595 frame_buffer = surface_texture_helper_->CreateTextureFrame( 608 native_handle_.SetTextureObject(surface_texture_, texture_id);
596 width, height, NativeHandleImpl(jni, texture_id, j_transform_matrix)); 609 frame_buffer = new rtc::RefCountedObject<JniNativeHandleBuffer>(
610 &native_handle_, width, height);
597 } else { 611 } else {
598 // Extract data from Java ByteBuffer and create output yuv420 frame - 612 // Extract data from Java ByteBuffer and create output yuv420 frame -
599 // for non surface decoding only. 613 // for non surface decoding only.
600 const int output_buffer_index = 614 const int output_buffer_index =
601 GetIntField(jni, j_decoder_output_buffer, j_info_index_field_); 615 GetIntField(jni, j_decoder_output_buffer, j_info_index_field_);
602 const int output_buffer_offset = 616 const int output_buffer_offset =
603 GetIntField(jni, j_decoder_output_buffer, j_info_offset_field_); 617 GetIntField(jni, j_decoder_output_buffer, j_info_offset_field_);
604 const int output_buffer_size = 618 const int output_buffer_size =
605 GetIntField(jni, j_decoder_output_buffer, j_info_size_field_); 619 GetIntField(jni, j_decoder_output_buffer, j_info_size_field_);
606 const int64_t timestamp_us = GetLongField( 620 const int64_t timestamp_us = GetLongField(
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 } 846 }
833 847
834 void MediaCodecVideoDecoderFactory::DestroyVideoDecoder( 848 void MediaCodecVideoDecoderFactory::DestroyVideoDecoder(
835 webrtc::VideoDecoder* decoder) { 849 webrtc::VideoDecoder* decoder) {
836 ALOGD << "Destroy video decoder."; 850 ALOGD << "Destroy video decoder.";
837 delete decoder; 851 delete decoder;
838 } 852 }
839 853
840 } // namespace webrtc_jni 854 } // namespace webrtc_jni
841 855
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698