sdl_sdlc - CSDN
sdl 订阅
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。 展开全文
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
信息
外文名
SDL
广泛的用于
许多著名的游戏
性    质
开放源代码的跨平台多媒体开发库
全    称
Simple DirectMedia Layer
SDL简介
SDL(Simple DirectMedia Layer)被广泛的用于许多著名的游戏。最著名的游戏是赢得Linux组游戏开发大奖的 文明:权利的召唤(Civilization: Call To Power)。SDL的作者是Sam Lantinga, Loki Entertainment Software的主力程序员(Lead Programmer)。
收起全文
精华内容
参与话题
  • SDL介绍

    万次阅读 多人点赞 2013-11-16 11:05:05
    SDL库的作用说白了就是封装了复杂的视音频底层操作,简化了视音频处理的难度。 以下转自WiKi: SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、...

    SDL库的作用说白了就是封装了复杂的视音频底层操作,简化了视音频处理的难度。

    以下转自WiKi:


    SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
    SDL使用GNU宽通用公共许可证为授权方式,意指动态链接(dynamic link)其库并不需要开放本身的源代码。因此诸如《雷神之锤4》等商业游戏也使用SDL来开发。


    结构
    虽然SDL时常被比较为‘跨平台的DirectX’,然而事实上SDL是定位成以精简的方式来完成基础的功能,它大幅度简化了控制图像、声音、输出入等工作所需撰写的代码。但更高级的绘图功能或是音效功能则需搭配OpenGL和OpenAL等API来达成。另外它本身也没有方便创建图形用户界面的函数。
    SDL在结构上是将不同操作系统的库再包装成相同的函数,例如SDL在Windows平台上其实是DirectX的再包装,旧版本包装的是DirectX 5,现时的版本(SDL 1.2)则是DirectX 7。而在使用X11的平台上(包括Linux),SDL则是与Xlib库沟通来输出图像。
    虽然SDL本身是使用C语言写成,但是它几乎可以被所有的编程语言所使用,例如:C++、Perl、Python(借由pygame库)、Pascal等等,甚至是Euphoria、Pliant这类较不流行的编程语言也都可行。
    SDL库分为 Video、Audio、CD-ROM、Joystick 和 Timer 等若干子系统,除此之外,还有一些单独的官方扩充函数库。这些库由官方网站提供,并包含在官方文档中,共同组成了SDL的“标准库”:
    SDL_image—支持时下流行的图像格式:BMP、PPM、XPM、 PCX、GIF、JPEG、PNG、TGA。
    SDL_mixer—更多的声音输出函数以及更多的声音格式支持。
    SDL_net—网络支持。
    SDL_ttf—TrueType字体渲染支持。
    SDL_rtf—简单的RTF渲染支持。


    子系统
    SDL将功能分成下列数个子系统(subsystem):
    Video(图像)—图像控制以及线程(thread)和事件管理(event)。
    Audio(声音)—声音控制
    Joystick(摇杆)—游戏摇杆控制
    CD-ROM(光盘驱动器)—光盘媒体控制
    Window Management(视窗管理)-与视窗程序设计集成
    Event(事件驱动)-处理事件驱动
    以下是一支用C语言写成、非常简单的SDL示例:

    // Headers
    #include "SDL.h"
     
    // Main function
    int main(int argc, char* argv[])
    {
        // Initialize SDL
        if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
            return(1);
     
        // Delay 2 seconds
        SDL_Delay(2000);
     
        // Quit SDL
        SDL_Quit();
     
        // Return
        return 0;
    }


    SDL与DirectX比较对应关系:

    SDL DirectX 说明
    SDL_Video、SDL_Image、OpenGL DirectDraw、Direct3D  
    SDL_Audio、SDL_Mixer DirectSound  
    SDL_Joystick、SDL_Base DirectInput  
    SDL_Net DirectPlay  
    SMPEG、SDL_Video、SDL_Audio、SDL_Sound、SDL_Filter DirectShow  

    使用SDL开发的游戏:

    《Spore》
    《Tux Paint》
    《Simutrans》
    《Stepmania》
    《Frozen Bubble》
    《无冬之夜》(Neverwinter Nights)
    《魔法门之英雄无敌III》(Heroes of Might and Magic III)(Linux版)
    《模拟城市3000》(Sim City 3000)(Linux版)
    《虚幻竞技场》(Unreal Tournament)(Linux版)
    《虚幻竞技场2003》(Unreal Tournament 2003)(Linux版)
    《虚幻竞技场2004》(Unreal Tournament 2004)(Linux版)
    《第二人生》(Second Life)(Linux版)
    《佣兵战场》(Soldier of Fortune)(Linux版)
    《韦诺之战》(Battle for Wesnoth)
    Bos Wars

    展开全文
  • SDL中文学习手册(全)

    热门讨论 2020-07-30 23:32:45
    SDL强大不用解释,全面学习了解是必须的。
  • 因为Linux的普及以及不受$M的牵制,SDL在过去的几年中,成为了跨平台开发PC游戏的首选。即使是在Windows平台下,SDL有具有自身的优势。与MFC使用不成熟的C++外表伪封装的win32api以及一家独唱推崇的COM风格和.net相...
  • 之前做过一个FFMPEG+SDL的简单播放器:《100行代码实现最简单的基于FFMPEG+SDL的视频播放器》。最近有不少人反映SDL已经升级到2.0版本了,甚至官网的Wiki上都只有SDL2.0的文档了,因此下载了SDL 2.0 并且进行了简单...

    =====================================================

    最简单的基于FFmpeg的视频播放器系列文章列表:

    100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)

    最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)

    最简单的基于FFmpeg的解码器-纯净版(不包含libavformat)

    最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器

    最简单的基于FFMPEG的Helloworld程序

    =====================================================


    简介

    之前做过一个FFMPEG+SDL的简单播放器:《100行代码实现最简单的基于FFMPEG+SDL的视频播放器》。该播放器采用SDL1.2显示视频。最近有不少人反映SDL已经升级到2.0版本了,甚至官网的Wiki上都只有SDL2.0的文档了,因此下载了SDL 2.0 并且进行了简单的研究。随后对此前的播放器进行了修改,将SDL1.2换成了SDL2.0。

    注:《100行代码实现最简单的基于FFMPEG+SDL的视频播放器》文章中提到的很多知识这里不再重复记录。本文重点记录SDL1.2与SDL2.0的不同。


    平台使用了VC2010,FFmpeg类库使用了最近的版本,SDL使用2.0版本。


    Simplest FFmpeg Player 2


    项目主页

    SourceForge:https://sourceforge.net/projects/simplestffmpegplayer/

    Github:https://github.com/leixiaohua1020/simplest_ffmpeg_player

    开源中国:http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_player


    流程图


    FFmpeg解码一个视频流程如下图所示:


    SDL2.0显示YUV的流程图:


    对比SDL1.2的流程图,发现变化还是很大的。几乎所有的API都发生了变化。但是函数和变量有一定的对应关系:

    SDL_SetVideoMode()————SDL_CreateWindow()

    SDL_Surface————SDL_Window

    SDL_CreateYUVOverlay()————SDL_CreateTexture()

    SDL_Overlay————SDL_Texture

    不再一一例举。

    下图为SDL1.x显示YUV的流程图。


    简单解释各个变量的作用:

    SDL_Window就是使用SDL的时候弹出的那个窗口。在SDL1.x版本中,只可以创建一个一个窗口。在SDL2.0版本中,可以创建多个窗口。
    SDL_Texture用于显示YUV数据。一个SDL_Texture对应一帧YUV数据。
    SDL_Renderer用于渲染SDL_Texture至SDL_Window。
    SDL_Rect用于确定SDL_Texture显示的位置。注意:一个SDL_Texture可以指定多个不同的SDL_Rect,这样就可以在SDL_Window不同位置显示相同的内容(使用SDL_RenderCopy()函数)。
    它们的关系如下图所示:


    下图举了个例子,指定了4个SDL_Rect,可以实现4分屏的显示。




    simplest_ffmpeg_player(标准版)代码

    最基础的版本,学习的开始。

    /**
     * 最简单的基于FFmpeg的视频播放器 2
     * Simplest FFmpeg Player 2
     *
     * 雷霄骅 Lei Xiaohua
     * leixiaohua1020@126.com
     * 中国传媒大学/数字电视技术
     * Communication University of China / Digital TV Technology
     * http://blog.csdn.net/leixiaohua1020
     *
     * 第2版使用SDL2.0取代了第一版中的SDL1.2
     * Version 2 use SDL 2.0 instead of SDL 1.2 in version 1.
     *
     * 本程序实现了视频文件的解码和显示(支持HEVC,H.264,MPEG2等)。
     * 是最简单的FFmpeg视频解码方面的教程。
     * 通过学习本例子可以了解FFmpeg的解码流程。
     * This software is a simplest video player based on FFmpeg.
     * Suitable for beginner of FFmpeg.
     *
     */
    
    
    
    #include <stdio.h>
    
    #define __STDC_CONSTANT_MACROS
    
    #ifdef _WIN32
    //Windows
    extern "C"
    {
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libswscale/swscale.h"
    #include "libavutil/imgutils.h"
    #include "SDL2/SDL.h"
    };
    #else
    //Linux...
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libswscale/swscale.h>
    #include <SDL2/SDL.h>
    #include <libavutil/imgutils.h>
    #ifdef __cplusplus
    };
    #endif
    #endif
    
    //Output YUV420P data as a file 
    #define OUTPUT_YUV420P 0
    
    int main(int argc, char* argv[])
    {
    	AVFormatContext	*pFormatCtx;
    	int				i, videoindex;
    	AVCodecContext	*pCodecCtx;
    	AVCodec			*pCodec;
    	AVFrame	*pFrame,*pFrameYUV;
    	unsigned char *out_buffer;
    	AVPacket *packet;
    	int y_size;
    	int ret, got_picture;
    	struct SwsContext *img_convert_ctx;
    
    	char filepath[]="bigbuckbunny_480x272.h265";
    	//SDL---------------------------
    	int screen_w=0,screen_h=0;
    	SDL_Window *screen; 
    	SDL_Renderer* sdlRenderer;
    	SDL_Texture* sdlTexture;
    	SDL_Rect sdlRect;
    
    	FILE *fp_yuv;
    
    	av_register_all();
    	avformat_network_init();
    	pFormatCtx = avformat_alloc_context();
    
    	if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
    		printf("Couldn't open input stream.\n");
    		return -1;
    	}
    	if(avformat_find_stream_info(pFormatCtx,NULL)<0){
    		printf("Couldn't find stream information.\n");
    		return -1;
    	}
    	videoindex=-1;
    	for(i=0; i<pFormatCtx->nb_streams; i++) 
    		if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
    			videoindex=i;
    			break;
    		}
    	if(videoindex==-1){
    		printf("Didn't find a video stream.\n");
    		return -1;
    	}
    
    	pCodecCtx=pFormatCtx->streams[videoindex]->codec;
    	pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    	if(pCodec==NULL){
    		printf("Codec not found.\n");
    		return -1;
    	}
    	if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){
    		printf("Could not open codec.\n");
    		return -1;
    	}
    	
    	pFrame=av_frame_alloc();
    	pFrameYUV=av_frame_alloc();
    	out_buffer=(unsigned char *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P,  pCodecCtx->width, pCodecCtx->height,1));
    	av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize,out_buffer,
    		AV_PIX_FMT_YUV420P,pCodecCtx->width, pCodecCtx->height,1);
    	
    	packet=(AVPacket *)av_malloc(sizeof(AVPacket));
    	//Output Info-----------------------------
    	printf("--------------- File Information ----------------\n");
    	av_dump_format(pFormatCtx,0,filepath,0);
    	printf("-------------------------------------------------\n");
    	img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, 
    		pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); 
    
    #if OUTPUT_YUV420P 
        fp_yuv=fopen("output.yuv","wb+");  
    #endif  
    	
    	if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  
    		printf( "Could not initialize SDL - %s\n", SDL_GetError()); 
    		return -1;
    	} 
    
    	screen_w = pCodecCtx->width;
    	screen_h = pCodecCtx->height;
    	//SDL 2.0 Support for multiple windows
    	screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
    		screen_w, screen_h,
    		SDL_WINDOW_OPENGL);
    
    	if(!screen) {  
    		printf("SDL: could not create window - exiting:%s\n",SDL_GetError());  
    		return -1;
    	}
    
    	sdlRenderer = SDL_CreateRenderer(screen, -1, 0);  
    	//IYUV: Y + U + V  (3 planes)
    	//YV12: Y + V + U  (3 planes)
    	sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);  
    
    	sdlRect.x=0;
    	sdlRect.y=0;
    	sdlRect.w=screen_w;
    	sdlRect.h=screen_h;
    
    	//SDL End----------------------
    	while(av_read_frame(pFormatCtx, packet)>=0){
    		if(packet->stream_index==videoindex){
    			ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
    			if(ret < 0){
    				printf("Decode Error.\n");
    				return -1;
    			}
    			if(got_picture){
    				sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, 
    					pFrameYUV->data, pFrameYUV->linesize);
    				
    #if OUTPUT_YUV420P
    				y_size=pCodecCtx->width*pCodecCtx->height;  
    				fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);    //Y 
    				fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);  //U
    				fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);  //V
    #endif
    				//SDL---------------------------
    #if 0
    				SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] );  
    #else
    				SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
    				pFrameYUV->data[0], pFrameYUV->linesize[0],
    				pFrameYUV->data[1], pFrameYUV->linesize[1],
    				pFrameYUV->data[2], pFrameYUV->linesize[2]);
    #endif	
    				
    				SDL_RenderClear( sdlRenderer );  
    				SDL_RenderCopy( sdlRenderer, sdlTexture,  NULL, &sdlRect);  
    				SDL_RenderPresent( sdlRenderer );  
    				//SDL End-----------------------
    				//Delay 40ms
    				SDL_Delay(40);
    			}
    		}
    		av_free_packet(packet);
    	}
    	//flush decoder
    	//FIX: Flush Frames remained in Codec
    	while (1) {
    		ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
    		if (ret < 0)
    			break;
    		if (!got_picture)
    			break;
    		sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, 
    			pFrameYUV->data, pFrameYUV->linesize);
    #if OUTPUT_YUV420P
    		int y_size=pCodecCtx->width*pCodecCtx->height;  
    		fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);    //Y 
    		fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);  //U
    		fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);  //V
    #endif
    		//SDL---------------------------
    		SDL_UpdateTexture( sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0] );  
    		SDL_RenderClear( sdlRenderer );  
    		SDL_RenderCopy( sdlRenderer, sdlTexture,  NULL, &sdlRect);  
    		SDL_RenderPresent( sdlRenderer );  
    		//SDL End-----------------------
    		//Delay 40ms
    		SDL_Delay(40);
    	}
    
    	sws_freeContext(img_convert_ctx);
    
    #if OUTPUT_YUV420P 
        fclose(fp_yuv);
    #endif 
    
    	SDL_Quit();
    
    	av_frame_free(&pFrameYUV);
    	av_frame_free(&pFrame);
    	avcodec_close(pCodecCtx);
    	avformat_close_input(&pFormatCtx);
    
    	return 0;
    }
    



    simplest_ffmpeg_player_su(SU版)代码

    标准版的基础之上引入了SDL的Event。

    效果如下:

    (1)SDL弹出的窗口可以移动了
    (2)画面显示是严格的40ms一帧

    /**
     * 最简单的基于FFmpeg的视频播放器2(SDL升级版)
     * Simplest FFmpeg Player 2(SDL Update)
     *
     * 雷霄骅 Lei Xiaohua
     * leixiaohua1020@126.com
     * 中国传媒大学/数字电视技术
     * Communication University of China / Digital TV Technology
     * http://blog.csdn.net/leixiaohua1020
     *
     * 第2版使用SDL2.0取代了第一版中的SDL1.2
     * Version 2 use SDL 2.0 instead of SDL 1.2 in version 1.
     *
     * 本程序实现了视频文件的解码和显示(支持HEVC,H.264,MPEG2等)。
     * 是最简单的FFmpeg视频解码方面的教程。
     * 通过学习本例子可以了解FFmpeg的解码流程。
     * 本版本中使用SDL消息机制刷新视频画面。
     * This software is a simplest video player based on FFmpeg.
     * Suitable for beginner of FFmpeg.
     *
     * 备注:
     * 标准版在播放视频的时候,画面显示使用延时40ms的方式。这么做有两个后果:
     * (1)SDL弹出的窗口无法移动,一直显示是忙碌状态
     * (2)画面显示并不是严格的40ms一帧,因为还没有考虑解码的时间。
     * SU(SDL Update)版在视频解码的过程中,不再使用延时40ms的方式,而是创建了
     * 一个线程,每隔40ms发送一个自定义的消息,告知主函数进行解码显示。这样做之后:
     * (1)SDL弹出的窗口可以移动了
     * (2)画面显示是严格的40ms一帧
     * Remark:
     * Standard Version use's SDL_Delay() to control video's frame rate, it has 2
     * disadvantages:
     * (1)SDL's Screen can't be moved and always "Busy".
     * (2)Frame rate can't be accurate because it doesn't consider the time consumed 
     * by avcodec_decode_video2()
     * SU(SDL Update)Version solved 2 problems above. It create a thread to send SDL 
     * Event every 40ms to tell the main loop to decode and show video frames.
     */
    
    #include <stdio.h>
    
    #define __STDC_CONSTANT_MACROS
    
    #ifdef _WIN32
    //Windows
    extern "C"
    {
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libswscale/swscale.h"
    #include "libavutil/imgutils.h"
    #include "SDL2/SDL.h"
    };
    #else
    //Linux...
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libswscale/swscale.h>
    #include <libavutil/imgutils.h>
    #include <SDL2/SDL.h>
    #ifdef __cplusplus
    };
    #endif
    #endif
    
    //Refresh Event
    #define SFM_REFRESH_EVENT  (SDL_USEREVENT + 1)
    
    #define SFM_BREAK_EVENT  (SDL_USEREVENT + 2)
    
    int thread_exit=0;
    int thread_pause=0;
    
    int sfp_refresh_thread(void *opaque){
    	thread_exit=0;
    	thread_pause=0;
    
    	while (!thread_exit) {
    		if(!thread_pause){
    			SDL_Event event;
    			event.type = SFM_REFRESH_EVENT;
    			SDL_PushEvent(&event);
    		}
    		SDL_Delay(40);
    	}
    	thread_exit=0;
    	thread_pause=0;
    	//Break
    	SDL_Event event;
    	event.type = SFM_BREAK_EVENT;
    	SDL_PushEvent(&event);
    
    	return 0;
    }
    
    
    int main(int argc, char* argv[])
    {
    
    	AVFormatContext	*pFormatCtx;
    	int				i, videoindex;
    	AVCodecContext	*pCodecCtx;
    	AVCodec			*pCodec;
    	AVFrame	*pFrame,*pFrameYUV;
    	unsigned char *out_buffer;
    	AVPacket *packet;
    	int ret, got_picture;
    
    	//------------SDL----------------
    	int screen_w,screen_h;
    	SDL_Window *screen; 
    	SDL_Renderer* sdlRenderer;
    	SDL_Texture* sdlTexture;
    	SDL_Rect sdlRect;
    	SDL_Thread *video_tid;
    	SDL_Event event;
    
    	struct SwsContext *img_convert_ctx;
    
    	//char filepath[]="bigbuckbunny_480x272.h265";
    	char filepath[]="Titanic.ts";
    
    	av_register_all();
    	avformat_network_init();
    	pFormatCtx = avformat_alloc_context();
    
    	if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
    		printf("Couldn't open input stream.\n");
    		return -1;
    	}
    	if(avformat_find_stream_info(pFormatCtx,NULL)<0){
    		printf("Couldn't find stream information.\n");
    		return -1;
    	}
    	videoindex=-1;
    	for(i=0; i<pFormatCtx->nb_streams; i++) 
    		if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
    			videoindex=i;
    			break;
    		}
    	if(videoindex==-1){
    		printf("Didn't find a video stream.\n");
    		return -1;
    	}
    	pCodecCtx=pFormatCtx->streams[videoindex]->codec;
    	pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    	if(pCodec==NULL){
    		printf("Codec not found.\n");
    		return -1;
    	}
    	if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){
    		printf("Could not open codec.\n");
    		return -1;
    	}
    	pFrame=av_frame_alloc();
    	pFrameYUV=av_frame_alloc();
    
    	out_buffer=(unsigned char *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P,  pCodecCtx->width, pCodecCtx->height,1));
    	av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize,out_buffer,
    		AV_PIX_FMT_YUV420P,pCodecCtx->width, pCodecCtx->height,1);
    
    	//Output Info-----------------------------
    	printf("---------------- File Information ---------------\n");
    	av_dump_format(pFormatCtx,0,filepath,0);
    	printf("-------------------------------------------------\n");
    	
    	img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, 
    		pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); 
    	
    
    	if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  
    		printf( "Could not initialize SDL - %s\n", SDL_GetError()); 
    		return -1;
    	} 
    	//SDL 2.0 Support for multiple windows
    	screen_w = pCodecCtx->width;
    	screen_h = pCodecCtx->height;
    	screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
    		screen_w, screen_h,SDL_WINDOW_OPENGL);
    
    	if(!screen) {  
    		printf("SDL: could not create window - exiting:%s\n",SDL_GetError());  
    		return -1;
    	}
    	sdlRenderer = SDL_CreateRenderer(screen, -1, 0);  
    	//IYUV: Y + U + V  (3 planes)
    	//YV12: Y + V + U  (3 planes)
    	sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);  
    
    	sdlRect.x=0;
    	sdlRect.y=0;
    	sdlRect.w=screen_w;
    	sdlRect.h=screen_h;
    
    	packet=(AVPacket *)av_malloc(sizeof(AVPacket));
    
    	video_tid = SDL_CreateThread(sfp_refresh_thread,NULL,NULL);
    	//------------SDL End------------
    	//Event Loop
    	
    	for (;;) {
    		//Wait
    		SDL_WaitEvent(&event);
    		if(event.type==SFM_REFRESH_EVENT){
    			while(1){
    				if(av_read_frame(pFormatCtx, packet)<0)
    					thread_exit=1;
    
    				if(packet->stream_index==videoindex)
    					break;
    			}
    			ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
    			if(ret < 0){
    				printf("Decode Error.\n");
    				return -1;
    			}
    			if(got_picture){
    				sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
    				//SDL---------------------------
    				SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] );  
    				SDL_RenderClear( sdlRenderer );  
    				//SDL_RenderCopy( sdlRenderer, sdlTexture, &sdlRect, &sdlRect );  
    				SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, NULL);  
    				SDL_RenderPresent( sdlRenderer );  
    				//SDL End-----------------------
    			}
    			av_free_packet(packet);
    		}else if(event.type==SDL_KEYDOWN){
    			//Pause
    			if(event.key.keysym.sym==SDLK_SPACE)
    				thread_pause=!thread_pause;
    		}else if(event.type==SDL_QUIT){
    			thread_exit=1;
    		}else if(event.type==SFM_BREAK_EVENT){
    			break;
    		}
    
    	}
    
    	sws_freeContext(img_convert_ctx);
    
    	SDL_Quit();
    	//--------------
    	av_frame_free(&pFrameYUV);
    	av_frame_free(&pFrame);
    	avcodec_close(pCodecCtx);
    	avformat_close_input(&pFormatCtx);
    
    	return 0;
    }
    



    运行结果

    程序运行后,会在命令行窗口打印一些视频信息,同时会弹出一个窗口播放视频内容。



    下载

    CSDN完整工程下载地址:

    http://download.csdn.net/detail/leixiaohua1020/7826277

    更新(2014.10.5)==============================

    版本升级至2.2。

    1.新版本在原版本的基础上增加了“flush_decoder”功能。当av_read_frame()循环退出的时候,实际上解码器中可能还包含剩余的几帧数据。因此需要通过“flush_decoder”将这几帧数据输出。“flush_decoder”功能简而言之即直接调用avcodec_decode_video2()获得AVFrame,而不再向解码器传递AVPacket。参考代码如下:

    	//FIX: Flush Frames remained in Codec
    	while (1) {
    		ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
    		if (ret < 0)
    			break;
    		if (!got_picture)
    			break;
    		sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
    		//处理...
    	}

    2.为了更好地适应Linux等其他操作系统,做到可以跨平台,去除掉了VC特有的一些函数。比如“#include "stdafx.h"”,“_tmain()”等等。

    具体信息参见文章:avcodec_decode_video2()解码视频后丢帧的问题解决

    2.2版下载地址:http://download.csdn.net/detail/leixiaohua1020/8002337


    更新-2.3(2015.1.03)==============================

    新增一个工程:最简单的基于FFmpeg的解码器-纯净版(不包含libavformat)

    2.3版CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/8322307


    更新-2.4(2015.2.13)==============================

    这次考虑到了跨平台的要求,调整了源代码。经过这次调整之后,源代码可以在以下平台编译通过:

    VC++:打开sln文件即可编译,无需配置。

    cl.exe:打开compile_cl.bat即可命令行下使用cl.exe进行编译,注意可能需要按照VC的安装路径调整脚本里面的参数。编译命令如下。

    ::VS2010 Environment
    call "D:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
    ::include
    @set INCLUDE=include;%INCLUDE%
    ::lib
    @set LIB=lib;%LIB%
    ::compile and link
    cl simplest_ffmpeg_player.cpp /MD /link SDL2.lib SDL2main.lib avcodec.lib ^
    avformat.lib avutil.lib avdevice.lib avfilter.lib postproc.lib swresample.lib swscale.lib ^
    /SUBSYSTEM:WINDOWS /OPT:NOREF

    MinGW:MinGW命令行下运行compile_mingw.sh即可使用MinGW的g++进行编译。编译命令如下。

    g++ simplest_ffmpeg_player.cpp -g -o simplest_ffmpeg_player.exe \
    -I /usr/local/include -L /usr/local/lib \
    -lmingw32 -lSDL2main -lSDL2 -lavformat -lavcodec -lavutil -lswscale

    GCC:Linux或者MacOS命令行下运行compile_gcc.sh即可使用GCC进行编译。编译命令如下。

    gcc simplest_ffmpeg_player.cpp -g -o simplest_ffmpeg_player.out \
    -I /usr/local/include -L /usr/local/lib -lSDL2main -lSDL2 -lavformat -lavcodec -lavutil -lswscale
    
    PS:相关的编译命令已经保存到了工程文件夹中

    SourceForge、Github等上面已经更新。

    更新-2.5(2015.7.17)==============================
    增加了下列工程:
    simplest_ffmpeg_decoder:一个包含了封装格式处理功能的解码器。使用了libavcodec和libavformat。
    simplest_video_play_sdl2:使用SDL2播放YUV的例子。
    simplest_ffmpeg_helloworld:输出FFmpeg类库的信息。

    SourceForge、Github等上面已经更新。



    展开全文
  • SDL介绍和简单实用

    万次阅读 2018-06-14 14:54:36
    SDL库的作用说白了就是封装了复杂的视音频底层操作,简化了视音频处理的难度。以下转自WiKi:SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、...

    SDL库的作用说白了就是封装了复杂的视音频底层操作,简化了视音频处理的难度。

    以下转自WiKi:


    SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
    SDL使用GNU宽通用公共许可证为授权方式,意指动态链接(dynamic link)其库并不需要开放本身的源代码。因此诸如《雷神之锤4》等商业游戏也使用SDL来开发。


    结构
    虽然SDL时常被比较为‘跨平台的DirectX’,然而事实上SDL是定位成以精简的方式来完成基础的功能,它大幅度简化了控制图像、声音、输出入等工作所需撰写的代码。但更高级的绘图功能或是音效功能则需搭配OpenGL和OpenAL等API来达成。另外它本身也没有方便创建图形用户界面的函数。
    SDL在结构上是将不同操作系统的库再包装成相同的函数,例如SDL在Windows平台上其实是DirectX的再包装,旧版本包装的是DirectX 5,现时的版本(SDL 1.2)则是DirectX 7。而在使用X11的平台上(包括Linux),SDL则是与Xlib库沟通来输出图像。
    虽然SDL本身是使用C语言写成,但是它几乎可以被所有的编程语言所使用,例如:C++、Perl、Python(借由pygame库)、Pascal等等,甚至是Euphoria、Pliant这类较不流行的编程语言也都可行。
    SDL库分为 Video、Audio、CD-ROM、Joystick 和 Timer 等若干子系统,除此之外,还有一些单独的官方扩充函数库。这些库由官方网站提供,并包含在官方文档中,共同组成了SDL的“标准库”:
    SDL_image—支持时下流行的图像格式:BMP、PPM、XPM、 PCX、GIF、JPEG、PNG、TGA。
    SDL_mixer—更多的声音输出函数以及更多的声音格式支持。
    SDL_net—网络支持。
    SDL_ttf—TrueType字体渲染支持。
    SDL_rtf—简单的RTF渲染支持。


    子系统
    SDL将功能分成下列数个子系统(subsystem):
    Video(图像)—图像控制以及线程(thread)和事件管理(event)。
    Audio(声音)—声音控制
    Joystick(摇杆)—游戏摇杆控制
    CD-ROM(光盘驱动器)—光盘媒体控制
    Window Management(视窗管理)-与视窗程序设计集成

    Event(事件驱动)-处理事件驱动


    SDL视频显示函数简介
    ▫ SDL_Init():初始化SDL系统
    ▫ SDL_CreateWindow():创建窗口SDL_Window
    ▫ SDL_CreateRenderer():创建渲染器SDL_Renderer
    ▫ SDL_CreateTexture():创建纹理SDL_Texture
    ▫ SDL_UpdateTexture():设置纹理的数据
    ▫ SDL_RenderCopy():将纹理的数据拷贝给渲染器
    ▫ SDL_RenderPresent():显示
    ▫ SDL_Delay():工具函数,用于延时。

    ▫ SDL_Quit():退出SDL系统

    SDL数据结构简介
    ▫ SDL_Window 代表了一个“窗口”
    ▫ SDL_Renderer 代表了一个“渲染器”
    ▫ SDL_Texture 代表了一个“纹理”

    ▫ SDL_Rect 一个简单的矩形结构

    SDL多线程
    函数
    SDL_CreateThread():创建一个线程
    数据结构
    DL_Thread:线程的句柄
    SDL事件
    函数
    SDL_WaitEvent()等待一个事件
    SDL_PushEvent()发送一个事件
    数据结构
    SDL_Event:代表一个事件


    以下是一支用C语言写成、非常简单的SDL示例:

    /**
     * 最简单的SDL2播放视频的例子(SDL2播放RGB/YUV)
     * Simplest Video Play SDL2 (SDL2 play RGB/YUV) 
     *
     * 雷霄骅 Lei Xiaohua
     * leixiaohua1020@126.com
     * 中国传媒大学/数字电视技术
     * Communication University of China / Digital TV Technology
     * http://blog.csdn.net/leixiaohua1020
     *
     * 本程序使用SDL2播放RGB/YUV视频像素数据。SDL实际上是对底层绘图
     * API(Direct3D,OpenGL)的封装,使用起来明显简单于直接调用底层
     * API。
     *
     * This software plays RGB/YUV raw video data using SDL2.
     * SDL is a wrapper of low-level API (Direct3D, OpenGL).
     * Use SDL is much easier than directly call these low-level API.  
     */
    
    #include <stdio.h>
    
    extern "C"
    {
    #include "sdl/SDL.h"
    };
    
    const int bpp=12;
    
    int screen_w=500,screen_h=500;
    const int pixel_w=320,pixel_h=180;
    
    unsigned char buffer[pixel_w*pixel_h*bpp/8];
    
    //Refresh Event
    #define REFRESH_EVENT  (SDL_USEREVENT + 1)
    //Break
    #define BREAK_EVENT  (SDL_USEREVENT + 2)
    
    int thread_exit=0;
    
    //每隔40毫秒向SDL系统发送一个REFRESH_EVENT事件
    int refresh_video(void *opaque){
    	thread_exit=0;
    	while (thread_exit==0) {
    		SDL_Event event;
    		event.type = REFRESH_EVENT;
    		SDL_PushEvent(&event);
    		SDL_Delay(40);
    	}
    	thread_exit=0;
    	//Break
    	SDL_Event event;
    	event.type = BREAK_EVENT;
    	SDL_PushEvent(&event);
    	return 0;
    }
    
    int main(int argc, char* argv[])
    {
    	if(SDL_Init(SDL_INIT_VIDEO)) {  
    		printf( "Could not initialize SDL - %s\n", SDL_GetError()); 
    		return -1;
    	} 
    
    	SDL_Window *screen; 
    	//SDL 2.0 Support for multiple windows
    	screen = SDL_CreateWindow("Simplest Video Play SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
    		screen_w, screen_h,SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
    	if(!screen) {  
    		printf("SDL: could not create window - exiting:%s\n",SDL_GetError());  
    		return -1;
    	}
    	SDL_Renderer* sdlRenderer = SDL_CreateRenderer(screen, -1, 0);  
    
    	Uint32 pixformat=0;
    	//IYUV: Y + U + V  (3 planes)
    	//YV12: Y + V + U  (3 planes)
    	pixformat= SDL_PIXELFORMAT_IYUV;  
    
    	SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer,pixformat, SDL_TEXTUREACCESS_STREAMING,pixel_w,pixel_h);
    
    	FILE *fp=NULL;
    	fp=fopen("test_yuv420p_320x180.yuv","rb+");
    
    	if(fp==NULL){
    		printf("cannot open this file\n");
    		return -1;
    	}
    
    	SDL_Rect sdlRect;  
    
    	SDL_Thread *refresh_thread = SDL_CreateThread(refresh_video,NULL,NULL);
    	SDL_Event event;
    	while(1){
    		//收取SDL系统里面的事件
    		SDL_WaitEvent(&event);
    		if(event.type==REFRESH_EVENT){
    			if (fread(buffer, 1, pixel_w*pixel_h*bpp/8, fp) != pixel_w*pixel_h*bpp/8){
    				// Loop
    				fseek(fp, 0, SEEK_SET);
    				fread(buffer, 1, pixel_w*pixel_h*bpp/8, fp);
    			}
    
    			SDL_UpdateTexture( sdlTexture, NULL, buffer, pixel_w);  
    
    			//FIX: If window is resize
    			sdlRect.x = 0;  
    			sdlRect.y = 0;  
    			sdlRect.w = screen_w;  
    			sdlRect.h = screen_h;  
    			
    			SDL_RenderClear( sdlRenderer );   
    			SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);  
    			SDL_RenderPresent( sdlRenderer );  
    			
    		}else if(event.type==SDL_WINDOWEVENT){
    			//If Resize
    			SDL_GetWindowSize(screen,&screen_w,&screen_h);
    		}else if(event.type==SDL_QUIT){
    			thread_exit=1;
    		}else if(event.type==BREAK_EVENT){
    			break;
    		}
    	}
    	SDL_Quit();
    	return 0;
    }
    

    SDL与DirectX比较对应关系:

    SDLDirectX说明
    SDL_Video、SDL_Image、OpenGLDirectDraw、Direct3D 
    SDL_Audio、SDL_MixerDirectSound 
    SDL_Joystick、SDL_BaseDirectInput 
    SDL_NetDirectPlay 
    SMPEG、SDL_Video、SDL_Audio、SDL_Sound、SDL_FilterDirectShow 

    使用SDL开发的游戏:

    《Spore》
    《Tux Paint》
    《Simutrans》
    《Stepmania》
    《Frozen Bubble》
    《无冬之夜》(Neverwinter Nights)
    《魔法门之英雄无敌III》(Heroes of Might and Magic III)(Linux版)
    《模拟城市3000》(Sim City 3000)(Linux版)
    《虚幻竞技场》(Unreal Tournament)(Linux版)
    《虚幻竞技场2003》(Unreal Tournament 2003)(Linux版)
    《虚幻竞技场2004》(Unreal Tournament 2004)(Linux版)
    《第二人生》(Second Life)(Linux版)
    《佣兵战场》(Soldier of Fortune)(Linux版)
    《韦诺之战》(Battle for Wesnoth)

    Bos Wars


    SDL详细教程:

    https://blog.csdn.net/lf426/article/category/364048/1

    展开全文
  • 安全开发流程(SDL

    万次阅读 2020-04-02 09:27:54
    一、SDL简介 SDL security development lifecycle(安全开发生命周期),是微软提出的从安全角度指导软件开发过程的管理模式。SDL是一个安全保证的过程,起重点是软件开发,它在开发的所有阶段都引入了安全和隐私...

    一、SDL简介

    SDL security development lifecycle(安全开发生命周期),是微软提出的从安全角度指导软件开发过程的管理模式。SDL是一个安全保证的过程,起重点是软件开发,它在开发的所有阶段都引入了安全和隐私的原则。自2004年起,SDL一直都是微软在全公司实施的强制性策略。

    二、SDL步骤图

    SDL中的方法,试图从安全漏洞产生的根源上解决问题,通过对软件工程的控制,保证产品的安全性。

    美国国家标准与技术研究所(NIST)估计,如果是在项目发布后在执行漏洞修复计划,其修复成本相当于在设计阶段执行修复的30倍

    三、SDL的步骤包括:

    阶段1:培训

    开发团队的所有成员都必须接受适当的安全培训,了解相关的安全知识,培训对象包括开发人员、测试人员、项目经理、产品经理等。

    阶段2:安全要求

    在项目确立之前,需要提前与项目经理或者产品owner进行沟通,确定安全的要求和需要做的事情。确认项目计划和里程碑,尽量避免因为安全问题而导致项目延期发布。

    阶段3:质量门/bug栏

    质量门和bug栏用于确定安全和隐私质量的最低可接受级别。

    Bug栏是应用于整个开发项目的质量门,用于定义安全漏洞的严重性阈值。例如,应用程序在发布时不得包含具有“关键”或“重要”评级的已知漏洞。Bug栏一经设定,便绝不能放松。

    阶段4:安全和隐私风险评估

    安全风险评估(SRA)和隐私风险评估(PRA)是一个必需的过程,必须包括以下信息:

    1、(安全)项目的哪些部分在发布前需要威胁模型?

    2、(安全)项目的哪些部分在发布前需要进行安全设计评析?

    3、(安全)项目的哪些部分需要并不食欲项目团队且双方认可的小组进行渗透测试?

    4、(安全)是否存在安全顾问认为有必要增加的测试或分析要求已缓解安全风险?

    5、(安全)模糊测试要求的具体范围是什么?

    6、(安全)隐私影响评级如何?

    阶段5:设计要求

    在设计阶段应仔细考虑安全和隐私问题,在项目初期确定好安全需求,尽可能避免安全引起的需求变更。

    阶段6:减小攻击面

    减小攻击面与威胁建模紧密相关,不过它解决安全问题的角度稍有不同。减小攻击面通过减小攻击者利用潜在弱点或漏洞的机会来降低风险,减小攻击面包括:关闭或限制对系统服务的访问,应用“最小权限原则”,以及尽可能进行分层防御。

    阶段7:威胁建模

    为项目或产品面临的威胁建立模型,明确可能来自的攻击有哪些方面。

    阶段8:使用指定的工具

    开发团队使用的编辑器、链接器等相关工具,可能会涉及一些安全相关的环节,因此在使用工具的版本上,需要提前与安全团队进行沟通。

    阶段9:弃用不安全函数

    许多常用函数可能存在安全隐患,应当禁用不安全的函数和API,使用安全团队推荐的函数。

    阶段10:静态分析

    代码静态分析可以由相关工具辅助完成,其结果与人工分析相结合。

    阶段11:动态程序分析

    动态分析是静态分析的补充,用于测试环节验证程序的安全性。

    阶段12:模糊测试(Fuzzing Test)

    模糊测试是一种专门形式的动态分析,它通过故意向应用程序引入不良格式或随机数据诱发程序故障。模糊测试策略的制定,以应用程序的预期用途,以及应用程序的功能和设计规范为基础。安全顾问可能要求进行额外的模糊测试,或者扩大模糊测试的范围和增加持续时间。

    阶段13:威胁模型和攻击面评析

    项目经常会因为需求等因素导致最终的产出偏离原本设定的目标,因此在项目后期对威胁模型和攻击面进行评析是有必要的,能够及时发现问题并修正。

    阶段14:事件响应计划

    受SDL要求约束的每个软件在发布时都必须包含事件响应计划。即使在发布时不包含任何已知漏洞的产品,也可能在日后面临新出现的威胁。需要注意的是,如果产品中包含第三方的代码,也需要留下第三方的联系方式并加入事件响应计划,以便在发生问题时能够找到对应的人。

    阶段15:最终安全评析

    最终安全评析(FSR)是在发布之前仔细检查对软件执行的所有安全活动。通过FSR将得出以下三种不同不同结果。

    1、  通过FSR。在FSR过程中确定所有安全和隐私问题都已得到修复或缓解。

    2、  通过FSR但有异常。在FSR过程中确定所有安全和隐私问题都已得到修复或缓解,并且/或者所有异常都已得到圆满解决。无法解决的问题将记录下来,在下次发布时更正。

    3、  需上报问题的FSR。如果团队未满足所有SDL要求,并且安全顾问和产品团队无法达成可接受的折中,则安全顾问不能批准项目,项目不能发布。团队必须在发布之前解决所有可解决的问题,或者上报高级管理层进行抉择。

    阶段16:发布/存档

    在通过FSR或者虽有问题但达成一致后,可以完成产品的发布。但发布的同时仍需对各种问题和文档进行存档,为紧急响应和产品升级提供帮助。
    从以上的过程可以看出,微软的SDL的过程实施非常细致。微软这些年来也一直帮助公司的所有产品团队,以及合作伙伴实施SDL,效果相当显著。

    相对于微软的SDL,OWASP推出了SAMM(Software Assurance Maturity Model),帮助开发者在软件工程的过程中实施安全

    SAMM与SDL的主要区别在于,SDL适用于软件开发商,他们以贩售软件为主要业务;而SAMM更适用于自主开发软件的使用者,如银行或在线服务提供商。软件开发商的软件工程往往较为成熟,有着严格的质量控制;而自主开发软件的企业组织,则更强调高效,因此在软件工程的做法上也存在差异。

    四、SDL实战经验准则:

    准则一:与项目经理进行充分沟通,排除足够的时间

    准则二:规范公司的立项流程,确保所有项目都能通知到安全团队,避免遗漏

    准则三:树立安全部门的权威,项目必须由安全部门审核完成后才能发布

    准则四:将技术方案写入开发、测试的工作手册中

    准则五:给工程师培训安全方案

    准则六:记录所有的安全bug,激励程序员编写安全的代码

    展开全文
  • SDL中文API

    2019-09-25 19:11:16
    相关文件 SDL2/SDL.h 功能:初始化SDL 参数: flags 系统名称,取值如下 SDL_INIT_TIMER  定时器子系统  SDL_INIT_AUDIO  音频子系统  SDL_INIT_VIDEO  视频子系统  SDL_INIT_JOYSTICK  操纵杆子系统  SDL_...
  • SDL显示图像和文字

    千次阅读 2015-01-16 14:20:06
    这两天在做一个视频分析软件需要用到SDL显示图像及文字,将阶段成果做一下总结: SDL本身并没有实际文字的功能,需要用到其扩展库SDL_ttf,下载地址: ...
  • SDLSDL简介

    千次阅读 2016-08-29 15:07:57
    1. SDL简介 SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux...
  • 关于SDL,在简介里面,有一些概念,但是很多人还是留言,不清楚到底是个什么。这节,我简单总结下:我们如何将一张图显示在屏幕上。这里简单的分为几个部分,硬件屏幕,驱动程序,软件部分。SDL不直接关注硬件屏幕,...
  • SDL2嵌入Qt的子窗口中

    万次阅读 2020-01-04 09:16:00
    SDL_Window* sdlWindow = SDL_CreateWindowFrom((void*) (QWidget的窗口->winId()));
  • Android本地视频播放器开发--SDL编译

    万次阅读 2013-06-13 12:12:31
    在上一章  Android本地视频播放器开发--ffmpeg解码视频文件中的音频(2)中使用OpenSL ES来播放视频的声音,遗留的问题是声音的不同步,由于视频实现... es来实现,由于SDL可以和OpenGL ES进行搭配,所以使用SDL+Op
  • 最简单的视音频播放示例7:SDL2播放RGB/YUV

    万次阅读 多人点赞 2015-01-13 16:08:52
    本文记录SDL播放视频的技术。在这里使用的版本是SDL2。实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API。在Windows平台下,SDL封装了Direct3D这类的API用于播放视频;封装了DirectSound这...
  • SDL2中文API(整理)

    万次阅读 多人点赞 2018-10-22 16:12:50
    相关文件 SDL2/SDL.h 功能:初始化SDL 参数: flags 系统名称,取值如下 SDL_INIT_TIMER  定时器子系统  SDL_INIT_AUDIO  音频子系统  SDL_INIT_VIDEO  视频子系统  SDL_INIT_JOYSTICK  操纵杆子系统  SDL_...
  • SDL2.0的下载可以参考这篇文章:SDL2学习笔记1-环境搭建以及HelloSDL。  本例开发环境:win7 64位 +VS2012 + SDL2.0.3 (stable)  第一步:新建MFC基于对话框的应用程序(此例工程命名为MFC_SDL),然后直接点击...
  • SDL2源代码分析2:窗口(SDL_Window)

    万次阅读 多人点赞 2014-12-22 00:48:37
    上一篇文章分析了SDL的初始化函数SDL_Init()。这篇文章继续分析SDL的源代码。本文分析SDL的窗口(Window)。
  • 在使用SDL2.0时,使用了SDL API函数SDL_SetWindowSize函数后,视频播放就会卡主,若是使用SDL_SetWindowPosition只是移动位置是不会有问题的? ShowData(const unsigned char *pY,const unsigned char *pU,const ...
  • 上一篇文章分析了SDL纹理赋值给渲染目标的函数SDL_RenderCopy()。这篇文章分析SDL显示视频最后的一个函数:SDL_RenderPresent()。
  • Linux 下SDL2 image安装及使用

    千次阅读 2015-05-24 11:00:16
    1. 安装SDL image 2.0 sudo apt-get install libsdl2-image-dev 如果没有安装过SDL2 ,应该会自动安装,也可以自己安装 sudo apt-get install libsdl2-dev 2. 测试,创建test,c,键入如下代码 #include #include ...
  • Linux/Ubuntu系统上SDL安装

    千次阅读 2015-12-07 15:59:44
    Linux/Ubuntu系统上SDL安装 一:准备下载包 SDL的官网网址:http://www.libsdl.org/ SDL库一共四个包: SDL基础包:SDL-1.2.15.tar.gz SDL扩展包: SDL_gfx-2.0.22.tar.gz(SDL图形核心包) SDL_image-1.2.10....
1 2 3 4 5 ... 20
收藏数 26,985
精华内容 10,794
关键字:

sdl