| 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 "media/gpu/dxva_video_decode_accelerator_win.h" | 5 #include "media/gpu/dxva_video_decode_accelerator_win.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #if !defined(OS_WIN) | 9 #if !defined(OS_WIN) |
| 10 #error This file should only be built on Windows. | 10 #error This file should only be built on Windows. |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 config_changed_ = true; | 451 config_changed_ = true; |
| 452 } else { | 452 } else { |
| 453 pending_config_changed_ = true; | 453 pending_config_changed_ = true; |
| 454 } | 454 } |
| 455 } | 455 } |
| 456 last_pps_.swap(pps); | 456 last_pps_.swap(pps); |
| 457 } | 457 } |
| 458 return true; | 458 return true; |
| 459 } | 459 } |
| 460 | 460 |
| 461 gfx::ColorSpace H264ConfigChangeDetector::current_color_space() const { |
| 462 if (!parser_) |
| 463 return gfx::ColorSpace(); |
| 464 // TODO(hubbe): Is using last_sps_id_ correct here? |
| 465 const H264SPS* sps = parser_->GetSPS(last_sps_id_); |
| 466 if (sps) |
| 467 return sps->GetColorSpace(); |
| 468 return gfx::ColorSpace(); |
| 469 } |
| 461 | 470 |
| 462 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( | 471 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( |
| 463 int32_t buffer_id, | 472 int32_t buffer_id, |
| 464 IMFSample* sample) | 473 IMFSample* sample, |
| 465 : input_buffer_id(buffer_id), picture_buffer_id(-1) { | 474 const gfx::ColorSpace& color_space) |
| 475 : input_buffer_id(buffer_id), |
| 476 picture_buffer_id(-1), |
| 477 color_space(color_space) { |
| 466 output_sample.Attach(sample); | 478 output_sample.Attach(sample); |
| 467 } | 479 } |
| 468 | 480 |
| 469 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( | 481 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( |
| 470 const PendingSampleInfo& other) = default; | 482 const PendingSampleInfo& other) = default; |
| 471 | 483 |
| 472 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} | 484 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} |
| 473 | 485 |
| 474 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( | 486 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( |
| 475 const GetGLContextCallback& get_gl_context_cb, | 487 const GetGLContextCallback& get_gl_context_cb, |
| (...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1592 DVLOG(1) << "Flags: " << std::hex << std::showbase | 1604 DVLOG(1) << "Flags: " << std::hex << std::showbase |
| 1593 << output_stream_info_.dwFlags; | 1605 << output_stream_info_.dwFlags; |
| 1594 if (codec_ == kCodecH264) { | 1606 if (codec_ == kCodecH264) { |
| 1595 CHECK_EQ(output_stream_info_.dwFlags, 0x107u); | 1607 CHECK_EQ(output_stream_info_.dwFlags, 0x107u); |
| 1596 } | 1608 } |
| 1597 DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize; | 1609 DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize; |
| 1598 DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment; | 1610 DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment; |
| 1599 return true; | 1611 return true; |
| 1600 } | 1612 } |
| 1601 | 1613 |
| 1602 void DXVAVideoDecodeAccelerator::DoDecode() { | 1614 void DXVAVideoDecodeAccelerator::DoDecode(const gfx::ColorSpace& color_space) { |
| 1603 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::DoDecode"); | 1615 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::DoDecode"); |
| 1604 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1616 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
| 1605 // This function is also called from FlushInternal in a loop which could | 1617 // This function is also called from FlushInternal in a loop which could |
| 1606 // result in the state transitioning to kStopped due to no decoded output. | 1618 // result in the state transitioning to kStopped due to no decoded output. |
| 1607 State state = GetState(); | 1619 State state = GetState(); |
| 1608 RETURN_AND_NOTIFY_ON_FAILURE( | 1620 RETURN_AND_NOTIFY_ON_FAILURE( |
| 1609 (state == kNormal || state == kFlushing || state == kStopped), | 1621 (state == kNormal || state == kFlushing || state == kStopped), |
| 1610 "DoDecode: not in normal/flushing/stopped state", ILLEGAL_STATE, ); | 1622 "DoDecode: not in normal/flushing/stopped state", ILLEGAL_STATE, ); |
| 1611 | 1623 |
| 1612 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; | 1624 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; |
| 1613 DWORD status = 0; | 1625 DWORD status = 0; |
| 1614 | |
| 1615 HRESULT hr = decoder_->ProcessOutput(0, // No flags | 1626 HRESULT hr = decoder_->ProcessOutput(0, // No flags |
| 1616 1, // # of out streams to pull from | 1627 1, // # of out streams to pull from |
| 1617 &output_data_buffer, &status); | 1628 &output_data_buffer, &status); |
| 1618 IMFCollection* events = output_data_buffer.pEvents; | 1629 IMFCollection* events = output_data_buffer.pEvents; |
| 1619 if (events != NULL) { | 1630 if (events != NULL) { |
| 1620 DVLOG(1) << "Got events from ProcessOuput, but discarding"; | 1631 DVLOG(1) << "Got events from ProcessOuput, but discarding"; |
| 1621 events->Release(); | 1632 events->Release(); |
| 1622 } | 1633 } |
| 1623 if (FAILED(hr)) { | 1634 if (FAILED(hr)) { |
| 1624 // A stream change needs further ProcessInput calls to get back decoder | 1635 // A stream change needs further ProcessInput calls to get back decoder |
| 1625 // output which is why we need to set the state to stopped. | 1636 // output which is why we need to set the state to stopped. |
| 1626 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { | 1637 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { |
| 1627 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) && | 1638 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) && |
| 1628 !SetDecoderOutputMediaType(MFVideoFormat_P010)) { | 1639 !SetDecoderOutputMediaType(MFVideoFormat_P010)) { |
| 1629 // Decoder didn't let us set NV12 output format. Not sure as to why | 1640 // Decoder didn't let us set NV12 output format. Not sure as to why |
| 1630 // this can happen. Give up in disgust. | 1641 // this can happen. Give up in disgust. |
| 1631 NOTREACHED() << "Failed to set decoder output media type to NV12"; | 1642 NOTREACHED() << "Failed to set decoder output media type to NV12"; |
| 1632 SetState(kStopped); | 1643 SetState(kStopped); |
| 1633 } else { | 1644 } else { |
| 1634 DVLOG(1) << "Received output format change from the decoder." | 1645 DVLOG(1) << "Received output format change from the decoder." |
| 1635 " Recursively invoking DoDecode"; | 1646 " Recursively invoking DoDecode"; |
| 1636 DoDecode(); | 1647 DoDecode(color_space); |
| 1637 } | 1648 } |
| 1638 return; | 1649 return; |
| 1639 } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { | 1650 } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { |
| 1640 // No more output from the decoder. Stop playback. | 1651 // No more output from the decoder. Stop playback. |
| 1641 SetState(kStopped); | 1652 SetState(kStopped); |
| 1642 return; | 1653 return; |
| 1643 } else { | 1654 } else { |
| 1644 NOTREACHED() << "Unhandled error in DoDecode()"; | 1655 NOTREACHED() << "Unhandled error in DoDecode()"; |
| 1645 return; | 1656 return; |
| 1646 } | 1657 } |
| 1647 } | 1658 } |
| 1648 TRACE_EVENT_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", this); | 1659 TRACE_EVENT_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", this); |
| 1649 | 1660 |
| 1650 TRACE_COUNTER1("DXVA Decoding", "TotalPacketsBeforeDecode", | 1661 TRACE_COUNTER1("DXVA Decoding", "TotalPacketsBeforeDecode", |
| 1651 inputs_before_decode_); | 1662 inputs_before_decode_); |
| 1652 | 1663 |
| 1653 inputs_before_decode_ = 0; | 1664 inputs_before_decode_ = 0; |
| 1654 | 1665 |
| 1655 RETURN_AND_NOTIFY_ON_FAILURE(ProcessOutputSample(output_data_buffer.pSample), | 1666 RETURN_AND_NOTIFY_ON_FAILURE( |
| 1656 "Failed to process output sample.", | 1667 ProcessOutputSample(output_data_buffer.pSample, color_space), |
| 1657 PLATFORM_FAILURE, ); | 1668 "Failed to process output sample.", PLATFORM_FAILURE, ); |
| 1658 } | 1669 } |
| 1659 | 1670 |
| 1660 bool DXVAVideoDecodeAccelerator::ProcessOutputSample(IMFSample* sample) { | 1671 bool DXVAVideoDecodeAccelerator::ProcessOutputSample( |
| 1672 IMFSample* sample, |
| 1673 const gfx::ColorSpace& color_space) { |
| 1661 RETURN_ON_FAILURE(sample, "Decode succeeded with NULL output sample", false); | 1674 RETURN_ON_FAILURE(sample, "Decode succeeded with NULL output sample", false); |
| 1662 | 1675 |
| 1663 LONGLONG input_buffer_id = 0; | 1676 LONGLONG input_buffer_id = 0; |
| 1664 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id), | 1677 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id), |
| 1665 "Failed to get input buffer id associated with sample", | 1678 "Failed to get input buffer id associated with sample", |
| 1666 false); | 1679 false); |
| 1667 | 1680 |
| 1668 { | 1681 { |
| 1669 base::AutoLock lock(decoder_lock_); | 1682 base::AutoLock lock(decoder_lock_); |
| 1670 DCHECK(pending_output_samples_.empty()); | 1683 DCHECK(pending_output_samples_.empty()); |
| 1671 pending_output_samples_.push_back( | 1684 pending_output_samples_.push_back( |
| 1672 PendingSampleInfo(input_buffer_id, sample)); | 1685 PendingSampleInfo(input_buffer_id, sample, color_space)); |
| 1673 } | 1686 } |
| 1674 | 1687 |
| 1675 if (pictures_requested_) { | 1688 if (pictures_requested_) { |
| 1676 DVLOG(1) << "Waiting for picture slots from the client."; | 1689 DVLOG(1) << "Waiting for picture slots from the client."; |
| 1677 main_thread_task_runner_->PostTask( | 1690 main_thread_task_runner_->PostTask( |
| 1678 FROM_HERE, | 1691 FROM_HERE, |
| 1679 base::Bind(&DXVAVideoDecodeAccelerator::ProcessPendingSamples, | 1692 base::Bind(&DXVAVideoDecodeAccelerator::ProcessPendingSamples, |
| 1680 weak_ptr_)); | 1693 weak_ptr_)); |
| 1681 return true; | 1694 return true; |
| 1682 } | 1695 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 } | 1746 } |
| 1734 | 1747 |
| 1735 if (width != index->second->size().width() || | 1748 if (width != index->second->size().width() || |
| 1736 height != index->second->size().height()) { | 1749 height != index->second->size().height()) { |
| 1737 HandleResolutionChanged(width, height); | 1750 HandleResolutionChanged(width, height); |
| 1738 return; | 1751 return; |
| 1739 } | 1752 } |
| 1740 | 1753 |
| 1741 pending_sample->picture_buffer_id = index->second->id(); | 1754 pending_sample->picture_buffer_id = index->second->id(); |
| 1742 index->second->set_bound(); | 1755 index->second->set_bound(); |
| 1756 index->second->set_color_space(pending_sample->color_space); |
| 1743 if (share_nv12_textures_) { | 1757 if (share_nv12_textures_) { |
| 1744 main_thread_task_runner_->PostTask( | 1758 main_thread_task_runner_->PostTask( |
| 1745 FROM_HERE, | 1759 FROM_HERE, |
| 1746 base::Bind(&DXVAVideoDecodeAccelerator::BindPictureBufferToSample, | 1760 base::Bind(&DXVAVideoDecodeAccelerator::BindPictureBufferToSample, |
| 1747 weak_ptr_, pending_sample->output_sample, | 1761 weak_ptr_, pending_sample->output_sample, |
| 1748 pending_sample->picture_buffer_id, | 1762 pending_sample->picture_buffer_id, |
| 1749 pending_sample->input_buffer_id)); | 1763 pending_sample->input_buffer_id)); |
| 1750 continue; | 1764 continue; |
| 1751 } | 1765 } |
| 1752 | 1766 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 // they need to be GL_TEXTURE_EXTERNAL_OES. | 1900 // they need to be GL_TEXTURE_EXTERNAL_OES. |
| 1887 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; | 1901 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; |
| 1888 client_->ProvidePictureBuffers( | 1902 client_->ProvidePictureBuffers( |
| 1889 kNumPictureBuffers, | 1903 kNumPictureBuffers, |
| 1890 provide_nv12_textures ? PIXEL_FORMAT_NV12 : PIXEL_FORMAT_UNKNOWN, | 1904 provide_nv12_textures ? PIXEL_FORMAT_NV12 : PIXEL_FORMAT_UNKNOWN, |
| 1891 provide_nv12_textures ? 2 : 1, gfx::Size(width, height), | 1905 provide_nv12_textures ? 2 : 1, gfx::Size(width, height), |
| 1892 provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D); | 1906 provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D); |
| 1893 } | 1907 } |
| 1894 } | 1908 } |
| 1895 | 1909 |
| 1896 void DXVAVideoDecodeAccelerator::NotifyPictureReady(int picture_buffer_id, | 1910 void DXVAVideoDecodeAccelerator::NotifyPictureReady( |
| 1897 int input_buffer_id) { | 1911 int picture_buffer_id, |
| 1912 int input_buffer_id, |
| 1913 const gfx::ColorSpace& color_space) { |
| 1898 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 1914 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 1899 // This task could execute after the decoder has been torn down. | 1915 // This task could execute after the decoder has been torn down. |
| 1900 if (GetState() != kUninitialized && client_) { | 1916 if (GetState() != kUninitialized && client_) { |
| 1901 // TODO(henryhsu): Use correct visible size instead of (0, 0). We can't use | 1917 // TODO(henryhsu): Use correct visible size instead of (0, 0). We can't use |
| 1902 // coded size here so use (0, 0) intentionally to have the client choose. | 1918 // coded size here so use (0, 0) intentionally to have the client choose. |
| 1903 Picture picture(picture_buffer_id, input_buffer_id, gfx::Rect(0, 0), false); | 1919 Picture picture(picture_buffer_id, input_buffer_id, gfx::Rect(0, 0), |
| 1920 color_space, false); |
| 1904 client_->PictureReady(picture); | 1921 client_->PictureReady(picture); |
| 1905 } | 1922 } |
| 1906 } | 1923 } |
| 1907 | 1924 |
| 1908 void DXVAVideoDecodeAccelerator::NotifyInputBuffersDropped() { | 1925 void DXVAVideoDecodeAccelerator::NotifyInputBuffersDropped() { |
| 1909 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 1926 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 1910 if (!client_) | 1927 if (!client_) |
| 1911 return; | 1928 return; |
| 1912 | 1929 |
| 1913 for (PendingInputs::iterator it = pending_input_buffers_.begin(); | 1930 for (PendingInputs::iterator it = pending_input_buffers_.begin(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1972 RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_DRAIN, 0), | 1989 RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_DRAIN, 0), |
| 1973 "Failed to send drain message", | 1990 "Failed to send drain message", |
| 1974 PLATFORM_FAILURE, ); | 1991 PLATFORM_FAILURE, ); |
| 1975 sent_drain_message_ = true; | 1992 sent_drain_message_ = true; |
| 1976 } | 1993 } |
| 1977 } | 1994 } |
| 1978 | 1995 |
| 1979 // Attempt to retrieve an output frame from the decoder. If we have one, | 1996 // Attempt to retrieve an output frame from the decoder. If we have one, |
| 1980 // return and proceed when the output frame is processed. If we don't have a | 1997 // return and proceed when the output frame is processed. If we don't have a |
| 1981 // frame then we are done. | 1998 // frame then we are done. |
| 1982 DoDecode(); | 1999 DoDecode(config_change_detector_->current_color_space()); |
| 1983 if (OutputSamplesPresent()) | 2000 if (OutputSamplesPresent()) |
| 1984 return; | 2001 return; |
| 1985 | 2002 |
| 1986 if (!processing_config_changed_) { | 2003 if (!processing_config_changed_) { |
| 1987 SetState(kFlushing); | 2004 SetState(kFlushing); |
| 1988 | 2005 |
| 1989 main_thread_task_runner_->PostTask( | 2006 main_thread_task_runner_->PostTask( |
| 1990 FROM_HERE, | 2007 FROM_HERE, |
| 1991 base::Bind(&DXVAVideoDecodeAccelerator::NotifyFlushDone, weak_ptr_)); | 2008 base::Bind(&DXVAVideoDecodeAccelerator::NotifyFlushDone, weak_ptr_)); |
| 1992 } else { | 2009 } else { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2021 PLATFORM_FAILURE, ); | 2038 PLATFORM_FAILURE, ); |
| 2022 | 2039 |
| 2023 processing_config_changed_ = config_changed; | 2040 processing_config_changed_ = config_changed; |
| 2024 | 2041 |
| 2025 if (config_changed) { | 2042 if (config_changed) { |
| 2026 pending_input_buffers_.push_back(sample); | 2043 pending_input_buffers_.push_back(sample); |
| 2027 FlushInternal(); | 2044 FlushInternal(); |
| 2028 return; | 2045 return; |
| 2029 } | 2046 } |
| 2030 | 2047 |
| 2048 gfx::ColorSpace color_space = config_change_detector_->current_color_space(); |
| 2049 |
| 2031 if (!inputs_before_decode_) { | 2050 if (!inputs_before_decode_) { |
| 2032 TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding", | 2051 TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding", |
| 2033 this); | 2052 this); |
| 2034 } | 2053 } |
| 2035 inputs_before_decode_++; | 2054 inputs_before_decode_++; |
| 2036 | 2055 |
| 2037 hr = decoder_->ProcessInput(0, sample.get(), 0); | 2056 hr = decoder_->ProcessInput(0, sample.get(), 0); |
| 2038 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it | 2057 // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it |
| 2039 // has enough data to produce one or more output samples. In this case the | 2058 // has enough data to produce one or more output samples. In this case the |
| 2040 // recommended options are to | 2059 // recommended options are to |
| 2041 // 1. Generate new output by calling IMFTransform::ProcessOutput until it | 2060 // 1. Generate new output by calling IMFTransform::ProcessOutput until it |
| 2042 // returns MF_E_TRANSFORM_NEED_MORE_INPUT. | 2061 // returns MF_E_TRANSFORM_NEED_MORE_INPUT. |
| 2043 // 2. Flush the input data | 2062 // 2. Flush the input data |
| 2044 // We implement the first option, i.e to retrieve the output sample and then | 2063 // We implement the first option, i.e to retrieve the output sample and then |
| 2045 // process the input again. Failure in either of these steps is treated as a | 2064 // process the input again. Failure in either of these steps is treated as a |
| 2046 // decoder failure. | 2065 // decoder failure. |
| 2047 if (hr == MF_E_NOTACCEPTING) { | 2066 if (hr == MF_E_NOTACCEPTING) { |
| 2048 DoDecode(); | 2067 DoDecode(color_space); |
| 2049 // If the DoDecode call resulted in an output frame then we should not | 2068 // If the DoDecode call resulted in an output frame then we should not |
| 2050 // process any more input until that frame is copied to the target surface. | 2069 // process any more input until that frame is copied to the target surface. |
| 2051 if (!OutputSamplesPresent()) { | 2070 if (!OutputSamplesPresent()) { |
| 2052 State state = GetState(); | 2071 State state = GetState(); |
| 2053 RETURN_AND_NOTIFY_ON_FAILURE( | 2072 RETURN_AND_NOTIFY_ON_FAILURE( |
| 2054 (state == kStopped || state == kNormal || state == kFlushing), | 2073 (state == kStopped || state == kNormal || state == kFlushing), |
| 2055 "Failed to process output. Unexpected decoder state: " << state, | 2074 "Failed to process output. Unexpected decoder state: " << state, |
| 2056 PLATFORM_FAILURE, ); | 2075 PLATFORM_FAILURE, ); |
| 2057 hr = decoder_->ProcessInput(0, sample.get(), 0); | 2076 hr = decoder_->ProcessInput(0, sample.get(), 0); |
| 2058 } | 2077 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2070 decoder_thread_task_runner_->PostTask( | 2089 decoder_thread_task_runner_->PostTask( |
| 2071 FROM_HERE, | 2090 FROM_HERE, |
| 2072 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2091 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
| 2073 base::Unretained(this))); | 2092 base::Unretained(this))); |
| 2074 return; | 2093 return; |
| 2075 } | 2094 } |
| 2076 } | 2095 } |
| 2077 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to process input sample", | 2096 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to process input sample", |
| 2078 PLATFORM_FAILURE, ); | 2097 PLATFORM_FAILURE, ); |
| 2079 | 2098 |
| 2080 DoDecode(); | 2099 DoDecode(color_space); |
| 2081 | 2100 |
| 2082 State state = GetState(); | 2101 State state = GetState(); |
| 2083 RETURN_AND_NOTIFY_ON_FAILURE( | 2102 RETURN_AND_NOTIFY_ON_FAILURE( |
| 2084 (state == kStopped || state == kNormal || state == kFlushing), | 2103 (state == kStopped || state == kNormal || state == kFlushing), |
| 2085 "Failed to process output. Unexpected decoder state: " << state, | 2104 "Failed to process output. Unexpected decoder state: " << state, |
| 2086 ILLEGAL_STATE, ); | 2105 ILLEGAL_STATE, ); |
| 2087 | 2106 |
| 2088 LONGLONG input_buffer_id = 0; | 2107 LONGLONG input_buffer_id = 0; |
| 2089 RETURN_ON_HR_FAILURE( | 2108 RETURN_ON_HR_FAILURE( |
| 2090 sample->GetSampleTime(&input_buffer_id), | 2109 sample->GetSampleTime(&input_buffer_id), |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2250 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), | 2269 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), |
| 2251 "Failed to make context current", | 2270 "Failed to make context current", |
| 2252 PLATFORM_FAILURE, ); | 2271 PLATFORM_FAILURE, ); |
| 2253 | 2272 |
| 2254 DCHECK(!output_picture_buffers_.empty()); | 2273 DCHECK(!output_picture_buffers_.empty()); |
| 2255 | 2274 |
| 2256 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface); | 2275 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface); |
| 2257 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", | 2276 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", |
| 2258 PLATFORM_FAILURE, ); | 2277 PLATFORM_FAILURE, ); |
| 2259 | 2278 |
| 2260 NotifyPictureReady(picture_buffer->id(), input_buffer_id); | 2279 NotifyPictureReady(picture_buffer->id(), input_buffer_id, gfx::ColorSpace()); |
| 2261 | 2280 |
| 2262 { | 2281 { |
| 2263 base::AutoLock lock(decoder_lock_); | 2282 base::AutoLock lock(decoder_lock_); |
| 2264 if (!pending_output_samples_.empty()) | 2283 if (!pending_output_samples_.empty()) |
| 2265 pending_output_samples_.pop_front(); | 2284 pending_output_samples_.pop_front(); |
| 2266 } | 2285 } |
| 2267 | 2286 |
| 2268 if (pending_flush_ || processing_config_changed_) { | 2287 if (pending_flush_ || processing_config_changed_) { |
| 2269 decoder_thread_task_runner_->PostTask( | 2288 decoder_thread_task_runner_->PostTask( |
| 2270 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, | 2289 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2302 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), | 2321 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), |
| 2303 "Failed to make context current", | 2322 "Failed to make context current", |
| 2304 PLATFORM_FAILURE, ); | 2323 PLATFORM_FAILURE, ); |
| 2305 | 2324 |
| 2306 DCHECK(!output_picture_buffers_.empty()); | 2325 DCHECK(!output_picture_buffers_.empty()); |
| 2307 | 2326 |
| 2308 bool result = picture_buffer->BindSampleToTexture(sample); | 2327 bool result = picture_buffer->BindSampleToTexture(sample); |
| 2309 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", | 2328 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", |
| 2310 PLATFORM_FAILURE, ); | 2329 PLATFORM_FAILURE, ); |
| 2311 | 2330 |
| 2312 NotifyPictureReady(picture_buffer->id(), input_buffer_id); | 2331 NotifyPictureReady(picture_buffer->id(), input_buffer_id, |
| 2332 picture_buffer->color_space()); |
| 2313 | 2333 |
| 2314 { | 2334 { |
| 2315 base::AutoLock lock(decoder_lock_); | 2335 base::AutoLock lock(decoder_lock_); |
| 2316 if (!pending_output_samples_.empty()) | 2336 if (!pending_output_samples_.empty()) |
| 2317 pending_output_samples_.pop_front(); | 2337 pending_output_samples_.pop_front(); |
| 2318 } | 2338 } |
| 2319 | 2339 |
| 2320 if (pending_flush_ || processing_config_changed_) { | 2340 if (pending_flush_ || processing_config_changed_) { |
| 2321 decoder_thread_task_runner_->PostTask( | 2341 decoder_thread_task_runner_->PostTask( |
| 2322 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, | 2342 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2689 SetState(kConfigChange); | 2709 SetState(kConfigChange); |
| 2690 Invalidate(); | 2710 Invalidate(); |
| 2691 Initialize(config_, client_); | 2711 Initialize(config_, client_); |
| 2692 decoder_thread_task_runner_->PostTask( | 2712 decoder_thread_task_runner_->PostTask( |
| 2693 FROM_HERE, | 2713 FROM_HERE, |
| 2694 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2714 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
| 2695 base::Unretained(this))); | 2715 base::Unretained(this))); |
| 2696 } | 2716 } |
| 2697 | 2717 |
| 2698 } // namespace media | 2718 } // namespace media |
| OLD | NEW |