OLD | NEW |
1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
2 * | 2 * |
3 * Use of this source code is governed by a BSD-style license | 3 * Use of this source code is governed by a BSD-style license |
4 * that can be found in the LICENSE file in the root of the source | 4 * that can be found in the LICENSE file in the root of the source |
5 * tree. An additional intellectual property rights grant can be found | 5 * tree. An additional intellectual property rights grant can be found |
6 * in the file PATENTS. All contributing project authors may | 6 * in the file PATENTS. All contributing project authors may |
7 * be found in the AUTHORS file in the root of the source tree. | 7 * be found in the AUTHORS file in the root of the source tree. |
8 */ | 8 */ |
9 | 9 |
10 #include "modules/video_coding/codecs/vp8/default_temporal_layers.h" | 10 #include "modules/video_coding/codecs/vp8/default_temporal_layers.h" |
11 | 11 |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <string.h> | 13 #include <string.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 #include "modules/include/module_common_types.h" | 18 #include "modules/include/module_common_types.h" |
19 #include "modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 19 #include "modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
20 #include "modules/video_coding/include/video_codec_interface.h" | 20 #include "modules/video_coding/include/video_codec_interface.h" |
21 #include "rtc_base/checks.h" | 21 #include "rtc_base/checks.h" |
| 22 #include "rtc_base/logging.h" |
22 #include "system_wrappers/include/field_trial.h" | 23 #include "system_wrappers/include/field_trial.h" |
23 | 24 |
| 25 #include "vpx/vp8cx.h" |
24 #include "vpx/vpx_encoder.h" | 26 #include "vpx/vpx_encoder.h" |
25 #include "vpx/vp8cx.h" | |
26 | 27 |
27 namespace webrtc { | 28 namespace webrtc { |
28 | 29 |
29 TemporalLayers::FrameConfig::FrameConfig() | 30 TemporalLayers::FrameConfig::FrameConfig() |
30 : FrameConfig(kNone, kNone, kNone, false) {} | 31 : FrameConfig(kNone, kNone, kNone, false) {} |
31 | 32 |
32 TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last, | 33 TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last, |
33 TemporalLayers::BufferFlags golden, | 34 TemporalLayers::BufferFlags golden, |
34 TemporalLayers::BufferFlags arf) | 35 TemporalLayers::BufferFlags arf) |
35 : FrameConfig(last, golden, arf, false) {} | 36 : FrameConfig(last, golden, arf, false) {} |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx); | 422 new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx); |
422 if (listener_ && !ExcludeOnTemporalLayersCreated(temporal_layers)) | 423 if (listener_ && !ExcludeOnTemporalLayersCreated(temporal_layers)) |
423 listener_->OnTemporalLayersCreated(simulcast_id, tl); | 424 listener_->OnTemporalLayersCreated(simulcast_id, tl); |
424 return tl; | 425 return tl; |
425 } | 426 } |
426 | 427 |
427 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) { | 428 void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) { |
428 listener_ = listener; | 429 listener_ = listener; |
429 } | 430 } |
430 | 431 |
| 432 std::vector<std::vector<uint8_t>> GetTemporalDependencies( |
| 433 int num_temporal_layers) { |
| 434 switch (num_temporal_layers) { |
| 435 case 1: |
| 436 return {}; |
| 437 case 2: |
| 438 return {}; |
| 439 case 3: |
| 440 if (field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) { |
| 441 return {}; |
| 442 } else { |
| 443 return {}; |
| 444 } |
| 445 case 4: |
| 446 return {}; |
| 447 default: |
| 448 RTC_NOTREACHED(); |
| 449 break; |
| 450 } |
| 451 RTC_NOTREACHED(); |
| 452 return {}; |
| 453 } |
| 454 |
| 455 DefaultTemporalLayersChecker::DefaultTemporalLayersChecker( |
| 456 int num_temporal_layers, |
| 457 uint8_t initial_tl0_pic_idx) |
| 458 : num_layers_(std::max(1, num_temporal_layers)), |
| 459 temporal_ids_(GetTemporalIds(num_layers_)), |
| 460 temporal_dependencies_(GetTemporalDependencies(num_layers_)), |
| 461 tl0_pic_idx_(initial_tl0_pic_idx), |
| 462 pattern_idx_(255) {} |
| 463 |
| 464 bool DefaultTemporalLayersChecker::CheckOnFrameEncoded( |
| 465 bool frame_is_keyframe, |
| 466 const CodecSpecificInfoVP8& codec_specific, |
| 467 TemporalLayers::FrameConfig& frame_config) { |
| 468 ++pattern_idx_; |
| 469 if (pattern_idx_ == temporal_ids_.size()) { |
| 470 // All no key-frame buffers soud be updated each pattern cycle. |
| 471 if (!last_.is_keyframe && !last_.is_updated_this_cycle) { |
| 472 LOG(LS_ERROR) << "Last buffer was not updated during pattern cycle."; |
| 473 return false; |
| 474 } |
| 475 if (!arf_.is_keyframe && !arf_.is_updated_this_cycle) { |
| 476 LOG(LS_ERROR) << "Arf buffer was not updated during pattern cycle."; |
| 477 return false; |
| 478 } |
| 479 if (!golden_.is_keyframe && !golden_.is_updated_this_cycle) { |
| 480 LOG(LS_ERROR) << "Golden buffer was not updated during pattern cycle."; |
| 481 return false; |
| 482 } |
| 483 last_.is_updated_this_cycle = false; |
| 484 arf_.is_updated_this_cycle = false; |
| 485 golden_.is_updated_this_cycle = false; |
| 486 } |
| 487 |
| 488 if (codec_specific.temporalIdx != temporal_ids_[pattern_idx_]) { |
| 489 LOG(LS_ERROR) << "Frame has an incorrect temporal index."; |
| 490 return false; |
| 491 } |
| 492 |
| 493 bool need_sync = true; |
| 494 std::vector<int> dependencies; |
| 495 |
| 496 if (frame_config.last_buffer_flags & |
| 497 TemporalLayers::BufferFlags::kReference) { |
| 498 uint8_t referenced_idx = temporal_ids_[last_.pattern_idx]; |
| 499 if (!last_.is_keyframe && referenced_idx > 0) { |
| 500 need_sync = false; |
| 501 } |
| 502 if (!last_.is_keyframe) { |
| 503 dependencies.push_back(referenced_idx); |
| 504 } |
| 505 } |
| 506 |
| 507 if (frame_config.arf_buffer_flags & TemporalLayers::BufferFlags::kReference) { |
| 508 uint8_t referenced_idx = temporal_ids_[arf_.pattern_idx]; |
| 509 if (!arf_.is_keyframe && referenced_idx > 0) { |
| 510 need_sync = false; |
| 511 } |
| 512 if (!arf_.is_keyframe) { |
| 513 dependencies.push_back(referenced_idx); |
| 514 } |
| 515 } |
| 516 |
| 517 if (frame_config.golden_buffer_flags & |
| 518 TemporalLayers::BufferFlags::kReference) { |
| 519 uint8_t referenced_idx = temporal_ids_[golden_.pattern_idx]; |
| 520 if (!golden_.is_keyframe && referenced_idx > 0) { |
| 521 need_sync = false; |
| 522 } |
| 523 if (!golden_.is_keyframe) { |
| 524 dependencies.push_back(referenced_idx); |
| 525 } |
| 526 } |
| 527 |
| 528 if (need_sync != codec_specific.layerSync) { |
| 529 LOG(LS_ERROR) << "Sync bit is set incorrectly on a frame."; |
| 530 return false; |
| 531 } |
| 532 |
| 533 std::sort(dependencies.begin(), dependencies.end()); |
| 534 size_t i, j; |
| 535 j = 0; |
| 536 for (i = 0; i < dependencies.size(); ++i) { |
| 537 while (j < temporal_dependencies_[pattern_idx_].size() && |
| 538 temporal_dependencies_[pattern_idx_][j] < dependencies[i]) { |
| 539 ++j; |
| 540 } |
| 541 if (j == temporal_dependencies_[pattern_idx_].size() || |
| 542 temporal_dependencies_[pattern_idx_][j] != dependencies[i]) { |
| 543 } |
| 544 } |
| 545 |
| 546 if (frame_config.last_buffer_flags & TemporalLayers::BufferFlags::kUpdate) { |
| 547 last_.is_updated_this_cycle = true; |
| 548 last_.pattern_idx = pattern_idx_; |
| 549 last_.is_keyframe = false; |
| 550 } |
| 551 if (frame_config.arf_buffer_flags & TemporalLayers::BufferFlags::kUpdate) { |
| 552 arf_.is_updated_this_cycle = true; |
| 553 arf_.pattern_idx = pattern_idx_; |
| 554 arf_.is_keyframe = false; |
| 555 } |
| 556 if (frame_config.golden_buffer_flags & TemporalLayers::BufferFlags::kUpdate) { |
| 557 golden_.is_updated_this_cycle = true; |
| 558 golden_.pattern_idx = pattern_idx_; |
| 559 golden_.is_keyframe = false; |
| 560 } |
| 561 if (frame_is_keyframe) { |
| 562 last_.is_keyframe = true; |
| 563 arf_.is_keyframe = true; |
| 564 golden_.is_keyframe = true; |
| 565 } |
| 566 tl0_pic_idx_ = codec_specific.tl0PicIdx; |
| 567 return true; |
| 568 } |
| 569 |
431 } // namespace webrtc | 570 } // namespace webrtc |
OLD | NEW |