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

Side by Side Diff: media/gpu/dxva_video_decode_accelerator_win.cc

Issue 1939683002: Test X11 header pollution (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/common/gpu/media/dxva_video_decode_accelerator_win.h" 5 #include "media/gpu/dxva_video_decode_accelerator_win.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #if !defined(OS_WIN) 9 #if !defined(OS_WIN)
10 #error This file should only be built on Windows. 10 #error This file should only be built on Windows.
11 #endif // !defined(OS_WIN) 11 #endif // !defined(OS_WIN)
12 12
13 #include <codecapi.h> 13 #include <codecapi.h>
14 #include <dxgi1_2.h> 14 #include <dxgi1_2.h>
15 #include <ks.h> 15 #include <ks.h>
16 #include <mfapi.h> 16 #include <mfapi.h>
17 #include <mferror.h> 17 #include <mferror.h>
18 #include <ntverp.h> 18 #include <ntverp.h>
19 #include <stddef.h> 19 #include <stddef.h>
20 #include <string.h> 20 #include <string.h>
21 #include <wmcodecdsp.h> 21 #include <wmcodecdsp.h>
(...skipping 21 matching lines...) Expand all
43 #include "ui/gl/gl_fence.h" 43 #include "ui/gl/gl_fence.h"
44 #include "ui/gl/gl_surface_egl.h" 44 #include "ui/gl/gl_surface_egl.h"
45 45
46 namespace { 46 namespace {
47 47
48 // Path is appended on to the PROGRAM_FILES base path. 48 // Path is appended on to the PROGRAM_FILES base path.
49 const wchar_t kVPXDecoderDLLPath[] = L"Intel\\Media SDK\\"; 49 const wchar_t kVPXDecoderDLLPath[] = L"Intel\\Media SDK\\";
50 50
51 const wchar_t kVP8DecoderDLLName[] = 51 const wchar_t kVP8DecoderDLLName[] =
52 #if defined(ARCH_CPU_X86) 52 #if defined(ARCH_CPU_X86)
53 L"mfx_mft_vp8vd_32.dll"; 53 L"mfx_mft_vp8vd_32.dll";
54 #elif defined(ARCH_CPU_X86_64) 54 #elif defined(ARCH_CPU_X86_64)
55 L"mfx_mft_vp8vd_64.dll"; 55 L"mfx_mft_vp8vd_64.dll";
56 #else 56 #else
57 #error Unsupported Windows CPU Architecture 57 #error Unsupported Windows CPU Architecture
58 #endif 58 #endif
59 59
60 const wchar_t kVP9DecoderDLLName[] = 60 const wchar_t kVP9DecoderDLLName[] =
61 #if defined(ARCH_CPU_X86) 61 #if defined(ARCH_CPU_X86)
62 L"mfx_mft_vp9vd_32.dll"; 62 L"mfx_mft_vp9vd_32.dll";
63 #elif defined(ARCH_CPU_X86_64) 63 #elif defined(ARCH_CPU_X86_64)
64 L"mfx_mft_vp9vd_64.dll"; 64 L"mfx_mft_vp9vd_64.dll";
65 #else 65 #else
66 #error Unsupported Windows CPU Architecture 66 #error Unsupported Windows CPU Architecture
67 #endif 67 #endif
68 68
69 const CLSID CLSID_WebmMfVp8Dec = { 69 const CLSID CLSID_WebmMfVp8Dec = {
70 0x451e3cb7, 70 0x451e3cb7,
71 0x2622, 71 0x2622,
72 0x4ba5, 72 0x4ba5,
73 { 0x8e, 0x1d, 0x44, 0xb3, 0xc4, 0x1d, 0x09, 0x24 } 73 {0x8e, 0x1d, 0x44, 0xb3, 0xc4, 0x1d, 0x09, 0x24}};
74 };
75 74
76 const CLSID CLSID_WebmMfVp9Dec = { 75 const CLSID CLSID_WebmMfVp9Dec = {
77 0x07ab4bd2, 76 0x07ab4bd2,
78 0x1979, 77 0x1979,
79 0x4fcd, 78 0x4fcd,
80 { 0xa6, 0x97, 0xdf, 0x9a, 0xd1, 0x5b, 0x34, 0xfe } 79 {0xa6, 0x97, 0xdf, 0x9a, 0xd1, 0x5b, 0x34, 0xfe}};
81 };
82 80
83 const CLSID MEDIASUBTYPE_VP80 = { 81 const CLSID MEDIASUBTYPE_VP80 = {
84 0x30385056, 82 0x30385056,
85 0x0000, 83 0x0000,
86 0x0010, 84 0x0010,
87 { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } 85 {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
88 };
89 86
90 const CLSID MEDIASUBTYPE_VP90 = { 87 const CLSID MEDIASUBTYPE_VP90 = {
91 0x30395056, 88 0x30395056,
92 0x0000, 89 0x0000,
93 0x0010, 90 0x0010,
94 { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } 91 {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
95 };
96 92
97 // The CLSID of the video processor media foundation transform which we use for 93 // The CLSID of the video processor media foundation transform which we use for
98 // texture color conversion in DX11. 94 // texture color conversion in DX11.
99 // Defined in mfidl.h in the Windows 10 SDK. ntverp.h provides VER_PRODUCTBUILD 95 // Defined in mfidl.h in the Windows 10 SDK. ntverp.h provides VER_PRODUCTBUILD
100 // to detect which SDK we are compiling with. 96 // to detect which SDK we are compiling with.
101 #if VER_PRODUCTBUILD < 10011 // VER_PRODUCTBUILD for 10.0.10158.0 SDK. 97 #if VER_PRODUCTBUILD < 10011 // VER_PRODUCTBUILD for 10.0.10158.0 SDK.
102 DEFINE_GUID(CLSID_VideoProcessorMFT, 98 DEFINE_GUID(CLSID_VideoProcessorMFT,
103 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 99 0x88753b26,
104 0xc9, 0x82); 100 0x5b24,
101 0x49bd,
102 0xb2,
103 0xe7,
104 0xc,
105 0x44,
106 0x5c,
107 0x78,
108 0xc9,
109 0x82);
105 #endif 110 #endif
106 111
107 // MF_XVP_PLAYBACK_MODE 112 // MF_XVP_PLAYBACK_MODE
108 // Data type: UINT32 (treat as BOOL) 113 // Data type: UINT32 (treat as BOOL)
109 // If this attribute is TRUE, the video processor will run in playback mode 114 // If this attribute is TRUE, the video processor will run in playback mode
110 // where it allows callers to allocate output samples and allows last frame 115 // where it allows callers to allocate output samples and allows last frame
111 // regeneration (repaint). 116 // regeneration (repaint).
112 DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12, 117 DEFINE_GUID(MF_XVP_PLAYBACK_MODE,
113 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9); 118 0x3c5d293f,
119 0xad67,
120 0x4e29,
121 0xaf,
122 0x12,
123 0xcf,
124 0x3e,
125 0x23,
126 0x8a,
127 0xcc,
128 0xe9);
114 129
115 // Defines the GUID for the Intel H264 DXVA device. 130 // Defines the GUID for the Intel H264 DXVA device.
116 static const GUID DXVA2_Intel_ModeH264_E = { 131 static const GUID DXVA2_Intel_ModeH264_E = {
117 0x604F8E68, 0x4951, 0x4c54,{ 0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6} 132 0x604F8E68,
118 }; 133 0x4951,
134 0x4c54,
135 {0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6}};
119 136
120 // R600, R700, Evergreen and Cayman AMD cards. These support DXVA via UVD3 137 // R600, R700, Evergreen and Cayman AMD cards. These support DXVA via UVD3
121 // or earlier, and don't handle resolutions higher than 1920 x 1088 well. 138 // or earlier, and don't handle resolutions higher than 1920 x 1088 well.
122 static const DWORD g_AMDUVD3GPUList[] = { 139 static const DWORD g_AMDUVD3GPUList[] = {
123 0x9400, 0x9401, 0x9402, 0x9403, 0x9405, 0x940a, 0x940b, 0x940f, 0x94c0, 140 0x9400, 0x9401, 0x9402, 0x9403, 0x9405, 0x940a, 0x940b, 0x940f, 0x94c0,
124 0x94c1, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 0x94c8, 0x94c9, 0x94cb, 141 0x94c1, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 0x94c8, 0x94c9, 0x94cb,
125 0x94cc, 0x94cd, 0x9580, 0x9581, 0x9583, 0x9586, 0x9587, 0x9588, 0x9589, 142 0x94cc, 0x94cd, 0x9580, 0x9581, 0x9583, 0x9586, 0x9587, 0x9588, 0x9589,
126 0x958a, 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 0x9500, 0x9501, 0x9504, 143 0x958a, 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 0x9500, 0x9501, 0x9504,
127 0x9505, 0x9506, 0x9507, 0x9508, 0x9509, 0x950f, 0x9511, 0x9515, 0x9517, 144 0x9505, 0x9506, 0x9507, 0x9508, 0x9509, 0x950f, 0x9511, 0x9515, 0x9517,
128 0x9519, 0x95c0, 0x95c2, 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c9, 0x95cc, 145 0x9519, 0x95c0, 0x95c2, 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c9, 0x95cc,
129 0x95cd, 0x95ce, 0x95cf, 0x9590, 0x9591, 0x9593, 0x9595, 0x9596, 0x9597, 146 0x95cd, 0x95ce, 0x95cf, 0x9590, 0x9591, 0x9593, 0x9595, 0x9596, 0x9597,
130 0x9598, 0x9599, 0x959b, 0x9610, 0x9611, 0x9612, 0x9613, 0x9614, 0x9615, 147 0x9598, 0x9599, 0x959b, 0x9610, 0x9611, 0x9612, 0x9613, 0x9614, 0x9615,
131 0x9616, 0x9710, 0x9711, 0x9712, 0x9713, 0x9714, 0x9715, 0x9440, 0x9441, 148 0x9616, 0x9710, 0x9711, 0x9712, 0x9713, 0x9714, 0x9715, 0x9440, 0x9441,
132 0x9442, 0x9443, 0x9444, 0x9446, 0x944a, 0x944b, 0x944c, 0x944e, 0x9450, 149 0x9442, 0x9443, 0x9444, 0x9446, 0x944a, 0x944b, 0x944c, 0x944e, 0x9450,
133 0x9452, 0x9456, 0x945a, 0x945b, 0x945e, 0x9460, 0x9462, 0x946a, 0x946b, 150 0x9452, 0x9456, 0x945a, 0x945b, 0x945e, 0x9460, 0x9462, 0x946a, 0x946b,
134 0x947a, 0x947b, 0x9480, 0x9487, 0x9488, 0x9489, 0x948a, 0x948f, 0x9490, 151 0x947a, 0x947b, 0x9480, 0x9487, 0x9488, 0x9489, 0x948a, 0x948f, 0x9490,
135 0x9491, 0x9495, 0x9498, 0x949c, 0x949e, 0x949f, 0x9540, 0x9541, 0x9542, 152 0x9491, 0x9495, 0x9498, 0x949c, 0x949e, 0x949f, 0x9540, 0x9541, 0x9542,
136 0x954e, 0x954f, 0x9552, 0x9553, 0x9555, 0x9557, 0x955f, 0x94a0, 0x94a1, 153 0x954e, 0x954f, 0x9552, 0x9553, 0x9555, 0x9557, 0x955f, 0x94a0, 0x94a1,
137 0x94a3, 0x94b1, 0x94b3, 0x94b4, 0x94b5, 0x94b9, 0x68e0, 0x68e1, 0x68e4, 154 0x94a3, 0x94b1, 0x94b3, 0x94b4, 0x94b5, 0x94b9, 0x68e0, 0x68e1, 0x68e4,
138 0x68e5, 0x68e8, 0x68e9, 0x68f1, 0x68f2, 0x68f8, 0x68f9, 0x68fa, 0x68fe, 155 0x68e5, 0x68e8, 0x68e9, 0x68f1, 0x68f2, 0x68f8, 0x68f9, 0x68fa, 0x68fe,
139 0x68c0, 0x68c1, 0x68c7, 0x68c8, 0x68c9, 0x68d8, 0x68d9, 0x68da, 0x68de, 156 0x68c0, 0x68c1, 0x68c7, 0x68c8, 0x68c9, 0x68d8, 0x68d9, 0x68da, 0x68de,
140 0x68a0, 0x68a1, 0x68a8, 0x68a9, 0x68b0, 0x68b8, 0x68b9, 0x68ba, 0x68be, 157 0x68a0, 0x68a1, 0x68a8, 0x68a9, 0x68b0, 0x68b8, 0x68b9, 0x68ba, 0x68be,
141 0x68bf, 0x6880, 0x6888, 0x6889, 0x688a, 0x688c, 0x688d, 0x6898, 0x6899, 158 0x68bf, 0x6880, 0x6888, 0x6889, 0x688a, 0x688c, 0x688d, 0x6898, 0x6899,
142 0x689b, 0x689e, 0x689c, 0x689d, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806, 159 0x689b, 0x689e, 0x689c, 0x689d, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806,
143 0x9807, 0x9808, 0x9809, 0x980a, 0x9640, 0x9641, 0x9647, 0x9648, 0x964a, 160 0x9807, 0x9808, 0x9809, 0x980a, 0x9640, 0x9641, 0x9647, 0x9648, 0x964a,
144 0x964b, 0x964c, 0x964e, 0x964f, 0x9642, 0x9643, 0x9644, 0x9645, 0x9649, 161 0x964b, 0x964c, 0x964e, 0x964f, 0x9642, 0x9643, 0x9644, 0x9645, 0x9649,
145 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6726, 0x6727, 0x6728, 162 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6726, 0x6727, 0x6728,
146 0x6729, 0x6738, 0x6739, 0x673e, 0x6740, 0x6741, 0x6742, 0x6743, 0x6744, 163 0x6729, 0x6738, 0x6739, 0x673e, 0x6740, 0x6741, 0x6742, 0x6743, 0x6744,
147 0x6745, 0x6746, 0x6747, 0x6748, 0x6749, 0x674a, 0x6750, 0x6751, 0x6758, 164 0x6745, 0x6746, 0x6747, 0x6748, 0x6749, 0x674a, 0x6750, 0x6751, 0x6758,
148 0x6759, 0x675b, 0x675d, 0x675f, 0x6840, 0x6841, 0x6842, 0x6843, 0x6849, 165 0x6759, 0x675b, 0x675d, 0x675f, 0x6840, 0x6841, 0x6842, 0x6843, 0x6849,
149 0x6850, 0x6858, 0x6859, 0x6760, 0x6761, 0x6762, 0x6763, 0x6764, 0x6765, 166 0x6850, 0x6858, 0x6859, 0x6760, 0x6761, 0x6762, 0x6763, 0x6764, 0x6765,
150 0x6766, 0x6767, 0x6768, 0x6770, 0x6771, 0x6772, 0x6778, 0x6779, 0x677b, 167 0x6766, 0x6767, 0x6768, 0x6770, 0x6771, 0x6772, 0x6778, 0x6779, 0x677b,
151 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707, 0x6708, 168 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707, 0x6708,
152 0x6709, 0x6718, 0x6719, 0x671c, 0x671d, 0x671f, 0x683D, 0x9900, 0x9901, 169 0x6709, 0x6718, 0x6719, 0x671c, 0x671d, 0x671f, 0x683D, 0x9900, 0x9901,
153 0x9903, 0x9904, 0x9905, 0x9906, 0x9907, 0x9908, 0x9909, 0x990a, 0x990b, 170 0x9903, 0x9904, 0x9905, 0x9906, 0x9907, 0x9908, 0x9909, 0x990a, 0x990b,
154 0x990c, 0x990d, 0x990e, 0x990f, 0x9910, 0x9913, 0x9917, 0x9918, 0x9919, 171 0x990c, 0x990d, 0x990e, 0x990f, 0x9910, 0x9913, 0x9917, 0x9918, 0x9919,
155 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998, 172 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998,
156 0x9999, 0x999a, 0x999b, 0x999c, 0x999d, 0x99a0, 0x99a2, 0x99a4, 173 0x9999, 0x999a, 0x999b, 0x999c, 0x999d, 0x99a0, 0x99a2, 0x99a4,
157 }; 174 };
158 175
159 // Legacy Intel GPUs (Second generation) which have trouble with resolutions 176 // Legacy Intel GPUs (Second generation) which have trouble with resolutions
160 // higher than 1920 x 1088 177 // higher than 1920 x 1088
161 static const DWORD g_IntelLegacyGPUList[] = { 178 static const DWORD g_IntelLegacyGPUList[] = {
162 0x102, 0x106, 0x116, 0x126, 179 0x102, 0x106, 0x116, 0x126,
163 }; 180 };
164 181
165 // Provides scoped access to the underlying buffer in an IMFMediaBuffer 182 // Provides scoped access to the underlying buffer in an IMFMediaBuffer
166 // instance. 183 // instance.
167 class MediaBufferScopedPointer { 184 class MediaBufferScopedPointer {
168 public: 185 public:
169 MediaBufferScopedPointer(IMFMediaBuffer* media_buffer) 186 MediaBufferScopedPointer(IMFMediaBuffer* media_buffer)
170 : media_buffer_(media_buffer), 187 : media_buffer_(media_buffer),
171 buffer_(nullptr), 188 buffer_(nullptr),
172 max_length_(0), 189 max_length_(0),
173 current_length_(0) { 190 current_length_(0) {
174 HRESULT hr = media_buffer_->Lock(&buffer_, &max_length_, &current_length_); 191 HRESULT hr = media_buffer_->Lock(&buffer_, &max_length_, &current_length_);
175 CHECK(SUCCEEDED(hr)); 192 CHECK(SUCCEEDED(hr));
176 } 193 }
177 194
178 ~MediaBufferScopedPointer() { 195 ~MediaBufferScopedPointer() {
179 HRESULT hr = media_buffer_->Unlock(); 196 HRESULT hr = media_buffer_->Unlock();
180 CHECK(SUCCEEDED(hr)); 197 CHECK(SUCCEEDED(hr));
181 } 198 }
182 199
183 uint8_t* get() { 200 uint8_t* get() { return buffer_; }
184 return buffer_;
185 }
186 201
187 DWORD current_length() const { 202 DWORD current_length() const { return current_length_; }
188 return current_length_;
189 }
190 203
191 private: 204 private:
192 base::win::ScopedComPtr<IMFMediaBuffer> media_buffer_; 205 base::win::ScopedComPtr<IMFMediaBuffer> media_buffer_;
193 uint8_t* buffer_; 206 uint8_t* buffer_;
194 DWORD max_length_; 207 DWORD max_length_;
195 DWORD current_length_; 208 DWORD current_length_;
196 209
197 DISALLOW_COPY_AND_ASSIGN(MediaBufferScopedPointer); 210 DISALLOW_COPY_AND_ASSIGN(MediaBufferScopedPointer);
198 }; 211 };
199 212
200 } // namespace 213 } // namespace
201 214
202 namespace content { 215 namespace media {
203 216
204 static const media::VideoCodecProfile kSupportedProfiles[] = { 217 static const media::VideoCodecProfile kSupportedProfiles[] = {
205 media::H264PROFILE_BASELINE, 218 media::H264PROFILE_BASELINE, media::H264PROFILE_MAIN,
206 media::H264PROFILE_MAIN, 219 media::H264PROFILE_HIGH, media::VP8PROFILE_ANY,
207 media::H264PROFILE_HIGH, 220 media::VP9PROFILE_PROFILE0, media::VP9PROFILE_PROFILE1,
208 media::VP8PROFILE_ANY, 221 media::VP9PROFILE_PROFILE2, media::VP9PROFILE_PROFILE3};
209 media::VP9PROFILE_PROFILE0,
210 media::VP9PROFILE_PROFILE1,
211 media::VP9PROFILE_PROFILE2,
212 media::VP9PROFILE_PROFILE3
213 };
214 222
215 CreateDXGIDeviceManager DXVAVideoDecodeAccelerator::create_dxgi_device_manager_ 223 CreateDXGIDeviceManager
216 = NULL; 224 DXVAVideoDecodeAccelerator::create_dxgi_device_manager_ = NULL;
217 225
218 #define RETURN_ON_FAILURE(result, log, ret) \ 226 #define RETURN_ON_FAILURE(result, log, ret) \
219 do { \ 227 do { \
220 if (!(result)) { \ 228 if (!(result)) { \
221 DLOG(ERROR) << log; \ 229 DLOG(ERROR) << log; \
222 return ret; \ 230 return ret; \
223 } \ 231 } \
224 } while (0) 232 } while (0)
225 233
226 #define RETURN_ON_HR_FAILURE(result, log, ret) \ 234 #define RETURN_ON_HR_FAILURE(result, log, ret) \
227 RETURN_ON_FAILURE(SUCCEEDED(result), \ 235 RETURN_ON_FAILURE(SUCCEEDED(result), \
228 log << ", HRESULT: 0x" << std::hex << result, \ 236 log << ", HRESULT: 0x" << std::hex << result, ret);
229 ret);
230 237
231 #define RETURN_AND_NOTIFY_ON_FAILURE(result, log, error_code, ret) \ 238 #define RETURN_AND_NOTIFY_ON_FAILURE(result, log, error_code, ret) \
232 do { \ 239 do { \
233 if (!(result)) { \ 240 if (!(result)) { \
234 DVLOG(1) << log; \ 241 DVLOG(1) << log; \
235 StopOnError(error_code); \ 242 StopOnError(error_code); \
236 return ret; \ 243 return ret; \
237 } \ 244 } \
238 } while (0) 245 } while (0)
239 246
240 #define RETURN_AND_NOTIFY_ON_HR_FAILURE(result, log, error_code, ret) \ 247 #define RETURN_AND_NOTIFY_ON_HR_FAILURE(result, log, error_code, ret) \
241 RETURN_AND_NOTIFY_ON_FAILURE(SUCCEEDED(result), \ 248 RETURN_AND_NOTIFY_ON_FAILURE(SUCCEEDED(result), \
242 log << ", HRESULT: 0x" << std::hex << result, \ 249 log << ", HRESULT: 0x" << std::hex << result, \
243 error_code, ret); 250 error_code, ret);
244 251
245 enum { 252 enum {
246 // Maximum number of iterations we allow before aborting the attempt to flush 253 // Maximum number of iterations we allow before aborting the attempt to flush
247 // the batched queries to the driver and allow torn/corrupt frames to be 254 // the batched queries to the driver and allow torn/corrupt frames to be
248 // rendered. 255 // rendered.
249 kFlushDecoderSurfaceTimeoutMs = 1, 256 kFlushDecoderSurfaceTimeoutMs = 1,
250 // Maximum iterations where we try to flush the d3d device. 257 // Maximum iterations where we try to flush the d3d device.
251 kMaxIterationsForD3DFlush = 4, 258 kMaxIterationsForD3DFlush = 4,
(...skipping 25 matching lines...) Expand all
277 base::win::ScopedComPtr<IMFSample> sample; 284 base::win::ScopedComPtr<IMFSample> sample;
278 sample.Attach(CreateEmptySample()); 285 sample.Attach(CreateEmptySample());
279 286
280 base::win::ScopedComPtr<IMFMediaBuffer> buffer; 287 base::win::ScopedComPtr<IMFMediaBuffer> buffer;
281 HRESULT hr = E_FAIL; 288 HRESULT hr = E_FAIL;
282 if (align == 0) { 289 if (align == 0) {
283 // Note that MFCreateMemoryBuffer is same as MFCreateAlignedMemoryBuffer 290 // Note that MFCreateMemoryBuffer is same as MFCreateAlignedMemoryBuffer
284 // with the align argument being 0. 291 // with the align argument being 0.
285 hr = MFCreateMemoryBuffer(buffer_length, buffer.Receive()); 292 hr = MFCreateMemoryBuffer(buffer_length, buffer.Receive());
286 } else { 293 } else {
287 hr = MFCreateAlignedMemoryBuffer(buffer_length, 294 hr =
288 align - 1, 295 MFCreateAlignedMemoryBuffer(buffer_length, align - 1, buffer.Receive());
289 buffer.Receive());
290 } 296 }
291 RETURN_ON_HR_FAILURE(hr, "Failed to create memory buffer for sample", NULL); 297 RETURN_ON_HR_FAILURE(hr, "Failed to create memory buffer for sample", NULL);
292 298
293 hr = sample->AddBuffer(buffer.get()); 299 hr = sample->AddBuffer(buffer.get());
294 RETURN_ON_HR_FAILURE(hr, "Failed to add buffer to sample", NULL); 300 RETURN_ON_HR_FAILURE(hr, "Failed to add buffer to sample", NULL);
295 301
296 buffer->SetCurrentLength(0); 302 buffer->SetCurrentLength(0);
297 return sample.Detach(); 303 return sample.Detach();
298 } 304 }
299 305
300 // Creates a Media Foundation sample with one buffer containing a copy of the 306 // Creates a Media Foundation sample with one buffer containing a copy of the
301 // given Annex B stream data. 307 // given Annex B stream data.
302 // If duration and sample time are not known, provide 0. 308 // If duration and sample time are not known, provide 0.
303 // |min_size| specifies the minimum size of the buffer (might be required by 309 // |min_size| specifies the minimum size of the buffer (might be required by
304 // the decoder for input). If no alignment is required, provide 0. 310 // the decoder for input). If no alignment is required, provide 0.
305 static IMFSample* CreateInputSample(const uint8_t* stream, 311 static IMFSample* CreateInputSample(const uint8_t* stream,
306 uint32_t size, 312 uint32_t size,
307 uint32_t min_size, 313 uint32_t min_size,
308 int alignment) { 314 int alignment) {
309 CHECK(stream); 315 CHECK(stream);
310 CHECK_GT(size, 0U); 316 CHECK_GT(size, 0U);
311 base::win::ScopedComPtr<IMFSample> sample; 317 base::win::ScopedComPtr<IMFSample> sample;
312 sample.Attach(CreateEmptySampleWithBuffer(std::max(min_size, size), 318 sample.Attach(
313 alignment)); 319 CreateEmptySampleWithBuffer(std::max(min_size, size), alignment));
314 RETURN_ON_FAILURE(sample.get(), "Failed to create empty sample", NULL); 320 RETURN_ON_FAILURE(sample.get(), "Failed to create empty sample", NULL);
315 321
316 base::win::ScopedComPtr<IMFMediaBuffer> buffer; 322 base::win::ScopedComPtr<IMFMediaBuffer> buffer;
317 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); 323 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive());
318 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", NULL); 324 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", NULL);
319 325
320 DWORD max_length = 0; 326 DWORD max_length = 0;
321 DWORD current_length = 0; 327 DWORD current_length = 0;
322 uint8_t* destination = NULL; 328 uint8_t* destination = NULL;
323 hr = buffer->Lock(&destination, &max_length, &current_length); 329 hr = buffer->Lock(&destination, &max_length, &current_length);
324 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL); 330 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL);
325 331
326 CHECK_EQ(current_length, 0u); 332 CHECK_EQ(current_length, 0u);
327 CHECK_GE(max_length, size); 333 CHECK_GE(max_length, size);
328 memcpy(destination, stream, size); 334 memcpy(destination, stream, size);
329 335
330 hr = buffer->SetCurrentLength(size); 336 hr = buffer->SetCurrentLength(size);
331 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL); 337 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL);
332 338
333 hr = buffer->Unlock(); 339 hr = buffer->Unlock();
334 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL); 340 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL);
335 341
336 return sample.Detach(); 342 return sample.Detach();
337 } 343 }
338 344
339 // Helper function to create a COM object instance from a DLL. The alternative 345 // Helper function to create a COM object instance from a DLL. The alternative
340 // is to use the CoCreateInstance API which requires the COM apartment to be 346 // is to use the CoCreateInstance API which requires the COM apartment to be
341 // initialized which is not the case on the GPU main thread. We want to avoid 347 // initialized which is not the case on the GPU main thread. We want to avoid
342 // initializing COM as it may have sideeffects. 348 // initializing COM as it may have sideeffects.
343 HRESULT CreateCOMObjectFromDll(HMODULE dll, const CLSID& clsid, const IID& iid, 349 HRESULT CreateCOMObjectFromDll(HMODULE dll,
350 const CLSID& clsid,
351 const IID& iid,
344 void** object) { 352 void** object) {
345 if (!dll || !object) 353 if (!dll || !object)
346 return E_INVALIDARG; 354 return E_INVALIDARG;
347 355
348 using GetClassObject = HRESULT (WINAPI*)( 356 using GetClassObject =
349 const CLSID& clsid, const IID& iid, void** object); 357 HRESULT(WINAPI*)(const CLSID& clsid, const IID& iid, void** object);
350 358
351 GetClassObject get_class_object = reinterpret_cast<GetClassObject>( 359 GetClassObject get_class_object = reinterpret_cast<GetClassObject>(
352 GetProcAddress(dll, "DllGetClassObject")); 360 GetProcAddress(dll, "DllGetClassObject"));
353 RETURN_ON_FAILURE( 361 RETURN_ON_FAILURE(get_class_object, "Failed to get DllGetClassObject pointer",
354 get_class_object, "Failed to get DllGetClassObject pointer", E_FAIL); 362 E_FAIL);
355 363
356 base::win::ScopedComPtr<IClassFactory> factory; 364 base::win::ScopedComPtr<IClassFactory> factory;
357 HRESULT hr = get_class_object( 365 HRESULT hr =
358 clsid, 366 get_class_object(clsid, __uuidof(IClassFactory), factory.ReceiveVoid());
359 __uuidof(IClassFactory),
360 factory.ReceiveVoid());
361 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject failed", hr); 367 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject failed", hr);
362 368
363 hr = factory->CreateInstance(NULL, iid, object); 369 hr = factory->CreateInstance(NULL, iid, object);
364 return hr; 370 return hr;
365 } 371 }
366 372
367 // Helper function to query the ANGLE device object. The template argument T 373 // Helper function to query the ANGLE device object. The template argument T
368 // identifies the device interface being queried. IDirect3DDevice9Ex for d3d9 374 // identifies the device interface being queried. IDirect3DDevice9Ex for d3d9
369 // and ID3D11Device for dx11. 375 // and ID3D11Device for dx11.
370 template<class T> 376 template <class T>
371 base::win::ScopedComPtr<T> QueryDeviceObjectFromANGLE(int object_type) { 377 base::win::ScopedComPtr<T> QueryDeviceObjectFromANGLE(int object_type) {
372 base::win::ScopedComPtr<T> device_object; 378 base::win::ScopedComPtr<T> device_object;
373 379
374 EGLDisplay egl_display = nullptr; 380 EGLDisplay egl_display = nullptr;
375 intptr_t egl_device = 0; 381 intptr_t egl_device = 0;
376 intptr_t device = 0; 382 intptr_t device = 0;
377 383
378 { 384 {
379 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. GetHardwareDisplay"); 385 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. GetHardwareDisplay");
380 egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 386 egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
381 } 387 }
382 388
383 RETURN_ON_FAILURE( 389 RETURN_ON_FAILURE(gfx::GLSurfaceEGL::HasEGLExtension("EGL_EXT_device_query"),
384 gfx::GLSurfaceEGL::HasEGLExtension("EGL_EXT_device_query"), 390 "EGL_EXT_device_query missing", device_object);
385 "EGL_EXT_device_query missing",
386 device_object);
387 391
388 PFNEGLQUERYDISPLAYATTRIBEXTPROC QueryDisplayAttribEXT = nullptr; 392 PFNEGLQUERYDISPLAYATTRIBEXTPROC QueryDisplayAttribEXT = nullptr;
389 393
390 { 394 {
391 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. eglGetProcAddress"); 395 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. eglGetProcAddress");
392 396
393 QueryDisplayAttribEXT = 397 QueryDisplayAttribEXT = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
394 reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(eglGetProcAddress( 398 eglGetProcAddress("eglQueryDisplayAttribEXT"));
395 "eglQueryDisplayAttribEXT"));
396 399
397 RETURN_ON_FAILURE( 400 RETURN_ON_FAILURE(
398 QueryDisplayAttribEXT, 401 QueryDisplayAttribEXT,
399 "Failed to get the eglQueryDisplayAttribEXT function from ANGLE", 402 "Failed to get the eglQueryDisplayAttribEXT function from ANGLE",
400 device_object); 403 device_object);
401 } 404 }
402 405
403 PFNEGLQUERYDEVICEATTRIBEXTPROC QueryDeviceAttribEXT = nullptr; 406 PFNEGLQUERYDEVICEATTRIBEXTPROC QueryDeviceAttribEXT = nullptr;
404 407
405 { 408 {
406 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. eglGetProcAddress"); 409 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. eglGetProcAddress");
407 410
408 QueryDeviceAttribEXT = 411 QueryDeviceAttribEXT = reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
409 reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(eglGetProcAddress( 412 eglGetProcAddress("eglQueryDeviceAttribEXT"));
410 "eglQueryDeviceAttribEXT"));
411 413
412 RETURN_ON_FAILURE( 414 RETURN_ON_FAILURE(
413 QueryDeviceAttribEXT, 415 QueryDeviceAttribEXT,
414 "Failed to get the eglQueryDeviceAttribEXT function from ANGLE", 416 "Failed to get the eglQueryDeviceAttribEXT function from ANGLE",
415 device_object); 417 device_object);
416 } 418 }
417 419
418 { 420 {
419 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. QueryDisplayAttribEXT"); 421 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. QueryDisplayAttribEXT");
420 422
421 RETURN_ON_FAILURE( 423 RETURN_ON_FAILURE(
422 QueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT, &egl_device), 424 QueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT, &egl_device),
423 "The eglQueryDisplayAttribEXT function failed to get the EGL device", 425 "The eglQueryDisplayAttribEXT function failed to get the EGL device",
424 device_object); 426 device_object);
425 } 427 }
426 428
427 RETURN_ON_FAILURE( 429 RETURN_ON_FAILURE(egl_device, "Failed to get the EGL device", device_object);
428 egl_device,
429 "Failed to get the EGL device",
430 device_object);
431 430
432 { 431 {
433 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. QueryDisplayAttribEXT"); 432 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. QueryDisplayAttribEXT");
434 433
435 RETURN_ON_FAILURE( 434 RETURN_ON_FAILURE(
436 QueryDeviceAttribEXT( 435 QueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(egl_device),
437 reinterpret_cast<EGLDeviceEXT>(egl_device), object_type, &device), 436 object_type, &device),
438 "The eglQueryDeviceAttribEXT function failed to get the device", 437 "The eglQueryDeviceAttribEXT function failed to get the device",
439 device_object); 438 device_object);
440 439
441 RETURN_ON_FAILURE(device, "Failed to get the ANGLE device", device_object); 440 RETURN_ON_FAILURE(device, "Failed to get the ANGLE device", device_object);
442 } 441 }
443 442
444 device_object = reinterpret_cast<T*>(device); 443 device_object = reinterpret_cast<T*>(device);
445 return device_object; 444 return device_object;
446 } 445 }
447 446
448 H264ConfigChangeDetector::H264ConfigChangeDetector() 447 H264ConfigChangeDetector::H264ConfigChangeDetector()
449 : last_sps_id_(0), 448 : last_sps_id_(0),
450 last_pps_id_(0), 449 last_pps_id_(0),
451 config_changed_(false), 450 config_changed_(false),
452 pending_config_changed_(false) { 451 pending_config_changed_(false) {}
453 }
454 452
455 H264ConfigChangeDetector::~H264ConfigChangeDetector() { 453 H264ConfigChangeDetector::~H264ConfigChangeDetector() {}
456 }
457 454
458 bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream, 455 bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream,
459 unsigned int size) { 456 unsigned int size) {
460 std::vector<uint8_t> sps; 457 std::vector<uint8_t> sps;
461 std::vector<uint8_t> pps; 458 std::vector<uint8_t> pps;
462 media::H264NALU nalu; 459 media::H264NALU nalu;
463 bool idr_seen = false; 460 bool idr_seen = false;
464 461
465 if (!parser_.get()) 462 if (!parser_.get())
466 parser_.reset(new media::H264Parser); 463 parser_.reset(new media::H264Parser);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 ~DXVAPictureBuffer(); 562 ~DXVAPictureBuffer();
566 563
567 bool InitializeTexture(const DXVAVideoDecodeAccelerator& decoder, 564 bool InitializeTexture(const DXVAVideoDecodeAccelerator& decoder,
568 bool use_rgb); 565 bool use_rgb);
569 566
570 bool ReusePictureBuffer(); 567 bool ReusePictureBuffer();
571 void ResetReuseFence(); 568 void ResetReuseFence();
572 // Copies the output sample data to the picture buffer provided by the 569 // Copies the output sample data to the picture buffer provided by the
573 // client. 570 // client.
574 // The dest_surface parameter contains the decoded bits. 571 // The dest_surface parameter contains the decoded bits.
575 bool CopyOutputSampleDataToPictureBuffer( 572 bool CopyOutputSampleDataToPictureBuffer(DXVAVideoDecodeAccelerator* decoder,
576 DXVAVideoDecodeAccelerator* decoder, 573 IDirect3DSurface9* dest_surface,
577 IDirect3DSurface9* dest_surface, 574 ID3D11Texture2D* dx11_texture,
578 ID3D11Texture2D* dx11_texture, 575 int input_buffer_id);
579 int input_buffer_id);
580 576
581 bool available() const { 577 bool available() const { return available_; }
582 return available_;
583 }
584 578
585 void set_available(bool available) { 579 void set_available(bool available) { available_ = available; }
586 available_ = available;
587 }
588 580
589 int id() const { 581 int id() const { return picture_buffer_.id(); }
590 return picture_buffer_.id();
591 }
592 582
593 gfx::Size size() const { 583 gfx::Size size() const { return picture_buffer_.size(); }
594 return picture_buffer_.size();
595 }
596 584
597 bool waiting_to_reuse() const { return waiting_to_reuse_; } 585 bool waiting_to_reuse() const { return waiting_to_reuse_; }
598 586
599 gfx::GLFence* reuse_fence() { return reuse_fence_.get(); } 587 gfx::GLFence* reuse_fence() { return reuse_fence_.get(); }
600 588
601 // Called when the source surface |src_surface| is copied to the destination 589 // Called when the source surface |src_surface| is copied to the destination
602 // |dest_surface| 590 // |dest_surface|
603 bool CopySurfaceComplete(IDirect3DSurface9* src_surface, 591 bool CopySurfaceComplete(IDirect3DSurface9* src_surface,
604 IDirect3DSurface9* dest_surface); 592 IDirect3DSurface9* dest_surface);
605 593
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 642
655 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 643 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
656 644
657 EGLint use_rgb = 1; 645 EGLint use_rgb = 1;
658 eglGetConfigAttrib(egl_display, egl_config, EGL_BIND_TO_TEXTURE_RGB, 646 eglGetConfigAttrib(egl_display, egl_config, EGL_BIND_TO_TEXTURE_RGB,
659 &use_rgb); 647 &use_rgb);
660 648
661 if (!picture_buffer->InitializeTexture(decoder, !!use_rgb)) 649 if (!picture_buffer->InitializeTexture(decoder, !!use_rgb))
662 return linked_ptr<DXVAPictureBuffer>(nullptr); 650 return linked_ptr<DXVAPictureBuffer>(nullptr);
663 651
664 EGLint attrib_list[] = { 652 EGLint attrib_list[] = {EGL_WIDTH,
665 EGL_WIDTH, buffer.size().width(), 653 buffer.size().width(),
666 EGL_HEIGHT, buffer.size().height(), 654 EGL_HEIGHT,
667 EGL_TEXTURE_FORMAT, use_rgb ? EGL_TEXTURE_RGB : EGL_TEXTURE_RGBA, 655 buffer.size().height(),
668 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, 656 EGL_TEXTURE_FORMAT,
669 EGL_NONE 657 use_rgb ? EGL_TEXTURE_RGB : EGL_TEXTURE_RGBA,
670 }; 658 EGL_TEXTURE_TARGET,
659 EGL_TEXTURE_2D,
660 EGL_NONE};
671 661
672 picture_buffer->decoding_surface_ = eglCreatePbufferFromClientBuffer( 662 picture_buffer->decoding_surface_ = eglCreatePbufferFromClientBuffer(
673 egl_display, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, 663 egl_display, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
674 picture_buffer->texture_share_handle_, egl_config, attrib_list); 664 picture_buffer->texture_share_handle_, egl_config, attrib_list);
675 RETURN_ON_FAILURE(picture_buffer->decoding_surface_, 665 RETURN_ON_FAILURE(picture_buffer->decoding_surface_,
676 "Failed to create surface", 666 "Failed to create surface",
677 linked_ptr<DXVAPictureBuffer>(NULL)); 667 linked_ptr<DXVAPictureBuffer>(NULL));
678 if (decoder.d3d11_device_ && decoder.use_keyed_mutex_) { 668 if (decoder.d3d11_device_ && decoder.use_keyed_mutex_) {
679 void* keyed_mutex = nullptr; 669 void* keyed_mutex = nullptr;
680 EGLBoolean ret = eglQuerySurfacePointerANGLE( 670 EGLBoolean ret = eglQuerySurfacePointerANGLE(
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 picture_buffer_(buffer), 735 picture_buffer_(buffer),
746 decoding_surface_(NULL), 736 decoding_surface_(NULL),
747 texture_share_handle_(nullptr), 737 texture_share_handle_(nullptr),
748 keyed_mutex_value_(0), 738 keyed_mutex_value_(0),
749 use_rgb_(true) {} 739 use_rgb_(true) {}
750 740
751 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::~DXVAPictureBuffer() { 741 DXVAVideoDecodeAccelerator::DXVAPictureBuffer::~DXVAPictureBuffer() {
752 if (decoding_surface_) { 742 if (decoding_surface_) {
753 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 743 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
754 744
755 eglReleaseTexImage( 745 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER);
756 egl_display,
757 decoding_surface_,
758 EGL_BACK_BUFFER);
759 746
760 eglDestroySurface( 747 eglDestroySurface(egl_display, decoding_surface_);
761 egl_display,
762 decoding_surface_);
763 decoding_surface_ = NULL; 748 decoding_surface_ = NULL;
764 } 749 }
765 } 750 }
766 751
767 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() { 752 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() {
768 DCHECK(decoding_surface_); 753 DCHECK(decoding_surface_);
769 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 754 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
770 eglReleaseTexImage( 755 eglReleaseTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER);
771 egl_display,
772 decoding_surface_,
773 EGL_BACK_BUFFER);
774 decoder_surface_.Release(); 756 decoder_surface_.Release();
775 target_surface_.Release(); 757 target_surface_.Release();
776 decoder_dx11_texture_.Release(); 758 decoder_dx11_texture_.Release();
777 waiting_to_reuse_ = false; 759 waiting_to_reuse_ = false;
778 set_available(true); 760 set_available(true);
779 if (egl_keyed_mutex_) { 761 if (egl_keyed_mutex_) {
780 HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_); 762 HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_);
781 RETURN_ON_FAILURE(hr == S_OK, "Could not release sync mutex", false); 763 RETURN_ON_FAILURE(hr == S_OK, "Could not release sync mutex", false);
782 } 764 }
783 return true; 765 return true;
784 } 766 }
785 767
786 void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ResetReuseFence() { 768 void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ResetReuseFence() {
787 if (!reuse_fence_ || !reuse_fence_->ResetSupported()) 769 if (!reuse_fence_ || !reuse_fence_->ResetSupported())
788 reuse_fence_.reset(gfx::GLFence::Create()); 770 reuse_fence_.reset(gfx::GLFence::Create());
789 else 771 else
790 reuse_fence_->ResetState(); 772 reuse_fence_->ResetState();
791 waiting_to_reuse_ = true; 773 waiting_to_reuse_ = true;
792 } 774 }
793 775
794 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer:: 776 bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::
795 CopyOutputSampleDataToPictureBuffer( 777 CopyOutputSampleDataToPictureBuffer(DXVAVideoDecodeAccelerator* decoder,
796 DXVAVideoDecodeAccelerator* decoder, 778 IDirect3DSurface9* dest_surface,
797 IDirect3DSurface9* dest_surface, 779 ID3D11Texture2D* dx11_texture,
798 ID3D11Texture2D* dx11_texture, 780 int input_buffer_id) {
799 int input_buffer_id) {
800 DCHECK(dest_surface || dx11_texture); 781 DCHECK(dest_surface || dx11_texture);
801 if (dx11_texture) { 782 if (dx11_texture) {
802 // Grab a reference on the decoder texture. This reference will be released 783 // Grab a reference on the decoder texture. This reference will be released
803 // when we receive a notification that the copy was completed or when the 784 // when we receive a notification that the copy was completed or when the
804 // DXVAPictureBuffer instance is destroyed. 785 // DXVAPictureBuffer instance is destroyed.
805 decoder_dx11_texture_ = dx11_texture; 786 decoder_dx11_texture_ = dx11_texture;
806 decoder->CopyTexture(dx11_texture, dx11_decoding_texture_.get(), 787 decoder->CopyTexture(dx11_texture, dx11_decoding_texture_.get(),
807 dx11_keyed_mutex_, keyed_mutex_value_, NULL, id(), 788 dx11_keyed_mutex_, keyed_mutex_value_, NULL, id(),
808 input_buffer_id); 789 input_buffer_id);
809 return true; 790 return true;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 decoder_dx11_texture_.Release(); 848 decoder_dx11_texture_.Release();
868 } 849 }
869 if (egl_keyed_mutex_) { 850 if (egl_keyed_mutex_) {
870 keyed_mutex_value_++; 851 keyed_mutex_value_++;
871 HRESULT result = 852 HRESULT result =
872 egl_keyed_mutex_->AcquireSync(keyed_mutex_value_, kAcquireSyncWaitMs); 853 egl_keyed_mutex_->AcquireSync(keyed_mutex_value_, kAcquireSyncWaitMs);
873 RETURN_ON_FAILURE(result == S_OK, "Could not acquire sync mutex", false); 854 RETURN_ON_FAILURE(result == S_OK, "Could not acquire sync mutex", false);
874 } 855 }
875 856
876 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 857 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
877 eglBindTexImage( 858 eglBindTexImage(egl_display, decoding_surface_, EGL_BACK_BUFFER);
878 egl_display,
879 decoding_surface_,
880 EGL_BACK_BUFFER);
881 859
882 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 860 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
883 glBindTexture(GL_TEXTURE_2D, current_texture); 861 glBindTexture(GL_TEXTURE_2D, current_texture);
884 return true; 862 return true;
885 } 863 }
886 864
887 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( 865 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo(
888 int32_t buffer_id, 866 int32_t buffer_id,
889 IMFSample* sample) 867 IMFSample* sample)
890 : input_buffer_id(buffer_id), picture_buffer_id(-1) { 868 : input_buffer_id(buffer_id), picture_buffer_id(-1) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 929
952 bool profile_supported = false; 930 bool profile_supported = false;
953 for (const auto& supported_profile : kSupportedProfiles) { 931 for (const auto& supported_profile : kSupportedProfiles) {
954 if (config.profile == supported_profile) { 932 if (config.profile == supported_profile) {
955 profile_supported = true; 933 profile_supported = true;
956 break; 934 break;
957 } 935 }
958 } 936 }
959 if (!profile_supported) { 937 if (!profile_supported) {
960 RETURN_AND_NOTIFY_ON_FAILURE(false, 938 RETURN_AND_NOTIFY_ON_FAILURE(false,
961 "Unsupported h.264, vp8, or vp9 profile", PLATFORM_FAILURE, false); 939 "Unsupported h.264, vp8, or vp9 profile",
940 PLATFORM_FAILURE, false);
962 } 941 }
963 942
964 // Not all versions of Windows 7 and later include Media Foundation DLLs. 943 // Not all versions of Windows 7 and later include Media Foundation DLLs.
965 // Instead of crashing while delay loading the DLL when calling MFStartup() 944 // Instead of crashing while delay loading the DLL when calling MFStartup()
966 // below, probe whether we can successfully load the DLL now. 945 // below, probe whether we can successfully load the DLL now.
967 // See http://crbug.com/339678 for details. 946 // See http://crbug.com/339678 for details.
968 HMODULE dxgi_manager_dll = ::GetModuleHandle(L"MFPlat.dll"); 947 HMODULE dxgi_manager_dll = ::GetModuleHandle(L"MFPlat.dll");
969 RETURN_ON_FAILURE(dxgi_manager_dll, "MFPlat.dll is required for decoding", 948 RETURN_ON_FAILURE(dxgi_manager_dll, "MFPlat.dll is required for decoding",
970 false); 949 false);
971 950
972 // On Windows 8+ mfplat.dll provides the MFCreateDXGIDeviceManager API. 951 // On Windows 8+ mfplat.dll provides the MFCreateDXGIDeviceManager API.
973 // On Windows 7 mshtmlmedia.dll provides it. 952 // On Windows 7 mshtmlmedia.dll provides it.
974 953
975 // TODO(ananta) 954 // TODO(ananta)
976 // The code below works, as in we can create the DX11 device manager for 955 // The code below works, as in we can create the DX11 device manager for
977 // Windows 7. However the IMFTransform we use for texture conversion and 956 // Windows 7. However the IMFTransform we use for texture conversion and
978 // copy does not exist on Windows 7. Look into an alternate approach 957 // copy does not exist on Windows 7. Look into an alternate approach
979 // and enable the code below. 958 // and enable the code below.
980 #if defined(ENABLE_DX11_FOR_WIN7) 959 #if defined(ENABLE_DX11_FOR_WIN7)
981 if (base::win::GetVersion() == base::win::VERSION_WIN7) { 960 if (base::win::GetVersion() == base::win::VERSION_WIN7) {
982 dxgi_manager_dll = ::GetModuleHandle(L"mshtmlmedia.dll"); 961 dxgi_manager_dll = ::GetModuleHandle(L"mshtmlmedia.dll");
983 RETURN_ON_FAILURE(dxgi_manager_dll, 962 RETURN_ON_FAILURE(dxgi_manager_dll,
984 "mshtmlmedia.dll is required for decoding", false); 963 "mshtmlmedia.dll is required for decoding", false);
985 } 964 }
986 #endif 965 #endif
987 // If we don't find the MFCreateDXGIDeviceManager API we fallback to D3D9 966 // If we don't find the MFCreateDXGIDeviceManager API we fallback to D3D9
988 // decoding. 967 // decoding.
989 if (dxgi_manager_dll && !create_dxgi_device_manager_) { 968 if (dxgi_manager_dll && !create_dxgi_device_manager_) {
990 create_dxgi_device_manager_ = reinterpret_cast<CreateDXGIDeviceManager>( 969 create_dxgi_device_manager_ = reinterpret_cast<CreateDXGIDeviceManager>(
991 ::GetProcAddress(dxgi_manager_dll, "MFCreateDXGIDeviceManager")); 970 ::GetProcAddress(dxgi_manager_dll, "MFCreateDXGIDeviceManager"));
992 } 971 }
993 972
994 RETURN_AND_NOTIFY_ON_FAILURE( 973 RETURN_AND_NOTIFY_ON_FAILURE(
995 gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle, 974 gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle,
996 "EGL_ANGLE_surface_d3d_texture_2d_share_handle unavailable", 975 "EGL_ANGLE_surface_d3d_texture_2d_share_handle unavailable",
997 PLATFORM_FAILURE, 976 PLATFORM_FAILURE, false);
998 false);
999 977
1000 RETURN_AND_NOTIFY_ON_FAILURE(gfx::GLFence::IsSupported(), 978 RETURN_AND_NOTIFY_ON_FAILURE(gfx::GLFence::IsSupported(),
1001 "GL fences are unsupported", PLATFORM_FAILURE, 979 "GL fences are unsupported", PLATFORM_FAILURE,
1002 false); 980 false);
1003 981
1004 State state = GetState(); 982 State state = GetState();
1005 RETURN_AND_NOTIFY_ON_FAILURE((state == kUninitialized), 983 RETURN_AND_NOTIFY_ON_FAILURE((state == kUninitialized),
1006 "Initialize: invalid state: " << state, ILLEGAL_STATE, false); 984 "Initialize: invalid state: " << state,
985 ILLEGAL_STATE, false);
1007 986
1008 media::InitializeMediaFoundation(); 987 media::InitializeMediaFoundation();
1009 988
1010 RETURN_AND_NOTIFY_ON_FAILURE(InitDecoder(config.profile), 989 RETURN_AND_NOTIFY_ON_FAILURE(InitDecoder(config.profile),
1011 "Failed to initialize decoder", PLATFORM_FAILURE, false); 990 "Failed to initialize decoder", PLATFORM_FAILURE,
991 false);
1012 992
1013 RETURN_AND_NOTIFY_ON_FAILURE(GetStreamsInfoAndBufferReqs(), 993 RETURN_AND_NOTIFY_ON_FAILURE(GetStreamsInfoAndBufferReqs(),
1014 "Failed to get input/output stream info.", PLATFORM_FAILURE, false); 994 "Failed to get input/output stream info.",
995 PLATFORM_FAILURE, false);
1015 996
1016 RETURN_AND_NOTIFY_ON_FAILURE( 997 RETURN_AND_NOTIFY_ON_FAILURE(
1017 SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0), 998 SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0),
1018 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed", 999 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed",
1019 PLATFORM_FAILURE, false); 1000 PLATFORM_FAILURE, false);
1020 1001
1021 RETURN_AND_NOTIFY_ON_FAILURE( 1002 RETURN_AND_NOTIFY_ON_FAILURE(
1022 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0), 1003 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0),
1023 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed", 1004 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed",
1024 PLATFORM_FAILURE, false); 1005 PLATFORM_FAILURE, false);
(...skipping 23 matching lines...) Expand all
1048 RETURN_ON_HR_FAILURE(hr, 1029 RETURN_ON_HR_FAILURE(hr,
1049 "D3D9 driver does not support H/W format conversion", false); 1030 "D3D9 driver does not support H/W format conversion", false);
1050 1031
1051 base::win::ScopedComPtr<IDirect3DDevice9> angle_device = 1032 base::win::ScopedComPtr<IDirect3DDevice9> angle_device =
1052 QueryDeviceObjectFromANGLE<IDirect3DDevice9>(EGL_D3D9_DEVICE_ANGLE); 1033 QueryDeviceObjectFromANGLE<IDirect3DDevice9>(EGL_D3D9_DEVICE_ANGLE);
1053 if (angle_device.get()) 1034 if (angle_device.get())
1054 using_angle_device_ = true; 1035 using_angle_device_ = true;
1055 1036
1056 if (using_angle_device_) { 1037 if (using_angle_device_) {
1057 hr = d3d9_device_ex_.QueryFrom(angle_device.get()); 1038 hr = d3d9_device_ex_.QueryFrom(angle_device.get());
1058 RETURN_ON_HR_FAILURE(hr, 1039 RETURN_ON_HR_FAILURE(
1059 "QueryInterface for IDirect3DDevice9Ex from angle device failed", 1040 hr, "QueryInterface for IDirect3DDevice9Ex from angle device failed",
1060 false); 1041 false);
1061 } else { 1042 } else {
1062 D3DPRESENT_PARAMETERS present_params = {0}; 1043 D3DPRESENT_PARAMETERS present_params = {0};
1063 present_params.BackBufferWidth = 1; 1044 present_params.BackBufferWidth = 1;
1064 present_params.BackBufferHeight = 1; 1045 present_params.BackBufferHeight = 1;
1065 present_params.BackBufferFormat = D3DFMT_UNKNOWN; 1046 present_params.BackBufferFormat = D3DFMT_UNKNOWN;
1066 present_params.BackBufferCount = 1; 1047 present_params.BackBufferCount = 1;
1067 present_params.SwapEffect = D3DSWAPEFFECT_DISCARD; 1048 present_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
1068 present_params.hDeviceWindow = NULL; 1049 present_params.hDeviceWindow = NULL;
1069 present_params.Windowed = TRUE; 1050 present_params.Windowed = TRUE;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 1083
1103 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { 1084 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
1104 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, 1085 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_,
1105 d3d11_device_manager_.Receive()); 1086 d3d11_device_manager_.Receive());
1106 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); 1087 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false);
1107 1088
1108 // This array defines the set of DirectX hardware feature levels we support. 1089 // This array defines the set of DirectX hardware feature levels we support.
1109 // The ordering MUST be preserved. All applications are assumed to support 1090 // The ordering MUST be preserved. All applications are assumed to support
1110 // 9.1 unless otherwise stated by the application. 1091 // 9.1 unless otherwise stated by the application.
1111 D3D_FEATURE_LEVEL feature_levels[] = { 1092 D3D_FEATURE_LEVEL feature_levels[] = {
1112 D3D_FEATURE_LEVEL_11_1, 1093 D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1,
1113 D3D_FEATURE_LEVEL_11_0, 1094 D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2,
1114 D3D_FEATURE_LEVEL_10_1, 1095 D3D_FEATURE_LEVEL_9_1};
1115 D3D_FEATURE_LEVEL_10_0,
1116 D3D_FEATURE_LEVEL_9_3,
1117 D3D_FEATURE_LEVEL_9_2,
1118 D3D_FEATURE_LEVEL_9_1
1119 };
1120 1096
1121 UINT flags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; 1097 UINT flags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
1122 1098
1123 #if defined _DEBUG 1099 #if defined _DEBUG
1124 flags |= D3D11_CREATE_DEVICE_DEBUG; 1100 flags |= D3D11_CREATE_DEVICE_DEBUG;
1125 #endif 1101 #endif
1126 1102
1127 D3D_FEATURE_LEVEL feature_level_out = D3D_FEATURE_LEVEL_11_0; 1103 D3D_FEATURE_LEVEL feature_level_out = D3D_FEATURE_LEVEL_11_0;
1128 hr = D3D11CreateDevice(NULL, 1104 hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags,
1129 D3D_DRIVER_TYPE_HARDWARE, 1105 feature_levels, arraysize(feature_levels),
1130 NULL, 1106 D3D11_SDK_VERSION, d3d11_device_.Receive(),
1131 flags, 1107 &feature_level_out, d3d11_device_context_.Receive());
1132 feature_levels,
1133 arraysize(feature_levels),
1134 D3D11_SDK_VERSION,
1135 d3d11_device_.Receive(),
1136 &feature_level_out,
1137 d3d11_device_context_.Receive());
1138 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device", false); 1108 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device", false);
1139 1109
1140 // Enable multithreaded mode on the device. This ensures that accesses to 1110 // Enable multithreaded mode on the device. This ensures that accesses to
1141 // context are synchronized across threads. We have multiple threads 1111 // context are synchronized across threads. We have multiple threads
1142 // accessing the context, the media foundation decoder threads and the 1112 // accessing the context, the media foundation decoder threads and the
1143 // decoder thread via the video format conversion transform. 1113 // decoder thread via the video format conversion transform.
1144 hr = multi_threaded_.QueryFrom(d3d11_device_.get()); 1114 hr = multi_threaded_.QueryFrom(d3d11_device_.get());
1145 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false); 1115 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false);
1146 multi_threaded_->SetMultithreadProtected(TRUE); 1116 multi_threaded_->SetMultithreadProtected(TRUE);
1147 1117
1148 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), 1118 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(),
1149 dx11_dev_manager_reset_token_); 1119 dx11_dev_manager_reset_token_);
1150 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 1120 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false);
1151 1121
1152 D3D11_QUERY_DESC query_desc; 1122 D3D11_QUERY_DESC query_desc;
1153 query_desc.Query = D3D11_QUERY_EVENT; 1123 query_desc.Query = D3D11_QUERY_EVENT;
1154 query_desc.MiscFlags = 0; 1124 query_desc.MiscFlags = 0;
1155 hr = d3d11_device_->CreateQuery( 1125 hr = d3d11_device_->CreateQuery(&query_desc, d3d11_query_.Receive());
1156 &query_desc,
1157 d3d11_query_.Receive());
1158 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); 1126 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false);
1159 1127
1160 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); 1128 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll");
1161 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", 1129 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor",
1162 false); 1130 false);
1163 1131
1164 hr = CreateCOMObjectFromDll( 1132 hr = CreateCOMObjectFromDll(video_processor_dll, CLSID_VideoProcessorMFT,
1165 video_processor_dll, 1133 __uuidof(IMFTransform),
1166 CLSID_VideoProcessorMFT, 1134 video_format_converter_mft_.ReceiveVoid());
1167 __uuidof(IMFTransform),
1168 video_format_converter_mft_.ReceiveVoid());
1169 if (FAILED(hr)) { 1135 if (FAILED(hr)) {
1170 base::debug::Alias(&hr); 1136 base::debug::Alias(&hr);
1171 // TODO(ananta) 1137 // TODO(ananta)
1172 // Remove this CHECK when the change to use DX11 for H/W decoding 1138 // Remove this CHECK when the change to use DX11 for H/W decoding
1173 // stablizes. 1139 // stablizes.
1174 CHECK(false); 1140 CHECK(false);
1175 } 1141 }
1176 1142
1177 RETURN_ON_HR_FAILURE(hr, "Failed to create video format converter", false); 1143 RETURN_ON_HR_FAILURE(hr, "Failed to create video format converter", false);
1178 1144
1179 base::win::ScopedComPtr<IMFAttributes> converter_attributes; 1145 base::win::ScopedComPtr<IMFAttributes> converter_attributes;
1180 hr = video_format_converter_mft_->GetAttributes( 1146 hr = video_format_converter_mft_->GetAttributes(
1181 converter_attributes.Receive()); 1147 converter_attributes.Receive());
1182 RETURN_ON_HR_FAILURE(hr, "Failed to get converter attributes", false); 1148 RETURN_ON_HR_FAILURE(hr, "Failed to get converter attributes", false);
1183 1149
1184 hr = converter_attributes->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE); 1150 hr = converter_attributes->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE);
1185 RETURN_ON_HR_FAILURE( 1151 RETURN_ON_HR_FAILURE(
1186 hr, 1152 hr, "Failed to set MF_XVP_PLAYBACK_MODE attribute on converter", false);
1187 "Failed to set MF_XVP_PLAYBACK_MODE attribute on converter",
1188 false);
1189 1153
1190 hr = converter_attributes->SetUINT32(MF_LOW_LATENCY, FALSE); 1154 hr = converter_attributes->SetUINT32(MF_LOW_LATENCY, FALSE);
1191 RETURN_ON_HR_FAILURE( 1155 RETURN_ON_HR_FAILURE(
1192 hr, 1156 hr, "Failed to set MF_LOW_LATENCY attribute on converter", false);
1193 "Failed to set MF_LOW_LATENCY attribute on converter",
1194 false);
1195 return true; 1157 return true;
1196 } 1158 }
1197 1159
1198 void DXVAVideoDecodeAccelerator::Decode( 1160 void DXVAVideoDecodeAccelerator::Decode(
1199 const media::BitstreamBuffer& bitstream_buffer) { 1161 const media::BitstreamBuffer& bitstream_buffer) {
1200 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1162 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1201 1163
1202 // SharedMemory will take over the ownership of handle. 1164 // SharedMemory will take over the ownership of handle.
1203 base::SharedMemory shm(bitstream_buffer.handle(), true); 1165 base::SharedMemory shm(bitstream_buffer.handle(), true);
1204 1166
1205 State state = GetState(); 1167 State state = GetState();
1206 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped || 1168 RETURN_AND_NOTIFY_ON_FAILURE(
1207 state == kFlushing), 1169 (state == kNormal || state == kStopped || state == kFlushing),
1208 "Invalid state: " << state, ILLEGAL_STATE,); 1170 "Invalid state: " << state, ILLEGAL_STATE, );
1209 if (bitstream_buffer.id() < 0) { 1171 if (bitstream_buffer.id() < 0) {
1210 RETURN_AND_NOTIFY_ON_FAILURE( 1172 RETURN_AND_NOTIFY_ON_FAILURE(
1211 false, "Invalid bitstream_buffer, id: " << bitstream_buffer.id(), 1173 false, "Invalid bitstream_buffer, id: " << bitstream_buffer.id(),
1212 INVALID_ARGUMENT, ); 1174 INVALID_ARGUMENT, );
1213 } 1175 }
1214 1176
1215 base::win::ScopedComPtr<IMFSample> sample; 1177 base::win::ScopedComPtr<IMFSample> sample;
1216 RETURN_AND_NOTIFY_ON_FAILURE(shm.Map(bitstream_buffer.size()), 1178 RETURN_AND_NOTIFY_ON_FAILURE(shm.Map(bitstream_buffer.size()),
1217 "Failed in base::SharedMemory::Map", 1179 "Failed in base::SharedMemory::Map",
1218 PLATFORM_FAILURE, ); 1180 PLATFORM_FAILURE, );
1219 1181
1220 sample.Attach(CreateInputSample( 1182 sample.Attach(CreateInputSample(
1221 reinterpret_cast<const uint8_t*>(shm.memory()), bitstream_buffer.size(), 1183 reinterpret_cast<const uint8_t*>(shm.memory()), bitstream_buffer.size(),
1222 std::min<uint32_t>(bitstream_buffer.size(), input_stream_info_.cbSize), 1184 std::min<uint32_t>(bitstream_buffer.size(), input_stream_info_.cbSize),
1223 input_stream_info_.cbAlignment)); 1185 input_stream_info_.cbAlignment));
1224 RETURN_AND_NOTIFY_ON_FAILURE(sample.get(), "Failed to create input sample", 1186 RETURN_AND_NOTIFY_ON_FAILURE(sample.get(), "Failed to create input sample",
1225 PLATFORM_FAILURE, ); 1187 PLATFORM_FAILURE, );
1226 1188
1227 RETURN_AND_NOTIFY_ON_HR_FAILURE(sample->SetSampleTime(bitstream_buffer.id()), 1189 RETURN_AND_NOTIFY_ON_HR_FAILURE(
1228 "Failed to associate input buffer id with sample", PLATFORM_FAILURE,); 1190 sample->SetSampleTime(bitstream_buffer.id()),
1191 "Failed to associate input buffer id with sample", PLATFORM_FAILURE, );
1229 1192
1230 decoder_thread_task_runner_->PostTask( 1193 decoder_thread_task_runner_->PostTask(
1231 FROM_HERE, 1194 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::DecodeInternal,
1232 base::Bind(&DXVAVideoDecodeAccelerator::DecodeInternal, 1195 base::Unretained(this), sample));
1233 base::Unretained(this), sample));
1234 } 1196 }
1235 1197
1236 void DXVAVideoDecodeAccelerator::AssignPictureBuffers( 1198 void DXVAVideoDecodeAccelerator::AssignPictureBuffers(
1237 const std::vector<media::PictureBuffer>& buffers) { 1199 const std::vector<media::PictureBuffer>& buffers) {
1238 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1200 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1239 1201
1240 State state = GetState(); 1202 State state = GetState();
1241 RETURN_AND_NOTIFY_ON_FAILURE((state != kUninitialized), 1203 RETURN_AND_NOTIFY_ON_FAILURE((state != kUninitialized),
1242 "Invalid state: " << state, ILLEGAL_STATE,); 1204 "Invalid state: " << state, ILLEGAL_STATE, );
1243 RETURN_AND_NOTIFY_ON_FAILURE((kNumPictureBuffers >= buffers.size()), 1205 RETURN_AND_NOTIFY_ON_FAILURE(
1244 "Failed to provide requested picture buffers. (Got " << buffers.size() << 1206 (kNumPictureBuffers >= buffers.size()),
1245 ", requested " << kNumPictureBuffers << ")", INVALID_ARGUMENT,); 1207 "Failed to provide requested picture buffers. (Got "
1208 << buffers.size() << ", requested " << kNumPictureBuffers << ")",
1209 INVALID_ARGUMENT, );
1246 1210
1247 // Copy the picture buffers provided by the client to the available list, 1211 // Copy the picture buffers provided by the client to the available list,
1248 // and mark these buffers as available for use. 1212 // and mark these buffers as available for use.
1249 for (size_t buffer_index = 0; buffer_index < buffers.size(); 1213 for (size_t buffer_index = 0; buffer_index < buffers.size(); ++buffer_index) {
1250 ++buffer_index) {
1251 DCHECK_LE(1u, buffers[buffer_index].texture_ids().size()); 1214 DCHECK_LE(1u, buffers[buffer_index].texture_ids().size());
1252 linked_ptr<DXVAPictureBuffer> picture_buffer = 1215 linked_ptr<DXVAPictureBuffer> picture_buffer =
1253 DXVAPictureBuffer::Create(*this, buffers[buffer_index], egl_config_); 1216 DXVAPictureBuffer::Create(*this, buffers[buffer_index], egl_config_);
1254 RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer.get(), 1217 RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer.get(),
1255 "Failed to allocate picture buffer", PLATFORM_FAILURE,); 1218 "Failed to allocate picture buffer",
1219 PLATFORM_FAILURE, );
1256 1220
1257 bool inserted = output_picture_buffers_.insert(std::make_pair( 1221 bool inserted =
1258 buffers[buffer_index].id(), picture_buffer)).second; 1222 output_picture_buffers_
1223 .insert(std::make_pair(buffers[buffer_index].id(), picture_buffer))
1224 .second;
1259 DCHECK(inserted); 1225 DCHECK(inserted);
1260 } 1226 }
1261 1227
1262 ProcessPendingSamples(); 1228 ProcessPendingSamples();
1263 if (pending_flush_) { 1229 if (pending_flush_) {
1264 decoder_thread_task_runner_->PostTask( 1230 decoder_thread_task_runner_->PostTask(
1265 FROM_HERE, 1231 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
1266 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, 1232 base::Unretained(this)));
1267 base::Unretained(this)));
1268 } 1233 }
1269 } 1234 }
1270 1235
1271 void DXVAVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) { 1236 void DXVAVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) {
1272 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1237 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1273 1238
1274 State state = GetState(); 1239 State state = GetState();
1275 RETURN_AND_NOTIFY_ON_FAILURE((state != kUninitialized), 1240 RETURN_AND_NOTIFY_ON_FAILURE((state != kUninitialized),
1276 "Invalid state: " << state, ILLEGAL_STATE,); 1241 "Invalid state: " << state, ILLEGAL_STATE, );
1277 1242
1278 if (output_picture_buffers_.empty() && stale_output_picture_buffers_.empty()) 1243 if (output_picture_buffers_.empty() && stale_output_picture_buffers_.empty())
1279 return; 1244 return;
1280 1245
1281 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); 1246 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
1282 // If we didn't find the picture id in the |output_picture_buffers_| map we 1247 // If we didn't find the picture id in the |output_picture_buffers_| map we
1283 // try the |stale_output_picture_buffers_| map, as this may have been an 1248 // try the |stale_output_picture_buffers_| map, as this may have been an
1284 // output picture buffer from before a resolution change, that at resolution 1249 // output picture buffer from before a resolution change, that at resolution
1285 // change time had yet to be displayed. The client is calling us back to tell 1250 // change time had yet to be displayed. The client is calling us back to tell
1286 // us that we can now recycle this picture buffer, so if we were waiting to 1251 // us that we can now recycle this picture buffer, so if we were waiting to
1287 // dispose of it we now can. 1252 // dispose of it we now can.
1288 if (it == output_picture_buffers_.end()) { 1253 if (it == output_picture_buffers_.end()) {
1289 if (!stale_output_picture_buffers_.empty()) { 1254 if (!stale_output_picture_buffers_.empty()) {
1290 it = stale_output_picture_buffers_.find(picture_buffer_id); 1255 it = stale_output_picture_buffers_.find(picture_buffer_id);
1291 RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(), 1256 RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(),
1292 "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,); 1257 "Invalid picture id: " << picture_buffer_id,
1258 INVALID_ARGUMENT, );
1293 main_thread_task_runner_->PostTask( 1259 main_thread_task_runner_->PostTask(
1294 FROM_HERE, 1260 FROM_HERE,
1295 base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer, 1261 base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer,
1296 weak_this_factory_.GetWeakPtr(), picture_buffer_id)); 1262 weak_this_factory_.GetWeakPtr(), picture_buffer_id));
1297 } 1263 }
1298 return; 1264 return;
1299 } 1265 }
1300 1266
1301 if (it->second->available() || it->second->waiting_to_reuse()) 1267 if (it->second->available() || it->second->waiting_to_reuse())
1302 return; 1268 return;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); 1312 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
1347 return; 1313 return;
1348 } 1314 }
1349 RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer->ReusePictureBuffer(), 1315 RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer->ReusePictureBuffer(),
1350 "Failed to reuse picture buffer", 1316 "Failed to reuse picture buffer",
1351 PLATFORM_FAILURE, ); 1317 PLATFORM_FAILURE, );
1352 1318
1353 ProcessPendingSamples(); 1319 ProcessPendingSamples();
1354 if (pending_flush_) { 1320 if (pending_flush_) {
1355 decoder_thread_task_runner_->PostTask( 1321 decoder_thread_task_runner_->PostTask(
1356 FROM_HERE, 1322 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
1357 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, 1323 base::Unretained(this)));
1358 base::Unretained(this)));
1359 } 1324 }
1360 } 1325 }
1361 1326
1362 void DXVAVideoDecodeAccelerator::Flush() { 1327 void DXVAVideoDecodeAccelerator::Flush() {
1363 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1328 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1364 1329
1365 DVLOG(1) << "DXVAVideoDecodeAccelerator::Flush"; 1330 DVLOG(1) << "DXVAVideoDecodeAccelerator::Flush";
1366 1331
1367 State state = GetState(); 1332 State state = GetState();
1368 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped), 1333 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped),
1369 "Unexpected decoder state: " << state, ILLEGAL_STATE,); 1334 "Unexpected decoder state: " << state,
1335 ILLEGAL_STATE, );
1370 1336
1371 SetState(kFlushing); 1337 SetState(kFlushing);
1372 1338
1373 pending_flush_ = true; 1339 pending_flush_ = true;
1374 1340
1375 decoder_thread_task_runner_->PostTask( 1341 decoder_thread_task_runner_->PostTask(
1376 FROM_HERE, 1342 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
1377 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, 1343 base::Unretained(this)));
1378 base::Unretained(this)));
1379 } 1344 }
1380 1345
1381 void DXVAVideoDecodeAccelerator::Reset() { 1346 void DXVAVideoDecodeAccelerator::Reset() {
1382 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1347 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1383 1348
1384 DVLOG(1) << "DXVAVideoDecodeAccelerator::Reset"; 1349 DVLOG(1) << "DXVAVideoDecodeAccelerator::Reset";
1385 1350
1386 State state = GetState(); 1351 State state = GetState();
1387 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped), 1352 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped),
1388 "Reset: invalid state: " << state, ILLEGAL_STATE,); 1353 "Reset: invalid state: " << state,
1354 ILLEGAL_STATE, );
1389 1355
1390 decoder_thread_.Stop(); 1356 decoder_thread_.Stop();
1391 1357
1392 SetState(kResetting); 1358 SetState(kResetting);
1393 1359
1394 // If we have pending output frames waiting for display then we drop those 1360 // If we have pending output frames waiting for display then we drop those
1395 // frames and set the corresponding picture buffer as available. 1361 // frames and set the corresponding picture buffer as available.
1396 PendingOutputSamples::iterator index; 1362 PendingOutputSamples::iterator index;
1397 for (index = pending_output_samples_.begin(); 1363 for (index = pending_output_samples_.begin();
1398 index != pending_output_samples_.end(); 1364 index != pending_output_samples_.end(); ++index) {
1399 ++index) {
1400 if (index->picture_buffer_id != -1) { 1365 if (index->picture_buffer_id != -1) {
1401 OutputBuffers::iterator it = output_picture_buffers_.find( 1366 OutputBuffers::iterator it =
1402 index->picture_buffer_id); 1367 output_picture_buffers_.find(index->picture_buffer_id);
1403 if (it != output_picture_buffers_.end()) { 1368 if (it != output_picture_buffers_.end()) {
1404 DXVAPictureBuffer* picture_buffer = it->second.get(); 1369 DXVAPictureBuffer* picture_buffer = it->second.get();
1405 picture_buffer->ReusePictureBuffer(); 1370 picture_buffer->ReusePictureBuffer();
1406 } 1371 }
1407 } 1372 }
1408 } 1373 }
1409 1374
1410 pending_output_samples_.clear(); 1375 pending_output_samples_.clear();
1411 1376
1412 NotifyInputBuffersDropped(); 1377 NotifyInputBuffersDropped();
1413 1378
1414 RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0), 1379 RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0),
1415 "Reset: Failed to send message.", PLATFORM_FAILURE,); 1380 "Reset: Failed to send message.",
1381 PLATFORM_FAILURE, );
1416 1382
1417 main_thread_task_runner_->PostTask( 1383 main_thread_task_runner_->PostTask(
1418 FROM_HERE, 1384 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::NotifyResetDone,
1419 base::Bind(&DXVAVideoDecodeAccelerator::NotifyResetDone, 1385 weak_this_factory_.GetWeakPtr()));
1420 weak_this_factory_.GetWeakPtr()));
1421 1386
1422 StartDecoderThread(); 1387 StartDecoderThread();
1423 SetState(kNormal); 1388 SetState(kNormal);
1424 } 1389 }
1425 1390
1426 void DXVAVideoDecodeAccelerator::Destroy() { 1391 void DXVAVideoDecodeAccelerator::Destroy() {
1427 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1392 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1428 Invalidate(); 1393 Invalidate();
1429 delete this; 1394 delete this;
1430 } 1395 }
1431 1396
1432 bool DXVAVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( 1397 bool DXVAVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1433 const base::WeakPtr<Client>& decode_client, 1398 const base::WeakPtr<Client>& decode_client,
1434 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { 1399 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1435 return false; 1400 return false;
1436 } 1401 }
1437 1402
1438 GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const { 1403 GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const {
1439 return GL_BGRA_EXT; 1404 return GL_BGRA_EXT;
1440 } 1405 }
1441 1406
1442 // static 1407 // static
1443 media::VideoDecodeAccelerator::SupportedProfiles 1408 media::VideoDecodeAccelerator::SupportedProfiles
1444 DXVAVideoDecodeAccelerator::GetSupportedProfiles() { 1409 DXVAVideoDecodeAccelerator::GetSupportedProfiles() {
1445 TRACE_EVENT0("gpu,startup", 1410 TRACE_EVENT0("gpu,startup",
1446 "DXVAVideoDecodeAccelerator::GetSupportedProfiles"); 1411 "DXVAVideoDecodeAccelerator::GetSupportedProfiles");
1447 1412
1448 // TODO(henryhsu): Need to ensure the profiles are actually supported. 1413 // TODO(henryhsu): Need to ensure the profiles are actually supported.
1449 SupportedProfiles profiles; 1414 SupportedProfiles profiles;
1450 for (const auto& supported_profile : kSupportedProfiles) { 1415 for (const auto& supported_profile : kSupportedProfiles) {
1451 std::pair<int, int> min_resolution = GetMinResolution(supported_profile); 1416 std::pair<int, int> min_resolution = GetMinResolution(supported_profile);
1452 std::pair<int, int> max_resolution = GetMaxResolution(supported_profile); 1417 std::pair<int, int> max_resolution = GetMaxResolution(supported_profile);
1453 1418
1454 SupportedProfile profile; 1419 SupportedProfile profile;
1455 profile.profile = supported_profile; 1420 profile.profile = supported_profile;
1456 profile.min_resolution.SetSize(min_resolution.first, min_resolution.second); 1421 profile.min_resolution.SetSize(min_resolution.first, min_resolution.second);
(...skipping 15 matching lines...) Expand all
1472 } else { 1437 } else {
1473 #if defined(ENABLE_DX11_FOR_WIN7) 1438 #if defined(ENABLE_DX11_FOR_WIN7)
1474 LoadLibrary(L"mshtmlmedia.dll"); 1439 LoadLibrary(L"mshtmlmedia.dll");
1475 #endif 1440 #endif
1476 } 1441 }
1477 } 1442 }
1478 1443
1479 // static 1444 // static
1480 std::pair<int, int> DXVAVideoDecodeAccelerator::GetMinResolution( 1445 std::pair<int, int> DXVAVideoDecodeAccelerator::GetMinResolution(
1481 media::VideoCodecProfile profile) { 1446 media::VideoCodecProfile profile) {
1482 TRACE_EVENT0("gpu,startup", 1447 TRACE_EVENT0("gpu,startup", "DXVAVideoDecodeAccelerator::GetMinResolution");
1483 "DXVAVideoDecodeAccelerator::GetMinResolution");
1484 std::pair<int, int> min_resolution; 1448 std::pair<int, int> min_resolution;
1485 if (profile >= media::H264PROFILE_BASELINE && 1449 if (profile >= media::H264PROFILE_BASELINE &&
1486 profile <= media::H264PROFILE_HIGH) { 1450 profile <= media::H264PROFILE_HIGH) {
1487 // Windows Media Foundation H.264 decoding does not support decoding videos 1451 // Windows Media Foundation H.264 decoding does not support decoding videos
1488 // with any dimension smaller than 48 pixels: 1452 // with any dimension smaller than 48 pixels:
1489 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 1453 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815
1490 min_resolution = std::make_pair(48, 48); 1454 min_resolution = std::make_pair(48, 48);
1491 } else { 1455 } else {
1492 // TODO(ananta) 1456 // TODO(ananta)
1493 // Detect this properly for VP8/VP9 profiles. 1457 // Detect this properly for VP8/VP9 profiles.
1494 min_resolution = std::make_pair(16, 16); 1458 min_resolution = std::make_pair(16, 16);
1495 } 1459 }
1496 return min_resolution; 1460 return min_resolution;
1497 } 1461 }
1498 1462
1499 // static 1463 // static
1500 std::pair<int, int> DXVAVideoDecodeAccelerator::GetMaxResolution( 1464 std::pair<int, int> DXVAVideoDecodeAccelerator::GetMaxResolution(
1501 const media::VideoCodecProfile profile) { 1465 const media::VideoCodecProfile profile) {
1502 TRACE_EVENT0("gpu,startup", 1466 TRACE_EVENT0("gpu,startup", "DXVAVideoDecodeAccelerator::GetMaxResolution");
1503 "DXVAVideoDecodeAccelerator::GetMaxResolution");
1504 std::pair<int, int> max_resolution; 1467 std::pair<int, int> max_resolution;
1505 if (profile >= media::H264PROFILE_BASELINE && 1468 if (profile >= media::H264PROFILE_BASELINE &&
1506 profile <= media::H264PROFILE_HIGH) { 1469 profile <= media::H264PROFILE_HIGH) {
1507 max_resolution = GetMaxH264Resolution(); 1470 max_resolution = GetMaxH264Resolution();
1508 } else { 1471 } else {
1509 // TODO(ananta) 1472 // TODO(ananta)
1510 // Detect this properly for VP8/VP9 profiles. 1473 // Detect this properly for VP8/VP9 profiles.
1511 max_resolution = std::make_pair(4096, 2160); 1474 max_resolution = std::make_pair(4096, 2160);
1512 } 1475 }
1513 return max_resolution; 1476 return max_resolution;
(...skipping 18 matching lines...) Expand all
1532 return max_resolution; 1495 return max_resolution;
1533 1496
1534 // To detect if a driver supports the desired resolutions, we try and create 1497 // To detect if a driver supports the desired resolutions, we try and create
1535 // a DXVA decoder instance for that resolution and profile. If that succeeds 1498 // a DXVA decoder instance for that resolution and profile. If that succeeds
1536 // we assume that the driver supports H/W H.264 decoding for that resolution. 1499 // we assume that the driver supports H/W H.264 decoding for that resolution.
1537 HRESULT hr = E_FAIL; 1500 HRESULT hr = E_FAIL;
1538 base::win::ScopedComPtr<ID3D11Device> device; 1501 base::win::ScopedComPtr<ID3D11Device> device;
1539 1502
1540 { 1503 {
1541 TRACE_EVENT0("gpu,startup", 1504 TRACE_EVENT0("gpu,startup",
1542 "GetMaxH264Resolution. QueryDeviceObjectFromANGLE"); 1505 "GetMaxH264Resolution. QueryDeviceObjectFromANGLE");
1543 1506
1544 device = QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); 1507 device = QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE);
1545 if (!device.get()) 1508 if (!device.get())
1546 return max_resolution; 1509 return max_resolution;
1547 } 1510 }
1548 1511
1549 base::win::ScopedComPtr<ID3D11VideoDevice> video_device; 1512 base::win::ScopedComPtr<ID3D11VideoDevice> video_device;
1550 hr = device.QueryInterface(IID_ID3D11VideoDevice, 1513 hr = device.QueryInterface(__uuidof(ID3D11VideoDevice),
1551 video_device.ReceiveVoid()); 1514 video_device.ReceiveVoid());
1552 if (FAILED(hr)) 1515 if (FAILED(hr))
1553 return max_resolution; 1516 return max_resolution;
1554 1517
1555 GUID decoder_guid = {}; 1518 GUID decoder_guid = {};
1556 1519
1557 { 1520 {
1558 TRACE_EVENT0("gpu,startup", 1521 TRACE_EVENT0("gpu,startup",
1559 "GetMaxH264Resolution. H.264 guid search begin"); 1522 "GetMaxH264Resolution. H.264 guid search begin");
1560 // Enumerate supported video profiles and look for the H264 profile. 1523 // Enumerate supported video profiles and look for the H264 profile.
1561 bool found = false; 1524 bool found = false;
1562 UINT profile_count = video_device->GetVideoDecoderProfileCount(); 1525 UINT profile_count = video_device->GetVideoDecoderProfileCount();
1563 for (UINT profile_idx = 0; profile_idx < profile_count; profile_idx++) { 1526 for (UINT profile_idx = 0; profile_idx < profile_count; profile_idx++) {
1564 GUID profile_id = {}; 1527 GUID profile_id = {};
1565 hr = video_device->GetVideoDecoderProfile(profile_idx, &profile_id); 1528 hr = video_device->GetVideoDecoderProfile(profile_idx, &profile_id);
1566 if (SUCCEEDED(hr) && 1529 if (SUCCEEDED(hr) && (profile_id == DXVA2_ModeH264_E ||
1567 (profile_id == DXVA2_ModeH264_E || 1530 profile_id == DXVA2_Intel_ModeH264_E)) {
1568 profile_id == DXVA2_Intel_ModeH264_E)) {
1569 decoder_guid = profile_id; 1531 decoder_guid = profile_id;
1570 found = true; 1532 found = true;
1571 break; 1533 break;
1572 } 1534 }
1573 } 1535 }
1574 if (!found) 1536 if (!found)
1575 return max_resolution; 1537 return max_resolution;
1576 } 1538 }
1577 1539
1578 // Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while 1540 // Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while
1579 // creating surfaces larger than 1920 x 1088. 1541 // creating surfaces larger than 1920 x 1088.
1580 if (IsLegacyGPU(device.get())) 1542 if (IsLegacyGPU(device.get()))
1581 return max_resolution; 1543 return max_resolution;
1582 1544
1583 // We look for the following resolutions in the driver. 1545 // We look for the following resolutions in the driver.
1584 // TODO(ananta) 1546 // TODO(ananta)
1585 // Look into whether this list needs to be expanded. 1547 // Look into whether this list needs to be expanded.
1586 static std::pair<int, int> resolution_array[] = { 1548 static std::pair<int, int> resolution_array[] = {
1587 // Use 1088 to account for 16x16 macroblocks. 1549 // Use 1088 to account for 16x16 macroblocks.
1588 std::make_pair(1920, 1088), 1550 std::make_pair(1920, 1088), std::make_pair(2560, 1440),
1589 std::make_pair(2560, 1440), 1551 std::make_pair(3840, 2160), std::make_pair(4096, 2160),
1590 std::make_pair(3840, 2160), 1552 std::make_pair(4096, 2304),
1591 std::make_pair(4096, 2160),
1592 std::make_pair(4096, 2304),
1593 }; 1553 };
1594 1554
1595 { 1555 {
1596 TRACE_EVENT0("gpu,startup", 1556 TRACE_EVENT0("gpu,startup",
1597 "GetMaxH264Resolution. Resolution search begin"); 1557 "GetMaxH264Resolution. Resolution search begin");
1598 1558
1599 for (size_t res_idx = 0; res_idx < arraysize(resolution_array); 1559 for (size_t res_idx = 0; res_idx < arraysize(resolution_array); res_idx++) {
1600 res_idx++) {
1601 D3D11_VIDEO_DECODER_DESC desc = {}; 1560 D3D11_VIDEO_DECODER_DESC desc = {};
1602 desc.Guid = decoder_guid; 1561 desc.Guid = decoder_guid;
1603 desc.SampleWidth = resolution_array[res_idx].first; 1562 desc.SampleWidth = resolution_array[res_idx].first;
1604 desc.SampleHeight = resolution_array[res_idx].second; 1563 desc.SampleHeight = resolution_array[res_idx].second;
1605 desc.OutputFormat = DXGI_FORMAT_NV12; 1564 desc.OutputFormat = DXGI_FORMAT_NV12;
1606 UINT config_count = 0; 1565 UINT config_count = 0;
1607 hr = video_device->GetVideoDecoderConfigCount(&desc, &config_count); 1566 hr = video_device->GetVideoDecoderConfigCount(&desc, &config_count);
1608 if (FAILED(hr) || config_count == 0) 1567 if (FAILED(hr) || config_count == 0)
1609 return max_resolution; 1568 return max_resolution;
1610 1569
1611 D3D11_VIDEO_DECODER_CONFIG config = {}; 1570 D3D11_VIDEO_DECODER_CONFIG config = {};
1612 hr = video_device->GetVideoDecoderConfig(&desc, 0, &config); 1571 hr = video_device->GetVideoDecoderConfig(&desc, 0, &config);
1613 if (FAILED(hr)) 1572 if (FAILED(hr))
1614 return max_resolution; 1573 return max_resolution;
1615 1574
1616 base::win::ScopedComPtr<ID3D11VideoDecoder> video_decoder; 1575 base::win::ScopedComPtr<ID3D11VideoDecoder> video_decoder;
1617 hr = video_device->CreateVideoDecoder(&desc, &config, 1576 hr = video_device->CreateVideoDecoder(&desc, &config,
1618 video_decoder.Receive()); 1577 video_decoder.Receive());
1619 if (!video_decoder.get()) 1578 if (!video_decoder.get())
1620 return max_resolution; 1579 return max_resolution;
1621 1580
1622 max_resolution = resolution_array[res_idx]; 1581 max_resolution = resolution_array[res_idx];
1623 } 1582 }
1624 } 1583 }
1625 return max_resolution; 1584 return max_resolution;
1626 } 1585 }
1627 1586
1628 // static 1587 // static
(...skipping 23 matching lines...) Expand all
1652 1611
1653 DXGI_ADAPTER_DESC adapter_desc = {}; 1612 DXGI_ADAPTER_DESC adapter_desc = {};
1654 hr = adapter->GetDesc(&adapter_desc); 1613 hr = adapter->GetDesc(&adapter_desc);
1655 if (FAILED(hr)) 1614 if (FAILED(hr))
1656 return legacy_gpu; 1615 return legacy_gpu;
1657 1616
1658 // We check if the device is an Intel or an AMD device and whether it is in 1617 // We check if the device is an Intel or an AMD device and whether it is in
1659 // the global list defined by the g_AMDUVD3GPUList and g_IntelLegacyGPUList 1618 // the global list defined by the g_AMDUVD3GPUList and g_IntelLegacyGPUList
1660 // arrays above. If yes then the device is treated as a legacy device. 1619 // arrays above. If yes then the device is treated as a legacy device.
1661 if ((adapter_desc.VendorId == kAMDGPUId1) || 1620 if ((adapter_desc.VendorId == kAMDGPUId1) ||
1662 adapter_desc.VendorId == kAMDGPUId2) { 1621 adapter_desc.VendorId == kAMDGPUId2) {
1663 { 1622 {
1664 TRACE_EVENT0("gpu,startup", 1623 TRACE_EVENT0("gpu,startup",
1665 "DXVAVideoDecodeAccelerator::IsLegacyGPU. AMD check"); 1624 "DXVAVideoDecodeAccelerator::IsLegacyGPU. AMD check");
1666 for (size_t i = 0; i < arraysize(g_AMDUVD3GPUList); i++) { 1625 for (size_t i = 0; i < arraysize(g_AMDUVD3GPUList); i++) {
1667 if (adapter_desc.DeviceId == g_AMDUVD3GPUList[i]) 1626 if (adapter_desc.DeviceId == g_AMDUVD3GPUList[i])
1668 return legacy_gpu; 1627 return legacy_gpu;
1669 } 1628 }
1670 } 1629 }
1671 } else if (adapter_desc.VendorId == kIntelGPU) { 1630 } else if (adapter_desc.VendorId == kIntelGPU) {
1672 { 1631 {
1673 TRACE_EVENT0("gpu,startup", 1632 TRACE_EVENT0("gpu,startup",
1674 "DXVAVideoDecodeAccelerator::IsLegacyGPU. Intel check"); 1633 "DXVAVideoDecodeAccelerator::IsLegacyGPU. Intel check");
1675 for (size_t i = 0; i < arraysize(g_IntelLegacyGPUList); i++) { 1634 for (size_t i = 0; i < arraysize(g_IntelLegacyGPUList); i++) {
1676 if (adapter_desc.DeviceId == g_IntelLegacyGPUList[i]) 1635 if (adapter_desc.DeviceId == g_IntelLegacyGPUList[i])
1677 return legacy_gpu; 1636 return legacy_gpu;
1678 } 1637 }
1679 } 1638 }
1680 } 1639 }
1681 legacy_gpu = false; 1640 legacy_gpu = false;
1682 return legacy_gpu; 1641 return legacy_gpu;
1683 } 1642 }
1684 1643
(...skipping 11 matching lines...) Expand all
1696 decoder_dll = ::GetModuleHandle(L"msmpeg2vdec.dll"); 1655 decoder_dll = ::GetModuleHandle(L"msmpeg2vdec.dll");
1697 RETURN_ON_FAILURE(decoder_dll, 1656 RETURN_ON_FAILURE(decoder_dll,
1698 "msmpeg2vdec.dll required for decoding is not loaded", 1657 "msmpeg2vdec.dll required for decoding is not loaded",
1699 false); 1658 false);
1700 1659
1701 // Check version of DLL, version 6.1.7140 is blacklisted due to high crash 1660 // Check version of DLL, version 6.1.7140 is blacklisted due to high crash
1702 // rates in browsers loading that DLL. If that is the version installed we 1661 // rates in browsers loading that DLL. If that is the version installed we
1703 // fall back to software decoding. See crbug/403440. 1662 // fall back to software decoding. See crbug/403440.
1704 std::unique_ptr<FileVersionInfo> version_info( 1663 std::unique_ptr<FileVersionInfo> version_info(
1705 FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll)); 1664 FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll));
1706 RETURN_ON_FAILURE(version_info, 1665 RETURN_ON_FAILURE(version_info, "unable to get version of msmpeg2vdec.dll",
1707 "unable to get version of msmpeg2vdec.dll",
1708 false); 1666 false);
1709 base::string16 file_version = version_info->file_version(); 1667 base::string16 file_version = version_info->file_version();
1710 RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos, 1668 RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos,
1711 "blacklisted version of msmpeg2vdec.dll 6.1.7140", 1669 "blacklisted version of msmpeg2vdec.dll 6.1.7140", false);
1712 false);
1713 codec_ = media::kCodecH264; 1670 codec_ = media::kCodecH264;
1714 clsid = __uuidof(CMSH264DecoderMFT); 1671 clsid = __uuidof(CMSH264DecoderMFT);
1715 } else if (enable_accelerated_vpx_decode_ && 1672 } else if (enable_accelerated_vpx_decode_ &&
1716 (profile == media::VP8PROFILE_ANY || 1673 (profile == media::VP8PROFILE_ANY ||
1717 profile == media::VP9PROFILE_PROFILE0 || 1674 profile == media::VP9PROFILE_PROFILE0 ||
1718 profile == media::VP9PROFILE_PROFILE1 || 1675 profile == media::VP9PROFILE_PROFILE1 ||
1719 profile == media::VP9PROFILE_PROFILE2 || 1676 profile == media::VP9PROFILE_PROFILE2 ||
1720 profile == media::VP9PROFILE_PROFILE3)) { 1677 profile == media::VP9PROFILE_PROFILE3)) {
1721 int program_files_key = base::DIR_PROGRAM_FILES; 1678 int program_files_key = base::DIR_PROGRAM_FILES;
1722 if (base::win::OSInfo::GetInstance()->wow64_status() == 1679 if (base::win::OSInfo::GetInstance()->wow64_status() ==
1723 base::win::OSInfo::WOW64_ENABLED) { 1680 base::win::OSInfo::WOW64_ENABLED) {
1724 program_files_key = base::DIR_PROGRAM_FILES6432; 1681 program_files_key = base::DIR_PROGRAM_FILES6432;
1725 } 1682 }
1726 1683
1727 base::FilePath dll_path; 1684 base::FilePath dll_path;
1728 RETURN_ON_FAILURE(PathService::Get(program_files_key, &dll_path), 1685 RETURN_ON_FAILURE(PathService::Get(program_files_key, &dll_path),
1729 "failed to get path for Program Files", false); 1686 "failed to get path for Program Files", false);
1730 1687
1731 dll_path = dll_path.Append(kVPXDecoderDLLPath); 1688 dll_path = dll_path.Append(kVPXDecoderDLLPath);
1732 if (profile == media::VP8PROFILE_ANY) { 1689 if (profile == media::VP8PROFILE_ANY) {
1733 codec_ = media::kCodecVP8; 1690 codec_ = media::kCodecVP8;
1734 dll_path = dll_path.Append(kVP8DecoderDLLName); 1691 dll_path = dll_path.Append(kVP8DecoderDLLName);
1735 clsid = CLSID_WebmMfVp8Dec; 1692 clsid = CLSID_WebmMfVp8Dec;
1736 } else { 1693 } else {
1737 codec_ = media::kCodecVP9; 1694 codec_ = media::kCodecVP9;
1738 dll_path = dll_path.Append(kVP9DecoderDLLName); 1695 dll_path = dll_path.Append(kVP9DecoderDLLName);
1739 clsid = CLSID_WebmMfVp9Dec; 1696 clsid = CLSID_WebmMfVp9Dec;
1740 } 1697 }
1741 decoder_dll = ::LoadLibraryEx(dll_path.value().data(), NULL, 1698 decoder_dll = ::LoadLibraryEx(dll_path.value().data(), NULL,
1742 LOAD_WITH_ALTERED_SEARCH_PATH); 1699 LOAD_WITH_ALTERED_SEARCH_PATH);
1743 RETURN_ON_FAILURE(decoder_dll, "vpx decoder dll is not loaded", false); 1700 RETURN_ON_FAILURE(decoder_dll, "vpx decoder dll is not loaded", false);
1744 } else { 1701 } else {
1745 RETURN_ON_FAILURE(false, "Unsupported codec.", false); 1702 RETURN_ON_FAILURE(false, "Unsupported codec.", false);
1746 } 1703 }
1747 1704
1748 HRESULT hr = CreateCOMObjectFromDll(decoder_dll, 1705 HRESULT hr = CreateCOMObjectFromDll(
1749 clsid, 1706 decoder_dll, clsid, __uuidof(IMFTransform), decoder_.ReceiveVoid());
1750 __uuidof(IMFTransform),
1751 decoder_.ReceiveVoid());
1752 RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false); 1707 RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false);
1753 1708
1754 RETURN_ON_FAILURE(CheckDecoderDxvaSupport(), 1709 RETURN_ON_FAILURE(CheckDecoderDxvaSupport(),
1755 "Failed to check decoder DXVA support", false); 1710 "Failed to check decoder DXVA support", false);
1756 1711
1757 ULONG_PTR device_manager_to_use = NULL; 1712 ULONG_PTR device_manager_to_use = NULL;
1758 if (use_dx11_) { 1713 if (use_dx11_) {
1759 CHECK(create_dxgi_device_manager_); 1714 CHECK(create_dxgi_device_manager_);
1760 RETURN_AND_NOTIFY_ON_FAILURE(CreateDX11DevManager(), 1715 RETURN_AND_NOTIFY_ON_FAILURE(CreateDX11DevManager(),
1761 "Failed to initialize DX11 device and manager", 1716 "Failed to initialize DX11 device and manager",
1762 PLATFORM_FAILURE, 1717 PLATFORM_FAILURE, false);
1763 false); 1718 device_manager_to_use =
1764 device_manager_to_use = reinterpret_cast<ULONG_PTR>( 1719 reinterpret_cast<ULONG_PTR>(d3d11_device_manager_.get());
1765 d3d11_device_manager_.get());
1766 } else { 1720 } else {
1767 RETURN_AND_NOTIFY_ON_FAILURE(CreateD3DDevManager(), 1721 RETURN_AND_NOTIFY_ON_FAILURE(CreateD3DDevManager(),
1768 "Failed to initialize D3D device and manager", 1722 "Failed to initialize D3D device and manager",
1769 PLATFORM_FAILURE, 1723 PLATFORM_FAILURE, false);
1770 false);
1771 device_manager_to_use = reinterpret_cast<ULONG_PTR>(device_manager_.get()); 1724 device_manager_to_use = reinterpret_cast<ULONG_PTR>(device_manager_.get());
1772 } 1725 }
1773 1726
1774 hr = decoder_->ProcessMessage( 1727 hr = decoder_->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER,
1775 MFT_MESSAGE_SET_D3D_MANAGER, 1728 device_manager_to_use);
1776 device_manager_to_use);
1777 if (use_dx11_) { 1729 if (use_dx11_) {
1778 RETURN_ON_HR_FAILURE(hr, "Failed to pass DX11 manager to decoder", false); 1730 RETURN_ON_HR_FAILURE(hr, "Failed to pass DX11 manager to decoder", false);
1779 } else { 1731 } else {
1780 RETURN_ON_HR_FAILURE(hr, "Failed to pass D3D manager to decoder", false); 1732 RETURN_ON_HR_FAILURE(hr, "Failed to pass D3D manager to decoder", false);
1781 } 1733 }
1782 1734
1783 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); 1735 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
1784 1736
1785 EGLint config_attribs[] = { 1737 EGLint config_attribs[] = {EGL_BUFFER_SIZE, 32,
1786 EGL_BUFFER_SIZE, 32, 1738 EGL_RED_SIZE, 8,
1787 EGL_RED_SIZE, 8, 1739 EGL_GREEN_SIZE, 8,
1788 EGL_GREEN_SIZE, 8, 1740 EGL_BLUE_SIZE, 8,
1789 EGL_BLUE_SIZE, 8, 1741 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
1790 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 1742 EGL_ALPHA_SIZE, 0,
1791 EGL_ALPHA_SIZE, 0, 1743 EGL_NONE};
1792 EGL_NONE
1793 };
1794 1744
1795 EGLint num_configs; 1745 EGLint num_configs;
1796 1746
1797 if (!eglChooseConfig( 1747 if (!eglChooseConfig(egl_display, config_attribs, &egl_config_, 1,
1798 egl_display, 1748 &num_configs))
1799 config_attribs,
1800 &egl_config_,
1801 1,
1802 &num_configs))
1803 return false; 1749 return false;
1804 1750
1805 return SetDecoderMediaTypes(); 1751 return SetDecoderMediaTypes();
1806 } 1752 }
1807 1753
1808 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { 1754 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() {
1809 base::win::ScopedComPtr<IMFAttributes> attributes; 1755 base::win::ScopedComPtr<IMFAttributes> attributes;
1810 HRESULT hr = decoder_->GetAttributes(attributes.Receive()); 1756 HRESULT hr = decoder_->GetAttributes(attributes.Receive());
1811 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); 1757 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false);
1812 1758
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 } 1861 }
1916 1862
1917 DVLOG(1) << "Min buffer size: " << input_stream_info_.cbSize; 1863 DVLOG(1) << "Min buffer size: " << input_stream_info_.cbSize;
1918 DVLOG(1) << "Max lookahead: " << input_stream_info_.cbMaxLookahead; 1864 DVLOG(1) << "Max lookahead: " << input_stream_info_.cbMaxLookahead;
1919 DVLOG(1) << "Alignment: " << input_stream_info_.cbAlignment; 1865 DVLOG(1) << "Alignment: " << input_stream_info_.cbAlignment;
1920 1866
1921 DVLOG(1) << "Output stream info: "; 1867 DVLOG(1) << "Output stream info: ";
1922 // The flags here should be the same and mean the same thing, except when 1868 // The flags here should be the same and mean the same thing, except when
1923 // DXVA is enabled, there is an extra 0x100 flag meaning decoder will 1869 // DXVA is enabled, there is an extra 0x100 flag meaning decoder will
1924 // allocate its own sample. 1870 // allocate its own sample.
1925 DVLOG(1) << "Flags: " 1871 DVLOG(1) << "Flags: " << std::hex << std::showbase
1926 << std::hex << std::showbase << output_stream_info_.dwFlags; 1872 << output_stream_info_.dwFlags;
1927 if (codec_ == media::kCodecH264) { 1873 if (codec_ == media::kCodecH264) {
1928 CHECK_EQ(output_stream_info_.dwFlags, 0x107u); 1874 CHECK_EQ(output_stream_info_.dwFlags, 0x107u);
1929 } 1875 }
1930 DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize; 1876 DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize;
1931 DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment; 1877 DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment;
1932 return true; 1878 return true;
1933 } 1879 }
1934 1880
1935 void DXVAVideoDecodeAccelerator::DoDecode() { 1881 void DXVAVideoDecodeAccelerator::DoDecode() {
1936 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 1882 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
1937 // This function is also called from FlushInternal in a loop which could 1883 // This function is also called from FlushInternal in a loop which could
1938 // result in the state transitioning to kStopped due to no decoded output. 1884 // result in the state transitioning to kStopped due to no decoded output.
1939 State state = GetState(); 1885 State state = GetState();
1940 RETURN_AND_NOTIFY_ON_FAILURE( 1886 RETURN_AND_NOTIFY_ON_FAILURE(
1941 (state == kNormal || state == kFlushing || state == kStopped), 1887 (state == kNormal || state == kFlushing || state == kStopped),
1942 "DoDecode: not in normal/flushing/stopped state", ILLEGAL_STATE,); 1888 "DoDecode: not in normal/flushing/stopped state", ILLEGAL_STATE, );
1943 1889
1944 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; 1890 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0};
1945 DWORD status = 0; 1891 DWORD status = 0;
1946 1892
1947 HRESULT hr = decoder_->ProcessOutput(0, // No flags 1893 HRESULT hr = decoder_->ProcessOutput(0, // No flags
1948 1, // # of out streams to pull from 1894 1, // # of out streams to pull from
1949 &output_data_buffer, 1895 &output_data_buffer, &status);
1950 &status);
1951 IMFCollection* events = output_data_buffer.pEvents; 1896 IMFCollection* events = output_data_buffer.pEvents;
1952 if (events != NULL) { 1897 if (events != NULL) {
1953 DVLOG(1) << "Got events from ProcessOuput, but discarding"; 1898 DVLOG(1) << "Got events from ProcessOuput, but discarding";
1954 events->Release(); 1899 events->Release();
1955 } 1900 }
1956 if (FAILED(hr)) { 1901 if (FAILED(hr)) {
1957 // A stream change needs further ProcessInput calls to get back decoder 1902 // A stream change needs further ProcessInput calls to get back decoder
1958 // output which is why we need to set the state to stopped. 1903 // output which is why we need to set the state to stopped.
1959 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { 1904 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
1960 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12)) { 1905 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12)) {
(...skipping 17 matching lines...) Expand all
1978 } 1923 }
1979 } 1924 }
1980 TRACE_EVENT_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", this); 1925 TRACE_EVENT_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", this);
1981 1926
1982 TRACE_COUNTER1("DXVA Decoding", "TotalPacketsBeforeDecode", 1927 TRACE_COUNTER1("DXVA Decoding", "TotalPacketsBeforeDecode",
1983 inputs_before_decode_); 1928 inputs_before_decode_);
1984 1929
1985 inputs_before_decode_ = 0; 1930 inputs_before_decode_ = 0;
1986 1931
1987 RETURN_AND_NOTIFY_ON_FAILURE(ProcessOutputSample(output_data_buffer.pSample), 1932 RETURN_AND_NOTIFY_ON_FAILURE(ProcessOutputSample(output_data_buffer.pSample),
1988 "Failed to process output sample.", PLATFORM_FAILURE,); 1933 "Failed to process output sample.",
1934 PLATFORM_FAILURE, );
1989 } 1935 }
1990 1936
1991 bool DXVAVideoDecodeAccelerator::ProcessOutputSample(IMFSample* sample) { 1937 bool DXVAVideoDecodeAccelerator::ProcessOutputSample(IMFSample* sample) {
1992 RETURN_ON_FAILURE(sample, "Decode succeeded with NULL output sample", false); 1938 RETURN_ON_FAILURE(sample, "Decode succeeded with NULL output sample", false);
1993 1939
1994 LONGLONG input_buffer_id = 0; 1940 LONGLONG input_buffer_id = 0;
1995 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id), 1941 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id),
1996 "Failed to get input buffer id associated with sample", 1942 "Failed to get input buffer id associated with sample",
1997 false); 1943 false);
1998 1944
(...skipping 15 matching lines...) Expand all
2014 1960
2015 int width = 0; 1961 int width = 0;
2016 int height = 0; 1962 int height = 0;
2017 if (!GetVideoFrameDimensions(sample, &width, &height)) { 1963 if (!GetVideoFrameDimensions(sample, &width, &height)) {
2018 RETURN_ON_FAILURE(false, "Failed to get D3D surface from output sample", 1964 RETURN_ON_FAILURE(false, "Failed to get D3D surface from output sample",
2019 false); 1965 false);
2020 } 1966 }
2021 1967
2022 // Go ahead and request picture buffers. 1968 // Go ahead and request picture buffers.
2023 main_thread_task_runner_->PostTask( 1969 main_thread_task_runner_->PostTask(
2024 FROM_HERE, 1970 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
2025 base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers, 1971 weak_this_factory_.GetWeakPtr(), width, height));
2026 weak_this_factory_.GetWeakPtr(),
2027 width,
2028 height));
2029 1972
2030 pictures_requested_ = true; 1973 pictures_requested_ = true;
2031 return true; 1974 return true;
2032 } 1975 }
2033 1976
2034 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() { 1977 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() {
2035 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1978 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2036 1979
2037 if (!output_picture_buffers_.size()) 1980 if (!output_picture_buffers_.size())
2038 return; 1981 return;
2039 1982
2040 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), 1983 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
2041 "Failed to make context current", 1984 "Failed to make context current",
2042 PLATFORM_FAILURE, ); 1985 PLATFORM_FAILURE, );
2043 1986
2044 OutputBuffers::iterator index; 1987 OutputBuffers::iterator index;
2045 1988
2046 for (index = output_picture_buffers_.begin(); 1989 for (index = output_picture_buffers_.begin();
2047 index != output_picture_buffers_.end() && 1990 index != output_picture_buffers_.end() && OutputSamplesPresent();
2048 OutputSamplesPresent();
2049 ++index) { 1991 ++index) {
2050 if (index->second->available()) { 1992 if (index->second->available()) {
2051 PendingSampleInfo* pending_sample = NULL; 1993 PendingSampleInfo* pending_sample = NULL;
2052 { 1994 {
2053 base::AutoLock lock(decoder_lock_); 1995 base::AutoLock lock(decoder_lock_);
2054 PendingSampleInfo& sample_info = pending_output_samples_.front(); 1996 PendingSampleInfo& sample_info = pending_output_samples_.front();
2055 if (sample_info.picture_buffer_id != -1) 1997 if (sample_info.picture_buffer_id != -1)
2056 continue; 1998 continue;
2057 pending_sample = &sample_info; 1999 pending_sample = &sample_info;
2058 } 2000 }
2059 2001
2060 int width = 0; 2002 int width = 0;
2061 int height = 0; 2003 int height = 0;
2062 if (!GetVideoFrameDimensions(pending_sample->output_sample.get(), 2004 if (!GetVideoFrameDimensions(pending_sample->output_sample.get(), &width,
2063 &width, &height)) { 2005 &height)) {
2064 RETURN_AND_NOTIFY_ON_FAILURE(false, 2006 RETURN_AND_NOTIFY_ON_FAILURE(
2065 "Failed to get D3D surface from output sample", PLATFORM_FAILURE,); 2007 false, "Failed to get D3D surface from output sample",
2008 PLATFORM_FAILURE, );
2066 } 2009 }
2067 2010
2068 if (width != index->second->size().width() || 2011 if (width != index->second->size().width() ||
2069 height != index->second->size().height()) { 2012 height != index->second->size().height()) {
2070 HandleResolutionChanged(width, height); 2013 HandleResolutionChanged(width, height);
2071 return; 2014 return;
2072 } 2015 }
2073 2016
2074 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2017 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2075 HRESULT hr = pending_sample->output_sample->GetBufferByIndex( 2018 HRESULT hr = pending_sample->output_sample->GetBufferByIndex(
2076 0, output_buffer.Receive()); 2019 0, output_buffer.Receive());
2077 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2020 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2078 "Failed to get buffer from output sample", PLATFORM_FAILURE,); 2021 hr, "Failed to get buffer from output sample", PLATFORM_FAILURE, );
2079 2022
2080 base::win::ScopedComPtr<IDirect3DSurface9> surface; 2023 base::win::ScopedComPtr<IDirect3DSurface9> surface;
2081 base::win::ScopedComPtr<ID3D11Texture2D> d3d11_texture; 2024 base::win::ScopedComPtr<ID3D11Texture2D> d3d11_texture;
2082 2025
2083 if (use_dx11_) { 2026 if (use_dx11_) {
2084 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer; 2027 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer;
2085 hr = dxgi_buffer.QueryFrom(output_buffer.get()); 2028 hr = dxgi_buffer.QueryFrom(output_buffer.get());
2086 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2029 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2087 "Failed to get DXGIBuffer from output sample", PLATFORM_FAILURE,); 2030 hr, "Failed to get DXGIBuffer from output sample",
2031 PLATFORM_FAILURE, );
2088 hr = dxgi_buffer->GetResource( 2032 hr = dxgi_buffer->GetResource(
2089 __uuidof(ID3D11Texture2D), 2033 __uuidof(ID3D11Texture2D),
2090 reinterpret_cast<void**>(d3d11_texture.Receive())); 2034 reinterpret_cast<void**>(d3d11_texture.Receive()));
2091 } else { 2035 } else {
2092 hr = MFGetService(output_buffer.get(), MR_BUFFER_SERVICE, 2036 hr = MFGetService(output_buffer.get(), MR_BUFFER_SERVICE,
2093 IID_PPV_ARGS(surface.Receive())); 2037 IID_PPV_ARGS(surface.Receive()));
2094 } 2038 }
2095 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2039 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2096 "Failed to get surface from output sample", PLATFORM_FAILURE,); 2040 hr, "Failed to get surface from output sample", PLATFORM_FAILURE, );
2097 2041
2098 pending_sample->picture_buffer_id = index->second->id(); 2042 pending_sample->picture_buffer_id = index->second->id();
2099 2043
2100 RETURN_AND_NOTIFY_ON_FAILURE( 2044 RETURN_AND_NOTIFY_ON_FAILURE(
2101 index->second->CopyOutputSampleDataToPictureBuffer( 2045 index->second->CopyOutputSampleDataToPictureBuffer(
2102 this, 2046 this, surface.get(), d3d11_texture.get(),
2103 surface.get(),
2104 d3d11_texture.get(),
2105 pending_sample->input_buffer_id), 2047 pending_sample->input_buffer_id),
2106 "Failed to copy output sample", PLATFORM_FAILURE,); 2048 "Failed to copy output sample", PLATFORM_FAILURE, );
2107 2049
2108 index->second->set_available(false); 2050 index->second->set_available(false);
2109 } 2051 }
2110 } 2052 }
2111 } 2053 }
2112 2054
2113 void DXVAVideoDecodeAccelerator::StopOnError( 2055 void DXVAVideoDecodeAccelerator::StopOnError(
2114 media::VideoDecodeAccelerator::Error error) { 2056 media::VideoDecodeAccelerator::Error error) {
2115 if (!main_thread_task_runner_->BelongsToCurrentThread()) { 2057 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
2116 main_thread_task_runner_->PostTask( 2058 main_thread_task_runner_->PostTask(
2117 FROM_HERE, 2059 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::StopOnError,
2118 base::Bind(&DXVAVideoDecodeAccelerator::StopOnError, 2060 weak_this_factory_.GetWeakPtr(), error));
2119 weak_this_factory_.GetWeakPtr(),
2120 error));
2121 return; 2061 return;
2122 } 2062 }
2123 2063
2124 if (client_) 2064 if (client_)
2125 client_->NotifyError(error); 2065 client_->NotifyError(error);
2126 client_ = NULL; 2066 client_ = NULL;
2127 2067
2128 if (GetState() != kUninitialized) { 2068 if (GetState() != kUninitialized) {
2129 Invalidate(); 2069 Invalidate();
2130 } 2070 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 2140
2201 void DXVAVideoDecodeAccelerator::RequestPictureBuffers(int width, int height) { 2141 void DXVAVideoDecodeAccelerator::RequestPictureBuffers(int width, int height) {
2202 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 2142 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2203 // This task could execute after the decoder has been torn down. 2143 // This task could execute after the decoder has been torn down.
2204 if (GetState() != kUninitialized && client_) { 2144 if (GetState() != kUninitialized && client_) {
2205 client_->ProvidePictureBuffers(kNumPictureBuffers, 1, 2145 client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
2206 gfx::Size(width, height), GL_TEXTURE_2D); 2146 gfx::Size(width, height), GL_TEXTURE_2D);
2207 } 2147 }
2208 } 2148 }
2209 2149
2210 void DXVAVideoDecodeAccelerator::NotifyPictureReady( 2150 void DXVAVideoDecodeAccelerator::NotifyPictureReady(int picture_buffer_id,
2211 int picture_buffer_id, 2151 int input_buffer_id) {
2212 int input_buffer_id) {
2213 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 2152 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2214 // This task could execute after the decoder has been torn down. 2153 // This task could execute after the decoder has been torn down.
2215 if (GetState() != kUninitialized && client_) { 2154 if (GetState() != kUninitialized && client_) {
2216 // TODO(henryhsu): Use correct visible size instead of (0, 0). We can't use 2155 // TODO(henryhsu): Use correct visible size instead of (0, 0). We can't use
2217 // coded size here so use (0, 0) intentionally to have the client choose. 2156 // coded size here so use (0, 0) intentionally to have the client choose.
2218 media::Picture picture(picture_buffer_id, input_buffer_id, 2157 media::Picture picture(picture_buffer_id, input_buffer_id, gfx::Rect(0, 0),
2219 gfx::Rect(0, 0), false); 2158 false);
2220 client_->PictureReady(picture); 2159 client_->PictureReady(picture);
2221 } 2160 }
2222 } 2161 }
2223 2162
2224 void DXVAVideoDecodeAccelerator::NotifyInputBuffersDropped() { 2163 void DXVAVideoDecodeAccelerator::NotifyInputBuffersDropped() {
2225 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 2164 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2226 if (!client_) 2165 if (!client_)
2227 return; 2166 return;
2228 2167
2229 for (PendingInputs::iterator it = pending_input_buffers_.begin(); 2168 for (PendingInputs::iterator it = pending_input_buffers_.begin();
2230 it != pending_input_buffers_.end(); ++it) { 2169 it != pending_input_buffers_.end(); ++it) {
2231 LONGLONG input_buffer_id = 0; 2170 LONGLONG input_buffer_id = 0;
2232 RETURN_ON_HR_FAILURE((*it)->GetSampleTime(&input_buffer_id), 2171 RETURN_ON_HR_FAILURE((*it)->GetSampleTime(&input_buffer_id),
2233 "Failed to get buffer id associated with sample",); 2172 "Failed to get buffer id associated with sample", );
2234 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 2173 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
2235 } 2174 }
2236 pending_input_buffers_.clear(); 2175 pending_input_buffers_.clear();
2237 } 2176 }
2238 2177
2239 void DXVAVideoDecodeAccelerator::DecodePendingInputBuffers() { 2178 void DXVAVideoDecodeAccelerator::DecodePendingInputBuffers() {
2240 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 2179 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2241 State state = GetState(); 2180 State state = GetState();
2242 RETURN_AND_NOTIFY_ON_FAILURE((state != kUninitialized), 2181 RETURN_AND_NOTIFY_ON_FAILURE((state != kUninitialized),
2243 "Invalid state: " << state, ILLEGAL_STATE,); 2182 "Invalid state: " << state, ILLEGAL_STATE, );
2244 2183
2245 if (pending_input_buffers_.empty() || OutputSamplesPresent()) 2184 if (pending_input_buffers_.empty() || OutputSamplesPresent())
2246 return; 2185 return;
2247 2186
2248 PendingInputs pending_input_buffers_copy; 2187 PendingInputs pending_input_buffers_copy;
2249 std::swap(pending_input_buffers_, pending_input_buffers_copy); 2188 std::swap(pending_input_buffers_, pending_input_buffers_copy);
2250 2189
2251 for (PendingInputs::iterator it = pending_input_buffers_copy.begin(); 2190 for (PendingInputs::iterator it = pending_input_buffers_copy.begin();
2252 it != pending_input_buffers_copy.end(); ++it) { 2191 it != pending_input_buffers_copy.end(); ++it) {
2253 DecodeInternal(*it); 2192 DecodeInternal(*it);
2254 } 2193 }
2255 } 2194 }
2256 2195
2257 void DXVAVideoDecodeAccelerator::FlushInternal() { 2196 void DXVAVideoDecodeAccelerator::FlushInternal() {
2258 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 2197 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2259 2198
2260 // We allow only one output frame to be present at any given time. If we have 2199 // We allow only one output frame to be present at any given time. If we have
2261 // an output frame, then we cannot complete the flush at this time. 2200 // an output frame, then we cannot complete the flush at this time.
2262 if (OutputSamplesPresent()) 2201 if (OutputSamplesPresent())
2263 return; 2202 return;
2264 2203
2265 // First drain the pending input because once the drain message is sent below, 2204 // First drain the pending input because once the drain message is sent below,
2266 // the decoder will ignore further input until it's drained. 2205 // the decoder will ignore further input until it's drained.
2267 if (!pending_input_buffers_.empty()) { 2206 if (!pending_input_buffers_.empty()) {
2268 decoder_thread_task_runner_->PostTask( 2207 decoder_thread_task_runner_->PostTask(
2269 FROM_HERE, 2208 FROM_HERE,
2270 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2209 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2271 base::Unretained(this))); 2210 base::Unretained(this)));
2272 decoder_thread_task_runner_->PostTask( 2211 decoder_thread_task_runner_->PostTask(
2273 FROM_HERE, 2212 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
2274 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, 2213 base::Unretained(this)));
2275 base::Unretained(this)));
2276 return; 2214 return;
2277 } 2215 }
2278 2216
2279 { 2217 {
2280 base::AutoLock lock(decoder_lock_); 2218 base::AutoLock lock(decoder_lock_);
2281 if (!sent_drain_message_) { 2219 if (!sent_drain_message_) {
2282 RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_DRAIN, 0), 2220 RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_DRAIN, 0),
2283 "Failed to send drain message", 2221 "Failed to send drain message",
2284 PLATFORM_FAILURE,); 2222 PLATFORM_FAILURE, );
2285 sent_drain_message_ = true; 2223 sent_drain_message_ = true;
2286 } 2224 }
2287 } 2225 }
2288 2226
2289 // Attempt to retrieve an output frame from the decoder. If we have one, 2227 // Attempt to retrieve an output frame from the decoder. If we have one,
2290 // return and proceed when the output frame is processed. If we don't have a 2228 // return and proceed when the output frame is processed. If we don't have a
2291 // frame then we are done. 2229 // frame then we are done.
2292 DoDecode(); 2230 DoDecode();
2293 if (OutputSamplesPresent()) 2231 if (OutputSamplesPresent())
2294 return; 2232 return;
2295 2233
2296 SetState(kFlushing); 2234 SetState(kFlushing);
2297 2235
2298 main_thread_task_runner_->PostTask( 2236 main_thread_task_runner_->PostTask(
2299 FROM_HERE, 2237 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::NotifyFlushDone,
2300 base::Bind(&DXVAVideoDecodeAccelerator::NotifyFlushDone, 2238 weak_this_factory_.GetWeakPtr()));
2301 weak_this_factory_.GetWeakPtr()));
2302 2239
2303 SetState(kNormal); 2240 SetState(kNormal);
2304 } 2241 }
2305 2242
2306 void DXVAVideoDecodeAccelerator::DecodeInternal( 2243 void DXVAVideoDecodeAccelerator::DecodeInternal(
2307 const base::win::ScopedComPtr<IMFSample>& sample) { 2244 const base::win::ScopedComPtr<IMFSample>& sample) {
2308 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 2245 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2309 2246
2310 if (GetState() == kUninitialized) 2247 if (GetState() == kUninitialized)
2311 return; 2248 return;
2312 2249
2313 if (OutputSamplesPresent() || !pending_input_buffers_.empty()) { 2250 if (OutputSamplesPresent() || !pending_input_buffers_.empty()) {
2314 pending_input_buffers_.push_back(sample); 2251 pending_input_buffers_.push_back(sample);
2315 return; 2252 return;
2316 } 2253 }
2317 2254
2318 // Check if the resolution, bit rate, etc changed in the stream. If yes we 2255 // Check if the resolution, bit rate, etc changed in the stream. If yes we
2319 // reinitialize the decoder to ensure that the stream decodes correctly. 2256 // reinitialize the decoder to ensure that the stream decodes correctly.
2320 bool config_changed = false; 2257 bool config_changed = false;
2321 2258
2322 HRESULT hr = CheckConfigChanged(sample.get(), &config_changed); 2259 HRESULT hr = CheckConfigChanged(sample.get(), &config_changed);
2323 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to check video stream config", 2260 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to check video stream config",
2324 PLATFORM_FAILURE,); 2261 PLATFORM_FAILURE, );
2325 2262
2326 if (config_changed) { 2263 if (config_changed) {
2327 pending_input_buffers_.push_back(sample); 2264 pending_input_buffers_.push_back(sample);
2328 main_thread_task_runner_->PostTask( 2265 main_thread_task_runner_->PostTask(
2329 FROM_HERE, 2266 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::ConfigChanged,
2330 base::Bind(&DXVAVideoDecodeAccelerator::ConfigChanged, 2267 weak_this_factory_.GetWeakPtr(), config_));
2331 weak_this_factory_.GetWeakPtr(),
2332 config_));
2333 return; 2268 return;
2334 } 2269 }
2335 2270
2336 if (!inputs_before_decode_) { 2271 if (!inputs_before_decode_) {
2337 TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding", 2272 TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding",
2338 this); 2273 this);
2339 } 2274 }
2340 inputs_before_decode_++; 2275 inputs_before_decode_++;
2341 2276
2342 hr = decoder_->ProcessInput(0, sample.get(), 0); 2277 hr = decoder_->ProcessInput(0, sample.get(), 0);
2343 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it 2278 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it
2344 // has enough data to produce one or more output samples. In this case the 2279 // has enough data to produce one or more output samples. In this case the
2345 // recommended options are to 2280 // recommended options are to
2346 // 1. Generate new output by calling IMFTransform::ProcessOutput until it 2281 // 1. Generate new output by calling IMFTransform::ProcessOutput until it
2347 // returns MF_E_TRANSFORM_NEED_MORE_INPUT. 2282 // returns MF_E_TRANSFORM_NEED_MORE_INPUT.
2348 // 2. Flush the input data 2283 // 2. Flush the input data
2349 // We implement the first option, i.e to retrieve the output sample and then 2284 // We implement the first option, i.e to retrieve the output sample and then
2350 // process the input again. Failure in either of these steps is treated as a 2285 // process the input again. Failure in either of these steps is treated as a
2351 // decoder failure. 2286 // decoder failure.
2352 if (hr == MF_E_NOTACCEPTING) { 2287 if (hr == MF_E_NOTACCEPTING) {
2353 DoDecode(); 2288 DoDecode();
2354 // If the DoDecode call resulted in an output frame then we should not 2289 // If the DoDecode call resulted in an output frame then we should not
2355 // process any more input until that frame is copied to the target surface. 2290 // process any more input until that frame is copied to the target surface.
2356 if (!OutputSamplesPresent()) { 2291 if (!OutputSamplesPresent()) {
2357 State state = GetState(); 2292 State state = GetState();
2358 RETURN_AND_NOTIFY_ON_FAILURE((state == kStopped || state == kNormal || 2293 RETURN_AND_NOTIFY_ON_FAILURE(
2359 state == kFlushing), 2294 (state == kStopped || state == kNormal || state == kFlushing),
2360 "Failed to process output. Unexpected decoder state: " << state, 2295 "Failed to process output. Unexpected decoder state: " << state,
2361 PLATFORM_FAILURE,); 2296 PLATFORM_FAILURE, );
2362 hr = decoder_->ProcessInput(0, sample.get(), 0); 2297 hr = decoder_->ProcessInput(0, sample.get(), 0);
2363 } 2298 }
2364 // If we continue to get the MF_E_NOTACCEPTING error we do the following:- 2299 // If we continue to get the MF_E_NOTACCEPTING error we do the following:-
2365 // 1. Add the input sample to the pending queue. 2300 // 1. Add the input sample to the pending queue.
2366 // 2. If we don't have any output samples we post the 2301 // 2. If we don't have any output samples we post the
2367 // DecodePendingInputBuffers task to process the pending input samples. 2302 // DecodePendingInputBuffers task to process the pending input samples.
2368 // If we have an output sample then the above task is posted when the 2303 // If we have an output sample then the above task is posted when the
2369 // output samples are sent to the client. 2304 // output samples are sent to the client.
2370 // This is because we only support 1 pending output sample at any 2305 // This is because we only support 1 pending output sample at any
2371 // given time due to the limitation with the Microsoft media foundation 2306 // given time due to the limitation with the Microsoft media foundation
2372 // decoder where it recycles the output Decoder surfaces. 2307 // decoder where it recycles the output Decoder surfaces.
2373 if (hr == MF_E_NOTACCEPTING) { 2308 if (hr == MF_E_NOTACCEPTING) {
2374 pending_input_buffers_.push_back(sample); 2309 pending_input_buffers_.push_back(sample);
2375 decoder_thread_task_runner_->PostTask( 2310 decoder_thread_task_runner_->PostTask(
2376 FROM_HERE, 2311 FROM_HERE,
2377 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2312 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2378 base::Unretained(this))); 2313 base::Unretained(this)));
2379 return; 2314 return;
2380 } 2315 }
2381 } 2316 }
2382 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to process input sample", 2317 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to process input sample",
2383 PLATFORM_FAILURE,); 2318 PLATFORM_FAILURE, );
2384 2319
2385 DoDecode(); 2320 DoDecode();
2386 2321
2387 State state = GetState(); 2322 State state = GetState();
2388 RETURN_AND_NOTIFY_ON_FAILURE((state == kStopped || state == kNormal || 2323 RETURN_AND_NOTIFY_ON_FAILURE(
2389 state == kFlushing), 2324 (state == kStopped || state == kNormal || state == kFlushing),
2390 "Failed to process output. Unexpected decoder state: " << state, 2325 "Failed to process output. Unexpected decoder state: " << state,
2391 ILLEGAL_STATE,); 2326 ILLEGAL_STATE, );
2392 2327
2393 LONGLONG input_buffer_id = 0; 2328 LONGLONG input_buffer_id = 0;
2394 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id), 2329 RETURN_ON_HR_FAILURE(
2395 "Failed to get input buffer id associated with sample",); 2330 sample->GetSampleTime(&input_buffer_id),
2331 "Failed to get input buffer id associated with sample", );
2396 // The Microsoft Media foundation decoder internally buffers up to 30 frames 2332 // The Microsoft Media foundation decoder internally buffers up to 30 frames
2397 // before returning a decoded frame. We need to inform the client that this 2333 // before returning a decoded frame. We need to inform the client that this
2398 // input buffer is processed as it may stop sending us further input. 2334 // input buffer is processed as it may stop sending us further input.
2399 // Note: This may break clients which expect every input buffer to be 2335 // Note: This may break clients which expect every input buffer to be
2400 // associated with a decoded output buffer. 2336 // associated with a decoded output buffer.
2401 // TODO(ananta) 2337 // TODO(ananta)
2402 // Do some more investigation into whether it is possible to get the MFT 2338 // Do some more investigation into whether it is possible to get the MFT
2403 // decoder to emit an output packet for every input packet. 2339 // decoder to emit an output packet for every input packet.
2404 // http://code.google.com/p/chromium/issues/detail?id=108121 2340 // http://code.google.com/p/chromium/issues/detail?id=108121
2405 // http://code.google.com/p/chromium/issues/detail?id=150925 2341 // http://code.google.com/p/chromium/issues/detail?id=150925
2406 main_thread_task_runner_->PostTask( 2342 main_thread_task_runner_->PostTask(
2407 FROM_HERE, 2343 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::NotifyInputBufferRead,
2408 base::Bind(&DXVAVideoDecodeAccelerator::NotifyInputBufferRead, 2344 weak_this_factory_.GetWeakPtr(), input_buffer_id));
2409 weak_this_factory_.GetWeakPtr(),
2410 input_buffer_id));
2411 } 2345 }
2412 2346
2413 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width, 2347 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width,
2414 int height) { 2348 int height) {
2415 dx11_video_format_converter_media_type_needs_init_ = true; 2349 dx11_video_format_converter_media_type_needs_init_ = true;
2416 2350
2417 main_thread_task_runner_->PostTask( 2351 main_thread_task_runner_->PostTask(
2418 FROM_HERE, 2352 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers,
2419 base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers, 2353 weak_this_factory_.GetWeakPtr(), false));
2420 weak_this_factory_.GetWeakPtr(), false));
2421 2354
2422 main_thread_task_runner_->PostTask( 2355 main_thread_task_runner_->PostTask(
2423 FROM_HERE, 2356 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
2424 base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers, 2357 weak_this_factory_.GetWeakPtr(), width, height));
2425 weak_this_factory_.GetWeakPtr(),
2426 width,
2427 height));
2428 } 2358 }
2429 2359
2430 void DXVAVideoDecodeAccelerator::DismissStaleBuffers(bool force) { 2360 void DXVAVideoDecodeAccelerator::DismissStaleBuffers(bool force) {
2431 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), 2361 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
2432 "Failed to make context current", 2362 "Failed to make context current",
2433 PLATFORM_FAILURE, ); 2363 PLATFORM_FAILURE, );
2434 2364
2435 OutputBuffers::iterator index; 2365 OutputBuffers::iterator index;
2436 2366
2437 for (index = output_picture_buffers_.begin(); 2367 for (index = output_picture_buffers_.begin();
2438 index != output_picture_buffers_.end(); 2368 index != output_picture_buffers_.end(); ++index) {
2439 ++index) {
2440 if (force || index->second->available()) { 2369 if (force || index->second->available()) {
2441 DVLOG(1) << "Dismissing picture id: " << index->second->id(); 2370 DVLOG(1) << "Dismissing picture id: " << index->second->id();
2442 client_->DismissPictureBuffer(index->second->id()); 2371 client_->DismissPictureBuffer(index->second->id());
2443 } else { 2372 } else {
2444 // Move to |stale_output_picture_buffers_| for deferred deletion. 2373 // Move to |stale_output_picture_buffers_| for deferred deletion.
2445 stale_output_picture_buffers_.insert( 2374 stale_output_picture_buffers_.insert(
2446 std::make_pair(index->first, index->second)); 2375 std::make_pair(index->first, index->second));
2447 } 2376 }
2448 } 2377 }
2449 2378
2450 output_picture_buffers_.clear(); 2379 output_picture_buffers_.clear();
2451 } 2380 }
2452 2381
2453 void DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer( 2382 void DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer(
2454 int32_t picture_buffer_id) { 2383 int32_t picture_buffer_id) {
2455 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), 2384 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
2456 "Failed to make context current", 2385 "Failed to make context current",
2457 PLATFORM_FAILURE, ); 2386 PLATFORM_FAILURE, );
2458 2387
2459 OutputBuffers::iterator it = stale_output_picture_buffers_.find( 2388 OutputBuffers::iterator it =
2460 picture_buffer_id); 2389 stale_output_picture_buffers_.find(picture_buffer_id);
2461 DCHECK(it != stale_output_picture_buffers_.end()); 2390 DCHECK(it != stale_output_picture_buffers_.end());
2462 DVLOG(1) << "Dismissing picture id: " << it->second->id(); 2391 DVLOG(1) << "Dismissing picture id: " << it->second->id();
2463 client_->DismissPictureBuffer(it->second->id()); 2392 client_->DismissPictureBuffer(it->second->id());
2464 stale_output_picture_buffers_.erase(it); 2393 stale_output_picture_buffers_.erase(it);
2465 } 2394 }
2466 2395
2467 DXVAVideoDecodeAccelerator::State 2396 DXVAVideoDecodeAccelerator::State DXVAVideoDecodeAccelerator::GetState() {
2468 DXVAVideoDecodeAccelerator::GetState() {
2469 static_assert(sizeof(State) == sizeof(long), "mismatched type sizes"); 2397 static_assert(sizeof(State) == sizeof(long), "mismatched type sizes");
2470 State state = static_cast<State>( 2398 State state = static_cast<State>(
2471 InterlockedAdd(reinterpret_cast<volatile long*>(&state_), 0)); 2399 InterlockedAdd(reinterpret_cast<volatile long*>(&state_), 0));
2472 return state; 2400 return state;
2473 } 2401 }
2474 2402
2475 void DXVAVideoDecodeAccelerator::SetState(State new_state) { 2403 void DXVAVideoDecodeAccelerator::SetState(State new_state) {
2476 if (!main_thread_task_runner_->BelongsToCurrentThread()) { 2404 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
2477 main_thread_task_runner_->PostTask( 2405 main_thread_task_runner_->PostTask(
2478 FROM_HERE, 2406 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::SetState,
2479 base::Bind(&DXVAVideoDecodeAccelerator::SetState, 2407 weak_this_factory_.GetWeakPtr(), new_state));
2480 weak_this_factory_.GetWeakPtr(),
2481 new_state));
2482 return; 2408 return;
2483 } 2409 }
2484 2410
2485 static_assert(sizeof(State) == sizeof(long), "mismatched type sizes"); 2411 static_assert(sizeof(State) == sizeof(long), "mismatched type sizes");
2486 ::InterlockedExchange(reinterpret_cast<volatile long*>(&state_), 2412 ::InterlockedExchange(reinterpret_cast<volatile long*>(&state_), new_state);
2487 new_state);
2488 DCHECK_EQ(state_, new_state); 2413 DCHECK_EQ(state_, new_state);
2489 } 2414 }
2490 2415
2491 void DXVAVideoDecodeAccelerator::StartDecoderThread() { 2416 void DXVAVideoDecodeAccelerator::StartDecoderThread() {
2492 decoder_thread_.init_com_with_mta(false); 2417 decoder_thread_.init_com_with_mta(false);
2493 decoder_thread_.Start(); 2418 decoder_thread_.Start();
2494 decoder_thread_task_runner_ = decoder_thread_.task_runner(); 2419 decoder_thread_task_runner_ = decoder_thread_.task_runner();
2495 } 2420 }
2496 2421
2497 bool DXVAVideoDecodeAccelerator::OutputSamplesPresent() { 2422 bool DXVAVideoDecodeAccelerator::OutputSamplesPresent() {
2498 base::AutoLock lock(decoder_lock_); 2423 base::AutoLock lock(decoder_lock_);
2499 return !pending_output_samples_.empty(); 2424 return !pending_output_samples_.empty();
2500 } 2425 }
2501 2426
2502 void DXVAVideoDecodeAccelerator::CopySurface(IDirect3DSurface9* src_surface, 2427 void DXVAVideoDecodeAccelerator::CopySurface(IDirect3DSurface9* src_surface,
2503 IDirect3DSurface9* dest_surface, 2428 IDirect3DSurface9* dest_surface,
2504 int picture_buffer_id, 2429 int picture_buffer_id,
2505 int input_buffer_id) { 2430 int input_buffer_id) {
2506 if (!decoder_thread_task_runner_->BelongsToCurrentThread()) { 2431 if (!decoder_thread_task_runner_->BelongsToCurrentThread()) {
2507 decoder_thread_task_runner_->PostTask( 2432 decoder_thread_task_runner_->PostTask(
2508 FROM_HERE, 2433 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurface,
2509 base::Bind(&DXVAVideoDecodeAccelerator::CopySurface, 2434 base::Unretained(this), src_surface, dest_surface,
2510 base::Unretained(this), 2435 picture_buffer_id, input_buffer_id));
2511 src_surface,
2512 dest_surface,
2513 picture_buffer_id,
2514 input_buffer_id));
2515 return; 2436 return;
2516 } 2437 }
2517 2438
2518 HRESULT hr = d3d9_device_ex_->StretchRect(src_surface, NULL, dest_surface, 2439 HRESULT hr = d3d9_device_ex_->StretchRect(src_surface, NULL, dest_surface,
2519 NULL, D3DTEXF_NONE); 2440 NULL, D3DTEXF_NONE);
2520 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed",); 2441 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", );
2521 2442
2522 // Ideally, this should be done immediately before the draw call that uses 2443 // Ideally, this should be done immediately before the draw call that uses
2523 // the texture. Flush it once here though. 2444 // the texture. Flush it once here though.
2524 hr = query_->Issue(D3DISSUE_END); 2445 hr = query_->Issue(D3DISSUE_END);
2525 RETURN_ON_HR_FAILURE(hr, "Failed to issue END",); 2446 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", );
2526 2447
2527 // If we are sharing the ANGLE device we don't need to wait for the Flush to 2448 // If we are sharing the ANGLE device we don't need to wait for the Flush to
2528 // complete. 2449 // complete.
2529 if (using_angle_device_) { 2450 if (using_angle_device_) {
2530 main_thread_task_runner_->PostTask( 2451 main_thread_task_runner_->PostTask(
2531 FROM_HERE, 2452 FROM_HERE,
2532 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, 2453 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
2533 weak_this_factory_.GetWeakPtr(), 2454 weak_this_factory_.GetWeakPtr(), src_surface, dest_surface,
2534 src_surface, 2455 picture_buffer_id, input_buffer_id));
2535 dest_surface,
2536 picture_buffer_id,
2537 input_buffer_id));
2538 return; 2456 return;
2539 } 2457 }
2540 2458
2541 // Flush the decoder device to ensure that the decoded frame is copied to the 2459 // Flush the decoder device to ensure that the decoded frame is copied to the
2542 // target surface. 2460 // target surface.
2543 decoder_thread_task_runner_->PostDelayedTask( 2461 decoder_thread_task_runner_->PostDelayedTask(
2544 FROM_HERE, 2462 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder,
2545 base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, 2463 base::Unretained(this), 0, src_surface,
2546 base::Unretained(this), 0, src_surface, dest_surface, 2464 dest_surface, picture_buffer_id, input_buffer_id),
2547 picture_buffer_id, input_buffer_id),
2548 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); 2465 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
2549 } 2466 }
2550 2467
2551 void DXVAVideoDecodeAccelerator::CopySurfaceComplete( 2468 void DXVAVideoDecodeAccelerator::CopySurfaceComplete(
2552 IDirect3DSurface9* src_surface, 2469 IDirect3DSurface9* src_surface,
2553 IDirect3DSurface9* dest_surface, 2470 IDirect3DSurface9* dest_surface,
2554 int picture_buffer_id, 2471 int picture_buffer_id,
2555 int input_buffer_id) { 2472 int input_buffer_id) {
2556 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 2473 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2557 2474
(...skipping 25 matching lines...) Expand all
2583 NotifyPictureReady(picture_buffer->id(), input_buffer_id); 2500 NotifyPictureReady(picture_buffer->id(), input_buffer_id);
2584 2501
2585 { 2502 {
2586 base::AutoLock lock(decoder_lock_); 2503 base::AutoLock lock(decoder_lock_);
2587 if (!pending_output_samples_.empty()) 2504 if (!pending_output_samples_.empty())
2588 pending_output_samples_.pop_front(); 2505 pending_output_samples_.pop_front();
2589 } 2506 }
2590 2507
2591 if (pending_flush_) { 2508 if (pending_flush_) {
2592 decoder_thread_task_runner_->PostTask( 2509 decoder_thread_task_runner_->PostTask(
2593 FROM_HERE, 2510 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
2594 base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, 2511 base::Unretained(this)));
2595 base::Unretained(this)));
2596 return; 2512 return;
2597 } 2513 }
2598 decoder_thread_task_runner_->PostTask( 2514 decoder_thread_task_runner_->PostTask(
2599 FROM_HERE, 2515 FROM_HERE,
2600 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2516 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2601 base::Unretained(this))); 2517 base::Unretained(this)));
2602 } 2518 }
2603 2519
2604 void DXVAVideoDecodeAccelerator::CopyTexture( 2520 void DXVAVideoDecodeAccelerator::CopyTexture(
2605 ID3D11Texture2D* src_texture, 2521 ID3D11Texture2D* src_texture,
(...skipping 20 matching lines...) Expand all
2626 // conversion as per msdn is done in the GPU. 2542 // conversion as per msdn is done in the GPU.
2627 2543
2628 D3D11_TEXTURE2D_DESC source_desc; 2544 D3D11_TEXTURE2D_DESC source_desc;
2629 src_texture->GetDesc(&source_desc); 2545 src_texture->GetDesc(&source_desc);
2630 2546
2631 // Set up the input and output types for the video processor MFT. 2547 // Set up the input and output types for the video processor MFT.
2632 if (!InitializeDX11VideoFormatConverterMediaType(source_desc.Width, 2548 if (!InitializeDX11VideoFormatConverterMediaType(source_desc.Width,
2633 source_desc.Height)) { 2549 source_desc.Height)) {
2634 RETURN_AND_NOTIFY_ON_FAILURE( 2550 RETURN_AND_NOTIFY_ON_FAILURE(
2635 false, "Failed to initialize media types for convesion.", 2551 false, "Failed to initialize media types for convesion.",
2636 PLATFORM_FAILURE,); 2552 PLATFORM_FAILURE, );
2637 } 2553 }
2638 2554
2639 // The input to the video processor is the output sample. 2555 // The input to the video processor is the output sample.
2640 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion; 2556 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion;
2641 { 2557 {
2642 base::AutoLock lock(decoder_lock_); 2558 base::AutoLock lock(decoder_lock_);
2643 PendingSampleInfo& sample_info = pending_output_samples_.front(); 2559 PendingSampleInfo& sample_info = pending_output_samples_.front();
2644 input_sample_for_conversion = sample_info.output_sample; 2560 input_sample_for_conversion = sample_info.output_sample;
2645 } 2561 }
2646 2562
(...skipping 21 matching lines...) Expand all
2668 PLATFORM_FAILURE, ); 2584 PLATFORM_FAILURE, );
2669 } 2585 }
2670 // The video processor MFT requires output samples to be allocated by the 2586 // The video processor MFT requires output samples to be allocated by the
2671 // caller. We create a sample with a buffer backed with the ID3D11Texture2D 2587 // caller. We create a sample with a buffer backed with the ID3D11Texture2D
2672 // interface exposed by ANGLE. This works nicely as this ensures that the 2588 // interface exposed by ANGLE. This works nicely as this ensures that the
2673 // video processor coverts the color space of the output frame and copies 2589 // video processor coverts the color space of the output frame and copies
2674 // the result into the ANGLE texture. 2590 // the result into the ANGLE texture.
2675 base::win::ScopedComPtr<IMFSample> output_sample; 2591 base::win::ScopedComPtr<IMFSample> output_sample;
2676 hr = MFCreateSample(output_sample.Receive()); 2592 hr = MFCreateSample(output_sample.Receive());
2677 if (FAILED(hr)) { 2593 if (FAILED(hr)) {
2678 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2594 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.",
2679 "Failed to create output sample.", PLATFORM_FAILURE,); 2595 PLATFORM_FAILURE, );
2680 } 2596 }
2681 2597
2682 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2598 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2683 hr = MFCreateDXGISurfaceBuffer( 2599 hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), dest_texture, 0,
2684 __uuidof(ID3D11Texture2D), dest_texture, 0, FALSE, 2600 FALSE, output_buffer.Receive());
2685 output_buffer.Receive());
2686 if (FAILED(hr)) { 2601 if (FAILED(hr)) {
2687 base::debug::Alias(&hr); 2602 base::debug::Alias(&hr);
2688 // TODO(ananta) 2603 // TODO(ananta)
2689 // Remove this CHECK when the change to use DX11 for H/W decoding 2604 // Remove this CHECK when the change to use DX11 for H/W decoding
2690 // stablizes. 2605 // stablizes.
2691 CHECK(false); 2606 CHECK(false);
2692 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2607 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.",
2693 "Failed to create output sample.", PLATFORM_FAILURE,); 2608 PLATFORM_FAILURE, );
2694 } 2609 }
2695 2610
2696 output_sample->AddBuffer(output_buffer.get()); 2611 output_sample->AddBuffer(output_buffer.get());
2697 2612
2698 hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0); 2613 hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0);
2699 if (FAILED(hr)) { 2614 if (FAILED(hr)) {
2700 DCHECK(false); 2615 DCHECK(false);
2701 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2616 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2702 "Failed to convert output sample format.", PLATFORM_FAILURE,); 2617 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, );
2703 } 2618 }
2704 2619
2705 DWORD status = 0; 2620 DWORD status = 0;
2706 MFT_OUTPUT_DATA_BUFFER format_converter_output = {}; 2621 MFT_OUTPUT_DATA_BUFFER format_converter_output = {};
2707 format_converter_output.pSample = output_sample.get(); 2622 format_converter_output.pSample = output_sample.get();
2708 hr = video_format_converter_mft_->ProcessOutput( 2623 hr = video_format_converter_mft_->ProcessOutput(
2709 0, // No flags 2624 0, // No flags
2710 1, // # of out streams to pull from 2625 1, // # of out streams to pull from
2711 &format_converter_output, 2626 &format_converter_output, &status);
2712 &status);
2713 2627
2714 if (FAILED(hr)) { 2628 if (FAILED(hr)) {
2715 base::debug::Alias(&hr); 2629 base::debug::Alias(&hr);
2716 // TODO(ananta) 2630 // TODO(ananta)
2717 // Remove this CHECK when the change to use DX11 for H/W decoding 2631 // Remove this CHECK when the change to use DX11 for H/W decoding
2718 // stablizes. 2632 // stablizes.
2719 CHECK(false); 2633 CHECK(false);
2720 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2634 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2721 "Failed to convert output sample format.", PLATFORM_FAILURE,); 2635 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, );
2722 } 2636 }
2723 2637
2724 if (dest_keyed_mutex) { 2638 if (dest_keyed_mutex) {
2725 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1); 2639 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1);
2726 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.", 2640 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.",
2727 PLATFORM_FAILURE, ); 2641 PLATFORM_FAILURE, );
2728 2642
2729 main_thread_task_runner_->PostTask( 2643 main_thread_task_runner_->PostTask(
2730 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, 2644 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
2731 weak_this_factory_.GetWeakPtr(), nullptr, nullptr, 2645 weak_this_factory_.GetWeakPtr(), nullptr, nullptr,
2732 picture_buffer_id, input_buffer_id)); 2646 picture_buffer_id, input_buffer_id));
2733 } else { 2647 } else {
2734 d3d11_device_context_->Flush(); 2648 d3d11_device_context_->Flush();
2735 d3d11_device_context_->End(d3d11_query_.get()); 2649 d3d11_device_context_->End(d3d11_query_.get());
2736 2650
2737 decoder_thread_task_runner_->PostDelayedTask( 2651 decoder_thread_task_runner_->PostDelayedTask(
2738 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, 2652 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder,
2739 base::Unretained(this), 0, 2653 base::Unretained(this), 0,
2740 reinterpret_cast<IDirect3DSurface9*>(NULL), 2654 reinterpret_cast<IDirect3DSurface9*>(NULL),
2741 reinterpret_cast<IDirect3DSurface9*>(NULL), 2655 reinterpret_cast<IDirect3DSurface9*>(NULL),
2742 picture_buffer_id, input_buffer_id), 2656 picture_buffer_id, input_buffer_id),
2743 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); 2657 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
2744 } 2658 }
2745 } 2659 }
2746 2660
2747 void DXVAVideoDecodeAccelerator::FlushDecoder( 2661 void DXVAVideoDecodeAccelerator::FlushDecoder(int iterations,
2748 int iterations, 2662 IDirect3DSurface9* src_surface,
2749 IDirect3DSurface9* src_surface, 2663 IDirect3DSurface9* dest_surface,
2750 IDirect3DSurface9* dest_surface, 2664 int picture_buffer_id,
2751 int picture_buffer_id, 2665 int input_buffer_id) {
2752 int input_buffer_id) {
2753 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 2666 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2754 2667
2755 // The DXVA decoder has its own device which it uses for decoding. ANGLE 2668 // The DXVA decoder has its own device which it uses for decoding. ANGLE
2756 // has its own device which we don't have access to. 2669 // has its own device which we don't have access to.
2757 // The above code attempts to copy the decoded picture into a surface 2670 // The above code attempts to copy the decoded picture into a surface
2758 // which is owned by ANGLE. As there are multiple devices involved in 2671 // which is owned by ANGLE. As there are multiple devices involved in
2759 // this, the StretchRect call above is not synchronous. 2672 // this, the StretchRect call above is not synchronous.
2760 // We attempt to flush the batched operations to ensure that the picture is 2673 // We attempt to flush the batched operations to ensure that the picture is
2761 // copied to the surface owned by ANGLE. 2674 // copied to the surface owned by ANGLE.
2762 // We need to do this in a loop and call flush multiple times. 2675 // We need to do this in a loop and call flush multiple times.
(...skipping 14 matching lines...) Expand all
2777 // Remove this CHECK when the change to use DX11 for H/W decoding 2690 // Remove this CHECK when the change to use DX11 for H/W decoding
2778 // stablizes. 2691 // stablizes.
2779 CHECK(false); 2692 CHECK(false);
2780 } 2693 }
2781 } else { 2694 } else {
2782 hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH); 2695 hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH);
2783 } 2696 }
2784 2697
2785 if ((hr == S_FALSE) && (++iterations < kMaxIterationsForD3DFlush)) { 2698 if ((hr == S_FALSE) && (++iterations < kMaxIterationsForD3DFlush)) {
2786 decoder_thread_task_runner_->PostDelayedTask( 2699 decoder_thread_task_runner_->PostDelayedTask(
2787 FROM_HERE, 2700 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder,
2788 base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, 2701 base::Unretained(this), iterations, src_surface,
2789 base::Unretained(this), iterations, src_surface, 2702 dest_surface, picture_buffer_id, input_buffer_id),
2790 dest_surface, picture_buffer_id, input_buffer_id),
2791 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); 2703 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
2792 return; 2704 return;
2793 } 2705 }
2794 2706
2795 main_thread_task_runner_->PostTask( 2707 main_thread_task_runner_->PostTask(
2796 FROM_HERE, 2708 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
2797 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, 2709 weak_this_factory_.GetWeakPtr(), src_surface,
2798 weak_this_factory_.GetWeakPtr(), 2710 dest_surface, picture_buffer_id, input_buffer_id));
2799 src_surface,
2800 dest_surface,
2801 picture_buffer_id,
2802 input_buffer_id));
2803 } 2711 }
2804 2712
2805 bool DXVAVideoDecodeAccelerator::InitializeDX11VideoFormatConverterMediaType( 2713 bool DXVAVideoDecodeAccelerator::InitializeDX11VideoFormatConverterMediaType(
2806 int width, int height) { 2714 int width,
2715 int height) {
2807 if (!dx11_video_format_converter_media_type_needs_init_) 2716 if (!dx11_video_format_converter_media_type_needs_init_)
2808 return true; 2717 return true;
2809 2718
2810 CHECK(video_format_converter_mft_.get()); 2719 CHECK(video_format_converter_mft_.get());
2811 2720
2812 HRESULT hr = video_format_converter_mft_->ProcessMessage( 2721 HRESULT hr = video_format_converter_mft_->ProcessMessage(
2813 MFT_MESSAGE_SET_D3D_MANAGER, 2722 MFT_MESSAGE_SET_D3D_MANAGER,
2814 reinterpret_cast<ULONG_PTR>( 2723 reinterpret_cast<ULONG_PTR>(d3d11_device_manager_.get()));
2815 d3d11_device_manager_.get()));
2816 2724
2817 if (FAILED(hr)) { 2725 if (FAILED(hr)) {
2818 base::debug::Alias(&hr); 2726 base::debug::Alias(&hr);
2819 // TODO(ananta) 2727 // TODO(ananta)
2820 // Remove this CHECK when the change to use DX11 for H/W decoding 2728 // Remove this CHECK when the change to use DX11 for H/W decoding
2821 // stablizes. 2729 // stablizes.
2822 CHECK(false); 2730 CHECK(false);
2823 } 2731 }
2824 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2732 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2825 "Failed to initialize video format converter", PLATFORM_FAILURE, false); 2733 "Failed to initialize video format converter",
2734 PLATFORM_FAILURE, false);
2826 2735
2827 video_format_converter_mft_->ProcessMessage( 2736 video_format_converter_mft_->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING,
2828 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); 2737 0);
2829 2738
2830 base::win::ScopedComPtr<IMFMediaType> media_type; 2739 base::win::ScopedComPtr<IMFMediaType> media_type;
2831 hr = MFCreateMediaType(media_type.Receive()); 2740 hr = MFCreateMediaType(media_type.Receive());
2832 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "MFCreateMediaType failed", 2741 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "MFCreateMediaType failed",
2833 PLATFORM_FAILURE, false); 2742 PLATFORM_FAILURE, false);
2834 2743
2835 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 2744 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
2836 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set major input type", 2745 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set major input type",
2837 PLATFORM_FAILURE, false); 2746 PLATFORM_FAILURE, false);
2838 2747
2839 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); 2748 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
2840 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set input sub type", 2749 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set input sub type",
2841 PLATFORM_FAILURE, false); 2750 PLATFORM_FAILURE, false);
2842 2751
2843 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, height); 2752 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, height);
2844 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set media type attributes", 2753 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set media type attributes",
2845 PLATFORM_FAILURE, false); 2754 PLATFORM_FAILURE, false);
2846 2755
2847 hr = video_format_converter_mft_->SetInputType(0, media_type.get(), 0); 2756 hr = video_format_converter_mft_->SetInputType(0, media_type.get(), 0);
2848 if (FAILED(hr)) { 2757 if (FAILED(hr)) {
2849 base::debug::Alias(&hr); 2758 base::debug::Alias(&hr);
2850 // TODO(ananta) 2759 // TODO(ananta)
2851 // Remove this CHECK when the change to use DX11 for H/W decoding 2760 // Remove this CHECK when the change to use DX11 for H/W decoding
2852 // stablizes. 2761 // stablizes.
2853 CHECK(false); 2762 CHECK(false);
2854 } 2763 }
2855 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set converter input type", 2764 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set converter input type",
2856 PLATFORM_FAILURE, false); 2765 PLATFORM_FAILURE, false);
2857 2766
2858 // It appears that we fail to set MFVideoFormat_ARGB32 as the output media 2767 // It appears that we fail to set MFVideoFormat_ARGB32 as the output media
2859 // type in certain configurations. Try to fallback to MFVideoFormat_RGB32 2768 // type in certain configurations. Try to fallback to MFVideoFormat_RGB32
2860 // in such cases. If both fail, then bail. 2769 // in such cases. If both fail, then bail.
2861 bool media_type_set = 2770 bool media_type_set = SetTransformOutputType(
2862 SetTransformOutputType(video_format_converter_mft_.get(), 2771 video_format_converter_mft_.get(), MFVideoFormat_ARGB32, width, height);
2863 MFVideoFormat_ARGB32,
2864 width,
2865 height);
2866 if (!media_type_set) { 2772 if (!media_type_set) {
2867 media_type_set = 2773 media_type_set = SetTransformOutputType(video_format_converter_mft_.get(),
2868 SetTransformOutputType(video_format_converter_mft_.get(), 2774 MFVideoFormat_RGB32, width, height);
2869 MFVideoFormat_RGB32,
2870 width,
2871 height);
2872 } 2775 }
2873 2776
2874 if (!media_type_set) { 2777 if (!media_type_set) {
2875 // Remove this once this stabilizes in the field. 2778 // Remove this once this stabilizes in the field.
2876 CHECK(false); 2779 CHECK(false);
2877 LOG(ERROR) << "Failed to find a matching RGB output type in the converter"; 2780 LOG(ERROR) << "Failed to find a matching RGB output type in the converter";
2878 return false; 2781 return false;
2879 } 2782 }
2880 2783
2881 dx11_video_format_converter_media_type_needs_init_ = false; 2784 dx11_video_format_converter_media_type_needs_init_ = false;
2882 return true; 2785 return true;
2883 } 2786 }
2884 2787
2885 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions( 2788 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(IMFSample* sample,
2886 IMFSample* sample, 2789 int* width,
2887 int* width, 2790 int* height) {
2888 int* height) {
2889 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2791 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2890 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive()); 2792 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive());
2891 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); 2793 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false);
2892 2794
2893 if (use_dx11_) { 2795 if (use_dx11_) {
2894 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer; 2796 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer;
2895 base::win::ScopedComPtr<ID3D11Texture2D> d3d11_texture; 2797 base::win::ScopedComPtr<ID3D11Texture2D> d3d11_texture;
2896 hr = dxgi_buffer.QueryFrom(output_buffer.get()); 2798 hr = dxgi_buffer.QueryFrom(output_buffer.get());
2897 RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample", 2799 RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample",
2898 false); 2800 false);
(...skipping 14 matching lines...) Expand all
2913 false); 2815 false);
2914 D3DSURFACE_DESC surface_desc; 2816 D3DSURFACE_DESC surface_desc;
2915 hr = surface->GetDesc(&surface_desc); 2817 hr = surface->GetDesc(&surface_desc);
2916 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); 2818 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false);
2917 *width = surface_desc.Width; 2819 *width = surface_desc.Width;
2918 *height = surface_desc.Height; 2820 *height = surface_desc.Height;
2919 } 2821 }
2920 return true; 2822 return true;
2921 } 2823 }
2922 2824
2923 bool DXVAVideoDecodeAccelerator::SetTransformOutputType( 2825 bool DXVAVideoDecodeAccelerator::SetTransformOutputType(IMFTransform* transform,
2924 IMFTransform* transform, 2826 const GUID& output_type,
2925 const GUID& output_type, 2827 int width,
2926 int width, 2828 int height) {
2927 int height) {
2928 HRESULT hr = E_FAIL; 2829 HRESULT hr = E_FAIL;
2929 base::win::ScopedComPtr<IMFMediaType> media_type; 2830 base::win::ScopedComPtr<IMFMediaType> media_type;
2930 2831
2931 for (uint32_t i = 0; 2832 for (uint32_t i = 0;
2932 SUCCEEDED(transform->GetOutputAvailableType( 2833 SUCCEEDED(transform->GetOutputAvailableType(0, i, media_type.Receive()));
2933 0, i, media_type.Receive()));
2934 ++i) { 2834 ++i) {
2935 GUID out_subtype = {0}; 2835 GUID out_subtype = {0};
2936 hr = media_type->GetGUID(MF_MT_SUBTYPE, &out_subtype); 2836 hr = media_type->GetGUID(MF_MT_SUBTYPE, &out_subtype);
2937 RETURN_ON_HR_FAILURE(hr, "Failed to get output major type", false); 2837 RETURN_ON_HR_FAILURE(hr, "Failed to get output major type", false);
2938 2838
2939 if (out_subtype == output_type) { 2839 if (out_subtype == output_type) {
2940 if (width && height) { 2840 if (width && height) {
2941 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, 2841 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width,
2942 height); 2842 height);
2943 RETURN_ON_HR_FAILURE(hr, "Failed to set media type attributes", false); 2843 RETURN_ON_HR_FAILURE(hr, "Failed to set media type attributes", false);
2944 } 2844 }
2945 hr = transform->SetOutputType(0, media_type.get(), 0); // No flags 2845 hr = transform->SetOutputType(0, media_type.get(), 0); // No flags
2946 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); 2846 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false);
2947 return true; 2847 return true;
2948 } 2848 }
2949 media_type.Release(); 2849 media_type.Release();
2950 } 2850 }
2951 return false; 2851 return false;
2952 } 2852 }
2953 2853
2954 HRESULT DXVAVideoDecodeAccelerator::CheckConfigChanged( 2854 HRESULT DXVAVideoDecodeAccelerator::CheckConfigChanged(IMFSample* sample,
2955 IMFSample* sample, bool* config_changed) { 2855 bool* config_changed) {
2956 if (codec_ != media::kCodecH264) 2856 if (codec_ != media::kCodecH264)
2957 return S_FALSE; 2857 return S_FALSE;
2958 2858
2959 base::win::ScopedComPtr<IMFMediaBuffer> buffer; 2859 base::win::ScopedComPtr<IMFMediaBuffer> buffer;
2960 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); 2860 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive());
2961 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr); 2861 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr);
2962 2862
2963 MediaBufferScopedPointer scoped_media_buffer(buffer.get()); 2863 MediaBufferScopedPointer scoped_media_buffer(buffer.get());
2964 2864
2965 if (!config_change_detector_->DetectConfig( 2865 if (!config_change_detector_->DetectConfig(
2966 scoped_media_buffer.get(), 2866 scoped_media_buffer.get(), scoped_media_buffer.current_length())) {
2967 scoped_media_buffer.current_length())) {
2968 RETURN_ON_HR_FAILURE(E_FAIL, "Failed to detect H.264 stream config", 2867 RETURN_ON_HR_FAILURE(E_FAIL, "Failed to detect H.264 stream config",
2969 E_FAIL); 2868 E_FAIL);
2970 } 2869 }
2971 *config_changed = config_change_detector_->config_changed(); 2870 *config_changed = config_change_detector_->config_changed();
2972 return S_OK; 2871 return S_OK;
2973 } 2872 }
2974 2873
2975 void DXVAVideoDecodeAccelerator::ConfigChanged( 2874 void DXVAVideoDecodeAccelerator::ConfigChanged(const Config& config) {
2976 const Config& config) {
2977 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 2875 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2978 2876
2979 SetState(kConfigChange); 2877 SetState(kConfigChange);
2980 DismissStaleBuffers(true); 2878 DismissStaleBuffers(true);
2981 Invalidate(); 2879 Invalidate();
2982 Initialize(config_, client_); 2880 Initialize(config_, client_);
2983 decoder_thread_task_runner_->PostTask( 2881 decoder_thread_task_runner_->PostTask(
2984 FROM_HERE, 2882 FROM_HERE,
2985 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2883 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2986 base::Unretained(this))); 2884 base::Unretained(this)));
2987 } 2885 }
2988 2886
2989 } // namespace content 2887 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/dxva_video_decode_accelerator_win.h ('k') | media/gpu/fake_video_decode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698