ffmpeg音视频学习(1)--使用SDL播放视频流

由于想要学习一下音视频的知识,所以想写博客记录一下学习历程,由于在学习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的接口流程

ffmpeg音视频学习(1)--使用SDL播放视频流_第1张图片

//初始化接口,根据需要选择适当的参数
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的使用流程与参数的具体作用就可以了。

你可能感兴趣的:(ffmpeg)