2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实现视频缩放(Scaling)功能。
2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实现视频缩放(Scaling)功能。
答案2023-05-04:
这段代码实现了使用 libswscale 库进行视频缩放的功能。下面是程序的主要流程:
1.获取命令行参数,包括输出文件名和目标图像大小。
2.解析目标图像大小,生成指定大小的输出文件。
3.创建缩放上下文(scaling context)并分配输入和输出图像数据的内存空间。
4.循环生成合成图像、将输入图像转换为输出图像并将输出图像写入输出文件中,重复该操作若干次。
5.释放内存空间并关闭输出文件。
具体步骤如下:
1.获取命令行参数。首先检查命令行参数是否符合要求,如果不符合则打印使用说明并退出程序。否则,解析输出文件名和目标图像大小。
2.解析目标图像大小。调用 libavutil.AvParseVideoSize() 函数解析目标图像大小,并根据解析结果生成一个指定大小的输出文件。
3.创建缩放上下文并分配内存空间。调用 libswscale.SwsGetContext() 函数创建一个缩放上下文,并使用 libavutil.AvImageAlloc() 函数分配输入和输出图像数据的内存空间。
4.循环处理图像。在循环中,首先生成一个 YUV420P 格式的合成图像。然后,调用 libswscale.SwsScale() 函数将输入图像转换为输出图像。最后,将输出图像写入输出文件中。在本程序中,处理图像的循环次数为 100 次。
5.释放内存空间并关闭输出文件。在程序结束时,需要释放输入和输出图像数据的内存空间,并关闭输出文件。
整个程序的主要目的是演示如何使用 libswscale 库进行视频缩放。它通过调用 libswscale 库的函数 SwsGetContext() 和 SwsScale() 实现了将一系列输入图像转换为指定大小的输出图像的功能。
代码见github/moonfdd/ffmpeg-go库。
命令如下:
go run ./examples/internalexamples/scaling_video/main.go ./out/big_buck_bunny.mp4 640*480
./lib/ffplay -f rawvideo -pix_fmt rgb24 -video_size 640x480 ./out/big_buck_bunny.mp4
golang代码如下:
package main
import (
"fmt"
"os"
"unsafe"
"github.com/moonfdd/ffmpeg-go/ffcommon"
"github.com/moonfdd/ffmpeg-go/libavutil"
"github.com/moonfdd/ffmpeg-go/libswscale"
)
func main0() (ret ffcommon.FInt) {
var src_data, dst_data [4]*ffcommon.FUint8T
var src_linesize, dst_linesize [4]ffcommon.FInt
var src_w ffcommon.FInt = 320
var src_h ffcommon.FInt = 240
var dst_w ffcommon.FInt
var dst_h ffcommon.FInt
var src_pix_fmt libavutil.AVPixelFormat = libavutil.AV_PIX_FMT_YUV420P
var dst_pix_fmt libavutil.AVPixelFormat = libavutil.AV_PIX_FMT_RGB24
var dst_size string
var dst_filename string
var dst_file *os.File
var dst_bufsize ffcommon.FInt
var sws_ctx *libswscale.SwsContext
var i ffcommon.FInt
if len(os.Args) != 3 {
fmt.Printf("Usage: %s output_file output_size\nAPI example program to show how to scale an image with libswscale.\nThis program generates a series of pictures, rescales them to the given output_size and saves them to an output file named output_file\n.\n", os.Args[0])
os.Exit(1)
}
dst_filename = os.Args[1]
dst_size = os.Args[2]
if libavutil.AvParseVideoSize(&dst_w, &dst_h, dst_size) < 0 {
fmt.Printf("Invalid size '%s', must be in the form WxH or a valid size abbreviation\n",
dst_size)
os.Exit(1)
}
dst_file, _ = os.Create(dst_filename)
if dst_file == nil {
fmt.Printf("Could not open destination file %s\n", dst_filename)
os.Exit(1)
}
/* create scaling context */
sws_ctx = libswscale.SwsGetContext(src_w, src_h, src_pix_fmt,
dst_w, dst_h, dst_pix_fmt,
libswscale.SWS_BILINEAR, nil, nil, nil)
if sws_ctx == nil {
fmt.Printf(
"Impossible to create scale context for the conversion fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
libavutil.AvGetPixFmtName(src_pix_fmt), src_w, src_h,
libavutil.AvGetPixFmtName(dst_pix_fmt), dst_w, dst_h)
ret = -libavutil.EINVAL
goto end
}
/* allocate source and destination image buffers */
ret = libavutil.AvImageAlloc(&src_data, &src_linesize,
src_w, src_h, src_pix_fmt, 16)
if ret < 0 {
fmt.Printf("Could not allocate source image\n")
goto end
}
/* buffer is going to be written to rawvideo file, no alignment */
ret = libavutil.AvImageAlloc(&dst_data, &dst_linesize,
dst_w, dst_h, dst_pix_fmt, 1)
if ret < 0 {
fmt.Printf("Could not allocate destination image\n")
goto end
}
dst_bufsize = ret
for i = 0; i < 100; i++ {
// /* generate synthetic video */
fill_yuv_image(&src_data, &src_linesize, src_w, src_h, i)
/* convert to destination format */
sws_ctx.SwsScale((**byte)(unsafe.Pointer(&src_data)),
(*int32)(unsafe.Pointer(&src_linesize)), 0, uint32(src_h), (**byte)(unsafe.Pointer(&dst_data)), (*int32)(unsafe.Pointer(&dst_linesize)))
// /* write scaled image to file */
dst_file.Write(ffcommon.ByteSliceFromByteP(dst_data[0], int(dst_bufsize)))
}
fmt.Printf("Scaling succeeded. Play the output file with the command:\nffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
libavutil.AvGetPixFmtName(dst_pix_fmt), dst_w, dst_h, dst_filename)
end:
dst_file.Close()
libavutil.AvFreep(uintptr(unsafe.Pointer(&src_data[0])))
libavutil.AvFreep(uintptr(unsafe.Pointer(&dst_data[0])))
sws_ctx.SwsFreeContext()
if ret < 0 {
return 1
} else {
return 0
}
}
func fill_yuv_image(data *[4]*ffcommon.FUint8T, linesize *[4]ffcommon.FInt, width, height, frame_index ffcommon.FInt) {
var x, y ffcommon.FInt
/* Y */
for y = 0; y < height; y++ {
for x = 0; x < width; x++ {
//data[0][y*linesize[0]+x] = x + y + frame_index*3
*(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(data[0])) + uintptr(y*linesize[0]+x))) = byte((x + y + frame_index*3) % 256)
}
}
/* Cb and Cr */
for y = 0; y < height/2; y++ {
for x = 0; x < width/2; x++ {
// data[1][y * linesize[1] + x] = 128 + y + frame_index * 2;
// data[2][y * linesize[2] + x] = 64 + x + frame_index * 5;
*(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(data[1])) + uintptr(y*linesize[1]+x))) = byte((128 + y + frame_index*2) % 256)
*(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(data[2])) + uintptr(y*linesize[2]+x))) = byte((64 + x + frame_index*5) % 256)
}
}
}
func main() {
os.Setenv("Path", os.Getenv("Path")+";./lib")
ffcommon.SetAvutilPath("./lib/avutil-56.dll")
ffcommon.SetAvcodecPath("./lib/avcodec-58.dll")
ffcommon.SetAvdevicePath("./lib/avdevice-58.dll")
ffcommon.SetAvfilterPath("./lib/avfilter-56.dll")
ffcommon.SetAvformatPath("./lib/avformat-58.dll")
ffcommon.SetAvpostprocPath("./lib/postproc-55.dll")
ffcommon.SetAvswresamplePath("./lib/swresample-3.dll")
ffcommon.SetAvswscalePath("./lib/swscale-5.dll")
genDir := "./out"
_, err := os.Stat(genDir)
if err != nil {
if os.IsNotExist(err) {
os.Mkdir(genDir, 0777) // Everyone can read write and execute
}
}
main0()
}

2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实现视频缩放(Scaling)功能。的更多相关文章
- kFreeBSD 7.0于2013/05/04发布 桌面环境 GNOME 3....
kFreeBSD 7.0于2013/05/04发布 桌面环境 GNOME 3.4, KDE 4.8.4, Xfce 4.8, and LXDE
- 最简单的基于FFmpeg的libswscale的示例(YUV转RGB)
===================================================== 最简单的基于FFmpeg的libswscale的示例系列文章列表: 最简单的基于FFmpeg ...
- Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- 最简单的基于FFmpeg的移动端例子:IOS 视频解码器-保存
===================================================== 最简单的基于FFmpeg的移动端例子系列文章列表: 最简单的基于FFmpeg的移动端例子:A ...
- 最简单的基于FFmpeg的移动端例子:IOS 视频转码器
===================================================== 最简单的基于FFmpeg的移动端例子系列文章列表: 最简单的基于FFmpeg的移动端例子:A ...
- FFmpeg简易播放器的实现-音视频同步
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10284653.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- 最简单的基于FFmpeg的libswscale的示例附件:测试图片生成工具
===================================================== 最简单的基于FFmpeg的libswscale的示例系列文章列表: 最简单的基于FFmpeg ...
- (转)FFMPEG filter使用实例(实现视频缩放,裁剪,水印等)
本文转载自http://blog.csdn.net/li_wen01/article/details/62442162 FFMPEG官网给出了FFMPEG 滤镜使用的实例,它是将视频中的像素点替换成字 ...
- FFmpeg基础库编程开发学习笔记——视频常见格式
声明一下:这些关于ffmpeg的文章仅仅是用于记录我的学习历程和以便于以后查阅,文章中的一些文字可能是直接摘自于其它文章.书籍或者文献,学习ffmpeg相关知识是为了使用在Android上,我也才是刚 ...
- FFMPEG,将字幕“烧进”MP4视频中
原文地址:http://blog.csdn.net/ufocode/article/details/75475539 由于mp4容器,不像MKV等容器有自己的字幕流. MKV这种容器的视频格式中,会带 ...
随机推荐
- 在VMWare里安装Win11虚机
1. 安装win11有最低硬件要求 64位CPU双核,内存4G,硬盘64G,受信任的平台模块(TPM)2.0,支持UEFI安全启动 2. VMware新建虚机的设置 1)创建64位虚拟机,CPU设置为 ...
- k8s中的kubeclt命令
一.kubectl 基本命令 1.陈述式资源管理方法: 1.kubernetes集群管理集群资源的唯一入口是通过相应的方法调用apiserver的接口 2.kubectl 是官方的CLI命令行工具,用 ...
- [代码片段] 获取分辨率DPI和像素、毫米、英寸互相转换
private static float DEFAULT_DPI_X = 0; private static float DEFAULT_DPI_Y = 0; /// <summary>获 ...
- MySQL根据经纬度和距离查询最近的数据
[lat]:输入的纬度 [lon]:输入的经度 [distance]:查询距离内的数据,单位m SELECT * FROM ( SELECT id lon, lat, vin, ROUND( 6378 ...
- 从0搭建Vue3组件库(六):前端流程化控制工具gulp的使用
前言 随着前端诸如webpack,rollup,vite的发展,gulp感觉似乎好像被取代了.其实并没有,只不过它从台前退居到了幕后.我们仍然可以在很多项目中看到它的身影,比如elementplus. ...
- Python学习笔记--元组+字符串
元组 元组一旦定义完成,就不能再被修改 同样,元组也可以进行嵌套操作 当然,若是在元组里面嵌套一个list,那么list里面的元素是可以进行修改的! 案例: 实现: 字符串 查找索引值: 字符串替换: ...
- Vue前端框架的基础学习,为之后打个基础
Vue 首先,在使用vue之前,我们需要先下载好一个vue.js文件,才能继续进行vue的学习,下载教程如下: 1.进入官网:https://v2.vuejs.org/ 2.选择页面中的Learn,再 ...
- Mathematica处理若干个点电荷的电位电场的一个程序包
来自 Mathematica for Theoretical Physics Electrodynamics, Quantum Mechanics, General Relativity and Fr ...
- Hugging News #0324: 🤖️ 黑客松结果揭晓、一键部署谷歌最新大语言模型、Gradio 新版发布,更新超多!
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- GLM:通用语言模型
ChatGPT已经火了一段时间了,国内也出现了一些平替,其中比较容易使用的是ChatGLM-6B:https://github.com/THUDM/ChatGLM-6B ,主要是能够让我们基于单卡自己 ...