2023-03-08:x265的视频编码器,不用ffmpeg,用libx265.dll也行。请用go语言调用libx265.dll,将yuv文件编码成h265文件。
2023-03-08:x265的视频编码器,不用ffmpeg,用libx265.dll也行。请用go语言调用libx265.dll,将yuv文件编码成h265文件。
答案2023-03-08:
使用 github.com/moonfdd/x265-go 库,代码写在了这个库里。
这个库根据头文件编写,不依赖头文件。
执行命令:
go run ./examples/simplest_x265_encoder/main.go
参考了雷霄骅的基于libx265的视频编码器,代码用golang编写。代码如下:
// https://github.com/leixiaohua1020/simplest_encoder/blob/master/simplest_x265_encoder/simplest_x265_encoder.cpp
package main
import (
"fmt"
"os"
"unsafe"
"github.com/moonfdd/ffmpeg-go/ffcommon"
"github.com/moonfdd/x265-go/libx265"
"github.com/moonfdd/x265-go/libx265common"
)
func main0() ffcommon.FInt {
var i, j ffcommon.FInt
var ret ffcommon.FInt
var y_size ffcommon.FInt
var buff []byte
//FILE* fp_src = fopen("../cuc_ieschool_640x360_yuv444p.yuv", "rb");
fp_src, _ := os.Open("./resources/cuc_ieschool_640x360_yuv420p.yuv")
fp_dst_file := "./out/cuc_ieschool_640x360_yuv420p.h265"
fp_dst, _ := os.Create(fp_dst_file)
var pNals *libx265.X265Nal
var iNal ffcommon.FUint32T = 0
var pParam *libx265.X265Param
var pHandle *libx265.X265Encoder
var pPic_in *libx265.X265Picture
//Encode 50 frame
//if set 0, encode all frame
var frame_num ffcommon.FInt = 0
var csp ffcommon.FInt = libx265.X265_CSP_I420
var width, height ffcommon.FInt = 640, 360
//Check
if fp_src == nil || fp_dst == nil {
fmt.Printf("Error open files.\n")
return -1
}
pParam = libx265.X265ParamAlloc()
pParam.X265ParamDefault()
pParam.BRepeatHeaders = 1 //write sps,pps before keyframe
pParam.InternalCsp = csp
pParam.SourceWidth = width
pParam.SourceHeight = height
pParam.FpsNum = 25
pParam.FpsDenom = 1
//Init
pHandle = pParam.X265EncoderOpen207()
if pHandle == nil {
fmt.Printf("x265_encoder_open err\n")
return 0
}
y_size = pParam.SourceWidth * pParam.SourceHeight
pPic_in = libx265.X265PictureAlloc()
pParam.X265PictureInit(pPic_in)
if frame_num == 0 {
fi, _ := fp_src.Stat()
switch csp {
case libx265.X265_CSP_I444:
buff = make([]byte, y_size*3)
frame_num = int32(fi.Size()) / (y_size * 3)
pPic_in.Planes[0] = uintptr(unsafe.Pointer(&buff[0]))
pPic_in.Planes[1] = uintptr(unsafe.Pointer(&buff[0])) + uintptr(y_size)
pPic_in.Planes[2] = uintptr(unsafe.Pointer(&buff[0])) + uintptr(y_size*2)
pPic_in.Stride[0] = width
pPic_in.Stride[1] = width
pPic_in.Stride[2] = width
case libx265.X265_CSP_I420:
buff = make([]byte, y_size*3/2)
frame_num = int32(fi.Size()) / (y_size * 3 / 2)
pPic_in.Planes[0] = uintptr(unsafe.Pointer(&buff[0]))
pPic_in.Planes[1] = uintptr(unsafe.Pointer(&buff[0])) + uintptr(y_size)
pPic_in.Planes[2] = uintptr(unsafe.Pointer(&buff[0])) + uintptr(y_size*5/4)
pPic_in.Stride[0] = width
pPic_in.Stride[1] = width / 2
pPic_in.Stride[2] = width / 2
default:
fmt.Printf("Colorspace Not Support.\n")
return -1
}
}
//Loop to Encode
for i = 0; i < frame_num; i++ {
switch csp {
case libx265.X265_CSP_I444:
fp_src.Read(ffcommon.ByteSliceFromByteP((*byte)(unsafe.Pointer(pPic_in.Planes[0])), int(y_size))) //Y
fp_src.Read(ffcommon.ByteSliceFromByteP((*byte)(unsafe.Pointer(pPic_in.Planes[1])), int(y_size))) //U
fp_src.Read(ffcommon.ByteSliceFromByteP((*byte)(unsafe.Pointer(pPic_in.Planes[2])), int(y_size))) //V
case libx265.X265_CSP_I420:
fp_src.Read(ffcommon.ByteSliceFromByteP((*byte)(unsafe.Pointer(pPic_in.Planes[0])), int(y_size))) //Y
fp_src.Read(ffcommon.ByteSliceFromByteP((*byte)(unsafe.Pointer(pPic_in.Planes[1])), int(y_size/4))) //U
fp_src.Read(ffcommon.ByteSliceFromByteP((*byte)(unsafe.Pointer(pPic_in.Planes[2])), int(y_size/4))) //V
default:
fmt.Printf("Colorspace Not Support.\n")
return -1
}
ret = pHandle.X265EncoderEncode(&pNals, &iNal, pPic_in, nil)
fmt.Printf("Succeed encode frame: %5d\n", i)
for j = 0; j < int32(iNal); j++ {
a := unsafe.Sizeof(libx265.X265Nal{})
pNal := (*libx265.X265Nal)(unsafe.Pointer(uintptr(unsafe.Pointer(pNals)) + uintptr(a*uintptr(j))))
fp_dst.Write(ffcommon.ByteSliceFromByteP(pNal.Payload, int(pNal.SizeBytes)))
}
}
//flush encoder
for {
ret = pHandle.X265EncoderEncode(&pNals, &iNal, nil, nil)
if ret == 0 {
break
}
fmt.Printf("Flush 1 frame.\n")
for j = 0; j < int32(iNal); j++ {
a := unsafe.Sizeof(libx265.X265Nal{})
pNal := (*libx265.X265Nal)(unsafe.Pointer(uintptr(unsafe.Pointer(pNals)) + uintptr(a*uintptr(j))))
fp_dst.Write(ffcommon.ByteSliceFromByteP(pNal.Payload, int(pNal.SizeBytes)))
}
i++
}
pHandle.X265EncoderClose()
pPic_in.X265PictureFree()
pParam.X265ParamFree()
fp_src.Close()
fp_dst.Close()
fmt.Printf("\nffplay %s\n", fp_dst_file)
return 0
}
func main() {
os.Setenv("Path", os.Getenv("Path")+";./lib")
libx265common.SetLibx265Path("./lib/libx265.dll")
main0()
}


2023-03-08:x265的视频编码器,不用ffmpeg,用libx265.dll也行。请用go语言调用libx265.dll,将yuv文件编码成h265文件。的更多相关文章
- switch结构2016/03/08
Switch 03/08 一.结构 switch(){ case *: ;break;……default: ;brek;} 练习:输入一个日期,判断这一年第几天? Console.Write(&q ...
- http://www.cnblogs.com/amboyna/archive/2008/03/08/1096024.html
http://www.cnblogs.com/amboyna/archive/2008/03/08/1096024.html
- ant 介绍 http://blog.csdn.net/sunjavaduke/archive/2007/03/08/1523819.aspx
转自: 本内容包含了Ant的历史简要介绍,Ant的功能以及Ant框架的介绍,并对下载安装使用Ant进行了示例介绍,同时通过一个Java程序讲解了Ant的基本使用方法. 1. Ant简介:这 ...
- 使用ffmpeg获取视频流后如何封装存储成mp4文件
int main(int argc,char *argv[]) 02 { 03 AVFormatContext *pFormatCtx; 04 int i,videoStream; 05 AVC ...
- 引用AForge.video.ffmpeg,打开时会报错:找不到指定的模块,需要把发行包第三方文件externals\ffmpeg\bin里的dll文件拷到windows的system32文件夹下。
引用AForge.video.ffmpeg,打开时会报错:找不到指定的模块,需要把发行包第三方文件externals\ffmpeg\bin里的dll文件拷到windows的system32文件夹下. ...
- 需求:过滤下面这个网页里共723行 校对中里 行数为两位数的 行 并设置sz和rz在Windows和Linux之间发送和接收文件不用搭FTP
需求:过滤下面这个网页里共723行 校对中里 行数为两位数的 行 并设置sz和rz在Windows和Linux之间发送和接收文件不用搭FTP 需求:过滤下面这个网页里共723行 校对中里 行数为两位数 ...
- [Weekly] 2014.03.01-2014.03.08
这周写过好多东西,虽然还没有完全弄明白线段树,但是progress还是有的! 不过有时候真的很想哭,因为自己的梦想连别人看看韩剧.无所事事还要分量轻,实在不明白政治课的Teamwork意义何在,花两分 ...
- 打开自定义链接新窗口(safari JS prompt的坑!)2016.03.08
很简单的一个小练习,但做的过程中发现safari的一个坑,使用prompt()方法的时候,点击取消和不输入一样,会返回空字符' ',而不是null! 要求: 制作新按钮,"新窗口打开网站&q ...
- 2018/03/08 每日一个Linux命令 之 chattr/lsattr
每日一个Linux命令 2018-03-08 Linux 命令 chattr/lsattr chattr [-参数] [+/-属性] [文件或者目录] 经过今天没有对铃,粥熬糊了,我就知道...... ...
- 2018/03/08 每日一学PHP 之 常量defind 和 const区别
常量defind 和 const区别 什么是常量? 如字面理解的,在脚本执行期间不可改变的的量. 定义一个常量应该注意的事项? 1:常量默认大小写敏感,错误的大小写不会被识别为常量. 2:常量只能是标 ...
随机推荐
- Flask CURD(增删改查)
1.创建flask项目 2.修改配置文件: ''' config.py 保存项目配置 ''' 导入Flask模块 from flask import Flask 额外安装: 数据库操作模块 from ...
- 记录一次线上gitlab11.x升级gitlab14.x版本操作
前言:gitlab11升级到14还是有挺多需要注意的坑,也算是做一次积累吧,升级前后,gitalb的WEB界面也变化了很多,升级过程需要注意的地方我放到最后说明,挺关键的 一.首先需要下载好要升级的包 ...
- Android日常--今日的APP进度+1
学了这么久的APP,是时候拿出来实践一下啦! 今天洗的内容都比较基础,基本上不涉及到后台代码的编写,看到本阶段的目标需要连接数据库,也是有被震住哈哈哈哈哈: 我发现,第一阶段主要分为两个界面,第一个注 ...
- Java笔记第七弹
案例:复制Java文件(打印流改进版) import java.io.*; public class Main{ public static void main(String[] args) thro ...
- PicGo+Typora+Github图床配置步骤(一键上传本地图片)
PicGo+Typora+Github图床配置步骤(一键上传本地图片) 一.配置前的准备 首先你需要有一个Github账号[GitHub]. 然后下载PicGo图片上传工具[PicGo]和Typora ...
- (3) MasaFramework 入门第三篇,使用MasaFramework
首先我们需要创建一个MasaFramework模板的项目,项目名称TokenDemo,项目类型如图所示 删除Web/TokenDemo.Admin项目,新建Masa Blazor Pro项目模板 项目 ...
- Sentinel 流量控制
一.Sentinel 介绍 Sentinel 是阿里巴巴出品的面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流,流量整形.熔断降级.系统负载保护等多个维度来保障微服务的稳定性.主页地 ...
- 游戏AI——GOAP技术要点
目录 什么是GOAP(Goal-Oriented Action Planning) 介绍 细节 难点与挑战 世界表达 具体类型表示 字符串表示 bool转化为枚举 规划器 Regoap流程 Middl ...
- C++ 测试框架 GoogleTest 初学者入门篇 乙
*以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/aFeiOGO-N9O7Ab_8KJ2wxw 开发者虽然主要负责工程 ...
- docker方式实现minio数据持久化离线安装
保存镜像 root@hello:~# docker pull minio/minio Using default tag: latest latest: Pulling from minio/mini ...