예제 #1
0
/**
  \fn ADMImage_To_yv12Surface
*/
static bool  ADMImage_To_yv12Surface(ADMImage *pic, IDirect3DSurface9 *surface)
{
  D3DLOCKED_RECT     lock;;
  if (ADM_FAILED(IDirect3DSurface9_LockRect(surface,&lock, NULL, 0)))
  {
      ADM_warning("D3D Cannot lock surface\n");
      return false;
  }

  // copy
  uint8_t *dst=(uint8_t *)lock.pBits;
  int  dStride=lock.Pitch;

  int width=pic->GetWidth(PLANAR_Y);
  int height=pic->GetHeight(PLANAR_Y);

  d3dBlit(pic, PLANAR_Y,dst,dStride,width,height);

  dst+=height*dStride;
  d3dBlit(pic, PLANAR_U,dst,dStride>>1,width>>1,height>>1);

  dst+=(height/2)*(dStride/2);
  d3dBlit(pic, PLANAR_V,dst,dStride>>1,width>>1,height>>1);

  if (ADM_FAILED(IDirect3DSurface9_UnlockRect(surface)))
  {
      ADM_warning("D3D Cannot unlock surface\n");
      return false;
  }
  return true;
}
예제 #2
0
/**
  \fn displayImage_argb
  \brief manually do the yv12-> RGB conversion + rescale and the upload to backbuffer
*/
bool dxvaRender::displayImage_argb(ADMImage *pic)
{
  IDirect3DSurface9 *bBuffer;
  // 1 upload to myYV12 surface
  if( ADM_FAILED(IDirect3DDevice9_GetBackBuffer(d3dDevice, 0, 0,
                                            D3DBACKBUFFER_TYPE_MONO,
                                            &bBuffer)))
  {
        ADM_warning("D3D Cannot create backBuffer\n");
        return false;
  }

  if(!ADMImage_To_argbSurface(pic,bBuffer,scaler))
  {
    ADM_warning("Image to argb surface failed\n");
    return false;
  }

  IDirect3DDevice9_BeginScene(d3dDevice);

  IDirect3DDevice9_EndScene(d3dDevice);
  if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
  {
    ADM_warning("D3D Present failed\n");
  }

  return true;
}
예제 #3
0
/**
  \fn ADMImage_To_argbSurface
*/
static bool  ADMImage_To_argbSurface(ADMImage *pic, IDirect3DSurface9 *surface,ADMColorScalerFull *scaler)
{
    D3DLOCKED_RECT     lock;

    if (ADM_FAILED(IDirect3DSurface9_LockRect(surface,&lock, NULL, 0)))
    {
        ADM_warning("D3D Cannot lock surface\n");
        return false;
    }
    // RGB
    uint8_t *src[3];
    uint8_t *dst[3];
    pic->GetReadPlanes(src);
    dst[0]=(uint8_t *)lock.pBits;
    dst[1]=dst[2]=NULL;
    int sourcePitch[3],dstPitch[3];
    pic->GetPitches(sourcePitch);
    dstPitch[0]=lock.Pitch;
    dstPitch[1]=dstPitch[2]=0;
    scaler-> convertPlanes(sourcePitch,dstPitch, src, dst);

    if (ADM_FAILED(IDirect3DSurface9_UnlockRect(surface)))
    {
        ADM_warning("D3D Cannot unlock surface\n");
        return false;
    }
    return true;
}
예제 #4
0
/**
  \fn brief input is already a surface, in yv12 format
*/
bool dxvaRender::displayImage_surface(ADMImage *pic,admDx2Surface *surface)
{
  // this does not work, both surfaces are coming from different device

  IDirect3DSurface9 *bBuffer;
  POINT point={0,0};
  // 1 upload to myYV12 surface
  if(ADM_FAILED(IDirect3DDevice9_UpdateSurface(d3dDevice,
          surface->surface,   // src
          &panScan,       // src rect
          myYV12Surface, // dst
          &point         // where to
        )))
        {
            ADM_warning("Copying surface failed, switching to non accelerated path \n");
            if(!pic->hwDownloadFromRef())
            {
              ADM_warning("Failed to download yv12 from dxva\n");
              return false;
            }
            // workaround : use default non bridged path
              if(useYV12)
              {
                  return displayImage_yv12(pic);
              }
              return displayImage_argb(pic);
            return false;
        }
 // upload....
  if( ADM_FAILED(IDirect3DDevice9_GetBackBuffer(d3dDevice, 0, 0,
                                            D3DBACKBUFFER_TYPE_MONO,
                                            &bBuffer)))
  {
        ADM_warning("D3D Cannot create backBuffer\n");
        return false;
  }


  // data are in YV12 surface, blit it to mySurface
  // zoom and color conversion happen there

  if (ADM_FAILED(IDirect3DDevice9_StretchRect(d3dDevice,
                  myYV12Surface,
                  NULL,
                  bBuffer,
                  NULL,
                  D3DTEXF_LINEAR)))
                  {
                         ADM_warning("StretchRec yv12 failed\n");
                  }
  IDirect3DDevice9_BeginScene(d3dDevice);
  IDirect3DDevice9_EndScene(d3dDevice);
  if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
  {
    ADM_warning("D3D Present failed\n");
  }

  return true;
}
예제 #5
0
/**
  \fn brief input is already a surface, in yv12 format
*/
bool dxvaRender::displayImage_surface(ADMImage *pic,admDx2Surface *surface)
{
  // this does not work, both surfaces are coming from different device

  IDirect3DSurface9 *bBuffer;
  POINT point={0,0};
  // OK
  ADM_info("surface duplicated\n");
  if( ADM_FAILED(D3DCall(IDirect3DDevice9,GetBackBuffer,d3dDevice, 0, 0,
                                              D3DBACKBUFFER_TYPE_MONO,
                                              &bBuffer)))
  {
      ADM_warning("D3D Cannot create backBuffer\n");
      return false;
  }

  // can we directly use the surface from dxva ? (can we at all ?)
  if (ADM_FAILED(D3DCall(IDirect3DDevice9,StretchRect,d3dDevice,
                  surface->surface,
                  NULL,
                  bBuffer,
                  NULL,
                  D3DTEXF_LINEAR)))
  {
    ADM_warning("StretchRec yv12 failed\n");
    // go to indirect route
    if(!pic->hwDownloadFromRef())
    {
        ADM_warning("Failed to download yv12 from dxva\n");
        return false;
    }
    // workaround : use default non bridged path
    if(useYV12)
    {
         return displayImage_yv12(pic);
    }
    return displayImage_argb(pic);
  }
  IDirect3DDevice9_BeginScene(d3dDevice);
  IDirect3DDevice9_EndScene(d3dDevice);
  if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
  {
    ADM_warning("D3D Present failed\n");
  }
  return true;
}
예제 #6
0
 /**
 \fn refresh
 \brief does not work correctly
 */
 bool dxvaRender::refresh(void)
 {
   ADM_info("Refresh**\n");
#if 0
   if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
   {
        ADM_warning("D3D Present failed\n");
   }
#else
    D3DCallNoArg(IDirect3DDevice9,BeginScene,d3dDevice);
    D3DCallNoArg(IDirect3DDevice9,EndScene,d3dDevice);
    if( ADM_FAILED(D3DCall(IDirect3DDevice9,Present,d3dDevice, &targetRect, 0, 0, 0)))
    {
        ADM_warning("D3D Present failed\n");
    }
#endif
  return true;
 }
예제 #7
0
 /**
 \fn refresh
 \brief does not work correctly
 */
 bool dxvaRender::refresh(void)
 {
   ADM_info("Refresh**\n");
   #if 0
   if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
   {
        ADM_warning("D3D Present failed\n");
   }
   #endif
  return true;
 }
예제 #8
0
/**
  \fn displayImage_yv12
  \brief copy image to myV12 surface then convert from yv12 to display format in mySurface

*/
bool dxvaRender::displayImage_yv12(ADMImage *pic)
{
    IDirect3DSurface9 *bBuffer;
    // 1 upload to myYV12 surface
    if(!ADMImage_To_yv12Surface(pic,myYV12Surface))
    {
      return false;
    }
   // upload....
    if( ADM_FAILED(IDirect3DDevice9_GetBackBuffer(d3dDevice, 0, 0,
                                              D3DBACKBUFFER_TYPE_MONO,
                                              &bBuffer)))
    {
          ADM_warning("D3D Cannot create backBuffer\n");
          return false;
    }


    // data are in YV12 surface, blit it to mySurface
    // zoom and color conversion happen there

    if (ADM_FAILED(IDirect3DDevice9_StretchRect(d3dDevice,
                    myYV12Surface,
                    NULL,
                    bBuffer,
                    NULL,
                    D3DTEXF_LINEAR)))
                    {
                           ADM_warning("StretchRec yv12 failed\n");
                    }
    IDirect3DDevice9_BeginScene(d3dDevice);
    IDirect3DDevice9_EndScene(d3dDevice);
    if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
    {
      ADM_warning("D3D Present failed\n");
    }

    return true;
}
예제 #9
0
/**
  \fn setup
  \brief Allocate stuff for a given display with/height. It is called again each time the zoom is changed
*/
bool dxvaRender::setup()
{
  D3DVIEWPORT9 viewPort = {0, 0, displayWidth, displayHeight, 0, 1};


    ADM_info("D3D (re)Setting up \n");
     D3DPRESENT_PARAMETERS presentationParameters;
     memset(&presentationParameters, 0, sizeof(presentationParameters));
     presentationParameters.Windowed               = TRUE;
     presentationParameters.SwapEffect             = D3DSWAPEFFECT_DISCARD; // We could use copy, but discard seems faster according to ms
     presentationParameters.Flags                  = D3DPRESENTFLAG_VIDEO;
     presentationParameters.hDeviceWindow          = windowId;
     presentationParameters.BackBufferWidth        = displayWidth;
     presentationParameters.BackBufferHeight       = displayHeight;
     presentationParameters.MultiSampleType        = D3DMULTISAMPLE_NONE;
     presentationParameters.PresentationInterval   = D3DPRESENT_INTERVAL_ONE;
     presentationParameters.BackBufferFormat       = displayMode.Format;
     presentationParameters.BackBufferCount        = 1;
     presentationParameters.EnableAutoDepthStencil = FALSE;


#ifndef REUSE_DEVICE
     if(ADM_FAILED(IDirect3D9_CreateDevice(  d3dHandle,
                                         D3DADAPTER_DEFAULT,
                                         D3DDEVTYPE_HAL,  presentationParameters.hDeviceWindow,
                                         D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                         &presentationParameters, &d3dDevice)))
     {
        ADM_warning("Failed to create D3D device\n");
        return false;
    }
#else
      d3dDevice=admD3D::getDevice();
#endif

      //

      D3DFORMAT yv12=(D3DFORMAT)MAKEFOURCC('Y','V','1','2');

      //
       if( ADM_FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(
                 d3dDevice, displayWidth,displayHeight,
                 displayMode.Format, D3DPOOL_DEFAULT, &mySurface, NULL)))
       {
                  ADM_warning("D3D Cannot create surface\n");
                  return false;
       }
       if( ADM_FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(
                 d3dDevice, imageWidth,imageHeight,
                 yv12, D3DPOOL_DEFAULT, &myYV12Surface, NULL)))
       {
                  ADM_warning("D3D Cannot create surface\n");
                  return false;
       }
      // put some defaults
      IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_SRCBLEND, D3DBLEND_ONE);
      IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
      IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHAFUNC, D3DCMP_GREATER);
      IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_ALPHAREF, (DWORD)0x0);
      IDirect3DDevice9_SetRenderState(d3dDevice, D3DRS_LIGHTING, FALSE);
      IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
      IDirect3DDevice9_SetSamplerState(d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
      //


  if(ADM_FAILED(IDirect3DDevice9_SetViewport(d3dDevice, &viewPort)))
  {
      ADM_warning("D3D Cannot set D3D viewport\n");
      return false;
  }

 scaler=new ADMColorScalerFull(ADM_CS_BICUBIC,imageWidth,imageHeight,displayWidth,displayHeight,
          ADM_COLOR_YV12,
          ADM_COLOR_RGB32A
      );
  videoBuffer=new uint8_t[displayWidth*displayHeight*4];
  panScan.left  =0;
  panScan.right =imageWidth-1;
  panScan.top   =0;
  panScan.bottom=imageHeight-1;

  targetRect.left  =0;
  targetRect.right =displayWidth-1;
  targetRect.top   =0;
  targetRect.bottom=displayHeight-1;
  ADM_info("Setup done\n");
  return true;
}
예제 #10
0
/**
    \fn changeZoom
*/
bool dxvaRender::init( GUI_WindowInfo *  window, uint32_t w, uint32_t h,renderZoom zoom)
{
    ADM_info("Initializing dxva2/D3D render\n");
    info=*window;
    baseInit(w,h,zoom);

    windowId=(HWND)window->systemWindowId;

    if(!d3dHandle)
    {
        ADM_warning("No D3DHandle\n");
        return false;
    }

    if (ADM_FAILED(IDirect3D9_GetAdapterDisplayMode(d3dHandle,
                                                D3DADAPTER_DEFAULT,
                                                &displayMode)))
    {
        ADM_warning("Dxv2/D3D Render: Cannot get display mode\n");
        return 0;
    }

    D3DCAPS9 deviceCapabilities;
    ADM_info("D3D Checking device capabilities\n");
    if (ADM_FAILED(IDirect3D9_GetDeviceCaps(d3dHandle,
                                        D3DADAPTER_DEFAULT,
                                        D3DDEVTYPE_HAL,
                                        &deviceCapabilities)))
    {
      ADM_warning("Cannot get device capabilities");
      return false;
    }
    int texture = deviceCapabilities.TextureCaps;
    ADM_info("Power of 2 : %d\n",  (texture & D3DPTEXTURECAPS_POW2) &&   !(texture & D3DPTEXTURECAPS_NONPOW2CONDITIONAL));
    ADM_info("Square only: %d\n",  (texture & D3DPTEXTURECAPS_SQUAREONLY));



      // Check if we support YV12
    D3DFORMAT fmt=displayMode.Format;
    D3DFORMAT yv12=(D3DFORMAT)MAKEFOURCC('Y','V','1','2');
    if (ADM_FAILED(IDirect3D9_CheckDeviceFormatConversion(   d3dHandle, // adapter
                                                         D3DADAPTER_DEFAULT, // device type
                                                         D3DDEVTYPE_HAL, // adapter format
                                                         yv12, // render target format
                                                         fmt)))  // depth stencil format
    {
        useYV12=false;
        ADM_info("D3D YV12 not supported\n");
    }
    else
    {
        useYV12=true;
        ADM_info("D3D YV12 is supported\n");
    }



    if(!setup())
    {
      ADM_warning("Dxva/D3D setup failed\n");
      return false;
    }
    videoWidget=(ADM_Qvideo *)info.widget;
    videoWidget->useExternalRedraw(true); // deactivate Qt Double buffering
    videoWidget->setDrawer(this);

    ADM_info("Dxva (D3D) init successful, dxva render. w=%d, h=%d,zoom=%d, displayWidth=%d, displayHeight=%d\n",(int)w,(int)h,(int)zoom,(int)displayWidth,(int)displayHeight);
    return true;
}