2 * Copyright (c) 2002 A'rpi
3 * Copyright (C) 2012 Clément Bœsch
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * libpostproc filter, ported from MPlayer.
27 #include "libavutil/avassert.h"
28 #include "libavutil/opt.h"
31 #include "libpostproc/postprocess.h"
37 pp_mode
*modes
[PP_QUALITY_MAX
+ 1];
41 #define OFFSET(x) offsetof(PPFilterContext, x)
42 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
43 static const AVOption pp_options
[] = {
44 { "subfilters", "set postprocess subfilters", OFFSET(subfilters
), AV_OPT_TYPE_STRING
, {.str
="de"}, .flags
= FLAGS
},
48 AVFILTER_DEFINE_CLASS(pp
);
50 static av_cold
int pp_init(AVFilterContext
*ctx
)
53 PPFilterContext
*pp
= ctx
->priv
;
55 for (i
= 0; i
<= PP_QUALITY_MAX
; i
++) {
56 pp
->modes
[i
] = pp_get_mode_by_name_and_quality(pp
->subfilters
, i
);
58 return AVERROR_EXTERNAL
;
60 pp
->mode_id
= PP_QUALITY_MAX
;
64 static int pp_process_command(AVFilterContext
*ctx
, const char *cmd
, const char *args
,
65 char *res
, int res_len
, int flags
)
67 PPFilterContext
*pp
= ctx
->priv
;
69 if (!strcmp(cmd
, "quality")) {
70 pp
->mode_id
= av_clip(strtol(args
, NULL
, 10), 0, PP_QUALITY_MAX
);
73 return AVERROR(ENOSYS
);
76 static int pp_query_formats(AVFilterContext
*ctx
)
78 static const enum PixelFormat pix_fmts
[] = {
79 AV_PIX_FMT_YUV420P
, AV_PIX_FMT_YUVJ420P
,
80 AV_PIX_FMT_YUV422P
, AV_PIX_FMT_YUVJ422P
,
83 AV_PIX_FMT_YUV444P
, AV_PIX_FMT_YUVJ444P
,
84 AV_PIX_FMT_YUV440P
, AV_PIX_FMT_YUVJ440P
,
88 ff_set_common_formats(ctx
, ff_make_format_list(pix_fmts
));
92 static int pp_config_props(AVFilterLink
*inlink
)
94 int flags
= PP_CPU_CAPS_AUTO
;
95 PPFilterContext
*pp
= inlink
->dst
->priv
;
97 switch (inlink
->format
) {
98 case AV_PIX_FMT_GRAY8
:
99 case AV_PIX_FMT_YUVJ420P
:
100 case AV_PIX_FMT_YUV420P
: flags
|= PP_FORMAT_420
; break;
101 case AV_PIX_FMT_YUVJ422P
:
102 case AV_PIX_FMT_YUV422P
: flags
|= PP_FORMAT_422
; break;
103 case AV_PIX_FMT_YUV411P
: flags
|= PP_FORMAT_411
; break;
104 case AV_PIX_FMT_GBRP
:
105 case AV_PIX_FMT_YUVJ444P
:
106 case AV_PIX_FMT_YUV444P
: flags
|= PP_FORMAT_444
; break;
107 case AV_PIX_FMT_YUVJ440P
:
108 case AV_PIX_FMT_YUV440P
: flags
|= PP_FORMAT_440
; break;
109 default: av_assert0(0);
112 pp
->pp_ctx
= pp_get_context(inlink
->w
, inlink
->h
, flags
);
114 return AVERROR(ENOMEM
);
118 static int pp_filter_frame(AVFilterLink
*inlink
, AVFrame
*inbuf
)
120 AVFilterContext
*ctx
= inlink
->dst
;
121 PPFilterContext
*pp
= ctx
->priv
;
122 AVFilterLink
*outlink
= ctx
->outputs
[0];
123 const int aligned_w
= FFALIGN(outlink
->w
, 8);
124 const int aligned_h
= FFALIGN(outlink
->h
, 8);
126 int qstride
, qp_type
;
129 outbuf
= ff_get_video_buffer(outlink
, aligned_w
, aligned_h
);
131 av_frame_free(&inbuf
);
132 return AVERROR(ENOMEM
);
134 av_frame_copy_props(outbuf
, inbuf
);
135 outbuf
->width
= inbuf
->width
;
136 outbuf
->height
= inbuf
->height
;
137 qp_table
= av_frame_get_qp_table(inbuf
, &qstride
, &qp_type
);
139 pp_postprocess((const uint8_t **)inbuf
->data
, inbuf
->linesize
,
140 outbuf
->data
, outbuf
->linesize
,
141 aligned_w
, outlink
->h
,
144 pp
->modes
[pp
->mode_id
],
146 outbuf
->pict_type
| (qp_type
? PP_PICT_TYPE_QP2
: 0));
148 av_frame_free(&inbuf
);
149 return ff_filter_frame(outlink
, outbuf
);
152 static av_cold
void pp_uninit(AVFilterContext
*ctx
)
155 PPFilterContext
*pp
= ctx
->priv
;
157 for (i
= 0; i
<= PP_QUALITY_MAX
; i
++)
158 pp_free_mode(pp
->modes
[i
]);
160 pp_free_context(pp
->pp_ctx
);
163 static const AVFilterPad pp_inputs
[] = {
166 .type
= AVMEDIA_TYPE_VIDEO
,
167 .config_props
= pp_config_props
,
168 .filter_frame
= pp_filter_frame
,
173 static const AVFilterPad pp_outputs
[] = {
176 .type
= AVMEDIA_TYPE_VIDEO
,
181 AVFilter ff_vf_pp
= {
183 .description
= NULL_IF_CONFIG_SMALL("Filter video using libpostproc."),
184 .priv_size
= sizeof(PPFilterContext
),
187 .query_formats
= pp_query_formats
,
189 .outputs
= pp_outputs
,
190 .process_command
= pp_process_command
,
191 .priv_class
= &pp_class
,
192 .flags
= AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,