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

Unified Diff: media/filters/ffmpeg_glue.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.h ('k') | media/filters/ffmpeg_glue_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/ffmpeg_glue.cc
diff --git a/media/filters/ffmpeg_glue.cc b/media/filters/ffmpeg_glue.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0d3957b527b5211c22e27cb1757189b1df970083
--- /dev/null
+++ b/media/filters/ffmpeg_glue.cc
@@ -0,0 +1,162 @@
+// 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 "base/string_util.h"
+#include "media/base/filters.h"
+#include "media/filters/ffmpeg_common.h"
+#include "media/filters/ffmpeg_glue.h"
+
+namespace {
+
+// FFmpeg protocol interface.
+int OpenContext(URLContext* h, const char* filename, int flags) {
+ scoped_refptr<media::DataSource> data_source;
+ media::FFmpegGlue::get()->GetDataSource(filename, &data_source);
+ if (!data_source)
+ return AVERROR_IO;
+
+ data_source->AddRef();
+ h->priv_data = data_source;
+ h->flags = URL_RDONLY;
+ // TODO(scherkus): data source should be able to tell us if we're streaming.
+ h->is_streamed = FALSE;
+ return 0;
+}
+
+int ReadContext(URLContext* h, unsigned char* buf, int size) {
+ media::DataSource* data_source =
+ reinterpret_cast<media::DataSource*>(h->priv_data);
+ int result = data_source->Read(buf, size);
+ if (result < 0)
+ result = AVERROR_IO;
+ return result;
+}
+
+int WriteContext(URLContext* h, unsigned char* buf, int size) {
+ // We don't support writing.
+ return AVERROR_IO;
+}
+
+offset_t SeekContext(URLContext* h, offset_t offset, int whence) {
+ media::DataSource* data_source =
+ reinterpret_cast<media::DataSource*>(h->priv_data);
+ offset_t new_offset = AVERROR_IO;
+ switch (whence) {
+ case SEEK_SET:
+ if (data_source->SetPosition(offset))
+ data_source->GetPosition(&new_offset);
+ break;
+
+ case SEEK_CUR:
+ int64 pos;
+ if (!data_source->GetPosition(&pos))
+ break;
+ if (data_source->SetPosition(pos + offset))
+ data_source->GetPosition(&new_offset);
+ break;
+
+ case SEEK_END:
+ int64 size;
+ if (!data_source->GetSize(&size))
+ break;
+ if (data_source->SetPosition(size + offset))
+ data_source->GetPosition(&new_offset);
+ break;
+
+ case AVSEEK_SIZE:
+ data_source->GetSize(&new_offset);
+ break;
+
+ default:
+ NOTREACHED();
+ }
+ if (new_offset < 0)
+ new_offset = AVERROR_IO;
+ return new_offset;
+}
+
+int CloseContext(URLContext* h) {
+ media::DataSource* data_source =
+ reinterpret_cast<media::DataSource*>(h->priv_data);
+ data_source->Release();
+ h->priv_data = NULL;
+ return 0;
+}
+
+} // namespace
+
+//------------------------------------------------------------------------------
+
+namespace media {
+
+// Use the HTTP protocol to avoid any file path separator issues.
+static const char kProtocol[] = "http";
+
+// Fill out our FFmpeg protocol definition.
+static URLProtocol kFFmpegProtocol = {
+ kProtocol,
+ &OpenContext,
+ &ReadContext,
+ &WriteContext,
+ &SeekContext,
+ &CloseContext,
+};
+
+FFmpegGlue::FFmpegGlue() {
+ // Register our protocol glue code with FFmpeg.
+ avcodec_init();
+ register_protocol(&kFFmpegProtocol);
+
+ // Now register the rest of FFmpeg.
+ av_register_all();
+}
+
+FFmpegGlue::~FFmpegGlue() {
+ DataSourceMap::iterator iter = data_sources_.begin();
+ while (iter != data_sources_.end()) {
+ DataSource* data_source = iter->second;
+ iter = data_sources_.erase(iter);
+ }
+}
+
+std::string FFmpegGlue::AddDataSource(DataSource* data_source) {
+ AutoLock auto_lock(lock_);
+ std::string key = GetDataSourceKey(data_source);
+ if (data_sources_.find(key) == data_sources_.end()) {
+ data_sources_[key] = data_source;
+ }
+ return key;
+}
+
+void FFmpegGlue::RemoveDataSource(DataSource* data_source) {
+ AutoLock auto_lock(lock_);
+ DataSourceMap::iterator iter = data_sources_.begin();
+ while (iter != data_sources_.end()) {
+ if (iter->second == data_source) {
+ iter = data_sources_.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+}
+
+void FFmpegGlue::GetDataSource(const std::string& key,
+ scoped_refptr<DataSource>* data_source) {
+ AutoLock auto_lock(lock_);
+ DataSourceMap::iterator iter = data_sources_.find(key);
+ if (iter == data_sources_.end()) {
+ *data_source = NULL;
+ return;
+ }
+ *data_source = iter->second;
+}
+
+std::string FFmpegGlue::GetDataSourceKey(DataSource* data_source) {
+ // Use the DataSource's memory address to generate the unique string. This
+ // also has the nice property that adding the same DataSource reference will
+ // not generate duplicate entries.
+ return StringPrintf("%s://0x%lx", kProtocol, static_cast<void*>(data_source));
+}
+
+} // namespace media
« no previous file with comments | « media/filters/ffmpeg_glue.h ('k') | media/filters/ffmpeg_glue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698