Example #1
0
STDMETHODIMP CDecDXVA2::Flush()
{
  CDecAvcodec::Flush();
  FlushDisplayQueue(FALSE);

#ifdef DEBUG
  int used = 0;
  for (int i = 0; i < m_NumSurfaces; i++) {
    d3d_surface_t *s = &m_pSurfaces[i];
    if (s->used) {
      used++;
    }
  }
  if (used > 0) {
    DbgLog((LOG_TRACE, 10, L"WARNING! %d frames still in use after flush", used));
  }
#endif

  // This solves an issue with corruption after seeks on AMD systems, see JIRA LAV-5
  if (m_dwVendorId == VEND_ID_ATI && m_nCodecId == AV_CODEC_ID_H264 && m_pDecoder) {
    if (m_bNative && m_pDXVA2Allocator) {
      // The allocator needs to be locked because flushes can happen async to other graph events
      // and in the worst case the allocator is decommited while we're using it.
      CAutoLock allocatorLock(m_pDXVA2Allocator);
      if (m_pDXVA2Allocator->IsCommited())
        CreateDXVA2Decoder(m_NumSurfaces, m_pRawSurface);
    } else if(!m_bNative)
      CreateDXVA2Decoder();
  }

  return S_OK;
}
Example #2
0
STDMETHODIMP CDecDXVA2::Flush()
{
  CDecAvcodec::Flush();
  FlushDisplayQueue(FALSE);

#ifdef DEBUG
  int used = 0;
  for (int i = 0; i < m_NumSurfaces; i++) {
    d3d_surface_t *s = &m_pSurfaces[i];
    if (s->used) {
      used++;
    }
  }
  if (used > 0) {
    DbgLog((LOG_TRACE, 10, L"WARNING! %d frames still in use after flush", used));
  }
#endif

  // This solves an issue with corruption after seeks on AMD systems, see JIRA LAV-5
  if (m_dwVendorId == VEND_ID_ATI && m_nCodecId == AV_CODEC_ID_H264 && m_pDecoder) {
    if (m_bNative && m_pDXVA2Allocator && m_pDXVA2Allocator->IsCommited())
      CreateDXVA2Decoder(m_NumSurfaces, m_pRawSurface);
    else if(!m_bNative)
      CreateDXVA2Decoder();
  }

  return S_OK;
}
Example #3
0
HRESULT CDecDXVA2::ReInitDXVA2Decoder(AVCodecContext *c)
{
  HRESULT hr = S_OK;

  // Don't allow decoder creation during first init
  if (m_bInInit)
    return S_FALSE;

  if (!m_pDecoder || GetAlignedDimension(c->coded_width) != m_dwSurfaceWidth || GetAlignedDimension(c->coded_height) != m_dwSurfaceHeight) {
    DbgLog((LOG_TRACE, 10, L"No DXVA2 Decoder or image dimensions changed -> Re-Allocating resources"));
    if (!m_pDecoder && m_bNative && !m_pDXVA2Allocator) {
      ASSERT(0);
      hr = E_FAIL;
    } else if (m_bNative) {
      avcodec_flush_buffers(c);

      m_dwSurfaceWidth  = GetAlignedDimension(c->coded_width);
      m_dwSurfaceHeight = GetAlignedDimension(c->coded_height);

      // Re-Commit the allocator (creates surfaces and new decoder)
      hr = m_pDXVA2Allocator->Decommit();
      if (m_pDXVA2Allocator->DecommitInProgress()) {
        DbgLog((LOG_TRACE, 10, L"WARNING! DXVA2 Allocator is still busy, trying to flush downstream"));
        m_pCallback->ReleaseAllDXVAResources();
        m_pCallback->GetOutputPin()->GetConnected()->BeginFlush();
        m_pCallback->GetOutputPin()->GetConnected()->EndFlush();
        if (m_pDXVA2Allocator->DecommitInProgress()) {
          DbgLog((LOG_TRACE, 10, L"WARNING! Flush had no effect, decommit of the allocator still not complete"));
        } else {
          DbgLog((LOG_TRACE, 10, L"Flush was successfull, decommit completed!"));
        }
      }
      hr = m_pDXVA2Allocator->Commit();
    } else if (!m_bNative) {
      if (SyncToProcessThread() == S_FALSE)
        FlushDisplayQueue(TRUE);
      hr = CreateDXVA2Decoder();
    }
  }

  return hr;
}