summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/libwebrtcglue/VideoStreamFactory.h
blob: 832d1e93990ec023392a254a28021a7252447e82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef VideoStreamFactory_h
#define VideoStreamFactory_h

#include "CodecConfig.h"
#include "mozilla/Atomics.h"
#include "mozilla/DataMutex.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/UniquePtr.h"
#include "api/video/video_source_interface.h"
#include "common_video/framerate_controller.h"
#include "rtc_base/time_utils.h"
#include "video/config/video_encoder_config.h"

namespace webrtc {
class VideoFrame;
}

namespace mozilla {

// Factory class for VideoStreams... vie_encoder.cc will call this to
// reconfigure.
class VideoStreamFactory
    : public webrtc::VideoEncoderConfig::VideoStreamFactoryInterface {
 public:
  struct ResolutionAndBitrateLimits {
    int resolution_in_mb;
    int min_bitrate_bps;
    int start_bitrate_bps;
    int max_bitrate_bps;
  };

  static ResolutionAndBitrateLimits GetLimitsFor(unsigned int aWidth,
                                                 unsigned int aHeight,
                                                 int aCapBps = 0);

  VideoStreamFactory(VideoCodecConfig aConfig,
                     webrtc::VideoCodecMode aCodecMode, int aMinBitrate,
                     int aStartBitrate, int aPrefMaxBitrate,
                     int aNegotiatedMaxBitrate,
                     const rtc::VideoSinkWants& aWants, bool aLockScaling)
      : mCodecMode(aCodecMode),
        mMaxFramerateForAllStreams(std::numeric_limits<unsigned int>::max()),
        mCodecConfig(std::forward<VideoCodecConfig>(aConfig)),
        mMinBitrate(aMinBitrate),
        mStartBitrate(aStartBitrate),
        mPrefMaxBitrate(aPrefMaxBitrate),
        mNegotiatedMaxBitrate(aNegotiatedMaxBitrate),
        mFramerateController("VideoStreamFactory::mFramerateController"),
        mWants(aWants),
        mLockScaling(aLockScaling) {}

  // This gets called off-main thread and may hold internal webrtc.org
  // locks. May *NOT* lock the conduit's mutex, to avoid deadlocks.
  std::vector<webrtc::VideoStream> CreateEncoderStreams(
      int aWidth, int aHeight,
      const webrtc::VideoEncoderConfig& aConfig) override;
  /**
   * Function to select and change the encoding resolution based on incoming
   * frame size and current available bandwidth.
   * @param width, height: dimensions of the frame
   */
  void SelectMaxFramerateForAllStreams(unsigned short aWidth,
                                       unsigned short aHeight);

  /**
   * Function to determine if the frame should be dropped based on the given
   * frame's resolution (combined with the factory's scaleResolutionDownBy) or
   * timestamp.
   * @param aFrame frame to be evaluated.
   * @return true if frame should be dropped, false otehrwise.
   */
  bool ShouldDropFrame(const webrtc::VideoFrame& aFrame);

 private:
  /**
   * Function to calculate a scaled down width and height based on
   * scaleDownByResolution, maxFS, and max pixel count settings.
   * @param aWidth current frame width
   * @param aHeight current frame height
   * @param aScaleDownByResolution value to scale width and height down by.
   * @param aMaxPixelCount maximum number of pixels wanted in a frame.
   * @return a gfx:IntSize containing  width and height to use. These may match
   * the aWidth and aHeight passed in if no scaling was needed.
   */
  gfx::IntSize CalculateScaledResolution(int aWidth, int aHeight,
                                         double aScaleDownByResolution,
                                         unsigned int aMaxPixelCount);

  /**
   * Function to select and change the encoding frame rate based on incoming
   * frame rate, current frame size and max-mbps setting.
   * @param aOldFramerate current framerate
   * @param aSendingWidth width of frames being sent
   * @param aSendingHeight height of frames being sent
   * @return new framerate meeting max-mbps requriements based on frame size
   */
  unsigned int SelectFrameRate(unsigned int aOldFramerate,
                               unsigned short aSendingWidth,
                               unsigned short aSendingHeight);

  // Used to limit number of streams for screensharing.
  Atomic<webrtc::VideoCodecMode> mCodecMode;

  // The framerate we're currently sending at.
  Atomic<unsigned int> mMaxFramerateForAllStreams;

  // The current send codec config, containing simulcast layer configs.
  const VideoCodecConfig mCodecConfig;

  // Bitrate limits in bps.
  const int mMinBitrate = 0;
  const int mStartBitrate = 0;
  const int mPrefMaxBitrate = 0;
  const int mNegotiatedMaxBitrate = 0;

  // DatamMutex used as object is mutated from a libwebrtc thread and
  // a seperate thread used to pass video frames to libwebrtc.
  DataMutex<webrtc::FramerateController> mFramerateController;

  const rtc::VideoSinkWants mWants;
  const bool mLockScaling;
};

}  // namespace mozilla

#endif