Index: content/renderer/media/video_track_recorder_unittest.cc |
diff --git a/content/renderer/media/video_track_recorder_unittest.cc b/content/renderer/media/video_track_recorder_unittest.cc |
index a8390825af89b13c947bd4a49c53df5c1f54ab8c..c2a059314c841589d9068419930f03c421572308 100644 |
--- a/content/renderer/media/video_track_recorder_unittest.cc |
+++ b/content/renderer/media/video_track_recorder_unittest.cc |
@@ -40,6 +40,29 @@ ACTION_P(RunClosure, closure) { |
closure.Run(); |
} |
+// VideoFrame holding ARGB memory-backed pixels (VideoFrame has no public API |
+// surface for creating this type of frames nor their storage). |
+class ARGBVideoFrame : public media::VideoFrame { |
+ public: |
+ ARGBVideoFrame(const gfx::Size& size) |
+ : VideoFrame(media::PIXEL_FORMAT_ARGB, |
+ STORAGE_OWNED_MEMORY, |
+ size, |
+ gfx::Rect(size), |
+ size, |
+ base::TimeDelta()), |
+ buffer_(size.GetArea()) { |
+ set_data(kARGBPlane, buffer_.data()); |
+ set_stride(kARGBPlane, size.GetArea()); |
+ } |
+ |
+ private: |
+ ~ARGBVideoFrame() final {} |
+ |
+ std::vector<uint8_t> buffer_; |
+ DISALLOW_COPY_AND_ASSIGN(ARGBVideoFrame); |
+}; |
+ |
const VideoTrackRecorder::CodecId kTrackRecorderTestCodec[] = { |
VideoTrackRecorder::CodecId::VP8, |
VideoTrackRecorder::CodecId::VP9 |
@@ -48,6 +71,11 @@ const VideoTrackRecorder::CodecId kTrackRecorderTestCodec[] = { |
#endif |
}; |
+// Typical frame size; cannot be arbitrarily small, should be reasonable. |
+static const gfx::Size kFrameSize(80,40); |
+ |
+static void DummyReleaseMailboxCB(const gpu::SyncToken& sync_token) {} |
+ |
class VideoTrackRecorderTest |
: public TestWithParam<VideoTrackRecorder::CodecId> { |
public: |
@@ -128,11 +156,9 @@ TEST_P(VideoTrackRecorderTest, ConstructAndDestruct) {} |
// Creates the encoder and encodes 2 frames of the same size; the encoder should |
// be initialised and produce a keyframe, then a non-keyframe. Finally a frame |
// of larger size is sent and is expected to be encoded as a keyframe. |
-TEST_P(VideoTrackRecorderTest, VideoEncoding) { |
- // |frame_size| cannot be arbitrarily small, should be reasonable. |
- const gfx::Size frame_size(160, 80); |
+TEST_P(VideoTrackRecorderTest, Encoding) { |
const scoped_refptr<VideoFrame> video_frame = |
- VideoFrame::CreateBlackFrame(frame_size); |
+ VideoFrame::CreateBlackFrame(kFrameSize); |
const double kFrameRate = 60.0f; |
video_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, |
kFrameRate); |
@@ -178,6 +204,70 @@ TEST_P(VideoTrackRecorderTest, VideoEncoding) { |
Mock::VerifyAndClearExpectations(this); |
} |
+// Verifies that a Mappable ARGB Video Frame can be correctly encoded. |
+TEST_P(VideoTrackRecorderTest, EncodingARGBFrame) { |
+ const scoped_refptr<VideoFrame> video_frame(new ARGBVideoFrame(kFrameSize)); |
+ |
+ InSequence s; |
+ base::RunLoop run_loop; |
+ base::Closure quit_closure = run_loop.QuitClosure(); |
+ scoped_refptr<VideoFrame> encoded_frame; |
+ base::StringPiece encoded_data; |
+ EXPECT_CALL(*this, DoOnEncodedVideo(_, _, _, true)) |
+ .Times(1) |
+ .WillOnce(DoAll(SaveArg<0>(&encoded_frame), |
+ SaveArg<1>(&encoded_data), |
+ RunClosure(quit_closure))); |
+ Encode(video_frame, base::TimeTicks::Now()); |
+ run_loop.Run(); |
+ |
+ EXPECT_EQ(media::PIXEL_FORMAT_I420, encoded_frame->format()); |
+ EXPECT_EQ(video_frame->coded_size(), encoded_frame->coded_size()); |
+ |
+ const size_t kEncodedSizeThreshold = 14; |
+ EXPECT_GE(encoded_data.size(), kEncodedSizeThreshold); |
+ |
+ Mock::VerifyAndClearExpectations(this); |
+} |
+ |
+// Tests that a not IsMappable() frame is encoded as a full black one. |
+TEST_P(VideoTrackRecorderTest, EncodingNonMappableFrame) { |
+ gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes] = {}; |
+ const scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapNativeTextures( |
+ media::PIXEL_FORMAT_ARGB, mailbox_holders, |
+ base::Bind(&DummyReleaseMailboxCB), kFrameSize, gfx::Rect(kFrameSize), |
+ kFrameSize, base::TimeDelta()); |
+ ASSERT_FALSE(video_frame->IsMappable()); |
+ |
+ InSequence s; |
+ base::RunLoop run_loop; |
+ base::Closure quit_closure = run_loop.QuitClosure(); |
+ scoped_refptr<VideoFrame> encoded_frame; |
+ EXPECT_CALL(*this, DoOnEncodedVideo(_, _, _, true)) |
+ .Times(1) |
+ .WillOnce(DoAll(SaveArg<0>(&encoded_frame), RunClosure(quit_closure))); |
+ Encode(video_frame, base::TimeTicks::Now()); |
+ run_loop.Run(); |
+ |
+ // |encoded_frame| should be full-black, since |video_frame| is not mappable. |
+ ASSERT_EQ(media::PIXEL_FORMAT_YV12, encoded_frame->format()); |
+ EXPECT_EQ(video_frame->coded_size(), encoded_frame->coded_size()); |
+ const uint8_t* y_plane = encoded_frame->data(media::VideoFrame::kYPlane); |
emircan
2016/07/12 22:57:00
Can we have this in a for loop?
mcasas
2016/07/13 00:45:31
Do you mean:
for (int i = 0; i < y_plane_size; ++
|
+ const int y_plane_size = encoded_frame->row_bytes(media::VideoFrame::kYPlane); |
+ for (int i = 0; i < y_plane_size; ++i) |
+ EXPECT_EQ(0u, y_plane[i]); |
+ const uint8_t* u_plane = encoded_frame->data(media::VideoFrame::kUPlane); |
+ const int u_plane_size = encoded_frame->row_bytes(media::VideoFrame::kUPlane); |
+ for (int i = 0; i < u_plane_size; ++i) |
+ EXPECT_EQ(0x80, u_plane[i]); |
+ const uint8_t* v_plane = encoded_frame->data(media::VideoFrame::kVPlane); |
+ const int v_plane_size = encoded_frame->row_bytes(media::VideoFrame::kVPlane); |
+ for (int i = 0; i < v_plane_size; ++i) |
+ EXPECT_EQ(0x80, v_plane[i]); |
+ |
+ Mock::VerifyAndClearExpectations(this); |
+} |
+ |
INSTANTIATE_TEST_CASE_P(, |
VideoTrackRecorderTest, |
ValuesIn(kTrackRecorderTestCodec)); |