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_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 Loading... |
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" | |
38 #include "media/video/video_decode_accelerator.h" | 37 #include "media/video/video_decode_accelerator.h" |
39 #include "third_party/angle/include/EGL/egl.h" | 38 #include "third_party/angle/include/EGL/egl.h" |
40 #include "third_party/angle/include/EGL/eglext.h" | 39 #include "third_party/angle/include/EGL/eglext.h" |
41 #include "ui/gl/gl_bindings.h" | 40 #include "ui/gl/gl_bindings.h" |
42 #include "ui/gl/gl_context.h" | 41 #include "ui/gl/gl_context.h" |
43 #include "ui/gl/gl_fence.h" | 42 #include "ui/gl/gl_fence.h" |
44 #include "ui/gl/gl_surface_egl.h" | 43 #include "ui/gl/gl_surface_egl.h" |
45 | 44 |
46 namespace { | 45 namespace { |
47 | 46 |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 H264ConfigChangeDetector::~H264ConfigChangeDetector() { | 376 H264ConfigChangeDetector::~H264ConfigChangeDetector() { |
378 } | 377 } |
379 | 378 |
380 bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream, | 379 bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream, |
381 unsigned int size) { | 380 unsigned int size) { |
382 std::vector<uint8_t> sps; | 381 std::vector<uint8_t> sps; |
383 std::vector<uint8_t> pps; | 382 std::vector<uint8_t> pps; |
384 media::H264NALU nalu; | 383 media::H264NALU nalu; |
385 bool idr_seen = false; | 384 bool idr_seen = false; |
386 | 385 |
387 media::H264Parser parser; | 386 if (!parser_.get()) |
388 parser.SetStream(stream, size); | 387 parser_.reset(new media::H264Parser); |
| 388 |
| 389 parser_->SetStream(stream, size); |
389 config_changed_ = false; | 390 config_changed_ = false; |
390 | 391 |
391 while (true) { | 392 while (true) { |
392 media::H264Parser::Result result = parser.AdvanceToNextNALU(&nalu); | 393 media::H264Parser::Result result = parser_->AdvanceToNextNALU(&nalu); |
393 | 394 |
394 if (result == media::H264Parser::kEOStream) | 395 if (result == media::H264Parser::kEOStream) |
395 break; | 396 break; |
396 | 397 |
397 if (result == media::H264Parser::kUnsupportedStream) { | 398 if (result == media::H264Parser::kUnsupportedStream) { |
398 DLOG(ERROR) << "Unsupported H.264 stream"; | 399 DLOG(ERROR) << "Unsupported H.264 stream"; |
399 return false; | 400 return false; |
400 } | 401 } |
401 | 402 |
402 if (result != media::H264Parser::kOk) { | 403 if (result != media::H264Parser::kOk) { |
403 DLOG(ERROR) << "Failed to parse H.264 stream"; | 404 DLOG(ERROR) << "Failed to parse H.264 stream"; |
404 return false; | 405 return false; |
405 } | 406 } |
406 | 407 |
407 switch (nalu.nal_unit_type) { | 408 switch (nalu.nal_unit_type) { |
408 case media::H264NALU::kSPS: | 409 case media::H264NALU::kSPS: |
409 result = parser.ParseSPS(&last_sps_id_); | 410 result = parser_->ParseSPS(&last_sps_id_); |
410 if (result == media::H264Parser::kUnsupportedStream) { | 411 if (result == media::H264Parser::kUnsupportedStream) { |
411 DLOG(ERROR) << "Unsupported SPS"; | 412 DLOG(ERROR) << "Unsupported SPS"; |
412 return false; | 413 return false; |
413 } | 414 } |
414 | 415 |
415 if (result != media::H264Parser::kOk) { | 416 if (result != media::H264Parser::kOk) { |
416 DLOG(ERROR) << "Could not parse SPS"; | 417 DLOG(ERROR) << "Could not parse SPS"; |
417 return false; | 418 return false; |
418 } | 419 } |
419 | 420 |
420 sps.assign(nalu.data, nalu.data + nalu.size); | 421 sps.assign(nalu.data, nalu.data + nalu.size); |
421 break; | 422 break; |
422 | 423 |
423 case media::H264NALU::kPPS: | 424 case media::H264NALU::kPPS: |
424 result = parser.ParsePPS(&last_pps_id_); | 425 result = parser_->ParsePPS(&last_pps_id_); |
425 if (result == media::H264Parser::kUnsupportedStream) { | 426 if (result == media::H264Parser::kUnsupportedStream) { |
426 DLOG(ERROR) << "Unsupported PPS"; | 427 DLOG(ERROR) << "Unsupported PPS"; |
427 return false; | 428 return false; |
428 } | 429 } |
429 if (result != media::H264Parser::kOk) { | 430 if (result != media::H264Parser::kOk) { |
430 DLOG(ERROR) << "Could not parse PPS"; | 431 DLOG(ERROR) << "Could not parse PPS"; |
431 return false; | 432 return false; |
432 } | 433 } |
433 pps.assign(nalu.data, nalu.data + nalu.size); | 434 pps.assign(nalu.data, nalu.data + nalu.size); |
434 break; | 435 break; |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed", | 926 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed", |
926 PLATFORM_FAILURE, false); | 927 PLATFORM_FAILURE, false); |
927 | 928 |
928 RETURN_AND_NOTIFY_ON_FAILURE( | 929 RETURN_AND_NOTIFY_ON_FAILURE( |
929 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0), | 930 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0), |
930 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed", | 931 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed", |
931 PLATFORM_FAILURE, false); | 932 PLATFORM_FAILURE, false); |
932 | 933 |
933 config_ = config; | 934 config_ = config; |
934 | 935 |
| 936 config_change_detector_.reset(new H264ConfigChangeDetector); |
| 937 |
935 SetState(kNormal); | 938 SetState(kNormal); |
936 | 939 |
937 StartDecoderThread(); | 940 StartDecoderThread(); |
938 return true; | 941 return true; |
939 } | 942 } |
940 | 943 |
941 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { | 944 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { |
942 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager"); | 945 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager"); |
943 | 946 |
944 HRESULT hr = E_FAIL; | 947 HRESULT hr = E_FAIL; |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1823 output_picture_buffers_.clear(); | 1826 output_picture_buffers_.clear(); |
1824 stale_output_picture_buffers_.clear(); | 1827 stale_output_picture_buffers_.clear(); |
1825 pending_output_samples_.clear(); | 1828 pending_output_samples_.clear(); |
1826 // We want to continue processing pending input after detecting a config | 1829 // We want to continue processing pending input after detecting a config |
1827 // change. | 1830 // change. |
1828 if (GetState() != kConfigChange) | 1831 if (GetState() != kConfigChange) |
1829 pending_input_buffers_.clear(); | 1832 pending_input_buffers_.clear(); |
1830 decoder_.Release(); | 1833 decoder_.Release(); |
1831 pictures_requested_ = false; | 1834 pictures_requested_ = false; |
1832 | 1835 |
| 1836 config_change_detector_.reset(); |
| 1837 |
1833 if (use_dx11_) { | 1838 if (use_dx11_) { |
1834 if (video_format_converter_mft_.get()) { | 1839 if (video_format_converter_mft_.get()) { |
1835 video_format_converter_mft_->ProcessMessage( | 1840 video_format_converter_mft_->ProcessMessage( |
1836 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); | 1841 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); |
1837 video_format_converter_mft_.Release(); | 1842 video_format_converter_mft_.Release(); |
1838 } | 1843 } |
1839 d3d11_device_context_.Release(); | 1844 d3d11_device_context_.Release(); |
1840 d3d11_device_.Release(); | 1845 d3d11_device_.Release(); |
1841 d3d11_device_manager_.Release(); | 1846 d3d11_device_manager_.Release(); |
1842 d3d11_query_.Release(); | 1847 d3d11_query_.Release(); |
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2627 IMFSample* sample, bool* config_changed) { | 2632 IMFSample* sample, bool* config_changed) { |
2628 if (codec_ != media::kCodecH264) | 2633 if (codec_ != media::kCodecH264) |
2629 return S_FALSE; | 2634 return S_FALSE; |
2630 | 2635 |
2631 base::win::ScopedComPtr<IMFMediaBuffer> buffer; | 2636 base::win::ScopedComPtr<IMFMediaBuffer> buffer; |
2632 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); | 2637 HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive()); |
2633 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr); | 2638 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr); |
2634 | 2639 |
2635 MediaBufferScopedPointer scoped_media_buffer(buffer.get()); | 2640 MediaBufferScopedPointer scoped_media_buffer(buffer.get()); |
2636 | 2641 |
2637 if (!config_change_detector_.DetectConfig( | 2642 if (!config_change_detector_->DetectConfig( |
2638 scoped_media_buffer.get(), | 2643 scoped_media_buffer.get(), |
2639 scoped_media_buffer.current_length())) { | 2644 scoped_media_buffer.current_length())) { |
2640 RETURN_ON_HR_FAILURE(E_FAIL, "Failed to detect H.264 stream config", | 2645 RETURN_ON_HR_FAILURE(E_FAIL, "Failed to detect H.264 stream config", |
2641 E_FAIL); | 2646 E_FAIL); |
2642 } | 2647 } |
2643 *config_changed = config_change_detector_.config_changed(); | 2648 *config_changed = config_change_detector_->config_changed(); |
2644 return S_OK; | 2649 return S_OK; |
2645 } | 2650 } |
2646 | 2651 |
2647 void DXVAVideoDecodeAccelerator::ConfigChanged( | 2652 void DXVAVideoDecodeAccelerator::ConfigChanged( |
2648 const Config& config) { | 2653 const Config& config) { |
2649 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 2654 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
2650 SetState(kConfigChange); | 2655 SetState(kConfigChange); |
2651 DismissStaleBuffers(true); | 2656 DismissStaleBuffers(true); |
2652 Invalidate(); | 2657 Invalidate(); |
2653 Initialize(config_, client_); | 2658 Initialize(config_, client_); |
2654 decoder_thread_task_runner_->PostTask( | 2659 decoder_thread_task_runner_->PostTask( |
2655 FROM_HERE, | 2660 FROM_HERE, |
2656 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2661 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
2657 base::Unretained(this))); | 2662 base::Unretained(this))); |
2658 } | 2663 } |
2659 | 2664 |
2660 } // namespace content | 2665 } // namespace content |
OLD | NEW |