如何使用指向C数据的指针在Golang中写入文件?

我正在使用FFmpeg编写一个用于Windows平台的应用程序,它是golang包装器goav,但我无法理解如何使用C指针来获取对数组的访问权限。

我正在尝试将来自C的uint8指针指向的帧数据写入golang中的.ppm文件。

一旦我完成了这个,为了certificateFFmpeg正在做我期望的概念,我想在OpenGl中将帧设置为纹理,以使video播放器具有很酷的过渡; 任何指向做得好而有效的指针将非常有帮助! 我猜我需要写一些着色器代码来绘制ppm作为纹理……

PPM文件结构看起来非常简单,只有标题,然后是从左上角到右下角的帧中每个像素的每个红色,绿色和蓝色值的数据字节

我开始理解如何在C和Go类型之间转换指针,但是我如何访问数据并在Go中写入与C相同的结果? 在CI中,只需设置数据的指针偏移量并说明要写入多少:

for (y = 0; y data[0]+y*pFrame->linesize[0], 1, width*3, pFile); } 

我已经删除了C代码的所有相关部分,包装器和我的代码,如下所示:

C代码 – libavutil / frame.h

 #include  typedef struct AVFrame { #define AV_NUM_DATA_POINTERS 8 uint8_t *data[AV_NUM_DATA_POINTERS]; int linesize[AV_NUM_DATA_POINTERS]; } 

Golang goav包装纸

 package avutil /* #cgo pkg-config: libavutil #include  #include  */ import "C" import ( "unsafe" ) type Frame C.struct_AVFrame func Data(f *Frame) *uint8 { return (*uint8)(unsafe.Pointer((*C.uint8_t)(unsafe.Pointer(&f.data)))) } func Linesize(f *Frame) int { return int(*(*C.int)(unsafe.Pointer(&f.linesize))) } 

我的Golang代码

 package main import "github.com/giorgisio/goav/avutil" func saveFrame(videoFrame *avutil.Frame, width int, height int, iFrame int) { var szFilename string var y int var file *os.File var err error szFilename = "" // Open file szFilename = fmt.Sprintf("frame%d.ppm", iFrame) if file, err = os.Create(szFilename); err != nil { log.Println("Error Reading") } // Write header fh := []byte(fmt.Sprintf("P6\n%d %d\n255\n", width, height)) file.Write(fh) var b byte = 0 // Write pixel data for y = 0; y < height; y++ { d := avutil.Data(videoFrame) // d should be a pointer to the first byte of data l := avutil.Linesize(videoFrame) // I'm basically lost trying to figure out how to correctly write // this to a file, the file is created, but when I open it in GIMP // the image is mostly black with glitchy fuzz - so it's not being // written properly; the header seems to be ok, it knows the height // and width at least. data := make([]byte, l*3) ptr := unsafe.Pointer(d) for i := 0; i < l; i++ { datum := (*uint8)(unsafe.Pointer(uintptr(ptr) + (uintptr(i)+(uintptr(y)*uintptr(l)))*unsafe.Sizeof(*d))) data = append(data, *datum) //fmt.Println(*datum) } n, err := file.Write(data) if err != nil { log.Println("Error Writing:", szFilename, "-", n) } } file.Close() } 

那么,如何使用指向数据的指针写入文件,就像在C中一样,并获得相同的结果?

第一帧应该是黑色所以0都是0但是我得到了一个毛躁的模糊,所以它必须访问一些随机数据

更新:我的修复程序使用C函数保存:

 package avutil /* #cgo pkg-config: libavutil #include  #include  #include  void SaveFrame(const char* location, AVFrame *pFrame, int width, int height) { FILE *pFile; int y; // Open file pFile=fopen(location, "wb"); if(pFile==NULL) return; // Write header fprintf(pFile, "P6\n%d %d\n255\n", width, height); // Write pixel data for(y=0; ydata[0]+y*pFrame->linesize[0], 1, width*3, pFile); // Close file fclose(pFile); } uint8_t* GetData(AVFrame *pFrame) { return pFrame->data[0]; } */ import "C" 

我在goav包装器包中更新了avutil文件,在顶部使用此保存function,然后将帧上下文传递给它,以便它可以从中获取数据指针。 我还将此Go函数添加到该avutil文件以调用C函数

 func SaveFrame(location string, f *Frame, width int, height int) { csLoc := C.CString(location) C.SaveFrame(csLoc, (*C.struct_AVFrame)(unsafe.Pointer(f)), C.int(width), C.int(height)) C.free(unsafe.Pointer(csLoc)) }