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文件。的更多相关文章

  1. C++内存管理(转)http://www.cnblogs.com/qiubole/archive/2008/03/07/1094770.html

    [导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不 ...

  2. NPOI 导入导出excel 支持 03 07

    因为微软的office成本太高了,所以开发项目的时候电脑上没安装office,而是安装了wps.但开发语言用的是C#,所以直接调用微软的office组件是很方便的,但一方面慢,一方面成本高,所以从网上 ...

  3. 原!操作 excel 03/07

    参考 所用jar包: poi-3.11.jar poi-ooxml-3.11.jar poi-ooxml-schemas-3.11.jar /* * Project: fusion-may-open- ...

  4. 使用ffmpeg获取视频流后如何封装存储成mp4文件

    int main(int argc,char *argv[]) 02 { 03  AVFormatContext *pFormatCtx; 04  int i,videoStream; 05  AVC ...

  5. [X264] MinGW编译x264,VC中调用libx264.dll-------------<参考转>

    1. 下载并按照MinGW,最好就缺省按照    http://sourceforge.net/projects/ ... ler/mingw-get-inst/    把C:\MinGW\bin添加 ...

  6. 引用AForge.video.ffmpeg,打开时会报错:找不到指定的模块,需要把发行包第三方文件externals\ffmpeg\bin里的dll文件拷到windows的system32文件夹下。

    引用AForge.video.ffmpeg,打开时会报错:找不到指定的模块,需要把发行包第三方文件externals\ffmpeg\bin里的dll文件拷到windows的system32文件夹下. ...

  7. 需求:过滤下面这个网页里共723行 校对中里 行数为两位数的 行 并设置sz和rz在Windows和Linux之间发送和接收文件不用搭FTP

    需求:过滤下面这个网页里共723行 校对中里 行数为两位数的 行 并设置sz和rz在Windows和Linux之间发送和接收文件不用搭FTP 需求:过滤下面这个网页里共723行 校对中里 行数为两位数 ...

  8. 2018/03/07 每日一个Linux命令 之 cat

    每日一个Linux命令 2018-03-07 Linux 命令 cat cat [-参数] fileName 在之前的Linux使用中 cat 命令一直作为文本输出指令来使用,很少可以深入学习的该命令 ...

  9. 2020软件工程作业01 Deadline: 2020/03/07 20:00pm

    1.建立博客 https://github.com/smithLIUandhisbaby 20177572 https://www.cnblogs.com/smith324/ 2.回顾——我的初心 对 ...

  10. x264 n-th pass编码时候Stats文件的含义

    x264 n-th pass(一般是2pass)编码时所用的文件包括下述x264参数生成.stats文件 options: 1280x816 fps=2997/125 timebase=125/299 ...

随机推荐

  1. mysql替换空格制表符换行

    update ztbdb_pro set pro=REPLACE(pro,CHAR(10),''); update ztbdb_pro set pro=REPLACE(pro,CHAR(13),'') ...

  2. 基于Centos7 minimal 加固

    一.用户帐号和环境-----------------------. 2 二.系统访问认证和授权--------------------- 3 三.核心调整--------------------- 4 ...

  3. Git 小技巧:忽略某些文件的更改

    *以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/dp9Mwq7vf0ASF_FftBN8Ww 作为一枚合格的代码贡献 ...

  4. 密码破解-john的使用

    john类似于hashcat一样,也是一款密码破解方式,john跟专注于系统密码的破解,并且和hashcat一样在kali中自带 hash请见hash的简单使用 重要的参数 --wordlist=字典 ...

  5. 如何规避MyBatis使用过程中带来的全表更新风险

    作者:京东零售 贾玉西 一.前言 程序员A: MyBatis用过吧? 程序员B: 用过 程序员A: 好巧,我也用过,那你遇到过什么风险没?比如全表数据被更新或者删除了. 程序员B: 咔,还没遇到过,这 ...

  6. 声网 X Yalla:面对面不如线上见,中东年轻人最偏爱的语聊房是怎样“炼”成的?

    "实时互动的本质是服务,而非功能."这是声网一直以来坚信的理念. 功能上线之后,服务才真正开始.实时互动的每一秒,甚至每一毫秒的体验都需要得到稳定.可靠的保证.而广大用户之所以能够 ...

  7. Git 操作命令清单 入门到精通(保姆级)

    一般来说,日常使用只要记住下图6个命令,就可以了.但是如果你想熟练使用它,要记住大概80个命令. 下面是常用的 Git 命令.几个专用名词的译名如下: Workspace:工作区 Index / St ...

  8. Tarjan强连通分量(scc)

    概念解释 节点强连通:\(v_i\)与\(v_j\)(\(v_i ≠ v_j\))强连通是指从\(vi\)到\(vj\)和从\(vj\)到\(vi\)都存在路径,即两节点互相可达 强连通图:在有向图\ ...

  9. 移动端网页--better-scroll容易采坑合集

    移动端网页--better-scroll容易采坑合集 一.better-scroll源码bug,浏览器需要刷新一次才能正常滑动 在new BScroll时,在options中加入 mouseWheel ...

  10. Oracle_表空间

    Oracle 表空间 在执行具体的操作之前,由于Oracle不允许删除现有临时表空间,所以在删除现有临时表空间时要终止现有的实时会话. 查询Oracle表空间名称,表空间物理文件路径 查询临时表空间: ...