c - 如何调用需要一个指向缓冲区的双指针的 Rust 函数

标签 c ffmpeg rust

我正在尝试映射以下 ffmpeg 函数:http://ffmpeg.org/doxygen/4.0/group__lavc__parsing.html#ga0dd9af605377fcbb49fffd982672d377使用rust 代码

int av_parser_parse2    (   AVCodecParserContext *      s,
        AVCodecContext *    avctx,
        uint8_t **      poutbuf,
        int *   poutbuf_size,
        const uint8_t *     buf,
        int     buf_size,
        int64_t     pts,
        int64_t     dts,
        int64_t     pos 
    )   
这是我的 Rust 代码草图:
fn parse2(
    &self, 
    av_codec_context: CodecContext,
    poutbuf: &mut [u8],
    poutbuf_size: &mut i32,
    buf: &[u8],
    pts: i64,
    dts: i64,
    pos: i64,
) -> Result<i32, Error> {
    unsafe {// ptr::null(), ptr::null_mut()
        match av_parser_parse2(self.as_mut_ptr(),
        av_codec_context.as_mut_ptr(),
        poutbuf.as_mut_ptr(),
        poutbuf_size.as_mut_ptr(),
        buf.as_mut_ptr(),
        buf.len() as i32,
        pts,
        dts,
        pos
) {
        }
    }
}
这是av_parser_parse2由 Rust 的 C 绑定(bind)生成:
pub fn av_parser_parse2(
    s: *mut AVCodecParserContext,
    avctx: *mut AVCodecContext,
    poutbuf: *mut *mut u8,
    poutbuf_size: *mut libc::c_int,
    buf: *const u8,
    buf_size: libc::c_int,
    pts: i64,
    dts: i64,
    pos: i64,
) -> libc::c_int
我在 2 个参数中遇到问题:
        poutbuf.as_mut_ptr(),
        poutbuf_size.as_mut_ptr(),
如何制作双指针?在 ffmpeg 中,用户将提供一个指向空缓冲区和大小的指针,这将被函数 av_parser_parse2 覆盖。 .我想我不想要 poutbuf: &mut [u8] , poutbuf_size: &mut i32,论据。也许我需要返回一个全新的Vec对于每个 parse2称呼?所以 parse2 的返回值将是元组 Vec, i32 .
所以我觉得我应该起飞poutbufpoutbuf_size从参数中调用 av_parser_parse2将成为 Vec 的东西返回。但是,我不能通过 Vec作为双指针,因为我不知道返回数据包的大小。
如何处理返回的缓冲区?

最佳答案

正如我从文档中了解到的那样,

poutbuf set to pointer to parsed buffer or NULL if not yet finished.


poutbuf_size set to size of parsed buffer or zero if not yet finished.


它们是输出参数,因此您无需在输入中指定它们,它将由 FFMPEG 分配。我不确定如何释放它,也许是 decode_frame(data, size);示例中使用。
如果我是对的,它必须以某种方式这样调用:
fn parse2<'a>(
    &'a self, 
    av_codec_context: CodecContext,
    buf: &[u8],
    pts: i64,
    dts: i64,
    pos: i64,
) -> (i32, Option<NonNull<[u8]>>) {
    let mut poutbuf: *mut u8 = ptr::null();
    let mut poutbuf_size: usize = 0;
    unsafe {
        let len = av_parser_parse2(self.as_mut_ptr(),
                av_codec_context.as_mut_ptr(),
                &mut poutbuf as *mut *mut u8,
                &mut poutbuf_size as *mut usize,
                buf.as_mut_ptr(),
                buf.len() as i32,
                pts,
                dts,
                pos
            );

        // Used pointer because I don't know who must deallocate this
        // If it must be deallocated by Rust, consider `Box<[u8]>`
        let poutbuf: Option<NonNull<[u8]>> = 
            if poutbuf::is_null(){ None }
            else {
                Some( NonNull::from(slice::from_raw_parts(poutbuf, poutbuf_size)))
            };
        (len, poutbuf)
    }
}

关于c - 如何调用需要一个指向缓冲区的双指针的 Rust 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64192169/

相关文章:

c - 将 fscanf/sscanf 字符串传递到结构字段 char[4]

c - 如何即时创建变量名称

java - 如何使用 ffmpeg Android 合并两个视频

macos - 如何使用 ffmpeg 在 Mac 上捕获定时屏幕录制

pointers - 如何创建一个可以在单个单词大小内容纳整数或指针的 Rust 类型?

rust - 错误 : cannot assign to immutable indexed content `i[..]`

rust - 如何使用 ncurses crate 显示方框图字符?

c - 在 C 中将主文件拆分为模块

c - 我是否需要互斥锁来保护可以通过 sysfs 获取/设置的 int 值?

ffmpeg - 尽管使用所有编解码器编译 ffmpeg,但无法将 FLV 转换为 MP4