diff options
author | glaznev@webrtc.org <glaznev@webrtc.org> | 2014-09-19 19:36:13 +0000 |
---|---|---|
committer | glaznev@webrtc.org <glaznev@webrtc.org> | 2014-09-19 19:36:13 +0000 |
commit | 88b24bb6406739ee83a491dca2d9ad59e5910c6c (patch) | |
tree | 7870f1c6a174234ff61b9ccb438f3de134cf3a20 | |
parent | 1a6b25ecc4c1c0af85cf879348cf8c965f3edf07 (diff) | |
download | talk-88b24bb6406739ee83a491dca2d9ad59e5910c6c.tar.gz |
Fix HW video decoder crash on some Android KK devices.
Remove direct access to decoder Java output buffer memory
when HW decoder is configured to decode to surface.
-
R=tkchin@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/30459005
git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7249 4adac7df-926f-26a2-2b94-8c16560cd09d
-rw-r--r-- | app/webrtc/java/jni/peerconnection_jni.cc | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/app/webrtc/java/jni/peerconnection_jni.cc b/app/webrtc/java/jni/peerconnection_jni.cc index ba54071..38f1e90 100644 --- a/app/webrtc/java/jni/peerconnection_jni.cc +++ b/app/webrtc/java/jni/peerconnection_jni.cc @@ -2393,7 +2393,7 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs( return true; } - // Extract data from Java DecoderOutputBufferInfo. + // Extract output buffer info from Java DecoderOutputBufferInfo. int output_buffer_index = GetIntField(jni, j_decoder_output_buffer_info, j_info_index_field_); if (output_buffer_index < 0) { @@ -2407,15 +2407,6 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs( GetIntField(jni, j_decoder_output_buffer_info, j_info_size_field_); CHECK_EXCEPTION(jni); - // Extract data from Java ByteBuffer. - jobjectArray output_buffers = reinterpret_cast<jobjectArray>(GetObjectField( - jni, *j_media_codec_video_decoder_, j_output_buffers_field_)); - jobject output_buffer = - jni->GetObjectArrayElement(output_buffers, output_buffer_index); - uint8_t* payload = - reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(output_buffer)); - CHECK_EXCEPTION(jni); - payload += output_buffer_offset; // Get decoded video frame properties. int color_format = GetIntField(jni, *j_media_codec_video_decoder_, j_color_format_field_); @@ -2426,27 +2417,25 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs( j_slice_height_field_); int texture_id = GetIntField(jni, *j_media_codec_video_decoder_, j_textureID_field_); - if (!use_surface_ && output_buffer_size < width * height * 3 / 2) { - ALOGE("Insufficient output buffer size: %d", output_buffer_size); - Reset(); - return false; - } - // Get frame timestamps from a queue. - int32_t timestamp = timestamps_.front(); - timestamps_.erase(timestamps_.begin()); - int64_t ntp_time_ms = ntp_times_ms_.front(); - ntp_times_ms_.erase(ntp_times_ms_.begin()); - int64_t frame_decoding_time_ms = GetCurrentTimeMs() - - frame_rtc_times_ms_.front(); - frame_rtc_times_ms_.erase(frame_rtc_times_ms_.begin()); - - ALOGV("Decoder frame out # %d. %d x %d. %d x %d. Color: 0x%x. Size: %d." - " DecTime: %lld", frames_decoded_, width, height, stride, slice_height, - color_format, output_buffer_size, frame_decoding_time_ms); - - // Create yuv420 frame. + // Extract data from Java ByteBuffer and create output yuv420 frame - + // for non surface decoding only. if (!use_surface_) { + if (output_buffer_size < width * height * 3 / 2) { + ALOGE("Insufficient output buffer size: %d", output_buffer_size); + Reset(); + return false; + } + jobjectArray output_buffers = reinterpret_cast<jobjectArray>(GetObjectField( + jni, *j_media_codec_video_decoder_, j_output_buffers_field_)); + jobject output_buffer = + jni->GetObjectArrayElement(output_buffers, output_buffer_index); + uint8_t* payload = reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress( + output_buffer)); + CHECK_EXCEPTION(jni); + payload += output_buffer_offset; + + // Create yuv420 frame. if (color_format == COLOR_FormatYUV420Planar) { decoded_image_.CreateFrame( stride * slice_height, payload, @@ -2471,11 +2460,25 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs( } } + // Get frame timestamps from a queue. + int32_t timestamp = timestamps_.front(); + timestamps_.erase(timestamps_.begin()); + int64_t ntp_time_ms = ntp_times_ms_.front(); + ntp_times_ms_.erase(ntp_times_ms_.begin()); + int64_t frame_decoding_time_ms = GetCurrentTimeMs() - + frame_rtc_times_ms_.front(); + frame_rtc_times_ms_.erase(frame_rtc_times_ms_.begin()); + + ALOGV("Decoder frame out # %d. %d x %d. %d x %d. Color: 0x%x. Size: %d." + " DecTime: %lld", frames_decoded_, width, height, stride, slice_height, + color_format, output_buffer_size, frame_decoding_time_ms); + // Return output buffer back to codec. - bool success = jni->CallBooleanMethod(*j_media_codec_video_decoder_, - j_release_output_buffer_method_, - output_buffer_index, - use_surface_); + bool success = jni->CallBooleanMethod( + *j_media_codec_video_decoder_, + j_release_output_buffer_method_, + output_buffer_index, + use_surface_); CHECK_EXCEPTION(jni); if (!success) { ALOGE("releaseOutputBuffer error"); |