OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 11 matching lines...) Expand all Loading... | |
22 | 22 |
23 #include "webrtc/common_types.h" | 23 #include "webrtc/common_types.h" |
24 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 24 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
25 #include "webrtc/modules/include/module_common_types.h" | 25 #include "webrtc/modules/include/module_common_types.h" |
26 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 26 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
27 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" | 27 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" |
28 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" | 28 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" |
29 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" | 29 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" |
30 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 30 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
31 #include "webrtc/rtc_base/checks.h" | 31 #include "webrtc/rtc_base/checks.h" |
32 #include "webrtc/rtc_base/numerics/exp_filter.h" | |
32 #include "webrtc/rtc_base/random.h" | 33 #include "webrtc/rtc_base/random.h" |
33 #include "webrtc/rtc_base/timeutils.h" | 34 #include "webrtc/rtc_base/timeutils.h" |
34 #include "webrtc/rtc_base/trace_event.h" | 35 #include "webrtc/rtc_base/trace_event.h" |
35 #include "webrtc/system_wrappers/include/clock.h" | 36 #include "webrtc/system_wrappers/include/clock.h" |
36 #include "webrtc/system_wrappers/include/field_trial.h" | 37 #include "webrtc/system_wrappers/include/field_trial.h" |
37 #include "webrtc/system_wrappers/include/metrics.h" | 38 #include "webrtc/system_wrappers/include/metrics.h" |
38 | 39 |
39 namespace webrtc { | 40 namespace webrtc { |
40 namespace { | 41 namespace { |
41 | 42 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 return false; | 116 return false; |
116 | 117 |
117 if (sscanf(group.c_str(), "Enabled-%d", boost_percentage) != 1) | 118 if (sscanf(group.c_str(), "Enabled-%d", boost_percentage) != 1) |
118 return false; | 119 return false; |
119 | 120 |
120 if (*boost_percentage < 0 || *boost_percentage > 100) | 121 if (*boost_percentage < 0 || *boost_percentage > 100) |
121 return false; | 122 return false; |
122 | 123 |
123 return true; | 124 return true; |
124 } | 125 } |
126 | |
127 void GetPostProcParamsFromFieldTrialGroup( | |
128 VP8DecoderImpl::DeblockParams* deblock_params) { | |
129 std::string group = | |
130 webrtc::field_trial::FindFullName(kVp8PostProcArmFieldTrial); | |
131 if (group.empty()) | |
132 return; | |
133 | |
134 VP8DecoderImpl::DeblockParams params; | |
135 if (sscanf(group.c_str(), "Enabled-%d,%d,%d", ¶ms.level, ¶ms.min_qp, | |
136 ¶ms.degrade_qp) != 3) | |
137 return; | |
138 | |
139 if (params.level < 0 || params.level > 16) | |
140 return; | |
141 | |
142 if (params.min_qp < 0 || params.degrade_qp <= params.min_qp) | |
143 return; | |
144 | |
145 *deblock_params = params; | |
146 } | |
brandtr
2017/08/09 10:50:39
nit: newline.
åsapersson
2017/08/09 14:03:27
Done.
| |
125 } // namespace | 147 } // namespace |
126 | 148 |
127 VP8Encoder* VP8Encoder::Create() { | 149 VP8Encoder* VP8Encoder::Create() { |
128 return new VP8EncoderImpl(); | 150 return new VP8EncoderImpl(); |
129 } | 151 } |
130 | 152 |
131 VP8Decoder* VP8Decoder::Create() { | 153 VP8Decoder* VP8Decoder::Create() { |
132 return new VP8DecoderImpl(); | 154 return new VP8DecoderImpl(); |
133 } | 155 } |
134 | 156 |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
918 int VP8EncoderImpl::SetChannelParameters(uint32_t packetLoss, int64_t rtt) { | 940 int VP8EncoderImpl::SetChannelParameters(uint32_t packetLoss, int64_t rtt) { |
919 return WEBRTC_VIDEO_CODEC_OK; | 941 return WEBRTC_VIDEO_CODEC_OK; |
920 } | 942 } |
921 | 943 |
922 int VP8EncoderImpl::RegisterEncodeCompleteCallback( | 944 int VP8EncoderImpl::RegisterEncodeCompleteCallback( |
923 EncodedImageCallback* callback) { | 945 EncodedImageCallback* callback) { |
924 encoded_complete_callback_ = callback; | 946 encoded_complete_callback_ = callback; |
925 return WEBRTC_VIDEO_CODEC_OK; | 947 return WEBRTC_VIDEO_CODEC_OK; |
926 } | 948 } |
927 | 949 |
950 class VP8DecoderImpl::QpSmoother { | |
951 public: | |
952 QpSmoother() : last_sample_ms_(rtc::TimeMillis()), smoother_(kAlpha) {} | |
953 | |
954 int GetAvg() const { | |
955 float value = smoother_.filtered(); | |
956 return (value == rtc::ExpFilter::kValueUndefined) ? 0 | |
957 : static_cast<int>(value); | |
958 } | |
959 | |
960 void Add(float sample) { | |
961 int64_t now_ms = rtc::TimeMillis(); | |
962 smoother_.Apply(static_cast<float>(now_ms - last_sample_ms_), sample); | |
963 last_sample_ms_ = now_ms; | |
964 } | |
965 | |
966 void Reset() { smoother_.Reset(kAlpha); } | |
967 | |
968 private: | |
969 const float kAlpha = 0.95f; | |
970 int64_t last_sample_ms_; | |
971 rtc::ExpFilter smoother_; | |
972 }; | |
973 | |
928 VP8DecoderImpl::VP8DecoderImpl() | 974 VP8DecoderImpl::VP8DecoderImpl() |
929 : use_postproc_arm_(webrtc::field_trial::FindFullName( | 975 : use_postproc_arm_( |
930 kVp8PostProcArmFieldTrial) == "Enabled"), | 976 webrtc::field_trial::IsEnabled(kVp8PostProcArmFieldTrial)), |
931 buffer_pool_(false, 300 /* max_number_of_buffers*/), | 977 buffer_pool_(false, 300 /* max_number_of_buffers*/), |
932 decode_complete_callback_(NULL), | 978 decode_complete_callback_(NULL), |
933 inited_(false), | 979 inited_(false), |
934 decoder_(NULL), | 980 decoder_(NULL), |
935 propagation_cnt_(-1), | 981 propagation_cnt_(-1), |
936 last_frame_width_(0), | 982 last_frame_width_(0), |
937 last_frame_height_(0), | 983 last_frame_height_(0), |
938 key_frame_required_(true) {} | 984 key_frame_required_(true), |
985 qp_(use_postproc_arm_ ? new QpSmoother() : nullptr) { | |
986 if (use_postproc_arm_) | |
987 GetPostProcParamsFromFieldTrialGroup(&deblock_); | |
988 } | |
939 | 989 |
940 VP8DecoderImpl::~VP8DecoderImpl() { | 990 VP8DecoderImpl::~VP8DecoderImpl() { |
941 inited_ = true; // in order to do the actual release | 991 inited_ = true; // in order to do the actual release |
942 Release(); | 992 Release(); |
943 } | 993 } |
944 | 994 |
945 int VP8DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) { | 995 int VP8DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) { |
946 int ret_val = Release(); | 996 int ret_val = Release(); |
947 if (ret_val < 0) { | 997 if (ret_val < 0) { |
948 return ret_val; | 998 return ret_val; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
992 if (propagation_cnt_ > 0) | 1042 if (propagation_cnt_ > 0) |
993 propagation_cnt_ = 0; | 1043 propagation_cnt_ = 0; |
994 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 1044 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
995 } | 1045 } |
996 | 1046 |
997 // Post process configurations. | 1047 // Post process configurations. |
998 #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID) | 1048 #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID) |
999 if (use_postproc_arm_) { | 1049 if (use_postproc_arm_) { |
1000 vp8_postproc_cfg_t ppcfg; | 1050 vp8_postproc_cfg_t ppcfg; |
1001 ppcfg.post_proc_flag = VP8_MFQE; | 1051 ppcfg.post_proc_flag = VP8_MFQE; |
1002 // For low resolutions, use stronger deblocking filter and enable the | 1052 // For low resolutions, use stronger deblocking filter. |
1003 // deblock and demacroblocker. | |
1004 int last_width_x_height = last_frame_width_ * last_frame_height_; | 1053 int last_width_x_height = last_frame_width_ * last_frame_height_; |
1005 if (last_width_x_height > 0 && last_width_x_height <= 320 * 240) { | 1054 if (last_width_x_height > 0 && last_width_x_height <= 320 * 240) { |
1006 ppcfg.deblocking_level = 6; // Only affects VP8_DEMACROBLOCK. | 1055 // Enable the deblock and demacroblocker based on qp thresholds. |
1007 ppcfg.post_proc_flag |= VP8_DEBLOCK | VP8_DEMACROBLOCK; | 1056 int qp = qp_->GetAvg(); |
brandtr
2017/08/09 10:50:39
Just to be safe, maybe add a RTC_DCHECK(qp_).
åsapersson
2017/08/09 14:03:27
Done.
| |
1057 if (qp > deblock_.min_qp) { | |
1058 int level = deblock_.level; | |
1059 if (qp < deblock_.degrade_qp) { | |
1060 // Use lower level. | |
1061 level = deblock_.level * (qp - deblock_.min_qp) / | |
1062 (deblock_.degrade_qp - deblock_.min_qp); | |
1063 } | |
1064 // Deblocking level only affects VP8_DEMACROBLOCK. | |
1065 ppcfg.deblocking_level = std::max(level, 1); | |
1066 ppcfg.post_proc_flag |= VP8_DEBLOCK | VP8_DEMACROBLOCK; | |
1067 } | |
1008 } | 1068 } |
1009 vpx_codec_control(decoder_, VP8_SET_POSTPROC, &ppcfg); | 1069 vpx_codec_control(decoder_, VP8_SET_POSTPROC, &ppcfg); |
1010 } | 1070 } |
1011 #else | 1071 #else |
1012 vp8_postproc_cfg_t ppcfg; | 1072 vp8_postproc_cfg_t ppcfg; |
1013 // MFQE enabled to reduce key frame popping. | 1073 // MFQE enabled to reduce key frame popping. |
1014 ppcfg.post_proc_flag = VP8_MFQE | VP8_DEBLOCK; | 1074 ppcfg.post_proc_flag = VP8_MFQE | VP8_DEBLOCK; |
1015 // For VGA resolutions and lower, enable the demacroblocker postproc. | 1075 // For VGA resolutions and lower, enable the demacroblocker postproc. |
1016 if (last_frame_width_ * last_frame_height_ <= 640 * 360) { | 1076 if (last_frame_width_ * last_frame_height_ <= 640 * 360) { |
1017 ppcfg.post_proc_flag |= VP8_DEMACROBLOCK; | 1077 ppcfg.post_proc_flag |= VP8_DEMACROBLOCK; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1097 } | 1157 } |
1098 | 1158 |
1099 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, | 1159 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, |
1100 uint32_t timestamp, | 1160 uint32_t timestamp, |
1101 int64_t ntp_time_ms, | 1161 int64_t ntp_time_ms, |
1102 int qp) { | 1162 int qp) { |
1103 if (img == NULL) { | 1163 if (img == NULL) { |
1104 // Decoder OK and NULL image => No show frame | 1164 // Decoder OK and NULL image => No show frame |
1105 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; | 1165 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; |
1106 } | 1166 } |
1167 if (qp_) { | |
1168 if (last_frame_width_ != static_cast<int>(img->d_w) || | |
1169 last_frame_height_ != static_cast<int>(img->d_h)) { | |
1170 qp_->Reset(); | |
1171 } | |
1172 qp_->Add(qp); | |
1173 } | |
1107 last_frame_width_ = img->d_w; | 1174 last_frame_width_ = img->d_w; |
1108 last_frame_height_ = img->d_h; | 1175 last_frame_height_ = img->d_h; |
1109 // Allocate memory for decoded image. | 1176 // Allocate memory for decoded image. |
1110 rtc::scoped_refptr<I420Buffer> buffer = | 1177 rtc::scoped_refptr<I420Buffer> buffer = |
1111 buffer_pool_.CreateBuffer(img->d_w, img->d_h); | 1178 buffer_pool_.CreateBuffer(img->d_w, img->d_h); |
1112 if (!buffer.get()) { | 1179 if (!buffer.get()) { |
1113 // Pool has too many pending frames. | 1180 // Pool has too many pending frames. |
1114 RTC_HISTOGRAM_BOOLEAN("WebRTC.Video.VP8DecoderImpl.TooManyPendingFrames", | 1181 RTC_HISTOGRAM_BOOLEAN("WebRTC.Video.VP8DecoderImpl.TooManyPendingFrames", |
1115 1); | 1182 1); |
1116 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; | 1183 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1149 buffer_pool_.Release(); | 1216 buffer_pool_.Release(); |
1150 inited_ = false; | 1217 inited_ = false; |
1151 return WEBRTC_VIDEO_CODEC_OK; | 1218 return WEBRTC_VIDEO_CODEC_OK; |
1152 } | 1219 } |
1153 | 1220 |
1154 const char* VP8DecoderImpl::ImplementationName() const { | 1221 const char* VP8DecoderImpl::ImplementationName() const { |
1155 return "libvpx"; | 1222 return "libvpx"; |
1156 } | 1223 } |
1157 | 1224 |
1158 } // namespace webrtc | 1225 } // namespace webrtc |
OLD | NEW |