加盟网站开发费用,做私单的网站,哪个网站可以做高数题,深圳市水榭花都房地产公司1.filter
在多媒体处理中#xff0c;filter 的意思是被编码到输出文件之前用来修改输入文件内容的一个软件工具。如#xff1a;视频翻转#xff0c;旋转#xff0c;缩放等。
语法#xff1a;[input_link_label1]… filter_nameparameters [output_link_label1]…
1、视…1.filter
在多媒体处理中filter 的意思是被编码到输出文件之前用来修改输入文件内容的一个软件工具。如视频翻转旋转缩放等。
语法[input_link_label1]… filter_nameparameters [output_link_label1]…
1、视频过滤器 -vf
如 input.mp4 视频按顺时针方向旋转 90 度
ffplay -i input.mp4 -vf transpose1
如 input.mp4 视频水平翻转(左右翻转)
ffplay -i input.mp4 -vf hflip
2、音频过滤器 -af
实现慢速播放声音速度是原始速度的 50%
offplay input.mp3 -af atempo0.5
过滤器链Filterchain
Filterchain 逗号分隔的一组 filter
语法“filter1,filter2,filter3,…filterN-2,filterN-1,filterN”
顺时针旋转 90 度并水平翻转
ffplay -i input.mp4 -vf transpose1,hflip
过滤器图(Filtergraph)
第一步 源视频宽度扩大两倍。
ffmpeg -i jidu.mp4 -t 10 -vf pad2*iw output.mp4
第二步源视频水平翻转
ffmpeg -i jidu.mp4 -t 10 -vf hflip output2.mp4
第三步水平翻转视频覆盖 output.mp4
ffmpeg -i output.mp4 -i output2.mp4 -filter_complex overlayw compare.mp4
是不是很复杂
用带有链接标记的过滤器图(Filtergraph)只需一条命令
基本语法
Filtergraph 分号分隔的一组 filterchain
“filterchain1;filterchain2;…filterchainN-1;filterchainN”
Filtergraph 的分类
1、简单(simple) 一对一
2、复杂(complex多对一 多对多
过滤器图处理流程 对于刚才用三步处理的方式用过滤器图可以这样做
ffplay -f lavfi -i testsrc -vf split[a][b];[a]pad2*iw[1];[b]hflip[2];[1][2]overlayw
F1: split 过滤器创建两个输入文件的拷贝并标记为[a],[b]
F2: [a]作为 pad 过滤器的输入pad 过滤器产生 2 倍宽度并输出到[1].
F3: [b]作为 hflip 过滤器的输入vflip 过滤器水平翻转视频并输出到[2].
F4: 用 overlay 过滤器把 [2]覆盖到[1]的旁边.
filter 涉及的结构体主要包括 FilterGraph, AVFilterGraph InputFilter, InputStream, OutputFilter, OutputStream AVFilter AVFilterContext AVFilterLink AVFilterPad
2.DirectShow
DirectShow简称 DShow 是一个 Windows 平台上的流媒体框架提供了高质量的多媒体流采集和回放功能。它支持多种多样的媒体文件格式包括 ASF、MPEG、AVI、MP3和 WAV 文件同时支持使 动或早期的 VFW 驱动来进行多媒体流的采集。
DirectShow 大大简化了媒体回放、格式转换和采集工作。但与此同时它也为用户自定义的解决方案提供了底层流控制框架从而使用户可以自行创建支持新的文件格式或其他用户的 DirectShow 组件。
DirectShow 是基于**组件对象模型COM**的因此当你编写 DirectShow 应用程序时你必须具备 COM 客户端程序编写的知识。对于大部分的应用程序你不需要实现自己的COM 对象DirectShow 提供了大部分你需要的 DirectShow 组件但是假如你需要编写自己的 DirectShow 组件来进行扩充那么你必须编写实现 COM 对象。
使用 DirectShow 编写的典型应用程序包括DVD 播放器、视频编辑程序、AVI 到 ASF转换器、 MP3 播放器和数字视频采集应用。 DirectShow 的架构如下图所示 /*** file* API example for decoding and filtering* example filtering_video.c*/#define _XOPEN_SOURCE 600 /* for usleep */
#include unistd.h
#include stdio.h
#include stdlib.h#include libavcodec/avcodec.h
#include libavformat/avformat.h
#include libavfilter/buffersink.h
#include libavfilter/buffersrc.h
#include libavutil/opt.hconst char *filter_descr scale640:480,hflip;
/* other way:scale78:24 [scl]; [scl] transposecclock // assumes [in] and [out] to be input output pads respectively*/static AVFormatContext *fmt_ctx;
static AVCodecContext *dec_ctx;
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
static int video_stream_index -1;
static int64_t last_pts AV_NOPTS_VALUE;static int open_input_file(const char *filename)
{int ret;AVCodec *dec;if ((ret avformat_open_input(fmt_ctx, filename, NULL, NULL)) 0) {av_log(NULL, AV_LOG_ERROR, Cannot open input file\n);return ret;}if ((ret avformat_find_stream_info(fmt_ctx, NULL)) 0) {av_log(NULL, AV_LOG_ERROR, Cannot find stream information\n);return ret;}/* select the video stream */ret av_find_best_stream(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 file\n);return ret;}video_stream_index ret;/* create decoding context */dec_ctx avcodec_alloc_context3(dec);if (!dec_ctx)return AVERROR(ENOMEM);avcodec_parameters_to_context(dec_ctx, fmt_ctx-streams[video_stream_index]-codecpar);/* init the video decoder */if ((ret avcodec_open2(dec_ctx, dec, NULL)) 0) {av_log(NULL, AV_LOG_ERROR, Cannot open video decoder\n);return ret;}return 0;
}static int init_filters(const char *filters_descr)
{char args[512];int ret 0;const AVFilter *buffersrc avfilter_get_by_name(buffer);const AVFilter *buffersink avfilter_get_by_name(buffersink);AVFilterInOut *outputs avfilter_inout_alloc();AVFilterInOut *inputs avfilter_inout_alloc();AVRational time_base fmt_ctx-streams[video_stream_index]-time_base;enum AVPixelFormat pix_fmts[] { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };filter_graph avfilter_graph_alloc();if (!outputs || !inputs || !filter_graph) {ret AVERROR(ENOMEM);goto end;}/* buffer video source: the decoded frames from the decoder will be inserted here. */snprintf(args, sizeof(args),video_size%dx%d:pix_fmt%d:time_base%d/%d:pixel_aspect%d/%d,dec_ctx-width, dec_ctx-height, dec_ctx-pix_fmt,time_base.num, time_base.den,dec_ctx-sample_aspect_ratio.num, dec_ctx-sample_aspect_ratio.den);ret avfilter_graph_create_filter(buffersrc_ctx, buffersrc, in,args, NULL, filter_graph);if (ret 0) {av_log(NULL, AV_LOG_ERROR, Cannot create buffer source\n);goto end;}/* buffer video sink: to terminate the filter chain. */ret avfilter_graph_create_filter(buffersink_ctx, buffersink, out,NULL, NULL, filter_graph);if (ret 0) {av_log(NULL, AV_LOG_ERROR, Cannot create buffer sink\n);goto end;}/** Set the endpoints for the filter graph. The filter_graph will* be linked to the graph described by filters_descr.*//** The buffer source output must be connected to the input pad of* the first filter described by filters_descr; since the first* filter input label is not specified, it is set to in by* default.*/outputs-name av_strdup(in);outputs-filter_ctx buffersrc_ctx;outputs-pad_idx 0;outputs-next NULL;/** The buffer sink input must be connected to the output pad of* the last filter described by filters_descr; since the last* filter output label is not specified, it is set to out by* default.*/inputs-name av_strdup(out);inputs-filter_ctx buffersink_ctx;inputs-pad_idx 0;inputs-next NULL;if ((ret avfilter_graph_parse_ptr(filter_graph, filters_descr,inputs, outputs, NULL)) 0)goto end;if ((ret avfilter_graph_config(filter_graph, NULL)) 0)goto end;end:avfilter_inout_free(inputs);avfilter_inout_free(outputs);return ret;
}/// 将yuv帧写入文件:yuv420p格式
FILE * g__file_fd;
static void write_frame(const AVFrame *frame)
{static int printf_flag 0;if(!printf_flag){printf_flag 1;printf(frame widht%d,frame height%d\n,frame-width,frame-height);if(frame-formatAV_PIX_FMT_YUV420P){printf(format is yuv420p\n);}else{printf(formet is %d \n,frame-format);}}fwrite(frame-data[0],1,frame-width*frame-height,g__file_fd);fwrite(frame-data[1],1,frame-width/2*frame-height/2,g__file_fd);fwrite(frame-data[2],1,frame-width/2*frame-height/2,g__file_fd);
}int main(int argc, char **argv)
{int ret;AVPacket packet;AVFrame *frame;AVFrame *filt_frame;if (argc ! 2) {fprintf(stderr, Usage: %s file\n, argv[0]);exit(1);}g__file_fd fopen(yuv888.yuv, w);frame av_frame_alloc();filt_frame av_frame_alloc();if (!frame || !filt_frame) {perror(Could not allocate frame);exit(1);}if ((ret open_input_file(argv[1])) 0)goto end;if ((ret init_filters(filter_descr)) 0)goto end;/* read all packets */while (1) {if ((ret av_read_frame(fmt_ctx, packet)) 0)break;if (packet.stream_index video_stream_index) {ret avcodec_send_packet(dec_ctx, packet);if (ret 0) {av_log(NULL, AV_LOG_ERROR, Error while sending a packet to the decoder\n);break;}while (ret 0) {ret avcodec_receive_frame(dec_ctx, frame);if (ret AVERROR(EAGAIN) || ret AVERROR_EOF) {break;} else if (ret 0) {av_log(NULL, AV_LOG_ERROR, Error while receiving a frame from the decoder\n);goto end;}frame-pts frame-best_effort_timestamp;/* push the decoded frame into the filtergraph */if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) 0) {av_log(NULL, AV_LOG_ERROR, Error while feeding the filtergraph\n);break;}/* pull filtered frames from the filtergraph */while (1) {ret av_buffersink_get_frame(buffersink_ctx, filt_frame);if (ret AVERROR(EAGAIN) || ret AVERROR_EOF)break;if (ret 0)goto end;write_frame(filt_frame);av_frame_unref(filt_frame);}av_frame_unref(frame);}}av_packet_unref(packet);}
end:avfilter_graph_free(filter_graph);avcodec_free_context(dec_ctx);avformat_close_input(fmt_ctx);av_frame_free(frame);av_frame_free(filt_frame);fclose(g__file_fd);if (ret 0 ret ! AVERROR_EOF) {fprintf(stderr, Error occurred: %s\n, av_err2str(ret));exit(1);}exit(0);
}