示例#1
0
HRESULT
WMFReader::CreateSourceReader()
{
  HRESULT hr;

  RefPtr<IMFAttributes> attr;
  hr = wmf::MFCreateAttributes(byRef(attr), 1);
  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);

  hr = attr->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, mSourceReaderCallback);
  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);

  if (mUseHwAccel) {
    hr = attr->SetUnknown(MF_SOURCE_READER_D3D_MANAGER,
                          mDXVA2Manager->GetDXVADeviceManager());
    if (FAILED(hr)) {
      DECODER_LOG("Failed to set DXVA2 D3D Device manager on source reader attributes");
      mUseHwAccel = false;
    }
  }

  hr = wmf::MFCreateSourceReaderFromByteStream(mByteStream, attr, byRef(mSourceReader));
  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);

  hr = ConfigureVideoDecoder();
  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);

  hr = ConfigureAudioDecoder();
  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);

  if (mUseHwAccel && mInfo.HasVideo()) {
    RefPtr<IMFTransform> videoDecoder;
    hr = mSourceReader->GetServiceForStream(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
                                            GUID_NULL,
                                            IID_IMFTransform,
                                            (void**)(IMFTransform**)(byRef(videoDecoder)));

    if (SUCCEEDED(hr)) {
      ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager());
      hr = videoDecoder->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER,
                                        manager);
      if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
        // Ignore MF_E_TRANSFORM_TYPE_NOT_SET. Vista returns this here
        // on some, perhaps all, video cards. This may be because activating
        // DXVA changes the available output types. It seems to be safe to
        // ignore this error.
        hr = S_OK;
      }
    }
    if (FAILED(hr)) {
      DECODER_LOG("Failed to set DXVA2 D3D Device manager on decoder hr=0x%x", hr);
      mUseHwAccel = false;
    }
  }
  return hr;
}
示例#2
0
nsresult
WMFReader::ReadMetadata(MediaInfo* aInfo,
                        MetadataTags** aTags)
{
    NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");

    LOG("WMFReader::ReadMetadata()");
    HRESULT hr;

    RefPtr<IMFAttributes> attr;
    hr = wmf::MFCreateAttributes(byRef(attr), 1);
    NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

    hr = attr->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, mSourceReaderCallback);
    NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

    if (mUseHwAccel) {
        hr = attr->SetUnknown(MF_SOURCE_READER_D3D_MANAGER,
                              mDXVA2Manager->GetDXVADeviceManager());
        if (FAILED(hr)) {
            LOG("Failed to set DXVA2 D3D Device manager on source reader attributes");
            mUseHwAccel = false;
        }
    }

    hr = wmf::MFCreateSourceReaderFromByteStream(mByteStream, attr, byRef(mSourceReader));
    NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

    hr = ConfigureVideoDecoder();
    NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

    hr = ConfigureAudioDecoder();
    NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

    if (mUseHwAccel && mInfo.mVideo.mHasVideo) {
        RefPtr<IMFTransform> videoDecoder;
        hr = mSourceReader->GetServiceForStream(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
                                                GUID_NULL,
                                                IID_IMFTransform,
                                                (void**)(IMFTransform**)(byRef(videoDecoder)));

        if (SUCCEEDED(hr)) {
            ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager());
            hr = videoDecoder->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER,
                                              manager);
            if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
                // Ignore MF_E_TRANSFORM_TYPE_NOT_SET. Vista returns this here
                // on some, perhaps all, video cards. This may be because activating
                // DXVA changes the available output types. It seems to be safe to
                // ignore this error.
                hr = S_OK;
            }
        }
        if (FAILED(hr)) {
            LOG("Failed to set DXVA2 D3D Device manager on decoder hr=0x%x", hr);
            mUseHwAccel = false;
            // Re-run the configuration process, so that the output video format
            // is set correctly to reflect that hardware acceleration is disabled.
            // Without this, we'd be running with !mUseHwAccel and the output format
            // set to NV12, which is the format we expect when using hardware
            // acceleration. This would cause us to misinterpret the frame contents.
            hr = ConfigureVideoDecoder();
        }
    }
    if (mInfo.HasVideo()) {
        LOG("Using DXVA: %s", (mUseHwAccel ? "Yes" : "No"));
    }

    // Abort if both video and audio failed to initialize.
    NS_ENSURE_TRUE(mInfo.HasValidMedia(), NS_ERROR_FAILURE);

    // Get the duration, and report it to the decoder if we have it.
    int64_t duration = 0;
    hr = GetSourceReaderDuration(mSourceReader, duration);
    if (SUCCEEDED(hr)) {
        ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
        mDecoder->SetMediaDuration(duration);
    }
    // We can seek if we get a duration *and* the reader reports that it's
    // seekable.
    bool canSeek = false;
    if (FAILED(hr) ||
            FAILED(GetSourceReaderCanSeek(mSourceReader, canSeek)) ||
            !canSeek) {
        mDecoder->SetMediaSeekable(false);
    }

    *aInfo = mInfo;
    *aTags = nullptr;
    // aTags can be retrieved using techniques like used here:
    // http://blogs.msdn.com/b/mf/archive/2010/01/12/mfmediapropdump.aspx

    return NS_OK;
}
示例#3
0
nsresult
WMFReader::ReadMetadata(VideoInfo* aInfo,
                        MetadataTags** aTags)
{
  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");

  LOG("WMFReader::ReadMetadata()");
  HRESULT hr;

  RefPtr<IMFAttributes> attr;
  hr = wmf::MFCreateAttributes(byRef(attr), 1);
  NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

  hr = attr->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, mSourceReaderCallback);
  NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

  if (mUseHwAccel) {
    hr = attr->SetUnknown(MF_SOURCE_READER_D3D_MANAGER,
                          mDXVA2Manager->GetDXVADeviceManager());
    if (FAILED(hr)) {
      LOG("Failed to set DXVA2 D3D Device manager on source reader attributes");
      mUseHwAccel = false;
    }
  }

  hr = wmf::MFCreateSourceReaderFromByteStream(mByteStream, attr, byRef(mSourceReader));
  NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

  hr = ConfigureVideoDecoder();
  NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

  hr = ConfigureAudioDecoder();
  NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);

  if (mUseHwAccel && mInfo.mHasVideo) {
    RefPtr<IMFTransform> videoDecoder;
    hr = mSourceReader->GetServiceForStream(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
                                            GUID_NULL,
                                            IID_IMFTransform,
                                            (void**)(IMFTransform**)(byRef(videoDecoder)));

    if (SUCCEEDED(hr)) {
      ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager());
      hr = videoDecoder->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER,
                                        manager);
    }
    if (FAILED(hr)) {
      LOG("Failed to set DXVA2 D3D Device manager on decoder");
      mUseHwAccel = false;
    }
  }
  if (mInfo.mHasVideo) {
    LOG("Using DXVA: %s", (mUseHwAccel ? "Yes" : "No"));
  }

  // Abort if both video and audio failed to initialize.
  NS_ENSURE_TRUE(mInfo.mHasAudio || mInfo.mHasVideo, NS_ERROR_FAILURE);

  int64_t duration = 0;
  if (SUCCEEDED(GetSourceReaderDuration(mSourceReader, duration))) {
    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
    mDecoder->SetMediaDuration(duration);
  }

  hr = GetSourceReaderCanSeek(mSourceReader, mCanSeek);
  NS_ASSERTION(SUCCEEDED(hr), "Can't determine if resource is seekable");

  *aInfo = mInfo;
  *aTags = nullptr;
  // aTags can be retrieved using techniques like used here:
  // http://blogs.msdn.com/b/mf/archive/2010/01/12/mfmediapropdump.aspx

  return NS_OK;
}