FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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] < 0 || 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  out = av_frame_clone(s->frames[x]);
103  if (!out)
104  return AVERROR(ENOMEM);
105  out->pts = s->pts[n];
106  ret = ff_filter_frame(ctx->outputs[0], out);
107  s->in_frames--;
108  }
109 
110  for (n = 0; n < s->nb_frames; n++)
111  av_frame_free(&s->frames[n]);
112  }
113 
114  return ret;
115 }
116 
118 {
119  ShuffleFramesContext *s = ctx->priv;
120 
121  while (s->in_frames > 0) {
122  s->in_frames--;
123  av_frame_free(&s->frames[s->in_frames]);
124  }
125 
126  av_freep(&s->frames);
127  av_freep(&s->map);
128  av_freep(&s->pts);
129 }
130 
131 #define OFFSET(x) offsetof(ShuffleFramesContext, x)
132 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
133 static const AVOption shuffleframes_options[] = {
134  { "mapping", "set destination indexes of input frames", OFFSET(mapping), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
135  { NULL },
136 };
137 
138 AVFILTER_DEFINE_CLASS(shuffleframes);
139 
141  {
142  .name = "default",
143  .type = AVMEDIA_TYPE_VIDEO,
144  .filter_frame = filter_frame,
145  },
146  { NULL },
147 };
148 
150  {
151  .name = "default",
152  .type = AVMEDIA_TYPE_VIDEO,
153  },
154  { NULL },
155 };
156 
158  .name = "shuffleframes",
159  .description = NULL_IF_CONFIG_SMALL("Shuffle video frames."),
160  .priv_size = sizeof(ShuffleFramesContext),
161  .priv_class = &shuffleframes_class,
162  .init = init,
163  .uninit = uninit,
164  .inputs = shuffleframes_inputs,
165  .outputs = shuffleframes_outputs,
167 };
#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:184
AVOption.
Definition: opt.h:245
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:260
#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:59
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1189
#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:268
static AVFrame * frame
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:53
#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:158
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
void * priv
private data for use by the filter
Definition: avfilter.h:322
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 outputs[]
Definition: af_afftfilt.c:386
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:480
static const AVFilterPad inputs[]
Definition: af_afftfilt.c:376
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:267
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
const VDPAUPixFmtMap * map
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:319
static int flags
Definition: cpu.c:47
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:307
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