首页 > 解决方案 > 如何在 Swift 中处理 c 枚举回调函数

问题描述

我想像这样设置一个自定义的快速回调函数

codecCtx.get_format = negotiatePixelFormat

其中 C 回调函数get_format声明为 this

var get_format: (@convention(c) (UnsafeMutablePointer<AVCodecContext>?, UnsafePointer<AVPixelFormat>?) -> AVPixelFormat)!

我的自定义 swift 函数函数看起来像这样

private func negotiatePixelFormat(codecContext:AVCodecContext,pixelFormat:AVPixelFormat)->AVPixelFormat{
        while pixelFormat == AV_PIX_FMT_NONE {
            if pixelFormat == AV_PIX_FMT_VIDEOTOOLBOX{
                if codecContext.hwaccel_context == nil{
                    return codecContext.pix_fmt //TBD
                }
            }
            return pixelFormat //TBD
        }
        return AV_PIX_FMT_NONE //TBD
    }

但我不知道如何将这些类型的函数合并在一起,也不能在哪里搜索某种文档。


原始的所有C代码如下

codecCtx->get_format = negotiatePixelFormat

自定义回调函数在哪里

static enum AVPixelFormat negotiate_pixel_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) {
    while (*fmt != AV_PIX_FMT_NONE) {
        if (*fmt == AV_PIX_FMT_VIDEOTOOLBOX) {  
            if (s->hwaccel_context == NULL) {
                int result = av_videotoolbox_default_init(s);
                if (result < 0) {
                    return s->pix_fmt;
                }
            }
            return *fmt;
        }
        ++fmt;
    }
    return s->pix_fmt;
}

标签: cswiftcallback

解决方案


当您知道回调的类型被导入为:

var get_format: (@convention(c) (UnsafeMutablePointer<AVCodecContext>?, UnsafePointer<AVPixelFormat>?) -> AVPixelFormat)!

你需要定义一个函数(UnsafeMutablePointer<AVCodecContext>?, UnsafePointer<AVPixelFormat>?),并返回AVPixelFormat

因此,您可能需要声明一个 Swift 函数,例如:

func negotiatePixelFormat(_ s: UnsafeMutablePointer<AVCodecContext>?, _ fmt: UnsafePointer<AVPixelFormat>?) -> AVPixelFormat {
    //...
}

据我所知,您在 C 中的回调函数在 Swift 中如下所示:

func negotiatePixelFormat(_ s: UnsafeMutablePointer<AVCodecContext>?, _ fmt: UnsafePointer<AVPixelFormat>?) -> AVPixelFormat {
    guard let s = s, var fmt = fmt else {
        return AV_PIX_FMT_NONE
    }
    while fmt.pointee != AV_PIX_FMT_NONE {
        if fmt.pointee == AV_PIX_FMT_VIDEOTOOLBOX {
            if s.pointee.hwaccel_context == nil {
                let result = av_videotoolbox_default_init(s)
                if result < 0 {
                    return s.pointee.pix_fmt
                }
            }
            return fmt.pointee
        }
        fmt += 1
    }
    return s.pointee.pix_fmt
}

您显示的信息缺少一些细节,因此您可能需要修复此代码的某些部分。


推荐阅读