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

Side by Side Diff: media/filters/ffmpeg_glue_unittest.cc

Issue 42029: Checking in media::FFmpegGlue, media::FFmpegDemuxer and tests. (Closed)
Patch Set: Created 11 years, 9 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
« no previous file with comments | « media/filters/ffmpeg_glue.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 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.
4
5 #include "media/base/filters.h"
6 #include "media/base/mock_media_filters.h"
7 #include "media/filters/ffmpeg_common.h"
8 #include "media/filters/ffmpeg_glue.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 // FFmpeg mocks to remove dependency on having the DLLs present.
12 extern "C" {
13 static bool g_avcodec_init = false;
14 static URLProtocol* g_protocol = NULL;
15 static bool g_av_register_all = false;
16
17 void avcodec_init() {
18 EXPECT_FALSE(g_avcodec_init);
19 g_avcodec_init = true;
20 }
21
22 int register_protocol(URLProtocol* protocol) {
23 EXPECT_FALSE(g_protocol);
24 g_protocol = protocol;
25 return 0;
26 }
27
28 void av_register_all() {
29 EXPECT_FALSE(g_av_register_all);
30 g_av_register_all = true;
31 }
32 } // extern "C"
33
34 TEST(FFmpegGlueTest, InitializeFFmpeg) {
35 // Singleton should initialize FFmpeg.
36 media::FFmpegGlue* glue = media::FFmpegGlue::get();
37 EXPECT_TRUE(glue);
38 EXPECT_TRUE(g_avcodec_init);
39 EXPECT_TRUE(g_protocol);
40 EXPECT_TRUE(g_av_register_all);
41
42 // Make sure URLProtocol was filled out correctly.
43 EXPECT_STREQ("http", g_protocol->name);
44 EXPECT_TRUE(g_protocol->url_close);
45 EXPECT_TRUE(g_protocol->url_open);
46 EXPECT_TRUE(g_protocol->url_read);
47 EXPECT_TRUE(g_protocol->url_seek);
48 EXPECT_TRUE(g_protocol->url_write);
49 }
50
51 TEST(FFmpegGlueTest, AddRemoveGetDataSource) {
52 // Prepare testing data.
53 media::FFmpegGlue* glue = media::FFmpegGlue::get();
54
55 // Create our data sources and add them to the glue layer.
56 bool deleted_a = false;
57 bool deleted_b = false;
58 media::MockFilterConfig config_a;
59 media::MockFilterConfig config_b;
60 scoped_refptr<media::MockDataSource> data_source_a
61 = new media::MockDataSource(&config_a, &deleted_a);
62 scoped_refptr<media::MockDataSource> data_source_b
63 = new media::MockDataSource(&config_b, &deleted_b);
64
65 // Make sure the keys are unique.
66 std::string key_a = glue->AddDataSource(data_source_a);
67 std::string key_b = glue->AddDataSource(data_source_b);
68 EXPECT_EQ(0, key_a.find("http://"));
69 EXPECT_EQ(0, key_b.find("http://"));
70 EXPECT_NE(key_a, key_b);
71
72 // Our keys should return our data sources.
73 scoped_refptr<media::DataSource> data_source_c;
74 scoped_refptr<media::DataSource> data_source_d;
75 glue->GetDataSource(key_a, &data_source_c);
76 glue->GetDataSource(key_b, &data_source_d);
77 EXPECT_EQ(data_source_a, data_source_c);
78 EXPECT_EQ(data_source_b, data_source_d);
79
80 // Adding the same DataSource should create the same key and not add an extra
81 // reference.
82 std::string key_a2 = glue->AddDataSource(data_source_a);
83 EXPECT_EQ(key_a, key_a2);
84 glue->GetDataSource(key_a2, &data_source_c);
85 EXPECT_EQ(data_source_a, data_source_c);
86
87 // Removes the data sources and then releases our references. They should be
88 // deleted.
89 glue->RemoveDataSource(data_source_a);
90 glue->GetDataSource(key_a, &data_source_c);
91 EXPECT_FALSE(data_source_c);
92 glue->GetDataSource(key_b, &data_source_d);
93 EXPECT_EQ(data_source_b, data_source_d);
94 glue->RemoveDataSource(data_source_b);
95 glue->GetDataSource(key_b, &data_source_d);
96 EXPECT_FALSE(data_source_d);
97 EXPECT_FALSE(deleted_a);
98 EXPECT_FALSE(deleted_b);
99 data_source_a = NULL;
100 data_source_b = NULL;
101 EXPECT_TRUE(deleted_a);
102 EXPECT_TRUE(deleted_b);
103 }
104
105 TEST(FFmpegGlueTest, OpenClose) {
106 // Prepare testing data.
107 media::FFmpegGlue* glue = media::FFmpegGlue::get();
108
109 // Create our data source and add them to the glue layer.
110 bool deleted = false;
111 media::MockFilterConfig config;
112 scoped_refptr<media::MockDataSource> data_source
113 = new media::MockDataSource(&config, &deleted);
114 std::string key = glue->AddDataSource(data_source);
115
116 // Prepare FFmpeg URLContext structure.
117 URLContext context;
118 memset(&context, 0, sizeof(context));
119
120 // Test opening a URLContext with a data source that doesn't exist.
121 EXPECT_EQ(AVERROR_IO, g_protocol->url_open(&context, "foobar", 0));
122
123 // Test opening a URLContext with our data source.
124 EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0));
125 EXPECT_EQ(URL_RDONLY, context.flags);
126 EXPECT_EQ(data_source, context.priv_data);
127 EXPECT_FALSE(context.is_streamed);
128
129 // Remove the data source from the glue layer, releasing a reference.
130 glue->RemoveDataSource(data_source);
131 EXPECT_FALSE(deleted);
132
133 // Remove our own reference -- URLContext should maintain a reference.
134 data_source = NULL;
135 EXPECT_FALSE(deleted);
136
137 // Close the URLContext, which should release the final reference.
138 EXPECT_EQ(0, g_protocol->url_close(&context));
139 EXPECT_TRUE(deleted);
140 }
141
142 TEST(FFmpegGlueTest, ReadingWriting) {
143 // Prepare testing data.
144 media::FFmpegGlue* glue = media::FFmpegGlue::get();
145 const size_t kBufferSize = 16;
146 unsigned char buffer[kBufferSize];
147
148 // Configure MockDataSource to be 8 characters long and fill reads with
149 // periods. Therefore our expected string should be a character of 8 periods.
150 const size_t kExpectedSize = 8;
151 media::MockFilterConfig config;
152 config.media_total_bytes = kExpectedSize;
153 config.data_source_value = '.';
154 const char kExpected[] = "........";
155 COMPILE_ASSERT(kExpectedSize == (arraysize(kExpected) - 1), string_length);
156
157 // Create our data source and add them to the glue layer.
158 bool deleted = false;
159 scoped_refptr<media::MockDataSource> data_source
160 = new media::MockDataSource(&config, &deleted);
161 std::string key = glue->AddDataSource(data_source);
162
163 // Open our data source and then remove it from the glue layer.
164 URLContext context;
165 memset(&context, 0, sizeof(context));
166 EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0));
167 glue->RemoveDataSource(data_source);
168 EXPECT_FALSE(deleted);
169
170 // Writing should always fail.
171 EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, NULL, 0));
172 EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, 0));
173 EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, -1));
174 EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, kBufferSize));
175 EXPECT_EQ(0, data_source->position());
176
177 // Reading should return same amount of bytes if <= kExpectedSize.
178 EXPECT_EQ(0, g_protocol->url_read(&context, buffer, 0));
179 EXPECT_EQ(kExpectedSize / 2,
180 g_protocol->url_read(&context, buffer, kExpectedSize / 2));
181 EXPECT_EQ(kExpectedSize,
182 g_protocol->url_read(&context, buffer, kExpectedSize));
183 buffer[kExpectedSize] = '\0';
184 EXPECT_STREQ(kExpected, reinterpret_cast<char*>(buffer));
185
186 // Test reading more than kExpectedSize for simulating EOF.
187 EXPECT_EQ(kExpectedSize, g_protocol->url_read(&context, buffer, kBufferSize));
188 buffer[kExpectedSize] = '\0';
189 EXPECT_STREQ(kExpected, reinterpret_cast<char*>(buffer));
190
191 // Close our data source.
192 EXPECT_EQ(0, g_protocol->url_close(&context));
193 EXPECT_FALSE(deleted);
194
195 // Remove our own reference, which should release the final reference.
196 data_source = NULL;
197 EXPECT_TRUE(deleted);
198 }
199
200 TEST(FFmpegGlueTest, Seeking) {
201 // Prepare testing data.
202 media::FFmpegGlue* glue = media::FFmpegGlue::get();
203 const int64 kSize = 32;
204
205 // Create our data source and add them to the glue layer.
206 bool deleted = false;
207 media::MockFilterConfig config;
208 config.media_total_bytes = kSize;
209 scoped_refptr<media::MockDataSource> data_source
210 = new media::MockDataSource(&config, &deleted);
211 std::string key = glue->AddDataSource(data_source);
212
213 // Open our data source and then remove it from the glue layer.
214 URLContext context;
215 memset(&context, 0, sizeof(context));
216 EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0));
217 glue->RemoveDataSource(data_source);
218 EXPECT_FALSE(deleted);
219
220 // Test SEEK_SET operations.
221 config.media_total_bytes = -1;
222 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_SET));
223
224 config.media_total_bytes = kSize;
225 EXPECT_TRUE(data_source->SetPosition(0));
226 EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_SET));
227 EXPECT_TRUE(data_source->SetPosition(5));
228 EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_SET));
229 EXPECT_EQ(0, data_source->position());
230 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, -5, SEEK_SET));
231 EXPECT_EQ(0, data_source->position());
232 EXPECT_EQ(kSize, g_protocol->url_seek(&context, kSize, SEEK_SET));
233 EXPECT_EQ(kSize, data_source->position());
234 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, kSize+1, SEEK_SET));
235 EXPECT_EQ(kSize, data_source->position());
236
237 // Test SEEK_CUR operations.
238 config.media_total_bytes = -1;
239 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_CUR));
240
241 config.media_total_bytes = kSize;
242 EXPECT_TRUE(data_source->SetPosition(0));
243 EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_CUR));
244 EXPECT_TRUE(data_source->SetPosition(5));
245 EXPECT_EQ(5, g_protocol->url_seek(&context, 0, SEEK_CUR));
246 EXPECT_EQ(0, g_protocol->url_seek(&context, -5, SEEK_CUR));
247 EXPECT_EQ(0, data_source->position());
248 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, -1, SEEK_CUR));
249 EXPECT_EQ(kSize, g_protocol->url_seek(&context, kSize, SEEK_CUR));
250 EXPECT_EQ(kSize, data_source->position());
251 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 1, SEEK_CUR));
252 EXPECT_EQ(kSize, data_source->position());
253
254 // Test SEEK_END operations.
255 config.media_total_bytes = -1;
256 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_END));
257
258 config.media_total_bytes = kSize;
259 EXPECT_TRUE(data_source->SetPosition(0));
260 EXPECT_EQ(kSize, g_protocol->url_seek(&context, 0, SEEK_END));
261 EXPECT_EQ(kSize, data_source->position());
262 EXPECT_EQ(kSize-5, g_protocol->url_seek(&context, -5, SEEK_END));
263 EXPECT_EQ(kSize-5, data_source->position());
264 EXPECT_EQ(0, g_protocol->url_seek(&context, -kSize, SEEK_END));
265 EXPECT_EQ(0, data_source->position());
266 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 1, SEEK_END));
267 EXPECT_EQ(0, data_source->position());
268
269 // Test AVSEEK_SIZE operation.
270 config.media_total_bytes = -1;
271 EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, AVSEEK_SIZE));
272
273 config.media_total_bytes = kSize;
274 EXPECT_TRUE(data_source->SetPosition(0));
275 EXPECT_EQ(kSize, g_protocol->url_seek(&context, 0, AVSEEK_SIZE));
276
277 // Close our data source.
278 EXPECT_EQ(0, g_protocol->url_close(&context));
279 EXPECT_FALSE(deleted);
280
281 // Remove our own reference, which should release the final reference.
282 data_source = NULL;
283 EXPECT_TRUE(deleted);
284 }
285
286 TEST(FFmpegGlueTest, Destructor) {
287 // Prepare testing data.
288 media::FFmpegGlue* glue = media::FFmpegGlue::get();
289
290 // We use a static bool since ~FFmpegGlue() will set it to true sometime
291 // after this function exits.
292 static bool deleted = false;
293
294 // Create our data source and add them to the glue layer.
295 media::MockFilterConfig config;
296 scoped_refptr<media::MockDataSource> data_source
297 = new media::MockDataSource(&config, &deleted);
298 std::string key = glue->AddDataSource(data_source);
299
300 // Remove our own reference.
301 data_source = NULL;
302 EXPECT_FALSE(deleted);
303
304 // ~FFmpegGlue() will be called when this unit test finishes execution. By
305 // leaving something inside FFmpegGlue's map we get to test our cleanup code.
306 //
307 // MockDataSource will be holding onto a bad MockFilterConfig pointer at this
308 // point but since no one is calling it everything will be ok.
309 }
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_glue.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698