首页 > 其他分享 >ffmpeg 添加自定义编解码插件

ffmpeg 添加自定义编解码插件

时间:2023-12-15 16:56:09浏览次数:42  
标签:编解码 插件 ffmpeg 自定义 mydecoder AV mk CODEC decoder

有两种方法:

一. ffmpeg 添加自定义编解码插件(以修改ffmpeg源码的方式添加)

例:添加一个解码器,给这个解码器取个名字叫mydecoder,可以通过下面的步骤添加:

1.在libavcodec目录下,新建文件mydecoder.c

#include "avcodec.h"
#include "codec_internal.h"

//自己封装的编解码器的头文件
#include "MyDecoder.h"

static av_cold int mk_init_decoder(AVCodecContext *avctx)
{
    //...
    return 0;
}

static int mk_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame,
                     AVPacket *avpkt)
{
    printf("decode in\n");
    //...
    return 0;
}

static av_cold int mk_close_decoder(AVCodecContext *avctx)
{
    //...
    return 0;
}

static void mk_flush(AVCodecContext *avctx)
{
    //...
}

//通过此结构体,来完成对mydecoder解码器的调用
//结构体的命名规则必须为 ff_xxx_decoder
//如果是编码器则为 ff_xxx_encoder
const FFCodec ff_mydecode_decoder = {
    .p.name = "myvideo",
    CODEC_LONG_NAME("mk video"),
    .p.type = AVMEDIA_TYPE_VIDEO,
    .p.id = AV_CODEC_ID_MYVIDEO,//需要手动在code_id.h头文件中声明
    .p.capabilities = AV_CODEC_CAP_PARAM_CHANGE,
    .init = mk_init_decoder,
    FF_CODEC_DECODE_CB(mk_decode),
    .close = mk_close_decoder,
    .flush = mk_flush};

2.嵌入mydecoder,使ffmpeg能识别到mydecoder解码器

  • 1.在 libavcodec/code_id.h 头文件中声明 AV_CODEC_ID_MYVIDEO。后面可以通过这个ID来找到mydecoder解码器

  • 2.在 libavcodec/codec_desc.cAVCodecDescriptor 编解码描述结构体中中添加如下代码

...
    {
        .id = AV_CODEC_ID_LEAD,
        .type = AVMEDIA_TYPE_VIDEO,
        .name = "lead",
        .long_name = NULL_IF_CONFIG_SMALL("LEAD MCMP"),
        .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
    },
	
	//mydecoder解码器的描述
    {
        .id = AV_CODEC_ID_MYVIDEO,
        .type = AVMEDIA_TYPE_VIDEO,
        .name = "myvideo",
        .long_name = NULL_IF_CONFIG_SMALL("mk video"),
        .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
    },

    /* various PCM "codecs" */
    {
        .id = AV_CODEC_ID_PCM_S16LE,
        .type = AVMEDIA_TYPE_AUDIO,
        .name = "pcm_s16le",
        .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16-bit little-endian"),
        .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
    },
...
  • 3.在 allcodecs.c 中添加 ff_mydecode_decoder 的声明。configure时,会通过解析此文件获取到可用的编解码器。mydecode为解码器名字,decoder表示为解码器
...
extern const FFCodec ff_mjpeg_decoder;
extern const FFCodec ff_mjpegb_decoder;

//根据这个声明,可以查找到mydecoder解码器
//ps:在执行configure时,也会根据此文件中声明的变量来获取编解码器
extern const FFCodec ff_mydecode_decoder;

extern const FFCodec ff_mmvideo_decoder;
extern const FFCodec ff_mobiclip_decoder;
...

3.修改Makefile,使mydecoder能编译进ffmpeg

...
OBJS-$(CONFIG_LIBOPENJPEG_ENCODER)        += libopenjpegenc.o

#添加下面行,在编译时会把mydecoder.c链接到libavcodec库中
#CONFIG_MYDECODE_DECODER变量是在configure的时候根据ff_mydecode_decoder生成
OBJS-$(CONFIG_MYDECODE_DECODER)            += mydecode.o
...

4.生成带mydecoder解码器的ffmpeg

  • 1.执行 ./configure --list-decoders 查看mydecoder解码器是否已添加

  • 2.执行 ./configure --disable-x86asm --enable-shared 生成配置文件

  • 2.1 可以通过 ./configure --help 查看使用说明

  • 2.2 执行configure后,会在ffbuild目录下生成一堆文件,主要关注 .mak 文件。可以参考 https://blog.csdn.net/sunshineywz/article/details/105855939

  • 3.执行 make 开始编译ffmpeg

二. 不修改ffmpeg源码的方式添加编解码器

  • allcodecs.c 源文件中声明了全部的编解码器。ffmpeg实现部分的编解码器,还有一部分只做了声明
    ,我们直接找到一个未做实现的编码器,比如 extern const FFCodec ff_h264_mf_encoder;,然后直接在
    自己的项目中实现它,如下:
const FFCodec ff_h264_mf_encoder = {
    .p.name = "myvideo00",
    CODEC_LONG_NAME("mk video"),
    .p.type = AVMEDIA_TYPE_VIDEO,
    .p.id = AV_CODEC_ID_H264,
    .p.capabilities = AV_CODEC_CAP_PARAM_CHANGE,
    .init = mk_init_encoder,//初始化
    FF_CODEC_ENCODE_CB(mk_encode),//编码一帧数据
    .close = mk_close_encoder,//关闭

最后,当使用const AVCodec *codec = avcodec_find_encoder_by_name("myvideo00");,查找编码器时,就会直接找到我们自定义的编码器。


两种添加自定义编解码器的方法的优缺点:

在C++工程中使用ffmpeg需要注意:

注意包含头文件的方法:

//在C++项目中,必须使用extern包含ffmpeg头文件,让编译器以C风格来解释ffmpeg接口
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
...
}

标签:编解码,插件,ffmpeg,自定义,mydecoder,AV,mk,CODEC,decoder
From: https://www.cnblogs.com/linxisuo/p/17903697.html

相关文章

  • decimal插件计算
    import{Decimal}from'decimal.js';//引入exportconstcal={jia(num1,num2){returnnewDecimal(num1).add(newDecimal(num2))},jian(num1,num2){returnnewDecimal(num1).sub(newDecimal(num2))},cheng(num1,num2){returnnewDecimal(num......
  • 3.草图大师安装胚子插件、布料模拟插件
    一、胚子插件导入1.下载及安装胚子插件,https://www.bilibili.com/video/BV1xP411s7su/?vd_source=d1a768a1747fb268e1e40d209416a9d02.在草图大师界面右键勾选 二、布料模拟插件导入1.72版ClothWorks只支持su2020(ruby2.5)及以下,su2021(ruby2.7)控制台,使用1.74版ClothWorks,su2......
  • 12月14日插件的具体使用
    配置好环境之后你就可以选择使用mapper或者service了 调用和mapper基本相同但是提供的调用方法更多了。然后你就能够更方便的开始后端开发了。今天的另一件事是逻辑视图建模这是一个针对于外卖管理系统的逻辑视图建模。(一),分析系统用例,确定对象类外卖管理系统包括”商家......
  • 自定义委托01
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceeventTest20231209{classProgram{staticvoidMain(string[]args){EventClassmy=newEventClass();......
  • 卸载Postman?这款IDEA插件真可以!
    Postman是大家最常用的API调试工具,那么有没有一种方法可以不用手动写入接口到Postman,即可进行接口调试操作?今天给大家推荐一款IDEA插件:ApipostHelper,写完代码就可以调试接口并一键生成接口文档!而且还可以根据已有的方法帮助您快速生成url和params。更重要的是他完全免费!Apipost......
  • 当你用neovim的mason插件管理lsp config,并且配置好bash的bashls后,却没有正常工作的解
    刚开始遇到这个情况我百思不得其解,检查了neovimcheckhealth,以为是npm包管理的问题,然后删了下删了下不但没有解决还把包管理整乱了……后来发现是我没仔细看bash-language-server这个包的官方文档。。。以下是bash-language-server的官方仓库:https://github.com/bash-lsp/......
  • 2023 idea 常用插件
    AlibabaJavaCodingGuidelines阿里巴巴代码规范检查插件AiXcoderCodeCompleter代码提示补全插件ArthasIdeaArthas是阿里开源的Java在线诊断工具,该插件可以自动生成Arthas在线Java代码诊断命令AutofillingJavacallarguments代码生成插件。通过快捷......
  • 卸载Postman?这款IDEA插件真可以!
    Postman是大家最常用的API调试工具,那么有没有一种方法可以不用手动写入接口到Postman,即可进行接口调试操作?今天给大家推荐一款IDEA插件:ApipostHelper,写完代码就可以调试接口并一键生成接口文档!而且还可以根据已有的方法帮助您快速生成url和params。更重要的是他完全免费!Apipos......
  • 这款IDEA插件太好用了!还免费
    IDEA是一款功能强大的集成开发环境(IDE),它可以帮助开发人员更加高效地编写、调试和部署软件应用程序。我们在编写完接口代码后需要进行接口调试等操作,一般需要打开额外的调试工具。今天给大家介绍一款IDEA插件:Apipost-Helper-2.0。代码写完直接编辑器内调试、还支持生成接口文档、......
  • php tp框架 自定义日志
    调用方法$file_log=['order_id'=>123,];(newLogs('log'))->infos('日志文案',$file_log);[2023-12-1415:24:13][INFO][log]{"msg":"日志文案","params":{"order_id":123},"file......