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/rtp_rtcp/source/tmmbr_help.h" | 11 #include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 #include <string.h> | 14 #include <string.h> |
15 | 15 |
16 #include <limits> | 16 #include <limits> |
17 | 17 |
| 18 #include "webrtc/base/checks.h" |
18 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h" | 19 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h" |
19 | 20 |
20 namespace webrtc { | 21 namespace webrtc { |
21 TMMBRSet::TMMBRSet() : | 22 TMMBRSet::TMMBRSet() : |
22 _sizeOfSet(0), | 23 _sizeOfSet(0), |
23 _lengthOfSet(0) | 24 _lengthOfSet(0) |
24 { | 25 { |
25 } | 26 } |
26 | 27 |
27 TMMBRSet::~TMMBRSet() | 28 TMMBRSet::~TMMBRSet() |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 } | 294 } |
294 } | 295 } |
295 } | 296 } |
296 // keep lowest bitrate | 297 // keep lowest bitrate |
297 for (uint32_t j = 0; j < candidateSet.sizeOfSet(); j++) | 298 for (uint32_t j = 0; j < candidateSet.sizeOfSet(); j++) |
298 { | 299 { |
299 if(candidateSet.PacketOH(j) == currentPacketOH | 300 if(candidateSet.PacketOH(j) == currentPacketOH |
300 && j != currentMinIndexTMMBR) | 301 && j != currentMinIndexTMMBR) |
301 { | 302 { |
302 candidateSet.ClearEntry(j); | 303 candidateSet.ClearEntry(j); |
| 304 numCandidates--; |
303 } | 305 } |
304 } | 306 } |
305 } | 307 } |
306 } | 308 } |
307 // 3. Select and remove tuple w/ lowest tmmbr. | 309 // 3. Select and remove tuple w/ lowest tmmbr. |
308 // (If more than 1, choose the one w/ highest OH). | 310 // (If more than 1, choose the one w/ highest OH). |
309 uint32_t minTMMBR = 0; | 311 uint32_t minTMMBR = 0; |
310 uint32_t minIndexTMMBR = 0; | 312 uint32_t minIndexTMMBR = 0; |
311 for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) | 313 for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) |
312 { | 314 { |
(...skipping 16 matching lines...) Expand all Loading... |
329 } | 331 } |
330 // first member of selected list | 332 // first member of selected list |
331 _boundingSet.SetEntry(numBoundingSet, | 333 _boundingSet.SetEntry(numBoundingSet, |
332 candidateSet.Tmmbr(minIndexTMMBR), | 334 candidateSet.Tmmbr(minIndexTMMBR), |
333 candidateSet.PacketOH(minIndexTMMBR), | 335 candidateSet.PacketOH(minIndexTMMBR), |
334 candidateSet.Ssrc(minIndexTMMBR)); | 336 candidateSet.Ssrc(minIndexTMMBR)); |
335 | 337 |
336 // set intersection value | 338 // set intersection value |
337 _ptrIntersectionBoundingSet[numBoundingSet] = 0; | 339 _ptrIntersectionBoundingSet[numBoundingSet] = 0; |
338 // calculate its maximum packet rate (where its line crosses x-axis) | 340 // calculate its maximum packet rate (where its line crosses x-axis) |
339 _ptrMaxPRBoundingSet[numBoundingSet] | 341 uint32_t packet_overhead_bits = 8 * _boundingSet.PacketOH(numBoundingSet); |
340 = _boundingSet.Tmmbr(numBoundingSet) * 1000 | 342 if (packet_overhead_bits == 0) { |
341 / float(8 * _boundingSet.PacketOH(numBoundingSet)); | 343 // Avoid division by zero. |
| 344 _ptrMaxPRBoundingSet[numBoundingSet] = std::numeric_limits<float>::max(); |
| 345 } else { |
| 346 _ptrMaxPRBoundingSet[numBoundingSet] = |
| 347 _boundingSet.Tmmbr(numBoundingSet) * 1000 / |
| 348 static_cast<float>(packet_overhead_bits); |
| 349 } |
342 numBoundingSet++; | 350 numBoundingSet++; |
343 // remove from candidate list | 351 // remove from candidate list |
344 candidateSet.ClearEntry(minIndexTMMBR); | 352 candidateSet.ClearEntry(minIndexTMMBR); |
345 numCandidates--; | 353 numCandidates--; |
346 | 354 |
347 // 4. Discard from candidate list all tuple w/ lower OH | 355 // 4. Discard from candidate list all tuple w/ lower OH |
348 // (next tuple must be steeper) | 356 // (next tuple must be steeper) |
349 for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) | 357 for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) |
350 { | 358 { |
351 if(candidateSet.Tmmbr(i) > 0 | 359 if(candidateSet.Tmmbr(i) > 0 |
352 && candidateSet.PacketOH(i) < _boundingSet.PacketOH(0)) | 360 && candidateSet.PacketOH(i) < _boundingSet.PacketOH(0)) |
353 { | 361 { |
354 candidateSet.ClearEntry(i); | 362 candidateSet.ClearEntry(i); |
355 numCandidates--; | 363 numCandidates--; |
356 } | 364 } |
357 } | 365 } |
358 | 366 |
359 if (numCandidates == 0) | 367 if (numCandidates == 0) |
360 { | 368 { |
361 // Should be true already:_boundingSet.lengthOfSet = numBoundingSet; | 369 // Should be true already:_boundingSet.lengthOfSet = numBoundingSet; |
362 assert(_boundingSet.lengthOfSet() == numBoundingSet); | 370 assert(_boundingSet.lengthOfSet() == numBoundingSet); |
363 return numBoundingSet; | 371 return numBoundingSet; |
364 } | 372 } |
365 | 373 |
366 bool getNewCandidate = true; | 374 bool getNewCandidate = true; |
367 int curCandidateTMMBR = 0; | 375 uint32_t curCandidateTMMBR = 0; |
368 int curCandidateIndex = 0; | 376 size_t curCandidateIndex = 0; |
369 int curCandidatePacketOH = 0; | 377 uint32_t curCandidatePacketOH = 0; |
370 int curCandidateSSRC = 0; | 378 uint32_t curCandidateSSRC = 0; |
371 do | 379 do |
372 { | 380 { |
373 if (getNewCandidate) | 381 if (getNewCandidate) |
374 { | 382 { |
375 // 5. Remove first remaining tuple from candidate list | 383 // 5. Remove first remaining tuple from candidate list |
376 for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) | 384 for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) |
377 { | 385 { |
378 if (candidateSet.Tmmbr(i) > 0) | 386 if (candidateSet.Tmmbr(i) > 0) |
379 { | 387 { |
380 curCandidateTMMBR = candidateSet.Tmmbr(i); | 388 curCandidateTMMBR = candidateSet.Tmmbr(i); |
381 curCandidatePacketOH = candidateSet.PacketOH(i); | 389 curCandidatePacketOH = candidateSet.PacketOH(i); |
382 curCandidateSSRC = candidateSet.Ssrc(i); | 390 curCandidateSSRC = candidateSet.Ssrc(i); |
383 curCandidateIndex = i; | 391 curCandidateIndex = i; |
384 candidateSet.ClearEntry(curCandidateIndex); | 392 candidateSet.ClearEntry(curCandidateIndex); |
385 break; | 393 break; |
386 } | 394 } |
387 } | 395 } |
388 } | 396 } |
389 | 397 |
390 // 6. Calculate packet rate and intersection of the current | 398 // 6. Calculate packet rate and intersection of the current |
391 // line with line of last tuple in selected list | 399 // line with line of last tuple in selected list |
| 400 RTC_DCHECK_NE(curCandidatePacketOH, |
| 401 _boundingSet.PacketOH(numBoundingSet - 1)); |
392 float packetRate | 402 float packetRate |
393 = float(curCandidateTMMBR | 403 = float(curCandidateTMMBR |
394 - _boundingSet.Tmmbr(numBoundingSet-1))*1000 | 404 - _boundingSet.Tmmbr(numBoundingSet-1))*1000 |
395 / (8*(curCandidatePacketOH | 405 / (8*(curCandidatePacketOH |
396 - _boundingSet.PacketOH(numBoundingSet-1))); | 406 - _boundingSet.PacketOH(numBoundingSet-1))); |
397 | 407 |
398 // 7. If the packet rate is equal or lower than intersection of | 408 // 7. If the packet rate is equal or lower than intersection of |
399 // last tuple in selected list, | 409 // last tuple in selected list, |
400 // remove last tuple in selected list & go back to step 6 | 410 // remove last tuple in selected list & go back to step 6 |
401 if(packetRate <= _ptrIntersectionBoundingSet[numBoundingSet-1]) | 411 if(packetRate <= _ptrIntersectionBoundingSet[numBoundingSet-1]) |
402 { | 412 { |
403 // remove last tuple and goto step 6 | 413 // remove last tuple and goto step 6 |
404 numBoundingSet--; | 414 numBoundingSet--; |
405 _boundingSet.ClearEntry(numBoundingSet); | 415 _boundingSet.ClearEntry(numBoundingSet); |
406 _ptrIntersectionBoundingSet[numBoundingSet] = 0; | 416 _ptrIntersectionBoundingSet[numBoundingSet] = 0; |
407 _ptrMaxPRBoundingSet[numBoundingSet] = 0; | 417 _ptrMaxPRBoundingSet[numBoundingSet] = 0; |
408 getNewCandidate = false; | 418 getNewCandidate = false; |
409 } else | 419 } else |
410 { | 420 { |
411 // 8. If packet rate is lower than maximum packet rate of | 421 // 8. If packet rate is lower than maximum packet rate of |
412 // last tuple in selected list, add current tuple to selected | 422 // last tuple in selected list, add current tuple to selected |
413 // list | 423 // list |
414 if (packetRate < _ptrMaxPRBoundingSet[numBoundingSet-1]) | 424 if (packetRate < _ptrMaxPRBoundingSet[numBoundingSet-1]) |
415 { | 425 { |
416 _boundingSet.SetEntry(numBoundingSet, | 426 _boundingSet.SetEntry(numBoundingSet, |
417 curCandidateTMMBR, | 427 curCandidateTMMBR, |
418 curCandidatePacketOH, | 428 curCandidatePacketOH, |
419 curCandidateSSRC); | 429 curCandidateSSRC); |
420 _ptrIntersectionBoundingSet[numBoundingSet] = packetRate; | 430 _ptrIntersectionBoundingSet[numBoundingSet] = packetRate; |
421 _ptrMaxPRBoundingSet[numBoundingSet] | 431 float packet_overhead_bits = |
422 = _boundingSet.Tmmbr(numBoundingSet)*1000 | 432 8 * _boundingSet.PacketOH(numBoundingSet); |
423 / float(8*_boundingSet.PacketOH(numBoundingSet)); | 433 RTC_DCHECK_NE(packet_overhead_bits, 0.0f); |
| 434 _ptrMaxPRBoundingSet[numBoundingSet] = |
| 435 _boundingSet.Tmmbr(numBoundingSet) * 1000 / |
| 436 packet_overhead_bits; |
424 numBoundingSet++; | 437 numBoundingSet++; |
425 } | 438 } |
426 numCandidates--; | 439 numCandidates--; |
427 getNewCandidate = true; | 440 getNewCandidate = true; |
428 } | 441 } |
429 | 442 |
430 // 9. Go back to step 5 if any tuple remains in candidate list | 443 // 9. Go back to step 5 if any tuple remains in candidate list |
431 } while (numCandidates > 0); | 444 } while (numCandidates > 0); |
432 | 445 |
433 return numBoundingSet; | 446 return numBoundingSet; |
(...skipping 29 matching lines...) Expand all Loading... |
463 uint32_t curNetBitRateKbit = _candidateSet.Tmmbr(i); | 476 uint32_t curNetBitRateKbit = _candidateSet.Tmmbr(i); |
464 if (curNetBitRateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE) { | 477 if (curNetBitRateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE) { |
465 curNetBitRateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE; | 478 curNetBitRateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE; |
466 } | 479 } |
467 *minBitrateKbit = curNetBitRateKbit < *minBitrateKbit ? | 480 *minBitrateKbit = curNetBitRateKbit < *minBitrateKbit ? |
468 curNetBitRateKbit : *minBitrateKbit; | 481 curNetBitRateKbit : *minBitrateKbit; |
469 } | 482 } |
470 return true; | 483 return true; |
471 } | 484 } |
472 } // namespace webrtc | 485 } // namespace webrtc |
OLD | NEW |