1 // Copyright (c) 2012 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/base/mac/video_frame_mac.h"
10 #include "base/callback_helpers.h"
11 #include "media/base/mac/corevideo_glue.h"
12 #include "media/base/video_frame.h"
14 #include "testing/gtest/include/gtest/gtest.h"
20 const int kWidth
= 64;
21 const int kHeight
= 48;
22 const base::TimeDelta kTimestamp
= base::TimeDelta::FromMicroseconds(1337);
25 VideoFrame::Format chrome
;
29 void Increment(int* i
) {
35 TEST(VideoFrameMac
, CheckBasicAttributes
) {
36 gfx::Size
size(kWidth
, kHeight
);
37 auto frame
= VideoFrame::CreateFrame(VideoFrame::I420
, size
, gfx::Rect(size
),
39 ASSERT_TRUE(frame
.get());
41 auto pb
= WrapVideoFrameInCVPixelBuffer(*frame
);
42 ASSERT_TRUE(pb
.get());
44 gfx::Size coded_size
= frame
->coded_size();
45 VideoFrame::Format format
= frame
->format();
47 EXPECT_EQ(coded_size
.width(), static_cast<int>(CVPixelBufferGetWidth(pb
)));
48 EXPECT_EQ(coded_size
.height(), static_cast<int>(CVPixelBufferGetHeight(pb
)));
49 EXPECT_EQ(VideoFrame::NumPlanes(format
), CVPixelBufferGetPlaneCount(pb
));
51 CVPixelBufferLockBaseAddress(pb
, 0);
52 for (size_t i
= 0; i
< VideoFrame::NumPlanes(format
); ++i
) {
53 gfx::Size plane_size
= VideoFrame::PlaneSize(format
, i
, coded_size
);
54 EXPECT_EQ(plane_size
.width(),
55 static_cast<int>(CVPixelBufferGetWidthOfPlane(pb
, i
)));
56 EXPECT_EQ(plane_size
.height(),
57 static_cast<int>(CVPixelBufferGetHeightOfPlane(pb
, i
)));
58 EXPECT_EQ(frame
->data(i
), CVPixelBufferGetBaseAddressOfPlane(pb
, i
));
60 CVPixelBufferUnlockBaseAddress(pb
, 0);
63 TEST(VideoFrameMac
, CheckFormats
) {
64 const FormatPair format_pairs
[] = {
65 {VideoFrame::I420
, kCVPixelFormatType_420YpCbCr8Planar
},
67 {VideoFrame::YV12
, 0},
68 {VideoFrame::YV16
, 0},
69 {VideoFrame::YV12A
, 0},
70 {VideoFrame::YV12J
, 0},
71 {VideoFrame::YV24
, 0},
74 gfx::Size
size(kWidth
, kHeight
);
75 for (const auto& format_pair
: format_pairs
) {
76 auto frame
= VideoFrame::CreateFrame(format_pair
.chrome
, size
,
77 gfx::Rect(size
), size
, kTimestamp
);
78 ASSERT_TRUE(frame
.get());
79 auto pb
= WrapVideoFrameInCVPixelBuffer(*frame
);
80 if (format_pair
.corevideo
) {
81 EXPECT_EQ(format_pair
.corevideo
, CVPixelBufferGetPixelFormatType(pb
));
83 EXPECT_EQ(nullptr, pb
.get());
88 TEST(VideoFrameMac
, CheckLifetime
) {
89 gfx::Size
size(kWidth
, kHeight
);
90 auto frame
= VideoFrame::CreateFrame(VideoFrame::I420
, size
, gfx::Rect(size
),
92 ASSERT_TRUE(frame
.get());
94 int instances_destroyed
= 0;
95 auto wrapper_frame
= VideoFrame::WrapVideoFrame(
96 frame
, frame
->visible_rect(), frame
->natural_size(),
97 base::Bind(&Increment
, &instances_destroyed
));
98 ASSERT_TRUE(wrapper_frame
.get());
100 auto pb
= WrapVideoFrameInCVPixelBuffer(*wrapper_frame
);
101 ASSERT_TRUE(pb
.get());
103 wrapper_frame
= nullptr;
104 EXPECT_EQ(0, instances_destroyed
);
106 EXPECT_EQ(1, instances_destroyed
);
109 TEST(VideoFrameMac
, CheckWrapperFrame
) {
110 const FormatPair format_pairs
[] = {
111 {VideoFrame::I420
, kCVPixelFormatType_420YpCbCr8Planar
},
113 CoreVideoGlue::kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
},
116 gfx::Size
size(kWidth
, kHeight
);
117 for (const auto& format_pair
: format_pairs
) {
118 base::ScopedCFTypeRef
<CVPixelBufferRef
> pb
;
119 CVPixelBufferCreate(nullptr, kWidth
, kHeight
, format_pair
.corevideo
,
120 nullptr, pb
.InitializeInto());
121 ASSERT_TRUE(pb
.get());
123 auto frame
= VideoFrame::WrapCVPixelBuffer(pb
.get(), kTimestamp
);
124 ASSERT_TRUE(frame
.get());
125 EXPECT_EQ(pb
.get(), frame
->cv_pixel_buffer());
126 EXPECT_EQ(format_pair
.chrome
, frame
->format());
129 EXPECT_EQ(1, CFGetRetainCount(pb
.get()));