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

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

Issue 1815063002: Detect configuration changes in H.264 video streams in the DXVA decoder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Report config changed only after we see an IDR frame Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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 "content/common/gpu/media/dxva_video_decode_accelerator_win.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 16 matching lines...) Expand all
27 #include "base/logging.h" 27 #include "base/logging.h"
28 #include "base/macros.h" 28 #include "base/macros.h"
29 #include "base/memory/scoped_ptr.h" 29 #include "base/memory/scoped_ptr.h"
30 #include "base/memory/shared_memory.h" 30 #include "base/memory/shared_memory.h"
31 #include "base/message_loop/message_loop.h" 31 #include "base/message_loop/message_loop.h"
32 #include "base/path_service.h" 32 #include "base/path_service.h"
33 #include "base/trace_event/trace_event.h" 33 #include "base/trace_event/trace_event.h"
34 #include "base/win/windows_version.h" 34 #include "base/win/windows_version.h"
35 #include "build/build_config.h" 35 #include "build/build_config.h"
36 #include "media/base/win/mf_initializer.h" 36 #include "media/base/win/mf_initializer.h"
37 #include "media/filters/h264_parser.h"
37 #include "media/video/video_decode_accelerator.h" 38 #include "media/video/video_decode_accelerator.h"
38 #include "third_party/angle/include/EGL/egl.h" 39 #include "third_party/angle/include/EGL/egl.h"
39 #include "third_party/angle/include/EGL/eglext.h" 40 #include "third_party/angle/include/EGL/eglext.h"
40 #include "ui/gl/gl_bindings.h" 41 #include "ui/gl/gl_bindings.h"
41 #include "ui/gl/gl_context.h" 42 #include "ui/gl/gl_context.h"
42 #include "ui/gl/gl_fence.h" 43 #include "ui/gl/gl_fence.h"
43 #include "ui/gl/gl_surface_egl.h" 44 #include "ui/gl/gl_surface_egl.h"
44 45
45 namespace { 46 namespace {
46 47
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 #endif 105 #endif
105 106
106 // MF_XVP_PLAYBACK_MODE 107 // MF_XVP_PLAYBACK_MODE
107 // Data type: UINT32 (treat as BOOL) 108 // Data type: UINT32 (treat as BOOL)
108 // If this attribute is TRUE, the video processor will run in playback mode 109 // If this attribute is TRUE, the video processor will run in playback mode
109 // where it allows callers to allocate output samples and allows last frame 110 // where it allows callers to allocate output samples and allows last frame
110 // regeneration (repaint). 111 // regeneration (repaint).
111 DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12, 112 DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12,
112 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9); 113 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9);
113 114
115 // Provides scoped access to the underlying buffer in an IMFMediaBuffer
116 // instance.
117 class MediaBufferScopedPointer {
118 public:
119 MediaBufferScopedPointer(IMFMediaBuffer* media_buffer)
120 : media_buffer_(media_buffer),
121 buffer_(nullptr),
122 max_length_(0),
123 current_length_(0) {
124 HRESULT hr = media_buffer_->Lock(&buffer_, &max_length_, &current_length_);
125 CHECK(SUCCEEDED(hr));
126 }
127
128 ~MediaBufferScopedPointer() {
129 HRESULT hr = media_buffer_->Unlock();
130 CHECK(SUCCEEDED(hr));
131 }
132
133 uint8_t* get() {
134 return buffer_;
135 }
136
137 DWORD current_length() const {
138 return current_length_;
139 }
140
141 private:
142 base::win::ScopedComPtr<IMFMediaBuffer> media_buffer_;
143 uint8_t* buffer_;
144 DWORD max_length_;
145 DWORD current_length_;
146
147 DISALLOW_COPY_AND_ASSIGN(MediaBufferScopedPointer);
148 };
149
114 } // namespace 150 } // namespace
115 151
116 namespace content { 152 namespace content {
117 153
118 static const media::VideoCodecProfile kSupportedProfiles[] = { 154 static const media::VideoCodecProfile kSupportedProfiles[] = {
119 media::H264PROFILE_BASELINE, 155 media::H264PROFILE_BASELINE,
120 media::H264PROFILE_MAIN, 156 media::H264PROFILE_MAIN,
121 media::H264PROFILE_HIGH, 157 media::H264PROFILE_HIGH,
122 media::VP8PROFILE_ANY, 158 media::VP8PROFILE_ANY,
123 media::VP9PROFILE_ANY 159 media::VP9PROFILE_ANY
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 reinterpret_cast<EGLDeviceEXT>(egl_device), object_type, &device), 360 reinterpret_cast<EGLDeviceEXT>(egl_device), object_type, &device),
325 "The eglQueryDeviceAttribEXT function failed to get the device", 361 "The eglQueryDeviceAttribEXT function failed to get the device",
326 device_object); 362 device_object);
327 363
328 RETURN_ON_FAILURE(device, "Failed to get the ANGLE device", device_object); 364 RETURN_ON_FAILURE(device, "Failed to get the ANGLE device", device_object);
329 365
330 device_object = reinterpret_cast<T*>(device); 366 device_object = reinterpret_cast<T*>(device);
331 return device_object; 367 return device_object;
332 } 368 }
333 369
370 H264ConfigChangeDetector::H264ConfigChangeDetector()
371 : last_sps_id_(0),
372 last_pps_id_(0),
373 config_changed_(false) {
374 }
375
376 H264ConfigChangeDetector::~H264ConfigChangeDetector() {
377 }
378
379 bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream,
380 unsigned int size) {
381 std::vector<uint8_t> sps;
382 std::vector<uint8_t> pps;
383 media::H264NALU nalu;
384 bool idr_seen = false;
385
386 media::H264Parser parser;
387 parser.SetStream(stream, size);
388 config_changed_ = false;
389
390 while (true) {
391 media::H264Parser::Result result = parser.AdvanceToNextNALU(&nalu);
392
393 if (result == media::H264Parser::kEOStream)
394 break;
395
396 if (result == media::H264Parser::kUnsupportedStream) {
397 DLOG(ERROR) << "Unsupported H.264 stream";
398 return false;
399 }
400
401 if (result != media::H264Parser::kOk) {
402 DLOG(ERROR) << "Failed to parse H.264 stream";
403 return false;
404 }
405
406 switch (nalu.nal_unit_type) {
407 case media::H264NALU::kSPS:
408 result = parser.ParseSPS(&last_sps_id_);
409 if (result == media::H264Parser::kUnsupportedStream) {
410 DLOG(ERROR) << "Unsupported SPS";
411 return false;
412 }
413
414 if (result != media::H264Parser::kOk) {
415 DLOG(ERROR) << "Could not parse SPS";
416 return false;
417 }
418
419 sps.assign(nalu.data, nalu.data + nalu.size);
420 break;
421
422 case media::H264NALU::kPPS:
423 result = parser.ParsePPS(&last_pps_id_);
424 if (result == media::H264Parser::kUnsupportedStream) {
425 DLOG(ERROR) << "Unsupported PPS";
426 return false;
427 }
428 if (result != media::H264Parser::kOk) {
429 DLOG(ERROR) << "Could not parse PPS";
430 return false;
431 }
432 pps.assign(nalu.data, nalu.data + nalu.size);
433 break;
434
435 case media::H264NALU::kIDRSlice:
436 idr_seen = true;
437 break;
438
439 default:
440 break;
441 }
442 }
443
444 if (!sps.empty() && sps != last_sps_) {
445 if (!last_sps_.empty() && idr_seen)
sandersd (OOO until July 31) 2016/03/18 23:38:29 I worry that Flash may send the SPS/PPS on one buf
ananta 2016/03/19 00:00:59 Thanks for pointing that out. Updated
446 config_changed_ = true;
447 last_sps_.swap(sps);
448 }
449
450 if (!pps.empty() && pps != last_pps_) {
451 if (!last_pps_.empty() && idr_seen)
452 config_changed_ = true;
453 last_pps_.swap(pps);
454 }
455 return true;
456 }
334 457
335 // Maintains information about a DXVA picture buffer, i.e. whether it is 458 // Maintains information about a DXVA picture buffer, i.e. whether it is
336 // available for rendering, the texture information, etc. 459 // available for rendering, the texture information, etc.
337 struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer { 460 struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
338 public: 461 public:
339 static linked_ptr<DXVAPictureBuffer> Create( 462 static linked_ptr<DXVAPictureBuffer> Create(
340 const DXVAVideoDecodeAccelerator& decoder, 463 const DXVAVideoDecodeAccelerator& decoder,
341 const media::PictureBuffer& buffer, 464 const media::PictureBuffer& buffer,
342 EGLConfig egl_config); 465 EGLConfig egl_config);
343 ~DXVAPictureBuffer(); 466 ~DXVAPictureBuffer();
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 RETURN_AND_NOTIFY_ON_FAILURE( 904 RETURN_AND_NOTIFY_ON_FAILURE(
782 SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0), 905 SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0),
783 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed", 906 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed",
784 PLATFORM_FAILURE, false); 907 PLATFORM_FAILURE, false);
785 908
786 RETURN_AND_NOTIFY_ON_FAILURE( 909 RETURN_AND_NOTIFY_ON_FAILURE(
787 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0), 910 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0),
788 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed", 911 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed",
789 PLATFORM_FAILURE, false); 912 PLATFORM_FAILURE, false);
790 913
914 config_ = config;
915
791 SetState(kNormal); 916 SetState(kNormal);
792 917
793 StartDecoderThread(); 918 StartDecoderThread();
794 return true; 919 return true;
795 } 920 }
796 921
797 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { 922 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() {
798 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager"); 923 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager");
799 924
800 HRESULT hr = E_FAIL; 925 HRESULT hr = E_FAIL;
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 return; 1158 return;
1034 1159
1035 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); 1160 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
1036 // If we didn't find the picture id in the |output_picture_buffers_| map we 1161 // If we didn't find the picture id in the |output_picture_buffers_| map we
1037 // try the |stale_output_picture_buffers_| map, as this may have been an 1162 // try the |stale_output_picture_buffers_| map, as this may have been an
1038 // output picture buffer from before a resolution change, that at resolution 1163 // output picture buffer from before a resolution change, that at resolution
1039 // change time had yet to be displayed. The client is calling us back to tell 1164 // change time had yet to be displayed. The client is calling us back to tell
1040 // us that we can now recycle this picture buffer, so if we were waiting to 1165 // us that we can now recycle this picture buffer, so if we were waiting to
1041 // dispose of it we now can. 1166 // dispose of it we now can.
1042 if (it == output_picture_buffers_.end()) { 1167 if (it == output_picture_buffers_.end()) {
1043 it = stale_output_picture_buffers_.find(picture_buffer_id); 1168 if (!stale_output_picture_buffers_.empty()) {
1044 RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(), 1169 it = stale_output_picture_buffers_.find(picture_buffer_id);
1045 "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,); 1170 RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(),
1046 main_thread_task_runner_->PostTask( 1171 "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,);
1047 FROM_HERE, 1172 main_thread_task_runner_->PostTask(
1048 base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer, 1173 FROM_HERE,
1049 weak_this_factory_.GetWeakPtr(), picture_buffer_id)); 1174 base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer,
1175 weak_this_factory_.GetWeakPtr(), picture_buffer_id));
1176 }
1050 return; 1177 return;
1051 } 1178 }
1052 1179
1053 if (it->second->available() || it->second->waiting_to_reuse()) 1180 if (it->second->available() || it->second->waiting_to_reuse())
1054 return; 1181 return;
1055 1182
1056 if (use_keyed_mutex_ || using_angle_device_) { 1183 if (use_keyed_mutex_ || using_angle_device_) {
1057 RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(), 1184 RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(),
1058 "Failed to reuse picture buffer", 1185 "Failed to reuse picture buffer",
1059 PLATFORM_FAILURE, ); 1186 PLATFORM_FAILURE, );
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 if (GetState() == kUninitialized) 1799 if (GetState() == kUninitialized)
1673 return; 1800 return;
1674 1801
1675 decoder_thread_.Stop(); 1802 decoder_thread_.Stop();
1676 weak_this_factory_.InvalidateWeakPtrs(); 1803 weak_this_factory_.InvalidateWeakPtrs();
1677 output_picture_buffers_.clear(); 1804 output_picture_buffers_.clear();
1678 stale_output_picture_buffers_.clear(); 1805 stale_output_picture_buffers_.clear();
1679 pending_output_samples_.clear(); 1806 pending_output_samples_.clear();
1680 pending_input_buffers_.clear(); 1807 pending_input_buffers_.clear();
1681 decoder_.Release(); 1808 decoder_.Release();
1809 pictures_requested_ = false;
1682 1810
1683 if (use_dx11_) { 1811 if (use_dx11_) {
1684 if (video_format_converter_mft_.get()) { 1812 if (video_format_converter_mft_.get()) {
1685 video_format_converter_mft_->ProcessMessage( 1813 video_format_converter_mft_->ProcessMessage(
1686 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); 1814 MFT_MESSAGE_NOTIFY_END_STREAMING, 0);
1687 video_format_converter_mft_.Release(); 1815 video_format_converter_mft_.Release();
1688 } 1816 }
1689 d3d11_device_context_.Release(); 1817 d3d11_device_context_.Release();
1690 d3d11_device_.Release(); 1818 d3d11_device_.Release();
1691 d3d11_device_manager_.Release(); 1819 d3d11_device_manager_.Release();
1692 d3d11_query_.Release(); 1820 d3d11_query_.Release();
1693 dx11_video_format_converter_media_type_needs_init_ = true; 1821 dx11_video_format_converter_media_type_needs_init_ = true;
1822 multi_threaded_.Release();
1694 } else { 1823 } else {
1695 d3d9_.Release(); 1824 d3d9_.Release();
1696 d3d9_device_ex_.Release(); 1825 d3d9_device_ex_.Release();
1697 device_manager_.Release(); 1826 device_manager_.Release();
1698 query_.Release(); 1827 query_.Release();
1699 } 1828 }
1700 1829
1701 SetState(kUninitialized); 1830 SetState(kUninitialized);
1702 } 1831 }
1703 1832
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 1967 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
1839 1968
1840 if (GetState() == kUninitialized) 1969 if (GetState() == kUninitialized)
1841 return; 1970 return;
1842 1971
1843 if (OutputSamplesPresent() || !pending_input_buffers_.empty()) { 1972 if (OutputSamplesPresent() || !pending_input_buffers_.empty()) {
1844 pending_input_buffers_.push_back(sample); 1973 pending_input_buffers_.push_back(sample);
1845 return; 1974 return;
1846 } 1975 }
1847 1976
1977 // Check if the resolution, bit rate, etc changed in the stream. If yes we
1978 // reinitialize the decoder to ensure that the stream decodes correctly.
1979 bool config_changed = false;
1980
1981 HRESULT hr = CheckConfigChanged(sample.get(), &config_changed);
1982 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to check video stream config",
1983 PLATFORM_FAILURE,);
1984
1985 if (config_changed) {
1986 main_thread_task_runner_->PostTask(
1987 FROM_HERE,
1988 base::Bind(&DXVAVideoDecodeAccelerator::ConfigChanged,
1989 weak_this_factory_.GetWeakPtr(),
1990 config_,
1991 sample));
1992 return;
1993 }
1994
1848 if (!inputs_before_decode_) { 1995 if (!inputs_before_decode_) {
1849 TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding", 1996 TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding",
1850 this); 1997 this);
1851 } 1998 }
1852 inputs_before_decode_++; 1999 inputs_before_decode_++;
1853 2000
1854 HRESULT hr = decoder_->ProcessInput(0, sample.get(), 0); 2001 hr = decoder_->ProcessInput(0, sample.get(), 0);
1855 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it 2002 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it
1856 // has enough data to produce one or more output samples. In this case the 2003 // has enough data to produce one or more output samples. In this case the
1857 // recommended options are to 2004 // recommended options are to
1858 // 1. Generate new output by calling IMFTransform::ProcessOutput until it 2005 // 1. Generate new output by calling IMFTransform::ProcessOutput until it
1859 // returns MF_E_TRANSFORM_NEED_MORE_INPUT. 2006 // returns MF_E_TRANSFORM_NEED_MORE_INPUT.
1860 // 2. Flush the input data 2007 // 2. Flush the input data
1861 // We implement the first option, i.e to retrieve the output sample and then 2008 // We implement the first option, i.e to retrieve the output sample and then
1862 // process the input again. Failure in either of these steps is treated as a 2009 // process the input again. Failure in either of these steps is treated as a
1863 // decoder failure. 2010 // decoder failure.
1864 if (hr == MF_E_NOTACCEPTING) { 2011 if (hr == MF_E_NOTACCEPTING) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 input_buffer_id)); 2069 input_buffer_id));
1923 } 2070 }
1924 2071
1925 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width, 2072 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width,
1926 int height) { 2073 int height) {
1927 dx11_video_format_converter_media_type_needs_init_ = true; 2074 dx11_video_format_converter_media_type_needs_init_ = true;
1928 2075
1929 main_thread_task_runner_->PostTask( 2076 main_thread_task_runner_->PostTask(
1930 FROM_HERE, 2077 FROM_HERE,
1931 base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers, 2078 base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers,
1932 weak_this_factory_.GetWeakPtr())); 2079 weak_this_factory_.GetWeakPtr(), false));
1933 2080
1934 main_thread_task_runner_->PostTask( 2081 main_thread_task_runner_->PostTask(
1935 FROM_HERE, 2082 FROM_HERE,
1936 base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers, 2083 base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
1937 weak_this_factory_.GetWeakPtr(), 2084 weak_this_factory_.GetWeakPtr(),
1938 width, 2085 width,
1939 height)); 2086 height));
1940 } 2087 }
1941 2088
1942 void DXVAVideoDecodeAccelerator::DismissStaleBuffers() { 2089 void DXVAVideoDecodeAccelerator::DismissStaleBuffers(bool force) {
1943 OutputBuffers::iterator index; 2090 OutputBuffers::iterator index;
1944 2091
1945 for (index = output_picture_buffers_.begin(); 2092 for (index = output_picture_buffers_.begin();
1946 index != output_picture_buffers_.end(); 2093 index != output_picture_buffers_.end();
1947 ++index) { 2094 ++index) {
1948 if (index->second->available()) { 2095 if (force || index->second->available()) {
1949 DVLOG(1) << "Dismissing picture id: " << index->second->id(); 2096 DVLOG(1) << "Dismissing picture id: " << index->second->id();
1950 client_->DismissPictureBuffer(index->second->id()); 2097 client_->DismissPictureBuffer(index->second->id());
1951 } else { 2098 } else {
1952 // Move to |stale_output_picture_buffers_| for deferred deletion. 2099 // Move to |stale_output_picture_buffers_| for deferred deletion.
1953 stale_output_picture_buffers_.insert( 2100 stale_output_picture_buffers_.insert(
1954 std::make_pair(index->first, index->second)); 2101 std::make_pair(index->first, index->second));
1955 } 2102 }
1956 } 2103 }
1957 2104
1958 output_picture_buffers_.clear(); 2105 output_picture_buffers_.clear();
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
2447 } 2594 }
2448 hr = transform->SetOutputType(0, media_type.get(), 0); // No flags 2595 hr = transform->SetOutputType(0, media_type.get(), 0); // No flags
2449 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); 2596 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false);
2450 return true; 2597 return true;
2451 } 2598 }
2452 media_type.Release(); 2599 media_type.Release();
2453 } 2600 }
2454 return false; 2601 return false;
2455 } 2602 }
2456 2603
2604 HRESULT DXVAVideoDecodeAccelerator::CheckConfigChanged(
2605 IMFSample* sample, bool* config_changed) {
2606 if (codec_ != media::kCodecH264)
2607 return S_FALSE;
2608
2609 base::win::ScopedComPtr<IMFMediaBuffer> buffer;
2610 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive());
2611 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr);
2612
2613 MediaBufferScopedPointer scoped_media_buffer(buffer.get());
2614
2615 if (!config_change_detector_.DetectConfig(
2616 scoped_media_buffer.get(),
2617 scoped_media_buffer.current_length())) {
2618 RETURN_ON_HR_FAILURE(E_FAIL, "Failed to detect H.264 stream config",
2619 E_FAIL);
2620 }
2621 *config_changed = config_change_detector_.config_changed();
2622 return S_OK;
2623 }
2624
2625 void DXVAVideoDecodeAccelerator::ConfigChanged(
2626 const Config& config,
2627 const base::win::ScopedComPtr<IMFSample>& input_sample) {
2628 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2629 DismissStaleBuffers(true);
2630 Invalidate();
2631 Initialize(config_, client_);
2632 decoder_thread_task_runner_->PostTask(
2633 FROM_HERE,
2634 base::Bind(&DXVAVideoDecodeAccelerator::DecodeInternal,
2635 base::Unretained(this), input_sample));
2636 }
2637
2457 } // namespace content 2638 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698