Qt加SDL示例开发指南


渲染BMP

#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>

int main(int argc, char *argv[])
{
	SDL_Surface *screen;
	SDL_Surface *loadbmp;
	SDL_Event event;
	SDL_Rect* SRCrect=0;
	SDL_Rect* DSTrect=0;
	int isRun=1;
	SDL_Init(SDL_INIT_VIDEO);
	screen=SDL_SetVideoMode(400, 400, 32, SDL_SWSURFACE);
	loadbmp=SDL_LoadBMP("sample.bmp");
	SDL_BlitSurface(loadbmp,SRCrect,screen,DSTrect);
	SDL_Flip(screen);
	while(isRun)
	{
		SDL_WaitEvent(&event);
		switch (event.type)
		{
			case SDL_QUIT:
				isRun=0;
				break;
		}
	}
	SDL_FreeSurface(screen);
	SDL_FreeSurface(loadbmp);
	return(0);
}


渲染YUV

#include <iostream>  
#include <fstream>  
#include "SDL.h"  
#include <windows.h>  
#pragma comment(lib, "SDL.lib")  
#pragma comment(lib, "SDLmain.lib")  
using namespace std;  
void useage();  
bool flip( unsigned char * src, int width, int height);  
    SDL_Surface *pscreen;  
    SDL_Overlay *poverlay;  
int main(int argc, char **argv)  
{  
    if(argc != 4)  
    {  
        useage();  
        return 1;  
    }  
    int readsize;  
    int width = 0, height = 0;  
    width = atoi(argv[2]);  
    height = atoi(argv[3]);  
    readsize = width * height *3 /2;  
    unsigned char *yuvframe = new unsigned char[readsize];  
    cout << "2010.12.12  显示 yuv 420的程序" << endl;  
    cout << "open "<< argv[1] <<": "<< width <<" x " << height << endl;  
    cout << "readsize: " << readsize << endl;  
    atexit(SDL_Quit);  
  
    //初始化SDL子系统  
    if(SDL_Init(SDL_INIT_VIDEO) < 0)  
    {  
        cout << "Unable to init SDL:" << SDL_GetError() << endl;  
        system("pause");  
        exit(1);  
    }  
    pscreen = SDL_SetVideoMode(width, height,24, SDL_SWSURFACE);  
    if(pscreen == NULL)  
    {  
        cout << "error at setvideomode" << endl;  
    }  
    poverlay = SDL_CreateYUVOverlay(width,height,SDL_YV12_OVERLAY,pscreen);  
    if(poverlay == NULL)  
    {  
        cout << "error at ppoverlay" << endl;  
    }  
    //打开文件  
    FILE *fyuv;  
    fyuv = fopen(argv[1],"rb");  
    if(fyuv == NULL)  
    {  
        cout << "can not open "<< argv[1] << endl;  
        return -1;  
    }  
    while(true)  
    {  
        //读取yuv数据  
        int rsize = fread(yuvframe,sizeof(char), readsize,fyuv);  
        if(rsize > 0)  
        {  
            static int num =0;  
            num ++;  
            flip(yuvframe, width, height);    
            char pnum[10];  
            sprintf(pnum,"#%d",num);  
            SDL_WM_SetCaption(pnum,NULL);  
        }  
        SDL_Delay(40);  
        //SDL事件处理  
        SDL_Event sdl_event;  
        while(SDL_PollEvent(&sdl_event))  
        {  
            switch(sdl_event.type)        
            {  
            case SDL_KEYDOWN:  
                break;  
            case SDL_KEYUP:  
                if(sdl_event.key.keysym.sym == SDLK_q)  
                {  
                    return 0;  
                }  
                break;  
            case SDL_QUIT:  
                return 0;  
            default:  
                break;  
            }  
        }     
    }  
    return 0;  
}  
void useage()  
{  
    cout << "play_yuv420 yuvfilename width height /n" << endl;  
}  
//显示(弹出flip)screen surface到屏幕上   
bool flip( unsigned char * src, int width, int height)   
{   
    unsigned char  *outy,*outu,*outv,*out_buffer,*op[3];  
    SDL_Rect rect;  
    rect.w = width;  
    rect.h = height;  
    rect.x = 0;  
    rect.y = 0;  
    out_buffer = src;  
    SDL_LockSurface(pscreen);  
    SDL_LockYUVOverlay(poverlay);  
    outy = out_buffer;  
    outu = out_buffer+width*height*5/4;  
    outv = out_buffer+width*height;  
    for(int y=0;y<pscreen->h && y<poverlay->h;y++)  
    {  
        op[0]=poverlay->pixels[0]+poverlay->pitches[0]*y;  
        op[1]=poverlay->pixels[1]+poverlay->pitches[1]*(y/2);  
        op[2]=poverlay->pixels[2]+poverlay->pitches[2]*(y/2);     
        memcpy(op[0],outy+y*width,width);  
        if(y%2 == 0)  
        {  
            memcpy(op[1],outu+width/2*y/2,width/2);  
            memcpy(op[2],outv+width/2*y/2,width/2);     
        }  
    }  
    SDL_UnlockYUVOverlay(poverlay);  
    SDL_UnlockSurface(pscreen);         
    SDL_DisplayYUVOverlay(poverlay, &rect);  
    return 0;  
} 









/*--------------------------------------------------------
 *
 * 			QThread Demo
 *
 * 		Copyright (C) 2010, dbzhang800
 * 		modified by leoluopy 2014
 * 		email: leoluopy@gmail.com
 *		 All rights reserved.
 *
 --------------------------------------------------------*/

	#include <QtCore/QCoreApplication>
	#include <QtCore/QObject>
	#include <QtCore/QThread>
	#include <QtCore/QDebug>

class Dummy:public QObject
{
	Q_OBJECT
public:
	Dummy(){}
public slots:
	void emitsig()
	{
		emit sig();
	}
signals:
	void sig();
};


class Thread:public QThread
{
	Q_OBJECT
public:
	Thread(QObject* parent=0)
	:QThread(parent),m_slot_called_num(0)
	{
		//moveToThread(this);
	}
public slots:
	void slot_main()
	{
		qDebug()<<"from thread slot_main:" <<currentThreadId();
		printf("slots_called_num:%d\n",m_slot_called_num);
		m_slot_called_num++;
	}
private:
	unsigned int m_slot_called_num ;
protected:
	void run()
	{
		qDebug()<<"thread thread:"<<currentThreadId();
		exec();
	}
};

	#include "main.moc"
	//generate cmd: moc -o main.moc main.cpp

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);
	qDebug()<<"main thread:"<<QThread::currentThreadId();

	Thread thread;
	Dummy dummy;

	QObject::connect(&dummy, SIGNAL(sig()), &thread, SLOT(slot_main()));

	thread.start();
	dummy.emitsig();
	dummy.emitsig();
	dummy.emitsig();

	return a.exec();
}


SDL展示封装类:

SDL_Displayer_c::SDL_Displayer_c()
{

}
SDL_Displayer_c::~SDL_Displayer_c()
{

}
void SDL_Displayer_c::InitEnv(int WindowWidth,int WindowHeight,int layer_width,int layer_height,long WinID)
{

	// We could get a resize event at any time, so clean previous mode
	SDL_QuitSubSystem(SDL_INIT_VIDEO);

	/*set sdl env*/
	char variable[64];
	#ifdef Q_OS_WIN
	sprintf(variable, "SDL_WINDOWID=0x%lx", frame_pre->winId());
	#else
	sprintf(variable, "SDL_WINDOWID=0x%lx", WinID);
	#endif
	putenv(variable);
	printf("SDL env variable : %s\n",variable);

	if ( SDL_InitSubSystem(SDL_INIT_VIDEO) < 0 ) {
		fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
		return;
	}
	pscreen = SDL_SetVideoMode(WindowWidth, WindowHeight,24, SDL_SWSURFACE);
	if ( ! pscreen ) {
		fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
		return;
	}
	printf("SDL Video Window Set OK !\n");


	poverlay = SDL_CreateYUVOverlay(layer_width,layer_height,SDL_YV12_OVERLAY,pscreen);
	if(poverlay == NULL){
		printf("error at ppoverlay");
		return ;
	}
}
int SDL_Displayer_c::flip( unsigned char * src, int width, int height,int display_x,int display_y)
{
	unsigned char  *outy,*outu,*outv,*out_buffer,*op[3];int y=0 ;
	SDL_Rect rect;
	rect.w = width;
	rect.h = height;
	rect.x = display_x;
	rect.y = display_y;
	out_buffer = src;
	SDL_LockSurface(pscreen);
	SDL_LockYUVOverlay(poverlay);
	outy = out_buffer;
	outu = out_buffer+width*height*5/4;
	outv = out_buffer+width*height;
	for( y=0;y<pscreen->h && y<poverlay->h;y++)
	{
		op[0]=poverlay->pixels[0]+poverlay->pitches[0]*y;
		op[1]=poverlay->pixels[1]+poverlay->pitches[1]*(y/2);
		op[2]=poverlay->pixels[2]+poverlay->pitches[2]*(y/2);
		memcpy(op[0],outy+y*width,width);
		if(y%2 == 0)
		{
			memcpy(op[1],outu+width/2*y/2,width/2);
			memcpy(op[2],outv+width/2*y/2,width/2);
		}
	}
	SDL_UnlockYUVOverlay(poverlay);
	SDL_UnlockSurface(pscreen);
	SDL_DisplayYUVOverlay(poverlay, &rect);

	return 0;
}
void SDL_Displayer_c::sdl_play(unsigned int width,unsigned int height,int display_x,int display_y,long WinID)
{
//	int readsize;
//	int width = 0, height = 0;
//	width = 176;
//	height =144;
//	readsize = width * height *3 /2;
//	unsigned char *yuvframe = (unsigned char*)malloc(readsize);
//	//打开文件
//	FILE *fyuv;
//	fyuv = fopen("./resource/raw/BUS_176x144_15_avc_96.yuv","rb");
//	if(fyuv == NULL)
//	{
//		fyuv = fopen("../resource/raw/BUS_176x144_15_avc_96.yuv","rb");
//		if(fyuv == NULL){
//			printf("can't load yuv file\n");
//			exit(1);
//		}
//	}
//	//读取yuv数据
//	while(fread(yuvframe,sizeof(char), readsize,fyuv)){
//		static int num =0;
//		num ++;
//		flip(yuvframe, width, height,display_x,display_y);
//		char pnum[10];
//		sprintf(pnum,"#%d",num);
//		SDL_WM_SetCaption(pnum,NULL);
//		SDL_Delay(40);
//	}
		static int num =0;
		num ++;
		flip(dummy.ImgBuf, width, height,display_x,display_y);
		char pnum[10];
		sprintf(pnum,"#%d",num);
		SDL_WM_SetCaption(pnum,NULL);
}

头文件:

	#include <SDL/SDL.h>

class SDL_Displayer_c
{
public:
		SDL_Displayer_c();
		void InitEnv(int WindowWidth,int WindowHeight,int layer_width,int layer_height,long WinID);
		int flip( unsigned char * src, int width, int height,int display_x,int display_y);
		void sdl_play(unsigned int width,unsigned int height,int display_x,int display_y,long WinID);
		~SDL_Displayer_c();
private:
		SDL_Surface *pscreen;
		SDL_Overlay *poverlay;
protected:
};




Qmessage弹出的提示消息:

		int ret = QMessageBox::warning(this, tr("Application"),  tr("The document has been modified. ""Do you want to save your changes?"),
				QMessageBox::Yes | QMessageBox::Default, QMessageBox::No,   QMessageBox::Cancel | QMessageBox::Escape);



参考文章:

Qthread与QObject

http://blog.csdn.net/sydnash/article/details/7425947

yuv播放SDL:

http://blog.csdn.net/pafone/article/details/6072711

qt嵌入SDL:

http://mobile.51cto.com/symbian-271066.htm

qt关闭事件捕捉:

http://no001.blog.51cto.com/1142339/282807

Qt线程基础:

http://blog.csdn.net/dbzhang800/article/details/6554104

Qt中关于undefined reference to `vtable for故障总结

http://www.cnblogs.com/qianyuming/archive/2011/03/09/1978910.html

QMessage的示例消息:

http://blog.const.net.cn/a/8744.htm

Qt布局管理器:

http://my.oschina.net/laopiao/blog/83851

SDL中YUV任意尺寸缩放

http://hi.baidu.com/deyaliu/item/5d40bb993e5f84d67b7f019d

数字图像插值算法

http://blog.csdn.net/qiqi5521/article/details/2207562

使用ffmpeg进行图像格式转换及缩放

http://blog.csdn.net/skys_broyal/article/details/10337147

AVFrame和AVPicture对比:

http://yul100887.blog.163.com/blog/static/200336135201211143525930/

Qt初始化最大窗口:

http://www.cnblogs.com/qq78292959/archive/2012/08/12/2634298.html

捕捉窗体变化信号:

http://www.myexception.cn/qt/555086.html

Boost线程管理:

http://www.cnblogs.com/tears-of-ramos/archive/2013/01/21/2870367.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值