OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/media.h" | 5 #include "media/base/media.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <delayimp.h> | |
8 | 9 |
9 #include "base/file_path.h" | 10 #include "base/file_path.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
12 #include "base/native_library.h" | 13 #include "base/native_library.h" |
13 #include "base/path_service.h" | 14 #include "base/path_service.h" |
14 | 15 |
16 #pragma comment(lib, "delayimp.lib") | |
17 | |
15 namespace media { | 18 namespace media { |
16 | 19 |
17 enum FFmpegDLLKeys { | 20 enum FFmpegDLLKeys { |
18 FILE_LIBAVCODEC, // full path to libavcodec media decoding library. | 21 FILE_LIBAVCODEC, // full path to libavcodec media decoding library. |
19 FILE_LIBAVFORMAT, // full path to libavformat media parsing library. | 22 FILE_LIBAVFORMAT, // full path to libavformat media parsing library. |
20 FILE_LIBAVUTIL, // full path to libavutil media utility library. | 23 FILE_LIBAVUTIL, // full path to libavutil media utility library. |
21 }; | 24 }; |
22 | 25 |
23 // Retrieves the DLLName for the given key. | 26 // Retrieves the DLLName for the given key. |
24 static FilePath::CharType* GetDLLName(FFmpegDLLKeys dll_key) { | 27 static const char* GetDLLName(FFmpegDLLKeys dll_key) { |
25 // TODO(ajwong): Do we want to lock to a specific ffmpeg version? | 28 // TODO(ajwong): Do we want to lock to a specific ffmpeg version? |
26 switch (dll_key) { | 29 switch (dll_key) { |
27 case FILE_LIBAVCODEC: | 30 case FILE_LIBAVCODEC: |
28 return FILE_PATH_LITERAL("avcodec-53.dll"); | 31 return "avcodec-53.dll"; |
29 case FILE_LIBAVFORMAT: | 32 case FILE_LIBAVFORMAT: |
30 return FILE_PATH_LITERAL("avformat-53.dll"); | 33 return "avformat-53.dll"; |
31 case FILE_LIBAVUTIL: | 34 case FILE_LIBAVUTIL: |
32 return FILE_PATH_LITERAL("avutil-51.dll"); | 35 return "avutil-51.dll"; |
33 default: | 36 default: |
34 LOG(DFATAL) << "Invalid DLL key requested: " << dll_key; | 37 LOG(DFATAL) << "Invalid DLL key requested: " << dll_key; |
35 return FILE_PATH_LITERAL(""); | 38 return ""; |
36 } | 39 } |
37 } | 40 } |
38 | 41 |
39 static bool g_media_library_is_initialized = false; | 42 static bool g_media_library_is_initialized = false; |
40 | 43 |
41 // Attempts to initialize the media library (loading DLLs, DSOs, etc.). | 44 // Attempts to initialize the media library (loading DLLs, DSOs, etc.). |
42 // Returns true if everything was successfully initialized, false otherwise. | 45 // Returns true if everything was successfully initialized, false otherwise. |
43 bool InitializeMediaLibrary(const FilePath& base_path) { | 46 bool InitializeMediaLibrary(const FilePath& base_path) { |
44 if (g_media_library_is_initialized) | 47 if (g_media_library_is_initialized) |
45 return true; | 48 return true; |
46 | 49 |
50 // LoadLibraryEx(..., LOAD_WITH_ALTERED_SEARCH_PATH) cannot handle | |
51 // relative path. | |
52 if (!base_path.IsAbsolute()) | |
53 return false; | |
54 | |
47 FFmpegDLLKeys path_keys[] = { | 55 FFmpegDLLKeys path_keys[] = { |
48 media::FILE_LIBAVCODEC, | 56 media::FILE_LIBAVCODEC, |
49 media::FILE_LIBAVFORMAT, | 57 media::FILE_LIBAVFORMAT, |
50 media::FILE_LIBAVUTIL | 58 media::FILE_LIBAVUTIL |
51 }; | 59 }; |
52 HMODULE libs[arraysize(path_keys)] = {NULL}; | 60 HMODULE libs[arraysize(path_keys)] = {NULL}; |
53 | 61 |
54 for (size_t i = 0; i < arraysize(path_keys); ++i) { | 62 for (size_t i = 0; i < arraysize(path_keys); ++i) { |
55 FilePath path = base_path.Append(GetDLLName(path_keys[i])); | 63 FilePath path = base_path.AppendASCII(GetDLLName(path_keys[i])); |
56 | 64 |
57 // Use alternate DLL search path so we don't load dependencies from the | 65 // Use alternate DLL search path so we don't load dependencies from the |
58 // system path. Refer to http://crbug.com/35857 | 66 // system path. Refer to http://crbug.com/35857 |
59 const wchar_t* cpath = path.value().c_str(); | 67 const wchar_t* cpath = path.value().c_str(); |
60 libs[i] = LoadLibraryEx(cpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); | 68 libs[i] = ::LoadLibraryEx(cpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
61 if (!libs[i]) | 69 if (!libs[i]) |
62 break; | 70 break; |
63 } | 71 } |
64 | 72 |
65 // Check that we loaded all libraries successfully. We only need to check the | 73 // Check that we loaded all libraries successfully. We only need to check the |
66 // last array element because the loop above will break without initializing | 74 // last array element because the loop above will break without initializing |
67 // it on any prior error. | 75 // it on any prior error. |
68 g_media_library_is_initialized = (libs[arraysize(libs) - 1] != NULL); | 76 bool media_library_is_initialized = (libs[arraysize(libs) - 1] != NULL); |
69 | 77 |
70 if (!g_media_library_is_initialized) { | 78 if (!media_library_is_initialized) { |
71 // Free any loaded libraries if we weren't successful. | 79 // Free any loaded libraries if we weren't successful. |
72 for (size_t i = 0; i < arraysize(libs) && libs[i] != NULL; ++i) { | 80 for (size_t i = 0; i < arraysize(libs) && libs[i] != NULL; ++i) { |
73 FreeLibrary(libs[i]); | 81 FreeLibrary(libs[i]); |
74 libs[i] = NULL; // Just to be safe. | 82 libs[i] = NULL; // Just to be safe. |
75 } | 83 } |
84 return false; | |
76 } | 85 } |
77 | 86 |
78 return g_media_library_is_initialized; | 87 // 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
| |
88 // LoadLibrary() sometimes AV's when called by delay load helper when we | |
89 // call function in ffmpeg for the first time, and we don't know why. | |
90 // Force delay load helper to fix import table here instead. | |
91 // Theoretically, there is no need to call LoadLibrary() before | |
92 // __HrLoadAllImportsForDll(), it will call LoadLibrary() itself, but there | |
93 // is no way to specify LOAD_WITH_ALTERED_SEARCH_PATH when calling | |
94 // __HrLoadAllImportsForDll(). So we do everything in 2 steps -- first call | |
95 // LoadLibraryEx(..., LOAD_WITH_ALTERED_SEARCH_PATH), then call | |
96 // __HrLoadAllImportsForDll(). Overhead is negligible compared to disk | |
97 // access time. | |
98 // Note: in case of error we are not unloading DLL because unload requires | |
99 // extra resources and should not be necessary; if we ever decide to | |
100 // unload by calling __FUnloadDelayLoadedDLL() please add /DELAY:UNLOAD | |
101 // to the linker command line. | |
102 for (size_t i = 0; i < arraysize(path_keys); ++i) { | |
103 if (FAILED(::__HrLoadAllImportsForDll(GetDLLName(path_keys[i])))) | |
104 media_library_is_initialized = false; | |
105 } | |
106 | |
107 g_media_library_is_initialized = media_library_is_initialized; | |
108 return media_library_is_initialized; | |
79 } | 109 } |
80 | 110 |
81 void InitializeMediaLibraryForTesting() { | 111 void InitializeMediaLibraryForTesting() { |
82 FilePath file_path; | 112 FilePath file_path; |
83 CHECK(PathService::Get(base::DIR_EXE, &file_path)); | 113 CHECK(PathService::Get(base::DIR_EXE, &file_path)); |
84 CHECK(InitializeMediaLibrary(file_path)); | 114 CHECK(InitializeMediaLibrary(file_path)); |
85 } | 115 } |
86 | 116 |
87 bool IsMediaLibraryInitialized() { | 117 bool IsMediaLibraryInitialized() { |
88 return g_media_library_is_initialized; | 118 return g_media_library_is_initialized; |
89 } | 119 } |
90 | 120 |
91 bool InitializeOpenMaxLibrary(const FilePath& module_dir) { | 121 bool InitializeOpenMaxLibrary(const FilePath& module_dir) { |
92 NOTIMPLEMENTED() << "OpenMAX is not used in Windows."; | 122 NOTIMPLEMENTED() << "OpenMAX is not used in Windows."; |
93 return false; | 123 return false; |
94 } | 124 } |
95 | 125 |
96 } // namespace media | 126 } // namespace media |
OLD | NEW |