//如果转换成功,则调用者使用完 pOutFrame 后,需要调用 avpicture_free(pOutFrame) 释放内存 //成功返回0,不成功返回非0 int CTool::ConvertFormat(/*[in]*/ const QVideoFrame &inFrame, /*[out]*/AVPicture &outFrame, /*[in]*/ int nOutWidth, /*[in]*/ int nOutHeight, /*[in]*/ AVPixelFormat pixelFormat) { int nRet = 0; AVPicture pic; nRet = avpicture_fill(&pic, (uint8_t*) inFrame.bits(), QVideoFrameFormatToFFMpegPixFormat(inFrame.pixelFormat()), inFrame.width(), inFrame.height()); if(nRet < 0) { LOG_MODEL_DEBUG("Tool", "avpicture_fill fail:%x", nRet); return nRet; } nRet = ConvertFormat(pic, inFrame.width(), inFrame.height(), QVideoFrameFormatToFFMpegPixFormat(inFrame.pixelFormat()), outFrame, nOutWidth, nOutHeight, pixelFormat); return nRet; }
int CTool::ConvertFormat(/*[in]*/const std::shared_ptr<CVideoFrame> &inFrame, /*[out]*/ std::shared_ptr<CVideoFrame> &outFrame, /** 转换后图像 */ /*[in]*/ int nOutWidth, /** 转换后的帧的宽度 */ /*[in]*/ int nOutHeight, /** 转换后的帧的高度 */ /*[in]*/ VideoFormat format) { int nRet = 0; if(!inFrame) { LOG_MODEL_ERROR("CTool", "frame is null"); return -1; } AVPixelFormat inFormat, outFormat; inFormat = VideoFormatToFFMpegPixFormat(inFrame->m_VideoInfo.Format); outFormat = VideoFormatToFFMpegPixFormat(format); AVPicture pic; nRet = avpicture_fill(&pic, (uint8_t*)inFrame->GetData(), inFormat, inFrame->m_VideoInfo.nWidth, inFrame->m_VideoInfo.nHeight); if(nRet < 0) { LOG_MODEL_ERROR("Tool", "avpicture_fill fail:%x", nRet); return nRet; } AVPicture outPic; nRet = ConvertFormat(pic, inFrame->m_VideoInfo.nWidth, inFrame->m_VideoInfo.nHeight, inFormat, outPic, nOutWidth, nOutHeight, outFormat); if(nRet) return nRet; int nLen = avpicture_get_size(outFormat, nOutWidth, nOutHeight); VideoInfo vi; vi.Format = format; vi.nHeight = nOutHeight; vi.nWidth = nOutWidth; vi.nRatio = inFrame->m_VideoInfo.nRatio; std::shared_ptr<CVideoFrame> frame( new CVideoFrame(outPic.data[0], nLen, vi, inFrame->m_Timestamp)); outFrame = frame; avpicture_free(&pic); avpicture_free(&outPic); return nRet; }
void D3D9CaptureSetup(IDirect3DDevice9* device) { IDirect3DSwapChain9* swap_chain = NULL; //通过交换链信息来获取相关信息 if (SUCCEEDED(device->GetSwapChain(0, &swap_chain))) { D3DPRESENT_PARAMETERS d3dpp; if (SUCCEEDED(swap_chain->GetPresentParameters(&d3dpp))) { if (d3d9_format != d3dpp.BackBufferFormat || d3d9_captureinfo.oWidth != d3dpp.BackBufferWidth || d3d9_captureinfo.oHeight != d3dpp.BackBufferHeight || reinterpret_cast<HWND>(d3d9_captureinfo.sNative) != d3dpp.hDeviceWindow) { //todo printf prsents info d3d11_format = ConverDXGIFormat(d3dpp.BackBufferFormat); d3d9_format = d3dpp.BackBufferFormat; d3d9_captureinfo.oWidth = d3dpp.BackBufferWidth; d3d9_captureinfo.oHeight = d3dpp.BackBufferHeight; d3d9_captureinfo.sNative = reinterpret_cast<unsigned __int64>(d3dpp.hDeviceWindow); d3d9_captureinfo.Reserved1 = ConvertFormat(d3dpp.BackBufferFormat); d3d9_captureinfo.Flip = 0; } } else logstream << "Don't have enough infomation to hook(failed to get present params)" << std::endl; //todo D3D9EX/PresentEx IDirect3DDevice9Ex* deviceEx = NULL; if (d3d9ex_support && SUCCEEDED(device->QueryInterface(__uuidof(IDirect3DDevice9Ex), reinterpret_cast<void**>(&deviceEx)))) { presentex.Do(h3d::GetVirtual(device, D3D9PRESENTEX_OFFSET), (h3d::WINAPIPROC)PresentEx); resetex.Do(h3d::GetVirtual(device, D3D9RESETEX_OFFSET), (h3d::WINAPIPROC)ResetEx); deviceEx->Release(); } present.Do(h3d::GetVirtual(device, D3D9PRESENT_OFFSET), (h3d::WINAPIPROC)Present); reset.Do(h3d::GetVirtual(device, D3D9RESET_OFFSET), (h3d::WINAPIPROC)Reset); swap_present.Do(h3d::GetVirtual(swap_chain, SWAPCHAINPRESENT_OFFSET), (h3d::WINAPIPROC)SwapPresent); swap_chain->Release(); logstream << "D3D9Capture Succesfully Set Up D3D9 HOOKS" << std::endl; } else logstream << "D3D9Capture Faild to get SwapCahin to initialize hooks" << std::endl; }
CTexture9::CTexture9(CDevice9* device, UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, HANDLE *pSharedHandle) : mDevice(device), mWidth(Width), mHeight(Height), mLevels(Levels), mUsage(Usage), mFormat(Format), mPool(Pool), mSharedHandle(pSharedHandle) { Log(info) << "CTexture9::CTexture9" << std::endl; //mDevice->AddRef(); if (!mLevels) { mLevels = (UINT)std::log2(std::max(mWidth, mHeight)) + 1; } if (mUsage == 0) { mUsage = D3DUSAGE_RENDERTARGET; } mSurfaces.reserve(mLevels); UINT width = mWidth, height = mHeight; for (int32_t i = 0; i < (int32_t)mLevels; i++) { CSurface9* ptr = new CSurface9(mDevice, this, width, height, mUsage, 1 /*Levels*/, mFormat, D3DMULTISAMPLE_NONE, 0 /*MultisampleQuality*/, false /*Discard*/, false /*Lockable*/, mPool, mSharedHandle); ptr->mMipIndex = i; mSurfaces.push_back(ptr); width /= 2; height /= 2; if (height == 0) { height = 1; } if (width == 0 && Width > 0) { width = 1; } } const vk::ImageTiling tiling = vk::ImageTiling::eOptimal; const vk::ImageUsageFlags usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst; const vk::MemoryPropertyFlags required_props = vk::MemoryPropertyFlagBits::eDeviceLocal; const vk::ImageCreateInfo imageCreateInfo = vk::ImageCreateInfo() .setImageType(vk::ImageType::e2D) .setFormat(ConvertFormat(mFormat)) .setExtent({ mWidth, mHeight, 1 }) .setMipLevels(mLevels) .setArrayLayers(1) .setSamples(vk::SampleCountFlagBits::e1) .setTiling(tiling) .setUsage(usage) .setSharingMode(vk::SharingMode::eExclusive) .setQueueFamilyIndexCount(0) .setPQueueFamilyIndices(nullptr) .setInitialLayout(vk::ImageLayout::ePreinitialized); mImage = mDevice->mDevice->createImageUnique(imageCreateInfo); vk::MemoryRequirements memoryRequirements; mDevice->mDevice->getImageMemoryRequirements(mImage.get(), &memoryRequirements); mImageMemoryAllocateInfo.setAllocationSize(memoryRequirements.size); mImageMemoryAllocateInfo.setMemoryTypeIndex(0); auto pass = mDevice->FindMemoryTypeFromProperties(memoryRequirements.memoryTypeBits, required_props, &mImageMemoryAllocateInfo.memoryTypeIndex); mImageDeviceMemory = mDevice->mDevice->allocateMemoryUnique(mImageMemoryAllocateInfo); mDevice->mDevice->bindImageMemory(mImage.get(), mImageDeviceMemory.get(), 0); //Now transition this thing from init to shader ready. SetImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal); /* This block handles the luminance & x formats. They are converted to color formats but need a little mapping to make them work correctly. */ vk::ComponentMapping componentMapping; switch (mFormat) { case D3DFMT_R5G6B5: //Vulkan has a matching format but nvidia doesn't support using it as a color attachment so we just use the other one and re-map the components. componentMapping = vk::ComponentMapping(vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eOne); break; case D3DFMT_A8: //TODO: Revisit A8 mapping. componentMapping = vk::ComponentMapping(vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eR); break; case D3DFMT_L8: componentMapping = vk::ComponentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eOne); break; case D3DFMT_L16: componentMapping = vk::ComponentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eOne); break; case D3DFMT_A8L8: componentMapping = vk::ComponentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG); break; case D3DFMT_X8R8G8B8: case D3DFMT_X8B8G8R8: componentMapping = vk::ComponentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eOne); break; default: break; } auto const viewInfo = vk::ImageViewCreateInfo() .setImage(mImage.get()) .setViewType(vk::ImageViewType::e2D) .setFormat(ConvertFormat(mFormat)) .setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, mLevels, 0, 1)) .setComponents(componentMapping); mImageView = mDevice->mDevice->createImageViewUnique(viewInfo); }
short ValueToStr(char *Values,short DataFormat,char *ValDesc,short Datasize,short RowNum,short ColNum,char *EqName,char *Property,BOOL Formatting) { short ind,i,stroff; char Buffer[BUFFER_SIZE+1]; double value; short col,row,cl=-1; stroff=0;ValDesc[0]=0; if (strcmp(Property,(char *)"STAQ") && strcmp(Property,(char *)"STCC")) { if (DataFormat==CF_TEXT) { for (i=0;Values[i] && i<Datasize-1;i++) ValDesc[i]=Values[i]; ValDesc[i]=0; return cl; } for (row=0;row<RowNum;row++) { for (col=0;col<ColNum;col++) { ind=col+row*ColNum; ConvertFormat((void *)&Values[ind*GetFormatSize(DataFormat)],DataFormat, (void *)&value,CF_DOUBLE,1); if (!strcmp(Property,(char *)"STAQ") || !strcmp(Property,(char *)"STCC")) sprintf(Buffer,"%d",(short)value); else { if (Formatting) sprintf(Buffer,"%lg",value);else sprintf(Buffer,"%lf",value); } if ((stroff+strlen(Buffer))>=(USHORT)Datasize) return cl; strcpy(&ValDesc[stroff],(char *)Buffer); stroff=strlen(ValDesc); if (stroff) { if (col==ColNum-1) ValDesc[stroff++]='\n'; else ValDesc[stroff++]='\t'; ValDesc[stroff]=0; } } } } else { i=0; while (i<RPCNumEqpsRead && strcmp(RPCMod[i].EqpName,EqName)) i++; value=*(double *)Values; if (i>=RPCNumEqpsRead) { sprintf(Buffer,"%lg",value); strcpy(ValDesc,(char *)Buffer); return cl; } while (i<RPCNumEqpsRead && !strcmp(RPCMod[i].EqpName,EqName)) { if ((RPCMod[i].Weight & ((short)value)) || (!RPCMod[i].Weight && !(short)value)) { if ((strlen(ValDesc)+strlen(RPCMod[i].StatName)+3)>=(USHORT)Datasize) { if ((strlen(ValDesc)+4)<=(USHORT)Datasize) stroff=strlen(ValDesc); else stroff=strlen(ValDesc)-4; strcpy(&ValDesc[stroff],(char *)" ->"); return cl; } if (strlen((char *)&ValDesc[stroff])) strcat(ValDesc,(char *)" + "); else cl=i; strcat(ValDesc,RPCMod[i].StatName); } i++; } stroff=strlen(ValDesc); if (stroff) ValDesc[stroff++]=9;ValDesc[stroff]=0; } if (stroff && (ValDesc[stroff-1]=='\t' || ValDesc[stroff-1]=='\n')) ValDesc[stroff-1]=0; return cl; }
short SyncRPC(char *Name,char *Property,char *Cycle,short Size,void *Data,short Datasize,short DataFormat,short dummy) { ElemDataStruct Elem; USHORT i; short j,cc,dataindex,flag; char Buffer[BUFFER_SIZE+1],eqname[EQNAME_SIZE+1]; char *values; double value; char *ptr; WORD connectionID; flag=abs(Size)/Size; if (strlen(Name)>ELEM_NAME_SIZE) return non_existent_elem; for (i=0;i<strlen(Name);i++) Elem.ElemName[i]=toupper(Name[i]); Elem.ElemName[i]=0; dataindex = SearchDataBase(RPCDataElems,Elem.ElemName,"NAME"); CString data; data.Format("%d",dataindex); AfxMessageBox(data,MB_OK,0); if (dataindex < 0) { strcpy(Buffer,"DEFAULT"); /************************/ cc = non_existent_fec; goto out2; } else strcpy((char *)Buffer,RPCData[dataindex].FecName); Elem.Values = NULL; Elem.FecIndex = SearchDataBase(RPCFecElems,Buffer,"FECNAME"); if (Elem.FecIndex < 0) { if (dataindex < 0) cc = non_existent_elem; else cc = non_existent_fec; goto out; } if (strlen(Property)>PROPERTY_SIZE) return illegal_property; strcpy(Elem.Property,Property); for (i=strlen(Elem.Property);i<PROPERTY_SIZE+1;i++) Elem.Property[i]=0; if (dataindex<0) { eqname[0]=0;Elem.EqNo=0; } else { strcpy((char *)eqname,RPCData[dataindex].EqName); Elem.EqNo=RPCData[dataindex].EqNumber; } strcpy(Elem.EqName,eqname); for (i=strlen(Elem.EqName);i<EQNAME_SIZE+1;i++) Elem.EqName[i]=0; Elem.DataFormat=DataFormat; if (Cycle==NULL) Elem.Cycle[0]=0; else strcpy(Elem.Cycle,Cycle); Elem.Size=abs(Size); if (Size<0) { switch (Elem.DataFormat) { case CF_TEXT: ptr=(char *)Data; for (i=0;i<abs(Size) && *ptr;i++) { j=0; while (*ptr && *ptr!='\t' && *ptr!='\r' && *ptr!='\n') Buffer[j++]=*ptr++; Buffer[j]=0; while (*ptr=='\t' || *ptr=='\r' || *ptr=='\n') ptr++; cc=StrToValue((double *)&value,Buffer,(char *)eqname,(char *)Property); if (!cc) { if (!i) { if ((Elem.Values = (char *) malloc(GetFormatSize(CF_DOUBLE)*abs(Size)))==NULL) {cc=out_of_memory;goto out;} } values=(char *)&value; for (j=0;j<GetFormatSize(CF_DOUBLE);j++) Elem.Values[i*GetFormatSize(CF_DOUBLE)+j]=values[j]; Elem.DataFormat=CF_DOUBLE; } else { if (strlen((char *)Data)>=(USHORT)GetFormatSize(CF_TEXT)) {cc=dimension_error;goto out;} if ((Elem.Values = (char *) malloc(GetFormatSize(CF_TEXT)*abs(Size)))==NULL) {cc=out_of_memory;goto out;} strcpy(Elem.Values,(char *)Data); break; } } break; case CF_DOUBLE: case CF_FLOAT: case CF_SHORT: case CF_LONG: case CF_BYTE: if ((Elem.Values = (char *) malloc(GetFormatSize(CF_DOUBLE)*abs(Size)))==NULL) {cc=out_of_memory;goto out;} ConvertFormat(Data,DataFormat,(void *)Elem.Values,CF_DOUBLE,abs(Size)); Elem.DataFormat=CF_DOUBLE; break; default: cc=illegal_format;goto out; } } cc=RPCConnect(0,&Elem,&connectionID); if (cc) goto out; cc=RPCSend(flag,&Elem,connectionID); if (cc) goto out; RPCReceive(flag,&Elem,connectionID); cc=Elem.CompCode; if (flag>0 && !cc && Data!=NULL) { ptr=(char *)Data; if (DataFormat==CF_TEXT) { if (Elem.DataFormat==CF_TEXT) { for (i=0;i<Datasize && Elem.Values[i];i++) ptr[i]=Elem.Values[i]; ptr[i]=0; } else ValueToStr(Elem.Values,Elem.DataFormat,ptr,Datasize, 1,abs(Size),Elem.EqName,Elem.Property,TRUE); } else ConvertFormat((void *)Elem.Values,Elem.DataFormat,Data,DataFormat,abs(Size)); } if (cc<0 && Data!=NULL && DataFormat==CF_TEXT && Datasize>(short)strlen(Elem.Values)) { strcpy((char *)Data,Elem.Values); } out: if (Elem.Values!=NULL) free((void *)Elem.Values); out2: lasterror = cc; return cc; }