mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 12:36:41 +08:00 
			
		
		
		
	avfilter: add shuffleframes filter
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
		| @@ -24,6 +24,7 @@ version <next>: | ||||
| - zscale filter | ||||
| - wve demuxer | ||||
| - zero-copy Intel QSV transcoding in ffmpeg | ||||
| - shuffleframes filter | ||||
|  | ||||
|  | ||||
| version 2.8: | ||||
|   | ||||
| @@ -9946,6 +9946,26 @@ Set the size of the box used to represent one palette color entry. Default is | ||||
| @code{30} (for a @code{30x30} pixel box). | ||||
| @end table | ||||
|  | ||||
| @section shuffleframes | ||||
|  | ||||
| Reorder and/or duplicate video frames. | ||||
|  | ||||
| It accepts the following parameters: | ||||
|  | ||||
| @table @option | ||||
| @item mapping | ||||
| Set the destination indexes of input frames. | ||||
| This is space or '|' separated list of indexes that maps input frames to output | ||||
| frames. Number of indexes also sets maximal value that each index may have. | ||||
| @end table | ||||
|  | ||||
| The first frame has the index 0. The default is to keep the input unchanged. | ||||
|  | ||||
| Swap second and third frame of every three frames of the input: | ||||
| @example | ||||
| ffmpeg -i INPUT -vf "shuffleframes=0 2 1" OUTPUT | ||||
| @end example | ||||
|  | ||||
| @section shuffleplanes | ||||
|  | ||||
| Reorder and/or duplicate video planes. | ||||
|   | ||||
| @@ -215,6 +215,7 @@ OBJS-$(CONFIG_SETSAR_FILTER)                 += vf_aspect.o | ||||
| OBJS-$(CONFIG_SETTB_FILTER)                  += settb.o | ||||
| OBJS-$(CONFIG_SHOWINFO_FILTER)               += vf_showinfo.o | ||||
| OBJS-$(CONFIG_SHOWPALETTE_FILTER)            += vf_showpalette.o | ||||
| OBJS-$(CONFIG_SHUFFLEFRAMES_FILTER)          += vf_shuffleframes.o | ||||
| OBJS-$(CONFIG_SHUFFLEPLANES_FILTER)          += vf_shuffleplanes.o | ||||
| OBJS-$(CONFIG_SIGNALSTATS_FILTER)            += vf_signalstats.o | ||||
| OBJS-$(CONFIG_SMARTBLUR_FILTER)              += vf_smartblur.o | ||||
|   | ||||
| @@ -236,6 +236,7 @@ void avfilter_register_all(void) | ||||
|     REGISTER_FILTER(SETTB,          settb,          vf); | ||||
|     REGISTER_FILTER(SHOWINFO,       showinfo,       vf); | ||||
|     REGISTER_FILTER(SHOWPALETTE,    showpalette,    vf); | ||||
|     REGISTER_FILTER(SHUFFLEFRAMES,  shuffleframes,  vf); | ||||
|     REGISTER_FILTER(SHUFFLEPLANES,  shuffleplanes,  vf); | ||||
|     REGISTER_FILTER(SIGNALSTATS,    signalstats,    vf); | ||||
|     REGISTER_FILTER(SMARTBLUR,      smartblur,      vf); | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
| #include "libavutil/version.h" | ||||
|  | ||||
| #define LIBAVFILTER_VERSION_MAJOR   6 | ||||
| #define LIBAVFILTER_VERSION_MINOR  12 | ||||
| #define LIBAVFILTER_VERSION_MINOR  13 | ||||
| #define LIBAVFILTER_VERSION_MICRO 100 | ||||
|  | ||||
| #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ | ||||
|   | ||||
							
								
								
									
										162
									
								
								libavfilter/vf_shuffleframes.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								libavfilter/vf_shuffleframes.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| /* | ||||
|  * Copyright (c) 2015 Paul B Mahol | ||||
|  * | ||||
|  * 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 | ||||
|  */ | ||||
|  | ||||
| #include "libavutil/avstring.h" | ||||
| #include "libavutil/common.h" | ||||
| #include "libavutil/internal.h" | ||||
| #include "libavutil/opt.h" | ||||
|  | ||||
| #include "avfilter.h" | ||||
| #include "internal.h" | ||||
| #include "video.h" | ||||
|  | ||||
| typedef struct ShuffleFramesContext { | ||||
|     const AVClass *class; | ||||
|     char *mapping; | ||||
|     AVFrame **frames; | ||||
|     int *map; | ||||
|     int64_t *pts; | ||||
|     int in_frames; | ||||
|     int nb_frames; | ||||
| } ShuffleFramesContext; | ||||
|  | ||||
| static av_cold int init(AVFilterContext *ctx) | ||||
| { | ||||
|     ShuffleFramesContext *s = ctx->priv; | ||||
|     char *mapping, *saveptr = NULL, *p; | ||||
|     int n, nb_items; | ||||
|  | ||||
|     nb_items = 1; | ||||
|     for (p = s->mapping; *p; p++) { | ||||
|         if (*p == '|' || *p == ' ') | ||||
|             nb_items++; | ||||
|     } | ||||
|  | ||||
|     s->frames = av_calloc(nb_items, sizeof(*s->frames)); | ||||
|     s->map    = av_calloc(nb_items, sizeof(*s->map)); | ||||
|     s->pts    = av_calloc(nb_items, sizeof(*s->pts)); | ||||
|     if (!s->map || !s->frames || !s->pts) { | ||||
|         return AVERROR(ENOMEM); | ||||
|     } | ||||
|  | ||||
|     mapping = av_strdup(s->mapping); | ||||
|     if (!mapping) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (n = 0; n < nb_items; n++) { | ||||
|         char *map = av_strtok(n == 0 ? mapping : NULL, " |", &saveptr); | ||||
|         if (!map || sscanf(map, "%d", &s->map[n]) != 1) { | ||||
|             av_free(mapping); | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
|  | ||||
|         if (s->map[n] < 0 || s->map[n] >= nb_items) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Index out of range.\n"); | ||||
|             av_free(mapping); | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     s->nb_frames = nb_items; | ||||
|     av_free(mapping); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
| { | ||||
|     AVFilterContext    *ctx = inlink->dst; | ||||
|     ShuffleFramesContext *s = ctx->priv; | ||||
|     int ret; | ||||
|  | ||||
|     if (s->in_frames < s->nb_frames) { | ||||
|         s->frames[s->in_frames] = frame; | ||||
|         s->pts[s->in_frames] = frame->pts; | ||||
|         s->in_frames++; | ||||
|         ret = 0; | ||||
|     } | ||||
|  | ||||
|     if (s->in_frames == s->nb_frames) { | ||||
|         int n, x; | ||||
|  | ||||
|         for (n = 0; n < s->nb_frames; n++) { | ||||
|             AVFrame *out; | ||||
|  | ||||
|             x = s->map[n]; | ||||
|             out = av_frame_clone(s->frames[x]); | ||||
|             if (!out) | ||||
|                 return AVERROR(ENOMEM); | ||||
|             out->pts = s->pts[n]; | ||||
|             ret = ff_filter_frame(ctx->outputs[0], out); | ||||
|             s->in_frames--; | ||||
|         } | ||||
|  | ||||
|         for (n = 0; n < s->nb_frames; n++) | ||||
|             av_frame_free(&s->frames[n]); | ||||
|     } | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static av_cold void uninit(AVFilterContext *ctx) | ||||
| { | ||||
|     ShuffleFramesContext *s = ctx->priv; | ||||
|  | ||||
|     av_freep(&s->frames); | ||||
|     av_freep(&s->map); | ||||
|     av_freep(&s->pts); | ||||
| } | ||||
|  | ||||
| #define OFFSET(x) offsetof(ShuffleFramesContext, x) | ||||
| #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) | ||||
| static const AVOption shuffleframes_options[] = { | ||||
|     { "mapping", "set destination indexes of input frames",  OFFSET(mapping), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS }, | ||||
|     { NULL }, | ||||
| }; | ||||
|  | ||||
| AVFILTER_DEFINE_CLASS(shuffleframes); | ||||
|  | ||||
| static const AVFilterPad shuffleframes_inputs[] = { | ||||
|     { | ||||
|         .name         = "default", | ||||
|         .type         = AVMEDIA_TYPE_VIDEO, | ||||
|         .filter_frame = filter_frame, | ||||
|     }, | ||||
|     { NULL }, | ||||
| }; | ||||
|  | ||||
| static const AVFilterPad shuffleframes_outputs[] = { | ||||
|     { | ||||
|         .name = "default", | ||||
|         .type = AVMEDIA_TYPE_VIDEO, | ||||
|     }, | ||||
|     { NULL }, | ||||
| }; | ||||
|  | ||||
| AVFilter ff_vf_shuffleframes = { | ||||
|     .name          = "shuffleframes", | ||||
|     .description   = NULL_IF_CONFIG_SMALL("Shuffle video frames"), | ||||
|     .priv_size     = sizeof(ShuffleFramesContext), | ||||
|     .priv_class    = &shuffleframes_class, | ||||
|     .init          = init, | ||||
|     .uninit        = uninit, | ||||
|     .inputs        = shuffleframes_inputs, | ||||
|     .outputs       = shuffleframes_outputs, | ||||
|     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user
	 Paul B Mahol
					Paul B Mahol