当前位置: 首页 > article >正文

(SDL2)SDL在ubuntu下的测试代码(雷霄骅)

安装好SDL后,可以使用代码测试一下,本文所用代码为雷神的代码,只修改了头文件即可,一个为播放音频,一个为播放视频,但是播放音频的会有明显卡顿,如果后续找到问题,会及时修改,如果你已解决,欢迎评论分享。

1.播放PCM

/*** 最简单的SDL2播放音频的例子(SDL2播放PCM)* Simplest Audio Play SDL2 (SDL2 play PCM) ** 雷霄骅 Lei Xiaohua* leixiaohua1020@126.com* 中国传媒大学/数字电视技术* Communication University of China / Digital TV Technology* http://blog.csdn.net/leixiaohua1020** 本程序使用SDL2播放PCM音频采样数据。SDL实际上是对底层绘图* API(Direct3D,OpenGL)的封装,使用起来明显简单于直接调用底层* API。** 函数调用步骤如下: ** [初始化]* SDL_Init(): 初始化SDL。* SDL_OpenAudio(): 根据参数(存储于SDL_AudioSpec)打开音频设备。* SDL_PauseAudio(): 播放音频数据。** [循环播放数据]* SDL_Delay(): 延时等待播放完成。** This software plays PCM raw audio data using SDL2.* SDL is a wrapper of low-level API (DirectSound).* Use SDL is much easier than directly call these low-level API.** The process is shown as follows:** [Init]* SDL_Init(): Init SDL.* SDL_OpenAudio(): Opens the audio device with the desired *					parameters (In SDL_AudioSpec).* SDL_PauseAudio(): Play Audio.** [Loop to play data]* SDL_Delay(): Wait for completetion of playback.*/#include <stdio.h>
// #include <tchar.h>extern "C"
{
#include "SDL2/SDL.h"
};//Buffer:
//|-----------|-------------|
//chunk-------pos---len-----|
static  Uint8  *audio_chunk; 
static  Uint32  audio_len; 
static  Uint8  *audio_pos; /* Audio Callback* The audio function callback takes the following parameters: * stream: A pointer to the audio buffer to be filled * len: The length (in bytes) of the audio buffer * 
*/ 
void  fill_audio(void *udata,Uint8 *stream,int len){ //SDL 2.0SDL_memset(stream, 0, len);if(audio_len==0)		/*  Only  play  if  we  have  data  left  */ return; len=(len>audio_len?audio_len:len);	/*  Mix  as  much  data  as  possible  */ SDL_MixAudio(stream,audio_pos,len,SDL_MIX_MAXVOLUME);audio_pos += len; audio_len -= len; 
} int main(int argc, char* argv[])
{//Initif(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  printf( "Could not initialize SDL - %s\n", SDL_GetError()); return -1;}//SDL_AudioSpecSDL_AudioSpec wanted_spec;wanted_spec.freq = 44100; wanted_spec.format = AUDIO_S16SYS; wanted_spec.channels = 2; wanted_spec.silence = 0; wanted_spec.samples = 1024; wanted_spec.callback = fill_audio; if (SDL_OpenAudio(&wanted_spec, NULL)<0){ printf("can't open audio.\n"); return -1; } FILE *fp=fopen("NocturneNo2inEflat_44.1k_s16le.pcm","rb+");if(fp == NULL){printf("cannot open this file\n");return -1;}int pcm_buffer_size=4096;char *pcm_buffer=(char *)malloc(pcm_buffer_size);int data_count=0;//PlaySDL_PauseAudio(0);while(1){if (fread(pcm_buffer, 1, pcm_buffer_size, fp) != pcm_buffer_size){// Loopfseek(fp, 0, SEEK_SET);fread(pcm_buffer, 1, pcm_buffer_size, fp);data_count=0;}	printf("Now Playing %10d Bytes data.\n",data_count);data_count+=pcm_buffer_size;//Set audio buffer (PCM data)audio_chunk = (Uint8 *) pcm_buffer; //Audio buffer lengthaudio_len =pcm_buffer_size;audio_pos = audio_chunk;while(audio_len>0)//Wait until finishSDL_Delay(1); }free(pcm_buffer);SDL_Quit();return 0;
}

ubuntu下编译:

gcc simplest_audio_play_sdl2.cpp -g -o simplest_audio_play_sdl2.out \
-I /usr/local/include -L /usr/local/lib -lSDL2main -lSDL2

2.播放yuv

/*** 最简单的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。** 函数调用步骤如下: ** [初始化]* SDL_Init(): 初始化SDL。* SDL_CreateWindow(): 创建窗口(Window)。* SDL_CreateRenderer(): 基于窗口创建渲染器(Render)。* SDL_CreateTexture(): 创建纹理(Texture)。** [循环渲染数据]* SDL_UpdateTexture(): 设置纹理的数据。* SDL_RenderCopy(): 纹理复制给渲染器。* SDL_RenderPresent(): 显示。** 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.  ** The process is shown as follows:** [Init]* SDL_Init(): Init SDL.* SDL_CreateWindow(): Create a Window.* SDL_CreateRenderer(): Create a Render.* SDL_CreateTexture(): Create a Texture.** [Loop to Render data]* SDL_UpdateTexture(): Set Texture's data.* SDL_RenderCopy(): Copy Texture to Render.* SDL_RenderPresent(): Show.*/#include <stdio.h>extern "C"
{
#include "SDL2/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)#define BREAK_EVENT  (SDL_USEREVENT + 2)int thread_exit=0;int refresh_video(void *opaque){thread_exit=0;while (!thread_exit) {SDL_Event event;event.type = REFRESH_EVENT;SDL_PushEvent(&event);SDL_Delay(40);}thread_exit=0;//BreakSDL_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 windowsscreen = 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){//WaitSDL_WaitEvent(&event);if(event.type==REFRESH_EVENT){if (fread(buffer, 1, pixel_w*pixel_h*bpp/8, fp) != pixel_w*pixel_h*bpp/8){// Loopfseek(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 resizesdlRect.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 ResizeSDL_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;
}

ubuntu下编译:

gcc simplest_video_play_sdl2.cpp -g -o simplest_video_play_sdl2.out \
-I /usr/local/include -L /usr/local/lib -lSDL2main -lSDL2

雷神写的demo合集:

批量下载


2021/11/16 更新

解决了雷神SDL2播放PCM音频例子中的哒哒噪音问题,原因是在回调函数内使用了混音器,修改如下:

 把原来的将audio_pos混音到stream改为直接复制audio_pos内容到stream。


2021/11/17更新

发现播放时的哒哒噪音声音并不是代码问题,因为昨天播放没有问题的代码今天又出现了异常。复现昨天的步骤发现,我昨天是在用SDL2播放一段16KS16单声道音频后,发现没有噪音,又去运行这段代码发现异常的哒哒噪音就没有了,今天在先播放昨天那段单声道音频后,噪音又消失了,怀疑虚拟机声卡有异常,暂时先这样吧。

http://www.lryc.cn/news/2419615.html

相关文章:

  • 负数求补码
  • short 下 32768的二进制
  • winRAR 破解注册码
  • 文件加密系统的设计与实现(源码+开题报告)
  • contest11 CF510E div2 ooxxx oooox oooox
  • Spider爬虫框架之Spiders模块
  • JS-变量提升与暂时性死区概念
  • 什么是WordPress?
  • jq-jquery根据内容设置select和input radio选中
  • 高数 | 工具及必备方法 | 【一元函数积分学】常用积分公式表
  • default-gateway和default-router的区别
  • Apche部署https详解
  • 采样定理的证明与推导
  • XSLT知识总结
  • 传说中的“摸奶节”!随便你怎么摸!
  • 社会网络分析与人脉网络:如何建立有效的人脉资源
  • Toybox、toolbox、busybox 软件协议
  • HTTP代理和SOCKS代理
  • 内存术语详解
  • 探索听诊器效应:了解声音在耳朵中的传播方式
  • StringTokenizer类的详解
  • 超音速启动 2020 年版发布
  • AMR音频格式分析
  • CrashRpt
  • 【音视频知识】MP4文件格式解析-详解
  • 日本的feature phone版twitter的follow链接
  • Android——bindService()方法启动服务
  • 汇编实验1——利用8255实现LED的流水点亮实验
  • td 元素属性 noWrap 防止折行、撑开及文字换行
  • 人类技术变革简史:娱乐产业的演进与创新