lavfi: add fade filter
Port fade filter from libavfilter soc repo, with minor fixes by Stefano. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
							parent
							
								
									fd0b42cce0
								
							
						
					
					
						commit
						704865fc87
					
				| @ -353,6 +353,39 @@ drawbox | ||||
| drawbox=10:20:200:60:red@@0.5" | ||||
| @end example | ||||
| 
 | ||||
| @section fade | ||||
| 
 | ||||
| Apply fade-in/out effect to input video. | ||||
| 
 | ||||
| It accepts the parameters: | ||||
| @var{type}:@var{start_frame}:@var{nb_frames} | ||||
| 
 | ||||
| @var{type} specifies if the effect type, can be either "in" for | ||||
| fade-in, or "out" for a fade-out effect. | ||||
| 
 | ||||
| @var{start_frame} specifies the number of the start frame for starting | ||||
| to apply the fade effect. | ||||
| 
 | ||||
| @var{nb_frames} specifies the number of frames for which the fade | ||||
| effect has to last. At the end of the fade-in effect the output video | ||||
| will have the same intensity as the input video, at the end of the | ||||
| fade-out transition the output video will be completely black. | ||||
| 
 | ||||
| A few usage examples follow, usable too as test scenarios. | ||||
| @example | ||||
| # fade in first 30 frames of video | ||||
| fade=in:0:30 | ||||
| 
 | ||||
| # fade out last 45 frames of a 200-frame video | ||||
| fade=out:155:45 | ||||
| 
 | ||||
| # fade in first 25 frames and fade out last 25 frames of a 1000-frame video | ||||
| fade=in:0:25, fade=out:975:25 | ||||
| 
 | ||||
| # make first 5 frames black, then fade in from frame 5-24 | ||||
| fade=in:5:20 | ||||
| @end example | ||||
| 
 | ||||
| @section fifo | ||||
| 
 | ||||
| Buffer input images and send them when they are requested. | ||||
|  | ||||
| @ -27,6 +27,7 @@ OBJS-$(CONFIG_COPY_FILTER)                   += vf_copy.o | ||||
| OBJS-$(CONFIG_CROP_FILTER)                   += vf_crop.o | ||||
| OBJS-$(CONFIG_CROPDETECT_FILTER)             += vf_cropdetect.o | ||||
| OBJS-$(CONFIG_DRAWBOX_FILTER)                += vf_drawbox.o | ||||
| OBJS-$(CONFIG_FADE_FILTER)                   += vf_fade.o | ||||
| OBJS-$(CONFIG_FIFO_FILTER)                   += vf_fifo.o | ||||
| OBJS-$(CONFIG_FORMAT_FILTER)                 += vf_format.o | ||||
| OBJS-$(CONFIG_FREI0R_FILTER)                 += vf_frei0r.o | ||||
|  | ||||
| @ -45,6 +45,7 @@ void avfilter_register_all(void) | ||||
|     REGISTER_FILTER (CROP,        crop,        vf); | ||||
|     REGISTER_FILTER (CROPDETECT,  cropdetect,  vf); | ||||
|     REGISTER_FILTER (DRAWBOX,     drawbox,     vf); | ||||
|     REGISTER_FILTER (FADE,        fade,        vf); | ||||
|     REGISTER_FILTER (FIFO,        fifo,        vf); | ||||
|     REGISTER_FILTER (FORMAT,      format,      vf); | ||||
|     REGISTER_FILTER (FREI0R,      frei0r,      vf); | ||||
|  | ||||
							
								
								
									
										170
									
								
								libavfilter/vf_fade.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								libavfilter/vf_fade.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,170 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2010 Brandon Mintern | ||||
|  * Copyright (c) 2007 Bobby Bingham | ||||
|  * | ||||
|  * This file is part of FFmpeg. | ||||
|  * | ||||
|  * FFmpeg is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2.1 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * FFmpeg is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with FFmpeg; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|  * @file | ||||
|  * video fade filter | ||||
|  * based heavily on vf_negate.c by Bobby Bingham | ||||
|  */ | ||||
| 
 | ||||
| #include "libavutil/pixdesc.h" | ||||
| #include "avfilter.h" | ||||
| 
 | ||||
| typedef struct { | ||||
|     int factor, fade_per_frame; | ||||
|     unsigned int frame_index, start_frame, stop_frame; | ||||
|     int hsub, vsub, bpp; | ||||
| } FadeContext; | ||||
| 
 | ||||
| static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) | ||||
| { | ||||
|     FadeContext *fade = ctx->priv; | ||||
|     unsigned int nb_frames; | ||||
|     char in_out[4]; | ||||
| 
 | ||||
|     if (!args || | ||||
|         sscanf(args, " %3[^:]:%u:%u", in_out, &fade->start_frame, &nb_frames) != 3) { | ||||
|         av_log(ctx, AV_LOG_ERROR, | ||||
|                "Expected 3 arguments '(in|out):#:#':'%s'\n", args); | ||||
|         return AVERROR(EINVAL); | ||||
|     } | ||||
| 
 | ||||
|     nb_frames = nb_frames ? nb_frames : 1; | ||||
|     fade->fade_per_frame = (1 << 16) / nb_frames; | ||||
|     if (!strcmp(in_out, "in")) | ||||
|         fade->factor = 0; | ||||
|     else if (!strcmp(in_out, "out")) { | ||||
|         fade->fade_per_frame = -fade->fade_per_frame; | ||||
|         fade->factor = (1 << 16); | ||||
|     } else { | ||||
|         av_log(ctx, AV_LOG_ERROR, | ||||
|                "first argument must be 'in' or 'out':'%s'\n", in_out); | ||||
|         return AVERROR(EINVAL); | ||||
|     } | ||||
|     fade->stop_frame = fade->start_frame + nb_frames; | ||||
| 
 | ||||
|     av_log(ctx, AV_LOG_INFO, | ||||
|            "type:%s start_frame:%d nb_frames:%d\n", | ||||
|            in_out, fade->start_frame, nb_frames); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     const static enum PixelFormat pix_fmts[] = { | ||||
|         PIX_FMT_YUV444P,  PIX_FMT_YUV422P,  PIX_FMT_YUV420P, | ||||
|         PIX_FMT_YUV411P,  PIX_FMT_YUV410P, | ||||
|         PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P, | ||||
|         PIX_FMT_YUV440P,  PIX_FMT_YUVJ440P, | ||||
|         PIX_FMT_RGB24,    PIX_FMT_BGR24, | ||||
|         PIX_FMT_NONE | ||||
|     }; | ||||
| 
 | ||||
|     avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static int config_props(AVFilterLink *inlink) | ||||
| { | ||||
|     FadeContext *fade = inlink->dst->priv; | ||||
|     const AVPixFmtDescriptor *pixdesc = &av_pix_fmt_descriptors[inlink->format]; | ||||
| 
 | ||||
|     fade->hsub = pixdesc->log2_chroma_w; | ||||
|     fade->vsub = pixdesc->log2_chroma_h; | ||||
| 
 | ||||
|     fade->bpp = av_get_bits_per_pixel(pixdesc) >> 3; | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) | ||||
| { | ||||
|     FadeContext *fade = inlink->dst->priv; | ||||
|     AVFilterBufferRef *outpic = inlink->cur_buf; | ||||
|     uint8_t *p; | ||||
|     int i, j, plane; | ||||
| 
 | ||||
|     if (fade->factor < 65536) { | ||||
|         /* luma or rgb plane */ | ||||
|         for (i = 0; i < h; i++) { | ||||
|             p = outpic->data[0] + (y+i) * outpic->linesize[0]; | ||||
|             for (j = 0; j < inlink->w * fade->bpp; j++) { | ||||
|                 /* fade->factor is using 16 lower-order bits for decimal
 | ||||
|                  * places. 32768 = 1 << 15, it is an integer representation | ||||
|                  * of 0.5 and is for rounding. */ | ||||
|                 *p = (*p * fade->factor + 32768) >> 16; | ||||
|                 p++; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (outpic->data[0] && outpic->data[1]) { | ||||
|             /* chroma planes */ | ||||
|             for (plane = 1; plane < 3; plane++) { | ||||
|                 for (i = 0; i < h; i++) { | ||||
|                     p = outpic->data[plane] + ((y+i) >> fade->vsub) * outpic->linesize[plane]; | ||||
|                     for (j = 0; j < inlink->w >> fade->hsub; j++) { | ||||
|                         /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
 | ||||
|                          * representation of 128.5. The .5 is for rounding | ||||
|                          * purposes. */ | ||||
|                         *p = ((*p - 128) * fade->factor + 8421367) >> 16; | ||||
|                         p++; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); | ||||
| } | ||||
| 
 | ||||
| static void end_frame(AVFilterLink *inlink) | ||||
| { | ||||
|     FadeContext *fade = inlink->dst->priv; | ||||
| 
 | ||||
|     avfilter_end_frame(inlink->dst->outputs[0]); | ||||
| 
 | ||||
|     if (fade->frame_index >= fade->start_frame && | ||||
|         fade->frame_index <= fade->stop_frame) | ||||
|         fade->factor += fade->fade_per_frame; | ||||
|     fade->factor = av_clip_uint16(fade->factor); | ||||
|     fade->frame_index++; | ||||
| } | ||||
| 
 | ||||
| AVFilter avfilter_vf_fade = { | ||||
|     .name          = "fade", | ||||
|     .description   = NULL_IF_CONFIG_SMALL("Fade in/out input video"), | ||||
|     .init          = init, | ||||
|     .priv_size     = sizeof(FadeContext), | ||||
|     .query_formats = query_formats, | ||||
| 
 | ||||
|     .inputs    = (AVFilterPad[]) {{ .name            = "default", | ||||
|                                     .type            = AVMEDIA_TYPE_VIDEO, | ||||
|                                     .config_props    = config_props, | ||||
|                                     .get_video_buffer = avfilter_null_get_video_buffer, | ||||
|                                     .start_frame      = avfilter_null_start_frame, | ||||
|                                     .draw_slice      = draw_slice, | ||||
|                                     .end_frame       = end_frame, | ||||
|                                     .min_perms       = AV_PERM_READ | AV_PERM_WRITE, | ||||
|                                     .rej_perms       = AV_PERM_PRESERVE, }, | ||||
|                                   { .name = NULL}}, | ||||
|     .outputs   = (AVFilterPad[]) {{ .name            = "default", | ||||
|                                     .type            = AVMEDIA_TYPE_VIDEO, }, | ||||
|                                   { .name = NULL}}, | ||||
| }; | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user