OLD | NEW |
---|---|
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.h" | 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" |
6 | 6 |
7 #if !defined(OS_WIN) | 7 #if !defined(OS_WIN) |
8 #error This file should only be built on Windows. | 8 #error This file should only be built on Windows. |
9 #endif // !defined(OS_WIN) | 9 #endif // !defined(OS_WIN) |
10 | 10 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 StopOnError(error_code); \ | 66 StopOnError(error_code); \ |
67 return ret; \ | 67 return ret; \ |
68 } \ | 68 } \ |
69 } while (0) | 69 } while (0) |
70 | 70 |
71 #define RETURN_AND_NOTIFY_ON_HR_FAILURE(result, log, error_code, ret) \ | 71 #define RETURN_AND_NOTIFY_ON_HR_FAILURE(result, log, error_code, ret) \ |
72 RETURN_AND_NOTIFY_ON_FAILURE(SUCCEEDED(result), \ | 72 RETURN_AND_NOTIFY_ON_FAILURE(SUCCEEDED(result), \ |
73 log << ", HRESULT: 0x" << std::hex << result, \ | 73 log << ", HRESULT: 0x" << std::hex << result, \ |
74 error_code, ret); | 74 error_code, ret); |
75 | 75 |
76 // Maximum number of iterations we allow before aborting the attempt to flush | |
77 // the batched queries to the driver. | |
Ami GONE FROM CHROMIUM
2012/11/13 23:07:13
Why is it safe to give up? What is the cost to co
ananta
2012/11/13 23:17:22
Cost to correctness would be torn frames in the wo
apatrick_chromium
2012/11/14 01:27:49
I expect it will be torn frames or similar. It won
| |
78 #define MAX_ITERATIONS_FOR_D3D_FLUSH 10 | |
Ami GONE FROM CHROMIUM
2012/11/13 23:07:13
prefer enum to #define
enum { kMaxiterationsForD3d
| |
79 | |
76 static IMFSample* CreateEmptySample() { | 80 static IMFSample* CreateEmptySample() { |
77 base::win::ScopedComPtr<IMFSample> sample; | 81 base::win::ScopedComPtr<IMFSample> sample; |
78 HRESULT hr = MFCreateSample(sample.Receive()); | 82 HRESULT hr = MFCreateSample(sample.Receive()); |
79 RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", NULL); | 83 RETURN_ON_HR_FAILURE(hr, "MFCreateSample failed", NULL); |
80 return sample.Detach(); | 84 return sample.Detach(); |
81 } | 85 } |
82 | 86 |
83 // Creates a Media Foundation sample with one buffer of length |buffer_length| | 87 // Creates a Media Foundation sample with one buffer of length |buffer_length| |
84 // on a |align|-byte boundary. Alignment must be a perfect power of 2 or 0. | 88 // on a |align|-byte boundary. Alignment must be a perfect power of 2 or 0. |
85 static IMFSample* CreateEmptySampleWithBuffer(int buffer_length, int align) { | 89 static IMFSample* CreateEmptySampleWithBuffer(int buffer_length, int align) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 DWORD max_length = 0; | 132 DWORD max_length = 0; |
129 DWORD current_length = 0; | 133 DWORD current_length = 0; |
130 uint8* destination = NULL; | 134 uint8* destination = NULL; |
131 hr = buffer->Lock(&destination, &max_length, ¤t_length); | 135 hr = buffer->Lock(&destination, &max_length, ¤t_length); |
132 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL); | 136 RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL); |
133 | 137 |
134 CHECK_EQ(current_length, 0u); | 138 CHECK_EQ(current_length, 0u); |
135 CHECK_GE(static_cast<int>(max_length), size); | 139 CHECK_GE(static_cast<int>(max_length), size); |
136 memcpy(destination, stream, size); | 140 memcpy(destination, stream, size); |
137 | 141 |
142 hr = buffer->SetCurrentLength(size); | |
Ami GONE FROM CHROMIUM
2012/11/13 23:07:13
what's this move about? unmentioned in CL descrip
ananta
2012/11/13 23:17:22
Sorry. needless change crept in. was debugging som
| |
143 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL); | |
144 | |
138 hr = buffer->Unlock(); | 145 hr = buffer->Unlock(); |
139 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL); | 146 RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL); |
140 | 147 |
141 hr = buffer->SetCurrentLength(size); | |
142 RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL); | |
143 | |
144 return sample.Detach(); | 148 return sample.Detach(); |
145 } | 149 } |
146 | 150 |
147 static IMFSample* CreateSampleFromInputBuffer( | 151 static IMFSample* CreateSampleFromInputBuffer( |
148 const media::BitstreamBuffer& bitstream_buffer, | 152 const media::BitstreamBuffer& bitstream_buffer, |
149 DWORD stream_size, | 153 DWORD stream_size, |
150 DWORD alignment) { | 154 DWORD alignment) { |
151 base::SharedMemory shm(bitstream_buffer.handle(), true); | 155 base::SharedMemory shm(bitstream_buffer.handle(), true); |
152 RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()), | 156 RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()), |
153 "Failed in base::SharedMemory::Map", NULL); | 157 "Failed in base::SharedMemory::Map", NULL); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 NULL, | 393 NULL, |
390 d3d_surface, | 394 d3d_surface, |
391 NULL, | 395 NULL, |
392 D3DTEXF_NONE); | 396 D3DTEXF_NONE); |
393 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", | 397 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", |
394 false); | 398 false); |
395 // Ideally, this should be done immediately before the draw call that uses | 399 // Ideally, this should be done immediately before the draw call that uses |
396 // the texture. Flush it once here though. | 400 // the texture. Flush it once here though. |
397 hr = query_->Issue(D3DISSUE_END); | 401 hr = query_->Issue(D3DISSUE_END); |
398 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", false); | 402 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", false); |
403 | |
404 // The loop below attempts to flush the batched queries to the driver. We | |
405 // don't want to loop endlessly waiting for the driver to return success. | |
Ami GONE FROM CHROMIUM
2012/11/13 23:07:13
...because we've seen driver bugs?
| |
406 // The current workaround is to allow a max of MAX_ITERATIONS_FOR_D3D_FLUSH | |
407 // iterations. | |
408 int iterations = 0; | |
399 do { | 409 do { |
410 if (iterations > MAX_ITERATIONS_FOR_D3D_FLUSH) | |
Ami GONE FROM CHROMIUM
2012/11/13 23:07:13
putting this test in the while condition would obv
ananta
2012/11/13 23:17:22
Done.
| |
411 break; | |
400 hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH); | 412 hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH); |
401 if (hr == S_FALSE) | 413 if (hr == S_FALSE) { |
402 Sleep(1); // Poor-man's Yield(). | 414 Sleep(1); // Poor-man's Yield(). |
415 ++iterations; | |
416 } | |
403 } while (hr == S_FALSE); | 417 } while (hr == S_FALSE); |
Ami GONE FROM CHROMIUM
2012/11/13 23:07:13
l.408-417 could be rewritten as:
int iterations =
ananta
2012/11/13 23:17:22
Done.
| |
418 | |
404 eglBindTexImage( | 419 eglBindTexImage( |
405 static_cast<EGLDisplay*>(eglGetDisplay(EGL_DEFAULT_DISPLAY)), | 420 static_cast<EGLDisplay*>(eglGetDisplay(EGL_DEFAULT_DISPLAY)), |
406 decoding_surface_, | 421 decoding_surface_, |
407 EGL_BACK_BUFFER); | 422 EGL_BACK_BUFFER); |
408 } else { | 423 } else { |
409 scoped_array<char> bits; | 424 scoped_array<char> bits; |
410 RETURN_ON_FAILURE(GetBitmapFromSurface(DXVAVideoDecodeAccelerator::device_, | 425 RETURN_ON_FAILURE(GetBitmapFromSurface(DXVAVideoDecodeAccelerator::device_, |
411 dest_surface, &bits), | 426 dest_surface, &bits), |
412 "Failed to get bitmap from surface for rendering", | 427 "Failed to get bitmap from surface for rendering", |
413 false); | 428 false); |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
811 | 826 |
812 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); | 827 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); |
813 RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false); | 828 RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false); |
814 | 829 |
815 // Not sure about this. msdn recommends setting this value on the input | 830 // Not sure about this. msdn recommends setting this value on the input |
816 // media type. | 831 // media type. |
817 hr = media_type->SetUINT32(MF_MT_INTERLACE_MODE, | 832 hr = media_type->SetUINT32(MF_MT_INTERLACE_MODE, |
818 MFVideoInterlace_MixedInterlaceOrProgressive); | 833 MFVideoInterlace_MixedInterlaceOrProgressive); |
819 RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false); | 834 RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false); |
820 | 835 |
836 hr = MFSetAttributeSize(media_type, MF_MT_PIXEL_ASPECT_RATIO, 2, 1); | |
Ami GONE FROM CHROMIUM
2012/11/13 23:07:13
wat?
ananta
2012/11/13 23:17:22
Unrelated change. Was debugging the small video pa
| |
837 RETURN_ON_HR_FAILURE(hr, "Failed to set aspect ratio", false); | |
838 | |
821 hr = decoder_->SetInputType(0, media_type, 0); // No flags | 839 hr = decoder_->SetInputType(0, media_type, 0); // No flags |
822 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); | 840 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); |
823 return true; | 841 return true; |
824 } | 842 } |
825 | 843 |
826 bool DXVAVideoDecodeAccelerator::SetDecoderOutputMediaType( | 844 bool DXVAVideoDecodeAccelerator::SetDecoderOutputMediaType( |
827 const GUID& subtype) { | 845 const GUID& subtype) { |
828 base::win::ScopedComPtr<IMFMediaType> out_media_type; | 846 base::win::ScopedComPtr<IMFMediaType> out_media_type; |
829 | 847 |
830 for (uint32 i = 0; | 848 for (uint32 i = 0; |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1138 return; | 1156 return; |
1139 } | 1157 } |
1140 | 1158 |
1141 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 1159 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
1142 &DXVAVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this))); | 1160 &DXVAVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this))); |
1143 | 1161 |
1144 state_ = kNormal; | 1162 state_ = kNormal; |
1145 } | 1163 } |
1146 | 1164 |
1147 } // namespace content | 1165 } // namespace content |
OLD | NEW |