Windows軟件插件-音視頻捕獲

下載本插件
音視頻捕獲就是獲取電腦外接的話筒,攝像頭,或線路輸入的音頻和視頻。
本插件捕獲電腦外接的音頻和視頻。最多可以同時獲取4個視頻源和4個音頻源。插件可以在win32和MFC程序中使用。

使用方法

首先,加載本“捕獲”DLL,獲得DLL模塊句柄。

	HMODULE hCap = LoadLibrary(L"捕獲.dll");//加載捕獲模塊

獲取所有導出函數的地址。

typedef int(__cdecl *MYPROC_Sample)(LONGLONG star, LONGLONG end, BYTE* pB, LONG len);struct CAP_INIT
{MYPROC_Sample VideoSample0 = NULL;//視頻樣本輸出函數MYPROC_Sample VideoSample1 = NULL;MYPROC_Sample VideoSample2 = NULL;MYPROC_Sample VideoSample3 = NULL;MYPROC_Sample AudioSample0 = NULL;//音頻樣本輸出函數MYPROC_Sample AudioSample1 = NULL;MYPROC_Sample AudioSample2 = NULL;MYPROC_Sample AudioSample3 = NULL;
};
struct CAP_VIDEO_INFO
{UINT32 Width=0;//視頻寬,單位像素UINT32 Height=0;//視頻高,單位像素double nFrames=0;//幀率WCHAR Name[MAX_PATH];//視頻捕獲設備名稱
};
struct CAP_AUDIO_INFO
{UINT32 nCh;//聲道數WCHAR Name[MAX_PATH];//音頻捕獲設備名稱
};typedef int(__cdecl *MYPROC_CAP_Init)(CAP_INIT init, CAP_VIDEO_INFO*& VideoInfo, CAP_AUDIO_INFO*& AudioInfo);
typedef int(__cdecl *MYPROC_VOID)();MYPROC_CAP_Init CAP_Init=NULL;
MYPROC_VOID CAP_ReleaseDevice=NULL;if (hCap){CAP_Init=(MYPROC_CAP_Init)GetProcAddress(hCap, "Init");//“初始化”函數CAP_ReleaseDevice=(MYPROC_VOID)GetProcAddress(hCap, "ReleaseDevice");//“釋放所有捕獲設備”函數}

定義8個全局函數,以提供給初始化函數;全局函數用于輸出視頻和音頻樣本。

int VideoSample0(LONGLONG star, LONGLONG end, BYTE* pB, LONG len)//視頻流1樣本輸出函數
{return 1; 
}int VideoSample1(LONGLONG star, LONGLONG end, BYTE* pB, LONG len)//視頻流2樣本輸出函數
{return 1; 
}int VideoSample2(LONGLONG star, LONGLONG end, BYTE* pB, LONG len)//視頻流3樣本輸出函數
{return 1; 
}int VideoSample3(LONGLONG star, LONGLONG end, BYTE* pB, LONG len)//視頻流4樣本輸出函數
{return 1; 
}int AudioSample0(LONGLONG star, LONGLONG end, BYTE* pB, LONG len)//音頻流1樣本輸出函數
{return 1; 
}int AudioSample1(LONGLONG star, LONGLONG end, BYTE* pB, LONG len)//音頻流2樣本輸出函數
{return 1; 
}int AudioSample2(LONGLONG star, LONGLONG end, BYTE* pB, LONG len)//音頻流3樣本輸出函數
{return 1; 
}int AudioSample3(LONGLONG star, LONGLONG end, BYTE* pB, LONG len)//音頻流4樣本輸出函數
{return 1; 
}CAP_INIT CapInit;CapInit.VideoSample0 = &VideoSample0;//為視頻,音頻源指定輸出函數CapInit.VideoSample1 = &VideoSample1;CapInit.VideoSample2 = &VideoSample2;CapInit.VideoSample3 = &VideoSample3;CapInit.AudioSample0 = &AudioSample0;CapInit.AudioSample1 = &AudioSample1;CapInit.AudioSample2 = &AudioSample2;CapInit.AudioSample3 = &AudioSample3;

捕獲視頻和音頻。
CAP_Init函數為每一個捕獲設備(接口為IMFMediaSource)創建1個源讀取器(接口為IMFSourceReader),并指定輸出媒體類型;
為每一個捕獲設備創建1個線程,在線程中使用源讀取器接口讀取樣本,反復調用CAP_INIT結構提供的樣本輸出函數輸出視頻和音頻樣本。

		CAP_VIDEO_INFO* pVInfo =  new CAP_VIDEO_INFO[4];//結構數組用于存儲視頻流,音頻流信息CAP_VIDEO_INFO* pAInfo = new CAP_AUDIO_INFO[4];WORD w = CAP_Init(CapInit, pVInfo, pAInfo);//獲取捕獲設備,創建視頻流,音頻流VCount = LOBYTE(w); //獲取視頻流數量ACount = HIBYTE(w);//獲取音頻流數量	

釋放所有獲取到的捕獲設備。
函數將終止所有捕獲線程,并釋放所有源讀取器接口。

		CAP_ReleaseDevice();

有關本插件的使用示例,可以看后續文章“Windows應用-音視頻捕獲”。

“捕獲”DLL的全部代碼

DLL.h

#pragma once
#include <SDKDDKVer.h>#define WIN32_LEAN_AND_MEAN             // 從 Windows 頭中排除極少使用的資料
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 構造函數將是顯式的
#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS         // 移除對話框中的 MFC 控件支持#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN            // 從 Windows 頭中排除極少使用的資料
#endif#include <afx.h>
#include <afxwin.h>         // MFC 核心組件和標準組件
#include <afxext.h>         // MFC 擴展
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>           // MFC 對 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>                     // MFC 對 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT// Windows 頭文件: 
#include <windows.h>#include "mfidl.h"
#include "mfapi.h"
#pragma comment(lib, "mfuuid")
#pragma comment(lib, "mf")
#pragma comment(lib, "mfplat")#include "mfreadwrite.h"
#pragma comment(lib, "mfreadwrite")#ifndef  SAFE_RELEASE
#define SAFE_RELEASEtemplate <class T> void SafeRelease(T** ppT)
{if (*ppT){(*ppT)->Release();*ppT = NULL;}
}#endif //SAFE_RELEASEtypedef int(__cdecl *MYPROC_Sample)(LONGLONG star, LONGLONG end, BYTE* pB, LONG len);struct CAP_INIT
{MYPROC_Sample VideoSample0 = NULL;//視頻樣本輸出函數MYPROC_Sample VideoSample1 = NULL;MYPROC_Sample VideoSample2 = NULL;MYPROC_Sample VideoSample3 = NULL;MYPROC_Sample AudioSample0 = NULL;//音頻樣本輸出函數MYPROC_Sample AudioSample1 = NULL;MYPROC_Sample AudioSample2 = NULL;MYPROC_Sample AudioSample3 = NULL;
};struct CAP_VIDEO_INFO
{UINT32 Width=0;//視頻寬,單位像素UINT32 Height=0;//視頻高,單位像素double nFrames=0;//幀率WCHAR Name[MAX_PATH];//視頻捕獲設備名稱
};struct CAP_AUDIO_INFO
{UINT32 nCh;//聲道數WCHAR Name[MAX_PATH];//音頻捕獲設備名稱
};class Capture
{
public:Capture();~Capture();CAP_INIT mInit;CAP_VIDEO_INFO mVideoInfo[4];HANDLE hEXIT = NULL;HANDLE hVThread[4];HANDLE hAThread[4];IMFSourceReader* pVideoReader[4];//視頻源讀取器指針數組IMFSourceReader* pAudioReader[4];//音頻源讀取器指針數組void GetDevice(int& mVideo, CAP_VIDEO_INFO* VideoInfo, int& mAudio, CAP_AUDIO_INFO* AudioInfo);//獲取前4個音頻,視頻捕獲設備void ReleaseDevice();//釋放捕獲的設備int Init(CAP_INIT init, CAP_VIDEO_INFO*& VideoInfo, CAP_AUDIO_INFO*& AudioInfo);//初始化捕獲設備
};struct PARAM
{Capture* pCapture = NULL;int index;
};

DLL.cpp

#include "DLL.h"Capture::Capture()
{HRESULT hr = MFStartup(MF_VERSION);hEXIT = CreateEvent(NULL, TRUE, FALSE, NULL);//創建“退出”事件。手動重置,初始無信號
}Capture::~Capture()
{CloseHandle(hEXIT);MFShutdown();
}DWORD WINAPI AudioThread(LPVOID lp);
DWORD WINAPI VideoThread(LPVOID lp);void Capture::GetDevice(int& mVideo, CAP_VIDEO_INFO* VideoInfo, int& mAudio, CAP_AUDIO_INFO* AudioInfo)//獲取捕獲設備
{HRESULT hr;IMFAttributes *pVideoAttributes = NULL;hr = MFCreateAttributes(&pVideoAttributes, 1);hr = pVideoAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);UINT32 countV;IMFActivate **ppVideoDevices = NULL;hr = MFEnumDeviceSources(pVideoAttributes, &ppVideoDevices, &countV);//枚舉視頻捕獲設備SafeRelease(&pVideoAttributes);if (countV > 4){for (int i = 4; i < (int)countV; i++)//釋放4個設備后面的設備{ppVideoDevices[i]->Release();}countV = 4;}mVideo = countV;for (DWORD i = 0; i < countV; i++)//獲取所有視頻源信息,為視頻源創建讀取樣本線程{hr = S_OK;WCHAR *szFriendlyName = NULL;UINT32 cchName;hr = ppVideoDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &szFriendlyName, &cchName); //獲取顯示名稱wmemset(VideoInfo[i].Name, 0, MAX_PATH);CopyMemory(VideoInfo[i].Name, szFriendlyName, 2 * (wcslen(szFriendlyName) + 1));CoTaskMemFree(szFriendlyName);IMFMediaSource *pSource = NULL;if (SUCCEEDED(hr)){hr = ppVideoDevices[i]->ActivateObject(IID_IMFMediaSource, (void**)&pSource);//激活對象}IMFAttributes* pIMFAttributes = NULL;if (SUCCEEDED(hr)){hr = MFCreateAttributes(&pIMFAttributes, 0);//創建空的屬性}if (SUCCEEDED(hr)){hr = pIMFAttributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, (UINT32)1);//使用基于硬件的媒體基礎轉換}if (SUCCEEDED(hr)){hr = pIMFAttributes->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, (UINT32)1);//允許源讀取器進行有限的視頻處理}hr = MFCreateSourceReaderFromMediaSource(pSource, pIMFAttributes, &pVideoReader[i]);//從媒體源創建源讀取器SafeRelease(&pIMFAttributes); SafeRelease(&pSource);IMFMediaType* pVideoMTV = NULL;if (SUCCEEDED(hr)){hr = MFCreateMediaType(&pVideoMTV);//創建空的媒體類型}if (SUCCEEDED(hr)){hr = pVideoMTV->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);//設置主要類型為視頻}if (SUCCEEDED(hr)){hr = pVideoMTV->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);//設置子類型RGB32}if (SUCCEEDED(hr)){hr = pVideoReader[i]->SetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, pVideoMTV);//設置源讀取器視頻輸出媒體類型}SafeRelease(&pVideoMTV);IMFMediaType* pMT = NULL;if (SUCCEEDED(hr)){hr = pVideoReader[i]->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pMT);//獲取源讀取器視頻輸出媒體類型。此時可以獲得完整的輸出媒體類型信息}UINT32 Width, Height;if (SUCCEEDED(hr)){hr = MFGetAttributeSize(pMT, MF_MT_FRAME_SIZE, &Width, &Height);//獲取視頻寬高VideoInfo[i].Width = Width; VideoInfo[i].Height = Height;}UINT32 Numerator, Denominator;if (SUCCEEDED(hr)){hr = MFGetAttributeRatio(pMT, MF_MT_FRAME_RATE, &Numerator, &Denominator);//獲取幀率VideoInfo[i].nFrames = (double)Numerator / (double)Denominator;}SafeRelease(&pMT);mVideoInfo[i] = VideoInfo[i];PARAM* pParam = new PARAM();pParam->index = i;pParam->pCapture = this;hVThread[i] = CreateThread(NULL, 0, VideoThread, pParam, 0, NULL);//為視頻源創建讀取線程}CoTaskMemFree(ppVideoDevices);//釋放視頻捕獲設備接口指針數組使用的內存IMFAttributes *pAudioAttributes = NULL;hr = MFCreateAttributes(&pAudioAttributes, 1);//創建空的屬性hr = pAudioAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID);UINT32 countA;IMFActivate **ppAudioDevices = NULL;hr = MFEnumDeviceSources(pAudioAttributes, &ppAudioDevices, &countA);//枚舉音頻捕獲設備SafeRelease(&pAudioAttributes);if (countA > 4){for (int i = 4; i < (int)countA; i++)//釋放4個設備后面的設備{ppAudioDevices[i]->Release();}countA = 4;}mAudio = countA;for (DWORD i = 0; i < countA; i++){hr = S_OK;WCHAR *szFriendlyName = NULL;UINT32 cchName;hr = ppAudioDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &szFriendlyName, &cchName); //獲取捕獲設備名稱wmemset(AudioInfo[i].Name, 0, MAX_PATH);CopyMemory(AudioInfo[i].Name, szFriendlyName, 2*(wcslen(szFriendlyName) + 1));CoTaskMemFree(szFriendlyName);IMFMediaSource *pSource = NULL;if (SUCCEEDED(hr)){hr = ppAudioDevices[i]->ActivateObject(IID_IMFMediaSource, (void**)&pSource);//激活對象}IMFAttributes* pIMFAttributes = NULL;if (SUCCEEDED(hr)){hr = MFCreateAttributes(&pIMFAttributes, 0);}if (SUCCEEDED(hr)){hr = pIMFAttributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, (UINT32)1);//使用基于硬件的媒體基礎轉換}if (SUCCEEDED(hr)){hr = pIMFAttributes->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, (UINT32)1);//允許源讀取器進行有限的視頻處理}if (SUCCEEDED(hr)){hr = MFCreateSourceReaderFromMediaSource(pSource, pIMFAttributes, &pAudioReader[i]);//從媒體源創建源讀取器}SafeRelease(&pIMFAttributes);SafeRelease(&pSource);IMFMediaType* pAudioMTA = NULL;if (SUCCEEDED(hr)){hr = MFCreateMediaType(&pAudioMTA);//創建空的媒體類型}if (SUCCEEDED(hr)){hr = pAudioMTA->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);//設置主要類型音頻}if (SUCCEEDED(hr)){hr = pAudioMTA->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);//設置子類型PCM}if (SUCCEEDED(hr)){hr = pAudioMTA->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, (UINT32)16);//設置樣本16位}if (SUCCEEDED(hr)){hr = pAudioMTA->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, (UINT32)48000);//設置樣本采樣率48000}if (SUCCEEDED(hr)){hr = pAudioReader[i]->SetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, NULL, pAudioMTA);//設置音頻輸出媒體類型(此時未提供媒體類型全部信息)}SafeRelease(&pAudioMTA);IMFMediaType* pMT = NULL;if (SUCCEEDED(hr)){hr = pAudioReader[i]->GetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, &pMT);//獲取音頻輸出媒體類型,此時可以得到完整的媒體類型信息}UINT32 nch;if (SUCCEEDED(hr)){hr = pMT->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &nch);//獲取聲道數AudioInfo[i].nCh = nch;}SafeRelease(&pMT);PARAM* pParam = new PARAM();pParam->index = i;pParam->pCapture = this;hAThread[i] = CreateThread(NULL, 0, AudioThread, pParam, 0, NULL);//為音頻源創建讀取線程}CoTaskMemFree(ppAudioDevices);//釋放音頻捕獲設備接口指針數組使用的內存
}DWORD WINAPI VideoThread(LPVOID lp)//視頻源讀取樣本線程共用函數
{PARAM* pParam = (PARAM*)lp;Capture* pCapture = pParam->pCapture;int index = pParam->index;HRESULT hr;IMFSourceReader* pIMFSourceReader = pCapture->pVideoReader[index];double dur = (double)10000000 / pCapture->mVideoInfo[index].nFrames;//計算1幀持續時間IMFSample* pMFSample = NULL; DWORD flags;
Agan:hr = pIMFSourceReader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, &flags, NULL, &pMFSample);//讀取視頻樣本if (hr == S_OK && pMFSample){LONGLONG Cur, Dur;hr = pMFSample->GetSampleTime(&Cur);//獲取顯示時間hr = pMFSample->GetSampleDuration(&Dur);//獲取持續時間DWORD Lt;hr = pMFSample->GetTotalLength(&Lt);//獲取有效長度DWORD count;hr = pMFSample->GetBufferCount(&count);//獲取緩沖區數量IMFMediaBuffer* pMFBuffer = NULL;if (count == 1)//如果只有1個緩沖區{hr = pMFSample->GetBufferByIndex(0, &pMFBuffer);}else//如果有多個緩沖區{hr = pMFSample->ConvertToContiguousBuffer(&pMFBuffer);}BYTE* pSB = NULL;hr = pMFBuffer->Lock(&pSB, NULL, NULL);//鎖定緩沖區switch (index){case 0://第1個視頻源pCapture->mInit.VideoSample0(Cur, Cur + Dur, pSB, (LONG)Lt);//發送樣本break;case 1://第2個pCapture->mInit.VideoSample1(Cur, Cur + Dur, pSB, (LONG)Lt);break;case 2:pCapture->mInit.VideoSample2(Cur, Cur + Dur, pSB, (LONG)Lt);break;case 3:pCapture->mInit.VideoSample3(Cur, Cur + Dur, pSB, (LONG)Lt);break;}hr = pMFBuffer->Unlock();//解鎖緩沖區SafeRelease(&pMFBuffer); SafeRelease(&pMFSample);//釋放接口}DWORD mExit = WaitForSingleObject(pCapture->hEXIT, 0);if (mExit == WAIT_OBJECT_0)//有“退出”信號{delete pParam;return 0;}goto Agan;
}DWORD WINAPI AudioThread(LPVOID lp)//讀取音頻源樣本線程共用函數
{PARAM* pParam = (PARAM*)lp;Capture* pCapture = pParam->pCapture;int index = pParam->index;HRESULT hr;IMFSourceReader* pIMFSourceReader = pCapture->pAudioReader[index];IMFSample* pMFSample = NULL; DWORD flags;
Agan:hr = pIMFSourceReader->ReadSample(MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, &flags, NULL, &pMFSample);//讀取音頻樣本if (hr == S_OK && pMFSample){LONGLONG Cur, Dur;hr = pMFSample->GetSampleTime(&Cur);//獲取顯示時間hr = pMFSample->GetSampleDuration(&Dur);//獲取持續時間DWORD Lt;hr = pMFSample->GetTotalLength(&Lt);//獲取有效長度DWORD count;hr = pMFSample->GetBufferCount(&count);//獲取緩沖區數量IMFMediaBuffer* pMFBuffer = NULL;if (count == 1)//如果只有1個緩沖區{hr = pMFSample->GetBufferByIndex(0, &pMFBuffer);}else//如果有多個緩沖區{hr = pMFSample->ConvertToContiguousBuffer(&pMFBuffer);}BYTE* pSB = NULL;hr = pMFBuffer->Lock(&pSB, NULL, NULL);//鎖定緩沖區switch (index){case 0://第1個音頻源pCapture->mInit.AudioSample0(Cur, Cur + Dur, pSB, (LONG)Lt);//發送樣本break;case 1://第2個pCapture->mInit.AudioSample1(Cur, Cur + Dur, pSB, (LONG)Lt);break;case 2:pCapture->mInit.AudioSample2(Cur, Cur + Dur, pSB, (LONG)Lt);break;case 3:pCapture->mInit.AudioSample3(Cur, Cur + Dur, pSB, (LONG)Lt);break;}hr = pMFBuffer->Unlock();//解鎖緩沖區SafeRelease(&pMFBuffer); SafeRelease(&pMFSample);//釋放接口}DWORD mExit = WaitForSingleObject(pCapture->hEXIT, 0);if (mExit == WAIT_OBJECT_0)//有“退出”信號{delete pParam;return 0;}goto Agan;
}void Capture::ReleaseDevice()
{SetEvent(hEXIT);//發送“退出”信號WaitForMultipleObjects(4, hVThread, TRUE, INFINITE);//等待所有線程退出WaitForMultipleObjects(4, hAThread, TRUE, INFINITE);for (int i = 0; i < 4; i++)//釋放所有視頻音頻源讀取器接口{SafeRelease(&pVideoReader[i]); SafeRelease(&pAudioReader[i]);}
}int Capture::Init(CAP_INIT init, CAP_VIDEO_INFO*& VideoInfo, CAP_AUDIO_INFO*& AudioInfo)
{mInit = init;ResetEvent(hEXIT);//設置“退出”無信號int mV, mA;GetDevice(mV,VideoInfo, mA,AudioInfo);//獲取前4個音頻,視頻捕獲設備return (int)MAKEWORD((BYTE)mA, (BYTE)mV);
}Capture mCapture;#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif__declspec(dllexport) int __cdecl Init(CAP_INIT init, CAP_VIDEO_INFO*& VideoInfo, CAP_AUDIO_INFO*& AudioInfo)//最多獲取前4個視頻音頻捕獲設備{return mCapture.Init(init, VideoInfo, AudioInfo);}__declspec(dllexport) int __cdecl ReleaseDevice()//釋放獲取到的捕獲設備{mCapture.ReleaseDevice();return 0;}#ifdef __cplusplus
}
#endif

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81451.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81451.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81451.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ios打包ipa獲取證書和打包創建經驗分享

在云打包或本地打包ios應用&#xff0c;打包成ipa格式的app文件的過程中&#xff0c;私鑰證書和profile文件是必須的。 其實打包的過程并不難&#xff0c;因為像hbuilderx這些打包工具&#xff0c;只要你輸入的是正確的證書&#xff0c;打包就肯定會成功。因此&#xff0c;證書…

CycleISP: Real Image Restoration via Improved Data Synthesis通過改進數據合成實現真實圖像恢復

摘要 大規模數據集的可用性極大釋放了深度卷積神經網絡(CNN)的潛力。然而,針對單圖像去噪問題,獲取真實數據集成本高昂且流程繁瑣。因此,圖像去噪算法主要基于合成數據開發與評估,這些數據通常通過廣泛假設的加性高斯白噪聲(AWGN)生成。盡管CNN在合成數據集上表現優異…

《Python星球日記》 第70天:Seq2Seq 與Transformer Decoder

名人說:路漫漫其修遠兮,吾將上下而求索。—— 屈原《離騷》 創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder??) 目錄 一、Seq2Seq模型基礎1. 什么是Seq2Seq模型?2. Encoder-Decoder架構詳解1??編碼器(Encoder)2??解碼器(Decoder)3. 傳統Seq2Seq模型的局限性…

Android 性能優化入門(二)—— 內存優化

1、概述 1.1 Java 對象的生命周期 各狀態含義&#xff1a; 創建&#xff1a;分配內存空間并調用構造方法應用&#xff1a;使用中&#xff0c;處于被強引用持有&#xff08;至少一個&#xff09;的狀態不可見&#xff1a;不被強引用持有&#xff0c;應用程序已經不再使用該對象…

GCC 版本與C++ 標準對應關系

GCC 版本 與支持的 C 標準&#xff08;C11、C14、C17、C20、C23&#xff09; 的對應關系 GCC 版本與 C 標準支持對照表 GCC 版本默認 C 標準C11C14C17C20C23GCC 4.8C98? (部分支持)????GCC 4.9C98? (完整支持)????GCC 5.1C98?? (完整支持)???GCC 6.1C14??? …

5、事務和limit補充

一、事務【都是重點】 1、了解 一個事務其實就是一個完整的業務邏輯。 要么同時發生&#xff0c;要么同時結束。 是一個最小的工作單元。 不可再分。 看這個視頻&#xff0c;黑馬的&#xff0c;4分鐘多點就能理解到 可以理解成&#xff1a; 開始事務-----如果中間拋出異常…

一套基于 Bootstrap 和 .NET Blazor 的開源企業級組件庫

前言 今天大姚給大家分享一套基于 Bootstrap 和 .NET Blazor 的開源企業級組件庫&#xff1a;Bootstrap Blazor。 項目介紹 BootstrapBlazor 是一套基于 Bootstrap 和 Blazor 的開源&#xff08;Apache License&#xff09;、企業級組件庫&#xff0c;無縫整合了 Bootstrap …

mac-M系列芯片安裝軟件報錯:***已損壞,無法打開。推出磁盤問題

因為你安裝的軟件在Intel 或arm芯片的mac上沒有簽名導致。 首先打開任何來源操作 在系統設置中配置&#xff0c;如下圖&#xff1a; 2. 然后打開終端&#xff0c;輸入&#xff1a; sudo spctl --master-disable然后輸入電腦鎖屏密碼 打開了任何來源&#xff0c;還遇到已損壞…

RK3568-鴻蒙5.1與原生固件-扇區對比分析

編譯生成的固件目錄地址 ../openharmony/out/rk3568/packages/phone/images鴻蒙OS RK3568固件分析 通過查看提供的信息&#xff0c;分析RK3568開發板固件的各個組件及其用途&#xff1a; 主要固件組件 根據終端輸出的文件列表&#xff0c;RK3568固件包含以下關鍵組件&#x…

Java正則表達式:從基礎到高級應用全解析

Java正則表達式應用與知識點詳解 一、正則表達式基礎概念 正則表達式(Regular Expression)是通過特定語法規則描述字符串模式的工具&#xff0c;常用于&#xff1a; 數據格式驗證文本搜索與替換字符串分割模式匹配提取 Java通過java.util.regex包提供支持&#xff0c;核心類…

進程間通信--信號量【Linux操作系統】

文章目錄 并發編程相關基礎概念信號量深刻理解信號量使用共享資源的方式分塊使用共享資源的方式會出現的問題舉例子理解信號量的第二個特性---預定信號量要成為計數器面臨的問題 信號量相關操作接口--POSIX庫函數&#xff1a;sem_init庫函數&#xff1a;sem_destroy庫函數&…

謝賽寧團隊提出 BLIP3-o:融合自回歸與擴散模型的統一多模態架構,開創CLIP特征驅動的圖像理解與生成新范式

BLIP3-o 是一個統一的多模態模型&#xff0c;它將自回歸模型的推理和指令遵循優勢與擴散模型的生成能力相結合。與之前擴散 VAE 特征或原始像素的研究不同&#xff0c;BLIP3-o 擴散了語義豐富的CLIP 圖像特征&#xff0c;從而為圖像理解和生成構建了強大而高效的架構。 此外還…

HarmonyOs開發之——— ArkWeb 實戰指南

HarmonyOs開發之——— ArkWeb 實戰指南 謝謝關注!! 前言:上一篇文章主要介紹HarmonyOs開發之———合理使用動畫與轉場:CSDN 博客鏈接 一、ArkWeb 組件基礎與生命周期管理 1.1 Web 組件核心能力概述 ArkWeb 的Web組件支持加載本地或在線網頁,提供完整的生命周期回調體…

黑馬程序員C++2024版筆記 第0章 C++入門

1.C代碼的基礎結構 以hello_world代碼為例&#xff1a; 預處理指令 #include<iostream> using namespace std; 代碼前2行是預處理指令&#xff0c;即代碼編譯前的準備工作。&#xff08;編譯是將源代碼轉化為可執行程序.exe文件的過程&#xff09; 主函數 主函數是…

日語學習-日語知識點小記-構建基礎-JLPT-N4階段(22):復習

日語學習-日語知識點小記-構建基礎-JLPT-N4階段(22):復習 1、前言(1)情況說明(2)工程師的信仰2、知識點(1)復習(2)復習3、單詞(1)日語(2)日語片假名單詞4、對話練習5、單詞辨析記錄6、總結1、前言 (1)情況說明 自己在今年,在日本留學中,目前在語言學校,…

Docker配置SRS服務器 ,ffmpeg使用rtmp協議推流+vlc拉流

目錄 演示視頻 前期配置 Docker配置 ffmpeg配置 vlc配置 下載并運行 SRS 服務 推拉流流程實現 演示視頻 2025-05-18 21-48-01 前期配置 Docker配置 運行 SRS 建議使用 Docker 配置 Docker 請移步&#xff1a; 一篇就夠&#xff01;Windows上Docker Desktop安裝 漢化完整指…

Redis——緩存雪崩、擊穿、穿透

緩存雪崩 大量緩存數據在同一時間過期或者Redis故障宕機時&#xff0c;若此時有大量請求&#xff0c;都會直接訪問到數據庫&#xff0c;導致數據庫壓力倍增甚至宕機。 大量數據同時過期解決方案&#xff1a; 1、均勻設置過期時間&#xff1a; 設置過期時間的時候可以追加一…

開源GPU架構RISC-V VCIX的深度學習潛力測試:從RTL仿真到MNIST實戰

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生專屬優惠。 一、開篇&#xff1a;AI芯片架構演變的三重挑戰 &#xff08;引述TPUv4采用RISC-V的行業案…

字符串相乘(43)

43. 字符串相乘 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:string multiply(string num1, string num2) {string res "0";for (int i 0; i < num2.size(); i) {string str multiplyOneNum(num1, num2[num2.size() -…

mathematics-2024《Graph Convolutional Network for Image Restoration: A Survey》

推薦深藍學院的《深度神經網絡加速&#xff1a;cuDNN 與 TensorRT》&#xff0c;課程面向就業&#xff0c;細致講解CUDA運算的理論支撐與實踐&#xff0c;學完可以系統化掌握CUDA基礎編程知識以及TensorRT實戰&#xff0c;并且能夠利用GPU開發高性能、高并發的軟件系統&#xf…