IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Python&C++相互混合调用编程全面实战-33完成扩展库pyffmpeg的尺寸和像素格式转换上下文初始化 -> 正文阅读

[C++知识库]Python&C++相互混合调用编程全面实战-33完成扩展库pyffmpeg的尺寸和像素格式转换上下文初始化

作者:虚坏叔叔
博客:https://xuhss.com

早餐店不会开到晚上,想吃的人早就来了!😄

完成扩展库pyffmpeg的尺寸和像素格式转换上下文初始化

在这里插入图片描述

一、定义上下文并支持解码函数宽高修改

XFFmepg.h添加成员变量 尺寸格式转换上下文

	// 尺寸和像素格式转换上下文 yuv->rgb
	SwsContext *sws = 0;

对应的解码函数支持修改宽高

	bool Decode(int outwidth, int outheight);

完整代码如下:

#pragma once
struct AVFormatContext;
struct AVPacket;
struct AVCodecContext;
struct AVFrame;
struct SwsContext;
class XFFmpeg
{
public:
	// 打开视频
	bool Open(const char *url);
	// 读取一阵视频 在内部存储
	bool Read();
	bool Decode(int outwidth, int outheight);
	void Close();
	XFFmpeg();
	~XFFmpeg();
	int totalms = 0;
protected:
	// 解封装上下文
	AVFormatContext *ic = 0;
	// 读取视频帧
	AVPacket *pkt = 0;
	// 解码器上下文
	AVCodecContext *vcodec = 0;
	// 解码后的yuv帧
	AVFrame *frame = 0;
	// 尺寸和像素格式转换上下文 yuv->rgb
	SwsContext *sws = 0;
};


XFFmepg.cpp添加头文件包含。因为要引入修改视频宽高的api

#include "XFFmpeg.h"
#include <stdio.h>
extern "C" {
#include "libavformat\avformat.h"
#include "libswscale\swscale.h"
}

库文件添加:

avformat.lib
avutil.lib
avcodec.lib
swscale.lib

在这里插入图片描述

对应的解码函数的实现完整代码如下:

bool XFFmpeg::Decode(int outwidth, int outheight) {
	if (!vcodec || !pkt) return false;

	// 发送到解码线程
	int re = avcodec_send_packet(vcodec, pkt);
	if (re != 0) return false;
	if (!frame)
		frame = av_frame_alloc();

	// 取到解码后的数据 yuv 前几帧会失败 失败不代表解码失败 只表示解码缓冲没有数据
	re = avcodec_receive_frame(vcodec, frame);
	if (re != 0) return false;

	// 像素格式和尺寸转换上下文
	// 将yuv转为rgb 并调整尺寸
	sws = sws_getCachedContext(sws,
		vcodec->width, vcodec->height, vcodec->pix_fmt, //原宽高/像素格式(YUV420p)
		outwidth, outheight, AV_PIX_FMT_BGRA, //目标宽高/像素格式(RGB)
		SWS_BICUBIC, // 转换的算法
		0, 0, 0
	);
	if (!sws)
	{
		// 出错一般都是参数格式有问题
		printf("sws_getCachedContext failed\n");
	}

	return true;
}

二、修改导出接口,支持python调用

由于添加了2个参数,PyFFmpeg.cpp修改导出的注册

PyObject *PyFFmpeg::Decode(PyFFmpeg*self, PyObject*args)
{
	if (!self->ff)
		Py_RETURN_FALSE;
	int w = 0;
	int h = 0;
	if (!PyArg_ParseTuple(args, "ii", &w, &h))
	{
		Py_RETURN_FALSE;
	}
	if (self->ff->Decode(w, h))
		Py_RETURN_TRUE;
	Py_RETURN_FALSE;
}
// 模块入口 模块名称 pyffmpeg
PyMODINIT_FUNC PyInit_pyffmpeg(void)
{
	PyObject *m = NULL;
	static PyModuleDef ffmod = {
		PyModuleDef_HEAD_INIT,
		"pyffmpeg",
		"", -1, 0
	};
	m = PyModule_Create(&ffmod);

	// 添加PyFFmpeg_python类
	static PyTypeObject type;
	memset(&type, 0, sizeof(PyFFmpeg));
	type.ob_base = { PyObject_HEAD_INIT(NULL) 0 };
	type.tp_name = "";
	type.tp_basicsize = sizeof(PyFFmpeg);
	type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
	type.tp_new = PyFFmpeg::Create;
	type.tp_init = (initproc)PyFFmpeg::Init;
	type.tp_dealloc = (destructor)PyFFmpeg::Close;

	static PyMethodDef ffmeth[] = {
		{ "open", (PyCFunction)PyFFmpeg::Open, METH_VARARGS, "" },
		{ "read", (PyCFunction)PyFFmpeg::Read, METH_NOARGS, "" },
		{ "decode", (PyCFunction)PyFFmpeg::Decode, METH_VARARGS, "" },
		{ NULL }
	};
	type.tp_methods = ffmeth;

	static PyGetSetDef sets[] = {
		{ "totalms", (getter)PyFFmpeg::GetTotalms, 0, 0,0 },
		{ NULL }
	};
	type.tp_getset = sets;

	// 初始化类型
	if (PyType_Ready(&type) < 0) {
		return NULL;
	}

	PyModule_AddObject(m, "PyFFmpeg", (PyObject*)&type);

	printf("Pyinit_pyffmpeg\n");
	return m;
}

三、Python传递默认宽高给解码函数

pyqt.py中添加宽高的调用:

isRunning = True
#输出的宽高,根据窗口尺寸
winWidth = 1280
winHeight = 720

#主函数 在子线程中调用,线程是c++创建
def main():
    print("Python main")
    global ff;
    global winWidth;
    global winHeight;
    while isRunning:
        #print(ff.read())
        re = ff.read()
        if re:
            print(".", end='', flush = True) #flush输出缓冲
            print(ff.decode(winWidth, winWidth), end='', flush = True)
            time.sleep(0.02)
        else:
            time.sleep(1)

运行:

在这里插入图片描述

只能保证没有出错。现在还看不到效果。

四、总结

  • 本文完成扩展库pyffmpeg的尺寸和像素格式转换上下文初始化 。
  • 如果觉得文章对你有用处,记得 点赞 收藏 转发 一波哦,博主也支持为铁粉丝制作专属动态壁纸哦~

💬 往期优质文章分享

🚀 优质教程分享 🚀

  • 🎄如果感觉文章看完了不过瘾,可以来我的其他 专栏 看一下哦~
  • 🎄比如以下几个专栏:Python实战微信订餐小程序、Python量化交易实战、C++ QT实战类项目 和 算法学习专栏
  • 🎄可以学习更多的关于C++/Python的相关内容哦!直接点击下面颜色字体就可以跳转啦!
学习路线指引(点击解锁)知识定位人群定位
🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战 💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统
?? C++ QT结合FFmpeg实战开发视频播放器??难度偏高分享学习QT成品的视频播放器源码,需要有扎实的C++知识!
💚 游戏爱好者九万人社区💚互助/吹水九万人游戏爱好者社区,聊天互助,白嫖奖品
💙 Python零基础到入门 💙Python初学者针对没有经过系统学习的小伙伴,核心目的就是让我们能够快速学习Python的知识以达到入门

🚀 资料白嫖,温馨提示 🚀

关注下面卡片即刻获取更多编程知识,包括各种语言学习资料,上千套PPT模板和各种游戏源码素材等等资料。更多内容可自行查看哦!

请添加图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 22:37:15  更:2022-07-04 22:37:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 17:23:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码