forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Checking in media::FFmpegGlue and some common FFmpeg code.
FFmpegGlue acts as an adapter between FFmpeg's URLProtocol and the media::DataSource interface, allowing us to use media::DataSource implementations for handling FFmpeg's IO. Review URL: http://codereview.chromium.org/28165 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11345 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
scherkus@chromium.org
committed
Mar 10, 2009
1 parent
dafd23c
commit 048539b
Showing
9 changed files
with
656 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
include_rules = [ | ||
"+third_party/ffmpeg/include", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// 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/filters/ffmpeg_common.h" | ||
|
||
namespace media { | ||
|
||
const char kFFmpegCodecID[] = "FFmpegCodecID"; | ||
|
||
namespace mime_type { | ||
|
||
const char kFFmpegAudio[] = "audio/x-ffmpeg"; | ||
const char kFFmpegVideo[] = "video/x-ffmpeg"; | ||
|
||
} // namespace mime_type | ||
|
||
} // namespace media |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// 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. | ||
|
||
// Used for FFmpeg error codes. | ||
#include <cerrno> | ||
|
||
#include "base/compiler_specific.h" | ||
|
||
// Include FFmpeg header files. | ||
extern "C" { | ||
// Temporarily disable possible loss of data warning. | ||
// TODO(scherkus): fix and upstream the compiler warnings. | ||
MSVC_PUSH_DISABLE_WARNING(4244); | ||
#include "third_party/ffmpeg/include/libavcodec/avcodec.h" | ||
#include "third_party/ffmpeg/include/libavformat/avformat.h" | ||
MSVC_POP_WARNING(); | ||
} // extern "C" | ||
|
||
namespace media { | ||
|
||
// MediaFormat key identifying the CodecID. | ||
extern const char kFFmpegCodecID[]; | ||
|
||
// FFmpeg MIME types. | ||
namespace mime_type { | ||
|
||
extern const char kFFmpegAudio[]; | ||
extern const char kFFmpegVideo[]; | ||
|
||
} // namespace mime_type | ||
|
||
} // namespace media |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.