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

Side by Side Diff: media/base/media_win.cc

Issue 9450001: Workaround for Windows-only crash inside delay load helper. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698