把自定义encoder加入ffmpeg源码

第一步:

在libavcodec目录下新建mkencoder.c并加入代码:
[cpp]  view plain  copy
  1. /*  
  2. *实现一个自己的encoder,编码工作其实就是把frame的数据拷贝到pkt 
  3. *作者:缪国凯(MK)  
  4. *821486004@qq.com  
  5. *2015-6-4  
  6. */   
  7.   
  8.   
  9. #include "avcodec.h"  
  10. #include "libavutil/pixdesc.h"  
  11.   
  12. static av_cold int mk_encode_init(AVCodecContext *avctx)  
  13. {  
  14.     printf("init mk encoder");  
  15.     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);  
  16.   
  17.     avctx->coded_frame = av_frame_alloc();  
  18.     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;  
  19.     avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc);  
  20.     if(!avctx->codec_tag)  
  21.         avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt);  
  22.     return 0;  
  23. }  
  24.   
  25. static int mk_encode(AVCodecContext *avctx, AVPacket *pkt,  
  26.     const AVFrame *frame, int *got_packet)  
  27. {  
  28.     int ret = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);  
  29.   
  30.     if (ret < 0)  
  31.         return ret;  
  32.   
  33.     if (pkt->data == NULL && pkt->size == 0)  
  34.     {  
  35.         av_new_packet(pkt,ret);  
  36.         pkt->size = ret;  
  37.     }  
  38.   
  39. //  if ((ret = ff_alloc_packet2(avctx, pkt, ret)) < 0)  
  40. //      return ret;  
  41.   
  42.     if ((ret = avpicture_layout((const AVPicture *)frame, avctx->pix_fmt, avctx->width,  
  43.         avctx->height, pkt->data, pkt->size)) < 0)  
  44.         return ret;  
  45.   
  46. //  if(avctx->codec_tag == AV_RL32("yuv2") && ret > 0 &&  
  47. //      avctx->pix_fmt   == AV_PIX_FMT_YUYV422)   
  48. //  {  
  49. //          int x;  
  50. //          for(x = 1; x < avctx->height*avctx->width*2; x += 2)  
  51. //              pkt->data[x] ^= 0x80;  
  52. //  }  
  53.     pkt->flags |= AV_PKT_FLAG_KEY;  
  54.     *got_packet = 1;  
  55.     return 0;  
  56. }  
  57.   
  58. static av_cold int mk_close(AVCodecContext *avctx)  
  59. {  
  60.     printf("close mk encoder");  
  61.     av_frame_free(&avctx->coded_frame);  
  62.     return 0;  
  63. }  
  64.   
  65. AVCodec ff_mkvideo_encoder = {  
  66.     .name           = "mkvideo",  
  67.     .long_name      = NULL_IF_CONFIG_SMALL("mk video"),  
  68.     .type           = AVMEDIA_TYPE_VIDEO,  
  69.     .id             = AV_CODEC_ID_MKVIDEO,  
  70.     .init           = mk_encode_init,  
  71.     .encode2        = mk_encode,  
  72.     .close          = mk_close,  
  73. };  

第二步:

在avcodec.h里的 enum AVCodecID 最后加入:
[cpp]  view plain  copy
  1. AV_CODEC_ID_MKVIDEO,  

第三步:

在allcodec.c的void avcodec_register_all(void)函数中加入
[cpp]  view plain  copy
  1. REGISTER_ENCODER(MKVIDEO,          mkvideo);  

第四步:

在makefile里加入
[cpp]  view plain  copy
  1. OBJS-$(CONFIG_MKVIDEO_ENCODER)              += mkencoder.o  

第五步:

在ffmpeg根目录config.h里加
[cpp]  view plain  copy
  1. #define CONFIG_MKVIDEO_ENCODER 1  

第六步:

在codec_desc.c的static const AVCodecDescriptor codec_descriptors[] 中 加入:
[cpp]  view plain  copy
  1. {  
  2.         .id        = AV_CODEC_ID_MKVIDEO,  
  3.         .type      = AVMEDIA_TYPE_VIDEO,  
  4.         .name      = "mkvideo",  
  5.         .long_name = NULL_IF_CONFIG_SMALL("mk video"),  
  6.         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,  
  7.     },  

第七步:

重新编译ffmpeg。

测试:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值