FFMPEG学习【libavcodec】:编解码器:硬件加速器桥:VDA

一、文件

vda.h

公共libavcodec VDA头文件。



二、数据结构

struct   vda_context{

VDADecoder decoder

VDA解码器对象。

编码:未使用。

解码:通过libavcodec设置/取消。


CVPixelBufferRef cv_buffer

包含当前图像数据的Core Video像素缓冲区。

编码:未使用。

编码:通过libavcodec设置。通过用户取消。


int use_sync_decoding

在同步模式下使用硬件解码器。

编码:未使用。

解码:通过用户设置。


int width

帧宽度。

编码:未使用。

解码:通过用户设置/取消。


int height

帧高度

编码:未使用。

解码:通过用户设置/取消。



int format

帧格式。

编码:未使用。

解码:通过用户设置/取消。



OSType cv_pix_fmt_type

输出图像缓冲区的像素格式。

编码:未使用。

解码:通过用户设置/取消。



uint8_t *  priv_bitstream

未使用

编码:未使用。

解码:通过用户设置/取消。



int  priv_bitstream_size;

未使用;


int priv_allocated_size

未使用


int use_ref_buffer

使用av_buffer来管理缓冲区。

当标志设置时,解码器返回的CVPixelBuffers将自动释放,因此必要时必须保留它们。 不设置此标志可能会导致内存泄漏。

编码:未使用。

解码:通过用户设置。

}

该结构用于向VDA FFmpeg HWAccel实现提供必要的配置和数据。


struct   AVVDAContext{

VDADecoder decoder;

VDA解码器对象。

调用者创建和释放。


VDADecoderOutputCallback output_callback;

必须传递给VDADecoderCreate的输出回调。


OSType cv_pix_fmt_type;

CVPixelBuffer格式VDA将用于解码帧的类型; 由调用者设置。

}

该结构体保存了用于初始化VDA解码的调用者和libavcodec之间需要传递的所有信息。

它的大小不是公共ABI的一部分,它必须使用av_vda_alloc_context()分配,并与av_free()一起释放。



三、函数

int ff_vda_create_decoder (struct vda_context *vda_ctx, uint8_t *extradata, int extradata_size)

解析:创建视频解码器。


int ff_vda_destroy_decoder (struct vda_context *vda_ctx)

销毁视频解码器。


AVVDAContext * av_vda_alloc_context (void)

解析:分配并初始化VDA上下文。

当调用者选择AV_PIX_FMT_VDA格式时,该函数应从get_format()回调中调用。 然后,主叫方必须创建将用于VDA加速解码的解码器对象(使用由libavcodec提供的输出回调)。

当使用VDA解码完成时,调用者必须摧毁解码器对象,并使用av_free()释放VDA上下文。

返回:新分配的上下文,失败时为NULL。


int av_vda_default_init (AVCodecContext *avctx)

解析:这是一个便捷的功能,可以使用内部实现创建和设置VDA上下文。

参数avctx - 相应的编解码器上下文。

返回:> = 0成功,失败时出现负ERROR码


int av_vda_default_init2(AVCodecContext * avctx,AVVDAContext * vdactx)

解析:这是一个便捷的功能,可以使用内部实现创建和设置VDA上下文。

参数: avctx - 相应的编解码器上下文

     vdactx  - 用来使用的VDA上下文

返回:> = 0成功,失败时出现负ERROR码


void av_vda_default_free(AVCodecContext * avctx)

解析:必须调用此函数来释放使用av_vda_default_init()初始化的VDA上下文。

参数: avctx - 相应的编解码器上下文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用 FFmpeg 进行音视频编解码时,需要注册相应的编解码器。可以通过 avcodec_register_all() 函数来注册 FFmpeg 中所有已经实现的编解码器。 具体步骤如下: 1. 引入头文件 ```c #include <libavcodec/avcodec.h> ``` 2. 注册编解码器 ```c avcodec_register_all(); ``` 3. 查找编解码器 在注册编解码器后,可以通过调用 avcodec_find_encoder() 或 avcodec_find_decoder() 函数来查找特定的编解码器。 例如,查找 H.264 编码器: ```c AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec) { // 没有找到 H.264 编码器 return -1; } ``` 4. 打开编解码器 在找到所需的编解码器后,可以通过调用 avcodec_open2() 函数来打开编解码器。该函数会分配一个 AVCodecContext 结构体,用于存储编解码器相关的信息。 例如,打开 H.264 编码器: ```c AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec) { // 没有找到 H.264 编码器 return -1; } AVCodecContext *codec_ctx = avcodec_alloc_context3(codec); if (!codec_ctx) { // 分配 AVCodecContext 失败 return -1; } // 设置编码参数 codec_ctx->width = width; codec_ctx->height = height; codec_ctx->time_base = (AVRational){1, fps}; codec_ctx->framerate = (AVRational){fps, 1}; // 打开编码器 if (avcodec_open2(codec_ctx, codec, NULL) < 0) { // 打开编码器失败 avcodec_free_context(&codec_ctx); return -1; } ``` 5. 使用编解码器 打开编码器后,就可以使用它进行音视频编解码了。对于编码器,可以通过调用 avcodec_send_frame() 函数发送待编码的帧,然后调用 avcodec_receive_packet() 函数获取编码后的数据包。 例如,使用 H.264 编码器进行视频编码: ```c AVPacket pkt = {0}; // 发送帧 if (avcodec_send_frame(codec_ctx, frame) < 0) { // 发送帧失败 return -1; } // 获取编码后的数据包 while (avcodec_receive_packet(codec_ctx, &pkt) == 0) { // 处理数据包 ... // 释放数据包内存 av_packet_unref(&pkt); } ``` 对于解码器,可以通过调用 avcodec_send_packet() 函数发送待解码的数据包,然后调用 avcodec_receive_frame() 函数获取解码后的帧。 例如,使用 H.264 解码器进行视频解码: ```c AVFrame *frame = av_frame_alloc(); // 发送数据包 if (avcodec_send_packet(codec_ctx, &pkt) < 0) { // 发送数据包失败 return -1; } // 获取解码后的帧 while (avcodec_receive_frame(codec_ctx, frame) == 0) { // 处理帧 ... } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值