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

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

Issue 1842523002: Fix the H.264 config detection code which lead to video playback errors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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"
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
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
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
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
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
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