您的位置:首页 > 其它

MFC利用SDL 绘制FFMPEG AVFrame 绘制YUV420P

2014-04-04 14:42 411 查看
代码比较简单

class SDLDraw{
private:
SDL_Window * pWindow;
SDL_Rect m_DrawRect;
SDL_Renderer * pRender;
SDL_Texture * pTexture;
HWND m_hWnd;
int m_Width;
int m_Height;
public:
SDLDraw();
~SDLDraw();
void Init(HWND hWnd);
void Destory();
void Draw(AVFrame* frame);
void Clear();

};


#define Y_BLACK	0
#define U_BLACK	128
#define V_BLACK	128
#pragma comment(lib, "SDL2.lib")
SDLDraw::SDLDraw(){
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);
pWindow=NULL;
pRender=NULL;
pTexture=NULL;
}
SDLDraw::~SDLDraw(){
Destory();
}
void SDLDraw::Init(HWND hWnd){
LONG_PTR WinMessage= (LONG_PTR)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
pWindow = SDL_CreateWindowFrom(hWnd );
SetWindowLongPtr(hWnd, GWLP_WNDPROC,  WinMessage);
m_DrawRect.x=0;
m_DrawRect.y=0;
int iWidth = 0;
int iHeight = 0;
SDL_GetWindowSize( pWindow, &iWidth, &iHeight );
m_DrawRect.w=iWidth;
m_DrawRect.h=iHeight;
pRender = SDL_CreateRenderer( pWindow,-1, SDL_RENDERER_TARGETTEXTURE );
m_Width=176;
m_Height=144;
m_hWnd=hWnd;
}
void SDLDraw::Destory(){
if ( pTexture != NULL )
{
SDL_DestroyTexture( pTexture );
pTexture = NULL    ;
}

if ( pRender != NULL )
{
SDL_DestroyRenderer( pRender );
pRender = NULL;
}
if ( NULL != pWindow )
{
SDL_DestroyWindow( pWindow );
pWindow = NULL;
}
}
void SDLDraw::Draw(AVFrame* frame){
if(!pWindow) return;
if(!frame) return;
int nWidth=frame->width;
int nHeight=frame->height;
if(nWidth!=m_Width||nHeight!=m_Height){
if ( pTexture != NULL )
{
SDL_DestroyTexture( pTexture );
pTexture = NULL    ;
}
}
m_Width=nWidth;
m_Height=nHeight;
if(!pTexture){
pTexture = SDL_CreateTexture( pRender,SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, nWidth, nHeight );
}
int iPitch = m_Width*SDL_BYTESPERPIXEL(SDL_PIXELFORMAT_YV12);
VideoConvter convert((AVPixelFormat)frame->format,PIX_FMT_YUV420P,nWidth,nHeight,nWidth,nHeight);
if(convert.Convert(frame)>=0){
const AVFrame* cframe=convert.GetFrame();
SDL_UpdateTexture( pTexture,NULL, cframe->data[0], iPitch );
}
SDL_RenderClear( pRender );
SDL_Rect sdlRT;
sdlRT.x = 0;
sdlRT.y = 0;
sdlRT.h = nHeight;
sdlRT.w = nWidth;
SDL_RenderCopy( pRender, pTexture, &sdlRT, &m_DrawRect );
SDL_RenderPresent( pRender );
}

void SDLDraw::Clear(){
int size=avpicture_get_size ((AVPixelFormat) PIX_FMT_YUV420P, m_DrawRect.w,m_DrawRect.h);
uint8_t* yuvBuffer=(uint8_t*) av_malloc(size);
AVFrame* pFrame = av_frame_alloc();
if (pFrame&&avpicture_fill((AVPicture*) pFrame, yuvBuffer, PIX_FMT_YUV420P, m_DrawRect.w,m_DrawRect.h)>= 0) {
pFrame->width =  m_DrawRect.w;
pFrame->height = m_DrawRect.h;
pFrame->format = PIX_FMT_YUV420P;
memset(pFrame->data[0],Y_BLACK,pFrame->linesize[0]* m_DrawRect.h);
memset(pFrame->data[1],U_BLACK,pFrame->linesize[1]* (m_DrawRect.h>>1));
memset(pFrame->data[2],V_BLACK,pFrame->linesize[2]* (m_DrawRect.h>>1));
}
Draw(pFrame);
if(pFrame){
av_frame_free(&pFrame);
}
av_free(yuvBuffer);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: