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
,
82 AV_PIX_FMT_YUV444P
, AV_PIX_FMT_YUVJ444P
,
85 ff_set_common_formats(ctx
, ff_make_format_list(pix_fmts
));
89 static int pp_config_props(AVFilterLink
*inlink
)
91 int flags
= PP_CPU_CAPS_AUTO
;
92 PPFilterContext
*pp
= inlink
->dst
->priv
;
94 switch (inlink
->format
) {
95 case AV_PIX_FMT_YUVJ420P
:
96 case AV_PIX_FMT_YUV420P
: flags
|= PP_FORMAT_420
; break;
97 case AV_PIX_FMT_YUVJ422P
:
98 case AV_PIX_FMT_YUV422P
: flags
|= PP_FORMAT_422
; break;
99 case AV_PIX_FMT_YUV411P
: flags
|= PP_FORMAT_411
; break;
100 case AV_PIX_FMT_YUVJ444P
:
101 case AV_PIX_FMT_YUV444P
: flags
|= PP_FORMAT_444
; break;
102 default: av_assert0(0);
105 pp
->pp_ctx
= pp_get_context(inlink
->w
, inlink
->h
, flags
);
107 return AVERROR(ENOMEM
);
111 static int pp_filter_frame(AVFilterLink
*inlink
, AVFrame
*inbuf
)
113 AVFilterContext
*ctx
= inlink
->dst
;
114 PPFilterContext
*pp
= ctx
->priv
;
115 AVFilterLink
*outlink
= ctx
->outputs
[0];
116 const int aligned_w
= FFALIGN(outlink
->w
, 8);
117 const int aligned_h
= FFALIGN(outlink
->h
, 8);
119 int qstride
, qp_type
;
122 outbuf
= ff_get_video_buffer(outlink
, aligned_w
, aligned_h
);
124 av_frame_free(&inbuf
);
125 return AVERROR(ENOMEM
);
127 av_frame_copy_props(outbuf
, inbuf
);
128 outbuf
->width
= inbuf
->width
;
129 outbuf
->height
= inbuf
->height
;
130 qp_table
= av_frame_get_qp_table(inbuf
, &qstride
, &qp_type
);
132 pp_postprocess((const uint8_t **)inbuf
->data
, inbuf
->linesize
,
133 outbuf
->data
, outbuf
->linesize
,
134 aligned_w
, outlink
->h
,
137 pp
->modes
[pp
->mode_id
],
139 outbuf
->pict_type
| (qp_type
? PP_PICT_TYPE_QP2
: 0));
141 av_frame_free(&inbuf
);
142 return ff_filter_frame(outlink
, outbuf
);
145 static av_cold
void pp_uninit(AVFilterContext
*ctx
)
148 PPFilterContext
*pp
= ctx
->priv
;
150 for (i
= 0; i
<= PP_QUALITY_MAX
; i
++)
151 pp_free_mode(pp
->modes
[i
]);
153 pp_free_context(pp
->pp_ctx
);
156 static const AVFilterPad pp_inputs
[] = {
159 .type
= AVMEDIA_TYPE_VIDEO
,
160 .config_props
= pp_config_props
,
161 .filter_frame
= pp_filter_frame
,
166 static const AVFilterPad pp_outputs
[] = {
169 .type
= AVMEDIA_TYPE_VIDEO
,
174 AVFilter ff_vf_pp
= {
176 .description
= NULL_IF_CONFIG_SMALL("Filter video using libpostproc."),
177 .priv_size
= sizeof(PPFilterContext
),
180 .query_formats
= pp_query_formats
,
182 .outputs
= pp_outputs
,
183 .process_command
= pp_process_command
,
184 .priv_class
= &pp_class
,
185 .flags
= AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,