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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/ffmpeg_glue.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/ffmpeg_glue_unittest.cc
diff --git a/media/filters/ffmpeg_glue_unittest.cc b/media/filters/ffmpeg_glue_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d1d2a8312ca711a1cf7d559814b933b3ba300960
--- /dev/null
+++ b/media/filters/ffmpeg_glue_unittest.cc
@@ -0,0 +1,309 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/base/filters.h"
+#include "media/base/mock_media_filters.h"
+#include "media/filters/ffmpeg_common.h"
+#include "media/filters/ffmpeg_glue.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// FFmpeg mocks to remove dependency on having the DLLs present.
+extern "C" {
+static bool g_avcodec_init = false;
+static URLProtocol* g_protocol = NULL;
+static bool g_av_register_all = false;
+
+void avcodec_init() {
+ EXPECT_FALSE(g_avcodec_init);
+ g_avcodec_init = true;
+}
+
+int register_protocol(URLProtocol* protocol) {
+ EXPECT_FALSE(g_protocol);
+ g_protocol = protocol;
+ return 0;
+}
+
+void av_register_all() {
+ EXPECT_FALSE(g_av_register_all);
+ g_av_register_all = true;
+}
+} // extern "C"
+
+TEST(FFmpegGlueTest, InitializeFFmpeg) {
+ // Singleton should initialize FFmpeg.
+ media::FFmpegGlue* glue = media::FFmpegGlue::get();
+ EXPECT_TRUE(glue);
+ EXPECT_TRUE(g_avcodec_init);
+ EXPECT_TRUE(g_protocol);
+ EXPECT_TRUE(g_av_register_all);
+
+ // Make sure URLProtocol was filled out correctly.
+ EXPECT_STREQ("http", g_protocol->name);
+ EXPECT_TRUE(g_protocol->url_close);
+ EXPECT_TRUE(g_protocol->url_open);
+ EXPECT_TRUE(g_protocol->url_read);
+ EXPECT_TRUE(g_protocol->url_seek);
+ EXPECT_TRUE(g_protocol->url_write);
+}
+
+TEST(FFmpegGlueTest, AddRemoveGetDataSource) {
+ // Prepare testing data.
+ media::FFmpegGlue* glue = media::FFmpegGlue::get();
+
+ // Create our data sources and add them to the glue layer.
+ bool deleted_a = false;
+ bool deleted_b = false;
+ media::MockFilterConfig config_a;
+ media::MockFilterConfig config_b;
+ scoped_refptr<media::MockDataSource> data_source_a
+ = new media::MockDataSource(&config_a, &deleted_a);
+ scoped_refptr<media::MockDataSource> data_source_b
+ = new media::MockDataSource(&config_b, &deleted_b);
+
+ // Make sure the keys are unique.
+ std::string key_a = glue->AddDataSource(data_source_a);
+ std::string key_b = glue->AddDataSource(data_source_b);
+ EXPECT_EQ(0, key_a.find("http://"));
+ EXPECT_EQ(0, key_b.find("http://"));
+ EXPECT_NE(key_a, key_b);
+
+ // Our keys should return our data sources.
+ scoped_refptr<media::DataSource> data_source_c;
+ scoped_refptr<media::DataSource> data_source_d;
+ glue->GetDataSource(key_a, &data_source_c);
+ glue->GetDataSource(key_b, &data_source_d);
+ EXPECT_EQ(data_source_a, data_source_c);
+ EXPECT_EQ(data_source_b, data_source_d);
+
+ // Adding the same DataSource should create the same key and not add an extra
+ // reference.
+ std::string key_a2 = glue->AddDataSource(data_source_a);
+ EXPECT_EQ(key_a, key_a2);
+ glue->GetDataSource(key_a2, &data_source_c);
+ EXPECT_EQ(data_source_a, data_source_c);
+
+ // Removes the data sources and then releases our references. They should be
+ // deleted.
+ glue->RemoveDataSource(data_source_a);
+ glue->GetDataSource(key_a, &data_source_c);
+ EXPECT_FALSE(data_source_c);
+ glue->GetDataSource(key_b, &data_source_d);
+ EXPECT_EQ(data_source_b, data_source_d);
+ glue->RemoveDataSource(data_source_b);
+ glue->GetDataSource(key_b, &data_source_d);
+ EXPECT_FALSE(data_source_d);
+ EXPECT_FALSE(deleted_a);
+ EXPECT_FALSE(deleted_b);
+ data_source_a = NULL;
+ data_source_b = NULL;
+ EXPECT_TRUE(deleted_a);
+ EXPECT_TRUE(deleted_b);
+}
+
+TEST(FFmpegGlueTest, OpenClose) {
+ // Prepare testing data.
+ media::FFmpegGlue* glue = media::FFmpegGlue::get();
+
+ // Create our data source and add them to the glue layer.
+ bool deleted = false;
+ media::MockFilterConfig config;
+ scoped_refptr<media::MockDataSource> data_source
+ = new media::MockDataSource(&config, &deleted);
+ std::string key = glue->AddDataSource(data_source);
+
+ // Prepare FFmpeg URLContext structure.
+ URLContext context;
+ memset(&context, 0, sizeof(context));
+
+ // Test opening a URLContext with a data source that doesn't exist.
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_open(&context, "foobar", 0));
+
+ // Test opening a URLContext with our data source.
+ EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0));
+ EXPECT_EQ(URL_RDONLY, context.flags);
+ EXPECT_EQ(data_source, context.priv_data);
+ EXPECT_FALSE(context.is_streamed);
+
+ // Remove the data source from the glue layer, releasing a reference.
+ glue->RemoveDataSource(data_source);
+ EXPECT_FALSE(deleted);
+
+ // Remove our own reference -- URLContext should maintain a reference.
+ data_source = NULL;
+ EXPECT_FALSE(deleted);
+
+ // Close the URLContext, which should release the final reference.
+ EXPECT_EQ(0, g_protocol->url_close(&context));
+ EXPECT_TRUE(deleted);
+}
+
+TEST(FFmpegGlueTest, ReadingWriting) {
+ // Prepare testing data.
+ media::FFmpegGlue* glue = media::FFmpegGlue::get();
+ const size_t kBufferSize = 16;
+ unsigned char buffer[kBufferSize];
+
+ // Configure MockDataSource to be 8 characters long and fill reads with
+ // periods. Therefore our expected string should be a character of 8 periods.
+ const size_t kExpectedSize = 8;
+ media::MockFilterConfig config;
+ config.media_total_bytes = kExpectedSize;
+ config.data_source_value = '.';
+ const char kExpected[] = "........";
+ COMPILE_ASSERT(kExpectedSize == (arraysize(kExpected) - 1), string_length);
+
+ // Create our data source and add them to the glue layer.
+ bool deleted = false;
+ scoped_refptr<media::MockDataSource> data_source
+ = new media::MockDataSource(&config, &deleted);
+ std::string key = glue->AddDataSource(data_source);
+
+ // Open our data source and then remove it from the glue layer.
+ URLContext context;
+ memset(&context, 0, sizeof(context));
+ EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0));
+ glue->RemoveDataSource(data_source);
+ EXPECT_FALSE(deleted);
+
+ // Writing should always fail.
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, NULL, 0));
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, 0));
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, -1));
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_write(&context, buffer, kBufferSize));
+ EXPECT_EQ(0, data_source->position());
+
+ // Reading should return same amount of bytes if <= kExpectedSize.
+ EXPECT_EQ(0, g_protocol->url_read(&context, buffer, 0));
+ EXPECT_EQ(kExpectedSize / 2,
+ g_protocol->url_read(&context, buffer, kExpectedSize / 2));
+ EXPECT_EQ(kExpectedSize,
+ g_protocol->url_read(&context, buffer, kExpectedSize));
+ buffer[kExpectedSize] = '\0';
+ EXPECT_STREQ(kExpected, reinterpret_cast<char*>(buffer));
+
+ // Test reading more than kExpectedSize for simulating EOF.
+ EXPECT_EQ(kExpectedSize, g_protocol->url_read(&context, buffer, kBufferSize));
+ buffer[kExpectedSize] = '\0';
+ EXPECT_STREQ(kExpected, reinterpret_cast<char*>(buffer));
+
+ // Close our data source.
+ EXPECT_EQ(0, g_protocol->url_close(&context));
+ EXPECT_FALSE(deleted);
+
+ // Remove our own reference, which should release the final reference.
+ data_source = NULL;
+ EXPECT_TRUE(deleted);
+}
+
+TEST(FFmpegGlueTest, Seeking) {
+ // Prepare testing data.
+ media::FFmpegGlue* glue = media::FFmpegGlue::get();
+ const int64 kSize = 32;
+
+ // Create our data source and add them to the glue layer.
+ bool deleted = false;
+ media::MockFilterConfig config;
+ config.media_total_bytes = kSize;
+ scoped_refptr<media::MockDataSource> data_source
+ = new media::MockDataSource(&config, &deleted);
+ std::string key = glue->AddDataSource(data_source);
+
+ // Open our data source and then remove it from the glue layer.
+ URLContext context;
+ memset(&context, 0, sizeof(context));
+ EXPECT_EQ(0, g_protocol->url_open(&context, key.c_str(), 0));
+ glue->RemoveDataSource(data_source);
+ EXPECT_FALSE(deleted);
+
+ // Test SEEK_SET operations.
+ config.media_total_bytes = -1;
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_SET));
+
+ config.media_total_bytes = kSize;
+ EXPECT_TRUE(data_source->SetPosition(0));
+ EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_SET));
+ EXPECT_TRUE(data_source->SetPosition(5));
+ EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_SET));
+ EXPECT_EQ(0, data_source->position());
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, -5, SEEK_SET));
+ EXPECT_EQ(0, data_source->position());
+ EXPECT_EQ(kSize, g_protocol->url_seek(&context, kSize, SEEK_SET));
+ EXPECT_EQ(kSize, data_source->position());
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, kSize+1, SEEK_SET));
+ EXPECT_EQ(kSize, data_source->position());
+
+ // Test SEEK_CUR operations.
+ config.media_total_bytes = -1;
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_CUR));
+
+ config.media_total_bytes = kSize;
+ EXPECT_TRUE(data_source->SetPosition(0));
+ EXPECT_EQ(0, g_protocol->url_seek(&context, 0, SEEK_CUR));
+ EXPECT_TRUE(data_source->SetPosition(5));
+ EXPECT_EQ(5, g_protocol->url_seek(&context, 0, SEEK_CUR));
+ EXPECT_EQ(0, g_protocol->url_seek(&context, -5, SEEK_CUR));
+ EXPECT_EQ(0, data_source->position());
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, -1, SEEK_CUR));
+ EXPECT_EQ(kSize, g_protocol->url_seek(&context, kSize, SEEK_CUR));
+ EXPECT_EQ(kSize, data_source->position());
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 1, SEEK_CUR));
+ EXPECT_EQ(kSize, data_source->position());
+
+ // Test SEEK_END operations.
+ config.media_total_bytes = -1;
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, SEEK_END));
+
+ config.media_total_bytes = kSize;
+ EXPECT_TRUE(data_source->SetPosition(0));
+ EXPECT_EQ(kSize, g_protocol->url_seek(&context, 0, SEEK_END));
+ EXPECT_EQ(kSize, data_source->position());
+ EXPECT_EQ(kSize-5, g_protocol->url_seek(&context, -5, SEEK_END));
+ EXPECT_EQ(kSize-5, data_source->position());
+ EXPECT_EQ(0, g_protocol->url_seek(&context, -kSize, SEEK_END));
+ EXPECT_EQ(0, data_source->position());
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 1, SEEK_END));
+ EXPECT_EQ(0, data_source->position());
+
+ // Test AVSEEK_SIZE operation.
+ config.media_total_bytes = -1;
+ EXPECT_EQ(AVERROR_IO, g_protocol->url_seek(&context, 0, AVSEEK_SIZE));
+
+ config.media_total_bytes = kSize;
+ EXPECT_TRUE(data_source->SetPosition(0));
+ EXPECT_EQ(kSize, g_protocol->url_seek(&context, 0, AVSEEK_SIZE));
+
+ // Close our data source.
+ EXPECT_EQ(0, g_protocol->url_close(&context));
+ EXPECT_FALSE(deleted);
+
+ // Remove our own reference, which should release the final reference.
+ data_source = NULL;
+ EXPECT_TRUE(deleted);
+}
+
+TEST(FFmpegGlueTest, Destructor) {
+ // Prepare testing data.
+ media::FFmpegGlue* glue = media::FFmpegGlue::get();
+
+ // We use a static bool since ~FFmpegGlue() will set it to true sometime
+ // after this function exits.
+ static bool deleted = false;
+
+ // Create our data source and add them to the glue layer.
+ media::MockFilterConfig config;
+ scoped_refptr<media::MockDataSource> data_source
+ = new media::MockDataSource(&config, &deleted);
+ std::string key = glue->AddDataSource(data_source);
+
+ // Remove our own reference.
+ data_source = NULL;
+ EXPECT_FALSE(deleted);
+
+ // ~FFmpegGlue() will be called when this unit test finishes execution. By
+ // leaving something inside FFmpegGlue's map we get to test our cleanup code.
+ //
+ // MockDataSource will be holding onto a bad MockFilterConfig pointer at this
+ // point but since no one is calling it everything will be ok.
+}
« 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