由于想要学习一下音视频的知识,所以想写博客记录一下学习历程,由于在学习ffmpeg的过程中,需要进行测试,而且对应音视频的渲染播放也应该有所了解,所以第一篇音视频博客打算先写一下关于SDL的使用。
1.开发环境
开发环境:vs2019社区版
语言:cpp
SDL版本:SDL2.0.10
2.在VS工程中使用SDL
对于cpp来说,引入外部dll,只需要引入头文件,添加链接库lib就可以使用了。
但对于SDL来说,由于在SDL_main中,存在宏定义,导致了我们的main函数必须使用纯正风格的main函数
/**
* \file SDL_main.h
*
* The application's main() function must be called with C linkage,
* and should be declared like this:
* \code
* #ifdef __cplusplus
* extern "C"
* #endif
* int main(int argc, char *argv[])
* {
* }
* \endcode
*/
#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE)
#define main SDL_main
#endif
也就是main函数声明必须为下面那种,否则则会链接错误
int main(int argc, char *argv[]){}
3.SDL播放YUV的接口流程
//初始化接口,根据需要选择适当的参数
SDL_Init();
//创建播放窗口,创建播放窗口存在两种方式
SDL_CreateWindow();
SDL_CreateWindowFrom();
//创建渲染器
SDL_CreateRenderer();
//创建渲染参数
SDL_CreateTexture();
//更新渲染参数
SDL_UpdateTexture();
//清除上一帧渲染
SDL_RenderClear();
//设置渲染器参数
SDL_RenderCopy();
//渲染当前数据
SDL_RenderPresent();
//延时,也就是当前帧播放时长,例如25帧动画,播放时长应该是40ms
SDL_Delay();
4.代码
为了方便后面的使用,就将上述的函数封装为一个类,代码如下:
#ifndef _SDLPLAYER_H_
#define _SDLPLAYER_H_
#pragma once
#include "SDL.h"
#include "common.h"
struct RawFrame {
int video_height = 0;
int video_width = 0;
int video_frameRate = 0;
int video_dataLen[8] = { 0 };
int video_stride[8] = { 0 };
char* data[8] = { nullptr };
};
class SDLPlayer
{
public:
int Init();
int UnInit();
int OpenWin(int height, int width);
int CloseWin();
int RenderYUV(RawFrame& frame);
private:
SDL_Window* m_SDLwin = nullptr;
SDL_Renderer* m_SDLRender = nullptr;
SDL_Texture* m_SDLTexture = nullptr;
};
#endif // !_SDLPALYER_H_
#include "SDLPlayer.h"
int SDLPlayer::Init()
{
int nRet = 0;
nRet = SDL_Init(SDL_INIT_EVERYTHING);
return nRet;
}
int SDLPlayer::UnInit()
{
int nRet = 0;
SDL_Quit();
return nRet;
}
int SDLPlayer::RenderYUV(RawFrame& frame)
{
int nRet = 0;
if (m_SDLTexture == nullptr) {
m_SDLTexture = SDL_CreateTexture(m_SDLRender, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, frame.video_width, frame.video_height);
}
SDL_UpdateTexture(m_SDLTexture, NULL, frame.data[0], frame.video_stride[0]);
SDL_RenderClear(m_SDLRender);
SDL_RenderCopy(m_SDLRender, m_SDLTexture, NULL, NULL);
SDL_RenderPresent(m_SDLRender);
SDL_Delay(1000/frame.video_frameRate);
return nRet;
}
int SDLPlayer::OpenWin(int height, int width) {
if (m_SDLwin != nullptr && m_SDLRender != nullptr && m_SDLTexture != nullptr)
return 0;
int nRet = 0;
m_SDLwin = SDL_CreateWindow("SDL Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
width, height, SDL_WINDOW_OPENGL);
m_SDLRender = SDL_CreateRenderer(m_SDLwin, -1, 0);
return nRet;
}
int SDLPlayer::CloseWin()
{
int nRet = 0;
SDL_DestroyRenderer(m_SDLRender);
m_SDLRender = nullptr;
SDL_DestroyTexture(m_SDLTexture);
m_SDLTexture = nullptr;
SDL_DestroyWindow(m_SDLwin);
m_SDLwin = nullptr;
return nRet;
}
关于SDL的博客大概就介绍到这里,大家需要的是了解各个API的使用流程与参数的具体作用就可以了。
来源:CSDN
作者:zhuanglewei
链接:https://blog.csdn.net/a15626193757/article/details/103914415