1 /*
2  *  Copyright (c) 2012 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 /*
12  * WebRTC's wrapper to libyuv.
13  */
14 
15 #ifndef COMMON_VIDEO_LIBYUV_INCLUDE_WEBRTC_LIBYUV_H_
16 #define COMMON_VIDEO_LIBYUV_INCLUDE_WEBRTC_LIBYUV_H_
17 
18 #include <stdint.h>
19 #include <stdio.h>
20 
21 #include <vector>
22 
23 #include "api/scoped_refptr.h"
24 #include "api/video/video_frame.h"
25 #include "api/video/video_frame_buffer.h"
26 #include "rtc_base/system/rtc_export.h"
27 
28 namespace webrtc {
29 
30 enum class VideoType {
31   kUnknown,
32   kI420,
33   kIYUV,
34   kRGB24,
35   kABGR,
36   kARGB,
37   kARGB4444,
38   kRGB565,
39   kARGB1555,
40   kYUY2,
41   kYV12,
42   kUYVY,
43   kMJPEG,
44   kNV21,
45   kNV12,
46   kBGRA,
47 };
48 
49 // This is the max PSNR value our algorithms can return.
50 const double kPerfectPSNR = 48.0f;
51 
52 // Calculate the required buffer size.
53 // Input:
54 //   - type         :The type of the designated video frame.
55 //   - width        :frame width in pixels.
56 //   - height       :frame height in pixels.
57 // Return value:    :The required size in bytes to accommodate the specified
58 //                   video frame.
59 size_t CalcBufferSize(VideoType type, int width, int height);
60 
61 // TODO(mikhal): Add unit test for these two functions and determine location.
62 // Print VideoFrame to file
63 // Input:
64 //    - frame       : Reference to video frame.
65 //    - file        : pointer to file object. It is assumed that the file is
66 //                    already open for writing.
67 // Return value: 0 if OK, < 0 otherwise.
68 int PrintVideoFrame(const VideoFrame& frame, FILE* file);
69 int PrintVideoFrame(const I420BufferInterface& frame, FILE* file);
70 
71 // Extract buffer from VideoFrame or I420BufferInterface (consecutive
72 // planes, no stride)
73 // Input:
74 //   - frame       : Reference to video frame.
75 //   - size        : pointer to the size of the allocated buffer. If size is
76 //                   insufficient, an error will be returned.
77 //   - buffer      : Pointer to buffer
78 // Return value: length of buffer if OK, < 0 otherwise.
79 int ExtractBuffer(const rtc::scoped_refptr<I420BufferInterface>& input_frame,
80                   size_t size,
81                   uint8_t* buffer);
82 int ExtractBuffer(const VideoFrame& input_frame, size_t size, uint8_t* buffer);
83 // Convert From I420
84 // Input:
85 //   - src_frame        : Reference to a source frame.
86 //   - dst_video_type   : Type of output video.
87 //   - dst_sample_size  : Required only for the parsing of MJPG.
88 //   - dst_frame        : Pointer to a destination frame.
89 // Return value: 0 if OK, < 0 otherwise.
90 // It is assumed that source and destination have equal height.
91 int ConvertFromI420(const VideoFrame& src_frame,
92                     VideoType dst_video_type,
93                     int dst_sample_size,
94                     uint8_t* dst_frame);
95 
96 rtc::scoped_refptr<I420BufferInterface> ScaleVideoFrameBuffer(
97     const I420BufferInterface& source,
98     int dst_width,
99     int dst_height);
100 
101 double I420SSE(const I420BufferInterface& ref_buffer,
102                const I420BufferInterface& test_buffer);
103 
104 // Compute PSNR for an I420 frame (all planes).
105 // Returns the PSNR in decibel, to a maximum of kInfinitePSNR.
106 double I420PSNR(const VideoFrame* ref_frame, const VideoFrame* test_frame);
107 double I420PSNR(const I420BufferInterface& ref_buffer,
108                 const I420BufferInterface& test_buffer);
109 
110 // Compute SSIM for an I420 frame (all planes).
111 double I420SSIM(const VideoFrame* ref_frame, const VideoFrame* test_frame);
112 double I420SSIM(const I420BufferInterface& ref_buffer,
113                 const I420BufferInterface& test_buffer);
114 
115 // Helper function for scaling NV12 to NV12.
116 // If the |src_width| and |src_height| matches the |dst_width| and |dst_height|,
117 // then |tmp_buffer| is not used. In other cases, the minimum size of
118 // |tmp_buffer| should be:
119 //   (src_width/2) * (src_height/2) * 2 + (dst_width/2) * (dst_height/2) * 2
120 void NV12Scale(uint8_t* tmp_buffer,
121                const uint8_t* src_y,
122                int src_stride_y,
123                const uint8_t* src_uv,
124                int src_stride_uv,
125                int src_width,
126                int src_height,
127                uint8_t* dst_y,
128                int dst_stride_y,
129                uint8_t* dst_uv,
130                int dst_stride_uv,
131                int dst_width,
132                int dst_height);
133 
134 // Helper class for directly converting and scaling NV12 to I420. The Y-plane
135 // will be scaled directly to the I420 destination, which makes this faster
136 // than separate NV12->I420 + I420->I420 scaling.
137 class RTC_EXPORT NV12ToI420Scaler {
138  public:
139   NV12ToI420Scaler();
140   ~NV12ToI420Scaler();
141   void NV12ToI420Scale(const uint8_t* src_y,
142                        int src_stride_y,
143                        const uint8_t* src_uv,
144                        int src_stride_uv,
145                        int src_width,
146                        int src_height,
147                        uint8_t* dst_y,
148                        int dst_stride_y,
149                        uint8_t* dst_u,
150                        int dst_stride_u,
151                        uint8_t* dst_v,
152                        int dst_stride_v,
153                        int dst_width,
154                        int dst_height);
155 
156  private:
157   std::vector<uint8_t> tmp_uv_planes_;
158 };
159 
160 // Convert VideoType to libyuv FourCC type
161 int ConvertVideoType(VideoType video_type);
162 
163 }  // namespace webrtc
164 
165 #endif  // COMMON_VIDEO_LIBYUV_INCLUDE_WEBRTC_LIBYUV_H_
166