把自定义encoder加入ffmpeg源码

59 篇文章 25 订阅
2 篇文章 0 订阅

第一步:

在libavcodec目录下新建mkencoder.c并加入代码:
/* 
*实现一个自己的encoder,编码工作其实就是把frame的数据拷贝到pkt
*作者:缪国凯(MK) 
*821486004@qq.com 
*2015-6-4 
*/ 


#include "avcodec.h"
#include "libavutil/pixdesc.h"

static av_cold int mk_encode_init(AVCodecContext *avctx)
{
	printf("init mk encoder");
	const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);

	avctx->coded_frame = av_frame_alloc();
	avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
	avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc);
	if(!avctx->codec_tag)
		avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt);
 	return 0;
}

static int mk_encode(AVCodecContext *avctx, AVPacket *pkt,
	const AVFrame *frame, int *got_packet)
{
	int ret = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);

	if (ret < 0)
		return ret;

	if (pkt->data == NULL && pkt->size == 0)
	{
		av_new_packet(pkt,ret);
		pkt->size = ret;
	}

// 	if ((ret = ff_alloc_packet2(avctx, pkt, ret)) < 0)
// 		return ret;

	if ((ret = avpicture_layout((const AVPicture *)frame, avctx->pix_fmt, avctx->width,
		avctx->height, pkt->data, pkt->size)) < 0)
		return ret;

// 	if(avctx->codec_tag == AV_RL32("yuv2") && ret > 0 &&
// 		avctx->pix_fmt   == AV_PIX_FMT_YUYV422) 
// 	{
// 			int x;
// 			for(x = 1; x < avctx->height*avctx->width*2; x += 2)
// 				pkt->data[x] ^= 0x80;
// 	}
	pkt->flags |= AV_PKT_FLAG_KEY;
	*got_packet = 1;
	return 0;
}

static av_cold int mk_close(AVCodecContext *avctx)
{
	printf("close mk encoder");
	av_frame_free(&avctx->coded_frame);
	return 0;
}

AVCodec ff_mkvideo_encoder = {
	.name           = "mkvideo",
	.long_name      = NULL_IF_CONFIG_SMALL("mk video"),
	.type           = AVMEDIA_TYPE_VIDEO,
	.id             = AV_CODEC_ID_MKVIDEO,
	.init           = mk_encode_init,
    .encode2        = mk_encode,
    .close          = mk_close,
};

第二步:

在avcodec.h里的 enum AVCodecID 最后加入:
AV_CODEC_ID_MKVIDEO,

第三步:

在allcodec.c的void avcodec_register_all(void)函数中加入
REGISTER_ENCODER(MKVIDEO,          mkvideo);

第四步:

在makefile里加入
OBJS-$(CONFIG_MKVIDEO_ENCODER)              += mkencoder.o

第五步:

在ffmpeg根目录config.h里加
#define CONFIG_MKVIDEO_ENCODER 1

第六步:

在codec_desc.c的static const AVCodecDescriptor codec_descriptors[] 中 加入:
{
        .id        = AV_CODEC_ID_MKVIDEO,
        .type      = AVMEDIA_TYPE_VIDEO,
        .name      = "mkvideo",
        .long_name = NULL_IF_CONFIG_SMALL("mk video"),
        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
    },

第七步:

重新编译ffmpeg。

测试:

运行命令:ffmpeg -encoders:在显示中找到自己的encoder:
 VFS... mjpeg                MJPEG (Motion JPEG)
 V..... mkvideo              mk video
 V.S... mpeg1video           MPEG-1 video
 V.S... mpeg2video           MPEG-2 video
运行命令:
ffmpeg -i test.avi -c:v mkvideo -y test.mk
把生成的test.mk改后缀为yuv,用yuvplayer播放。
播放成功!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dancing_night

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值