FFmpeg
Loading...
Searching...
No Matches
vf_qp.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
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 <math.h>
22#include "libavutil/eval.h"
23#include "libavutil/opt.h"
25
26#include "avfilter.h"
27#include "filters.h"
28#include "video.h"
29
30typedef struct QPContext {
31 const AVClass *class;
33 int8_t lut[257];
34 int h, qstride;
36} QPContext;
37
38static const char *const var_names[] = { "known", "qp", "x", "y", "w", "h", NULL };
39
40#define OFFSET(x) offsetof(QPContext, x)
41#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
42
43static const AVOption qp_options[] = {
44 { "qp", "set qp expression", OFFSET(qp_expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
45 { NULL }
46};
47
49
50static int config_input(AVFilterLink *inlink)
51{
52 AVFilterContext *ctx = inlink->dst;
53 QPContext *s = ctx->priv;
54 int i;
55 int ret;
56 AVExpr *e = NULL;
57
58 if (!s->qp_expr_str)
59 return 0;
60
61 ret = av_expr_parse(&e, s->qp_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx);
62 if (ret < 0)
63 return ret;
64
65 s->h = (inlink->h + 15) >> 4;
66 s->qstride = (inlink->w + 15) >> 4;
67 for (i = -129; i < 128; i++) {
68 double var_values[] = { i != -129, i, NAN, NAN, s->qstride, s->h, 0};
69 double temp_val = av_expr_eval(e, var_values, NULL);
70
71 if (isnan(temp_val)) {
72 if(strchr(s->qp_expr_str, 'x') || strchr(s->qp_expr_str, 'y'))
73 s->evaluate_per_mb = 1;
74 else {
75 av_expr_free(e);
76 return AVERROR(EINVAL);
77 }
78 }
79
80 s->lut[i + 129] = lrintf(temp_val);
81 }
82 av_expr_free(e);
83
84 return 0;
85}
86
87static int filter_frame(AVFilterLink *inlink, AVFrame *in)
88{
89 AVFilterContext *ctx = inlink->dst;
90 AVFilterLink *outlink = ctx->outputs[0];
91 QPContext *s = ctx->priv;
92 AVFrame *out = NULL;
93 int ret;
94
95 AVFrameSideData *sd_in;
96 AVVideoEncParams *par_in = NULL;
97 int8_t in_qp_global = 0;
98
99 AVVideoEncParams *par_out;
100
101 if (!s->qp_expr_str || ctx->is_disabled)
102 return ff_filter_frame(outlink, in);
103
105 if (sd_in && sd_in->size >= sizeof(AVVideoEncParams)) {
106 par_in = (AVVideoEncParams*)sd_in->data;
107
108 // we accept the input QP table only if it is of the MPEG2 type
109 // and contains either no blocks at all or 16x16 macroblocks
110 if (par_in->type == AV_VIDEO_ENC_PARAMS_MPEG2 &&
111 (par_in->nb_blocks == s->h * s->qstride || !par_in->nb_blocks)) {
112 in_qp_global = par_in->qp;
113 if (!par_in->nb_blocks)
114 par_in = NULL;
115 } else
116 par_in = NULL;
117 }
118
119 out = av_frame_clone(in);
120 if (!out) {
121 ret = AVERROR(ENOMEM);
122 goto fail;
123 }
124
126 (s->evaluate_per_mb || sd_in) ?
127 s->h * s->qstride : 0);
128 if (!par_out) {
129 ret = AVERROR(ENOMEM);
130 goto fail;
131 }
132
133#define BLOCK_QP_DELTA(block_idx) \
134 (par_in ? av_video_enc_params_block(par_in, block_idx)->delta_qp : 0)
135
136 if (s->evaluate_per_mb) {
137 int y, x;
138
139 for (y = 0; y < s->h; y++)
140 for (x = 0; x < s->qstride; x++) {
141 unsigned int block_idx = y * s->qstride + x;
142 AVVideoBlockParams *b = av_video_enc_params_block(par_out, block_idx);
143 double qp = sd_in ? in_qp_global + BLOCK_QP_DELTA(block_idx) : NAN;
144 double var_values[] = { !!sd_in, qp, x, y, s->qstride, s->h, 0};
145 double temp_val;
146
147 ret = av_expr_parse_and_eval(&temp_val, s->qp_expr_str,
148 var_names, var_values,
149 NULL, NULL, NULL, NULL, 0, 0, ctx);
150 if (ret < 0)
151 goto fail;
152 b->delta_qp = lrintf(temp_val);
153 }
154 } else if (sd_in) {
155 int y, x;
156
157 for (y = 0; y < s->h; y++)
158 for (x = 0; x < s->qstride; x++) {
159 unsigned int block_idx = y * s->qstride + x;
160 AVVideoBlockParams *b = av_video_enc_params_block(par_out, block_idx);
161 b->delta_qp = s->lut[129 + (int8_t)(in_qp_global + BLOCK_QP_DELTA(block_idx))];
162 }
163 } else {
164 par_out->qp = s->lut[0];
165 }
166
167 ret = ff_filter_frame(outlink, out);
168 out = NULL;
169fail:
170 av_frame_free(&in);
172 return ret;
173}
174
175static const AVFilterPad qp_inputs[] = {
176 {
177 .name = "default",
178 .type = AVMEDIA_TYPE_VIDEO,
179 .filter_frame = filter_frame,
180 .config_props = config_input,
181 },
182};
183
185 .p.name = "qp",
186 .p.description = NULL_IF_CONFIG_SMALL("Change video quantization parameters."),
187 .p.priv_class = &qp_class,
190 .priv_size = sizeof(QPContext),
193};
static int config_input(AVFilterLink *inlink)
const FFFilter ff_vf_qp
Definition vf_qp.c:184
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:598
#define NULL
Definition coverity.c:32
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition eval.c:368
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition eval.c:824
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
Definition eval.c:839
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition eval.c:735
simple arithmetic expression evaluator
#define fail
Definition test.h:479
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
Definition avfilter.h:204
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition avfilter.h:182
#define AVERROR(e)
Definition error.h:45
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:659
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition frame.c:483
@ AV_FRAME_DATA_VIDEO_ENC_PARAMS
Encoding parameters for a video frame, as described by AVVideoEncParams.
Definition frame.h:170
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define b
Definition input.c:43
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define isnan(x)
Definition libm.h:342
#define lrintf(x)
Definition libm_mips.h:72
#define NAN
static const char *const var_names[]
Definition noise.c:30
AVOptions.
Describe the class of an AVClass context structure.
Definition log.h:76
Definition eval.c:171
An instance of a filter.
Definition avfilter.h:273
A filter pad used for either input or output.
Definition filters.h:40
Structure to hold side data for an AVFrame.
Definition frame.h:327
size_t size
Definition frame.h:330
uint8_t * data
Definition frame.h:329
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
Data structure for storing block-level encoding information.
Video encoding parameters for a given frame.
enum AVVideoEncParamsType type
Type of the parameters (the codec they are used with).
unsigned int nb_blocks
Number of blocks in the array.
int32_t qp
Base quantisation parameter for the frame.
int qstride
Definition vf_qp.c:34
int8_t lut[257]
Definition vf_qp.c:33
char * qp_expr_str
Definition vf_qp.c:32
int h
Definition vf_qp.c:34
int evaluate_per_mb
Definition vf_qp.c:35
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
static const AVFilterPad qp_inputs[]
Definition vf_qp.c:175
static int config_input(AVFilterLink *inlink)
Definition vf_qp.c:50
static const AVOption qp_options[]
Definition vf_qp.c:43
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition vf_qp.c:87
#define BLOCK_QP_DELTA(block_idx)
#define OFFSET(x)
Definition vf_qp.c:40
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition video.c:37
AVVideoEncParams * av_video_enc_params_create_side_data(AVFrame *frame, enum AVVideoEncParamsType type, unsigned int nb_blocks)
Allocates memory for AVEncodeInfoFrame plus an array of nb_blocks AVEncodeInfoBlock in the given AVFr...
static av_always_inline AVVideoBlockParams * av_video_enc_params_block(AVVideoEncParams *par, unsigned int idx)
Get the block at the specified idx.
@ AV_VIDEO_ENC_PARAMS_MPEG2