版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、ffmpeg 代码实现视频添加水印功能备忘:用 ffmpeg 给视频添加水印的命令为 :ffmpeg -i in.mp4 -i xxx.png -filter_complex overlay=5:5 out.mp4 代码实现 如下 , 主要是用了参考了 ffmpeg.c 里面的 filter_complex 的 代码 :cpp view plaincopy#include <unistd.h>#include <stdio.h> #include <assert.h>#include <libavcodec/avcodec.h> #include
2、 <libavformat/avformat.h> #include <libavfilter/avfiltergraph.h> #include <libavfilter/avcodec.h> #include <libavfilter/buffersink.h>#include<libavfilter/buffersrc.h> #include <libswscale/swscale.h>const char *filter_descr =overlay=5:5;#define ENABLE_YUV_FILE 1AVF
3、ormatContext *input_fmt_ctx; AVCodecContext *input_dec_ctx; AVFormatContext *overlay_fmt_ctx; AVCodecContext *overlay_dec_ctx;intinput_video_stream_idx, overlay_video_stream_idx; AVFilterGraph *filter_graph;AVFilterInOut *inputs;AVFilterInOut *outputs;AVFilterContext *buffersrc_ctx;AVFilterContextAV
4、FilterContext *bufferoverlay_ctx;*buffersink_ctx; int ret; int got_frame;intvideo_eof_reached = 0; int overlay_eof_reached = 0; int active_stream_index = -1;FILE* fp_yuv; voidyuv420p_save(AVFrame *pFrame); int video_transcode_step(AVFrame* mVideoFrame);intintoverlay_transcode_step(AVFrame* mOverlayF
5、rame); video_output_eof_packet(const char* tag,AVStream* ist, AVFilterContext* ifilter); static int open_input_file(const char *filename) int ret;AVCodec *dec; if (ret = avformat_open_input(&input_fmt_ctx, filename, NULL, NULL) < 0) av_log(NULL, AV_LOG_ERROR, Cannot open input filen); return
6、ret; if (ret = avformat_find_stream_info(input_fmt_ctx, NULL) < 0) av_log(NULL, AV_LOG_ERROR, Cannot findstream informationn);return ret; /* select the video stream */ret = av_find_best_stream(input_fmt_ctx,ifAVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0); (ret < 0) av_log(NULL, AV_LOG_ERROR,Cannot
7、find a video stream in the input filen); return ret; input_video_stream_idx = ret;input_dec_ctx = input_fmt_ctx->streamsinput_video_stream_idx->co dec;/* init the video decoder */if (ret =avcodec_open2(input_dec_ctx, dec, NULL) < 0) av_log(NULL, AV_LOG_ERROR, Cannotopen video decodern);retu
8、rn ret;return 0; static int open_overlay_file(const char *filename) int ret; AVCodec *dec; if (ret = avformat_open_input(&overlay_fmt_ctx, filename, NULL, NULL) < 0) av_log(NULL, AV_LOG_ERROR, Cannot open input filen);return ret; if (ret = avformat_find_stream_info(overlay_fmt_ctx, NULL) <
9、 0) av_log(NULL, AV_LOG_ERROR, Cannot findstream informationn);return ret; /* select the video stream */ret =av_find_best_stream(overlay_fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0); if (ret < 0) av_log(NULL, AV_LOG_ERROR, Cannot find a video stream in the input filen);return ret; overlay_vi
10、deo_stream_idx = ret; overlay_dec_ctx = overlay_fmt_ctx->streamsoverlay_video_stream_idx-& gt;codec; /* init the video decoder */ if (ret = avcodec_open2(overlay_dec_ctx, dec, NULL) < 0) av_log(NULL, AV_LOG_ERROR, Cannotopen video decodern);return ret; printf(overlay format = %sn, overlay_fmt_
11、ctx->iformat->name); return 0; static intvideo_config_input_filter(AVFilterInOut* inputs, AVFilterContext* input_filter_ctx) char args512; memset(args, 0, sizeof(args);AVFilterContext*first_filter = inputs->filter_ctx;int pad_idx =inputs->pad_idx; AVFilter *filter = avfilter_get_by_name(
12、buffer); / AVRational time_base = input_dec_ctx->time_base;AVStream* video_st = input_fmt_ctx->streamsinput_video_stream_idx; AVRational time_base = video_st->time_base; snprintf(args, sizeof(args), video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d:sws_param=flags=%d:frame_rate
13、=%d/%d, input_dec_ctx->width, input_dec_ctx->height, input_dec_ctx->pix_fmt, input_dec_ctx->time_base.num, input_dec_ctx->time_base.den, input_dec_ctx->sample_aspect_ratio.num, input_dec_ctx->sample_aspect_ratio.den, SWS_BILINEAR + (video_st->codec->flags&CODEC_FLAG_BI
14、TE XACT) ? SWS_BITEXACT:0), video_st->r_frame_rate.num, video_st->r_frame_rate.den); printf(input args = %sn, args);ret =avfilter_graph_create_filter(input_filter_ctx, filter, src_in, args, NULL, filter_graph);if (ret < 0 ) printf(video config input filter fail.n);return -1; ret = avfilter_
15、link(*input_filter_ctx, 0,first_filter, pad_idx);assert(ret >= 0);printf(video_config_input_filter avfilter_link ret = %dn, ret); return ret; static int video_config_overlay_filter(AVFilterInOut* inputs, AVFilterContext* overlay_filter_ctx ) charargs512;memset(args, 0, sizeof(args);AVFilterContex
16、t *first_filter = inputs->filter_ctx;AVFilter *filter =/AVRationalint pad_idx = inputs->pad_idx;avfilter_get_by_name(buffer);time_base = overlay_dec_ctx->time_base;AVStream* overlay_st = overlay_fmt_ctx->streamsoverlay_video_stream_idx;AVRational time_base = overlay_st->time_base; snp
17、rintf(args, sizeof(args), video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_ aspect=%d/%d:sws_param=flags=%d:frame_rate=%d/%d, overlay_dec_ctx->width, overlay_dec_ctx->height, overlay_dec_ctx->pix_fmt, time_base.num, time_base.den, overlay_dec_ctx->sample_aspect_ratio.num, overlay_dec_ct
18、x->sample_aspect_ratio.den, SWS_BILINEAR + (overlay_st->codec->flags&CODEC_FLAG_BIT EXACT) ? SWS_BITEXACT:0), overlay_st->r_frame_rate.num, overlay_st->r_frame_rate.den);printf(overlay args = %sn, args);ret =avfilter_graph_create_filter(overlay_filter_ctx, filter, overlay_in, args
19、, NULL, filter_graph);if (ret < 0 ) printf(video config overlay filter fail.n);return -1; ret = avfilter_link(*overlay_filter_ctx, 0, first_filter, pad_idx); assert(ret >= 0);printf(video_config_overlay_filter ret = %dn, ret); avfilter_inout_free(&inputs); return ret; static int video_conf
20、ig_output_filter(AVFilterInOut* outputs, AVFilterContext* out_filter_ctx) char args512;AVFilterContext *last_filter = outputs->filter_ctx;int pad_idx = outputs->pad_idx; AVFilter *buffersink = avfilter_get_by_name(ffbuffersink);int ret = avfilter_graph_create_filter(out_filter_ctx, buffersink,
21、 video_out, NULL, NULL, filter_graph);assert(ret >= 0); if (ret < 0) return ret; ret = avfilter_link(last_filter, pad_idx, *out_filter_ctx, 0);assert(ret >= 0);if (ret <0) return ret;avfilter_inout_free(&outputs); return 0; static int init_input_filters()filter_graph->scale_sws_op
22、ts =av_strdup(flags=0x4);av_opt_set(filter_graph,aresample_swr_opts, , 0);ret =avfilter_graph_parse2(filter_graph, filter_descr, &inputs, &outputs);assert(inputs&& inputs->next&& !inputs->next->next);ret =video_config_input_filter(inputs, &buffersrc_ctx); ret = v
23、ideo_config_overlay_filter(inputs->next, &bufferoverlay_ctx); return ret; static int init_output_filters() return video_config_output_filter(outputs,&buffersink_ctx); int reap_filters() AVFilterBufferRef *picref; while (1) ret = av_buffersink_get_buffer_ref(buffersink_ctx, &picref, AV
24、_BUFFERSINK_FLAG_NO_REQUEST); if (ret = AVERROR(EAGAIN) | ret = AVERROR_EOF)/printf(reap_filters fail ret = %dn, ret);return 0; / no frame filtered. printf(samplesref n);AVFrame* filtered_frame = avcodec_alloc_frame(); avcodec_get_frame_defaults(filtered_frame);avfilter_copy_buf_props(filtered_frame
25、, picref); yuv420p_save(filtered_frame); avfilter_unref_bufferp(&picref); int transcode_from_filter(AVFilterContext* ifilters, int* eof_reached_arr, int* active_stream_indext) int ret= 0;ret =avfilter_graph_request_oldest(filter_graph);if (ret>= 0) return ret; if (ret =AVERROR_EOF) return ret
26、; ifreturn ret; (ret != AVERROR(EAGAIN) int nb_requests_max = 0;int i; for (i = 0; i < 2;i+) int eof_reached = eof_reached_arri;if (eof_reached) continue; AVFilterContext* ifilter = ifiltersi; int nb_requests = av_buffersrc_get_nb_failed_requests(ifilter); if (nb_requests > nb_requests_max) nb
27、_requests_max = nb_requests; *active_stream_indext = i; return ret; int main()char avcodec_register_all(); av_register_all(); avfilter_register_all(); avformat_network_init();char* video_file = outFileSrc.mp4;#ifoverlay_video_file = my_logo.png; / light1.mp4ENABLE_YUV_FILE const char* yuvFile = outW
28、ater.yuv; fp_yuv = fopen(yuvFile, wb); #endif open_input_file(video_file); open_overlay_file(overlay_video_file); filter_graph = avfilter_graph_alloc();if (!filter_graph) printf(filter graph alloc fail.n); return -1; init_input_filters(); init_output_filters();if (ret =avfilter_graph_config(filter_g
29、raph, NULL) < 0) return ret; AVFrame* mVideoFrame = avcodec_alloc_frame(); AVFrame* mOverlayFrame = avcodec_alloc_frame();while(1) if(video_eof_reached && overlay_eof_reached) printf(stream EOF.n); break; AVFilterContext* ifilters = buffersrc_ctx, bufferoverlay_ctx; int eof_reacheds = vid
30、eo_eof_reached, overlay_eof_reached; ret = transcode_from_filter(ifilters, eof_reacheds, &active_stream_index);if (ret >= 0) ret = reap_filters();if (ret = ret = reap_filters(); continue; assert(ret >= 0); continue; AVERROR_EOF) assert(ret >= 0);if (ret = AVERROR(EAGAIN) && acti
31、ve_stream_index < 0) continue; assert(active_stream_index >= 0); printf(active_stream_index = %dn, active_stream_index);if (active_stream_index = 0) video_transcode_step(mVideoFrame);continue; overlay_transcode_step(mOverlayFrame); if (input_dec_ctx) avcodec_close(input_dec_ctx); avformat_clos
32、e_input(&input_fmt_ctx); if (overlay_dec_ctx)avcodec_close(overlay_dec_ctx); avformat_close_input(&overlay_fmt_ctx); printf(my_filtering_video3 end n); return 0; int video_transcode_step(AVFrame* mVideoFrame) int ret = 0;AVPacket pkt;ret =av_read_frame(input_fmt_ctx, &pkt);if (ret = AVER
33、ROR(EAGAIN) return 0; if (ret < 0) video_eof_reached = 1;assert(ret = AVERROR_EOF);ret = video_output_eof_packet(video_eof,input_fmt_ctx->streamsinput_video_stream_idx, avcodec_decode_video2(input_dec_ctx, mVideoFrame,buffersrc_ctx);assert (ret >= 0);return ret; input_video_stream_idx) if (
34、pkt.stream_index !=/ av_free(&pkt);return ret; ret =&got_frame, &pkt);if (ret < 0)printf(Error decoding input videon);if (got_frame) int64_t best_effort_timestamp = av_frame_get_best_effort_timestamp(mVideoFrame); mVideoFrame->pts = best_effort_timestamp;if (av_buffersrc_add_frame(
35、buffersrc_ctx, mVideoFrame, AV_BUFFERSRC_FLAG_PUSH) < 0)av_log(NULL, AV_LOG_ERROR, Errorwhile feeding the video filtergraphn);return -1; reap_filters(); return 0; int overlay_transcode_step(AVFrame*mOverlayFrame) int ret = 0;AVPacket pkt;ret = av_read_frame(overlay_fmt_ctx, &pkt);ifreturn 0;i
36、f (ret < 0) overlay_eof_reached = 1;(ret = AVERROR(EAGAIN) ret = video_output_eof_packet(overlay_eof,overlay_fmt_ctx->streamsinput_video_stream_idx, best_effort_timestamp = av_frame_get_best_effort_timestamp(mOverlayFrame); mOverlayFrame->pts = best_effort_timestamp;bufferoverlay_ctx);asser
37、t(ret >=0 );return ret;if (pkt.stream_index !=overlay_video_stream_idx)av_free_packet(&pkt);returnret;ret =avcodec_decode_video2(overlay_dec_ctx,mOverlayFrame, &got_frame, &pkt);if (ret< 0) printf(Error decoding overlayvideon);if (got_frame) int64_tif (av_buffersrc_add_frame(bufferoverlay_ctx, mOverlayFrame, AV_BUFFERSRC_FLAG_PUSH) < 0) av_log(NULL, AV_LOG_ERROR, Errorwhile feeding the audio filtergraphn);return -1;return 0;/*output EOF packet to filter to flush */intvideo_output_eof_packet(const char* tag, AVStream* ist, AVFilterContext*
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 长沙市雨花区2025-2026学年第二学期五年级语文第七单元测试卷(部编版含答案)
- 伊春市桦南县2025-2026学年第二学期三年级语文期末考试卷(部编版含答案)
- 海西蒙古族藏族自治州德令哈市2025-2026学年第二学期五年级语文第八单元测试卷(部编版含答案)
- 蜡裂解及重合装置操作工安全检查知识考核试卷含答案
- 耕种机械制造工安全文化知识考核试卷含答案
- 耐蚀砖板衬里工岗前工作能力考核试卷含答案
- 茶叶拼配师岗前纪律考核试卷含答案
- 钻井工安全教育模拟考核试卷含答案
- 牡丹江市林口县2025-2026学年第二学期三年级语文第七单元测试卷(部编版含答案)
- 辽阳市弓长岭区2025-2026学年第二学期二年级语文第七单元测试卷(部编版含答案)
- 专题70 实验仪器与安全 十年(2015-2024)高考化学真题分类汇编(解析版)
- “沙钢杯”第十一届全国钢铁行业职业技能竞赛(电工)理论试题及答案
- 离婚协议书范本两个小孩
- 四年级下册体育教学计划与教案
- DB32T 4399-2022《高层建筑工程抗震设防超限界定界定标准》
- 尊重和传承中华民族历史文化讲解
- 化妆日常护理培训课件模板
- 保险公司客养的重要性课件
- 医学生创新创业课件概述
- 中枢性面瘫与周围性面瘫区别课件
- 2024年中交集团暨中国交建总部招聘笔试参考题库含答案解析
评论
0/150
提交评论