ffmpeg tutorial2学习--使用SDL显示到屏幕上
2016-05-19 23:10
405 查看
SDL的YUV接受4种YUV格式,最快的就是YV12,这和 YUV420P相似,只是UV被交换了。
420 表示是以4:2:0的比例来采样,
P planar 表示YUV在不同的数组中,即是分开放的。
======下面是如何使用SDL的简单说明
1.先include进文件,初始化SDL
#include <SDL.h>
#include <SDL_thread.h>
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO| SDL_INIT_TIMER))
{
fprintf(stderr, "could not initialize SDL--%s\n", SDL_GetError());
exit(1);
}
SDL_Init() 告诉库我们将要使用哪些特性
2.创建一个Display
现在我们需要一个填充的screen,显示图像的区域叫做“surface”
SDL_Surface *screen;
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
if(!screen)
{
fprintf(stderr, "SDL:could not set video mode-- exiting\n");
exit(1);
}
z到这里,用宽度和高度建立了一个screen。
SDL_SetVideoMode的第三个参数表示screen的深度--0是一个特殊的值,表示与当前display的值一样。
现在我们要在screen的上面创建一个YUV overlay,这样我们可以把视频放进去,并且创建一个SWSContext来把图像数据转换成YUV420;
SDL_Overlay *bmp = NULL;
struct SWSContext *sws_ctx = NULL;
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,
SDL_YV12_OVERLAY, screen);
// initialize SWS context for software scaling
sws_ctx = sws_getContext(pCodecCtx->width,
pCodecCtx->height,
pCodecCtx->pix_fmt,
pCodecCtx->width,
pCodecCtx->height,
PIX_FMT_YUV420P,
SWS_BILINEAR,
NULL,
NULL,
NULL
);
就像我们所说的,我们使用了YV12来显示图像,并从ffmpeg中得到YUV420数据。
### 显示图像
为了显示图像,我们创建一个AVPicture结构体,设置它的数据指针和linesize到YUV overlay
if(frameFinished)
{
SDL_LockYUVOverlay(bmp);
AVPicture pict;
pict.data[0] = bmp->pixels[0];
pict.data[1] = bmp->pixels[2];
pict.data[2] = bmp->pixels[1];
pict.linesize[0] = bmp->pitches[0];
pict.linesize[1] = bmp->pitches[2];
pict.linesize[2] = bmp->pitches[1];
//Convert the image into YUV format taht sdl uses
sws_scale(sws_ctx, (uint8_t const* const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pict.data, pict.linesize);
SDL_UnlockYUVOverlay(bmp);
}
首先,我们lock了overlay,因为我们要往里面写。AVPicture结构体,有一个data指针,是一个4个指针的数组。我们在处理YUV420P,所以只用了3个通道。linesize,就像名字表示的那样。在YUV中相对应的名字是‘pixels` and `pitches。
pitches指的是一个给定line的宽度。
我们给pict写数据,实际就是给ovelay来写。
### 画图像
我们仍旧需要告诉SDL来实际显示我们给他的数据。我们要给这个函数传递一个矩形,以便告诉它视频在哪里显示以及高度和宽度。这样,SDL就能做scale,并且这可以得到GPU的协助以便更快的scale。
SDL_Rect rect;
if(frameFinished)
{
......
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL_DisplayYUVOverlay(bmp, &rect);
}
到此为止,视频能够显示了。
我们来看一下SDL 的另外一个特性:它的event 系统。当你在SDL 程序里面,打字,或者移动鼠标的时候,或者给它发送一个信号,它会产生一个事件 **event**.你的程序 会检查这些事件是否需要处理。你的程序也可以自己生成事件来发送给SDL event系统。这在SDL多线程编程时尤其有用,我们将在tutorial4看到。在这个程序中,我们在处理完一个packet后获取事件。现在,我们要处理SDL_QUIT事件,这样可以退出。
SDL_Event event;
av_free_packet(&packet);
SDL_PollEvent(&event);
witch(event.type){
case SDL_Quit:
SDL_Quit();
exit(0);
break;
default:
break;
}
=====================
注意:
1.本例子中使用的SDL是用的1.2.xxx版本的,目前最新的是2.X版,有很大的不同,
我在测试该例子的时候,专门下载了1.2.XXX版的
2.同教程1一样,需要把SDL的lib和include包含到工程的属性里面
我这里没有放到工程里,而是设置成全局的
方法参考
/article/2129062.html
其中那个菜单直接在“视图”菜单里面就有 ,即“属性管理器”
3.可能会出现错误 =====================
注意:
1.本例子中使用的SDL是用的1.2.xxx版本的,目前最新的是2.X版,有很大的不同,
我在测试该例子的时候,专门下载了1.2.XXX版的
2.同教程1一样,需要把SDL的lib和include包含到工程的属性里面
我这里没有放到工程里,而是设置成全局的
方法参考
/article/2129062.html
其中那个菜单直接在“视图”菜单里面就有 ,即“属性管理器”
3.可能会出现错误
无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用
这个原因是没有把SDLmain.lib 放进去,放到连接库 里面即可。
4.
4.
SDL的YUV接受4种YUV格式,最快的就是YV12,这和 YUV420P相似,只是UV被交换了。
420 表示是以4:2:0的比例来采样,
P planar 表示YUV在不同的数组中,即是分开放的。
======下面是如何使用SDL的简单说明
1.先include进文件,初始化SDL
#include <SDL.h>
#include <SDL_thread.h>
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO| SDL_INIT_TIMER))
{
fprintf(stderr, "could not initialize SDL--%s\n", SDL_GetError());
exit(1);
}
SDL_Init() 告诉库我们将要使用哪些特性
2.创建一个Display
现在我们需要一个填充的screen,显示图像的区域叫做“surface”
SDL_Surface *screen;
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
if(!screen)
{
fprintf(stderr, "SDL:could not set video mode-- exiting\n");
exit(1);
}
z到这里,用宽度和高度建立了一个screen。
SDL_SetVideoMode的第三个参数表示screen的深度--0是一个特殊的值,表示与当前display的值一样。
现在我们要在screen的上面创建一个YUV overlay,这样我们可以把视频放进去,并且创建一个SWSContext来把图像数据转换成YUV420;
SDL_Overlay *bmp = NULL;
struct SWSContext *sws_ctx = NULL;
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,
SDL_YV12_OVERLAY, screen);
// initialize SWS context for software scaling
sws_ctx = sws_getContext(pCodecCtx->width,
pCodecCtx->height,
pCodecCtx->pix_fmt,
pCodecCtx->width,
pCodecCtx->height,
PIX_FMT_YUV420P,
SWS_BILINEAR,
NULL,
NULL,
NULL
);
就像我们所说的,我们使用了YV12来显示图像,并从ffmpeg中得到YUV420数据。
### 显示图像
为了显示图像,我们创建一个AVPicture结构体,设置它的数据指针和linesize到YUV overlay
if(frameFinished)
{
SDL_LockYUVOverlay(bmp);
AVPicture pict;
pict.data[0] = bmp->pixels[0];
pict.data[1] = bmp->pixels[2];
pict.data[2] = bmp->pixels[1];
pict.linesize[0] = bmp->pitches[0];
pict.linesize[1] = bmp->pitches[2];
pict.linesize[2] = bmp->pitches[1];
//Convert the image into YUV format taht sdl uses
sws_scale(sws_ctx, (uint8_t const* const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pict.data, pict.linesize);
SDL_UnlockYUVOverlay(bmp);
}
首先,我们lock了overlay,因为我们要往里面写。AVPicture结构体,有一个data指针,是一个4个指针的数组。我们在处理YUV420P,所以只用了3个通道。linesize,就像名字表示的那样。在YUV中相对应的名字是‘pixels` and `pitches。
pitches指的是一个给定line的宽度。
我们给pict写数据,实际就是给ovelay来写。
### 画图像
我们仍旧需要告诉SDL来实际显示我们给他的数据。我们要给这个函数传递一个矩形,以便告诉它视频在哪里显示以及高度和宽度。这样,SDL就能做scale,并且这可以得到GPU的协助以便更快的scale。
SDL_Rect rect;
if(frameFinished)
{
......
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL_DisplayYUVOverlay(bmp, &rect);
}
到此为止,视频能够显示了。
我们来看一下SDL 的另外一个特性:它的event 系统。当你在SDL 程序里面,打字,或者移动鼠标的时候,或者给它发送一个信号,它会产生一个事件 **event**.你的程序 会检查这些事件是否需要处理。你的程序也可以自己生成事件来发送给SDL event系统。这在SDL多线程编程时尤其有用,我们将在tutorial4看到。在这个程序中,我们在处理完一个packet后获取事件。现在,我们要处理SDL_QUIT事件,这样可以退出。
SDL_Event event;
av_free_packet(&packet);
SDL_PollEvent(&event);
witch(event.type){
case SDL_Quit:
SDL_Quit();
exit(0);
break;
default:
break;
}
=====================
注意:
1.本例子中使用的SDL是用的1.2.xxx版本的,目前最新的是2.X版,有很大的不同,
我在测试该例子的时候,专门下载了1.2.XXX版的
2.同教程1一样,需要把SDL的lib和include包含到工程的属性里面
我这里没有放到工程里,而是设置成全局的
方法参考
/article/2129062.html
其中那个菜单直接在“视图”菜单里面就有 ,即“属性管理器”
3.可能会出现错误 =====================
注意:
1.本例子中使用的SDL是用的1.2.xxx版本的,目前最新的是2.X版,有很大的不同,
我在测试该例子的时候,专门下载了1.2.XXX版的
2.同教程1一样,需要把SDL的lib和include包含到工程的属性里面
我这里没有放到工程里,而是设置成全局的
方法参考
/article/2129062.html
其中那个菜单直接在“视图”菜单里面就有 ,即“属性管理器”
3.可能会出现错误
无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用
这个原因是没有把SDLmain.lib 放进去,放到连接库 里面即可。
4.
无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用
这个原因是没有把SDLmain.lib 放进去,放到连接库 里面即可。4.
相关文章推荐
- Android消息机制字典型探究(一)
- 条件随机场CRF HMM,MEMM的比较
- Codeforces Beta Round #37 C. Old Berland Language 暴力 dfs
- IM聊天系统
- C# Sort排序
- dubbo服务者配置说明
- dubbo服务者配置说明
- Oracle10GODP连接11G数据库,出现ORA - 1017用户名/口令无效; 登录被拒绝 的问题
- MDWIKI
- 自搭博客日记2
- 优化的网站注册时[验证邮箱]的流程
- 字符串反转方法汇总
- Google官方 由浅入深详解Fragment【附Fragment使用常见问题】
- android收货地址整理
- poj 3384 半平面交
- Android 截屏技术
- 简单的图片查看器---ImageView的学习
- ICMP
- jmeter(3)简单的HTTP请求(非录制)
- QT类中keyPressEvent函数的重写