| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    76 #define ALOGV(...) |    76 #define ALOGV(...) | 
|    77 #endif |    77 #endif | 
|    78 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER) |    78 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER) | 
|    79 #define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_ENCODER) |    79 #define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_ENCODER) | 
|    80 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_ENCODER) |    80 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_ENCODER) | 
|    81  |    81  | 
|    82 namespace { |    82 namespace { | 
|    83 // Maximum time limit between incoming frames before requesting a key frame. |    83 // Maximum time limit between incoming frames before requesting a key frame. | 
|    84 const size_t kFrameDiffThresholdMs = 350; |    84 const size_t kFrameDiffThresholdMs = 350; | 
|    85 const int kMinKeyFrameInterval = 6; |    85 const int kMinKeyFrameInterval = 6; | 
 |    86 const char kH264HighProfileFieldTrial[] = "WebRTC-H264HighProfile"; | 
|    86 }  // namespace |    87 }  // namespace | 
|    87  |    88  | 
|    88 // MediaCodecVideoEncoder is a webrtc::VideoEncoder implementation that uses |    89 // MediaCodecVideoEncoder is a webrtc::VideoEncoder implementation that uses | 
|    89 // Android's MediaCodec SDK API behind the scenes to implement (hopefully) |    90 // Android's MediaCodec SDK API behind the scenes to implement (hopefully) | 
|    90 // HW-backed video encode.  This C++ class is implemented as a very thin shim, |    91 // HW-backed video encode.  This C++ class is implemented as a very thin shim, | 
|    91 // delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder. |    92 // delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder. | 
|    92 // MediaCodecVideoEncoder is created, operated, and destroyed on a single |    93 // MediaCodecVideoEncoder is created, operated, and destroyed on a single | 
|    93 // thread, currently the libjingle Worker thread. |    94 // thread, currently the libjingle Worker thread. | 
|    94 class MediaCodecVideoEncoder : public webrtc::VideoEncoder, |    95 class MediaCodecVideoEncoder : public webrtc::VideoEncoder, | 
|    95                                public rtc::MessageHandler { |    96                                public rtc::MessageHandler { | 
| (...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1186  |  1187  | 
|  1187 const char* MediaCodecVideoEncoder::ImplementationName() const { |  1188 const char* MediaCodecVideoEncoder::ImplementationName() const { | 
|  1188   return "MediaCodec"; |  1189   return "MediaCodec"; | 
|  1189 } |  1190 } | 
|  1190  |  1191  | 
|  1191 MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() |  1192 MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() | 
|  1192     : egl_context_(nullptr) { |  1193     : egl_context_(nullptr) { | 
|  1193   JNIEnv* jni = AttachCurrentThreadIfNeeded(); |  1194   JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 
|  1194   ScopedLocalRefFrame local_ref_frame(jni); |  1195   ScopedLocalRefFrame local_ref_frame(jni); | 
|  1195   jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder"); |  1196   jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder"); | 
 |  1197   jclass j_decoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoDecoder"); | 
|  1196   supported_codecs_.clear(); |  1198   supported_codecs_.clear(); | 
|  1197  |  1199  | 
|  1198   bool is_vp8_hw_supported = jni->CallStaticBooleanMethod( |  1200   bool is_vp8_hw_supported = jni->CallStaticBooleanMethod( | 
|  1199       j_encoder_class, |  1201       j_encoder_class, | 
|  1200       GetStaticMethodID(jni, j_encoder_class, "isVp8HwSupported", "()Z")); |  1202       GetStaticMethodID(jni, j_encoder_class, "isVp8HwSupported", "()Z")); | 
|  1201   CHECK_EXCEPTION(jni); |  1203   CHECK_EXCEPTION(jni); | 
|  1202   if (is_vp8_hw_supported) { |  1204   if (is_vp8_hw_supported) { | 
|  1203     ALOGD << "VP8 HW Encoder supported."; |  1205     ALOGD << "VP8 HW Encoder supported."; | 
|  1204     supported_codecs_.push_back(cricket::VideoCodec("VP8")); |  1206     supported_codecs_.push_back(cricket::VideoCodec("VP8")); | 
|  1205   } |  1207   } | 
|  1206  |  1208  | 
|  1207   bool is_vp9_hw_supported = jni->CallStaticBooleanMethod( |  1209   bool is_vp9_hw_supported = jni->CallStaticBooleanMethod( | 
|  1208       j_encoder_class, |  1210       j_encoder_class, | 
|  1209       GetStaticMethodID(jni, j_encoder_class, "isVp9HwSupported", "()Z")); |  1211       GetStaticMethodID(jni, j_encoder_class, "isVp9HwSupported", "()Z")); | 
|  1210   CHECK_EXCEPTION(jni); |  1212   CHECK_EXCEPTION(jni); | 
|  1211   if (is_vp9_hw_supported) { |  1213   if (is_vp9_hw_supported) { | 
|  1212     ALOGD << "VP9 HW Encoder supported."; |  1214     ALOGD << "VP9 HW Encoder supported."; | 
|  1213     supported_codecs_.push_back(cricket::VideoCodec("VP9")); |  1215     supported_codecs_.push_back(cricket::VideoCodec("VP9")); | 
|  1214   } |  1216   } | 
|  1215  |  1217  | 
 |  1218   // Check if high profile is supported by decoder. If yes, encoder can always | 
 |  1219   // fall back to baseline profile as a subset as high profile. | 
 |  1220   bool is_h264_high_profile_hw_supported = false; | 
 |  1221   if (webrtc::field_trial::FindFullName(kH264HighProfileFieldTrial) == | 
 |  1222       "Enabled") { | 
 |  1223     is_h264_high_profile_hw_supported = jni->CallStaticBooleanMethod( | 
 |  1224         j_decoder_class, | 
 |  1225         GetStaticMethodID(jni, j_decoder_class, "isH264HighProfileHwSupported", | 
 |  1226                           "()Z")); | 
 |  1227     CHECK_EXCEPTION(jni); | 
 |  1228   } | 
 |  1229   if (is_h264_high_profile_hw_supported) { | 
 |  1230     ALOGD << "H.264 High Profile HW Encoder supported."; | 
 |  1231     // TODO(magjed): Enumerate actual level instead of using hardcoded level | 
 |  1232     // 3.1. Level 3.1 is 1280x720@30fps which is enough for now. | 
 |  1233     cricket::VideoCodec constrained_high(cricket::kH264CodecName); | 
 |  1234     const webrtc::H264::ProfileLevelId constrained_high_profile( | 
 |  1235         webrtc::H264::kProfileConstrainedHigh, webrtc::H264::kLevel3_1); | 
 |  1236     constrained_high.SetParam( | 
 |  1237         cricket::kH264FmtpProfileLevelId, | 
 |  1238         *webrtc::H264::ProfileLevelIdToString(constrained_high_profile)); | 
 |  1239     constrained_high.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1"); | 
 |  1240     constrained_high.SetParam(cricket::kH264FmtpPacketizationMode, "1"); | 
 |  1241     supported_codecs_.push_back(constrained_high); | 
 |  1242   } | 
 |  1243  | 
|  1216   bool is_h264_hw_supported = jni->CallStaticBooleanMethod( |  1244   bool is_h264_hw_supported = jni->CallStaticBooleanMethod( | 
|  1217       j_encoder_class, |  1245       j_encoder_class, | 
|  1218       GetStaticMethodID(jni, j_encoder_class, "isH264HwSupported", "()Z")); |  1246       GetStaticMethodID(jni, j_encoder_class, "isH264HwSupported", "()Z")); | 
|  1219   CHECK_EXCEPTION(jni); |  1247   CHECK_EXCEPTION(jni); | 
|  1220   if (is_h264_hw_supported) { |  1248   if (is_h264_hw_supported) { | 
|  1221     ALOGD << "H.264 HW Encoder supported."; |  1249     ALOGD << "H.264 HW Encoder supported."; | 
|  1222     // TODO(magjed): Push Constrained High profile as well when negotiation is |  1250     // TODO(magjed): Push Constrained High profile as well when negotiation is | 
|  1223     // ready, http://crbug/webrtc/6337. We can negotiate Constrained High |  1251     // ready, http://crbug/webrtc/6337. We can negotiate Constrained High | 
|  1224     // profile as long as we have decode support for it and still send Baseline |  1252     // profile as long as we have decode support for it and still send Baseline | 
|  1225     // since Baseline is a subset of the High profile. |  1253     // since Baseline is a subset of the High profile. | 
|  1226     cricket::VideoCodec constrained_baseline(cricket::kH264CodecName); |  1254     cricket::VideoCodec constrained_baseline(cricket::kH264CodecName); | 
|  1227     // TODO(magjed): Enumerate actual level instead of using hardcoded level |  | 
|  1228     // 3.1. Level 3.1 is 1280x720@30fps which is enough for now. |  | 
|  1229     const webrtc::H264::ProfileLevelId constrained_baseline_profile( |  1255     const webrtc::H264::ProfileLevelId constrained_baseline_profile( | 
|  1230         webrtc::H264::kProfileConstrainedBaseline, webrtc::H264::kLevel3_1); |  1256         webrtc::H264::kProfileConstrainedBaseline, webrtc::H264::kLevel3_1); | 
|  1231     constrained_baseline.SetParam( |  1257     constrained_baseline.SetParam( | 
|  1232         cricket::kH264FmtpProfileLevelId, |  1258         cricket::kH264FmtpProfileLevelId, | 
|  1233         *webrtc::H264::ProfileLevelIdToString(constrained_baseline_profile)); |  1259         *webrtc::H264::ProfileLevelIdToString(constrained_baseline_profile)); | 
|  1234     constrained_baseline.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1"); |  1260     constrained_baseline.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1"); | 
|  1235     constrained_baseline.SetParam(cricket::kH264FmtpPacketizationMode, "1"); |  1261     constrained_baseline.SetParam(cricket::kH264FmtpPacketizationMode, "1"); | 
|  1236     supported_codecs_.push_back(constrained_baseline); |  1262     supported_codecs_.push_back(constrained_baseline); | 
|  1237   } |  1263   } | 
|  1238 } |  1264 } | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1279   return supported_codecs_; |  1305   return supported_codecs_; | 
|  1280 } |  1306 } | 
|  1281  |  1307  | 
|  1282 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( |  1308 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( | 
|  1283     webrtc::VideoEncoder* encoder) { |  1309     webrtc::VideoEncoder* encoder) { | 
|  1284   ALOGD << "Destroy video encoder."; |  1310   ALOGD << "Destroy video encoder."; | 
|  1285   delete encoder; |  1311   delete encoder; | 
|  1286 } |  1312 } | 
|  1287  |  1313  | 
|  1288 }  // namespace webrtc_jni |  1314 }  // namespace webrtc_jni | 
| OLD | NEW |