參考了csdn上Win32Project1_ffmpeg_dxva2這個例子,很不錯,直接就可以運行。
但是,有幾個問題:
1、窗口無法正常縮放,縮放後,圖像大小並沒有一起縮放
2、H265的編碼格式,顯示下面有一塊綠色。
3、無法從顯卡獲取YUV420P數據或者NV12數據
3、找了很久網上也沒有相關代碼實現從顯卡獲取數據到內存(有些方法相當慢,基本無法使用!)
第3個問題,萬能的網絡變得不再萬能,基本都是無解,要麼實現不了,要麼速度慢:
這個相當於是從顯存直接複製到內存,如果速度慢了,就失去意義了,因爲硬件解碼的目的就是減少CPU佔用和提升解碼實時性。
其實,ffmpeg就自帶了一個函數的,這個函數速度還是比較快的,對了,就是這個函數
av_image_copy_uc_from
只是大家都不會用而已,直接貼代碼:
static int Extract(AVCodecContext *va, AVFrame *src, AVFrame *dst,CCacheBuffer *cache )
{
BYTE *pNV12=new BYTE[va->width*va->height*4];
int width;
int height;
int pitch;
int format;
int surfaceDesc_Height;
void *pSourceFrame;
D3DLOCKED_RECT lock;
DWORD dwTime1=::GetTickCount();
LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)src->data[3];
D3DSURFACE_DESC surfaceDesc;
IDirect3DSurface9_GetDesc(d3d, &surfaceDesc);
if (!dst->data[0])
{
delete []pNV12;
return -1;
}
width=surfaceDesc.Width;
height=surfaceDesc.Height;
format=surfaceDesc.Format;
if ( format == MAKEFOURCC('N', 'V', '1', '2') )
{
height = 3 * height / 2; // FULL Y, SUBSAMPLED UV PLANES
}
dwTime1=::GetTickCount();
if (FAILED(IDirect3DSurface9_LockRect(d3d, &lock, NULL, D3DLOCK_READONLY)))
{
delete []pNV12;
return -1;
}
pSourceFrame = lock.pBits;
pitch = lock.Pitch;
surfaceDesc_Height=surfaceDesc.Height;
uint8_t *plane[2] = {
( uint8_t *) lock.pBits,
(uint8_t*)lock.pBits + lock.Pitch * surfaceDesc.Height
};
const uint8_t *source[4]={( uint8_t *)lock.pBits,( uint8_t *)lock.pBits + lock.Pitch * surfaceDesc.Height,0,0};
int linesize_source[4]={lock.Pitch,lock.Pitch,0,0};
uint8_t *dest[4]={( uint8_t *)pNV12,( uint8_t *)pNV12+lock.Pitch * surfaceDesc.Height,0,0};
int linesize_dest[4]={lock.Pitch,lock.Pitch,0,0};
av_image_copy_uc_from(dest,linesize_dest,source,linesize_source,AV_PIX_FMT_NV12,va->width,va->height)
IDirect3DSurface9_UnlockRect(d3d);
libyuv::NV12ToI420(pNV12,pitch,pNV12+pitch*surfaceDesc_Height,pitch,dst->data[0],va->width,dst->data[1],va->width/2,dst->data[2],va->width/2,va->width,va->height);
//TRACE("時間:%d\n",::GetTickCount()-dwTime1);
delete []pNV12;
return 0;
}
實驗了下,已經相當快了!打開一個4K視頻,一幀花的時間平均不到30ms。1080P或者更低分辨率肯定是更沒問題的。
好了,謝謝大家!本人QQ35744025,對音視頻有些研究,需要合作交流的,歡迎騷擾!