SVT-AV1接入ffmpeg说明

一 编译集成

Files · v2.3.0 · Alliance for Open Media / SVT-AV1 · GitLab

cd /SVT-AV1/Build/linux/

./build.sh

make install

GitHub - FFmpeg/FFmpeg: Mirror of https://git.ffmpeg.org/ffmpeg.git

./configure --enable-libsvtav1 --enable-gpl --extra-ldflags='-L/usr/local/lib' --extra-libs='-lSvtAv1Enc -lz -lm -lstdc++ -ldl -lpthread' --extra-cflags='-I/usr/local/include/'

make && make install

./ffmpeg -codecs|grep av1

DEV.L. av1 Alliance for Open Media AV1 (decoders: libdav1d av1 av1_cuvid ) (encoders: libsvtav1 )

二 SVT-AV1视频编码命令行

ffmpeg -i input.mp4 -c:v libsvtav1 -crf 30 -preset 4 -y output.mp4

ffmpeg 接入wrapper代码review

#include <stdint.h> //标准头文件

#include <EbSvtAv1ErrorCodes.h> //SVT编码错误信息头文件

#include <EbSvtAv1Enc.h> //SVT编码API头文件

//以下是ffmpeg自己的头文件

#include "libavutil/common.h"

#include "libavutil/frame.h"

#include "libavutil/imgutils.h"

#include "libavutil/opt.h"

#include "libavutil/pixdesc.h"

#include "libavutil/avassert.h"

typedef enum eos_status {

EOS_NOT_REACHED = 0,

EOS_SEND,

EOS_RECEIVED

} EOS_STATUS;

typedef struct SvtContext {

const AVClass *class;

EbSvtAv1EncConfiguration enc_params; //SVT-AV1编码器的配置参数

EbComponentType *svt_handle;//SVT-AV1 编码器的句柄

EbBufferHeaderType *in_buf; //输入缓冲区

int raw_size;//原始数据大

int max_tu_size;//最大传输单元大小

AVFrame *frame;//当前处理的视频帧

AVBufferPool *pool;//缓冲池,用于管理编码输出

EOS_STATUS eos_flag;//结束状态标志

//用户选项

int hierarchial_level; //层次预测级别

int la_depth; //前瞻深度

int enc_mode;//编码模式

int rc_mode ;// 码率控制模式

int scd;//场景变化监测

int qp;//固定量化参数

int tier;//操作点层级

int tile_columns;//tile列数

int tile_rows;//tile行数

} SvtContext;

static const struct {

EbErrorType eb_err; // SVT-AV1错误码

int av_err; // FFmpeg错误码

const char *desc; // 错误描述

} svt_errors[] = {

{ EB_ErrorNone, 0, "success" },

{ EB_ErrorInsufficientResources, AVERROR(ENOMEM), "insufficient resources" },

{ EB_ErrorUndefined, AVERROR(EINVAL), "undefined error" },

{ EB_ErrorInvalidComponent, AVERROR(EINVAL), "invalid component" },

{ EB_ErrorBadParameter, AVERROR(EINVAL), "bad parameter" },

{ EB_ErrorDestroyThreadFailed, AVERROR_EXTERNAL, "failed to destroy thread" },

{ EB_ErrorSemaphoreUnresponsive, AVERROR_EXTERNAL, "semaphore unresponsive" },

{ EB_ErrorDestroySemaphoreFailed, AVERROR_EXTERNAL, "failed to destroy semaphore"},

{ EB_ErrorCreateMutexFailed, AVERROR_EXTERNAL, "failed to create mutex" },

{ EB_ErrorMutexUnresponsive, AVERROR_EXTERNAL, "mutex unresponsive" },

{ EB_ErrorDestroyMutexFailed, AVERROR_EXTERNAL, "failed to destroy mutex" },

{ EB_NoErrorEmptyQueue, AVERROR(EAGAIN), "empty queue" },

};

static int svt_map_error(EbErrorType eb_err, const char **desc)

{

int i;

av_assert0(desc);

for (i = 0; i < FF_ARRAY_ELEMS(svt_errors); i++) {

if (svt_errors[i].eb_err == eb_err) {

*desc = svt_errors[i].desc;

return svt_errors[i].av_err;

}

}

*desc = "unknown error";

return AVERROR_UNKNOWN;

}

static int svt_print_error(void *log_ctx, EbErrorType err,

const char *error_string)

{

const char *desc;

int ret = svt_map_error(err, &desc);

av_log(log_ctx, AV_LOG_ERROR, "%s: %s (0x%x)\n", error_string, desc, err);

return ret;

}

static int alloc_buffer(EbSvtAV1EncConfiguration *config, SvtContext *svt_enc)

{

const int pack_mode_10bit = (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ?1:0; //定一个变量,pack_mode_10bit, 用于判断是否需要对10位编码进行特殊处理

//如果编码器的位深大于8位,并且compressed_ten_bit_format. 为0, 则设置为1,表示需要特殊处理

//否则设置为0

const size_t luma_size_8bit = config->source_width * config->source_height 分别是输入视频的宽度和高度

1 << pack_mode_10bit 如果pack_mode_10bit 为1,则乘以2,否则乘以1,这用语计算10位编码时的额外数据大小

const size_t luma_size_10bit = (config->encoder_bit_depth > 8 && pack_mode_10bit == 0) ? luma_size_8bit: 0;

//计算10位亮度分量的大小

如果编码器的位深度大于8位,并且pack_mode_10bit, 为0,则使用与8位相同的大小,否则设置为0,表示不使用10位编码。

EbSvtIOFormat *in_data; //声明一个指向EbSvtIOFormat 的指针in_data, 用于表示输入数据的格式

svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3/2;

//对于YUV420格式,总大小为亮度分量大小乘以1.5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值