FFmpeg  4.0
vf_shuffleframes.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/avstring.h"
23 #include "libavutil/common.h"
24 #include "libavutil/internal.h"
25 #include "libavutil/opt.h"
26 
27 #include "avfilter.h"
28 #include "internal.h"
29 #include "video.h"
30 
31 typedef struct ShuffleFramesContext {
32  const AVClass *class;
33  char *mapping;
35  int *map;
36  int64_t *pts;
37  int in_frames;
38  int nb_frames;
40 
42 {
43  ShuffleFramesContext *s = ctx->priv;
44  char *mapping, *saveptr = NULL, *p;
45  int n, nb_items;
46 
47  nb_items = 1;
48  for (p = s->mapping; *p; p++) {
49  if (*p == '|' || *p == ' ')
50  nb_items++;
51  }
52 
53  s->frames = av_calloc(nb_items, sizeof(*s->frames));
54  s->map = av_calloc(nb_items, sizeof(*s->map));
55  s->pts = av_calloc(nb_items, sizeof(*s->pts));
56  if (!s->map || !s->frames || !s->pts) {
57  return AVERROR(ENOMEM);
58  }
59 
60  mapping = av_strdup(s->mapping);
61  if (!mapping)
62  return AVERROR(ENOMEM);
63 
64  for (n = 0; n < nb_items; n++) {
65  char *map = av_strtok(n == 0 ? mapping : NULL, " |", &saveptr);
66  if (!map || sscanf(map, "%d", &s->map[n]) != 1) {
67  av_free(mapping);
68  return AVERROR(EINVAL);
69  }
70 
71  if (s->map[n] < -1 || s->map[n] >= nb_items) {
72  av_log(ctx, AV_LOG_ERROR, "Index out of range.\n");
73  av_free(mapping);
74  return AVERROR(EINVAL);
75  }
76  }
77 
78  s->nb_frames = nb_items;
79  av_free(mapping);
80  return 0;
81 }
82 
83 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
84 {
85  AVFilterContext *ctx = inlink->dst;
86  ShuffleFramesContext *s = ctx->priv;
87  int ret = 0;
88 
89  if (s->in_frames < s->nb_frames) {
90  s->frames[s->in_frames] = frame;
91  s->pts[s->in_frames] = frame->pts;
92  s->in_frames++;
93  }
94 
95  if (s->in_frames == s->nb_frames) {
96  int n, x;
97 
98  for (n = 0; n < s->nb_frames; n++) {
99  AVFrame *out;
100 
101  x = s->map[n];
102  if (x >= 0) {
103  out = av_frame_clone(s->frames[x]);
104  if (!out)
105  return AVERROR(ENOMEM);
106  out->pts = s->pts[n];
107  ret = ff_filter_frame(ctx->outputs[0], out);
108  }
109  s->in_frames--;
110  }
111 
112  for (n = 0; n < s->nb_frames; n++)
113  av_frame_free(&s->frames[n]);
114  }
115 
116  return ret;
117 }
118 
120 {
121  ShuffleFramesContext *s = ctx->priv;
122 
123  while (s->in_frames > 0) {
124  s->in_frames--;
125  av_frame_free(&s->frames[s->in_frames]);
126  }
127 
128  av_freep(&s->frames);
129  av_freep(&s->map);
130  av_freep(&s->pts);
131 }
132 
133 #define OFFSET(x) offsetof(ShuffleFramesContext, x)
134 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
135 static const AVOption shuffleframes_options[] = {
136  { "mapping", "set destination indexes of input frames", OFFSET(mapping), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
137  { NULL },
138 };
139 
140 AVFILTER_DEFINE_CLASS(shuffleframes);
141 
143  {
144  .name = "default",
145  .type = AVMEDIA_TYPE_VIDEO,
146  .filter_frame = filter_frame,
147  },
148  { NULL },
149 };
150 
152  {
153  .name = "default",
154  .type = AVMEDIA_TYPE_VIDEO,
155  },
156  { NULL },
157 };
158 
160  .name = "shuffleframes",
161  .description = NULL_IF_CONFIG_SMALL("Shuffle video frames."),
162  .priv_size = sizeof(ShuffleFramesContext),
163  .priv_class = &shuffleframes_class,
164  .init = init,
165  .uninit = uninit,
166  .inputs = shuffleframes_inputs,
167  .outputs = shuffleframes_outputs,
169 };
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:768
This structure describes decoded (raw) audio or video data.
Definition: frame.h:218
AVOption.
Definition: opt.h:246
Main libavfilter public API header.
static const AVOption shuffleframes_options[]
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:125
const char * name
Pad name.
Definition: internal.h:60
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
#define av_cold
Definition: attributes.h:82
AVOptions.
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:311
static AVFrame * frame
static int flags
Definition: log.c:55
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
simple assert() macros that are a bit more flexible than ISO C assert().
common internal API header
static const AVFilterPad shuffleframes_outputs[]
AVFormatContext * ctx
Definition: movenc.c:48
int n
Definition: avisynth_c.h:684
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:538
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
static const AVFilterPad shuffleframes_inputs[]
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
Definition: avstring.c:184
#define OFFSET(x)
common internal and external API header
static av_cold void uninit(AVFilterContext *ctx)
#define av_free(p)
An instance of a filter.
Definition: avfilter.h:338
FILE * out
Definition: movenc.c:54
#define av_freep(p)
#define FLAGS
static av_cold int init(AVFilterContext *ctx)
internal API functions
AVFILTER_DEFINE_CLASS(shuffleframes)
AVFilter ff_vf_shuffleframes