OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2015 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 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 #include "webrtc/sdk/android/src/jni/androidmediacodeccommon.h" | 43 #include "webrtc/sdk/android/src/jni/androidmediacodeccommon.h" |
44 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" | 44 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" |
45 #include "webrtc/sdk/android/src/jni/jni_helpers.h" | 45 #include "webrtc/sdk/android/src/jni/jni_helpers.h" |
46 #include "webrtc/sdk/android/src/jni/native_handle_impl.h" | 46 #include "webrtc/sdk/android/src/jni/native_handle_impl.h" |
47 #include "webrtc/system_wrappers/include/field_trial.h" | 47 #include "webrtc/system_wrappers/include/field_trial.h" |
48 | 48 |
49 using rtc::Bind; | 49 using rtc::Bind; |
50 using rtc::Thread; | 50 using rtc::Thread; |
51 using rtc::ThreadManager; | 51 using rtc::ThreadManager; |
52 | 52 |
53 using webrtc::CodecSpecificInfo; | 53 namespace webrtc { |
54 using webrtc::EncodedImage; | 54 namespace jni { |
55 using webrtc::VideoFrame; | |
56 using webrtc::RTPFragmentationHeader; | |
57 using webrtc::VideoCodec; | |
58 using webrtc::VideoCodecType; | |
59 using webrtc::kVideoCodecH264; | |
60 using webrtc::kVideoCodecVP8; | |
61 using webrtc::kVideoCodecVP9; | |
62 using webrtc::QualityScaler; | |
63 | |
64 namespace webrtc_jni { | |
65 | 55 |
66 // Maximum supported HW video encoder fps. | 56 // Maximum supported HW video encoder fps. |
67 #define MAX_VIDEO_FPS 30 | 57 #define MAX_VIDEO_FPS 30 |
68 // Maximum allowed fps value in SetRates() call. | 58 // Maximum allowed fps value in SetRates() call. |
69 #define MAX_ALLOWED_VIDEO_FPS 60 | 59 #define MAX_ALLOWED_VIDEO_FPS 60 |
70 // Maximum allowed frames in encoder input queue. | 60 // Maximum allowed frames in encoder input queue. |
71 #define MAX_ENCODER_Q_SIZE 2 | 61 #define MAX_ENCODER_Q_SIZE 2 |
72 // Maximum amount of dropped frames caused by full encoder queue - exceeding | 62 // Maximum amount of dropped frames caused by full encoder queue - exceeding |
73 // this threshold means that encoder probably got stuck and need to be reset. | 63 // this threshold means that encoder probably got stuck and need to be reset. |
74 #define ENCODER_STALL_FRAMEDROP_THRESHOLD 60 | 64 #define ENCODER_STALL_FRAMEDROP_THRESHOLD 60 |
(...skipping 11 matching lines...) Expand all Loading... |
86 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_ENCODER) | 76 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_ENCODER) |
87 | 77 |
88 namespace { | 78 namespace { |
89 // Maximum time limit between incoming frames before requesting a key frame. | 79 // Maximum time limit between incoming frames before requesting a key frame. |
90 const size_t kFrameDiffThresholdMs = 350; | 80 const size_t kFrameDiffThresholdMs = 350; |
91 const int kMinKeyFrameInterval = 6; | 81 const int kMinKeyFrameInterval = 6; |
92 const char kH264HighProfileFieldTrial[] = "WebRTC-H264HighProfile"; | 82 const char kH264HighProfileFieldTrial[] = "WebRTC-H264HighProfile"; |
93 const char kCustomQPThresholdsFieldTrial[] = "WebRTC-CustomQPThresholds"; | 83 const char kCustomQPThresholdsFieldTrial[] = "WebRTC-CustomQPThresholds"; |
94 } // namespace | 84 } // namespace |
95 | 85 |
96 // MediaCodecVideoEncoder is a webrtc::VideoEncoder implementation that uses | 86 // MediaCodecVideoEncoder is a VideoEncoder implementation that uses |
97 // Android's MediaCodec SDK API behind the scenes to implement (hopefully) | 87 // Android's MediaCodec SDK API behind the scenes to implement (hopefully) |
98 // HW-backed video encode. This C++ class is implemented as a very thin shim, | 88 // HW-backed video encode. This C++ class is implemented as a very thin shim, |
99 // delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder. | 89 // delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder. |
100 // MediaCodecVideoEncoder must be operated on a single task queue, currently | 90 // MediaCodecVideoEncoder must be operated on a single task queue, currently |
101 // this is the encoder queue from ViE encoder. | 91 // this is the encoder queue from ViE encoder. |
102 class MediaCodecVideoEncoder : public webrtc::VideoEncoder { | 92 class MediaCodecVideoEncoder : public VideoEncoder { |
103 public: | 93 public: |
104 virtual ~MediaCodecVideoEncoder(); | 94 virtual ~MediaCodecVideoEncoder(); |
105 MediaCodecVideoEncoder(JNIEnv* jni, | 95 MediaCodecVideoEncoder(JNIEnv* jni, |
106 const cricket::VideoCodec& codec, | 96 const cricket::VideoCodec& codec, |
107 jobject egl_context); | 97 jobject egl_context); |
108 | 98 |
109 // webrtc::VideoEncoder implementation. | 99 // VideoEncoder implementation. |
110 int32_t InitEncode(const webrtc::VideoCodec* codec_settings, | 100 int32_t InitEncode(const VideoCodec* codec_settings, |
111 int32_t /* number_of_cores */, | 101 int32_t /* number_of_cores */, |
112 size_t /* max_payload_size */) override; | 102 size_t /* max_payload_size */) override; |
113 int32_t Encode(const webrtc::VideoFrame& input_image, | 103 int32_t Encode(const VideoFrame& input_image, |
114 const webrtc::CodecSpecificInfo* /* codec_specific_info */, | 104 const CodecSpecificInfo* /* codec_specific_info */, |
115 const std::vector<webrtc::FrameType>* frame_types) override; | 105 const std::vector<FrameType>* frame_types) override; |
116 int32_t RegisterEncodeCompleteCallback( | 106 int32_t RegisterEncodeCompleteCallback( |
117 webrtc::EncodedImageCallback* callback) override; | 107 EncodedImageCallback* callback) override; |
118 int32_t Release() override; | 108 int32_t Release() override; |
119 int32_t SetChannelParameters(uint32_t /* packet_loss */, | 109 int32_t SetChannelParameters(uint32_t /* packet_loss */, |
120 int64_t /* rtt */) override; | 110 int64_t /* rtt */) override; |
121 int32_t SetRateAllocation(const webrtc::BitrateAllocation& rate_allocation, | 111 int32_t SetRateAllocation(const BitrateAllocation& rate_allocation, |
122 uint32_t frame_rate) override; | 112 uint32_t frame_rate) override; |
123 | 113 |
124 bool SupportsNativeHandle() const override { return egl_context_ != nullptr; } | 114 bool SupportsNativeHandle() const override { return egl_context_ != nullptr; } |
125 const char* ImplementationName() const override; | 115 const char* ImplementationName() const override; |
126 | 116 |
127 // Fills the input buffer with data from the buffers passed as parameters. | 117 // Fills the input buffer with data from the buffers passed as parameters. |
128 bool FillInputBuffer(JNIEnv* jni, | 118 bool FillInputBuffer(JNIEnv* jni, |
129 int input_buffer_index, | 119 int input_buffer_index, |
130 uint8_t const* buffer_y, | 120 uint8_t const* buffer_y, |
131 int stride_y, | 121 int stride_y, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 // previously-current values are reused instead of the passed parameters | 153 // previously-current values are reused instead of the passed parameters |
164 // (makes it easier to reason about thread-safety). | 154 // (makes it easier to reason about thread-safety). |
165 int32_t InitEncodeInternal(int width, | 155 int32_t InitEncodeInternal(int width, |
166 int height, | 156 int height, |
167 int kbps, | 157 int kbps, |
168 int fps, | 158 int fps, |
169 bool use_surface); | 159 bool use_surface); |
170 // Reconfigure to match |frame| in width, height. Also reconfigures the | 160 // Reconfigure to match |frame| in width, height. Also reconfigures the |
171 // encoder if |frame| is a texture/byte buffer and the encoder is initialized | 161 // encoder if |frame| is a texture/byte buffer and the encoder is initialized |
172 // for byte buffer/texture. Returns false if reconfiguring fails. | 162 // for byte buffer/texture. Returns false if reconfiguring fails. |
173 bool MaybeReconfigureEncoder(JNIEnv* jni, const webrtc::VideoFrame& frame); | 163 bool MaybeReconfigureEncoder(JNIEnv* jni, const VideoFrame& frame); |
174 | 164 |
175 // Returns true if the frame is a texture frame and we should use surface | 165 // Returns true if the frame is a texture frame and we should use surface |
176 // based encoding. | 166 // based encoding. |
177 bool IsTextureFrame(JNIEnv* jni, const webrtc::VideoFrame& frame); | 167 bool IsTextureFrame(JNIEnv* jni, const VideoFrame& frame); |
178 | 168 |
179 bool EncodeByteBuffer(JNIEnv* jni, | 169 bool EncodeByteBuffer(JNIEnv* jni, |
180 bool key_frame, | 170 bool key_frame, |
181 const webrtc::VideoFrame& frame, | 171 const VideoFrame& frame, |
182 int input_buffer_index); | 172 int input_buffer_index); |
183 bool EncodeTexture(JNIEnv* jni, | 173 bool EncodeTexture(JNIEnv* jni, bool key_frame, const VideoFrame& frame); |
184 bool key_frame, | |
185 const webrtc::VideoFrame& frame); | |
186 // Encodes a new style org.webrtc.VideoFrame. Might be a I420 or a texture | 174 // Encodes a new style org.webrtc.VideoFrame. Might be a I420 or a texture |
187 // frame. | 175 // frame. |
188 bool EncodeJavaFrame(JNIEnv* jni, | 176 bool EncodeJavaFrame(JNIEnv* jni, |
189 bool key_frame, | 177 bool key_frame, |
190 jobject frame, | 178 jobject frame, |
191 int input_buffer_index); | 179 int input_buffer_index); |
192 | 180 |
193 // Helper accessors for MediaCodecVideoEncoder$OutputBufferInfo members. | 181 // Helper accessors for MediaCodecVideoEncoder$OutputBufferInfo members. |
194 int GetOutputBufferInfoIndex(JNIEnv* jni, jobject j_output_buffer_info); | 182 int GetOutputBufferInfoIndex(JNIEnv* jni, jobject j_output_buffer_info); |
195 jobject GetOutputBufferInfoBuffer(JNIEnv* jni, jobject j_output_buffer_info); | 183 jobject GetOutputBufferInfoBuffer(JNIEnv* jni, jobject j_output_buffer_info); |
(...skipping 16 matching lines...) Expand all Loading... |
212 // Mutex for protecting inited_. It is only used for correctness checking on | 200 // Mutex for protecting inited_. It is only used for correctness checking on |
213 // debug build. It is used for checking that encoder has been released in the | 201 // debug build. It is used for checking that encoder has been released in the |
214 // destructor. Because this might happen on a different thread, we need a | 202 // destructor. Because this might happen on a different thread, we need a |
215 // mutex. | 203 // mutex. |
216 rtc::CriticalSection inited_crit_; | 204 rtc::CriticalSection inited_crit_; |
217 #endif | 205 #endif |
218 | 206 |
219 // Type of video codec. | 207 // Type of video codec. |
220 const cricket::VideoCodec codec_; | 208 const cricket::VideoCodec codec_; |
221 | 209 |
222 webrtc::EncodedImageCallback* callback_; | 210 EncodedImageCallback* callback_; |
223 | 211 |
224 // State that is constant for the lifetime of this object once the ctor | 212 // State that is constant for the lifetime of this object once the ctor |
225 // returns. | 213 // returns. |
226 rtc::SequencedTaskChecker encoder_queue_checker_; | 214 rtc::SequencedTaskChecker encoder_queue_checker_; |
227 ScopedGlobalRef<jclass> j_media_codec_video_encoder_class_; | 215 ScopedGlobalRef<jclass> j_media_codec_video_encoder_class_; |
228 ScopedGlobalRef<jobject> j_media_codec_video_encoder_; | 216 ScopedGlobalRef<jobject> j_media_codec_video_encoder_; |
229 jmethodID j_init_encode_method_; | 217 jmethodID j_init_encode_method_; |
230 jmethodID j_get_input_buffers_method_; | 218 jmethodID j_get_input_buffers_method_; |
231 jmethodID j_dequeue_input_buffer_method_; | 219 jmethodID j_dequeue_input_buffer_method_; |
232 jmethodID j_encode_buffer_method_; | 220 jmethodID j_encode_buffer_method_; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 int current_encoding_time_ms_; // Overall encoding time in the current second | 254 int current_encoding_time_ms_; // Overall encoding time in the current second |
267 int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame. | 255 int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame. |
268 int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame. | 256 int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame. |
269 // Holds the task while the polling loop is paused. | 257 // Holds the task while the polling loop is paused. |
270 std::unique_ptr<rtc::QueuedTask> encode_task_; | 258 std::unique_ptr<rtc::QueuedTask> encode_task_; |
271 | 259 |
272 struct InputFrameInfo { | 260 struct InputFrameInfo { |
273 InputFrameInfo(int64_t encode_start_time, | 261 InputFrameInfo(int64_t encode_start_time, |
274 int32_t frame_timestamp, | 262 int32_t frame_timestamp, |
275 int64_t frame_render_time_ms, | 263 int64_t frame_render_time_ms, |
276 webrtc::VideoRotation rotation) | 264 VideoRotation rotation) |
277 : encode_start_time(encode_start_time), | 265 : encode_start_time(encode_start_time), |
278 frame_timestamp(frame_timestamp), | 266 frame_timestamp(frame_timestamp), |
279 frame_render_time_ms(frame_render_time_ms), | 267 frame_render_time_ms(frame_render_time_ms), |
280 rotation(rotation) {} | 268 rotation(rotation) {} |
281 // Time when video frame is sent to encoder input. | 269 // Time when video frame is sent to encoder input. |
282 const int64_t encode_start_time; | 270 const int64_t encode_start_time; |
283 | 271 |
284 // Input frame information. | 272 // Input frame information. |
285 const int32_t frame_timestamp; | 273 const int32_t frame_timestamp; |
286 const int64_t frame_render_time_ms; | 274 const int64_t frame_render_time_ms; |
287 const webrtc::VideoRotation rotation; | 275 const VideoRotation rotation; |
288 }; | 276 }; |
289 std::list<InputFrameInfo> input_frame_infos_; | 277 std::list<InputFrameInfo> input_frame_infos_; |
290 int32_t output_timestamp_; // Last output frame timestamp from | 278 int32_t output_timestamp_; // Last output frame timestamp from |
291 // |input_frame_infos_|. | 279 // |input_frame_infos_|. |
292 int64_t output_render_time_ms_; // Last output frame render time from | 280 int64_t output_render_time_ms_; // Last output frame render time from |
293 // |input_frame_infos_|. | 281 // |input_frame_infos_|. |
294 webrtc::VideoRotation output_rotation_; // Last output frame rotation from | 282 VideoRotation output_rotation_; // Last output frame rotation from |
295 // |input_frame_infos_|. | 283 // |input_frame_infos_|. |
296 | 284 |
297 // Frame size in bytes fed to MediaCodec. | 285 // Frame size in bytes fed to MediaCodec. |
298 int yuv_size_; | 286 int yuv_size_; |
299 // True only when between a callback_->OnEncodedImage() call return a positive | 287 // True only when between a callback_->OnEncodedImage() call return a positive |
300 // value and the next Encode() call being ignored. | 288 // value and the next Encode() call being ignored. |
301 bool drop_next_input_frame_; | 289 bool drop_next_input_frame_; |
302 bool scale_; | 290 bool scale_; |
303 webrtc::H264::Profile profile_; | 291 H264::Profile profile_; |
304 // Global references; must be deleted in Release(). | 292 // Global references; must be deleted in Release(). |
305 std::vector<jobject> input_buffers_; | 293 std::vector<jobject> input_buffers_; |
306 webrtc::H264BitstreamParser h264_bitstream_parser_; | 294 H264BitstreamParser h264_bitstream_parser_; |
307 | 295 |
308 // VP9 variables to populate codec specific structure. | 296 // VP9 variables to populate codec specific structure. |
309 webrtc::GofInfoVP9 gof_; // Contains each frame's temporal information for | 297 GofInfoVP9 gof_; // Contains each frame's temporal information for |
310 // non-flexible VP9 mode. | 298 // non-flexible VP9 mode. |
311 size_t gof_idx_; | 299 size_t gof_idx_; |
312 | 300 |
313 // EGL context - owned by factory, should not be allocated/destroyed | 301 // EGL context - owned by factory, should not be allocated/destroyed |
314 // by MediaCodecVideoEncoder. | 302 // by MediaCodecVideoEncoder. |
315 jobject egl_context_; | 303 jobject egl_context_; |
316 | 304 |
317 // Temporary fix for VP8. | 305 // Temporary fix for VP8. |
318 // Sends a key frame if frames are largely spaced apart (possibly | 306 // Sends a key frame if frames are largely spaced apart (possibly |
319 // corresponding to a large image change). | 307 // corresponding to a large image change). |
320 int64_t last_frame_received_ms_; | 308 int64_t last_frame_received_ms_; |
321 int frames_received_since_last_key_; | 309 int frames_received_since_last_key_; |
322 webrtc::VideoCodecMode codec_mode_; | 310 VideoCodecMode codec_mode_; |
323 | 311 |
324 // RTP state. | 312 // RTP state. |
325 uint16_t picture_id_; | 313 uint16_t picture_id_; |
326 uint8_t tl0_pic_idx_; | 314 uint8_t tl0_pic_idx_; |
327 | 315 |
328 bool sw_fallback_required_; | 316 bool sw_fallback_required_; |
329 | 317 |
330 // All other member variables should be before WeakPtrFactory. Valid only from | 318 // All other member variables should be before WeakPtrFactory. Valid only from |
331 // InitEncode to Release. | 319 // InitEncode to Release. |
332 std::unique_ptr<rtc::WeakPtrFactory<MediaCodecVideoEncoder>> weak_factory_; | 320 std::unique_ptr<rtc::WeakPtrFactory<MediaCodecVideoEncoder>> weak_factory_; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 jni, j_output_buffer_info_class, "buffer", "Ljava/nio/ByteBuffer;"); | 393 jni, j_output_buffer_info_class, "buffer", "Ljava/nio/ByteBuffer;"); |
406 j_info_is_key_frame_field_ = | 394 j_info_is_key_frame_field_ = |
407 GetFieldID(jni, j_output_buffer_info_class, "isKeyFrame", "Z"); | 395 GetFieldID(jni, j_output_buffer_info_class, "isKeyFrame", "Z"); |
408 j_info_presentation_timestamp_us_field_ = GetFieldID( | 396 j_info_presentation_timestamp_us_field_ = GetFieldID( |
409 jni, j_output_buffer_info_class, "presentationTimestampUs", "J"); | 397 jni, j_output_buffer_info_class, "presentationTimestampUs", "J"); |
410 if (CheckException(jni)) { | 398 if (CheckException(jni)) { |
411 ALOGW << "MediaCodecVideoEncoder ctor failed."; | 399 ALOGW << "MediaCodecVideoEncoder ctor failed."; |
412 ProcessHWError(true /* reset_if_fallback_unavailable */); | 400 ProcessHWError(true /* reset_if_fallback_unavailable */); |
413 } | 401 } |
414 | 402 |
415 webrtc::Random random(rtc::TimeMicros()); | 403 Random random(rtc::TimeMicros()); |
416 picture_id_ = random.Rand<uint16_t>() & 0x7FFF; | 404 picture_id_ = random.Rand<uint16_t>() & 0x7FFF; |
417 tl0_pic_idx_ = random.Rand<uint8_t>(); | 405 tl0_pic_idx_ = random.Rand<uint8_t>(); |
418 } | 406 } |
419 | 407 |
420 int32_t MediaCodecVideoEncoder::InitEncode( | 408 int32_t MediaCodecVideoEncoder::InitEncode(const VideoCodec* codec_settings, |
421 const webrtc::VideoCodec* codec_settings, | 409 int32_t /* number_of_cores */, |
422 int32_t /* number_of_cores */, | 410 size_t /* max_payload_size */) { |
423 size_t /* max_payload_size */) { | |
424 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 411 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
425 if (codec_settings == NULL) { | 412 if (codec_settings == NULL) { |
426 ALOGE << "NULL VideoCodec instance"; | 413 ALOGE << "NULL VideoCodec instance"; |
427 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 414 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
428 } | 415 } |
429 // Factory should guard against other codecs being used with us. | 416 // Factory should guard against other codecs being used with us. |
430 const VideoCodecType codec_type = GetCodecType(); | 417 const VideoCodecType codec_type = GetCodecType(); |
431 RTC_CHECK(codec_settings->codecType == codec_type) | 418 RTC_CHECK(codec_settings->codecType == codec_type) |
432 << "Unsupported codec " << codec_settings->codecType << " for " | 419 << "Unsupported codec " << codec_settings->codecType << " for " |
433 << codec_type; | 420 << codec_type; |
(...skipping 11 matching lines...) Expand all Loading... |
445 } else if (codec_type == kVideoCodecVP9) { | 432 } else if (codec_type == kVideoCodecVP9) { |
446 scale_ = codec_settings->VP9().automaticResizeOn; | 433 scale_ = codec_settings->VP9().automaticResizeOn; |
447 } else { | 434 } else { |
448 scale_ = true; | 435 scale_ = true; |
449 } | 436 } |
450 | 437 |
451 ALOGD << "InitEncode request: " << init_width << " x " << init_height; | 438 ALOGD << "InitEncode request: " << init_width << " x " << init_height; |
452 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); | 439 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); |
453 | 440 |
454 // Check allowed H.264 profile | 441 // Check allowed H.264 profile |
455 profile_ = webrtc::H264::Profile::kProfileBaseline; | 442 profile_ = H264::Profile::kProfileBaseline; |
456 if (codec_type == kVideoCodecH264) { | 443 if (codec_type == kVideoCodecH264) { |
457 const rtc::Optional<webrtc::H264::ProfileLevelId> profile_level_id = | 444 const rtc::Optional<H264::ProfileLevelId> profile_level_id = |
458 webrtc::H264::ParseSdpProfileLevelId(codec_.params); | 445 H264::ParseSdpProfileLevelId(codec_.params); |
459 RTC_DCHECK(profile_level_id); | 446 RTC_DCHECK(profile_level_id); |
460 profile_ = profile_level_id->profile; | 447 profile_ = profile_level_id->profile; |
461 ALOGD << "H.264 profile: " << profile_; | 448 ALOGD << "H.264 profile: " << profile_; |
462 } | 449 } |
463 | 450 |
464 return InitEncodeInternal( | 451 return InitEncodeInternal( |
465 init_width, init_height, codec_settings->startBitrate, | 452 init_width, init_height, codec_settings->startBitrate, |
466 codec_settings->maxFramerate, codec_settings->expect_encode_from_texture); | 453 codec_settings->maxFramerate, codec_settings->expect_encode_from_texture); |
467 } | 454 } |
468 | 455 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 return false; | 533 return false; |
547 } | 534 } |
548 | 535 |
549 int32_t MediaCodecVideoEncoder::ProcessHWErrorOnEncode() { | 536 int32_t MediaCodecVideoEncoder::ProcessHWErrorOnEncode() { |
550 ProcessHWError(true /* reset_if_fallback_unavailable */); | 537 ProcessHWError(true /* reset_if_fallback_unavailable */); |
551 return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE | 538 return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE |
552 : WEBRTC_VIDEO_CODEC_ERROR; | 539 : WEBRTC_VIDEO_CODEC_ERROR; |
553 } | 540 } |
554 | 541 |
555 VideoCodecType MediaCodecVideoEncoder::GetCodecType() const { | 542 VideoCodecType MediaCodecVideoEncoder::GetCodecType() const { |
556 return webrtc::PayloadStringToCodecType(codec_.name); | 543 return PayloadStringToCodecType(codec_.name); |
557 } | 544 } |
558 | 545 |
559 int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width, | 546 int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width, |
560 int height, | 547 int height, |
561 int kbps, | 548 int kbps, |
562 int fps, | 549 int fps, |
563 bool use_surface) { | 550 bool use_surface) { |
564 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 551 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
565 if (sw_fallback_required_) { | 552 if (sw_fallback_required_) { |
566 return WEBRTC_VIDEO_CODEC_OK; | 553 return WEBRTC_VIDEO_CODEC_OK; |
(...skipping 28 matching lines...) Expand all Loading... |
595 current_bytes_ = 0; | 582 current_bytes_ = 0; |
596 current_acc_qp_ = 0; | 583 current_acc_qp_ = 0; |
597 current_encoding_time_ms_ = 0; | 584 current_encoding_time_ms_ = 0; |
598 last_input_timestamp_ms_ = -1; | 585 last_input_timestamp_ms_ = -1; |
599 last_output_timestamp_ms_ = -1; | 586 last_output_timestamp_ms_ = -1; |
600 output_timestamp_ = 0; | 587 output_timestamp_ = 0; |
601 output_render_time_ms_ = 0; | 588 output_render_time_ms_ = 0; |
602 input_frame_infos_.clear(); | 589 input_frame_infos_.clear(); |
603 drop_next_input_frame_ = false; | 590 drop_next_input_frame_ = false; |
604 use_surface_ = use_surface; | 591 use_surface_ = use_surface; |
605 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1); | 592 gof_.SetGofInfoVP9(TemporalStructureMode::kTemporalStructureMode1); |
606 gof_idx_ = 0; | 593 gof_idx_ = 0; |
607 last_frame_received_ms_ = -1; | 594 last_frame_received_ms_ = -1; |
608 frames_received_since_last_key_ = kMinKeyFrameInterval; | 595 frames_received_since_last_key_ = kMinKeyFrameInterval; |
609 | 596 |
610 // We enforce no extra stride/padding in the format creation step. | 597 // We enforce no extra stride/padding in the format creation step. |
611 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( | 598 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( |
612 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type); | 599 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type); |
613 const bool encode_status = jni->CallBooleanMethod( | 600 const bool encode_status = jni->CallBooleanMethod( |
614 *j_media_codec_video_encoder_, j_init_encode_method_, j_video_codec_enum, | 601 *j_media_codec_video_encoder_, j_init_encode_method_, j_video_codec_enum, |
615 profile_, width, height, kbps, fps, | 602 profile_, width, height, kbps, fps, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 #endif | 666 #endif |
680 inited_ = true; | 667 inited_ = true; |
681 } | 668 } |
682 weak_factory_.reset(new rtc::WeakPtrFactory<MediaCodecVideoEncoder>(this)); | 669 weak_factory_.reset(new rtc::WeakPtrFactory<MediaCodecVideoEncoder>(this)); |
683 encode_task_.reset(new EncodeTask(weak_factory_->GetWeakPtr())); | 670 encode_task_.reset(new EncodeTask(weak_factory_->GetWeakPtr())); |
684 | 671 |
685 return WEBRTC_VIDEO_CODEC_OK; | 672 return WEBRTC_VIDEO_CODEC_OK; |
686 } | 673 } |
687 | 674 |
688 int32_t MediaCodecVideoEncoder::Encode( | 675 int32_t MediaCodecVideoEncoder::Encode( |
689 const webrtc::VideoFrame& frame, | 676 const VideoFrame& frame, |
690 const webrtc::CodecSpecificInfo* /* codec_specific_info */, | 677 const CodecSpecificInfo* /* codec_specific_info */, |
691 const std::vector<webrtc::FrameType>* frame_types) { | 678 const std::vector<FrameType>* frame_types) { |
692 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 679 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
693 if (sw_fallback_required_) | 680 if (sw_fallback_required_) |
694 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; | 681 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; |
695 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 682 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
696 ScopedLocalRefFrame local_ref_frame(jni); | 683 ScopedLocalRefFrame local_ref_frame(jni); |
697 const int64_t frame_input_time_ms = rtc::TimeMillis(); | 684 const int64_t frame_input_time_ms = rtc::TimeMillis(); |
698 | 685 |
699 if (!inited_) { | 686 if (!inited_) { |
700 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 687 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
701 } | 688 } |
702 | 689 |
703 bool send_key_frame = false; | 690 bool send_key_frame = false; |
704 if (codec_mode_ == webrtc::kRealtimeVideo) { | 691 if (codec_mode_ == kRealtimeVideo) { |
705 ++frames_received_since_last_key_; | 692 ++frames_received_since_last_key_; |
706 int64_t now_ms = rtc::TimeMillis(); | 693 int64_t now_ms = rtc::TimeMillis(); |
707 if (last_frame_received_ms_ != -1 && | 694 if (last_frame_received_ms_ != -1 && |
708 (now_ms - last_frame_received_ms_) > kFrameDiffThresholdMs) { | 695 (now_ms - last_frame_received_ms_) > kFrameDiffThresholdMs) { |
709 // Add limit to prevent triggering a key for every frame for very low | 696 // Add limit to prevent triggering a key for every frame for very low |
710 // framerates (e.g. if frame diff > kFrameDiffThresholdMs). | 697 // framerates (e.g. if frame diff > kFrameDiffThresholdMs). |
711 if (frames_received_since_last_key_ > kMinKeyFrameInterval) { | 698 if (frames_received_since_last_key_ > kMinKeyFrameInterval) { |
712 ALOGD << "Send key, frame diff: " << (now_ms - last_frame_received_ms_); | 699 ALOGD << "Send key, frame diff: " << (now_ms - last_frame_received_ms_); |
713 send_key_frame = true; | 700 send_key_frame = true; |
714 } | 701 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 if (consecutive_full_queue_frame_drops_ >= | 741 if (consecutive_full_queue_frame_drops_ >= |
755 ENCODER_STALL_FRAMEDROP_THRESHOLD) { | 742 ENCODER_STALL_FRAMEDROP_THRESHOLD) { |
756 ALOGE << "Encoder got stuck."; | 743 ALOGE << "Encoder got stuck."; |
757 return ProcessHWErrorOnEncode(); | 744 return ProcessHWErrorOnEncode(); |
758 } | 745 } |
759 frames_dropped_media_encoder_++; | 746 frames_dropped_media_encoder_++; |
760 return WEBRTC_VIDEO_CODEC_OK; | 747 return WEBRTC_VIDEO_CODEC_OK; |
761 } | 748 } |
762 consecutive_full_queue_frame_drops_ = 0; | 749 consecutive_full_queue_frame_drops_ = 0; |
763 | 750 |
764 rtc::scoped_refptr<webrtc::VideoFrameBuffer> input_buffer( | 751 rtc::scoped_refptr<VideoFrameBuffer> input_buffer(frame.video_frame_buffer()); |
765 frame.video_frame_buffer()); | |
766 | 752 |
767 VideoFrame input_frame(input_buffer, frame.timestamp(), | 753 VideoFrame input_frame(input_buffer, frame.timestamp(), |
768 frame.render_time_ms(), frame.rotation()); | 754 frame.render_time_ms(), frame.rotation()); |
769 | 755 |
770 if (!MaybeReconfigureEncoder(jni, input_frame)) { | 756 if (!MaybeReconfigureEncoder(jni, input_frame)) { |
771 ALOGE << "Failed to reconfigure encoder."; | 757 ALOGE << "Failed to reconfigure encoder."; |
772 return WEBRTC_VIDEO_CODEC_ERROR; | 758 return WEBRTC_VIDEO_CODEC_ERROR; |
773 } | 759 } |
774 | 760 |
775 const bool key_frame = | 761 const bool key_frame = |
776 frame_types->front() != webrtc::kVideoFrameDelta || send_key_frame; | 762 frame_types->front() != kVideoFrameDelta || send_key_frame; |
777 bool encode_status = true; | 763 bool encode_status = true; |
778 | 764 |
779 int j_input_buffer_index = -1; | 765 int j_input_buffer_index = -1; |
780 if (!use_surface_) { | 766 if (!use_surface_) { |
781 j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, | 767 j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, |
782 j_dequeue_input_buffer_method_); | 768 j_dequeue_input_buffer_method_); |
783 if (CheckException(jni)) { | 769 if (CheckException(jni)) { |
784 ALOGE << "Exception in dequeu input buffer."; | 770 ALOGE << "Exception in dequeu input buffer."; |
785 return ProcessHWErrorOnEncode(); | 771 return ProcessHWErrorOnEncode(); |
786 } | 772 } |
787 if (j_input_buffer_index == -1) { | 773 if (j_input_buffer_index == -1) { |
788 // Video codec falls behind - no input buffer available. | 774 // Video codec falls behind - no input buffer available. |
789 ALOGW << "Encoder drop frame - no input buffers available"; | 775 ALOGW << "Encoder drop frame - no input buffers available"; |
790 if (frames_received_ > 1) { | 776 if (frames_received_ > 1) { |
791 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; | 777 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; |
792 frames_dropped_media_encoder_++; | 778 frames_dropped_media_encoder_++; |
793 } else { | 779 } else { |
794 // Input buffers are not ready after codec initialization, HW is still | 780 // Input buffers are not ready after codec initialization, HW is still |
795 // allocating thme - this is expected and should not result in drop | 781 // allocating thme - this is expected and should not result in drop |
796 // frame report. | 782 // frame report. |
797 frames_received_ = 0; | 783 frames_received_ = 0; |
798 } | 784 } |
799 return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887. | 785 return WEBRTC_VIDEO_CODEC_OK; // TODO(fischman): see webrtc bug 2887. |
800 } else if (j_input_buffer_index == -2) { | 786 } else if (j_input_buffer_index == -2) { |
801 return ProcessHWErrorOnEncode(); | 787 return ProcessHWErrorOnEncode(); |
802 } | 788 } |
803 } | 789 } |
804 | 790 |
805 if (input_frame.video_frame_buffer()->type() != | 791 if (input_frame.video_frame_buffer()->type() != |
806 webrtc::VideoFrameBuffer::Type::kNative) { | 792 VideoFrameBuffer::Type::kNative) { |
807 encode_status = | 793 encode_status = |
808 EncodeByteBuffer(jni, key_frame, input_frame, j_input_buffer_index); | 794 EncodeByteBuffer(jni, key_frame, input_frame, j_input_buffer_index); |
809 } else { | 795 } else { |
810 AndroidVideoFrameBuffer* android_buffer = | 796 AndroidVideoFrameBuffer* android_buffer = |
811 static_cast<AndroidVideoFrameBuffer*>( | 797 static_cast<AndroidVideoFrameBuffer*>( |
812 input_frame.video_frame_buffer().get()); | 798 input_frame.video_frame_buffer().get()); |
813 switch (android_buffer->android_type()) { | 799 switch (android_buffer->android_type()) { |
814 case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer: | 800 case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer: |
815 encode_status = EncodeTexture(jni, key_frame, input_frame); | 801 encode_status = EncodeTexture(jni, key_frame, input_frame); |
816 break; | 802 break; |
(...skipping 28 matching lines...) Expand all Loading... |
845 rtc::TaskQueue::Current()->PostDelayedTask(std::move(encode_task_), | 831 rtc::TaskQueue::Current()->PostDelayedTask(std::move(encode_task_), |
846 kMediaCodecPollMs); | 832 kMediaCodecPollMs); |
847 } | 833 } |
848 | 834 |
849 if (!DeliverPendingOutputs(jni)) { | 835 if (!DeliverPendingOutputs(jni)) { |
850 return ProcessHWErrorOnEncode(); | 836 return ProcessHWErrorOnEncode(); |
851 } | 837 } |
852 return WEBRTC_VIDEO_CODEC_OK; | 838 return WEBRTC_VIDEO_CODEC_OK; |
853 } | 839 } |
854 | 840 |
855 bool MediaCodecVideoEncoder::MaybeReconfigureEncoder( | 841 bool MediaCodecVideoEncoder::MaybeReconfigureEncoder(JNIEnv* jni, |
856 JNIEnv* jni, | 842 const VideoFrame& frame) { |
857 const webrtc::VideoFrame& frame) { | |
858 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 843 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
859 | 844 |
860 bool is_texture = IsTextureFrame(jni, frame); | 845 bool is_texture = IsTextureFrame(jni, frame); |
861 const bool reconfigure_due_to_format = is_texture != use_surface_; | 846 const bool reconfigure_due_to_format = is_texture != use_surface_; |
862 const bool reconfigure_due_to_size = | 847 const bool reconfigure_due_to_size = |
863 frame.width() != width_ || frame.height() != height_; | 848 frame.width() != width_ || frame.height() != height_; |
864 | 849 |
865 if (reconfigure_due_to_format) { | 850 if (reconfigure_due_to_format) { |
866 ALOGD << "Reconfigure encoder due to format change. " | 851 ALOGD << "Reconfigure encoder due to format change. " |
867 << (use_surface_ ? | 852 << (use_surface_ ? |
(...skipping 13 matching lines...) Expand all Loading... |
881 if (!reconfigure_due_to_format && !reconfigure_due_to_size) | 866 if (!reconfigure_due_to_format && !reconfigure_due_to_size) |
882 return true; | 867 return true; |
883 | 868 |
884 Release(); | 869 Release(); |
885 | 870 |
886 return InitEncodeInternal(width_, height_, 0, 0, is_texture) == | 871 return InitEncodeInternal(width_, height_, 0, 0, is_texture) == |
887 WEBRTC_VIDEO_CODEC_OK; | 872 WEBRTC_VIDEO_CODEC_OK; |
888 } | 873 } |
889 | 874 |
890 bool MediaCodecVideoEncoder::IsTextureFrame(JNIEnv* jni, | 875 bool MediaCodecVideoEncoder::IsTextureFrame(JNIEnv* jni, |
891 const webrtc::VideoFrame& frame) { | 876 const VideoFrame& frame) { |
892 if (frame.video_frame_buffer()->type() != | 877 if (frame.video_frame_buffer()->type() != VideoFrameBuffer::Type::kNative) { |
893 webrtc::VideoFrameBuffer::Type::kNative) { | |
894 return false; | 878 return false; |
895 } | 879 } |
896 | 880 |
897 AndroidVideoFrameBuffer* android_buffer = | 881 AndroidVideoFrameBuffer* android_buffer = |
898 static_cast<AndroidVideoFrameBuffer*>(frame.video_frame_buffer().get()); | 882 static_cast<AndroidVideoFrameBuffer*>(frame.video_frame_buffer().get()); |
899 switch (android_buffer->android_type()) { | 883 switch (android_buffer->android_type()) { |
900 case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer: | 884 case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer: |
901 return true; | 885 return true; |
902 case AndroidVideoFrameBuffer::AndroidType::kJavaBuffer: | 886 case AndroidVideoFrameBuffer::AndroidType::kJavaBuffer: |
903 return jni->IsInstanceOf(static_cast<AndroidVideoBuffer*>(android_buffer) | 887 return jni->IsInstanceOf(static_cast<AndroidVideoBuffer*>(android_buffer) |
904 ->video_frame_buffer(), | 888 ->video_frame_buffer(), |
905 *j_video_frame_texture_buffer_class_); | 889 *j_video_frame_texture_buffer_class_); |
906 default: | 890 default: |
907 RTC_NOTREACHED(); | 891 RTC_NOTREACHED(); |
908 return false; | 892 return false; |
909 } | 893 } |
910 } | 894 } |
911 | 895 |
912 bool MediaCodecVideoEncoder::EncodeByteBuffer(JNIEnv* jni, | 896 bool MediaCodecVideoEncoder::EncodeByteBuffer(JNIEnv* jni, |
913 bool key_frame, | 897 bool key_frame, |
914 const webrtc::VideoFrame& frame, | 898 const VideoFrame& frame, |
915 int input_buffer_index) { | 899 int input_buffer_index) { |
916 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 900 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
917 RTC_CHECK(!use_surface_); | 901 RTC_CHECK(!use_surface_); |
918 | 902 |
919 rtc::scoped_refptr<webrtc::I420BufferInterface> i420_buffer = | 903 rtc::scoped_refptr<I420BufferInterface> i420_buffer = |
920 frame.video_frame_buffer()->ToI420(); | 904 frame.video_frame_buffer()->ToI420(); |
921 if (!FillInputBuffer(jni, input_buffer_index, i420_buffer->DataY(), | 905 if (!FillInputBuffer(jni, input_buffer_index, i420_buffer->DataY(), |
922 i420_buffer->StrideY(), i420_buffer->DataU(), | 906 i420_buffer->StrideY(), i420_buffer->DataU(), |
923 i420_buffer->StrideU(), i420_buffer->DataV(), | 907 i420_buffer->StrideU(), i420_buffer->DataV(), |
924 i420_buffer->StrideV())) { | 908 i420_buffer->StrideV())) { |
925 return false; | 909 return false; |
926 } | 910 } |
927 bool encode_status = jni->CallBooleanMethod( | 911 bool encode_status = jni->CallBooleanMethod( |
928 *j_media_codec_video_encoder_, j_encode_buffer_method_, key_frame, | 912 *j_media_codec_video_encoder_, j_encode_buffer_method_, key_frame, |
929 input_buffer_index, yuv_size_, current_timestamp_us_); | 913 input_buffer_index, yuv_size_, current_timestamp_us_); |
(...skipping 25 matching lines...) Expand all Loading... |
955 | 939 |
956 RTC_CHECK(!libyuv::ConvertFromI420(buffer_y, stride_y, buffer_u, stride_u, | 940 RTC_CHECK(!libyuv::ConvertFromI420(buffer_y, stride_y, buffer_u, stride_u, |
957 buffer_v, stride_v, yuv_buffer, width_, | 941 buffer_v, stride_v, yuv_buffer, width_, |
958 width_, height_, encoder_fourcc_)) | 942 width_, height_, encoder_fourcc_)) |
959 << "ConvertFromI420 failed"; | 943 << "ConvertFromI420 failed"; |
960 return true; | 944 return true; |
961 } | 945 } |
962 | 946 |
963 bool MediaCodecVideoEncoder::EncodeTexture(JNIEnv* jni, | 947 bool MediaCodecVideoEncoder::EncodeTexture(JNIEnv* jni, |
964 bool key_frame, | 948 bool key_frame, |
965 const webrtc::VideoFrame& frame) { | 949 const VideoFrame& frame) { |
966 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 950 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
967 RTC_CHECK(use_surface_); | 951 RTC_CHECK(use_surface_); |
968 NativeHandleImpl handle = | 952 NativeHandleImpl handle = |
969 static_cast<AndroidTextureBuffer*>(frame.video_frame_buffer().get()) | 953 static_cast<AndroidTextureBuffer*>(frame.video_frame_buffer().get()) |
970 ->native_handle_impl(); | 954 ->native_handle_impl(); |
971 | 955 |
972 jfloatArray sampling_matrix = handle.sampling_matrix.ToJava(jni); | 956 jfloatArray sampling_matrix = handle.sampling_matrix.ToJava(jni); |
973 bool encode_status = jni->CallBooleanMethod( | 957 bool encode_status = jni->CallBooleanMethod( |
974 *j_media_codec_video_encoder_, j_encode_texture_method_, key_frame, | 958 *j_media_codec_video_encoder_, j_encode_texture_method_, key_frame, |
975 handle.oes_texture_id, sampling_matrix, current_timestamp_us_); | 959 handle.oes_texture_id, sampling_matrix, current_timestamp_us_); |
(...skipping 14 matching lines...) Expand all Loading... |
990 jlongFromPointer(this), key_frame, frame, input_buffer_index); | 974 jlongFromPointer(this), key_frame, frame, input_buffer_index); |
991 if (CheckException(jni)) { | 975 if (CheckException(jni)) { |
992 ALOGE << "Exception in encode frame."; | 976 ALOGE << "Exception in encode frame."; |
993 ProcessHWError(true /* reset_if_fallback_unavailable */); | 977 ProcessHWError(true /* reset_if_fallback_unavailable */); |
994 return false; | 978 return false; |
995 } | 979 } |
996 return encode_status; | 980 return encode_status; |
997 } | 981 } |
998 | 982 |
999 int32_t MediaCodecVideoEncoder::RegisterEncodeCompleteCallback( | 983 int32_t MediaCodecVideoEncoder::RegisterEncodeCompleteCallback( |
1000 webrtc::EncodedImageCallback* callback) { | 984 EncodedImageCallback* callback) { |
1001 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 985 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
1002 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 986 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
1003 ScopedLocalRefFrame local_ref_frame(jni); | 987 ScopedLocalRefFrame local_ref_frame(jni); |
1004 callback_ = callback; | 988 callback_ = callback; |
1005 return WEBRTC_VIDEO_CODEC_OK; | 989 return WEBRTC_VIDEO_CODEC_OK; |
1006 } | 990 } |
1007 | 991 |
1008 int32_t MediaCodecVideoEncoder::Release() { | 992 int32_t MediaCodecVideoEncoder::Release() { |
1009 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 993 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
1010 if (!inited_) { | 994 if (!inited_) { |
(...skipping 20 matching lines...) Expand all Loading... |
1031 rtc::CritScope lock(&inited_crit_); | 1015 rtc::CritScope lock(&inited_crit_); |
1032 #endif | 1016 #endif |
1033 inited_ = false; | 1017 inited_ = false; |
1034 } | 1018 } |
1035 use_surface_ = false; | 1019 use_surface_ = false; |
1036 ALOGD << "EncoderRelease done."; | 1020 ALOGD << "EncoderRelease done."; |
1037 return WEBRTC_VIDEO_CODEC_OK; | 1021 return WEBRTC_VIDEO_CODEC_OK; |
1038 } | 1022 } |
1039 | 1023 |
1040 int32_t MediaCodecVideoEncoder::SetRateAllocation( | 1024 int32_t MediaCodecVideoEncoder::SetRateAllocation( |
1041 const webrtc::BitrateAllocation& rate_allocation, | 1025 const BitrateAllocation& rate_allocation, |
1042 uint32_t frame_rate) { | 1026 uint32_t frame_rate) { |
1043 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); | 1027 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); |
1044 const uint32_t new_bit_rate = rate_allocation.get_sum_kbps(); | 1028 const uint32_t new_bit_rate = rate_allocation.get_sum_kbps(); |
1045 if (sw_fallback_required_) | 1029 if (sw_fallback_required_) |
1046 return WEBRTC_VIDEO_CODEC_OK; | 1030 return WEBRTC_VIDEO_CODEC_OK; |
1047 frame_rate = | 1031 frame_rate = |
1048 (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? frame_rate : MAX_ALLOWED_VIDEO_FPS; | 1032 (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? frame_rate : MAX_ALLOWED_VIDEO_FPS; |
1049 if (last_set_bitrate_kbps_ == new_bit_rate && last_set_fps_ == frame_rate) { | 1033 if (last_set_bitrate_kbps_ == new_bit_rate && last_set_fps_ == frame_rate) { |
1050 return WEBRTC_VIDEO_CODEC_OK; | 1034 return WEBRTC_VIDEO_CODEC_OK; |
1051 } | 1035 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 uint8_t* payload = reinterpret_cast<uint8_t*>( | 1124 uint8_t* payload = reinterpret_cast<uint8_t*>( |
1141 jni->GetDirectBufferAddress(j_output_buffer)); | 1125 jni->GetDirectBufferAddress(j_output_buffer)); |
1142 if (CheckException(jni)) { | 1126 if (CheckException(jni)) { |
1143 ALOGE << "Exception in get direct buffer address."; | 1127 ALOGE << "Exception in get direct buffer address."; |
1144 ProcessHWError(true /* reset_if_fallback_unavailable */); | 1128 ProcessHWError(true /* reset_if_fallback_unavailable */); |
1145 return WEBRTC_VIDEO_CODEC_ERROR; | 1129 return WEBRTC_VIDEO_CODEC_ERROR; |
1146 } | 1130 } |
1147 | 1131 |
1148 // Callback - return encoded frame. | 1132 // Callback - return encoded frame. |
1149 const VideoCodecType codec_type = GetCodecType(); | 1133 const VideoCodecType codec_type = GetCodecType(); |
1150 webrtc::EncodedImageCallback::Result callback_result( | 1134 EncodedImageCallback::Result callback_result( |
1151 webrtc::EncodedImageCallback::Result::OK); | 1135 EncodedImageCallback::Result::OK); |
1152 if (callback_) { | 1136 if (callback_) { |
1153 std::unique_ptr<webrtc::EncodedImage> image( | 1137 std::unique_ptr<EncodedImage> image( |
1154 new webrtc::EncodedImage(payload, payload_size, payload_size)); | 1138 new EncodedImage(payload, payload_size, payload_size)); |
1155 image->_encodedWidth = width_; | 1139 image->_encodedWidth = width_; |
1156 image->_encodedHeight = height_; | 1140 image->_encodedHeight = height_; |
1157 image->_timeStamp = output_timestamp_; | 1141 image->_timeStamp = output_timestamp_; |
1158 image->capture_time_ms_ = output_render_time_ms_; | 1142 image->capture_time_ms_ = output_render_time_ms_; |
1159 image->rotation_ = output_rotation_; | 1143 image->rotation_ = output_rotation_; |
1160 image->content_type_ = | 1144 image->content_type_ = (codec_mode_ == VideoCodecMode::kScreensharing) |
1161 (codec_mode_ == webrtc::VideoCodecMode::kScreensharing) | 1145 ? VideoContentType::SCREENSHARE |
1162 ? webrtc::VideoContentType::SCREENSHARE | 1146 : VideoContentType::UNSPECIFIED; |
1163 : webrtc::VideoContentType::UNSPECIFIED; | 1147 image->timing_.flags = TimingFrameFlags::kInvalid; |
1164 image->timing_.flags = webrtc::TimingFrameFlags::kInvalid; | 1148 image->_frameType = (key_frame ? kVideoFrameKey : kVideoFrameDelta); |
1165 image->_frameType = | |
1166 (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta); | |
1167 image->_completeFrame = true; | 1149 image->_completeFrame = true; |
1168 webrtc::CodecSpecificInfo info; | 1150 CodecSpecificInfo info; |
1169 memset(&info, 0, sizeof(info)); | 1151 memset(&info, 0, sizeof(info)); |
1170 info.codecType = codec_type; | 1152 info.codecType = codec_type; |
1171 if (codec_type == kVideoCodecVP8) { | 1153 if (codec_type == kVideoCodecVP8) { |
1172 info.codecSpecific.VP8.pictureId = picture_id_; | 1154 info.codecSpecific.VP8.pictureId = picture_id_; |
1173 info.codecSpecific.VP8.nonReference = false; | 1155 info.codecSpecific.VP8.nonReference = false; |
1174 info.codecSpecific.VP8.simulcastIdx = 0; | 1156 info.codecSpecific.VP8.simulcastIdx = 0; |
1175 info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx; | 1157 info.codecSpecific.VP8.temporalIdx = kNoTemporalIdx; |
1176 info.codecSpecific.VP8.layerSync = false; | 1158 info.codecSpecific.VP8.layerSync = false; |
1177 info.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx; | 1159 info.codecSpecific.VP8.tl0PicIdx = kNoTl0PicIdx; |
1178 info.codecSpecific.VP8.keyIdx = webrtc::kNoKeyIdx; | 1160 info.codecSpecific.VP8.keyIdx = kNoKeyIdx; |
1179 } else if (codec_type == kVideoCodecVP9) { | 1161 } else if (codec_type == kVideoCodecVP9) { |
1180 if (key_frame) { | 1162 if (key_frame) { |
1181 gof_idx_ = 0; | 1163 gof_idx_ = 0; |
1182 } | 1164 } |
1183 info.codecSpecific.VP9.picture_id = picture_id_; | 1165 info.codecSpecific.VP9.picture_id = picture_id_; |
1184 info.codecSpecific.VP9.inter_pic_predicted = key_frame ? false : true; | 1166 info.codecSpecific.VP9.inter_pic_predicted = key_frame ? false : true; |
1185 info.codecSpecific.VP9.flexible_mode = false; | 1167 info.codecSpecific.VP9.flexible_mode = false; |
1186 info.codecSpecific.VP9.ss_data_available = key_frame ? true : false; | 1168 info.codecSpecific.VP9.ss_data_available = key_frame ? true : false; |
1187 info.codecSpecific.VP9.tl0_pic_idx = tl0_pic_idx_++; | 1169 info.codecSpecific.VP9.tl0_pic_idx = tl0_pic_idx_++; |
1188 info.codecSpecific.VP9.temporal_idx = webrtc::kNoTemporalIdx; | 1170 info.codecSpecific.VP9.temporal_idx = kNoTemporalIdx; |
1189 info.codecSpecific.VP9.spatial_idx = webrtc::kNoSpatialIdx; | 1171 info.codecSpecific.VP9.spatial_idx = kNoSpatialIdx; |
1190 info.codecSpecific.VP9.temporal_up_switch = true; | 1172 info.codecSpecific.VP9.temporal_up_switch = true; |
1191 info.codecSpecific.VP9.inter_layer_predicted = false; | 1173 info.codecSpecific.VP9.inter_layer_predicted = false; |
1192 info.codecSpecific.VP9.gof_idx = | 1174 info.codecSpecific.VP9.gof_idx = |
1193 static_cast<uint8_t>(gof_idx_++ % gof_.num_frames_in_gof); | 1175 static_cast<uint8_t>(gof_idx_++ % gof_.num_frames_in_gof); |
1194 info.codecSpecific.VP9.num_spatial_layers = 1; | 1176 info.codecSpecific.VP9.num_spatial_layers = 1; |
1195 info.codecSpecific.VP9.spatial_layer_resolution_present = false; | 1177 info.codecSpecific.VP9.spatial_layer_resolution_present = false; |
1196 if (info.codecSpecific.VP9.ss_data_available) { | 1178 if (info.codecSpecific.VP9.ss_data_available) { |
1197 info.codecSpecific.VP9.spatial_layer_resolution_present = true; | 1179 info.codecSpecific.VP9.spatial_layer_resolution_present = true; |
1198 info.codecSpecific.VP9.width[0] = width_; | 1180 info.codecSpecific.VP9.width[0] = width_; |
1199 info.codecSpecific.VP9.height[0] = height_; | 1181 info.codecSpecific.VP9.height[0] = height_; |
1200 info.codecSpecific.VP9.gof.CopyGofInfoVP9(gof_); | 1182 info.codecSpecific.VP9.gof.CopyGofInfoVP9(gof_); |
1201 } | 1183 } |
1202 } | 1184 } |
1203 picture_id_ = (picture_id_ + 1) & 0x7FFF; | 1185 picture_id_ = (picture_id_ + 1) & 0x7FFF; |
1204 | 1186 |
1205 // Generate a header describing a single fragment. | 1187 // Generate a header describing a single fragment. |
1206 webrtc::RTPFragmentationHeader header; | 1188 RTPFragmentationHeader header; |
1207 memset(&header, 0, sizeof(header)); | 1189 memset(&header, 0, sizeof(header)); |
1208 if (codec_type == kVideoCodecVP8 || codec_type == kVideoCodecVP9) { | 1190 if (codec_type == kVideoCodecVP8 || codec_type == kVideoCodecVP9) { |
1209 header.VerifyAndAllocateFragmentationHeader(1); | 1191 header.VerifyAndAllocateFragmentationHeader(1); |
1210 header.fragmentationOffset[0] = 0; | 1192 header.fragmentationOffset[0] = 0; |
1211 header.fragmentationLength[0] = image->_length; | 1193 header.fragmentationLength[0] = image->_length; |
1212 header.fragmentationPlType[0] = 0; | 1194 header.fragmentationPlType[0] = 0; |
1213 header.fragmentationTimeDiff[0] = 0; | 1195 header.fragmentationTimeDiff[0] = 0; |
1214 if (codec_type == kVideoCodecVP8) { | 1196 if (codec_type == kVideoCodecVP8) { |
1215 int qp; | 1197 int qp; |
1216 if (webrtc::vp8::GetQp(payload, payload_size, &qp)) { | 1198 if (vp8::GetQp(payload, payload_size, &qp)) { |
1217 current_acc_qp_ += qp; | 1199 current_acc_qp_ += qp; |
1218 image->qp_ = qp; | 1200 image->qp_ = qp; |
1219 } | 1201 } |
1220 } else if (codec_type == kVideoCodecVP9) { | 1202 } else if (codec_type == kVideoCodecVP9) { |
1221 int qp; | 1203 int qp; |
1222 if (webrtc::vp9::GetQp(payload, payload_size, &qp)) { | 1204 if (vp9::GetQp(payload, payload_size, &qp)) { |
1223 current_acc_qp_ += qp; | 1205 current_acc_qp_ += qp; |
1224 image->qp_ = qp; | 1206 image->qp_ = qp; |
1225 } | 1207 } |
1226 } | 1208 } |
1227 } else if (codec_type == kVideoCodecH264) { | 1209 } else if (codec_type == kVideoCodecH264) { |
1228 h264_bitstream_parser_.ParseBitstream(payload, payload_size); | 1210 h264_bitstream_parser_.ParseBitstream(payload, payload_size); |
1229 int qp; | 1211 int qp; |
1230 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) { | 1212 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) { |
1231 current_acc_qp_ += qp; | 1213 current_acc_qp_ += qp; |
1232 image->qp_ = qp; | 1214 image->qp_ = qp; |
1233 } | 1215 } |
1234 // For H.264 search for start codes. | 1216 // For H.264 search for start codes. |
1235 const std::vector<webrtc::H264::NaluIndex> nalu_idxs = | 1217 const std::vector<H264::NaluIndex> nalu_idxs = |
1236 webrtc::H264::FindNaluIndices(payload, payload_size); | 1218 H264::FindNaluIndices(payload, payload_size); |
1237 if (nalu_idxs.empty()) { | 1219 if (nalu_idxs.empty()) { |
1238 ALOGE << "Start code is not found!"; | 1220 ALOGE << "Start code is not found!"; |
1239 ALOGE << "Data:" << image->_buffer[0] << " " << image->_buffer[1] | 1221 ALOGE << "Data:" << image->_buffer[0] << " " << image->_buffer[1] |
1240 << " " << image->_buffer[2] << " " << image->_buffer[3] | 1222 << " " << image->_buffer[2] << " " << image->_buffer[3] |
1241 << " " << image->_buffer[4] << " " << image->_buffer[5]; | 1223 << " " << image->_buffer[4] << " " << image->_buffer[5]; |
1242 ProcessHWError(true /* reset_if_fallback_unavailable */); | 1224 ProcessHWError(true /* reset_if_fallback_unavailable */); |
1243 return false; | 1225 return false; |
1244 } | 1226 } |
1245 header.VerifyAndAllocateFragmentationHeader(nalu_idxs.size()); | 1227 header.VerifyAndAllocateFragmentationHeader(nalu_idxs.size()); |
1246 for (size_t i = 0; i < nalu_idxs.size(); i++) { | 1228 for (size_t i = 0; i < nalu_idxs.size(); i++) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 ". QP: " << (current_acc_qp_ / current_frames_divider) << | 1291 ". QP: " << (current_acc_qp_ / current_frames_divider) << |
1310 " for last " << statistic_time_ms << " ms."; | 1292 " for last " << statistic_time_ms << " ms."; |
1311 stat_start_time_ms_ = rtc::TimeMillis(); | 1293 stat_start_time_ms_ = rtc::TimeMillis(); |
1312 current_frames_ = 0; | 1294 current_frames_ = 0; |
1313 current_bytes_ = 0; | 1295 current_bytes_ = 0; |
1314 current_acc_qp_ = 0; | 1296 current_acc_qp_ = 0; |
1315 current_encoding_time_ms_ = 0; | 1297 current_encoding_time_ms_ = 0; |
1316 } | 1298 } |
1317 } | 1299 } |
1318 | 1300 |
1319 webrtc::VideoEncoder::ScalingSettings | 1301 VideoEncoder::ScalingSettings MediaCodecVideoEncoder::GetScalingSettings() |
1320 MediaCodecVideoEncoder::GetScalingSettings() const { | 1302 const { |
1321 if (webrtc::field_trial::IsEnabled(kCustomQPThresholdsFieldTrial)) { | 1303 if (field_trial::IsEnabled(kCustomQPThresholdsFieldTrial)) { |
1322 const VideoCodecType codec_type = GetCodecType(); | 1304 const VideoCodecType codec_type = GetCodecType(); |
1323 std::string experiment_string = | 1305 std::string experiment_string = |
1324 webrtc::field_trial::FindFullName(kCustomQPThresholdsFieldTrial); | 1306 field_trial::FindFullName(kCustomQPThresholdsFieldTrial); |
1325 ALOGD << "QP custom thresholds: " << experiment_string << " for codec " | 1307 ALOGD << "QP custom thresholds: " << experiment_string << " for codec " |
1326 << codec_type; | 1308 << codec_type; |
1327 int low_vp8_qp_threshold; | 1309 int low_vp8_qp_threshold; |
1328 int high_vp8_qp_threshold; | 1310 int high_vp8_qp_threshold; |
1329 int low_h264_qp_threshold; | 1311 int low_h264_qp_threshold; |
1330 int high_h264_qp_threshold; | 1312 int high_h264_qp_threshold; |
1331 int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%u,%u,%u,%u", | 1313 int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%u,%u,%u,%u", |
1332 &low_vp8_qp_threshold, &high_vp8_qp_threshold, | 1314 &low_vp8_qp_threshold, &high_vp8_qp_threshold, |
1333 &low_h264_qp_threshold, &high_h264_qp_threshold); | 1315 &low_h264_qp_threshold, &high_h264_qp_threshold); |
1334 if (parsed_values == 4) { | 1316 if (parsed_values == 4) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 bool is_h264_high_profile_hw_supported = jni->CallStaticBooleanMethod( | 1366 bool is_h264_high_profile_hw_supported = jni->CallStaticBooleanMethod( |
1385 j_decoder_class, | 1367 j_decoder_class, |
1386 GetStaticMethodID(jni, j_decoder_class, "isH264HighProfileHwSupported", | 1368 GetStaticMethodID(jni, j_decoder_class, "isH264HighProfileHwSupported", |
1387 "()Z")); | 1369 "()Z")); |
1388 CHECK_EXCEPTION(jni); | 1370 CHECK_EXCEPTION(jni); |
1389 if (is_h264_high_profile_hw_supported) { | 1371 if (is_h264_high_profile_hw_supported) { |
1390 ALOGD << "H.264 High Profile HW Encoder supported."; | 1372 ALOGD << "H.264 High Profile HW Encoder supported."; |
1391 // TODO(magjed): Enumerate actual level instead of using hardcoded level | 1373 // TODO(magjed): Enumerate actual level instead of using hardcoded level |
1392 // 3.1. Level 3.1 is 1280x720@30fps which is enough for now. | 1374 // 3.1. Level 3.1 is 1280x720@30fps which is enough for now. |
1393 cricket::VideoCodec constrained_high(cricket::kH264CodecName); | 1375 cricket::VideoCodec constrained_high(cricket::kH264CodecName); |
1394 const webrtc::H264::ProfileLevelId constrained_high_profile( | 1376 const H264::ProfileLevelId constrained_high_profile( |
1395 webrtc::H264::kProfileConstrainedHigh, webrtc::H264::kLevel3_1); | 1377 H264::kProfileConstrainedHigh, H264::kLevel3_1); |
1396 constrained_high.SetParam( | 1378 constrained_high.SetParam( |
1397 cricket::kH264FmtpProfileLevelId, | 1379 cricket::kH264FmtpProfileLevelId, |
1398 *webrtc::H264::ProfileLevelIdToString(constrained_high_profile)); | 1380 *H264::ProfileLevelIdToString(constrained_high_profile)); |
1399 constrained_high.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1"); | 1381 constrained_high.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1"); |
1400 constrained_high.SetParam(cricket::kH264FmtpPacketizationMode, "1"); | 1382 constrained_high.SetParam(cricket::kH264FmtpPacketizationMode, "1"); |
1401 supported_codecs_with_h264_hp_.push_back(constrained_high); | 1383 supported_codecs_with_h264_hp_.push_back(constrained_high); |
1402 } | 1384 } |
1403 | 1385 |
1404 bool is_h264_hw_supported = jni->CallStaticBooleanMethod( | 1386 bool is_h264_hw_supported = jni->CallStaticBooleanMethod( |
1405 j_encoder_class, | 1387 j_encoder_class, |
1406 GetStaticMethodID(jni, j_encoder_class, "isH264HwSupported", "()Z")); | 1388 GetStaticMethodID(jni, j_encoder_class, "isH264HwSupported", "()Z")); |
1407 CHECK_EXCEPTION(jni); | 1389 CHECK_EXCEPTION(jni); |
1408 if (is_h264_hw_supported) { | 1390 if (is_h264_hw_supported) { |
1409 ALOGD << "H.264 HW Encoder supported."; | 1391 ALOGD << "H.264 HW Encoder supported."; |
1410 // TODO(magjed): Push Constrained High profile as well when negotiation is | 1392 // TODO(magjed): Push Constrained High profile as well when negotiation is |
1411 // ready, http://crbug/webrtc/6337. We can negotiate Constrained High | 1393 // ready, http://crbug/webrtc/6337. We can negotiate Constrained High |
1412 // profile as long as we have decode support for it and still send Baseline | 1394 // profile as long as we have decode support for it and still send Baseline |
1413 // since Baseline is a subset of the High profile. | 1395 // since Baseline is a subset of the High profile. |
1414 cricket::VideoCodec constrained_baseline(cricket::kH264CodecName); | 1396 cricket::VideoCodec constrained_baseline(cricket::kH264CodecName); |
1415 const webrtc::H264::ProfileLevelId constrained_baseline_profile( | 1397 const H264::ProfileLevelId constrained_baseline_profile( |
1416 webrtc::H264::kProfileConstrainedBaseline, webrtc::H264::kLevel3_1); | 1398 H264::kProfileConstrainedBaseline, H264::kLevel3_1); |
1417 constrained_baseline.SetParam( | 1399 constrained_baseline.SetParam( |
1418 cricket::kH264FmtpProfileLevelId, | 1400 cricket::kH264FmtpProfileLevelId, |
1419 *webrtc::H264::ProfileLevelIdToString(constrained_baseline_profile)); | 1401 *H264::ProfileLevelIdToString(constrained_baseline_profile)); |
1420 constrained_baseline.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1"); | 1402 constrained_baseline.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1"); |
1421 constrained_baseline.SetParam(cricket::kH264FmtpPacketizationMode, "1"); | 1403 constrained_baseline.SetParam(cricket::kH264FmtpPacketizationMode, "1"); |
1422 supported_codecs_.push_back(constrained_baseline); | 1404 supported_codecs_.push_back(constrained_baseline); |
1423 supported_codecs_with_h264_hp_.push_back(constrained_baseline); | 1405 supported_codecs_with_h264_hp_.push_back(constrained_baseline); |
1424 } | 1406 } |
1425 } | 1407 } |
1426 | 1408 |
1427 MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() { | 1409 MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() { |
1428 ALOGD << "MediaCodecVideoEncoderFactory dtor"; | 1410 ALOGD << "MediaCodecVideoEncoderFactory dtor"; |
1429 if (egl_context_) { | 1411 if (egl_context_) { |
1430 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 1412 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
1431 jni->DeleteGlobalRef(egl_context_); | 1413 jni->DeleteGlobalRef(egl_context_); |
1432 } | 1414 } |
1433 } | 1415 } |
1434 | 1416 |
1435 void MediaCodecVideoEncoderFactory::SetEGLContext( | 1417 void MediaCodecVideoEncoderFactory::SetEGLContext( |
1436 JNIEnv* jni, jobject egl_context) { | 1418 JNIEnv* jni, jobject egl_context) { |
1437 ALOGD << "MediaCodecVideoEncoderFactory::SetEGLContext"; | 1419 ALOGD << "MediaCodecVideoEncoderFactory::SetEGLContext"; |
1438 if (egl_context_) { | 1420 if (egl_context_) { |
1439 jni->DeleteGlobalRef(egl_context_); | 1421 jni->DeleteGlobalRef(egl_context_); |
1440 egl_context_ = nullptr; | 1422 egl_context_ = nullptr; |
1441 } | 1423 } |
1442 egl_context_ = jni->NewGlobalRef(egl_context); | 1424 egl_context_ = jni->NewGlobalRef(egl_context); |
1443 if (CheckException(jni)) { | 1425 if (CheckException(jni)) { |
1444 ALOGE << "error calling NewGlobalRef for EGL Context."; | 1426 ALOGE << "error calling NewGlobalRef for EGL Context."; |
1445 } | 1427 } |
1446 } | 1428 } |
1447 | 1429 |
1448 webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder( | 1430 VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder( |
1449 const cricket::VideoCodec& codec) { | 1431 const cricket::VideoCodec& codec) { |
1450 if (supported_codecs().empty()) { | 1432 if (supported_codecs().empty()) { |
1451 ALOGW << "No HW video encoder for codec " << codec.name; | 1433 ALOGW << "No HW video encoder for codec " << codec.name; |
1452 return nullptr; | 1434 return nullptr; |
1453 } | 1435 } |
1454 if (FindMatchingCodec(supported_codecs(), codec)) { | 1436 if (FindMatchingCodec(supported_codecs(), codec)) { |
1455 ALOGD << "Create HW video encoder for " << codec.name; | 1437 ALOGD << "Create HW video encoder for " << codec.name; |
1456 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 1438 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
1457 ScopedLocalRefFrame local_ref_frame(jni); | 1439 ScopedLocalRefFrame local_ref_frame(jni); |
1458 return new MediaCodecVideoEncoder(jni, codec, egl_context_); | 1440 return new MediaCodecVideoEncoder(jni, codec, egl_context_); |
1459 } | 1441 } |
1460 ALOGW << "Can not find HW video encoder for type " << codec.name; | 1442 ALOGW << "Can not find HW video encoder for type " << codec.name; |
1461 return nullptr; | 1443 return nullptr; |
1462 } | 1444 } |
1463 | 1445 |
1464 const std::vector<cricket::VideoCodec>& | 1446 const std::vector<cricket::VideoCodec>& |
1465 MediaCodecVideoEncoderFactory::supported_codecs() const { | 1447 MediaCodecVideoEncoderFactory::supported_codecs() const { |
1466 if (webrtc::field_trial::IsEnabled(kH264HighProfileFieldTrial)) { | 1448 if (field_trial::IsEnabled(kH264HighProfileFieldTrial)) { |
1467 return supported_codecs_with_h264_hp_; | 1449 return supported_codecs_with_h264_hp_; |
1468 } else { | 1450 } else { |
1469 return supported_codecs_; | 1451 return supported_codecs_; |
1470 } | 1452 } |
1471 } | 1453 } |
1472 | 1454 |
1473 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( | 1455 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) { |
1474 webrtc::VideoEncoder* encoder) { | |
1475 ALOGD << "Destroy video encoder."; | 1456 ALOGD << "Destroy video encoder."; |
1476 delete encoder; | 1457 delete encoder; |
1477 } | 1458 } |
1478 | 1459 |
1479 JNI_FUNCTION_DECLARATION(void, | 1460 JNI_FUNCTION_DECLARATION(void, |
1480 MediaCodecVideoEncoder_nativeFillBuffer, | 1461 MediaCodecVideoEncoder_nativeFillBuffer, |
1481 JNIEnv* jni, | 1462 JNIEnv* jni, |
1482 jclass, | 1463 jclass, |
1483 jlong native_encoder, | 1464 jlong native_encoder, |
1484 jint input_buffer, | 1465 jint input_buffer, |
1485 jobject j_buffer_y, | 1466 jobject j_buffer_y, |
1486 jint stride_y, | 1467 jint stride_y, |
1487 jobject j_buffer_u, | 1468 jobject j_buffer_u, |
1488 jint stride_u, | 1469 jint stride_u, |
1489 jobject j_buffer_v, | 1470 jobject j_buffer_v, |
1490 jint stride_v) { | 1471 jint stride_v) { |
1491 uint8_t* buffer_y = | 1472 uint8_t* buffer_y = |
1492 static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_y)); | 1473 static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_y)); |
1493 uint8_t* buffer_u = | 1474 uint8_t* buffer_u = |
1494 static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_u)); | 1475 static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_u)); |
1495 uint8_t* buffer_v = | 1476 uint8_t* buffer_v = |
1496 static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_v)); | 1477 static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_v)); |
1497 | 1478 |
1498 reinterpret_cast<MediaCodecVideoEncoder*>(native_encoder) | 1479 reinterpret_cast<MediaCodecVideoEncoder*>(native_encoder) |
1499 ->FillInputBuffer(jni, input_buffer, buffer_y, stride_y, buffer_u, | 1480 ->FillInputBuffer(jni, input_buffer, buffer_y, stride_y, buffer_u, |
1500 stride_u, buffer_v, stride_v); | 1481 stride_u, buffer_v, stride_v); |
1501 } | 1482 } |
1502 | 1483 |
1503 } // namespace webrtc_jni | 1484 } // namespace jni |
| 1485 } // namespace webrtc |
OLD | NEW |