blob: bbe08862dc381966ef70a18e05f3de88389d6600 [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"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "media/base/video_common.h"
20#include "rtc_base/constructor_magic.h"
21#include "rtc_base/critical_section.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "rtc_base/thread_annotations.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000023
24namespace cricket {
25
henrike@webrtc.org28e20752013-07-10 00:45:36 +000026// VideoAdapter adapts an input video frame to an output frame based on the
27// specified input and output formats. The adaptation includes dropping frames
Per766ad3b2016-04-05 15:23:49 +020028// to reduce frame rate and scaling frames.
29// VideoAdapter is thread safe.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030class VideoAdapter {
31 public:
32 VideoAdapter();
sprangc5d62e22017-04-02 23:53:04 -070033 // The output frames will have height and width that is divisible by
34 // |required_resolution_alignment|.
35 explicit VideoAdapter(int required_resolution_alignment);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036 virtual ~VideoAdapter();
37
nisse47ac4622016-05-25 08:47:01 -070038 // Return the adapted resolution and cropping parameters given the
39 // input resolution. The input frame should first be cropped, then
40 // scaled to the final output resolution. Returns true if the frame
41 // should be adapted, and false if it should be dropped.
42 bool AdaptFrameResolution(int in_width,
magjed709f73c2016-05-13 10:26:00 -070043 int in_height,
magjed604abe02016-05-19 06:05:40 -070044 int64_t in_timestamp_ns,
magjed709f73c2016-05-13 10:26:00 -070045 int* cropped_width,
46 int* cropped_height,
47 int* out_width,
48 int* out_height);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049
Åsa Persson2e4419e2018-09-06 15:02:55 +020050 // DEPRECATED. Please use OnOutputFormatRequest below.
51 // TODO(asapersson): Remove this once it is no longer used.
Per766ad3b2016-04-05 15:23:49 +020052 // Requests the output frame size and frame interval from
magjed709f73c2016-05-13 10:26:00 -070053 // |AdaptFrameResolution| to not be larger than |format|. Also, the input
54 // frame size will be cropped to match the requested aspect ratio. The
55 // requested aspect ratio is orientation agnostic and will be adjusted to
56 // maintain the input orientation, so it doesn't matter if e.g. 1280x720 or
57 // 720x1280 is requested.
Åsa Persson2e4419e2018-09-06 15:02:55 +020058 // Note: Should be called from the source only.
Danil Chapovalov00c71832018-06-15 15:58:38 +020059 void OnOutputFormatRequest(const absl::optional<VideoFormat>& format);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +000060
Åsa Persson2e4419e2018-09-06 15:02:55 +020061 // Requests output frame size and frame interval from |AdaptFrameResolution|.
62 // |target_aspect_ratio|: The input frame size will be cropped to match the
63 // requested aspect ratio. The aspect ratio is orientation agnostic and will
64 // be adjusted to maintain the input orientation (i.e. it doesn't matter if
65 // e.g. <1280,720> or <720,1280> is requested).
66 // |max_pixel_count|: The maximum output frame size.
67 // |max_fps|: The maximum output framerate.
68 // Note: Should be called from the source only.
69 void OnOutputFormatRequest(
70 const absl::optional<std::pair<int, int>>& target_aspect_ratio,
71 const absl::optional<int>& max_pixel_count,
72 const absl::optional<int>& max_fps);
73
Magnus Jedvert06aa2092018-10-26 14:00:18 +020074 // Same as above, but allows setting two different target aspect ratios
75 // depending on incoming frame orientation. This gives more fine-grained
76 // control and can e.g. be used to force landscape video to be cropped to
77 // portrait video.
78 void OnOutputFormatRequest(
79 const absl::optional<std::pair<int, int>>& target_landscape_aspect_ratio,
80 const absl::optional<int>& max_landscape_pixel_count,
81 const absl::optional<std::pair<int, int>>& target_portrait_aspect_ratio,
82 const absl::optional<int>& max_portrait_pixel_count,
83 const absl::optional<int>& max_fps);
84
sprang84a37592017-02-10 07:04:27 -080085 // Requests the output frame size from |AdaptFrameResolution| to have as close
sprangc5d62e22017-04-02 23:53:04 -070086 // as possible to |target_pixel_count| pixels (if set) but no more than
87 // |max_pixel_count|.
88 // |max_framerate_fps| is essentially analogous to |max_pixel_count|, but for
89 // framerate rather than resolution.
90 // Set |max_pixel_count| and/or |max_framerate_fps| to
91 // std::numeric_limit<int>::max() if no upper limit is desired.
Åsa Persson2e4419e2018-09-06 15:02:55 +020092 // Note: Should be called from the sink only.
sprangc5d62e22017-04-02 23:53:04 -070093 void OnResolutionFramerateRequest(
Danil Chapovalov00c71832018-06-15 15:58:38 +020094 const absl::optional<int>& target_pixel_count,
sprangc5d62e22017-04-02 23:53:04 -070095 int max_pixel_count,
96 int max_framerate_fps);
buildbot@webrtc.org71dffb72014-06-24 07:24:49 +000097
henrike@webrtc.org28e20752013-07-10 00:45:36 +000098 private:
magjed604abe02016-05-19 06:05:40 -070099 // Determine if frame should be dropped based on input fps and requested fps.
100 bool KeepFrame(int64_t in_timestamp_ns);
101
Per766ad3b2016-04-05 15:23:49 +0200102 int frames_in_; // Number of input frames.
103 int frames_out_; // Number of output frames.
104 int frames_scaled_; // Number of frames scaled.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000105 int adaption_changes_; // Number of changes in scale factor.
Per766ad3b2016-04-05 15:23:49 +0200106 int previous_width_; // Previous adapter output width.
107 int previous_height_; // Previous adapter output height.
kthelgasonc8474172016-12-08 08:04:51 -0800108 // Resolution must be divisible by this factor.
109 const int required_resolution_alignment_;
magjed604abe02016-05-19 06:05:40 -0700110 // The target timestamp for the next frame based on requested format.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200111 absl::optional<int64_t> next_frame_timestamp_ns_
danilchapa37de392017-09-09 04:17:22 -0700112 RTC_GUARDED_BY(critical_section_);
Per766ad3b2016-04-05 15:23:49 +0200113
Åsa Persson2e4419e2018-09-06 15:02:55 +0200114 // Max number of pixels/fps requested via calls to OnOutputFormatRequest,
115 // OnResolutionFramerateRequest respectively.
Per766ad3b2016-04-05 15:23:49 +0200116 // The adapted output format is the minimum of these.
Magnus Jedvert06aa2092018-10-26 14:00:18 +0200117 absl::optional<std::pair<int, int>> target_landscape_aspect_ratio_
danilchapa37de392017-09-09 04:17:22 -0700118 RTC_GUARDED_BY(critical_section_);
Magnus Jedvert06aa2092018-10-26 14:00:18 +0200119 absl::optional<int> max_landscape_pixel_count_
120 RTC_GUARDED_BY(critical_section_);
121 absl::optional<std::pair<int, int>> target_portrait_aspect_ratio_
122 RTC_GUARDED_BY(critical_section_);
123 absl::optional<int> max_portrait_pixel_count_
124 RTC_GUARDED_BY(critical_section_);
Åsa Persson2e4419e2018-09-06 15:02:55 +0200125 absl::optional<int> max_fps_ RTC_GUARDED_BY(critical_section_);
danilchapa37de392017-09-09 04:17:22 -0700126 int resolution_request_target_pixel_count_ RTC_GUARDED_BY(critical_section_);
127 int resolution_request_max_pixel_count_ RTC_GUARDED_BY(critical_section_);
128 int max_framerate_request_ RTC_GUARDED_BY(critical_section_);
Per766ad3b2016-04-05 15:23:49 +0200129
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000130 // The critical section to protect the above variables.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000131 rtc::CriticalSection critical_section_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000132
henrikg3c089d72015-09-16 05:37:44 -0700133 RTC_DISALLOW_COPY_AND_ASSIGN(VideoAdapter);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134};
135
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136} // namespace cricket
137
Steve Anton10542f22019-01-11 09:11:00 -0800138#endif // MEDIA_BASE_VIDEO_ADAPTER_H_