diff options
author | dalecurtis@google.com <dalecurtis@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-21 22:20:04 +0000 |
---|---|---|
committer | dalecurtis@google.com <dalecurtis@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-21 22:20:04 +0000 |
commit | 243d52e3d20fbd72d5fdb9cb0a57dccf10600742 (patch) | |
tree | 7f545abe0006fb7ecfa9e50b4ce9ff7737950998 /media | |
parent | c9def35e9f827c073ccd217bab9bc2398b8a0c38 (diff) | |
download | chromium_src-243d52e3d20fbd72d5fdb9cb0a57dccf10600742.zip chromium_src-243d52e3d20fbd72d5fdb9cb0a57dccf10600742.tar.gz chromium_src-243d52e3d20fbd72d5fdb9cb0a57dccf10600742.tar.bz2 |
Using Ronald's libclang based converter, we're able to translate
ffmpeg from C99 to C89 syntax and compile through MSVC++! This is
awesome for many reasons:
- Better performance! MSVC compiled code is as fast as some of the
hand rolled assembly in certain cases (per rbultje).
- Debugging symbols! (!!!) Crash dumps will now be symbolized with
all symbols instead of the missing symbols traces we get in crash
reports today.
- No more hand rolling binaries every time ffmpeg needs a security
fix or someone wants to make a change!
- Greatly reduced binary size, the Chrome DLLs are ~3.2mb smaller
and the Chromium DLLs ~2.3mb smaller: Chrome: 5205049 -> 1817600,
Chromium: 3587185 -> 1147904.
This change also cleans up the media library initialization code
and gets rid of the old dll names in various places. There is
still one other locations which need to be updated separately:
http://src.chromium.org/viewvc/chrome/trunk/tools/build/site_config/config.py
The downside is this will add ~3minutes of compile time (on T3500)
for non-GOMA users and ~30 seconds for GOMA users (-j 256).
More information available here:
https://gerrit.chromium.org/gerrit/#/c/34728/
BUG=39887
TEST=Manual testing. Unit tests. It actually compiles!
Review URL: https://codereview.chromium.org/11036039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163213 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/media_posix.cc | 71 | ||||
-rw-r--r-- | media/base/media_win.cc | 102 |
2 files changed, 51 insertions, 122 deletions
diff --git a/media/base/media_posix.cc b/media/base/media_posix.cc index 7028ae2..ff50287 100644 --- a/media/base/media_posix.cc +++ b/media/base/media_posix.cc @@ -6,17 +6,17 @@ #include <string> -#include <dlfcn.h> - #include "base/file_path.h" #include "base/logging.h" -#include "base/native_library.h" #include "base/path_service.h" #include "base/stringize_macros.h" #include "media/ffmpeg/ffmpeg_common.h" #include "third_party/ffmpeg/ffmpeg_stubs.h" -namespace tp_ffmpeg = third_party_ffmpeg; +using third_party_ffmpeg::kNumStubModules; +using third_party_ffmpeg::kModuleFfmpegsumo; +using third_party_ffmpeg::InitializeStubs; +using third_party_ffmpeg::StubPathMap; namespace media { @@ -34,60 +34,49 @@ namespace media { #if defined(OS_MACOSX) // TODO(evan): should be using .so like ffmepgsumo here. #define DSO_NAME(MODULE, VERSION) ("lib" MODULE "." VERSION ".dylib") -static const FilePath::CharType sumo_name[] = +static const FilePath::CharType kSumoLib[] = FILE_PATH_LITERAL("ffmpegsumo.so"); #elif defined(OS_POSIX) #define DSO_NAME(MODULE, VERSION) ("lib" MODULE ".so." VERSION) -static const FilePath::CharType sumo_name[] = +static const FilePath::CharType kSumoLib[] = FILE_PATH_LITERAL("libffmpegsumo.so"); #else #error "Do not know how to construct DSO name for this OS." #endif -static const FilePath::CharType openmax_name[] = - FILE_PATH_LITERAL("libOmxCore.so"); - -// Retrieves the DSOName for the given key. -static std::string GetDSOName(tp_ffmpeg::StubModules stub_key) { - // TODO(ajwong): Remove this once mac is migrated. Either that, or have GYP - // set a constant that we can switch implementations based off of. - switch (stub_key) { - case tp_ffmpeg::kModuleAvcodec54: - return FILE_PATH_LITERAL(DSO_NAME("avcodec", AVCODEC_VERSION)); - case tp_ffmpeg::kModuleAvformat54: - return FILE_PATH_LITERAL(DSO_NAME("avformat", AVFORMAT_VERSION)); - case tp_ffmpeg::kModuleAvutil51: - return FILE_PATH_LITERAL(DSO_NAME("avutil", AVUTIL_VERSION)); - default: - LOG(DFATAL) << "Invalid stub module requested: " << stub_key; - return FILE_PATH_LITERAL(""); - } -} +// Use a global to indicate whether the library has been initialized or not. We +// rely on function level static initialization in InitializeMediaLibrary() to +// guarantee this is only set once in a thread safe manner. static bool g_media_library_is_initialized = false; -// Attempts to initialize the media library (loading DSOs, etc.). -// Returns true if everything was successfully initialized, false otherwise. -bool InitializeMediaLibrary(const FilePath& module_dir) { - if (g_media_library_is_initialized) - return true; +static bool InitializeMediaLibraryInternal(const FilePath& module_dir) { + DCHECK(!g_media_library_is_initialized); - // TODO(ajwong): We need error resolution. - tp_ffmpeg::StubPathMap paths; - for (int i = 0; i < static_cast<int>(tp_ffmpeg::kNumStubModules); ++i) { - tp_ffmpeg::StubModules module = static_cast<tp_ffmpeg::StubModules>(i); + StubPathMap paths; - // Add the sumo library first so it takes precedence. - paths[module].push_back(module_dir.Append(sumo_name).value()); + // First try to initialize with Chrome's sumo library. + DCHECK_EQ(kNumStubModules, 1); + paths[kModuleFfmpegsumo].push_back(module_dir.Append(kSumoLib).value()); - // Add the more specific FFmpeg library name. - FilePath path = module_dir.Append(GetDSOName(module)); - paths[module].push_back(path.value()); - } + // If that fails, see if any system libraries are available. + paths[kModuleFfmpegsumo].push_back(module_dir.Append( + FILE_PATH_LITERAL(DSO_NAME("avutil", AVUTIL_VERSION))).value()); + paths[kModuleFfmpegsumo].push_back(module_dir.Append( + FILE_PATH_LITERAL(DSO_NAME("avcodec", AVCODEC_VERSION))).value()); + paths[kModuleFfmpegsumo].push_back(module_dir.Append( + FILE_PATH_LITERAL(DSO_NAME("avformat", AVFORMAT_VERSION))).value()); - g_media_library_is_initialized = tp_ffmpeg::InitializeStubs(paths); + g_media_library_is_initialized = InitializeStubs(paths); return g_media_library_is_initialized; } +bool InitializeMediaLibrary(const FilePath& base_path) { + static const bool kMediaLibraryInitialized = + InitializeMediaLibraryInternal(base_path); + DCHECK_EQ(kMediaLibraryInitialized, g_media_library_is_initialized); + return kMediaLibraryInitialized; +} + void InitializeMediaLibraryForTesting() { FilePath file_path; CHECK(PathService::Get(base::DIR_EXE, &file_path)); diff --git a/media/base/media_win.cc b/media/base/media_win.cc index f0f78ab..616d370 100644 --- a/media/base/media_win.cc +++ b/media/base/media_win.cc @@ -13,7 +13,6 @@ #include "base/file_path.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "base/native_library.h" #include "base/path_service.h" @@ -21,97 +20,38 @@ namespace media { -enum FFmpegDLLKeys { - FILE_LIBAVCODEC, // full path to libavcodec media decoding library. - FILE_LIBAVFORMAT, // full path to libavformat media parsing library. - FILE_LIBAVUTIL, // full path to libavutil media utility library. -}; - -// Retrieves the DLLName for the given key. -static const char* GetDLLName(FFmpegDLLKeys dll_key) { - // TODO(ajwong): Do we want to lock to a specific ffmpeg version? - switch (dll_key) { - case FILE_LIBAVCODEC: - return "avcodec-54.dll"; - case FILE_LIBAVFORMAT: - return "avformat-54.dll"; - case FILE_LIBAVUTIL: - return "avutil-51.dll"; - default: - LOG(DFATAL) << "Invalid DLL key requested: " << dll_key; - return ""; - } -} +// FFmpeg library name. +static const char* kFFmpegDLL = "ffmpegsumo.dll"; +// Use a global to indicate whether the library has been initialized or not. We +// rely on function level static initialization in InitializeMediaLibrary() to +// guarantee this is only set once in a thread safe manner. static bool g_media_library_is_initialized = false; -// Attempts to initialize the media library (loading DLLs, DSOs, etc.). -// Returns true if everything was successfully initialized, false otherwise. -bool InitializeMediaLibrary(const FilePath& base_path) { - if (g_media_library_is_initialized) - return true; +static bool InitializeMediaLibraryInternal(const FilePath& base_path) { + DCHECK(!g_media_library_is_initialized); // LoadLibraryEx(..., LOAD_WITH_ALTERED_SEARCH_PATH) cannot handle // relative path. if (!base_path.IsAbsolute()) return false; - FFmpegDLLKeys path_keys[] = { - media::FILE_LIBAVCODEC, - media::FILE_LIBAVFORMAT, - media::FILE_LIBAVUTIL - }; - HMODULE libs[arraysize(path_keys)] = {NULL}; - - for (size_t i = 0; i < arraysize(path_keys); ++i) { - FilePath path = base_path.AppendASCII(GetDLLName(path_keys[i])); - - // Use alternate DLL search path so we don't load dependencies from the - // system path. Refer to http://crbug.com/35857 - const wchar_t* cpath = path.value().c_str(); - libs[i] = ::LoadLibraryEx(cpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - if (!libs[i]) - break; - } - - // Check that we loaded all libraries successfully. We only need to check the - // last array element because the loop above will break without initializing - // it on any prior error. - bool media_library_is_initialized = (libs[arraysize(libs) - 1] != NULL); + // Use alternate DLL search path so we don't load dependencies from the + // system path. Refer to http://crbug.com/35857 + HMODULE lib = ::LoadLibraryEx( + base_path.AppendASCII(kFFmpegDLL).value().c_str(), NULL, + LOAD_WITH_ALTERED_SEARCH_PATH); - if (!media_library_is_initialized) { - // Free any loaded libraries if we weren't successful. - for (size_t i = 0; i < arraysize(libs) && libs[i] != NULL; ++i) { - FreeLibrary(libs[i]); - libs[i] = NULL; // Just to be safe. - } - return false; - } - - // Workaround for http://crbug.com/110983 - // LoadLibrary() sometimes AV's when called by delay load helper when we - // call function in ffmpeg for the first time, and we don't know why. - // Force delay load helper to fix import table here instead. - // Theoretically, there is no need to call LoadLibrary() before - // __HrLoadAllImportsForDll(), it will call LoadLibrary() itself, but there - // is no way to specify LOAD_WITH_ALTERED_SEARCH_PATH when calling - // __HrLoadAllImportsForDll(). So we do everything in 2 steps -- first call - // LoadLibraryEx(..., LOAD_WITH_ALTERED_SEARCH_PATH), then call - // __HrLoadAllImportsForDll(). Overhead is negligible compared to disk - // access time. - // Note: in case of error we are not unloading DLL because unload requires - // extra resources and should not be necessary; if we ever decide to - // unload by calling __FUnloadDelayLoadedDLL() please add /DELAY:UNLOAD - // to the linker command line. - // TODO(enal): remove that code when we find underlying issue. Delay load - // should work if library is alreday in memory, regardless of permissions... - for (size_t i = 0; i < arraysize(path_keys); ++i) { - if (FAILED(::__HrLoadAllImportsForDll(GetDLLName(path_keys[i])))) - media_library_is_initialized = false; - } + // Check that we loaded the library successfully. + g_media_library_is_initialized = (lib != NULL); + return g_media_library_is_initialized; +} - g_media_library_is_initialized = media_library_is_initialized; - return media_library_is_initialized; +bool InitializeMediaLibrary(const FilePath& base_path) { + static const bool kMediaLibraryInitialized = + InitializeMediaLibraryInternal(base_path); + DCHECK_EQ(kMediaLibraryInitialized, g_media_library_is_initialized); + return kMediaLibraryInitialized; } void InitializeMediaLibraryForTesting() { |