| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/muxers/webm_muxer.h" | 5 #include "media/muxers/webm_muxer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 const scoped_refptr<VideoFrame> video_frame = | 104 const scoped_refptr<VideoFrame> video_frame = |
| 105 VideoFrame::CreateBlackFrame(frame_size); | 105 VideoFrame::CreateBlackFrame(frame_size); |
| 106 const std::string encoded_data("abcdefghijklmnopqrstuvwxyz"); | 106 const std::string encoded_data("abcdefghijklmnopqrstuvwxyz"); |
| 107 | 107 |
| 108 EXPECT_CALL(*this, WriteCallback(_)) | 108 EXPECT_CALL(*this, WriteCallback(_)) |
| 109 .Times(AtLeast(1)) | 109 .Times(AtLeast(1)) |
| 110 .WillRepeatedly( | 110 .WillRepeatedly( |
| 111 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); | 111 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); |
| 112 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( | 112 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( |
| 113 WebmMuxer::VideoParameters(video_frame), | 113 WebmMuxer::VideoParameters(video_frame), |
| 114 base::WrapUnique(new std::string(encoded_data)), base::TimeTicks::Now(), | 114 base::WrapUnique(new std::string(encoded_data)), nullptr, |
| 115 false /* keyframe */)); | 115 base::TimeTicks::Now(), false /* keyframe */)); |
| 116 | 116 |
| 117 // First time around WriteCallback() is pinged a number of times to write the | 117 // First time around WriteCallback() is pinged a number of times to write the |
| 118 // Matroska header, but at the end it dumps |encoded_data|. | 118 // Matroska header, but at the end it dumps |encoded_data|. |
| 119 EXPECT_EQ(last_encoded_length_, encoded_data.size()); | 119 EXPECT_EQ(last_encoded_length_, encoded_data.size()); |
| 120 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_); | 120 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_); |
| 121 EXPECT_GE(GetWebmMuxerPosition(), static_cast<int64_t>(last_encoded_length_)); | 121 EXPECT_GE(GetWebmMuxerPosition(), static_cast<int64_t>(last_encoded_length_)); |
| 122 EXPECT_EQ(GetWebmSegmentMode(), mkvmuxer::Segment::kLive); | 122 EXPECT_EQ(GetWebmSegmentMode(), mkvmuxer::Segment::kLive); |
| 123 | 123 |
| 124 const int64_t begin_of_second_block = accumulated_position_; | 124 const int64_t begin_of_second_block = accumulated_position_; |
| 125 EXPECT_CALL(*this, WriteCallback(_)) | 125 EXPECT_CALL(*this, WriteCallback(_)) |
| 126 .Times(AtLeast(1)) | 126 .Times(AtLeast(1)) |
| 127 .WillRepeatedly( | 127 .WillRepeatedly( |
| 128 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); | 128 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); |
| 129 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( | 129 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( |
| 130 video_frame, base::WrapUnique(new std::string(encoded_data)), | 130 video_frame, base::WrapUnique(new std::string(encoded_data)), nullptr, |
| 131 base::TimeTicks::Now(), false /* keyframe */)); | 131 base::TimeTicks::Now(), false /* keyframe */)); |
| 132 | 132 |
| 133 // The second time around the callbacks should include a SimpleBlock header, | 133 // The second time around the callbacks should include a SimpleBlock header, |
| 134 // namely the track index, a timestamp and a flags byte, for a total of 6B. | 134 // namely the track index, a timestamp and a flags byte, for a total of 6B. |
| 135 EXPECT_EQ(last_encoded_length_, encoded_data.size()); | 135 EXPECT_EQ(last_encoded_length_, encoded_data.size()); |
| 136 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_); | 136 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_); |
| 137 const uint32_t kSimpleBlockSize = 6u; | 137 const uint32_t kSimpleBlockSize = 6u; |
| 138 EXPECT_EQ(static_cast<int64_t>(begin_of_second_block + kSimpleBlockSize + | 138 EXPECT_EQ(static_cast<int64_t>(begin_of_second_block + kSimpleBlockSize + |
| 139 encoded_data.size()), | 139 encoded_data.size()), |
| 140 accumulated_position_); | 140 accumulated_position_); |
| 141 | 141 |
| 142 // Force an error in libwebm and expect OnEncodedVideo to fail. | 142 // Force an error in libwebm and expect OnEncodedVideo to fail. |
| 143 webm_muxer_.ForceOneLibWebmErrorForTesting(); | 143 webm_muxer_.ForceOneLibWebmErrorForTesting(); |
| 144 EXPECT_FALSE( | 144 EXPECT_FALSE(webm_muxer_.OnEncodedVideo( |
| 145 webm_muxer_.OnEncodedVideo(WebmMuxer::VideoParameters(video_frame), | 145 WebmMuxer::VideoParameters(video_frame), |
| 146 base::MakeUnique<std::string>(encoded_data), | 146 base::MakeUnique<std::string>(encoded_data), nullptr, |
| 147 base::TimeTicks::Now(), true /* keyframe */)); | 147 base::TimeTicks::Now(), true /* keyframe */)); |
| 148 } |
| 149 |
| 150 // This test sends two frames and checks that the WriteCallback is called with |
| 151 // appropriate params in both cases. |
| 152 TEST_P(WebmMuxerTest, OnEncodedVideoTwoAlphaFrames) { |
| 153 if (GetParam().num_audio_tracks > 0) |
| 154 return; |
| 155 |
| 156 const gfx::Size frame_size(160, 80); |
| 157 const scoped_refptr<VideoFrame> video_frame = |
| 158 VideoFrame::CreateTransparentFrame(frame_size); |
| 159 const std::string encoded_data("abcdefghijklmnopqrstuvwxyz"); |
| 160 const std::string alpha_encoded_data("ijklmnopqrstuvwxyz"); |
| 161 |
| 162 InSequence s; |
| 163 EXPECT_CALL(*this, WriteCallback(_)) |
| 164 .Times(AtLeast(1)) |
| 165 .WillRepeatedly( |
| 166 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); |
| 167 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( |
| 168 WebmMuxer::VideoParameters(video_frame), |
| 169 base::WrapUnique(new std::string(encoded_data)), |
| 170 base::WrapUnique(new std::string(alpha_encoded_data)), |
| 171 base::TimeTicks::Now(), false /* keyframe */)); |
| 172 |
| 173 // First time around WriteCallback() is pinged a number of times to write the |
| 174 // Matroska header, but at the end it dumps |encoded_data|. |
| 175 EXPECT_EQ(last_encoded_length_, 1u); |
| 176 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_); |
| 177 EXPECT_GE(GetWebmMuxerPosition(), static_cast<int64_t>(last_encoded_length_)); |
| 178 EXPECT_EQ(GetWebmSegmentMode(), mkvmuxer::Segment::kLive); |
| 179 |
| 180 const int64_t begin_of_second_block = accumulated_position_; |
| 181 EXPECT_CALL(*this, WriteCallback(_)) |
| 182 .Times(AtLeast(1)) |
| 183 .WillRepeatedly( |
| 184 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); |
| 185 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( |
| 186 video_frame, base::WrapUnique(new std::string(encoded_data)), |
| 187 base::WrapUnique(new std::string(alpha_encoded_data)), |
| 188 base::TimeTicks::Now(), false /* keyframe */)); |
| 189 |
| 190 EXPECT_EQ(last_encoded_length_, 1u); |
| 191 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_); |
| 192 const uint32_t kBlockSize = 21u; |
| 193 EXPECT_EQ( |
| 194 static_cast<int64_t>(begin_of_second_block + kBlockSize + |
| 195 encoded_data.size() + alpha_encoded_data.size()), |
| 196 accumulated_position_); |
| 197 |
| 198 // Force an error in libwebm and expect OnEncodedVideo to fail. |
| 199 webm_muxer_.ForceOneLibWebmErrorForTesting(); |
| 200 EXPECT_FALSE(webm_muxer_.OnEncodedVideo( |
| 201 WebmMuxer::VideoParameters(video_frame), |
| 202 base::MakeUnique<std::string>(encoded_data), nullptr, |
| 203 base::TimeTicks::Now(), true /* keyframe */)); |
| 148 } | 204 } |
| 149 | 205 |
| 150 TEST_P(WebmMuxerTest, OnEncodedAudioTwoFrames) { | 206 TEST_P(WebmMuxerTest, OnEncodedAudioTwoFrames) { |
| 151 if (GetParam().num_video_tracks > 0) | 207 if (GetParam().num_video_tracks > 0) |
| 152 return; | 208 return; |
| 153 | 209 |
| 154 const int sample_rate = 48000; | 210 const int sample_rate = 48000; |
| 155 const int bits_per_sample = 16; | 211 const int bits_per_sample = 16; |
| 156 const int frames_per_buffer = 480; | 212 const int frames_per_buffer = 480; |
| 157 media::AudioParameters audio_params( | 213 media::AudioParameters audio_params( |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 if (GetParam().num_video_tracks == 0 || GetParam().num_audio_tracks == 0) | 264 if (GetParam().num_video_tracks == 0 || GetParam().num_audio_tracks == 0) |
| 209 return; | 265 return; |
| 210 | 266 |
| 211 // First send a video keyframe. | 267 // First send a video keyframe. |
| 212 const gfx::Size frame_size(160, 80); | 268 const gfx::Size frame_size(160, 80); |
| 213 const scoped_refptr<VideoFrame> video_frame = | 269 const scoped_refptr<VideoFrame> video_frame = |
| 214 VideoFrame::CreateBlackFrame(frame_size); | 270 VideoFrame::CreateBlackFrame(frame_size); |
| 215 const std::string encoded_video("thisisanencodedvideopacket"); | 271 const std::string encoded_video("thisisanencodedvideopacket"); |
| 216 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( | 272 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( |
| 217 WebmMuxer::VideoParameters(video_frame), | 273 WebmMuxer::VideoParameters(video_frame), |
| 218 base::WrapUnique(new std::string(encoded_video)), base::TimeTicks::Now(), | 274 base::WrapUnique(new std::string(encoded_video)), nullptr, |
| 219 true /* keyframe */)); | 275 base::TimeTicks::Now(), true /* keyframe */)); |
| 220 // A few encoded non key frames. | 276 // A few encoded non key frames. |
| 221 const int kNumNonKeyFrames = 2; | 277 const int kNumNonKeyFrames = 2; |
| 222 for (int i = 0; i < kNumNonKeyFrames; ++i) { | 278 for (int i = 0; i < kNumNonKeyFrames; ++i) { |
| 223 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( | 279 EXPECT_TRUE(webm_muxer_.OnEncodedVideo( |
| 224 WebmMuxer::VideoParameters(video_frame), | 280 WebmMuxer::VideoParameters(video_frame), |
| 225 base::WrapUnique(new std::string(encoded_video)), | 281 base::WrapUnique(new std::string(encoded_video)), nullptr, |
| 226 base::TimeTicks::Now(), false /* keyframe */)); | 282 base::TimeTicks::Now(), false /* keyframe */)); |
| 227 } | 283 } |
| 228 | 284 |
| 229 const int sample_rate = 48000; | 285 const int sample_rate = 48000; |
| 230 const int bits_per_sample = 16; | 286 const int bits_per_sample = 16; |
| 231 const int frames_per_buffer = 480; | 287 const int frames_per_buffer = 480; |
| 232 media::AudioParameters audio_params( | 288 media::AudioParameters audio_params( |
| 233 media::AudioParameters::Format::AUDIO_PCM_LOW_LATENCY, | 289 media::AudioParameters::Format::AUDIO_PCM_LOW_LATENCY, |
| 234 media::CHANNEL_LAYOUT_MONO, sample_rate, bits_per_sample, | 290 media::CHANNEL_LAYOUT_MONO, sample_rate, bits_per_sample, |
| 235 frames_per_buffer); | 291 frames_per_buffer); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 264 {kCodecVP9, 0, 1}, | 320 {kCodecVP9, 0, 1}, |
| 265 {kCodecVP9, 1, 1}, | 321 {kCodecVP9, 1, 1}, |
| 266 {kCodecH264, 1, 0}, | 322 {kCodecH264, 1, 0}, |
| 267 {kCodecH264, 0, 1}, | 323 {kCodecH264, 0, 1}, |
| 268 {kCodecH264, 1, 1}, | 324 {kCodecH264, 1, 1}, |
| 269 }; | 325 }; |
| 270 | 326 |
| 271 INSTANTIATE_TEST_CASE_P(, WebmMuxerTest, ValuesIn(kTestCases)); | 327 INSTANTIATE_TEST_CASE_P(, WebmMuxerTest, ValuesIn(kTestCases)); |
| 272 | 328 |
| 273 } // namespace media | 329 } // namespace media |
| OLD | NEW |