Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: media/base/android/media_codec_bridge_impl_unittest.cc

Issue 2697643003: media: Clean up MediaCodecBridge and remove subclasses (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <memory> 8 #include <memory>
9 #include <string> 9 #include <string>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h"
12 #include "media/base/android/media_codec_bridge_impl.h" 13 #include "media/base/android/media_codec_bridge_impl.h"
13 #include "media/base/android/media_codec_util.h" 14 #include "media/base/android/media_codec_util.h"
14 #include "media/base/decoder_buffer.h" 15 #include "media/base/decoder_buffer.h"
16 #include "media/base/media_util.h"
15 #include "media/base/test_data_util.h" 17 #include "media/base/test_data_util.h"
16 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gmock/include/gmock/gmock.h"
17 19
20 using testing::IsNull;
21 using testing::NotNull;
22
18 namespace { 23 namespace {
19 24
20 // The first frame of 25 // The first frame of
21 // http://www.html5rocks.com/en/tutorials/audio/quick/test.mp3 26 // http://www.html5rocks.com/en/tutorials/audio/quick/test.mp3
22 unsigned char test_mp3[] = { 27 unsigned char test_mp3[] = {
23 0xff, 0xfb, 0xd2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x05, 0x00, 28 0xff, 0xfb, 0xd2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x05, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x2a, 0x7e, 0x40, 29 0x00, 0x00, 0x00, 0x00, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x2a, 0x7e, 0x40,
25 0xc0, 0x19, 0x4a, 0x80, 0x0d, 0x60, 0x48, 0x1b, 0x40, 0xf7, 0xbd, 0xb9, 30 0xc0, 0x19, 0x4a, 0x80, 0x0d, 0x60, 0x48, 0x1b, 0x40, 0xf7, 0xbd, 0xb9,
26 0xd9, 0x40, 0x6f, 0x82, 0x01, 0x8b, 0x17, 0xa0, 0x80, 0xc5, 0x01, 0xad, 31 0xd9, 0x40, 0x6f, 0x82, 0x01, 0x8b, 0x17, 0xa0, 0x80, 0xc5, 0x01, 0xad,
27 0x9a, 0xd3, 0x00, 0x12, 0xc0, 0x72, 0x93, 0x67, 0xd0, 0x03, 0x6f, 0xa4, 32 0x9a, 0xd3, 0x00, 0x12, 0xc0, 0x72, 0x93, 0x67, 0xd0, 0x03, 0x6f, 0xa4,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 } \ 109 } \
105 } while (0) 110 } while (0)
106 111
107 static const int kPresentationTimeBase = 100; 112 static const int kPresentationTimeBase = 100;
108 static const int kMaxInputPts = kPresentationTimeBase + 2; 113 static const int kMaxInputPts = kPresentationTimeBase + 2;
109 114
110 static inline const base::TimeDelta InfiniteTimeOut() { 115 static inline const base::TimeDelta InfiniteTimeOut() {
111 return base::TimeDelta::FromMicroseconds(-1); 116 return base::TimeDelta::FromMicroseconds(-1);
112 } 117 }
113 118
114 void DecodeMediaFrame(VideoCodecBridge* media_codec, 119 void DecodeMediaFrame(MediaCodecBridge* media_codec,
115 const uint8_t* data, 120 const uint8_t* data,
116 size_t data_size, 121 size_t data_size,
117 const base::TimeDelta input_presentation_timestamp, 122 const base::TimeDelta input_presentation_timestamp,
118 const base::TimeDelta initial_timestamp_lower_bound) { 123 const base::TimeDelta initial_timestamp_lower_bound) {
119 base::TimeDelta input_pts = input_presentation_timestamp; 124 base::TimeDelta input_pts = input_presentation_timestamp;
120 base::TimeDelta timestamp = initial_timestamp_lower_bound; 125 base::TimeDelta timestamp = initial_timestamp_lower_bound;
121 base::TimeDelta new_timestamp; 126 base::TimeDelta new_timestamp;
122 for (int i = 0; i < 10; ++i) { 127 for (int i = 0; i < 10; ++i) {
123 int input_buf_index = -1; 128 int input_buf_index = -1;
124 MediaCodecStatus status = 129 MediaCodecStatus status =
(...skipping 14 matching lines...) Expand all
139 if (status == MEDIA_CODEC_OK && output_buf_index > 0) { 144 if (status == MEDIA_CODEC_OK && output_buf_index > 0) {
140 media_codec->ReleaseOutputBuffer(output_buf_index, false); 145 media_codec->ReleaseOutputBuffer(output_buf_index, false);
141 } 146 }
142 // Output time stamp should not be smaller than old timestamp. 147 // Output time stamp should not be smaller than old timestamp.
143 ASSERT_TRUE(new_timestamp >= timestamp); 148 ASSERT_TRUE(new_timestamp >= timestamp);
144 input_pts += base::TimeDelta::FromMicroseconds(33000); 149 input_pts += base::TimeDelta::FromMicroseconds(33000);
145 timestamp = new_timestamp; 150 timestamp = new_timestamp;
146 } 151 }
147 } 152 }
148 153
149 TEST(MediaCodecBridgeTest, Initialize) { 154 AudioDecoderConfig NewAudioConfig(
155 AudioCodec codec,
156 std::vector<uint8_t> extra_data = std::vector<uint8_t>(),
157 base::TimeDelta seek_preroll = base::TimeDelta(),
158 int64_t codec_delay = 0) {
159 AudioDecoderConfig config;
160 config.Initialize(codec, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
161 extra_data, Unencrypted(), seek_preroll, codec_delay);
162 return config;
163 }
164
165 TEST(MediaCodecBridgeTest, CreateH264Decoder) {
150 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE(); 166 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE();
151 167
152 std::unique_ptr<media::MediaCodecBridge> media_codec; 168 MediaCodecBridgeImpl::CreateVideoDecoder(
153 media_codec.reset(VideoCodecBridge::CreateDecoder(
154 kCodecH264, false, gfx::Size(640, 480), nullptr, nullptr, 169 kCodecH264, false, gfx::Size(640, 480), nullptr, nullptr,
155 std::vector<uint8_t>(), std::vector<uint8_t>())); 170 std::vector<uint8_t>(), std::vector<uint8_t>());
156 } 171 }
157 172
158 TEST(MediaCodecBridgeTest, DoNormal) { 173 TEST(MediaCodecBridgeTest, DoNormal) {
159 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE(); 174 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE();
160 175
161 std::unique_ptr<media::AudioCodecBridge> media_codec; 176 std::unique_ptr<media::MediaCodecBridge> media_codec =
162 media_codec.reset(AudioCodecBridge::Create(kCodecMP3)); 177 MediaCodecBridgeImpl::CreateAudioDecoder(NewAudioConfig(kCodecMP3),
163 178 nullptr);
164 ASSERT_TRUE(media_codec->ConfigureAndStart(kCodecMP3, 44100, 2, nullptr, 0, 0, 179 ASSERT_THAT(media_codec, NotNull());
165 0, nullptr));
166 180
167 int input_buf_index = -1; 181 int input_buf_index = -1;
168 MediaCodecStatus status = 182 MediaCodecStatus status =
169 media_codec->DequeueInputBuffer(InfiniteTimeOut(), &input_buf_index); 183 media_codec->DequeueInputBuffer(InfiniteTimeOut(), &input_buf_index);
170 ASSERT_EQ(MEDIA_CODEC_OK, status); 184 ASSERT_EQ(MEDIA_CODEC_OK, status);
171 ASSERT_GE(input_buf_index, 0); 185 ASSERT_GE(input_buf_index, 0);
172 186
173 int64_t input_pts = kPresentationTimeBase; 187 int64_t input_pts = kPresentationTimeBase;
174 media_codec->QueueInputBuffer(input_buf_index, test_mp3, sizeof(test_mp3), 188 media_codec->QueueInputBuffer(input_buf_index, test_mp3, sizeof(test_mp3),
175 base::TimeDelta::FromMicroseconds(++input_pts)); 189 base::TimeDelta::FromMicroseconds(++input_pts));
(...skipping 10 matching lines...) Expand all
186 size_t total_size = 0; 200 size_t total_size = 0;
187 while (!eos) { 201 while (!eos) {
188 size_t unused_offset = 0; 202 size_t unused_offset = 0;
189 size_t size = 0; 203 size_t size = 0;
190 base::TimeDelta timestamp; 204 base::TimeDelta timestamp;
191 int output_buf_index = -1; 205 int output_buf_index = -1;
192 status = media_codec->DequeueOutputBuffer(InfiniteTimeOut(), 206 status = media_codec->DequeueOutputBuffer(InfiniteTimeOut(),
193 &output_buf_index, &unused_offset, 207 &output_buf_index, &unused_offset,
194 &size, &timestamp, &eos, nullptr); 208 &size, &timestamp, &eos, nullptr);
195 switch (status) { 209 switch (status) {
196 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 210 case MEDIA_CODEC_TRY_AGAIN_LATER:
197 FAIL(); 211 FAIL();
198 return; 212 return;
199 213
200 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: 214 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED:
201 continue; 215 continue;
202 216
203 case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: 217 case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
204 continue; 218 continue;
205 219
206 default: 220 default:
207 break; 221 break;
208 } 222 }
209 ASSERT_GE(output_buf_index, 0); 223 ASSERT_GE(output_buf_index, 0);
210 EXPECT_LE(1u, size); 224 EXPECT_LE(1u, size);
211 total_size += size; 225 total_size += size;
212 } 226 }
213 EXPECT_EQ(kDecodedAudioLengthInBytes, total_size); 227 EXPECT_EQ(kDecodedAudioLengthInBytes, total_size);
214 ASSERT_LE(input_pts, kMaxInputPts); 228 ASSERT_LE(input_pts, kMaxInputPts);
215 } 229 }
216 230
217 TEST(MediaCodecBridgeTest, InvalidVorbisHeader) { 231 TEST(MediaCodecBridgeTest, InvalidVorbisHeader) {
218 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE(); 232 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE();
219 233
220 std::unique_ptr<media::AudioCodecBridge> media_codec;
221 media_codec.reset(AudioCodecBridge::Create(kCodecVorbis));
222
223 // The first byte of the header is not 0x02. 234 // The first byte of the header is not 0x02.
224 uint8_t invalid_first_byte[] = {0x00, 0xff, 0xff, 0xff, 0xff}; 235 std::vector<uint8_t> invalid_first_byte = {{0x00, 0xff, 0xff, 0xff, 0xff}};
225 EXPECT_FALSE(media_codec->ConfigureAndStart( 236 ASSERT_THAT(MediaCodecBridgeImpl::CreateAudioDecoder(
226 kCodecVorbis, 44100, 2, invalid_first_byte, sizeof(invalid_first_byte), 0, 237 NewAudioConfig(kCodecVorbis, invalid_first_byte), nullptr),
227 0, nullptr)); 238 IsNull());
228
229 // Size of the header does not match with the data we passed in.
230 uint8_t invalid_size[] = {0x02, 0x01, 0xff, 0x01, 0xff};
231 EXPECT_FALSE(
232 media_codec->ConfigureAndStart(kCodecVorbis, 44100, 2, invalid_size,
233 sizeof(invalid_size), 0, 0, nullptr));
234 239
235 // Size of the header is too large. 240 // Size of the header is too large.
236 size_t large_size = 8 * 1024 * 1024 + 2; 241 size_t large_size = 8 * 1024 * 1024 + 2;
237 uint8_t* very_large_header = new uint8_t[large_size]; 242 std::vector<uint8_t> large_header(large_size, 0xff);
238 very_large_header[0] = 0x02; 243 large_header.front() = 0x02;
239 for (size_t i = 1; i < large_size - 1; ++i) 244 large_header.back() = 0xfe;
240 very_large_header[i] = 0xff; 245 ASSERT_THAT(MediaCodecBridgeImpl::CreateAudioDecoder(
241 very_large_header[large_size - 1] = 0xfe; 246 NewAudioConfig(kCodecVorbis, large_header), nullptr),
242 EXPECT_FALSE(media_codec->ConfigureAndStart( 247 IsNull());
243 kCodecVorbis, 44100, 2, very_large_header, 0x80000000, 0, 0, nullptr));
244 delete[] very_large_header;
245 } 248 }
246 249
247 TEST(MediaCodecBridgeTest, InvalidOpusHeader) { 250 TEST(MediaCodecBridgeTest, InvalidOpusHeader) {
248 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE(); 251 SKIP_TEST_IF_MEDIA_CODEC_IS_NOT_AVAILABLE();
249 252
250 std::unique_ptr<media::AudioCodecBridge> media_codec; 253 std::vector<uint8_t> dummy_extra_data = {{0, 0}};
251 media_codec.reset(AudioCodecBridge::Create(kCodecOpus));
252 if (!media_codec)
253 return;
254
255 uint8_t dummy_extra_data[] = {0, 0};
256
257 // Extra Data is NULL.
258 EXPECT_FALSE(media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, nullptr, 0,
259 -1, 0, nullptr));
260 254
261 // Codec Delay is < 0. 255 // Codec Delay is < 0.
262 EXPECT_FALSE( 256 ASSERT_THAT(
263 media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, dummy_extra_data, 257 MediaCodecBridgeImpl::CreateAudioDecoder(
264 sizeof(dummy_extra_data), -1, 0, nullptr)); 258 NewAudioConfig(kCodecOpus, dummy_extra_data, base::TimeDelta(), -1),
259 nullptr),
260 IsNull());
265 261
266 // Seek Preroll is < 0. 262 // Seek Preroll is < 0.
267 EXPECT_FALSE( 263 ASSERT_THAT(MediaCodecBridgeImpl::CreateAudioDecoder(
268 media_codec->ConfigureAndStart(kCodecOpus, 48000, 2, dummy_extra_data, 264 NewAudioConfig(kCodecOpus, dummy_extra_data,
269 sizeof(dummy_extra_data), 0, -1, nullptr)); 265 base::TimeDelta::FromMicroseconds(-1)),
266 nullptr),
267 IsNull());
270 } 268 }
271 269
272 TEST(MediaCodecBridgeTest, PresentationTimestampsDoNotDecrease) { 270 TEST(MediaCodecBridgeTest, PresentationTimestampsDoNotDecrease) {
273 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED(); 271 if (!MediaCodecUtil::IsVp8DecoderAvailable()) {
272 VLOG(0) << "Could not run test - VP8 not supported on device.";
273 return;
274 }
274 275
275 std::unique_ptr<VideoCodecBridge> media_codec(VideoCodecBridge::CreateDecoder( 276 std::unique_ptr<MediaCodecBridge> media_codec(
276 kCodecVP8, false, gfx::Size(320, 240), nullptr, nullptr, 277 MediaCodecBridgeImpl::CreateVideoDecoder(
277 std::vector<uint8_t>(), std::vector<uint8_t>())); 278 kCodecVP8, false, gfx::Size(320, 240), nullptr, nullptr,
278 EXPECT_TRUE(media_codec.get()); 279 std::vector<uint8_t>(), std::vector<uint8_t>()));
280 ASSERT_THAT(media_codec, NotNull());
279 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vp8-I-frame-320x240"); 281 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("vp8-I-frame-320x240");
280 DecodeMediaFrame(media_codec.get(), buffer->data(), buffer->data_size(), 282 DecodeMediaFrame(media_codec.get(), buffer->data(), buffer->data_size(),
281 base::TimeDelta(), base::TimeDelta()); 283 base::TimeDelta(), base::TimeDelta());
282 284
283 // Simulate a seek to 10 seconds, and each chunk has 2 I-frames. 285 // Simulate a seek to 10 seconds, and each chunk has 2 I-frames.
284 std::vector<uint8_t> chunk(buffer->data(), 286 std::vector<uint8_t> chunk(buffer->data(),
285 buffer->data() + buffer->data_size()); 287 buffer->data() + buffer->data_size());
286 chunk.insert(chunk.end(), buffer->data(), 288 chunk.insert(chunk.end(), buffer->data(),
287 buffer->data() + buffer->data_size()); 289 buffer->data() + buffer->data_size());
288 media_codec->Flush(); 290 media_codec->Flush();
289 DecodeMediaFrame(media_codec.get(), &chunk[0], chunk.size(), 291 DecodeMediaFrame(media_codec.get(), &chunk[0], chunk.size(),
290 base::TimeDelta::FromMicroseconds(10000000), 292 base::TimeDelta::FromMicroseconds(10000000),
291 base::TimeDelta::FromMicroseconds(9900000)); 293 base::TimeDelta::FromMicroseconds(9900000));
292 294
293 // Simulate a seek to 5 seconds. 295 // Simulate a seek to 5 seconds.
294 media_codec->Flush(); 296 media_codec->Flush();
295 DecodeMediaFrame(media_codec.get(), &chunk[0], chunk.size(), 297 DecodeMediaFrame(media_codec.get(), &chunk[0], chunk.size(),
296 base::TimeDelta::FromMicroseconds(5000000), 298 base::TimeDelta::FromMicroseconds(5000000),
297 base::TimeDelta::FromMicroseconds(4900000)); 299 base::TimeDelta::FromMicroseconds(4900000));
298 } 300 }
299 301
300 TEST(MediaCodecBridgeTest, CreateUnsupportedCodec) { 302 TEST(MediaCodecBridgeTest, CreateUnsupportedCodec) {
301 EXPECT_EQ(nullptr, AudioCodecBridge::Create(kUnknownAudioCodec)); 303 EXPECT_THAT(MediaCodecBridgeImpl::CreateAudioDecoder(
302 EXPECT_EQ(nullptr, 304 NewAudioConfig(kUnknownAudioCodec), nullptr),
303 VideoCodecBridge::CreateDecoder( 305 IsNull());
304 kUnknownVideoCodec, false, gfx::Size(320, 240), nullptr, 306 EXPECT_THAT(MediaCodecBridgeImpl::CreateVideoDecoder(
305 nullptr, std::vector<uint8_t>(), std::vector<uint8_t>())); 307 kUnknownVideoCodec, false, gfx::Size(320, 240), nullptr,
308 nullptr, std::vector<uint8_t>(), std::vector<uint8_t>()),
309 IsNull());
306 } 310 }
307 311
308 } // namespace media 312 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_codec_bridge_impl.cc ('k') | media/base/android/media_codec_direction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698