1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/cast/test/utility/video_utility.h"
10 #include "base/rand_util.h"
11 #include "third_party/libyuv/include/libyuv/compare.h"
12 #include "ui/gfx/geometry/size.h"
17 double I420PSNR(const scoped_refptr
<media::VideoFrame
>& frame1
,
18 const scoped_refptr
<media::VideoFrame
>& frame2
) {
19 if (frame1
->visible_rect().width() != frame2
->visible_rect().width() ||
20 frame1
->visible_rect().height() != frame2
->visible_rect().height())
23 return libyuv::I420Psnr(frame1
->visible_data(VideoFrame::kYPlane
),
24 frame1
->stride(VideoFrame::kYPlane
),
25 frame1
->visible_data(VideoFrame::kUPlane
),
26 frame1
->stride(VideoFrame::kUPlane
),
27 frame1
->visible_data(VideoFrame::kVPlane
),
28 frame1
->stride(VideoFrame::kVPlane
),
29 frame2
->visible_data(VideoFrame::kYPlane
),
30 frame2
->stride(VideoFrame::kYPlane
),
31 frame2
->visible_data(VideoFrame::kUPlane
),
32 frame2
->stride(VideoFrame::kUPlane
),
33 frame2
->visible_data(VideoFrame::kVPlane
),
34 frame2
->stride(VideoFrame::kVPlane
),
35 frame1
->visible_rect().width(),
36 frame1
->visible_rect().height());
39 double I420SSIM(const scoped_refptr
<media::VideoFrame
>& frame1
,
40 const scoped_refptr
<media::VideoFrame
>& frame2
) {
41 if (frame1
->visible_rect().width() != frame2
->visible_rect().width() ||
42 frame1
->visible_rect().height() != frame2
->visible_rect().height())
45 return libyuv::I420Ssim(frame1
->visible_data(VideoFrame::kYPlane
),
46 frame1
->stride(VideoFrame::kYPlane
),
47 frame1
->visible_data(VideoFrame::kUPlane
),
48 frame1
->stride(VideoFrame::kUPlane
),
49 frame1
->visible_data(VideoFrame::kVPlane
),
50 frame1
->stride(VideoFrame::kVPlane
),
51 frame2
->visible_data(VideoFrame::kYPlane
),
52 frame2
->stride(VideoFrame::kYPlane
),
53 frame2
->visible_data(VideoFrame::kUPlane
),
54 frame2
->stride(VideoFrame::kUPlane
),
55 frame2
->visible_data(VideoFrame::kVPlane
),
56 frame2
->stride(VideoFrame::kVPlane
),
57 frame1
->visible_rect().width(),
58 frame1
->visible_rect().height());
61 void PopulateVideoFrame(VideoFrame
* frame
, int start_value
) {
62 const gfx::Size frame_size
= frame
->coded_size();
63 const int stripe_size
=
64 std::max(32, std::min(frame_size
.width(), frame_size
.height()) / 8) & -2;
67 const int height
= frame_size
.height();
68 const int stride_y
= frame
->stride(VideoFrame::kYPlane
);
69 uint8
* y_plane
= frame
->data(VideoFrame::kYPlane
);
70 for (int j
= 0; j
< height
; ++j
) {
71 const int stripe_j
= (j
/ stripe_size
) * stripe_size
;
72 for (int i
= 0; i
< stride_y
; ++i
) {
73 const int stripe_i
= (i
/ stripe_size
) * stripe_size
;
74 *y_plane
= static_cast<uint8
>(start_value
+ stripe_i
+ stripe_j
);
79 const int half_height
= (height
+ 1) / 2;
80 if (frame
->format() == PIXEL_FORMAT_NV12
) {
81 const int stride_uv
= frame
->stride(VideoFrame::kUVPlane
);
82 uint8
* uv_plane
= frame
->data(VideoFrame::kUVPlane
);
85 for (int j
= 0; j
< half_height
; ++j
) {
86 const int stripe_j
= (j
/ stripe_size
) * stripe_size
;
87 for (int i
= 0; i
< stride_uv
; i
+= 2) {
88 const int stripe_i
= (i
/ stripe_size
) * stripe_size
;
89 *uv_plane
= *(uv_plane
+ 1) =
90 static_cast<uint8
>(start_value
+ stripe_i
+ stripe_j
);
95 DCHECK(frame
->format() == PIXEL_FORMAT_I420
||
96 frame
->format() == PIXEL_FORMAT_YV12
);
97 const int stride_u
= frame
->stride(VideoFrame::kUPlane
);
98 const int stride_v
= frame
->stride(VideoFrame::kVPlane
);
99 uint8
* u_plane
= frame
->data(VideoFrame::kUPlane
);
100 uint8
* v_plane
= frame
->data(VideoFrame::kVPlane
);
103 for (int j
= 0; j
< half_height
; ++j
) {
104 const int stripe_j
= (j
/ stripe_size
) * stripe_size
;
105 for (int i
= 0; i
< stride_u
; ++i
) {
106 const int stripe_i
= (i
/ stripe_size
) * stripe_size
;
107 *u_plane
= static_cast<uint8
>(start_value
+ stripe_i
+ stripe_j
);
113 for (int j
= 0; j
< half_height
; ++j
) {
114 const int stripe_j
= (j
/ stripe_size
) * stripe_size
;
115 for (int i
= 0; i
< stride_v
; ++i
) {
116 const int stripe_i
= (i
/ stripe_size
) * stripe_size
;
117 *v_plane
= static_cast<uint8
>(start_value
+ stripe_i
+ stripe_j
);
124 void PopulateVideoFrameWithNoise(VideoFrame
* frame
) {
125 const int height
= frame
->coded_size().height();
126 const int stride_y
= frame
->stride(VideoFrame::kYPlane
);
127 const int stride_u
= frame
->stride(VideoFrame::kUPlane
);
128 const int stride_v
= frame
->stride(VideoFrame::kVPlane
);
129 const int half_height
= (height
+ 1) / 2;
130 uint8
* const y_plane
= frame
->data(VideoFrame::kYPlane
);
131 uint8
* const u_plane
= frame
->data(VideoFrame::kUPlane
);
132 uint8
* const v_plane
= frame
->data(VideoFrame::kVPlane
);
134 base::RandBytes(y_plane
, height
* stride_y
);
135 base::RandBytes(u_plane
, half_height
* stride_u
);
136 base::RandBytes(v_plane
, half_height
* stride_v
);
139 bool PopulateVideoFrameFromFile(VideoFrame
* frame
, FILE* video_file
) {
140 const int width
= frame
->coded_size().width();
141 const int height
= frame
->coded_size().height();
142 const int half_width
= (width
+ 1) / 2;
143 const int half_height
= (height
+ 1) / 2;
144 const size_t frame_size
= width
* height
+ 2 * half_width
* half_height
;
145 uint8
* const y_plane
= frame
->data(VideoFrame::kYPlane
);
146 uint8
* const u_plane
= frame
->data(VideoFrame::kUPlane
);
147 uint8
* const v_plane
= frame
->data(VideoFrame::kVPlane
);
149 uint8
* const raw_data
= new uint8
[frame_size
];
150 const size_t count
= fread(raw_data
, 1, frame_size
, video_file
);
151 if (count
!= frame_size
)
154 memcpy(y_plane
, raw_data
, width
* height
);
155 memcpy(u_plane
, raw_data
+ width
* height
, half_width
* half_height
);
157 raw_data
+ width
* height
+ half_width
* half_height
,
158 half_width
* half_height
);