为了显示视频,我们使用SDL(SDL官方地址)。
SDL是一款优秀的跨平台的多媒体类库,可以直接在窗口绘制图片(视频流)。
本例中的视频流格式采用YCbCr。为了方便,许多人将YCbCr称为YUV。然而,YUV是模拟数据,YCbCr是数字数据。ffmpeg和SDL采用YCbCr格式。
现在,我们使用SDL替代示例1中的saveFrame,将视频流直接输出到屏幕上。
1.初始化SDL类库
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)){
cout << SDL_GetError() << endl;
return -1;
}
SDL_Init: 参数用来指定初始化SDL的不同模块;
SDL_GetError: 输出调试信息。
2.创建SDL绘制窗体
//create window
SDL_Window *window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
nWidth, nHeight, SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
if(window == nullptr){
cout << SDL_GetError() << endl;
return -1;
}
//create render
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(renderer == nullptr){
cout << SDL_GetError() << endl;
return -1;
}
//get renderer info
SDL_RendererInfo renderer_info = {0};
if(!SDL_GetRendererInfo(renderer, &renderer_info)){
cout << renderer_info.name << endl;
//return -1;
}
if(!renderer_info.num_texture_formats){
cout << SDL_GetError() << endl;
return -1;
}
//create texture
Uint32 pixFormat = SDL_PIXELFORMAT_IYUV;
SDL_Texture *pTexture = SDL_CreateTexture(renderer, pixFormat,
SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);
SDL界面绘制工作包括以下部分:
a.创建窗体(window); SDL_CreateWindow
b.为窗体创建一个绘制上下文(render); SDL_CreateRenderer
c.获取当前窗体的绘制信息(差错检查); SDL_GetRendererInfo
d.创建纹理(texture); SDL_CreateTexture
3.数据流与纹理数据绑定
sws_scale(sws_ctx, pFrame->data, pFrame->linesize,
0, pCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
SDL_UpdateTexture(pTexture, nullptr, pFrameYUV->data[0], pFrameYUV->linesize[0]);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, pTexture, nullptr, nullptr);
SDL_RenderPresent(renderer);
4.SDL事件循环
SDL_PollEvent(&event);
switch(event.type){
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
default:
break;
}
SDL事件循环主要为响应GUI交互(鼠标、键盘等消息)。
至此,一个视频显示界面程序已经完成,接下来,我们需要加入音频播放。