2023-05-04:用go語言重寫ffmpeg的scaling_video.c示例,用于實現(xiàn)視頻縮放(Scaling)功能。
答案2023-05-04:
這段代碼實現(xiàn)了使用 libswscale 庫進(jìn)行視頻縮放的功能。下面是程序的主要流程:
1.獲取命令行參數(shù),包括輸出文件名和目標(biāo)圖像大小。
2.解析目標(biāo)圖像大小,生成指定大小的輸出文件。
3.創(chuàng)建縮放上下文(scaling context)并分配輸入和輸出圖像數(shù)據(jù)的內(nèi)存空間。
4.循環(huán)生成合成圖像、將輸入圖像轉(zhuǎn)換為輸出圖像并將輸出圖像寫入輸出文件中,重復(fù)該操作若干次。
5.釋放內(nèi)存空間并關(guān)閉輸出文件。
具體步驟如下:
1.獲取命令行參數(shù)。首先檢查命令行參數(shù)是否符合要求,如果不符合則打印使用說明并退出程序。否則,解析輸出文件名和目標(biāo)圖像大小。
2.解析目標(biāo)圖像大小。調(diào)用 libavutil.AvParseVideoSize()
函數(shù)解析目標(biāo)圖像大小,并根據(jù)解析結(jié)果生成一個指定大小的輸出文件。
3.創(chuàng)建縮放上下文并分配內(nèi)存空間。調(diào)用 libswscale.SwsGetContext()
函數(shù)創(chuàng)建一個縮放上下文,并使用 libavutil.AvImageAlloc()
函數(shù)分配輸入和輸出圖像數(shù)據(jù)的內(nèi)存空間。
4.循環(huán)處理圖像。在循環(huán)中,首先生成一個 YUV420P 格式的合成圖像。然后,調(diào)用 libswscale.SwsScale()
函數(shù)將輸入圖像轉(zhuǎn)換為輸出圖像。最后,將輸出圖像寫入輸出文件中。在本程序中,處理圖像的循環(huán)次數(shù)為 100 次。
5.釋放內(nèi)存空間并關(guān)閉輸出文件。在程序結(jié)束時,需要釋放輸入和輸出圖像數(shù)據(jù)的內(nèi)存空間,并關(guān)閉輸出文件。
整個程序的主要目的是演示如何使用 libswscale 庫進(jìn)行視頻縮放。它通過調(diào)用 libswscale 庫的函數(shù) SwsGetContext()
和 SwsScale()
實現(xiàn)了將一系列輸入圖像轉(zhuǎn)換為指定大小的輸出圖像的功能。
代碼見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代碼如下:文章來源:http://www.zghlxwxcb.cn/news/detail-433642.html
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()
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-433642.html
到了這里,關(guān)于2023-05-04:用go語言重寫ffmpeg的scaling_video.c示例,用于實現(xiàn)視頻縮放(Scaling)功能。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!