tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rtp_frame_reference_finder.cc (6615B)


      1 /*
      2 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
      3 *
      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
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "modules/video_coding/rtp_frame_reference_finder.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <utility>
     17 #include <variant>
     18 
     19 #include "api/video/video_codec_type.h"
     20 #include "modules/rtp_rtcp/source/frame_object.h"
     21 #include "modules/rtp_rtcp/source/rtp_video_header.h"
     22 #include "modules/video_coding/codecs/interface/common_constants.h"
     23 #include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
     24 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
     25 #include "modules/video_coding/rtp_frame_id_only_ref_finder.h"
     26 #include "modules/video_coding/rtp_generic_ref_finder.h"
     27 #include "modules/video_coding/rtp_seq_num_only_ref_finder.h"
     28 #include "modules/video_coding/rtp_vp8_ref_finder.h"
     29 #include "modules/video_coding/rtp_vp9_ref_finder.h"
     30 #include "rtc_base/numerics/sequence_number_util.h"
     31 
     32 namespace webrtc {
     33 namespace internal {
     34 class RtpFrameReferenceFinderImpl {
     35 public:
     36  RtpFrameReferenceFinderImpl() = default;
     37 
     38  RtpFrameReferenceFinder::ReturnVector ManageFrame(
     39      std::unique_ptr<RtpFrameObject> frame);
     40  RtpFrameReferenceFinder::ReturnVector PaddingReceived(uint16_t seq_num);
     41  void ClearTo(uint16_t seq_num);
     42 
     43 private:
     44  using RefFinder = std::variant<std::monostate,
     45                                 RtpGenericFrameRefFinder,
     46                                 RtpFrameIdOnlyRefFinder,
     47                                 RtpSeqNumOnlyRefFinder,
     48                                 RtpVp8RefFinder,
     49                                 RtpVp9RefFinder>;
     50 
     51  template <typename T>
     52  T& GetRefFinderAs();
     53  RefFinder ref_finder_;
     54 };
     55 
     56 RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinderImpl::ManageFrame(
     57    std::unique_ptr<RtpFrameObject> frame) {
     58  const RTPVideoHeader& video_header = frame->GetRtpVideoHeader();
     59 
     60  if (video_header.generic.has_value()) {
     61    return GetRefFinderAs<RtpGenericFrameRefFinder>().ManageFrame(
     62        std::move(frame), *video_header.generic);
     63  }
     64 
     65  switch (frame->codec_type()) {
     66    case kVideoCodecVP8: {
     67      const RTPVideoHeaderVP8& vp8_header =
     68          std::get<RTPVideoHeaderVP8>(video_header.video_type_header);
     69 
     70      if (vp8_header.temporalIdx == kNoTemporalIdx ||
     71          vp8_header.tl0PicIdx == kNoTl0PicIdx) {
     72        if (vp8_header.pictureId == kNoPictureId) {
     73          return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
     74              std::move(frame));
     75        }
     76 
     77        return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
     78            std::move(frame), vp8_header.pictureId);
     79      }
     80 
     81      return GetRefFinderAs<RtpVp8RefFinder>().ManageFrame(std::move(frame));
     82    }
     83    case kVideoCodecVP9: {
     84      const RTPVideoHeaderVP9& vp9_header =
     85          std::get<RTPVideoHeaderVP9>(video_header.video_type_header);
     86 
     87      if (vp9_header.temporal_idx == kNoTemporalIdx) {
     88        if (vp9_header.picture_id == kNoPictureId) {
     89          return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
     90              std::move(frame));
     91        }
     92 
     93        return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
     94            std::move(frame), vp9_header.picture_id);
     95      }
     96 
     97      return GetRefFinderAs<RtpVp9RefFinder>().ManageFrame(std::move(frame));
     98    }
     99    case kVideoCodecGeneric: {
    100      if (auto* generic_header = std::get_if<RTPVideoHeaderLegacyGeneric>(
    101              &video_header.video_type_header)) {
    102        return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
    103            std::move(frame), generic_header->picture_id);
    104      }
    105 
    106      return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
    107          std::move(frame));
    108    }
    109    default: {
    110      return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
    111          std::move(frame));
    112    }
    113  }
    114 }
    115 
    116 RtpFrameReferenceFinder::ReturnVector
    117 RtpFrameReferenceFinderImpl::PaddingReceived(uint16_t seq_num) {
    118  if (auto* ref_finder = std::get_if<RtpSeqNumOnlyRefFinder>(&ref_finder_)) {
    119    return ref_finder->PaddingReceived(seq_num);
    120  }
    121  return {};
    122 }
    123 
    124 void RtpFrameReferenceFinderImpl::ClearTo(uint16_t seq_num) {
    125  struct ClearToVisitor {
    126    void operator()(std::monostate& /* ref_finder */) {}
    127    void operator()(RtpGenericFrameRefFinder& /* ref_finder */) {}
    128    void operator()(RtpFrameIdOnlyRefFinder& /* ref_finder */) {}
    129    void operator()(RtpSeqNumOnlyRefFinder& ref_finder) {
    130      ref_finder.ClearTo(seq_num);
    131    }
    132    void operator()(RtpVp8RefFinder& ref_finder) {
    133      ref_finder.ClearTo(seq_num);
    134    }
    135    void operator()(RtpVp9RefFinder& ref_finder) {
    136      ref_finder.ClearTo(seq_num);
    137    }
    138    uint16_t seq_num;
    139  };
    140 
    141  std::visit(ClearToVisitor{seq_num}, ref_finder_);
    142 }
    143 
    144 template <typename T>
    145 T& RtpFrameReferenceFinderImpl::GetRefFinderAs() {
    146  if (auto* ref_finder = std::get_if<T>(&ref_finder_)) {
    147    return *ref_finder;
    148  }
    149  return ref_finder_.emplace<T>();
    150 }
    151 
    152 }  // namespace internal
    153 
    154 RtpFrameReferenceFinder::RtpFrameReferenceFinder()
    155    : RtpFrameReferenceFinder(0) {}
    156 
    157 RtpFrameReferenceFinder::RtpFrameReferenceFinder(int64_t picture_id_offset)
    158    : picture_id_offset_(picture_id_offset),
    159      impl_(std::make_unique<internal::RtpFrameReferenceFinderImpl>()) {}
    160 
    161 RtpFrameReferenceFinder::~RtpFrameReferenceFinder() = default;
    162 
    163 RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinder::ManageFrame(
    164    std::unique_ptr<RtpFrameObject> frame) {
    165  // If we have cleared past this frame, drop it.
    166  if (cleared_to_seq_num_ != -1 &&
    167      AheadOf<uint16_t>(cleared_to_seq_num_, frame->first_seq_num())) {
    168    return {};
    169  }
    170 
    171  auto frames = impl_->ManageFrame(std::move(frame));
    172  AddPictureIdOffset(frames);
    173  return frames;
    174 }
    175 
    176 RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinder::PaddingReceived(
    177    uint16_t seq_num) {
    178  auto frames = impl_->PaddingReceived(seq_num);
    179  AddPictureIdOffset(frames);
    180  return frames;
    181 }
    182 
    183 void RtpFrameReferenceFinder::ClearTo(uint16_t seq_num) {
    184  cleared_to_seq_num_ = seq_num;
    185  impl_->ClearTo(seq_num);
    186 }
    187 
    188 void RtpFrameReferenceFinder::AddPictureIdOffset(ReturnVector& frames) {
    189  for (auto& frame : frames) {
    190    frame->SetId(frame->Id() + picture_id_offset_);
    191    for (size_t i = 0; i < frame->num_references; ++i) {
    192      frame->references[i] += picture_id_offset_;
    193    }
    194  }
    195 }
    196 
    197 }  // namespace webrtc