龙空技术网

2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实

福大大架构师每日一题 201

前言:

眼前姐妹们对“c语言目标代码”大约比较看重,小伙伴们都想要知道一些“c语言目标代码”的相关文章。那么小编同时在网络上收集了一些关于“c语言目标代码””的相关知识,希望咱们能喜欢,朋友们一起来学习一下吧!

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 mainimport (    "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()}

在这里插入图片描述

福大大架构师每日一题java当死,golang当立。最新面试题,涉及golang,rust,mysql,redis,云原生,算法,分布式,网络,操作系统。493篇原创内容

公众号

标签: #c语言目标代码