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

Side by Side Diff: webrtc/sdk/android/src/jni/videodecoderwrapper.cc

Issue 3009613002: Android: Replace webrtc_jni namespace with nested jni namespace (Closed)
Patch Set: Rebase Created 3 years, 3 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 * Copyright 2017 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/sdk/android/src/jni/videodecoderwrapper.h" 11 #include "webrtc/sdk/android/src/jni/videodecoderwrapper.h"
12 12
13 #include "webrtc/api/video/video_frame.h" 13 #include "webrtc/api/video/video_frame.h"
14 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 14 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
15 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h" 15 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h"
16 #include "webrtc/modules/video_coding/utility/vp9_uncompressed_header_parser.h" 16 #include "webrtc/modules/video_coding/utility/vp9_uncompressed_header_parser.h"
17 #include "webrtc/rtc_base/logging.h" 17 #include "webrtc/rtc_base/logging.h"
18 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" 18 #include "webrtc/sdk/android/src/jni/classreferenceholder.h"
19 19
20 namespace webrtc_jni { 20 namespace webrtc {
21 namespace jni {
21 22
22 VideoDecoderWrapper::VideoDecoderWrapper(JNIEnv* jni, jobject decoder) 23 VideoDecoderWrapper::VideoDecoderWrapper(JNIEnv* jni, jobject decoder)
23 : android_video_buffer_factory_(jni), 24 : android_video_buffer_factory_(jni),
24 decoder_(jni, decoder), 25 decoder_(jni, decoder),
25 encoded_image_class_(jni, FindClass(jni, "org/webrtc/EncodedImage")), 26 encoded_image_class_(jni, FindClass(jni, "org/webrtc/EncodedImage")),
26 frame_type_class_(jni, 27 frame_type_class_(jni,
27 FindClass(jni, "org/webrtc/EncodedImage$FrameType")), 28 FindClass(jni, "org/webrtc/EncodedImage$FrameType")),
28 settings_class_(jni, FindClass(jni, "org/webrtc/VideoDecoder$Settings")), 29 settings_class_(jni, FindClass(jni, "org/webrtc/VideoDecoder$Settings")),
29 video_frame_class_(jni, FindClass(jni, "org/webrtc/VideoFrame")), 30 video_frame_class_(jni, FindClass(jni, "org/webrtc/VideoFrame")),
30 video_codec_status_class_(jni, 31 video_codec_status_class_(jni,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 jni->GetMethodID(*video_codec_status_class_, "getNumber", "()I"); 70 jni->GetMethodID(*video_codec_status_class_, "getNumber", "()I");
70 71
71 integer_constructor_ = jni->GetMethodID(*integer_class_, "<init>", "(I)V"); 72 integer_constructor_ = jni->GetMethodID(*integer_class_, "<init>", "(I)V");
72 int_value_method_ = jni->GetMethodID(*integer_class_, "intValue", "()I"); 73 int_value_method_ = jni->GetMethodID(*integer_class_, "intValue", "()I");
73 74
74 initialized_ = false; 75 initialized_ = false;
75 // QP parsing starts enabled and we disable it if the decoder provides frames. 76 // QP parsing starts enabled and we disable it if the decoder provides frames.
76 qp_parsing_enabled_ = true; 77 qp_parsing_enabled_ = true;
77 } 78 }
78 79
79 int32_t VideoDecoderWrapper::InitDecode( 80 int32_t VideoDecoderWrapper::InitDecode(const VideoCodec* codec_settings,
80 const webrtc::VideoCodec* codec_settings, 81 int32_t number_of_cores) {
81 int32_t number_of_cores) {
82 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 82 JNIEnv* jni = AttachCurrentThreadIfNeeded();
83 ScopedLocalRefFrame local_ref_frame(jni); 83 ScopedLocalRefFrame local_ref_frame(jni);
84 84
85 codec_settings_ = *codec_settings; 85 codec_settings_ = *codec_settings;
86 number_of_cores_ = number_of_cores; 86 number_of_cores_ = number_of_cores;
87 return InitDecodeInternal(jni); 87 return InitDecodeInternal(jni);
88 } 88 }
89 89
90 int32_t VideoDecoderWrapper::InitDecodeInternal(JNIEnv* jni) { 90 int32_t VideoDecoderWrapper::InitDecodeInternal(JNIEnv* jni) {
91 jobject settings = 91 jobject settings =
(...skipping 14 matching lines...) Expand all
106 } 106 }
107 107
108 // The decoder was reinitialized so re-enable the QP parsing in case it stops 108 // The decoder was reinitialized so re-enable the QP parsing in case it stops
109 // providing QP values. 109 // providing QP values.
110 qp_parsing_enabled_ = true; 110 qp_parsing_enabled_ = true;
111 111
112 return HandleReturnCode(jni, ret); 112 return HandleReturnCode(jni, ret);
113 } 113 }
114 114
115 int32_t VideoDecoderWrapper::Decode( 115 int32_t VideoDecoderWrapper::Decode(
116 const webrtc::EncodedImage& input_image, 116 const EncodedImage& input_image,
117 bool missing_frames, 117 bool missing_frames,
118 const webrtc::RTPFragmentationHeader* fragmentation, 118 const RTPFragmentationHeader* fragmentation,
119 const webrtc::CodecSpecificInfo* codec_specific_info, 119 const CodecSpecificInfo* codec_specific_info,
120 int64_t render_time_ms) { 120 int64_t render_time_ms) {
121 if (!initialized_) { 121 if (!initialized_) {
122 // Most likely initializing the codec failed. 122 // Most likely initializing the codec failed.
123 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 123 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
124 } 124 }
125 125
126 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 126 JNIEnv* jni = AttachCurrentThreadIfNeeded();
127 ScopedLocalRefFrame local_ref_frame(jni); 127 ScopedLocalRefFrame local_ref_frame(jni);
128 128
129 FrameExtraInfo frame_extra_info; 129 FrameExtraInfo frame_extra_info;
130 frame_extra_info.capture_time_ms = input_image.capture_time_ms_; 130 frame_extra_info.capture_time_ms = input_image.capture_time_ms_;
131 frame_extra_info.timestamp_rtp = input_image._timeStamp; 131 frame_extra_info.timestamp_rtp = input_image._timeStamp;
132 frame_extra_info.qp = 132 frame_extra_info.qp =
133 qp_parsing_enabled_ ? ParseQP(input_image) : rtc::Optional<uint8_t>(); 133 qp_parsing_enabled_ ? ParseQP(input_image) : rtc::Optional<uint8_t>();
134 frame_extra_infos_.push_back(frame_extra_info); 134 frame_extra_infos_.push_back(frame_extra_info);
135 135
136 jobject jinput_image = 136 jobject jinput_image =
137 ConvertEncodedImageToJavaEncodedImage(jni, input_image); 137 ConvertEncodedImageToJavaEncodedImage(jni, input_image);
138 jobject ret = 138 jobject ret =
139 jni->CallObjectMethod(*decoder_, decode_method_, jinput_image, nullptr); 139 jni->CallObjectMethod(*decoder_, decode_method_, jinput_image, nullptr);
140 return HandleReturnCode(jni, ret); 140 return HandleReturnCode(jni, ret);
141 } 141 }
142 142
143 int32_t VideoDecoderWrapper::RegisterDecodeCompleteCallback( 143 int32_t VideoDecoderWrapper::RegisterDecodeCompleteCallback(
144 webrtc::DecodedImageCallback* callback) { 144 DecodedImageCallback* callback) {
145 callback_ = callback; 145 callback_ = callback;
146 return WEBRTC_VIDEO_CODEC_OK; 146 return WEBRTC_VIDEO_CODEC_OK;
147 } 147 }
148 148
149 int32_t VideoDecoderWrapper::Release() { 149 int32_t VideoDecoderWrapper::Release() {
150 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 150 JNIEnv* jni = AttachCurrentThreadIfNeeded();
151 ScopedLocalRefFrame local_ref_frame(jni); 151 ScopedLocalRefFrame local_ref_frame(jni);
152 jobject ret = jni->CallObjectMethod(*decoder_, release_method_); 152 jobject ret = jni->CallObjectMethod(*decoder_, release_method_);
153 frame_extra_infos_.clear(); 153 frame_extra_infos_.clear();
154 initialized_ = false; 154 initialized_ = false;
(...skipping 26 matching lines...) Expand all
181 LOG(LS_WARNING) << "Java decoder produced an unexpected frame."; 181 LOG(LS_WARNING) << "Java decoder produced an unexpected frame.";
182 return; 182 return;
183 } 183 }
184 184
185 frame_extra_info = frame_extra_infos_.front(); 185 frame_extra_info = frame_extra_infos_.front();
186 frame_extra_infos_.pop_front(); 186 frame_extra_infos_.pop_front();
187 // If the decoder might drop frames so iterate through the queue until we 187 // If the decoder might drop frames so iterate through the queue until we
188 // find a matching timestamp. 188 // find a matching timestamp.
189 } while (frame_extra_info.capture_time_ms != capture_time_ms); 189 } while (frame_extra_info.capture_time_ms != capture_time_ms);
190 190
191 webrtc::VideoFrame frame = android_video_buffer_factory_.CreateFrame( 191 VideoFrame frame = android_video_buffer_factory_.CreateFrame(
192 jni, jframe, frame_extra_info.timestamp_rtp); 192 jni, jframe, frame_extra_info.timestamp_rtp);
193 193
194 rtc::Optional<int32_t> decoding_time_ms; 194 rtc::Optional<int32_t> decoding_time_ms;
195 if (jdecode_time_ms != nullptr) { 195 if (jdecode_time_ms != nullptr) {
196 decoding_time_ms = rtc::Optional<int32_t>( 196 decoding_time_ms = rtc::Optional<int32_t>(
197 jni->CallIntMethod(jdecode_time_ms, int_value_method_)); 197 jni->CallIntMethod(jdecode_time_ms, int_value_method_));
198 } 198 }
199 199
200 rtc::Optional<uint8_t> qp; 200 rtc::Optional<uint8_t> qp;
201 if (jqp != nullptr) { 201 if (jqp != nullptr) {
202 qp = rtc::Optional<uint8_t>(jni->CallIntMethod(jqp, int_value_method_)); 202 qp = rtc::Optional<uint8_t>(jni->CallIntMethod(jqp, int_value_method_));
203 // The decoder provides QP values itself, no need to parse the bitstream. 203 // The decoder provides QP values itself, no need to parse the bitstream.
204 qp_parsing_enabled_ = false; 204 qp_parsing_enabled_ = false;
205 } else { 205 } else {
206 qp = frame_extra_info.qp; 206 qp = frame_extra_info.qp;
207 // The decoder doesn't provide QP values, ensure bitstream parsing is 207 // The decoder doesn't provide QP values, ensure bitstream parsing is
208 // enabled. 208 // enabled.
209 qp_parsing_enabled_ = true; 209 qp_parsing_enabled_ = true;
210 } 210 }
211 211
212 callback_->Decoded(frame, decoding_time_ms, qp); 212 callback_->Decoded(frame, decoding_time_ms, qp);
213 } 213 }
214 214
215 jobject VideoDecoderWrapper::ConvertEncodedImageToJavaEncodedImage( 215 jobject VideoDecoderWrapper::ConvertEncodedImageToJavaEncodedImage(
216 JNIEnv* jni, 216 JNIEnv* jni,
217 const webrtc::EncodedImage& image) { 217 const EncodedImage& image) {
218 jobject buffer = jni->NewDirectByteBuffer(image._buffer, image._length); 218 jobject buffer = jni->NewDirectByteBuffer(image._buffer, image._length);
219 jfieldID frame_type_field; 219 jfieldID frame_type_field;
220 switch (image._frameType) { 220 switch (image._frameType) {
221 case webrtc::kEmptyFrame: 221 case kEmptyFrame:
222 frame_type_field = empty_frame_field_; 222 frame_type_field = empty_frame_field_;
223 break; 223 break;
224 case webrtc::kVideoFrameKey: 224 case kVideoFrameKey:
225 frame_type_field = video_frame_key_field_; 225 frame_type_field = video_frame_key_field_;
226 break; 226 break;
227 case webrtc::kVideoFrameDelta: 227 case kVideoFrameDelta:
228 frame_type_field = video_frame_delta_field_; 228 frame_type_field = video_frame_delta_field_;
229 break; 229 break;
230 default: 230 default:
231 RTC_NOTREACHED(); 231 RTC_NOTREACHED();
232 return nullptr; 232 return nullptr;
233 } 233 }
234 jobject frame_type = 234 jobject frame_type =
235 jni->GetStaticObjectField(*frame_type_class_, frame_type_field); 235 jni->GetStaticObjectField(*frame_type_class_, frame_type_field);
236 jobject qp = nullptr; 236 jobject qp = nullptr;
237 if (image.qp_ != -1) { 237 if (image.qp_ != -1) {
(...skipping 16 matching lines...) Expand all
254 } 254 }
255 255
256 LOG(LS_WARNING) << "Falling back to software decoder."; 256 LOG(LS_WARNING) << "Falling back to software decoder.";
257 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 257 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
258 } else { 258 } else {
259 return value; 259 return value;
260 } 260 }
261 } 261 }
262 262
263 rtc::Optional<uint8_t> VideoDecoderWrapper::ParseQP( 263 rtc::Optional<uint8_t> VideoDecoderWrapper::ParseQP(
264 const webrtc::EncodedImage& input_image) { 264 const EncodedImage& input_image) {
265 if (input_image.qp_ != -1) { 265 if (input_image.qp_ != -1) {
266 return rtc::Optional<uint8_t>(input_image.qp_); 266 return rtc::Optional<uint8_t>(input_image.qp_);
267 } 267 }
268 268
269 rtc::Optional<uint8_t> qp; 269 rtc::Optional<uint8_t> qp;
270 switch (codec_settings_.codecType) { 270 switch (codec_settings_.codecType) {
271 case webrtc::kVideoCodecVP8: { 271 case kVideoCodecVP8: {
272 int qp_int; 272 int qp_int;
273 if (webrtc::vp8::GetQp(input_image._buffer, input_image._length, 273 if (vp8::GetQp(input_image._buffer, input_image._length, &qp_int)) {
274 &qp_int)) {
275 qp = rtc::Optional<uint8_t>(qp_int); 274 qp = rtc::Optional<uint8_t>(qp_int);
276 } 275 }
277 break; 276 break;
278 } 277 }
279 case webrtc::kVideoCodecVP9: { 278 case kVideoCodecVP9: {
280 int qp_int; 279 int qp_int;
281 if (webrtc::vp9::GetQp(input_image._buffer, input_image._length, 280 if (vp9::GetQp(input_image._buffer, input_image._length, &qp_int)) {
282 &qp_int)) {
283 qp = rtc::Optional<uint8_t>(qp_int); 281 qp = rtc::Optional<uint8_t>(qp_int);
284 } 282 }
285 break; 283 break;
286 } 284 }
287 case webrtc::kVideoCodecH264: { 285 case kVideoCodecH264: {
288 h264_bitstream_parser_.ParseBitstream(input_image._buffer, 286 h264_bitstream_parser_.ParseBitstream(input_image._buffer,
289 input_image._length); 287 input_image._length);
290 int qp_int; 288 int qp_int;
291 if (h264_bitstream_parser_.GetLastSliceQp(&qp_int)) { 289 if (h264_bitstream_parser_.GetLastSliceQp(&qp_int)) {
292 qp = rtc::Optional<uint8_t>(qp_int); 290 qp = rtc::Optional<uint8_t>(qp_int);
293 } 291 }
294 break; 292 break;
295 } 293 }
296 default: 294 default:
297 break; // Default is to not provide QP. 295 break; // Default is to not provide QP.
298 } 296 }
299 return qp; 297 return qp;
300 } 298 }
301 299
302 JNI_FUNCTION_DECLARATION(void, 300 JNI_FUNCTION_DECLARATION(void,
303 VideoDecoderWrapperCallback_nativeOnDecodedFrame, 301 VideoDecoderWrapperCallback_nativeOnDecodedFrame,
304 JNIEnv* jni, 302 JNIEnv* jni,
305 jclass, 303 jclass,
306 jlong jnative_decoder, 304 jlong jnative_decoder,
307 jobject jframe, 305 jobject jframe,
308 jobject jdecode_time_ms, 306 jobject jdecode_time_ms,
309 jobject jqp) { 307 jobject jqp) {
310 VideoDecoderWrapper* native_decoder = 308 VideoDecoderWrapper* native_decoder =
311 reinterpret_cast<VideoDecoderWrapper*>(jnative_decoder); 309 reinterpret_cast<VideoDecoderWrapper*>(jnative_decoder);
312 native_decoder->OnDecodedFrame(jni, jframe, jdecode_time_ms, jqp); 310 native_decoder->OnDecodedFrame(jni, jframe, jdecode_time_ms, jqp);
313 } 311 }
314 312
315 } // namespace webrtc_jni 313 } // namespace jni
314 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/sdk/android/src/jni/videodecoderwrapper.h ('k') | webrtc/sdk/android/src/jni/videofilerenderer_jni.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698