FFmpeg 4.3 H265七,使用SDLVSQT显示yuv文件 改造 - 工厂模式封装,接口可以既使用SDL,也可以使用Opengl等其他显示图片. SDL图像缩放-锯齿问题。starttimer

前言

前面几节的学习都是通过SDL 播放 YUV 文件, 或者 一张图片
实际开发中,我们并不一定使用SDL 来完成播放的操作,还可以通过opengl 或者其他第三方的来播放。
因此我们这里有了一个想法:可以封装一套 videoview 的播放API ,让SDL 或者 OpenGL 都来继承这些 API以及具体的实现。
这样的好处是:这一套 动态库 或者 静态库 可以用到很多项目中,而不是只能用于SDL 中,如果后续用OpenGL 实现,只需要写一个OpenGL的实现即可

零,工厂模式回顾

一,定义父类以及 接口

父类名为 XVideoView:

包含了 多个需要子类实现的 纯虚函数。

1.1 第一个对外接口 -让user选择哪种子类实现 视频文件的显示

static XVideoView* create(ViewType type = SDL_TYPE);

该方法需要在XVideoView.cpp中实现,传递不同的ViewType,就生成不同的


    ////////////////////////////////////////////////////
    ///ViewType 是自定义的枚举类型, 包含支持的类型,比如说SDL, OPENGL,这一步让user 选择使用SDL 显示,还是使用 其他方式显示
    ///默认参数是SDL_TYPE,如果不传递参数,默认就是使用SDL 渲染图像
    static XVideoView* create(ViewType type = SDL_TYPE);

1.2 第二个对外接口-初始化渲染窗口函数,这个是要具体的子类实现的。

virtual bool Init(int width, int height, Format fmt = RGBA8888, void* winid = nullptr) = 0;

因此该函数的设计必须是纯虚函数。且要保证线程安全。

    //////////////////////
    /// 纯虚函数,初始化渲染窗口 线程安全
    /// 子类必须实现,如果子类是XSDL,那么init方法里面就需要完成关于sdl的初始化实现
    /// @param width  视频文件的分辨率 ,例如 1080 * 720,width的值就是1080
    /// @param height 视频文件的分辨率 ,例如 1080 * 720,height的值就是720
    /// @param fmt 类似 RGB888,YUV420P ,表示的是绘制的格式
    /// @param winid 窗口句柄,如果为空,创建新窗口
    /// @return 是否创建成功
    /// 
    virtual bool Init(int width, int height, Format fmt = RGBA8888, void* winid = nullptr) = 0;

  

1.3第三个对外接口 - 渲染图像函数,这个是要具体的子类实现的。

因此该函数的设计必须是纯虚函数。且要保证线程安全。

    virtual bool Draw(const unsigned char* data, int linesize = 0) = 0;

    //////////////////////////////////////////////////
    /// 渲染图像 线程安全
    ///@para data 渲染的二进制数据
    ///@para linesize 一行数据的字节数,对于YUV420P就是Y一行字节数
    /// linesize<=0 就根据宽度和像素格式自动算出大小
    /// @return 渲染是否成功
    virtual bool Draw(const unsigned char* data, int linesize = 0) = 0;

1.4 第四个对外接口 - 清理所有申请的资源函数,这个是要具体的子类实现的。

virtual void Close() = 0;

    //清理所有申请的资源,包括关闭窗口
    virtual void Close() = 0;

1.5  第五个对外接口,记录当前 包裹  视频文件 UI组件的宽和高

我们的视频文件在实际开发中一般显示 在一个 ui 组件中,当user 将整个界面放大,缩小,全屏的情况下,包裹视频文件的UI组件也会跟着变大,变小,因此我们需要记录 包裹UI 组件的大小。,这样就可以 让 视频填充 的时候,知道 包裹 UI的大小。

    void setscaleLable(int labelwidth, int lableheight);

    //当我们将widget的大小变化的时候,存放视频的 lable 控件的大小也要跟着变化,我们需要记录 lable的宽和高


    void setscaleLable(int labelwidth, int lableheight);

1.6 第六个对外接口,该函数主要是为了不使用winid创建的 窗口,如何关闭问题,一般开发中不会使用到。

    /// 处理窗口退出事件,这个方法主要是为了在不使用qt的windows的情况下,意味着创建的显示sdl的window是和 label没有关系的
    /// 那么这个窗口的关闭是要接受  sdl的quit_event 事件,即:我们在 isexit 内部实现中调用 SDL_WaitEventTimeout
    /// 那么在什么时候调用这个isexit方法呢?在qt的 timeevent中调用就OK了
    virtual bool IsExit() = 0;

1.6 测试说明:main.cpp中调用 XVideoViewRefactory.cpp 显示,

main.cpp,中调用 xvideoviewrefactory.cpp 显示

二 父类关键变量说明,以及父类的创建子类的函数实现

关键变量 和 枚举

protected:
	int width_ = 0;				//视频文件的分辨率 例如 1080 * 720,width_的值就是1080
	int height_ = 0;			//视频文件的分辨率 例如 1080 * 720,height_的值就是720
	Format fmt_ = RGBA8888;		//视频文件的像素格式
	std::mutex mtx_;			//确保线程安全


	int lablewidth_ = 0; //放置 视频的 lable 的宽和高
	int lableheight_ = 0;
	void* winid_ = nullptr;


public:
	enum  Format{
		RGBA8888 = 0,		// sdl 对应格式为 SDL_PIXELFORMAT_RGBA8888,OPENGL对应格式为xxxxx
		ARGB8888,			// sdl 对应格式为 SDL_PIXELFORMAT_ARGB8888,OPENGL对应格式为xxxxx
		YUV420P				// sdl 对应格式为 SDL_PIXELFORMAT_IYUV,OPENGL对应格式为xxxxx
	};
	enum ViewType {
		SDL_TYPE,
		OPENGL_TYPE
	};

创建子类的函数实现

XVideoView* XVideoView::create(ViewType type)
{
	switch (type)
	{
	case XVideoView::ViewType::SDL_TYPE:
		qDebug() << "XVideoView create XSDL.class";
		return new XSDL();
		break;
	default:
		break;
	}
	return nullptr;
}

void
敬告:该系列的课程在抓紧录制更新中,敬请大家关注。敬告:本课程项目仅供学习参考,请不要直接商用,概不负责任何法律责任。 该系列的课程涉及:FFmpeg,WebRTC,SRS,Nginx,Darwin,Live555,等。包括:音视频、流媒体、直播、Android、视频监控28181、等。 我将带领大家一起来学习使用FFmpeg开发视频监控项目,并动手操练。具体内容包括: 一、视频监控的架构和流程二、FFmpeg4.3+SDL2+Qt5开发环境的搭建三、FFmpeg的SDK编程回顾总结并操练四、SDL2.0的编程回顾总结并操练五、颜色空间转换RGB和YUV的原理与实战六、Qt5+FFmpeg本地摄像头采集预览实战、代码封装:摄像头h264/5编码并存储八、Qt5+FFmpeg单路网络摄像头采集预览九、Qt5+FFmpeg单路网络摄像头采集预览录制会看十、onvif与GB/T-28181的简介  音视频与流媒体是一门很复杂的技术,涉及的概念、原理、理论非常多,很多初学者不学 基础理论,而是直接做项目,往往会看到c/c++的代码时一头雾水,不知道代码到底是什么意思,这是为什么呢?   因为没有学习音视频和流媒体的基础理论,就比如学习英语,不学习基本单词,而是天天听英语新闻,总也听不懂。 所以呢,一定要认真学习基础理论,然后再学习播放器、转码器、非编、流媒体直播、视频监控、等等。   梅老师从事音视频与流媒体行业18年;曾在永新视博、中科大洋、百度、美国Harris广播事业部等公司就职,经验丰富;曾亲手主导广电直播全套项目,精通h.264/h.265/aac,曾亲自参与百度app上的网页播放器等实战产品。  目前全身心自主创业,主要聚焦音视频+流媒体行业,精通音视频加密、流媒体在线转码快编等热门产品。  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值