Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1059259
  • 博文数量: 77
  • 博客积分: 821
  • 博客等级: 军士长
  • 技术积分: 1905
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-23 16:17
个人简介

学校:上海交通大学软件工程 学历:硕士 行业:从事流媒体移动开发 QQ: 412595942 邮箱:yiikai1987910@gmail.com

文章分类

全部博文(77)

文章存档

2016年(4)

2015年(15)

2014年(16)

2013年(12)

2012年(21)

2011年(9)

分类: C/C++

2014-10-14 16:27:07

     ffmpeg中的filter功能不得不说真不错,类似于gstreamer,所有的filter(过滤器)都是相互连接对应的pad来完成数据流在其中的转换的,从src filter进,从sink filter出。相信玩过gstreamer的朋友一定能理解这种模式,如果不明白的朋友可以去gst官网了解下其方式,我本人认为这个比直接看filter来理解更容易。 
   好了,那水印的添加也是通过avfilter这个模块来做的,主要是通过movie和overlay这两个filter来处理,废话不多说,上代码,主要提供一个最简单的使用avfilter的教程。

   代码下载地址:

点击(此处)折叠或打开

  1. const char* filename = "E:\\C++Learning\\FFMPEG_SDL_WIN32_PLAYER_by_nick_avfilter\\FLV_STREAM\\4.flv";
  2. const char* filters_descr = "[in]scale=1280:720[scale];movie=1.jpg[wm];[scale][wm]overlay=0:0[out]";
  3. int main()
  4. {
  5.     FILE *fp_yuv=fopen("test.yuv","wb+");
  6.     if(!fp_yuv)
  7.         return 0;
  8.     int ret = 0;
  9.     av_register_all();
  10.     avfilter_register_all();
  11.     AVFormatContext *pFormat = NULL;
  12.     avformat_open_input(&pFormat,filename,NULL,NULL);
  13.     if(!pFormat)
  14.         return 0;
  15.     if (avformat_find_stream_info(pFormat, NULL) < 0)
  16.     {
  17.         printf("Could not find stream information\n");
  18.     }
  19.     av_dump_format(pFormat, 0, filename, 0);
  20.     AVCodecContext *video_dec_ctx = pFormat->streams[0]->codec;
  21.     AVStream *video_st = pFormat->streams[0];
  22.     AVCodec *video_dec = avcodec_find_decoder(video_dec_ctx->codec_id);
  23.     avcodec_open2(video_dec_ctx, video_dec,NULL);
  24.     if(!video_dec_ctx || !video_dec || !video_st)
  25.         return 0;
  26.     uint8_t *video_dst_data[4] = {NULL};
  27.     int video_dst_linesize[4];
  28.     int video_dst_bufsize;
  29.     ret = av_image_alloc(video_dst_data, video_dst_linesize,
  30.         1280, 720,
  31.         video_dec_ctx->pix_fmt, 1);
  32.     video_dst_bufsize = ret;
  33.     AVPacket *pkt=(AVPacket *)malloc(sizeof(AVPacket));
  34.     av_init_packet(pkt);
  35.     
  36.     //filter
  37.     AVFilter *buffersrc = avfilter_get_by_name("buffer");
  38.     AVFilter *buffersink = avfilter_get_by_name("buffersink");
  39.     AVFilterInOut *outputs = avfilter_inout_alloc();
  40.     AVFilterInOut *inputs = avfilter_inout_alloc();

  41.     enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
  42.     AVFilterContext *buffersink_ctx;
  43.     AVFilterContext *buffersrc_ctx;
  44.     AVFilterGraph *filter_graph;
  45.     filter_graph = avfilter_graph_alloc();
  46.     if (!outputs || !inputs || !filter_graph) {
  47.         ret = AVERROR(ENOMEM);
  48.         return 0;
  49.     }
  50.     char args[512] = {0};
  51.     _snprintf(args, sizeof(args),
  52.         "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
  53.         video_dec_ctx->width, video_dec_ctx->height, video_dec_ctx->pix_fmt,
  54.         video_dec_ctx->time_base.num, video_dec_ctx->time_base.den,
  55.         video_dec_ctx->sample_aspect_ratio.num, video_dec_ctx->sample_aspect_ratio.den);

  56.     ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
  57.         args, NULL, filter_graph);
  58.     if (ret < 0) {
  59.         av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
  60.         return 0;
  61.     }
  62.     ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
  63.         NULL, NULL, filter_graph);
  64.     if (ret < 0) {
  65.         av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
  66.         return 0;
  67.     }

  68.     ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
  69.         AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
  70.     if (ret < 0) {
  71.         av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
  72.         return 0;
  73.     }
  74.     outputs->name = av_strdup("in");
  75.     outputs->filter_ctx = buffersrc_ctx;
  76.     outputs->pad_idx = 0;
  77.     outputs->next = NULL;

  78.     inputs->name = av_strdup("out");
  79.     inputs->filter_ctx = buffersink_ctx;
  80.     inputs->pad_idx = 0;
  81.     inputs->next = NULL;

  82.     if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
  83.         &inputs, &outputs, NULL)) < 0)
  84.         return 0;

  85.     if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
  86.         return 0;

  87.     int gotpicture = 0;

  88.     while(1)
  89.     {
  90.         av_read_frame(pFormat,pkt);
  91.         if(pkt->stream_index == 0)
  92.         {
  93.             AVFrame* pFrame = avcodec_alloc_frame();
  94.             ret = avcodec_decode_video2(video_dec_ctx,pFrame,&gotpicture,pkt);
  95.             if(ret<0)
  96.                 return 0;
  97.             if(gotpicture)
  98.             {    
  99.                 if (av_buffersrc_add_frame_flags(buffersrc_ctx, pFrame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
  100.                     av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
  101.                     break;
  102.                 }

  103.                 /* pull filtered frames from the filtergraph */
  104.                 while (1) {
  105.                     AVFrame* filt_frame = avcodec_alloc_frame();
  106.                     ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
  107.                     if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF || ret == AVERROR(EIO))
  108.                         break;
  109.                     if (ret < 0)
  110.                         return 0;
  111.                     //int y_size=filt_frame->width*filt_frame->height;
  112.                     av_image_copy(video_dst_data, video_dst_linesize,
  113.                         (const uint8_t **)(filt_frame->data), filt_frame->linesize,
  114.                         PIX_FMT_YUV420P, filt_frame->width, filt_frame->height);
  115.                     fwrite(video_dst_data[0], 1, video_dst_bufsize, fp_yuv);
  116.                     avcodec_free_frame(&filt_frame);
  117.                 }
  118.                 avcodec_free_frame(&pFrame);
  119.                 fclose(fp_yuv);
  120.                 return 0;
  121.             }
  122.             else
  123.             {

  124.             }
  125.             printf("video\n");
  126.         }
  127.         av_free_packet(pkt);
  128.         
  129.     }
  130.     return 0;
  131.     
  132. }

阅读(8347) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~