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

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: Flag a pending configuration change if we detect a change in SPS/PPS and return config changed the … 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 pending_config_changed_(false) {
375 }
376
377 H264ConfigChangeDetector::~H264ConfigChangeDetector() {
378 }
379
380 bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream,
381 unsigned int size) {
382 std::vector<uint8_t> sps;
383 std::vector<uint8_t> pps;
384 media::H264NALU nalu;
385 bool idr_seen = false;
386
387 media::H264Parser parser;
388 parser.SetStream(stream, size);
389 config_changed_ = false;
390
391 while (true) {
392 media::H264Parser::Result result = parser.AdvanceToNextNALU(&nalu);
393
394 if (result == media::H264Parser::kEOStream)
395 break;
396
397 if (result == media::H264Parser::kUnsupportedStream) {
398 DLOG(ERROR) << "Unsupported H.264 stream";
399 return false;
400 }
401
402 if (result != media::H264Parser::kOk) {
403 DLOG(ERROR) << "Failed to parse H.264 stream";
404 return false;
405 }
406
407 switch (nalu.nal_unit_type) {
408 case media::H264NALU::kSPS:
409 result = parser.ParseSPS(&last_sps_id_);
410 if (result == media::H264Parser::kUnsupportedStream) {
411 DLOG(ERROR) << "Unsupported SPS";
412 return false;
413 }
414
415 if (result != media::H264Parser::kOk) {
416 DLOG(ERROR) << "Could not parse SPS";
417 return false;
418 }
419
420 sps.assign(nalu.data, nalu.data + nalu.size);
421 break;
422
423 case media::H264NALU::kPPS:
424 result = parser.ParsePPS(&last_pps_id_);
425 if (result == media::H264Parser::kUnsupportedStream) {
426 DLOG(ERROR) << "Unsupported PPS";
427 return false;
428 }
429 if (result != media::H264Parser::kOk) {
430 DLOG(ERROR) << "Could not parse PPS";
431 return false;
432 }
433 pps.assign(nalu.data, nalu.data + nalu.size);
434 break;
435
436 case media::H264NALU::kIDRSlice:
437 idr_seen = true;
438 // If we previously detected a configuration change, and see an IDR
439 // slice next time around, we need to flag a configuration change.
440 if (pending_config_changed_) {
441 config_changed_ = true;
442 pending_config_changed_ = false;
443 }
444 break;
445
446 default:
447 break;
448 }
449 }
450
451 if (!sps.empty() && sps != last_sps_) {
452 if (!last_sps_.empty()) {
453 // Flag configuration changes after we see an IDR slice.
454 if (idr_seen) {
455 config_changed_ = true;
456 } else {
457 pending_config_changed_ = true;
458 }
459 }
460 last_sps_.swap(sps);
461 }
462
463 if (!pps.empty() && pps != last_pps_) {
464 if (!last_pps_.empty()) {
465 // Flag configuration changes after we see an IDR slice.
466 if (idr_seen) {
467 config_changed_ = true;
468 } else {
469 pending_config_changed_ = true;
470 }
471 }
472 last_pps_.swap(pps);
473 }
474 return true;
475 }
334 476
335 // Maintains information about a DXVA picture buffer, i.e. whether it is 477 // Maintains information about a DXVA picture buffer, i.e. whether it is
336 // available for rendering, the texture information, etc. 478 // available for rendering, the texture information, etc.
337 struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer { 479 struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
338 public: 480 public:
339 static linked_ptr<DXVAPictureBuffer> Create( 481 static linked_ptr<DXVAPictureBuffer> Create(
340 const DXVAVideoDecodeAccelerator& decoder, 482 const DXVAVideoDecodeAccelerator& decoder,
341 const media::PictureBuffer& buffer, 483 const media::PictureBuffer& buffer,
342 EGLConfig egl_config); 484 EGLConfig egl_config);
343 ~DXVAPictureBuffer(); 485 ~DXVAPictureBuffer();
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 RETURN_AND_NOTIFY_ON_FAILURE( 923 RETURN_AND_NOTIFY_ON_FAILURE(
782 SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0), 924 SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0),
783 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed", 925 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed",
784 PLATFORM_FAILURE, false); 926 PLATFORM_FAILURE, false);
785 927
786 RETURN_AND_NOTIFY_ON_FAILURE( 928 RETURN_AND_NOTIFY_ON_FAILURE(
787 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0), 929 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0),
788 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed", 930 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed",
789 PLATFORM_FAILURE, false); 931 PLATFORM_FAILURE, false);
790 932
933 config_ = config;
934
791 SetState(kNormal); 935 SetState(kNormal);
792 936
793 StartDecoderThread(); 937 StartDecoderThread();
794 return true; 938 return true;
795 } 939 }
796 940
797 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { 941 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() {
798 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager"); 942 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager");
799 943
800 HRESULT hr = E_FAIL; 944 HRESULT hr = E_FAIL;
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 return; 1177 return;
1034 1178
1035 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); 1179 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 1180 // 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 1181 // 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 1182 // 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 1183 // 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 1184 // us that we can now recycle this picture buffer, so if we were waiting to
1041 // dispose of it we now can. 1185 // dispose of it we now can.
1042 if (it == output_picture_buffers_.end()) { 1186 if (it == output_picture_buffers_.end()) {
1043 it = stale_output_picture_buffers_.find(picture_buffer_id); 1187 if (!stale_output_picture_buffers_.empty()) {
1044 RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(), 1188 it = stale_output_picture_buffers_.find(picture_buffer_id);
1045 "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,); 1189 RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(),
1046 main_thread_task_runner_->PostTask( 1190 "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,);
1047 FROM_HERE, 1191 main_thread_task_runner_->PostTask(
1048 base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer, 1192 FROM_HERE,
1049 weak_this_factory_.GetWeakPtr(), picture_buffer_id)); 1193 base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer,
1194 weak_this_factory_.GetWeakPtr(), picture_buffer_id));
1195 }
1050 return; 1196 return;
1051 } 1197 }
1052 1198
1053 if (it->second->available() || it->second->waiting_to_reuse()) 1199 if (it->second->available() || it->second->waiting_to_reuse())
1054 return; 1200 return;
1055 1201
1056 if (use_keyed_mutex_ || using_angle_device_) { 1202 if (use_keyed_mutex_ || using_angle_device_) {
1057 RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(), 1203 RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(),
1058 "Failed to reuse picture buffer", 1204 "Failed to reuse picture buffer",
1059 PLATFORM_FAILURE, ); 1205 PLATFORM_FAILURE, );
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 if (GetState() == kUninitialized) 1818 if (GetState() == kUninitialized)
1673 return; 1819 return;
1674 1820
1675 decoder_thread_.Stop(); 1821 decoder_thread_.Stop();
1676 weak_this_factory_.InvalidateWeakPtrs(); 1822 weak_this_factory_.InvalidateWeakPtrs();
1677 output_picture_buffers_.clear(); 1823 output_picture_buffers_.clear();
1678 stale_output_picture_buffers_.clear(); 1824 stale_output_picture_buffers_.clear();
1679 pending_output_samples_.clear(); 1825 pending_output_samples_.clear();
1680 pending_input_buffers_.clear(); 1826 pending_input_buffers_.clear();
1681 decoder_.Release(); 1827 decoder_.Release();
1828 pictures_requested_ = false;
1682 1829
1683 if (use_dx11_) { 1830 if (use_dx11_) {
1684 if (video_format_converter_mft_.get()) { 1831 if (video_format_converter_mft_.get()) {
1685 video_format_converter_mft_->ProcessMessage( 1832 video_format_converter_mft_->ProcessMessage(
1686 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); 1833 MFT_MESSAGE_NOTIFY_END_STREAMING, 0);
1687 video_format_converter_mft_.Release(); 1834 video_format_converter_mft_.Release();
1688 } 1835 }
1689 d3d11_device_context_.Release(); 1836 d3d11_device_context_.Release();
1690 d3d11_device_.Release(); 1837 d3d11_device_.Release();
1691 d3d11_device_manager_.Release(); 1838 d3d11_device_manager_.Release();
1692 d3d11_query_.Release(); 1839 d3d11_query_.Release();
1693 dx11_video_format_converter_media_type_needs_init_ = true; 1840 dx11_video_format_converter_media_type_needs_init_ = true;
1841 multi_threaded_.Release();
1694 } else { 1842 } else {
1695 d3d9_.Release(); 1843 d3d9_.Release();
1696 d3d9_device_ex_.Release(); 1844 d3d9_device_ex_.Release();
1697 device_manager_.Release(); 1845 device_manager_.Release();
1698 query_.Release(); 1846 query_.Release();
1699 } 1847 }
1700 1848
1701 SetState(kUninitialized); 1849 SetState(kUninitialized);
1702 } 1850 }
1703 1851
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 1986 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
1839 1987
1840 if (GetState() == kUninitialized) 1988 if (GetState() == kUninitialized)
1841 return; 1989 return;
1842 1990
1843 if (OutputSamplesPresent() || !pending_input_buffers_.empty()) { 1991 if (OutputSamplesPresent() || !pending_input_buffers_.empty()) {
1844 pending_input_buffers_.push_back(sample); 1992 pending_input_buffers_.push_back(sample);
1845 return; 1993 return;
1846 } 1994 }
1847 1995
1996 // Check if the resolution, bit rate, etc changed in the stream. If yes we
1997 // reinitialize the decoder to ensure that the stream decodes correctly.
1998 bool config_changed = false;
1999
2000 HRESULT hr = CheckConfigChanged(sample.get(), &config_changed);
2001 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to check video stream config",
2002 PLATFORM_FAILURE,);
2003
2004 if (config_changed) {
2005 main_thread_task_runner_->PostTask(
2006 FROM_HERE,
2007 base::Bind(&DXVAVideoDecodeAccelerator::ConfigChanged,
2008 weak_this_factory_.GetWeakPtr(),
2009 config_,
2010 sample));
2011 return;
2012 }
2013
1848 if (!inputs_before_decode_) { 2014 if (!inputs_before_decode_) {
1849 TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding", 2015 TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding",
1850 this); 2016 this);
1851 } 2017 }
1852 inputs_before_decode_++; 2018 inputs_before_decode_++;
1853 2019
1854 HRESULT hr = decoder_->ProcessInput(0, sample.get(), 0); 2020 hr = decoder_->ProcessInput(0, sample.get(), 0);
1855 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it 2021 // 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 2022 // has enough data to produce one or more output samples. In this case the
1857 // recommended options are to 2023 // recommended options are to
1858 // 1. Generate new output by calling IMFTransform::ProcessOutput until it 2024 // 1. Generate new output by calling IMFTransform::ProcessOutput until it
1859 // returns MF_E_TRANSFORM_NEED_MORE_INPUT. 2025 // returns MF_E_TRANSFORM_NEED_MORE_INPUT.
1860 // 2. Flush the input data 2026 // 2. Flush the input data
1861 // We implement the first option, i.e to retrieve the output sample and then 2027 // 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 2028 // process the input again. Failure in either of these steps is treated as a
1863 // decoder failure. 2029 // decoder failure.
1864 if (hr == MF_E_NOTACCEPTING) { 2030 if (hr == MF_E_NOTACCEPTING) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 input_buffer_id)); 2088 input_buffer_id));
1923 } 2089 }
1924 2090
1925 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width, 2091 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width,
1926 int height) { 2092 int height) {
1927 dx11_video_format_converter_media_type_needs_init_ = true; 2093 dx11_video_format_converter_media_type_needs_init_ = true;
1928 2094
1929 main_thread_task_runner_->PostTask( 2095 main_thread_task_runner_->PostTask(
1930 FROM_HERE, 2096 FROM_HERE,
1931 base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers, 2097 base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers,
1932 weak_this_factory_.GetWeakPtr())); 2098 weak_this_factory_.GetWeakPtr(), false));
1933 2099
1934 main_thread_task_runner_->PostTask( 2100 main_thread_task_runner_->PostTask(
1935 FROM_HERE, 2101 FROM_HERE,
1936 base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers, 2102 base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
1937 weak_this_factory_.GetWeakPtr(), 2103 weak_this_factory_.GetWeakPtr(),
1938 width, 2104 width,
1939 height)); 2105 height));
1940 } 2106 }
1941 2107
1942 void DXVAVideoDecodeAccelerator::DismissStaleBuffers() { 2108 void DXVAVideoDecodeAccelerator::DismissStaleBuffers(bool force) {
1943 OutputBuffers::iterator index; 2109 OutputBuffers::iterator index;
1944 2110
1945 for (index = output_picture_buffers_.begin(); 2111 for (index = output_picture_buffers_.begin();
1946 index != output_picture_buffers_.end(); 2112 index != output_picture_buffers_.end();
1947 ++index) { 2113 ++index) {
1948 if (index->second->available()) { 2114 if (force || index->second->available()) {
1949 DVLOG(1) << "Dismissing picture id: " << index->second->id(); 2115 DVLOG(1) << "Dismissing picture id: " << index->second->id();
1950 client_->DismissPictureBuffer(index->second->id()); 2116 client_->DismissPictureBuffer(index->second->id());
1951 } else { 2117 } else {
1952 // Move to |stale_output_picture_buffers_| for deferred deletion. 2118 // Move to |stale_output_picture_buffers_| for deferred deletion.
1953 stale_output_picture_buffers_.insert( 2119 stale_output_picture_buffers_.insert(
1954 std::make_pair(index->first, index->second)); 2120 std::make_pair(index->first, index->second));
1955 } 2121 }
1956 } 2122 }
1957 2123
1958 output_picture_buffers_.clear(); 2124 output_picture_buffers_.clear();
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
2447 } 2613 }
2448 hr = transform->SetOutputType(0, media_type.get(), 0); // No flags 2614 hr = transform->SetOutputType(0, media_type.get(), 0); // No flags
2449 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); 2615 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false);
2450 return true; 2616 return true;
2451 } 2617 }
2452 media_type.Release(); 2618 media_type.Release();
2453 } 2619 }
2454 return false; 2620 return false;
2455 } 2621 }
2456 2622
2623 HRESULT DXVAVideoDecodeAccelerator::CheckConfigChanged(
2624 IMFSample* sample, bool* config_changed) {
2625 if (codec_ != media::kCodecH264)
2626 return S_FALSE;
2627
2628 base::win::ScopedComPtr<IMFMediaBuffer> buffer;
2629 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive());
2630 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr);
2631
2632 MediaBufferScopedPointer scoped_media_buffer(buffer.get());
2633
2634 if (!config_change_detector_.DetectConfig(
2635 scoped_media_buffer.get(),
2636 scoped_media_buffer.current_length())) {
2637 RETURN_ON_HR_FAILURE(E_FAIL, "Failed to detect H.264 stream config",
2638 E_FAIL);
2639 }
2640 *config_changed = config_change_detector_.config_changed();
2641 return S_OK;
2642 }
2643
2644 void DXVAVideoDecodeAccelerator::ConfigChanged(
2645 const Config& config,
2646 const base::win::ScopedComPtr<IMFSample>& input_sample) {
2647 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2648 DismissStaleBuffers(true);
2649 Invalidate();
2650 Initialize(config_, client_);
2651 decoder_thread_task_runner_->PostTask(
2652 FROM_HERE,
2653 base::Bind(&DXVAVideoDecodeAccelerator::DecodeInternal,
2654 base::Unretained(this), input_sample));
2655 }
2656
2457 } // namespace content 2657 } // 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