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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_VIDEO_TRACK_ADAPTER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_VIDEO_TRACK_ADAPTER_H_
#include <stdint.h>
#include <optional>
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "media/base/video_frame.h"
#include "third_party/blink/public/platform/modules/mediastream/media_stream_types.h"
#include "third_party/blink/public/web/modules/mediastream/encoded_video_frame.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/webrtc_overrides/low_precision_timer.h"
namespace blink {
class VideoTrackAdapterSettings;
// VideoTrackAdapter is a helper class used by MediaStreamVideoSource used for
// adapting the video resolution from a source implementation to the resolution
// a track requires. Different tracks can have different resolution constraints.
// The constraints can be set as max width and height as well as max and min
// aspect ratio.
// Video frames are delivered to a track using a VideoCaptureDeliverFrameCB on
// the video task runner.
// Adaptations is done by wrapping the original media::VideoFrame in a new
// media::VideoFrame with a new visible_rect and natural_size.
class MODULES_EXPORT VideoTrackAdapter
: public WTF::ThreadSafeRefCounted<VideoTrackAdapter> {
public:
using OnMutedCallback = base::RepeatingCallback<void(bool mute_state)>;
VideoTrackAdapter(
scoped_refptr<base::SequencedTaskRunner> video_task_runner,
base::WeakPtr<MediaStreamVideoSource> media_stream_video_source);
VideoTrackAdapter(const VideoTrackAdapter&) = delete;
VideoTrackAdapter& operator=(const VideoTrackAdapter&) = delete;
// Register |track| to receive video frames in and |encoded_frame_callback|
// and in |frame_callback| with a resolution within the boundaries of the
// arguments, and settings updates in |settings_callback|. Must be called on
// the main render thread. |source_frame_rate| is used to calculate a prudent
// interval to check for passing frames and inform of the result via
// |on_muted_state_callback|.
void AddTrack(const MediaStreamVideoTrack* track,
MediaStreamVideoSourceCallbacks video_stream_fallbacks,
const VideoTrackAdapterSettings& settings);
void RemoveTrack(const MediaStreamVideoTrack* track);
void ReconfigureTrack(const MediaStreamVideoTrack* track,
const VideoTrackAdapterSettings& settings);
// Delivers |frame| to all tracks that have registered a callback.
// Must be called on the video task runner.
void DeliverFrameOnVideoTaskRunner(
scoped_refptr<media::VideoFrame> video_frame,
base::TimeTicks estimated_capture_time);
// Delivers |encoded_frame| to all tracks that have registered a callback.
// Must be called on the video task runner.
void DeliverEncodedVideoFrameOnVideoTaskRunner(
scoped_refptr<EncodedVideoFrame> frame,
base::TimeTicks estimated_capture_time);
// Called if a frame was dropped prior to delivery, i.e.
// DeliverFrameOnVideoTaskRunner() will not be called for this frame.
void OnFrameDroppedOnVideoTaskRunner(
media::VideoCaptureFrameDropReason reason);
// Called when it is guaranteed that all subsequent frames delivered
// over DeliverFrameOnVideoTaskRunner() will have a sub-capture-target version
// that is equal-to-or-greater-than the given sub-capture-target version.
void NewSubCaptureTargetVersionOnVideoTaskRunner(
uint32_t sub_capture_target_version);
base::SequencedTaskRunner* video_task_runner() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return video_task_runner_.get();
}
// Start monitor that frames are delivered to this object. I.E, that
// |DeliverFrameOnVideoTaskRunner| is called with a frame rate of
// |source_frame_rate|. |on_muted_callback| is triggered on the main render
// thread.
void StartFrameMonitoring(double source_frame_rate,
const OnMutedCallback& on_muted_callback);
void StopFrameMonitoring();
void SetSourceFrameSize(const gfx::Size& source_frame_size);
// Exported for testing.
//
// Calculates the desired size of a VideoTrack instance, and returns true if
// |desired_size| is updated successfully, false otherwise.
// |desired_size| is not updated if |settings| has rescaling disabled and
// |input_size| is invalid.
static bool CalculateDesiredSize(bool is_rotated,
const gfx::Size& input_size,
const VideoTrackAdapterSettings& settings,
gfx::Size* desired_size);
std::optional<gfx::Size> source_frame_size() const {
return source_frame_size_;
}
private:
virtual ~VideoTrackAdapter();
friend class WTF::ThreadSafeRefCounted<VideoTrackAdapter>;
// These aliases mimic the definition of VideoCaptureDeliverFrameCB,
// VideoTrackSettingsCallback and VideoTrackFormatCallback respectively.
using VideoCaptureDeliverFrameInternalCallback =
WTF::CrossThreadFunction<void(
scoped_refptr<media::VideoFrame> video_frame,
base::TimeTicks estimated_capture_time)>;
using VideoCaptureNotifyFrameDroppedInternalCallback =
WTF::CrossThreadFunction<void(media::VideoCaptureFrameDropReason)>;
using DeliverEncodedVideoFrameInternalCallback =
WTF::CrossThreadFunction<void(
scoped_refptr<EncodedVideoFrame> video_frame,
base::TimeTicks estimated_capture_time)>;
using VideoCaptureSubCaptureTargetVersionInternalCallback =
WTF::CrossThreadFunction<void(uint32_t)>;
using VideoTrackSettingsInternalCallback = WTF::CrossThreadFunction<void(
gfx::Size frame_size,
double frame_rate,
std::optional<gfx::Size> metadata_source_size,
std::optional<float> device_scale_factor)>;
using VideoTrackFormatInternalCallback =
WTF::CrossThreadFunction<void(const media::VideoCaptureFormat&)>;
void AddTrackOnVideoTaskRunner(
const MediaStreamVideoTrack* track,
VideoCaptureDeliverFrameInternalCallback frame_callback,
VideoCaptureNotifyFrameDroppedInternalCallback
notify_frame_dropped_callback,
DeliverEncodedVideoFrameInternalCallback encoded_frame_callback,
VideoCaptureSubCaptureTargetVersionInternalCallback
sub_capture_target_version_callback,
VideoTrackSettingsInternalCallback settings_callback,
VideoTrackFormatInternalCallback format_callback,
const VideoTrackAdapterSettings& settings);
void RemoveTrackOnVideoTaskRunner(const MediaStreamVideoTrack* track);
void ReconfigureTrackOnVideoTaskRunner(
const MediaStreamVideoTrack* track,
const VideoTrackAdapterSettings& settings);
using OnMutedInternalCallback =
WTF::CrossThreadFunction<void(bool mute_state)>;
void StartFrameMonitoringOnVideoTaskRunner(
OnMutedInternalCallback on_muted_state_callback,
double source_frame_rate);
void StopFrameMonitoringOnVideoTaskRunner();
void SetSourceFrameSizeOnVideoTaskRunner(const gfx::Size& frame_size);
// Compare |old_frame_counter_snapshot_| with the current |frame_counter_|,
// and inform of the situation (muted, not muted) via |on_muted_callback_|.
void CheckFramesReceivedOnVideoTaskRunner();
// |thread_checker_| is bound to the main render thread.
SEQUENCE_CHECKER(sequence_checker_);
const scoped_refptr<base::SequencedTaskRunner> video_task_runner_;
base::WeakPtr<MediaStreamVideoSource> media_stream_video_source_;
// |renderer_task_runner_| is used to ensure that
// VideoCaptureDeliverFrameCB is released on the main render thread.
const scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_;
// VideoFrameResolutionAdapter is an inner class that lives on the video task
// runner. It does the resolution adaptation and delivers frames to all
// registered tracks.
class VideoFrameResolutionAdapter;
using FrameAdapters = WTF::Vector<scoped_refptr<VideoFrameResolutionAdapter>>;
FrameAdapters adapters_;
// Is non-null while frame monitoring. It is only accessed on the video task
// runner.
std::unique_ptr<LowPrecisionTimer> monitoring_frame_rate_timer_;
OnMutedInternalCallback on_muted_callback_;
// Keeps track of it frames have been received. It is only accessed on the
// video task runner.
bool muted_state_;
// Running frame counter, accessed on the video task runner.
uint64_t frame_counter_;
uint64_t old_frame_counter_snapshot_;
// Frame rate configured on the video source, accessed on the video task
// runner.
float source_frame_rate_;
// Resolution configured on the video source, accessed on the video task
// runner.
std::optional<gfx::Size> source_frame_size_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_VIDEO_TRACK_ADAPTER_H_
|