FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavfilter
vf_shuffleplanes.c
Go to the documentation of this file.
1
/*
2
* This file is part of FFmpeg.
3
*
4
* FFmpeg is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
8
*
9
* FFmpeg is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
13
*
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with FFmpeg; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
*/
18
19
#include "
libavutil/avstring.h
"
20
#include "
libavutil/common.h
"
21
#include "
libavutil/internal.h
"
22
#include "
libavutil/opt.h
"
23
#include "
libavutil/pixdesc.h
"
24
#include "
libavutil/pixfmt.h
"
25
26
#include "
avfilter.h
"
27
#include "
internal.h
"
28
#include "
video.h
"
29
30
typedef
struct
ShufflePlanesContext
{
31
const
AVClass
*
class
;
32
33
/* number of planes in the selected pixel format */
34
int
planes
;
35
36
/* mapping indices */
37
int
map
[4];
38
39
/* set to 1 if some plane is used more than once, so we need to make a copy */
40
int
copy
;
41
}
ShufflePlanesContext
;
42
43
static
av_cold
int
shuffleplanes_config_input
(
AVFilterLink
*inlink)
44
{
45
AVFilterContext
*ctx = inlink->
dst
;
46
ShufflePlanesContext
*
s
= ctx->
priv
;
47
const
AVPixFmtDescriptor
*desc;
48
int
used[4] = { 0 };
49
int
i;
50
51
s->
copy
= 0;
52
s->
planes
=
av_pix_fmt_count_planes
(inlink->
format
);
53
desc =
av_pix_fmt_desc_get
(inlink->
format
);
54
55
for
(i = 0; i < s->
planes
; i++) {
56
if
(s->
map
[i] >= s->
planes
) {
57
av_log
(ctx,
AV_LOG_ERROR
,
58
"Non-existing input plane #%d mapped to output plane #%d.\n"
,
59
s->
map
[i], i);
60
return
AVERROR
(EINVAL);
61
}
62
63
if
((desc->
log2_chroma_h
|| desc->
log2_chroma_w
) &&
64
(i == 1 || i == 2) != (s->
map
[i] == 1 || s->
map
[i] == 2)) {
65
av_log
(ctx,
AV_LOG_ERROR
,
66
"Cannot map between a subsampled chroma plane and a luma "
67
"or alpha plane.\n"
);
68
return
AVERROR
(EINVAL);
69
}
70
71
if
((desc->
flags
&
AV_PIX_FMT_FLAG_PAL
||
72
desc->
flags
&
AV_PIX_FMT_FLAG_PSEUDOPAL
) &&
73
(i == 1) != (s->
map
[i] == 1)) {
74
av_log
(ctx,
AV_LOG_ERROR
,
75
"Cannot map between a palette plane and a data plane.\n"
);
76
return
AVERROR
(EINVAL);
77
}
78
if
(used[s->
map
[i]])
79
s->
copy
= 1;
80
used[s->
map
[i]]++;
81
}
82
83
return
0;
84
}
85
86
static
int
shuffleplanes_filter_frame
(
AVFilterLink
*inlink,
AVFrame
*
frame
)
87
{
88
AVFilterContext
*ctx = inlink->
dst
;
89
ShufflePlanesContext
*
s
= ctx->
priv
;
90
uint8_t
*shuffled_data[4] = {
NULL
};
91
int
shuffled_linesize[4] = { 0 };
92
int
i,
ret
;
93
94
for
(i = 0; i < s->
planes
; i++) {
95
shuffled_data[i] = frame->
data
[s->
map
[i]];
96
shuffled_linesize[i] = frame->
linesize
[s->
map
[i]];
97
}
98
memcpy(frame->
data
, shuffled_data,
sizeof
(shuffled_data));
99
memcpy(frame->
linesize
, shuffled_linesize,
sizeof
(shuffled_linesize));
100
101
if
(s->
copy
) {
102
AVFrame
*
copy
=
ff_get_video_buffer
(ctx->
outputs
[0], frame->
width
, frame->
height
);
103
104
if
(!copy) {
105
ret =
AVERROR
(ENOMEM);
106
goto
fail;
107
}
108
109
av_frame_copy
(copy, frame);
110
111
ret =
av_frame_copy_props
(copy, frame);
112
if
(ret < 0) {
113
av_frame_free
(©);
114
goto
fail;
115
}
116
117
av_frame_free
(&frame);
118
frame =
copy
;
119
}
120
121
return
ff_filter_frame
(ctx->
outputs
[0], frame);
122
fail:
123
av_frame_free
(&frame);
124
return
ret
;
125
}
126
127
#define OFFSET(x) offsetof(ShufflePlanesContext, x)
128
#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
129
static
const
AVOption
shuffleplanes_options
[] = {
130
{
"map0"
,
"Index of the input plane to be used as the first output plane "
,
OFFSET
(map[0]),
AV_OPT_TYPE_INT
, { .i64 = 0 }, 0, 4,
FLAGS
},
131
{
"map1"
,
"Index of the input plane to be used as the second output plane "
,
OFFSET
(map[1]),
AV_OPT_TYPE_INT
, { .i64 = 1 }, 0, 4,
FLAGS
},
132
{
"map2"
,
"Index of the input plane to be used as the third output plane "
,
OFFSET
(map[2]),
AV_OPT_TYPE_INT
, { .i64 = 2 }, 0, 4,
FLAGS
},
133
{
"map3"
,
"Index of the input plane to be used as the fourth output plane "
,
OFFSET
(map[3]),
AV_OPT_TYPE_INT
, { .i64 = 3 }, 0, 4,
FLAGS
},
134
{
NULL
},
135
};
136
137
static
const
AVClass
shuffleplanes_class
= {
138
.
class_name
=
"shuffleplanes"
,
139
.item_name =
av_default_item_name
,
140
.option =
shuffleplanes_options
,
141
.version =
LIBAVUTIL_VERSION_INT
,
142
};
143
144
static
const
AVFilterPad
shuffleplanes_inputs
[] = {
145
{
146
.
name
=
"default"
,
147
.type =
AVMEDIA_TYPE_VIDEO
,
148
.config_props =
shuffleplanes_config_input
,
149
.filter_frame =
shuffleplanes_filter_frame
,
150
.get_video_buffer =
ff_null_get_video_buffer
,
151
},
152
{
NULL
},
153
};
154
155
static
const
AVFilterPad
shuffleplanes_outputs
[] = {
156
{
157
.
name
=
"default"
,
158
.type =
AVMEDIA_TYPE_VIDEO
,
159
},
160
{
NULL
},
161
};
162
163
AVFilter
ff_vf_shuffleplanes
= {
164
.
name
=
"shuffleplanes"
,
165
.description =
NULL_IF_CONFIG_SMALL
(
"Shuffle video planes"
),
166
167
.priv_size =
sizeof
(
ShufflePlanesContext
),
168
.priv_class = &shuffleplanes_class,
169
170
.
inputs
= shuffleplanes_inputs,
171
.
outputs
= shuffleplanes_outputs,
172
};
Generated on Sun Mar 8 2015 02:35:08 for FFmpeg by
1.8.2