Chromium Code Reviews| Index: media/base/media_win.cc |
| =================================================================== |
| --- media/base/media_win.cc (revision 122285) |
| +++ media/base/media_win.cc (working copy) |
| @@ -5,6 +5,7 @@ |
| #include "media/base/media.h" |
| #include <windows.h> |
| +#include <delayimp.h> |
| #include "base/file_path.h" |
| #include "base/logging.h" |
| @@ -12,6 +13,8 @@ |
| #include "base/native_library.h" |
| #include "base/path_service.h" |
| +#pragma comment(lib, "delayimp.lib") |
| + |
| namespace media { |
| enum FFmpegDLLKeys { |
| @@ -21,18 +24,18 @@ |
| }; |
| // Retrieves the DLLName for the given key. |
| -static FilePath::CharType* GetDLLName(FFmpegDLLKeys dll_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 FILE_PATH_LITERAL("avcodec-53.dll"); |
| + return "avcodec-53.dll"; |
| case FILE_LIBAVFORMAT: |
| - return FILE_PATH_LITERAL("avformat-53.dll"); |
| + return "avformat-53.dll"; |
| case FILE_LIBAVUTIL: |
| - return FILE_PATH_LITERAL("avutil-51.dll"); |
| + return "avutil-51.dll"; |
| default: |
| LOG(DFATAL) << "Invalid DLL key requested: " << dll_key; |
| - return FILE_PATH_LITERAL(""); |
| + return ""; |
| } |
| } |
| @@ -44,6 +47,11 @@ |
| if (g_media_library_is_initialized) |
| return true; |
| + // 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, |
| @@ -52,12 +60,12 @@ |
| HMODULE libs[arraysize(path_keys)] = {NULL}; |
| for (size_t i = 0; i < arraysize(path_keys); ++i) { |
| - FilePath path = base_path.Append(GetDLLName(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); |
| + libs[i] = ::LoadLibraryEx(cpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| if (!libs[i]) |
| break; |
| } |
| @@ -65,17 +73,39 @@ |
| // 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. |
| - g_media_library_is_initialized = (libs[arraysize(libs) - 1] != NULL); |
| + bool media_library_is_initialized = (libs[arraysize(libs) - 1] != NULL); |
| - if (!g_media_library_is_initialized) { |
| + 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; |
| } |
| - return g_media_library_is_initialized; |
| + // Workaround for http://crbug.com/110983 |
|
rvargas (doing something else)
2012/02/27 19:23:40
nit: There should be a TODO to remove this code wh
|
| + // 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. |
| + for (size_t i = 0; i < arraysize(path_keys); ++i) { |
| + if (FAILED(::__HrLoadAllImportsForDll(GetDLLName(path_keys[i])))) |
| + media_library_is_initialized = false; |
| + } |
| + |
| + g_media_library_is_initialized = media_library_is_initialized; |
| + return media_library_is_initialized; |
| } |
| void InitializeMediaLibraryForTesting() { |