把自定义的demuxer加入ffmpeg源码

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

.简介:把上一篇文章中的demuxer加入ffmpeg源码中去,使可以用命令行方式调用自定义的demuxer

第一步:

在libavformat目录下新建mkdemuxer.c和mkdemuxer.h,代码如下:

mkdemuxer.c:

/* 
*实现一个自己的demuxer并加入到demuxer链中去
*作者:缪国凯(MK) 
*821486004@qq.com 
*2015-6-3 
*/ 

#include "mkdemuxer.h"

typedef struct MKVideoDemuxerContext {
	const AVClass *pclass;     /**< Class for private options. */
	int width, height;        /**< Integers describing video size, set by a private option. */
	char *pixel_format;       /**< Set by a private option. */
	AVRational framerate;     /**< AVRational describing framerate, set by a private option. */
} MKVideoDemuxerContext;

int mkvideo_read_header(AVFormatContext *ctx)
{
	MKVideoDemuxerContext *s = ctx->priv_data;
	enum AVPixelFormat pix_fmt;
	AVStream *st;

	st = avformat_new_stream(ctx, NULL);
	if (!st)
		return AVERROR(ENOMEM);

	st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

	st->codec->codec_id = ctx->iformat->raw_codec_id;

	//这里就简单的直接赋值为420p
	pix_fmt = AV_PIX_FMT_YUV420P;

	st->time_base.num = s->framerate.den;
	st->time_base.den = s->framerate.num;
	st->pts_wrap_bits = 64;
	

	st->codec->width  = s->width;
	st->codec->height = s->height;
	st->codec->pix_fmt = pix_fmt;

	AVRational tmpRa;
	tmpRa.den = 1;
	tmpRa.num = 8;
	st->codec->bit_rate = av_rescale_q(avpicture_get_size(st->codec->pix_fmt, s->width, s->height),
		tmpRa, st->time_base);

	return 0;
}

int mkvideo_read_packet(AVFormatContext *s, AVPacket *pkt)
{
	int packet_size, ret, width, height;
	AVStream *st = s->streams[0];

	width = st->codec->width;
	height = st->codec->height;

	packet_size = avpicture_get_size(st->codec->pix_fmt, width, height);
	if (packet_size < 0)
		return -1;

	ret = av_get_packet(s->pb, pkt, packet_size);
	pkt->pts = pkt->dts = pkt->pos / packet_size;

	pkt->stream_index = 0;
	if (ret < 0)
		return ret;
	
	return 0;
}

#define OFFSET(x) offsetof(MKVideoDemuxerContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM

static const AVOption mk_options[] = 
{
	{ "video_size", "set frame size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC },
	{ "pixel_format", "set pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },
	{ "framerate", "set frame rate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, DEC },
	{ NULL },
};

static const AVClass mk_demuxer_class = {
	.class_name = "mk video demuxer",
	.item_name  = av_default_item_name,
	.option     = mk_options,
	.version    = LIBAVUTIL_VERSION_INT,
};

AVInputFormat ff_mk_demuxer = {
	.name           = "mk",
	.long_name      = NULL_IF_CONFIG_SMALL("MK Video Container"),
	.flags          = AVFMT_GENERIC_INDEX,
	.extensions     = "mk",	
	.priv_class     = &mk_demuxer_class,	
	.raw_codec_id   = AV_CODEC_ID_RAWVIDEO,
	.priv_data_size = sizeof(MKVideoDemuxerContext),
	
	.read_header    = mkvideo_read_header,
	.read_packet    = mkvideo_read_packet,
};


mkdemuxer.h:

/* 
*实现一个自己的demuxer并加入到demuxer链中去
*作者:缪国凯(MK) 
*821486004@qq.com 
*2015-6-3 
*/ 

#ifndef AVFORMAT_MKDEMUXER_H
#define AVFORMAT_MKDEMUXER_H

#include "libavutil/opt.h"
#include "avformat.h"

int mkvideo_read_header(AVFormatContext *ctx);
int mkvideo_read_packet(AVFormatContext *s, AVPacket *pkt);

#endif //AVFORMAT_MKDEMUXER_H


第二步:

在libavformat下的allformats.c的av_register_all里加入:

REGISTER_DEMUXER   (MK,              mk);//add ByMK for mk demuxer  

第三步:

在libavformat目录下的makefile文件的# muxers/demuxers后加入:

OBJS-$(CONFIG_MK_DEMUXER)                  += mkdemuxer.o 

第四步:

在ffmpeg根目录的config.h里加入:

#define CONFIG_MK_DEMUXER 1  

第五步:

如果不想重新configure,则在ffmpeg根目录的config.mak文件中加入:
CONFIG_MK_DEMUXER=yes


OK,按照正常的编译去编译ffmpeg,然后运行ffmpeg.exe输入ffmpeg -formats 看到有mk这个muxer了,如下:

 DE mk              mk (MK Video Container)
  E mkvtimestamp_v2 extract pts as timecode v2 format, as defined by mkvtoolnix
 DE mlp             raw MLP
 D  mlv             Magic Lantern Video (MLV)
 D  mm              American Laser Games MM
 DE mmf             Yamaha SMAF
  E mov             QuickTime / MOV

再试一下命令:ffmpeg -s 1280x720 -i test.mk -y test.avi。

注意:当.mk格式作为输入的时候,必须加输入参数-s 分辨率,就和yuv作为输入一样(因为从本质上讲就是yuv...)。

成功!OK,大功告成。


原理在上一篇的博文中已经讲到了,下一步,实现自己的encoder。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dancing_night

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

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

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

打赏作者

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

抵扣说明:

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

余额充值