Index: media/gpu/dxva_video_decode_accelerator_win.cc |
diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc |
index 8f3f2575c3e7fa3feef923511a0ee269ac876fc8..ce43d8713c650bd2109c259d0bd5a6335e3f84db 100644 |
--- a/media/gpu/dxva_video_decode_accelerator_win.cc |
+++ b/media/gpu/dxva_video_decode_accelerator_win.cc |
@@ -39,7 +39,6 @@ |
#include "build/build_config.h" |
#include "gpu/command_buffer/service/gpu_preferences.h" |
#include "gpu/config/gpu_driver_bug_workarounds.h" |
-#include "media/base/win/mf_helpers.h" |
#include "media/base/win/mf_initializer.h" |
#include "media/gpu/dxva_picture_buffer_win.h" |
#include "media/video/video_decode_accelerator.h" |
@@ -188,6 +187,42 @@ |
0x102, 0x106, 0x116, 0x126, |
}; |
+// Provides scoped access to the underlying buffer in an IMFMediaBuffer |
+// instance. |
+class MediaBufferScopedPointer { |
+ public: |
+ explicit MediaBufferScopedPointer(IMFMediaBuffer* media_buffer) |
+ : media_buffer_(media_buffer), |
+ buffer_(nullptr), |
+ max_length_(0), |
+ current_length_(0) { |
+ HRESULT hr = media_buffer_->Lock(&buffer_, &max_length_, ¤t_length_); |
+ CHECK(SUCCEEDED(hr)); |
+ } |
+ |
+ ~MediaBufferScopedPointer() { |
+ HRESULT hr = media_buffer_->Unlock(); |
+ CHECK(SUCCEEDED(hr)); |
+ } |
+ |
+ uint8_t* get() { return buffer_; } |
+ |
+ DWORD current_length() const { return current_length_; } |
+ |
+ private: |
+ base::win::ScopedComPtr<IMFMediaBuffer> media_buffer_; |
+ uint8_t* buffer_; |
+ DWORD max_length_; |
+ DWORD current_length_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MediaBufferScopedPointer); |
+}; |
+ |
+void LogDXVAError(int line) { |
+ LOG(ERROR) << "Error in dxva_video_decode_accelerator_win.cc on line " |
+ << line; |
+} |
+ |
} // namespace |
namespace media { |
@@ -199,6 +234,34 @@ |
CreateDXGIDeviceManager |
DXVAVideoDecodeAccelerator::create_dxgi_device_manager_ = NULL; |
+ |
+#define RETURN_ON_FAILURE(result, log, ret) \ |
+ do { \ |
+ if (!(result)) { \ |
+ DLOG(ERROR) << log; \ |
+ LogDXVAError(__LINE__); \ |
+ return ret; \ |
+ } \ |
+ } while (0) |
+ |
+#define RETURN_ON_HR_FAILURE(result, log, ret) \ |
+ RETURN_ON_FAILURE(SUCCEEDED(result), \ |
+ log << ", HRESULT: 0x" << std::hex << result, ret); |
+ |
+#define RETURN_AND_NOTIFY_ON_FAILURE(result, log, error_code, ret) \ |
+ do { \ |
+ if (!(result)) { \ |
+ DVLOG(1) << log; \ |
+ LogDXVAError(__LINE__); \ |
+ StopOnError(error_code); \ |
+ return ret; \ |
+ } \ |
+ } while (0) |
+ |
+#define RETURN_AND_NOTIFY_ON_HR_FAILURE(result, log, error_code, ret) \ |
+ RETURN_AND_NOTIFY_ON_FAILURE(SUCCEEDED(result), \ |
+ log << ", HRESULT: 0x" << std::hex << result, \ |
+ error_code, ret); |
enum { |
// Maximum number of iterations we allow before aborting the attempt to flush |
@@ -219,6 +282,41 @@ |
kAcquireSyncWaitMs = 0, |
}; |
+static IMFSample* CreateEmptySample() { |
+ base::win::ScopedComPtr<IMFSample> sample; |
+ HRESULT hr = MFCreateSample(sample.Receive()); |
+ RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", NULL); |
+ return sample.Detach(); |
+} |
+ |
+// Creates a Media Foundation sample with one buffer of length |buffer_length| |
+// on a |align|-byte boundary. Alignment must be a perfect power of 2 or 0. |
+static IMFSample* CreateEmptySampleWithBuffer(uint32_t buffer_length, |
+ int align) { |
+ CHECK_GT(buffer_length, 0U); |
+ |
+ base::win::ScopedComPtr<IMFSample> sample; |
+ sample.Attach(CreateEmptySample()); |
+ |
+ base::win::ScopedComPtr<IMFMediaBuffer> buffer; |
+ HRESULT hr = E_FAIL; |
+ if (align == 0) { |
+ // Note that MFCreateMemoryBuffer is same as MFCreateAlignedMemoryBuffer |
+ // with the align argument being 0. |
+ hr = MFCreateMemoryBuffer(buffer_length, buffer.Receive()); |
+ } else { |
+ hr = |
+ MFCreateAlignedMemoryBuffer(buffer_length, align - 1, buffer.Receive()); |
+ } |
+ RETURN_ON_HR_FAILURE(hr, "Failed to create memory buffer for sample", NULL); |
+ |
+ hr = sample->AddBuffer(buffer.get()); |
+ RETURN_ON_HR_FAILURE(hr, "Failed to add buffer to sample", NULL); |
+ |
+ buffer->SetCurrentLength(0); |
+ return sample.Detach(); |
+} |
+ |
// Creates a Media Foundation sample with one buffer containing a copy of the |
// given Annex B stream data. |
// If duration and sample time are not known, provide 0. |
@@ -232,7 +330,7 @@ |
CHECK_GT(size, 0U); |
base::win::ScopedComPtr<IMFSample> sample; |
sample.Attach( |
- mf::CreateEmptySampleWithBuffer(std::max(min_size, size), alignment)); |
+ CreateEmptySampleWithBuffer(std::max(min_size, size), alignment)); |
RETURN_ON_FAILURE(sample.get(), "Failed to create empty sample", NULL); |
base::win::ScopedComPtr<IMFMediaBuffer> buffer; |
@@ -2653,7 +2751,7 @@ |
HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); |
RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr); |
- mf::MediaBufferScopedPointer scoped_media_buffer(buffer.get()); |
+ MediaBufferScopedPointer scoped_media_buffer(buffer.get()); |
if (!config_change_detector_->DetectConfig( |
scoped_media_buffer.get(), scoped_media_buffer.current_length())) { |