blob: 6b2e7488667e0a20106e0265cc5ccf38796cfc34 [file] [log] [blame]
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef MEDIA_BASE_VIDEO_ADAPTER_H_
12#define MEDIA_BASE_VIDEO_ADAPTER_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
Åsa Persson2e4419e2018-09-06 15:02:55 +020016#include <utility>
17
Danil Chapovalov00c71832018-06-15 15:58:38 +020018#include "absl/types/optional.h"
Rasmus Brandt287e4642019-11-15 16:56:01 +010019#include "api/video/video_source_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "media/base/video_common.h"
21#include "rtc_base/constructor_magic.h"
22#include "rtc_base/critical_section.h"
Yves Gerey3e707812018-11-28 16:47:49 +010023#include "rtc_base/thread_annotations.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000024
25namespace cricket {
26
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027// VideoAdapter adapts an input video frame to an output frame based on the
28// specified input and output formats. The adaptation includes dropping frames
Per766ad3b2016-04-05 15:23:49 +020029// to reduce frame rate and scaling frames.
30// VideoAdapter is thread safe.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000031class VideoAdapter {
32 public:
33 VideoAdapter();
sprangc5d62e22017-04-02 23:53:04 -070034 // The output frames will have height and width that is divisible by
35 // |required_resolution_alignment|.
36 explicit VideoAdapter(int required_resolution_alignment);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037 virtual ~VideoAdapter();
38
nisse47ac4622016-05-25 08:47:01 -070039 // Return the adapted resolution and cropping parameters given the
40 // input resolution. The input frame should first be cropped, then
41 // scaled to the final output resolution. Returns true if the frame
42 // should be adapted, and false if it should be dropped.
43 bool AdaptFrameResolution(int in_width,
magjed709f73c2016-05-13 10:26:00 -070044 int in_height,
magjed604abe02016-05-19 06:05:40 -070045 int64_t in_timestamp_ns,
magjed709f73c2016-05-13 10:26:00 -070046 int* cropped_width,
47 int* cropped_height,
48 int* out_width,
49 int* out_height);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050
Åsa Persson2e4419e2018-09-06 15:02:55 +020051 // DEPRECATED. Please use OnOutputFormatRequest below.
52 // TODO(asapersson): Remove this once it is no longer used.
Per766ad3b2016-04-05 15:23:49 +020053 // Requests the output frame size and frame interval from
magjed709f73c2016-05-13 10:26:00 -070054 // |AdaptFrameResolution| to not be larger than |format|. Also, the input
55 // frame size will be cropped to match the requested aspect ratio. The
56 // requested aspect ratio is orientation agnostic and will be adjusted to
57 // maintain the input orientation, so it doesn't matter if e.g. 1280x720 or
58 // 720x1280 is requested.
Åsa Persson2e4419e2018-09-06 15:02:55 +020059 // Note: Should be called from the source only.
Danil Chapovalov00c71832018-06-15 15:58:38 +020060 void OnOutputFormatRequest(const absl::optional<VideoFormat>& format);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +000061
Åsa Persson2e4419e2018-09-06 15:02:55 +020062 // Requests output frame size and frame interval from |AdaptFrameResolution|.
63 // |target_aspect_ratio|: The input frame size will be cropped to match the
64 // requested aspect ratio. The aspect ratio is orientation agnostic and will
65 // be adjusted to maintain the input orientation (i.e. it doesn't matter if
66 // e.g. <1280,720> or <720,1280> is requested).
67 // |max_pixel_count|: The maximum output frame size.
68 // |max_fps|: The maximum output framerate.
69 // Note: Should be called from the source only.
70 void OnOutputFormatRequest(
71 const absl::optional<std::pair<int, int>>& target_aspect_ratio,
72 const absl::optional<int>& max_pixel_count,
73 const absl::optional<int>& max_fps);
74
Magnus Jedvert06aa2092018-10-26 14:00:18 +020075 // Same as above, but allows setting two different target aspect ratios
76 // depending on incoming frame orientation. This gives more fine-grained
77 // control and can e.g. be used to force landscape video to be cropped to
78 // portrait video.
79 void OnOutputFormatRequest(
80 const absl::optional<std::pair<int, int>>& target_landscape_aspect_ratio,
81 const absl::optional<int>& max_landscape_pixel_count,
82 const absl::optional<std::pair<int, int>>& target_portrait_aspect_ratio,
83 const absl::optional<int>& max_portrait_pixel_count,
84 const absl::optional<int>& max_fps);
85
sprang84a37592017-02-10 07:04:27 -080086 // Requests the output frame size from |AdaptFrameResolution| to have as close
Rasmus Brandt287e4642019-11-15 16:56:01 +010087 // as possible to |sink_wants.target_pixel_count| pixels (if set)
88 // but no more than |sink_wants.max_pixel_count|.
89 // |sink_wants.max_framerate_fps| is essentially analogous to
90 // |sink_wants.max_pixel_count|, but for framerate rather than resolution.
91 // Set |sink_wants.max_pixel_count| and/or |sink_wants.max_framerate_fps| to
sprangc5d62e22017-04-02 23:53:04 -070092 // std::numeric_limit<int>::max() if no upper limit is desired.
Åsa Persson2e4419e2018-09-06 15:02:55 +020093 // Note: Should be called from the sink only.
Rasmus Brandt287e4642019-11-15 16:56:01 +010094 void OnSinkWants(const rtc::VideoSinkWants& sink_wants);
buildbot@webrtc.org71dffb72014-06-24 07:24:49 +000095
henrike@webrtc.org28e20752013-07-10 00:45:36 +000096 private:
magjed604abe02016-05-19 06:05:40 -070097 // Determine if frame should be dropped based on input fps and requested fps.
98 bool KeepFrame(int64_t in_timestamp_ns);
99
Per766ad3b2016-04-05 15:23:49 +0200100 int frames_in_; // Number of input frames.
101 int frames_out_; // Number of output frames.
102 int frames_scaled_; // Number of frames scaled.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000103 int adaption_changes_; // Number of changes in scale factor.
Per766ad3b2016-04-05 15:23:49 +0200104 int previous_width_; // Previous adapter output width.
105 int previous_height_; // Previous adapter output height.
Åsa Persson3f7e0ed2019-10-18 15:03:13 +0200106 const bool variable_start_scale_factor_;
kthelgasonc8474172016-12-08 08:04:51 -0800107 // Resolution must be divisible by this factor.
108 const int required_resolution_alignment_;
magjed604abe02016-05-19 06:05:40 -0700109 // The target timestamp for the next frame based on requested format.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200110 absl::optional<int64_t> next_frame_timestamp_ns_
danilchapa37de392017-09-09 04:17:22 -0700111 RTC_GUARDED_BY(critical_section_);
Per766ad3b2016-04-05 15:23:49 +0200112
Åsa Persson2e4419e2018-09-06 15:02:55 +0200113 // Max number of pixels/fps requested via calls to OnOutputFormatRequest,
114 // OnResolutionFramerateRequest respectively.
Per766ad3b2016-04-05 15:23:49 +0200115 // The adapted output format is the minimum of these.
Magnus Jedvert06aa2092018-10-26 14:00:18 +0200116 absl::optional<std::pair<int, int>> target_landscape_aspect_ratio_
danilchapa37de392017-09-09 04:17:22 -0700117 RTC_GUARDED_BY(critical_section_);
Magnus Jedvert06aa2092018-10-26 14:00:18 +0200118 absl::optional<int> max_landscape_pixel_count_
119 RTC_GUARDED_BY(critical_section_);
120 absl::optional<std::pair<int, int>> target_portrait_aspect_ratio_
121 RTC_GUARDED_BY(critical_section_);
122 absl::optional<int> max_portrait_pixel_count_
123 RTC_GUARDED_BY(critical_section_);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200124 absl::optional<int> max_fps_ RTC_GUARDED_BY(critical_section_);
danilchapa37de392017-09-09 04:17:22 -0700125 int resolution_request_target_pixel_count_ RTC_GUARDED_BY(critical_section_);
126 int resolution_request_max_pixel_count_ RTC_GUARDED_BY(critical_section_);
127 int max_framerate_request_ RTC_GUARDED_BY(critical_section_);
Per766ad3b2016-04-05 15:23:49 +0200128
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129 // The critical section to protect the above variables.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000130 rtc::CriticalSection critical_section_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131
henrikg3c089d72015-09-16 05:37:44 -0700132 RTC_DISALLOW_COPY_AND_ASSIGN(VideoAdapter);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000133};
134
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000135} // namespace cricket
136
Steve Anton10542f22019-01-11 09:11:00 -0800137#endif // MEDIA_BASE_VIDEO_ADAPTER_H_