]> git.sesse.net Git - vlc/blob - modules/video_filter/hqdn3d.c
Qt4: Fixed uninitialized variable
[vlc] / modules / video_filter / hqdn3d.c
1 /*****************************************************************************
2  * hqdn3d.c : high-quality denoise 3D ported from MPlayer
3  *****************************************************************************
4  * Copyright (C) 2011 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Cheng Sun <chengsun9@gmail.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_filter.h>
35 #include "filter_picture.h"
36
37
38 #include "hqdn3d.h"
39
40 /*****************************************************************************
41  * Local protypes
42  *****************************************************************************/
43 static int  Open         (vlc_object_t *);
44 static void Close        (vlc_object_t *);
45 static picture_t *Filter (filter_t *, picture_t *);
46
47 /*****************************************************************************
48  * Module descriptor
49  *****************************************************************************/
50
51 #define FILTER_PREFIX       "hqdn3d-"
52
53 #define LUMA_SPAT_TEXT          N_("Spatial luma strength (0-254)")
54 #define LUMA_SPAT_LONGTEXT      N_("Spatial luma strength (default 4)")
55 #define CHROMA_SPAT_TEXT        N_("Spatial chroma strength (0-254)")
56 #define CHROMA_SPAT_LONGTEXT    N_("Spatial chroma strength (default 3)")
57 #define LUMA_TEMP_TEXT          N_("Temporal luma strength (0-254)")
58 #define LUMA_TEMP_LONGTEXT      N_("Temporal luma strength (default 6)")
59 #define CHROMA_TEMP_TEXT        N_("Temporal chroma strength (0-254)")
60 #define CHROMA_TEMP_LONGTEXT    N_("Temporal chroma strength (default 4.5)")
61
62 vlc_module_begin()
63     set_shortname(N_("HQ Denoiser 3D"))
64     set_description(N_("High Quality 3D Denoiser filter"))
65     set_capability("video filter2", 0)
66     set_category(CAT_VIDEO)
67     set_subcategory(SUBCAT_VIDEO_VFILTER)
68
69     add_float_with_range(FILTER_PREFIX "luma-spat", 4.0, 0.0, 254.0,
70             LUMA_SPAT_TEXT, LUMA_SPAT_LONGTEXT, false)
71     add_float_with_range(FILTER_PREFIX "chroma-spat", 3.0, 0.0, 254.0,
72             CHROMA_SPAT_TEXT, CHROMA_SPAT_LONGTEXT, false)
73     add_float_with_range(FILTER_PREFIX "luma-temp", 6.0, 0.0, 254.0,
74             LUMA_TEMP_TEXT, LUMA_TEMP_LONGTEXT, false)
75     add_float_with_range(FILTER_PREFIX "chroma-temp", 4.5, 0.0, 254.0,
76             CHROMA_TEMP_TEXT, CHROMA_TEMP_LONGTEXT, false)
77
78     add_shortcut("hqdn3d")
79
80     set_callbacks(Open, Close)
81 vlc_module_end()
82
83 static const char *const filter_options[] = {
84     "luma-spat", "chroma-spat", "luma-temp", "chroma-temp", NULL
85 };
86
87 /*****************************************************************************
88  * filter_sys_t
89  *****************************************************************************/
90 struct filter_sys_t
91 {
92     const vlc_chroma_description_t *chroma;
93     int w[3], h[3];
94
95     float luma_spat;
96     float chroma_spat;
97     float luma_temp;
98     float chroma_temp;
99
100     struct vf_priv_s cfg;
101 };
102
103 /*****************************************************************************
104  * Open
105  *****************************************************************************/
106 static int Open(vlc_object_t *this)
107 {
108     filter_t *filter = (filter_t *)this;
109     filter_sys_t *sys;
110     struct vf_priv_s *cfg;
111     const video_format_t *fmt_in  = &filter->fmt_in.video;
112     const video_format_t *fmt_out = &filter->fmt_out.video;
113     const vlc_fourcc_t fourcc_in  = fmt_in->i_chroma;
114     const vlc_fourcc_t fourcc_out = fmt_out->i_chroma;
115     int wmax = 0;
116
117     const vlc_chroma_description_t *chroma =
118             vlc_fourcc_GetChromaDescription(fourcc_in);
119     if (!chroma || chroma->plane_count != 3 || chroma->pixel_size != 1) {
120         msg_Err(filter, "Unsupported chroma (%4.4s)", (char*)&fourcc_in);
121         return VLC_EGENERIC;
122     }
123
124     if (fourcc_in != fourcc_out) {
125         msg_Err(filter, "Input and output chromas don't match");
126         return VLC_EGENERIC;
127     }
128
129     /* Allocate structure */
130     sys = calloc(1, sizeof(filter_sys_t));
131     if (!sys) {
132         return VLC_ENOMEM;
133     }
134     cfg = &sys->cfg;
135
136     sys->chroma = chroma;
137
138     for (int i = 0; i < 3; ++i) {
139         sys->w[i] = fmt_in->i_width  * chroma->p[i].w.num / chroma->p[i].w.den;
140         if (sys->w[i] > wmax) wmax = sys->w[i];
141         sys->h[i] = fmt_out->i_height * chroma->p[i].h.num / chroma->p[i].h.den;
142     }
143     cfg->Line = malloc(wmax*sizeof(int));
144     if (!cfg->Line) {
145         free(sys);
146         return VLC_ENOMEM;
147     }
148
149     filter->p_sys = sys;
150     filter->pf_video_filter = Filter;
151
152     config_ChainParse(filter, FILTER_PREFIX, filter_options,
153                       filter->p_cfg);
154
155     sys->luma_spat =
156             var_CreateGetFloatCommand(filter, FILTER_PREFIX "luma-spat");
157     sys->chroma_spat =
158             var_CreateGetFloatCommand(filter, FILTER_PREFIX "chroma-spat");
159     sys->luma_temp =
160             var_CreateGetFloatCommand(filter, FILTER_PREFIX "luma-temp");
161     sys->chroma_temp =
162             var_CreateGetFloatCommand(filter, FILTER_PREFIX "chroma-temp");
163
164     PrecalcCoefs(cfg->Coefs[0], sys->luma_spat);
165     PrecalcCoefs(cfg->Coefs[1], sys->luma_temp);
166     PrecalcCoefs(cfg->Coefs[2], sys->chroma_spat);
167     PrecalcCoefs(cfg->Coefs[3], sys->chroma_temp);
168
169     return VLC_SUCCESS;
170 }
171
172 /*****************************************************************************
173  * Close
174  *****************************************************************************/
175 static void Close(vlc_object_t *this)
176 {
177     filter_t *filter = (filter_t *)this;
178     filter_sys_t *sys = filter->p_sys;
179     struct vf_priv_s *cfg = &sys->cfg;
180
181     for (int i = 0; i < 3; ++i) {
182         free(cfg->Frame[i]);
183     }
184     free(cfg->Line);
185     free(sys);
186 }
187
188 /*****************************************************************************
189  * Filter
190  *****************************************************************************/
191 static picture_t *Filter(filter_t *filter, picture_t *src)
192 {
193     picture_t *dst;
194     filter_sys_t *sys = filter->p_sys;
195     struct vf_priv_s *cfg = &sys->cfg;
196
197     if (!src) return NULL;
198
199     dst = filter_NewPicture(filter);
200     if (!dst) {
201         picture_Release(src);
202         return NULL;
203     }
204
205     deNoise(src->p[0].p_pixels, dst->p[0].p_pixels,
206             cfg->Line, &cfg->Frame[0], sys->w[0], sys->h[0],
207             src->p[0].i_pitch, dst->p[0].i_pitch,
208             cfg->Coefs[0],
209             cfg->Coefs[0],
210             cfg->Coefs[1]);
211     deNoise(src->p[1].p_pixels, dst->p[1].p_pixels,
212             cfg->Line, &cfg->Frame[1], sys->w[1], sys->h[1],
213             src->p[1].i_pitch, dst->p[1].i_pitch,
214             cfg->Coefs[2],
215             cfg->Coefs[2],
216             cfg->Coefs[3]);
217     deNoise(src->p[2].p_pixels, dst->p[2].p_pixels,
218             cfg->Line, &cfg->Frame[2], sys->w[2], sys->h[2],
219             src->p[2].i_pitch, dst->p[2].i_pitch,
220             cfg->Coefs[2],
221             cfg->Coefs[2],
222             cfg->Coefs[3]);
223
224     return CopyInfoAndRelease(dst, src);
225 }