2023-03-07:x264的视频编码器,不用ffmpeg,用libx264.dll也行。请用go语言调用libx264.dll,将yuv文件编码成h264文件。
2023-03-07:x264的视频编码器,不用ffmpeg,用libx264.dll也行。请用go语言调用libx264.dll,将yuv文件编码成h264文件。
答案2023-03-07:
使用 github.com/moonfdd/x264-go 库,代码写在了这个库里。
这个库根据头文件编写,不依赖头文件。
执行命令:
go run ./examples/simplest_x264_encoder/main.go
参考了雷霄骅的基于libx264的视频编码器,代码用golang编写。代码如下:
// https://github.com/leixiaohua1020/simplest_encoder/blob/master/simplest_x264_encoder/simplest_x264_encoder.cpp
package main
import (
"fmt"
"os"
"unsafe"
"github.com/moonfdd/ffmpeg-go/ffcommon"
"github.com/moonfdd/x264-go/libx264"
"github.com/moonfdd/x264-go/libx264common"
)
func main0() ffcommon.FInt {
var ret ffcommon.FInt
var y_size ffcommon.FInt
var i, j ffcommon.FInt
//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.h264"
fp_dst, _ := os.Create(fp_dst_file)
//Encode 50 frame
//if set 0, encode all frame
var frame_num ffcommon.FInt = 0
var csp ffcommon.FInt = libx264.X264_CSP_I420
var width, height ffcommon.FInt = 640, 360
var iNal ffcommon.FInt = 0
var pNals *libx264.X264NalT
var pHandle *libx264.X264T
pPic_in := new(libx264.X264PictureT)
pPic_out := new(libx264.X264PictureT)
pParam := new(libx264.X264ParamT)
//Check
if fp_src == nil || fp_dst == nil {
fmt.Printf("Error open files.\n")
return -1
}
pParam.X264ParamDefault()
pParam.IWidth = width
pParam.IHeight = height
/*
//Param
pParam->i_log_level = X264_LOG_DEBUG;
pParam->i_threads = X264_SYNC_LOOKAHEAD_AUTO;
pParam->i_frame_total = 0;
pParam->i_keyint_max = 10;
pParam->i_bframe = 5;
pParam->b_open_gop = 0;
pParam->i_bframe_pyramid = 0;
pParam->rc.i_qp_constant=0;
pParam->rc.i_qp_max=0;
pParam->rc.i_qp_min=0;
pParam->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
pParam->i_fps_den = 1;
pParam->i_fps_num = 25;
pParam->i_timebase_den = pParam->i_fps_num;
pParam->i_timebase_num = pParam->i_fps_den;
*/
pParam.ICsp = csp
pParam.X264ParamApplyProfile(libx264.X264ProfileNames[5])
pHandle = pParam.X264EncoderOpen164()
pPic_out.X264PictureInit()
pPic_in.X264PictureAlloc(csp, pParam.IWidth, pParam.IHeight)
//ret = x264_encoder_headers(pHandle, &pNals, &iNal);
y_size = pParam.IWidth * pParam.IHeight
//detect frame number
if frame_num == 0 {
fi, _ := fp_src.Stat()
switch csp {
case libx264.X264_CSP_I444:
frame_num = int32(fi.Size()) / (y_size * 3)
case libx264.X264_CSP_I420:
frame_num = int32(fi.Size()) / (y_size * 3 / 2)
default:
fmt.Printf("Colorspace Not Support.\n")
return -1
}
}
//Loop to Encode
for i = 0; i < frame_num; i++ {
switch csp {
case libx264.X264_CSP_I444:
fp_src.Read(ffcommon.ByteSliceFromByteP(pPic_in.Img.Plane[0], int(y_size))) //Y
fp_src.Read(ffcommon.ByteSliceFromByteP(pPic_in.Img.Plane[1], int(y_size))) //U
fp_src.Read(ffcommon.ByteSliceFromByteP(pPic_in.Img.Plane[2], int(y_size))) //V
case libx264.X264_CSP_I420:
fp_src.Read(ffcommon.ByteSliceFromByteP(pPic_in.Img.Plane[0], int(y_size))) //Y
fp_src.Read(ffcommon.ByteSliceFromByteP(pPic_in.Img.Plane[1], int(y_size/4))) //U
fp_src.Read(ffcommon.ByteSliceFromByteP(pPic_in.Img.Plane[2], int(y_size/4))) //V
default:
fmt.Printf("Colorspace Not Support.\n")
return -1
}
pPic_in.IPts = int64(i)
ret = pHandle.X264EncoderEncode(&pNals, &iNal, pPic_in, pPic_out)
if ret < 0 {
fmt.Printf("Error.\n")
return -1
}
fmt.Printf("Succeed encode frame: %5d\n", i)
for j = 0; j < iNal; j++ {
a := unsafe.Sizeof(libx264.X264NalT{})
pNal := (*libx264.X264NalT)(unsafe.Pointer(uintptr(unsafe.Pointer(pNals)) + uintptr(a*uintptr(j))))
fp_dst.Write(ffcommon.ByteSliceFromByteP(pNal.PPayload, int(pNal.IPayload)))
}
}
i = 0
//flush encoder
for {
ret = pHandle.X264EncoderEncode(&pNals, &iNal, nil, pPic_out)
if ret == 0 {
break
}
fmt.Printf("Flush 1 frame.\n")
for j = 0; j < iNal; j++ {
a := unsafe.Sizeof(libx264.X264NalT{})
pNal := (*libx264.X264NalT)(unsafe.Pointer(uintptr(unsafe.Pointer(pNals)) + uintptr(a*uintptr(j))))
fp_dst.Write(ffcommon.ByteSliceFromByteP(pNal.PPayload, int(pNal.IPayload)))
}
i++
}
pPic_in.X264PictureClean()
pHandle.X264EncoderClose()
pHandle = nil
fp_src.Close()
fp_dst.Close()
fmt.Printf("\nffplay %s\n", fp_dst_file)
return 0
}
func main() {
fmt.Println(libx264.X264_POINTVER)
os.Setenv("Path", os.Getenv("Path")+";./lib")
libx264common.SetLibx264Path("./lib/libx264-164.dll")
main0()
}


2023-03-07:x264的视频编码器,不用ffmpeg,用libx264.dll也行。请用go语言调用libx264.dll,将yuv文件编码成h264文件。的更多相关文章
- C++内存管理(转)http://www.cnblogs.com/qiubole/archive/2008/03/07/1094770.html
[导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不 ...
- NPOI 导入导出excel 支持 03 07
因为微软的office成本太高了,所以开发项目的时候电脑上没安装office,而是安装了wps.但开发语言用的是C#,所以直接调用微软的office组件是很方便的,但一方面慢,一方面成本高,所以从网上 ...
- 原!操作 excel 03/07
参考 所用jar包: poi-3.11.jar poi-ooxml-3.11.jar poi-ooxml-schemas-3.11.jar /* * Project: fusion-may-open- ...
- 使用ffmpeg获取视频流后如何封装存储成mp4文件
int main(int argc,char *argv[]) 02 { 03 AVFormatContext *pFormatCtx; 04 int i,videoStream; 05 AVC ...
- [X264] MinGW编译x264,VC中调用libx264.dll-------------<参考转>
1. 下载并按照MinGW,最好就缺省按照 http://sourceforge.net/projects/ ... ler/mingw-get-inst/ 把C:\MinGW\bin添加 ...
- 引用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行 校对中里 行数为两位数 ...
- 2018/03/07 每日一个Linux命令 之 cat
每日一个Linux命令 2018-03-07 Linux 命令 cat cat [-参数] fileName 在之前的Linux使用中 cat 命令一直作为文本输出指令来使用,很少可以深入学习的该命令 ...
- 2020软件工程作业01 Deadline: 2020/03/07 20:00pm
1.建立博客 https://github.com/smithLIUandhisbaby 20177572 https://www.cnblogs.com/smith324/ 2.回顾——我的初心 对 ...
- x264 n-th pass编码时候Stats文件的含义
x264 n-th pass(一般是2pass)编码时所用的文件包括下述x264参数生成.stats文件 options: 1280x816 fps=2997/125 timebase=125/299 ...
随机推荐
- pycharm conmunity 2022.1没有mange repositories,只能使用命令方式修改镜像源(长期可信)
https://blog.csdn.net/qq_43625764/article/details/124656990
- var 和let const的区别
var 是ES5语法,let,const是ES6语法,var存在变量提升. let const有块级作用域,var没有
- SpringBoot解决跨域方案
SpringBoot解决跨域的几种方式 跨域资源共享(CORS):通过修改Http协议header的方式,实现跨域.说的简单点就是,通过设置HTTP的响应头信息,告知浏览器哪些情况在不符合同源策略的条 ...
- 在Linux中安装containerd作为kubernetes的容器运行时
概述 从kubernetes1.24开始的版本移除了内置的docker支持,用户可以自行选择需要使用的容器运行时,比如containerd.CRI-O.Docker Engine等等,这里我们采用二进 ...
- AC自动机模板题 HDU - 2222
Keywords Search HDU - 2222 贴个vj的链接https://vjudge.net/problem/HDU-2222 题意:T组数据,n个单词,再给你一个串,看有几个单词在这个 ...
- Java 2023年接地气的中高级面试题一(附答案)
直入主题: Q1:为什么要用分布式锁? 在分布式系统中,多个进程或线程可能会同时访问共享资源,这可能会导致数据不一致.并发性问题.性能下降等问题.为了解决这些问题,我们通常会使用分布式锁来协调多个进程 ...
- js函数防抖节流
// 3.1 函数防抖: // 当持续触发事件时,一定时间段内没有再次触发事件,事件处理函数才会执行一次,如果设定时间到来之前,又触发了事件,就重新开始延时.// 也就是说当一个用户一直触发这个函数, ...
- SQL Server修改sa用户密码
SQL Server数据库使用windows用户登录,安全性->登录名->找到sa用户->属性: 可直接修改sa用户密码(可去掉勾选强制实施密码策略)
- python中socket使用UDP协议简单实现服务端与客户端通信
UDP为不可靠传输,也就是发送方不关心对方是否收到消息,一般用于聊天软件.但现在的聊天软件虽然使用的是UDP协议,但已从代码层面上解决了丢失信息的问题. 下面使用python代码简单实现了服务端与客户 ...
- python之wypy入门
wxPython入门 第一个应用程序:"Hello, World!" 按惯例,我们先来写一个 "Hello, World!" 小程序.这是代码: # -*- c ...