libswscale错误的dst图像指针cgo

libswscale错误的dst图像指针cgo,go,ffmpeg,cgo,swscale,Go,Ffmpeg,Cgo,Swscale,我试图在使用cgo编码到h264之前使用libswscale来缩放图像。这里我编写了一个简单的演示(很抱歉代码风格不好,我只想快速验证): 每次运行代码段时,我都会收到一个错误,提示错误的dst图像指针,我的代码有什么问题。我是cgo的新手,所以代码对你来说可能很傻,我为此道歉。 如果你有更优雅的方式来实现功能,我洗耳恭听。如有任何建议,我们将不胜感激。swscale需要一个二维阵列。这是指向指针数组的指针。每个指针指向图像的不同平面(y、u、v)。您正在创建一个缓冲区,并将一个指针传递给该缓冲

我试图在使用cgo编码到h264之前使用libswscale来缩放图像。这里我编写了一个简单的演示(很抱歉代码风格不好,我只想快速验证):

每次运行代码段时,我都会收到一个错误,提示
错误的dst图像指针
,我的代码有什么问题。我是cgo的新手,所以代码对你来说可能很傻,我为此道歉。
如果你有更优雅的方式来实现功能,我洗耳恭听。如有任何建议,我们将不胜感激。

swscale需要一个二维阵列。这是指向指针数组的指针。每个指针指向图像的不同平面(y、u、v)。您正在创建一个缓冲区,并将一个指针传递给该缓冲区的指针。没有指向给定给swscale的U和V平面的指针。因此指针是错误的。

事实证明,我的输入和输出缓冲区都是错误的,它们都需要是@szatmary提到的二维数组。这是工作代码

func Scale(img []byte, outw, outh int) []byte {
    input, _, _ := image.Decode(bytes.NewReader(img))
    if a, ok := input.(*image.YCbCr); ok {
        width, height := a.Rect.Dx(), a.Rect.Dy()
        var format C.enum_AVPixelFormat = C.AV_PIX_FMT_YUV420P
        context := C.sws_getContext(C.int(width), C.int(height), format, C.int(outw), C.int(outh), 0, C.int(0x10), nil, nil, nil)
        y := (*C.uint8_t)(C.malloc(C.ulong(len(a.Y))))
        C.memcpy(unsafe.Pointer(y), unsafe.Pointer(&a.Y[0]), (C.size_t)(len(a.Y)))
        cb := (*C.uint8_t)(C.malloc(C.ulong(len(a.Cb))))
        C.memcpy(unsafe.Pointer(cb), unsafe.Pointer(&a.Cb[0]), (C.size_t)(len(a.Cb)))
        cr := (*C.uint8_t)(C.malloc(C.ulong(len(a.Cr))))
        C.memcpy(unsafe.Pointer(cr), unsafe.Pointer(&a.Cr[0]), (C.size_t)(len(a.Cr)))
        in := []*C.uint8_t{y, cb, cr}
        stride := []C.int{C.int(a.YStride), C.int(a.CStride), C.int(a.CStride), 0}
        outstride := []C.int{C.int(outw), C.int(outw / 2), C.int(outw / 2), 0}
        paneSize := outw * outh
        a := (*C.uint8_t)(C.malloc(C.ulong(paneSize)))
        b := (*C.uint8_t)(C.malloc(C.ulong(paneSize >> 2)))
        c := (*C.uint8_t)(C.malloc(C.ulong(paneSize >> 2)))
        out := []*C.uint8_t{a, b, c}
        C.sws_scale(context, (**C.uint8_t)(unsafe.Pointer(&in[0])), (*C.int)(&stride[0]), 0,
            C.int(height), (**C.uint8_t)(unsafe.Pointer(&out[0])), (*C.int)(&outstride[0]))
        min := image.Point{0, 0}
        max := image.Point{outw, outh}
        output := image.NewYCbCr(image.Rectangle{Min: min, Max: max}, image.YCbCrSubsampleRatio420)
        C.memcpy(unsafe.Pointer(&output.Y[0]), unsafe.Pointer(a), (C.size_t)(paneSize))
        C.memcpy(unsafe.Pointer(&output.Cb[0]), unsafe.Pointer(b), (C.size_t)(paneSize>>2))
        C.memcpy(unsafe.Pointer(&output.Cr[0]), unsafe.Pointer(c), (C.size_t)(paneSize>>2))
        opt := jpeg.Options{
            Quality: 75,
        }
        var buf bytes.Buffer
        w := bufio.NewWriter(&buf)
        jpeg.Encode(w, output, &opt)
        return buf.Bytes()
    }
    return nil
}

这与C无关。@stderr谢谢你的提醒,编辑了如何传递一个二维数组,我尝试了:=[]*C.int{(*C.int)(不安全的指针(&a[0]),(*C.int)(不安全的指针(&b[0]),(*C.int)(不安全的指针(&C[0]),nil}C.sws_尺度(上下文,**C.uint8\t)(unsafe.Pointer(&in[0]),(*C.int)(&stride[0]),0,C.int(height),(**C.uint8_t)(unsafe.Pointer(&out[0]),(*C.int)(&outstride[0]))但出现了恐慌:
运行时错误:cgo参数具有Go指针到Go指针
func Scale(img []byte, outw, outh int) []byte {
    input, _, _ := image.Decode(bytes.NewReader(img))
    if a, ok := input.(*image.YCbCr); ok {
        width, height := a.Rect.Dx(), a.Rect.Dy()
        var format C.enum_AVPixelFormat = C.AV_PIX_FMT_YUV420P
        context := C.sws_getContext(C.int(width), C.int(height), format, C.int(outw), C.int(outh), 0, C.int(0x10), nil, nil, nil)
        y := (*C.uint8_t)(C.malloc(C.ulong(len(a.Y))))
        C.memcpy(unsafe.Pointer(y), unsafe.Pointer(&a.Y[0]), (C.size_t)(len(a.Y)))
        cb := (*C.uint8_t)(C.malloc(C.ulong(len(a.Cb))))
        C.memcpy(unsafe.Pointer(cb), unsafe.Pointer(&a.Cb[0]), (C.size_t)(len(a.Cb)))
        cr := (*C.uint8_t)(C.malloc(C.ulong(len(a.Cr))))
        C.memcpy(unsafe.Pointer(cr), unsafe.Pointer(&a.Cr[0]), (C.size_t)(len(a.Cr)))
        in := []*C.uint8_t{y, cb, cr}
        stride := []C.int{C.int(a.YStride), C.int(a.CStride), C.int(a.CStride), 0}
        outstride := []C.int{C.int(outw), C.int(outw / 2), C.int(outw / 2), 0}
        paneSize := outw * outh
        a := (*C.uint8_t)(C.malloc(C.ulong(paneSize)))
        b := (*C.uint8_t)(C.malloc(C.ulong(paneSize >> 2)))
        c := (*C.uint8_t)(C.malloc(C.ulong(paneSize >> 2)))
        out := []*C.uint8_t{a, b, c}
        C.sws_scale(context, (**C.uint8_t)(unsafe.Pointer(&in[0])), (*C.int)(&stride[0]), 0,
            C.int(height), (**C.uint8_t)(unsafe.Pointer(&out[0])), (*C.int)(&outstride[0]))
        min := image.Point{0, 0}
        max := image.Point{outw, outh}
        output := image.NewYCbCr(image.Rectangle{Min: min, Max: max}, image.YCbCrSubsampleRatio420)
        C.memcpy(unsafe.Pointer(&output.Y[0]), unsafe.Pointer(a), (C.size_t)(paneSize))
        C.memcpy(unsafe.Pointer(&output.Cb[0]), unsafe.Pointer(b), (C.size_t)(paneSize>>2))
        C.memcpy(unsafe.Pointer(&output.Cr[0]), unsafe.Pointer(c), (C.size_t)(paneSize>>2))
        opt := jpeg.Options{
            Quality: 75,
        }
        var buf bytes.Buffer
        w := bufio.NewWriter(&buf)
        jpeg.Encode(w, output, &opt)
        return buf.Bytes()
    }
    return nil
}