| 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 |
| 11 #include "webrtc/modules/video_coding/media_opt_util.h" | 11 #include "webrtc/modules/video_coding/media_opt_util.h" |
| 12 | 12 |
| 13 #include <float.h> | 13 #include <float.h> |
| 14 #include <limits.h> | 14 #include <limits.h> |
| 15 #include <math.h> | 15 #include <math.h> |
| 16 | 16 |
| 17 #include <algorithm> | 17 #include <algorithm> |
| 18 #include <limits> |
| 18 | 19 |
| 19 #include "webrtc/modules/include/module_common_types.h" | 20 #include "webrtc/modules/include/module_common_types.h" |
| 20 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 21 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
| 21 #include "webrtc/modules/video_coding/include/video_coding_defines.h" | 22 #include "webrtc/modules/video_coding/include/video_coding_defines.h" |
| 22 #include "webrtc/modules/video_coding/fec_tables_xor.h" | 23 #include "webrtc/modules/video_coding/fec_tables_xor.h" |
| 23 #include "webrtc/modules/video_coding/nack_fec_tables.h" | 24 #include "webrtc/modules/video_coding/nack_fec_tables.h" |
| 24 | 25 |
| 25 namespace webrtc { | 26 namespace webrtc { |
| 26 // Max value of loss rates in off-line model | 27 // Max value of loss rates in off-line model |
| 27 static const int kPacketLossMax = 129; | 28 static const int kPacketLossMax = 129; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 | 238 |
| 238 // Update FEC with protectionFactorK | 239 // Update FEC with protectionFactorK |
| 239 void VCMFecMethod::UpdateProtectionFactorK(uint8_t protectionFactorK) { | 240 void VCMFecMethod::UpdateProtectionFactorK(uint8_t protectionFactorK) { |
| 240 _protectionFactorK = protectionFactorK; | 241 _protectionFactorK = protectionFactorK; |
| 241 } | 242 } |
| 242 | 243 |
| 243 bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { | 244 bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { |
| 244 // FEC PROTECTION SETTINGS: varies with packet loss and bitrate | 245 // FEC PROTECTION SETTINGS: varies with packet loss and bitrate |
| 245 | 246 |
| 246 // No protection if (filtered) packetLoss is 0 | 247 // No protection if (filtered) packetLoss is 0 |
| 247 uint8_t packetLoss = (uint8_t)(255 * parameters->lossPr); | 248 uint8_t packetLoss = static_cast<uint8_t>(255 * parameters->lossPr); |
| 248 if (packetLoss == 0) { | 249 if (packetLoss == 0) { |
| 249 _protectionFactorK = 0; | 250 _protectionFactorK = 0; |
| 250 _protectionFactorD = 0; | 251 _protectionFactorD = 0; |
| 251 return true; | 252 return true; |
| 252 } | 253 } |
| 253 | 254 |
| 254 // Parameters for FEC setting: | 255 // Parameters for FEC setting: |
| 255 // first partition size, thresholds, table pars, spatial resoln fac. | 256 // first partition size, thresholds, table pars, spatial resoln fac. |
| 256 | 257 |
| 257 // First partition protection: ~ 20% | 258 // First partition protection: ~ 20% |
| 258 uint8_t firstPartitionProt = (uint8_t)(255 * 0.20); | 259 uint8_t firstPartitionProt = static_cast<uint8_t>(255 * 0.20); |
| 259 | 260 |
| 260 // Minimum protection level needed to generate one FEC packet for one | 261 // Minimum protection level needed to generate one FEC packet for one |
| 261 // source packet/frame (in RTP sender) | 262 // source packet/frame (in RTP sender) |
| 262 uint8_t minProtLevelFec = 85; | 263 uint8_t minProtLevelFec = 85; |
| 263 | 264 |
| 264 // Threshold on packetLoss and bitRrate/frameRate (=average #packets), | 265 // Threshold on packetLoss and bitRrate/frameRate (=average #packets), |
| 265 // above which we allocate protection to cover at least first partition. | 266 // above which we allocate protection to cover at least first partition. |
| 266 uint8_t lossThr = 0; | 267 uint8_t lossThr = 0; |
| 267 uint8_t packetNumThr = 1; | 268 uint8_t packetNumThr = 1; |
| 268 | 269 |
| 269 // Parameters for range of rate index of table. | 270 // Parameters for range of rate index of table. |
| 270 const uint8_t ratePar1 = 5; | 271 const uint8_t ratePar1 = 5; |
| 271 const uint8_t ratePar2 = 49; | 272 const uint8_t ratePar2 = 49; |
| 272 | 273 |
| 273 // Spatial resolution size, relative to a reference size. | 274 // Spatial resolution size, relative to a reference size. |
| 274 float spatialSizeToRef = | 275 float spatialSizeToRef = |
| 275 static_cast<float>(parameters->codecWidth * parameters->codecHeight) / | 276 static_cast<float>(parameters->codecWidth * parameters->codecHeight) / |
| 276 (static_cast<float>(704 * 576)); | 277 (static_cast<float>(704 * 576)); |
| 277 // resolnFac: This parameter will generally increase/decrease the FEC rate | 278 // resolnFac: This parameter will generally increase/decrease the FEC rate |
| 278 // (for fixed bitRate and packetLoss) based on system size. | 279 // (for fixed bitRate and packetLoss) based on system size. |
| 279 // Use a smaller exponent (< 1) to control/soften system size effect. | 280 // Use a smaller exponent (< 1) to control/soften system size effect. |
| 280 const float resolnFac = 1.0 / powf(spatialSizeToRef, 0.3f); | 281 const float resolnFac = 1.0 / powf(spatialSizeToRef, 0.3f); |
| 281 | 282 |
| 282 const int bitRatePerFrame = BitsPerFrame(parameters); | 283 const int bitRatePerFrame = BitsPerFrame(parameters); |
| 283 | 284 |
| 284 // Average number of packets per frame (source and fec): | 285 // Average number of packets per frame (source and fec): |
| 285 const uint8_t avgTotPackets = | 286 const uint8_t avgTotPackets = static_cast<uint8_t>( |
| 286 1 + (uint8_t)(static_cast<float>(bitRatePerFrame) * 1000.0 / | 287 std::min(static_cast<float>(std::numeric_limits<uint8_t>::max()), |
| 287 static_cast<float>(8.0 * _maxPayloadSize) + | 288 1.5f + |
| 288 0.5); | 289 static_cast<float>(bitRatePerFrame) * 1000.0f / |
| 290 static_cast<float>(8.0 * _maxPayloadSize))); |
| 289 | 291 |
| 290 // FEC rate parameters: for P and I frame | 292 // FEC rate parameters: for P and I frame |
| 291 uint8_t codeRateDelta = 0; | 293 uint8_t codeRateDelta = 0; |
| 292 uint8_t codeRateKey = 0; | 294 uint8_t codeRateKey = 0; |
| 293 | 295 |
| 294 // Get index for table: the FEC protection depends on an effective rate. | 296 // Get index for table: the FEC protection depends on an effective rate. |
| 295 // The range on the rate index corresponds to rates (bps) | 297 // The range on the rate index corresponds to rates (bps) |
| 296 // from ~200k to ~8000k, for 30fps | 298 // from ~200k to ~8000k, for 30fps |
| 297 const uint16_t effRateFecTable = | 299 const uint16_t effRateFecTable = |
| 298 static_cast<uint16_t>(resolnFac * bitRatePerFrame); | 300 static_cast<uint16_t>(resolnFac * bitRatePerFrame); |
| 299 uint8_t rateIndexTable = (uint8_t)VCM_MAX( | 301 uint8_t rateIndexTable = static_cast<uint8_t>( |
| 300 VCM_MIN((effRateFecTable - ratePar1) / ratePar1, ratePar2), 0); | 302 VCM_MAX(VCM_MIN((effRateFecTable - ratePar1) / ratePar1, ratePar2), 0)); |
| 301 | 303 |
| 302 // Restrict packet loss range to 50: | 304 // Restrict packet loss range to 50: |
| 303 // current tables defined only up to 50% | 305 // current tables defined only up to 50% |
| 304 if (packetLoss >= kPacketLossMax) { | 306 if (packetLoss >= kPacketLossMax) { |
| 305 packetLoss = kPacketLossMax - 1; | 307 packetLoss = kPacketLossMax - 1; |
| 306 } | 308 } |
| 307 uint16_t indexTable = rateIndexTable * kPacketLossMax + packetLoss; | 309 uint16_t indexTable = rateIndexTable * kPacketLossMax + packetLoss; |
| 308 | 310 |
| 309 // Check on table index | 311 // Check on table index |
| 310 assert(indexTable < kSizeCodeRateXORTable); | 312 assert(indexTable < kSizeCodeRateXORTable); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 321 | 323 |
| 322 // Check limit on amount of protection for P frame; 50% is max. | 324 // Check limit on amount of protection for P frame; 50% is max. |
| 323 if (codeRateDelta >= kPacketLossMax) { | 325 if (codeRateDelta >= kPacketLossMax) { |
| 324 codeRateDelta = kPacketLossMax - 1; | 326 codeRateDelta = kPacketLossMax - 1; |
| 325 } | 327 } |
| 326 | 328 |
| 327 // For Key frame: | 329 // For Key frame: |
| 328 // Effectively at a higher rate, so we scale/boost the rate | 330 // Effectively at a higher rate, so we scale/boost the rate |
| 329 // The boost factor may depend on several factors: ratio of packet | 331 // The boost factor may depend on several factors: ratio of packet |
| 330 // number of I to P frames, how much protection placed on P frames, etc. | 332 // number of I to P frames, how much protection placed on P frames, etc. |
| 331 const uint8_t packetFrameDelta = (uint8_t)(0.5 + parameters->packetsPerFrame); | 333 const uint8_t packetFrameDelta = |
| 334 static_cast<uint8_t>(0.5 + parameters->packetsPerFrame); |
| 332 const uint8_t packetFrameKey = | 335 const uint8_t packetFrameKey = |
| 333 (uint8_t)(0.5 + parameters->packetsPerFrameKey); | 336 static_cast<uint8_t>(0.5 + parameters->packetsPerFrameKey); |
| 334 const uint8_t boostKey = BoostCodeRateKey(packetFrameDelta, packetFrameKey); | 337 const uint8_t boostKey = BoostCodeRateKey(packetFrameDelta, packetFrameKey); |
| 335 | 338 |
| 336 rateIndexTable = (uint8_t)VCM_MAX( | 339 rateIndexTable = static_cast<uint8_t>(VCM_MAX( |
| 337 VCM_MIN(1 + (boostKey * effRateFecTable - ratePar1) / ratePar1, ratePar2), | 340 VCM_MIN(1 + (boostKey * effRateFecTable - ratePar1) / ratePar1, ratePar2), |
| 338 0); | 341 0)); |
| 339 uint16_t indexTableKey = rateIndexTable * kPacketLossMax + packetLoss; | 342 uint16_t indexTableKey = rateIndexTable * kPacketLossMax + packetLoss; |
| 340 | 343 |
| 341 indexTableKey = VCM_MIN(indexTableKey, kSizeCodeRateXORTable); | 344 indexTableKey = VCM_MIN(indexTableKey, kSizeCodeRateXORTable); |
| 342 | 345 |
| 343 // Check on table index | 346 // Check on table index |
| 344 assert(indexTableKey < kSizeCodeRateXORTable); | 347 assert(indexTableKey < kSizeCodeRateXORTable); |
| 345 | 348 |
| 346 // Protection factor for I frame | 349 // Protection factor for I frame |
| 347 codeRateKey = kCodeRateXORTable[indexTableKey]; | 350 codeRateKey = kCodeRateXORTable[indexTableKey]; |
| 348 | 351 |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 _shortMaxLossPr255 = 0; | 651 _shortMaxLossPr255 = 0; |
| 649 Release(); | 652 Release(); |
| 650 } | 653 } |
| 651 | 654 |
| 652 void VCMLossProtectionLogic::Release() { | 655 void VCMLossProtectionLogic::Release() { |
| 653 _selectedMethod.reset(); | 656 _selectedMethod.reset(); |
| 654 } | 657 } |
| 655 | 658 |
| 656 } // namespace media_optimization | 659 } // namespace media_optimization |
| 657 } // namespace webrtc | 660 } // namespace webrtc |
| OLD | NEW |