]> git.sesse.net Git - vlc/blob - modules/video_filter/deinterlace/deinterlace.h
Refactored deinterlacer module
[vlc] / modules / video_filter / deinterlace / deinterlace.h
1 /*****************************************************************************
2  * deinterlace.h : deinterlacer plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2011 the VideoLAN team
5  * $Id$
6  *
7  * Author: Sam Hocevar <sam@zoy.org>
8  *         Juha Jeronen <juha.jeronen@jyu.fi> (Phosphor and IVTC modes)
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifndef VLC_DEINTERLACE_H
26 #define VLC_DEINTERLACE_H 1
27
28 /* Forward declarations */
29 struct filter_t;
30 struct picture_t;
31 struct vlc_object_t;
32
33 #include <vlc_common.h>
34 #include <vlc_mouse.h>
35
36 /* Local algorithm headers */
37 #include "algo_basic.h"
38 #include "algo_x.h"
39 #include "algo_yadif.h"
40 #include "algo_phosphor.h"
41 #include "algo_ivtc.h"
42
43 /*****************************************************************************
44  * Local data
45  *****************************************************************************/
46
47 /** Available deinterlace modes. */
48 static const char *const mode_list[] = {
49     "discard", "blend", "mean", "bob", "linear", "x",
50     "yadif", "yadif2x", "phosphor", "ivtc" };
51
52 /** User labels for the available deinterlace modes. */
53 static const char *const mode_list_text[] = {
54     N_("Discard"), N_("Blend"), N_("Mean"), N_("Bob"), N_("Linear"), "X",
55     "Yadif", "Yadif (2x)", N_("Phosphor"), N_("Film NTSC (IVTC)") };
56
57 /*****************************************************************************
58  * Data structures
59  *****************************************************************************/
60
61 /**
62  * Available deinterlace algorithms.
63  * @see SetFilterMethod()
64  */
65 typedef enum { DEINTERLACE_DISCARD, DEINTERLACE_MEAN,    DEINTERLACE_BLEND,
66                DEINTERLACE_BOB,     DEINTERLACE_LINEAR,  DEINTERLACE_X,
67                DEINTERLACE_YADIF,   DEINTERLACE_YADIF2X, DEINTERLACE_PHOSPHOR,
68                DEINTERLACE_IVTC } deinterlace_mode;
69
70 #define METADATA_SIZE (3)
71 /**
72  * Metadata history structure, used for framerate doublers.
73  * This is used for computing field duration in Deinterlace().
74  * @see Deinterlace()
75  */
76 typedef struct {
77     mtime_t pi_date[METADATA_SIZE];
78     int     pi_nb_fields[METADATA_SIZE];
79     bool    pb_top_field_first[METADATA_SIZE];
80 } metadata_history_t;
81
82 #define HISTORY_SIZE (3)
83 #define CUSTOM_PTS -1
84 /**
85  * Top-level deinterlace subsystem state.
86  */
87 struct filter_sys_t
88 {
89     int  i_mode;              /**< Deinterlace mode */
90
91     /* Algorithm behaviour flags */
92     bool b_double_rate;       /**< Shall we double the framerate? */
93     bool b_half_height;       /**< Shall be divide the height by 2 */
94     bool b_use_frame_history; /**< Use the input frame history buffer? */
95
96     /** Merge routine: C, MMX, SSE, ALTIVEC, NEON, ... */
97     void (*pf_merge) ( void *, const void *, const void *, size_t );
98     /** Merge finalization routine: C, MMX, SSE, ALTIVEC, NEON, ... */
99     void (*pf_end_merge) ( void );
100
101     /**
102      * Metadata history (PTS, nb_fields, TFF). Used for framerate doublers.
103      * @see metadata_history_t
104      */
105     metadata_history_t meta;
106
107     /** Output frame timing / framerate doubler control
108         (see extra documentation in deinterlace.h) */
109     int i_frame_offset;
110
111     /** Input frame history buffer for algorithms with temporal filtering. */
112     picture_t *pp_history[HISTORY_SIZE];
113
114     /* Algorithm-specific substructures */
115     phosphor_sys_t phosphor; /**< Phosphor algorithm state. */
116     ivtc_sys_t ivtc;         /**< IVTC algorithm state. */
117 };
118
119 /*****************************************************************************
120  * Filter control related internal functions for the deinterlace filter
121  *****************************************************************************/
122
123 /**
124  * Setup the deinterlace method to use.
125  *
126  * FIXME: extract i_chroma from p_filter automatically?
127  *
128  * @param p_filter The filter instance.
129  * @param psz_method Desired method. See mode_list for available choices.
130  * @param i_chroma Input chroma. Set this to p_filter->fmt_in.video.i_chroma.
131  * @see mode_list
132  */
133 void SetFilterMethod( filter_t *p_filter, const char *psz_method,
134                       vlc_fourcc_t i_chroma );
135
136 /**
137  * Get the output video format of the chosen deinterlace method
138  * for the given input video format.
139  *
140  * Note that each algorithm is allowed to specify its output format,
141  * which may (for some input formats) differ from the input format.
142  *
143  * @param p_filter The filter instance.
144  * @param[out] p_dst Output video format. The structure must be allocated by caller.
145  * @param[in] p_src Input video format.
146  * @see SetFilterMethod()
147  */
148 void GetOutputFormat( filter_t *p_filter,
149                       video_format_t *p_dst,
150                       const video_format_t *p_src );
151
152 /**
153  * Returns whether the specified chroma is implemented in the deinterlace
154  * filter.
155  *
156  * Currently, supported chromas are I420, J420 (4:2:0 full scale),
157  * YV12 (like I420, but YVU), I422 and J422.
158  *
159  * Note for deinterlace hackers: adding support for a new chroma typically
160  * requires changes to all low-level functions across all the algorithms.
161  *
162  * @see vlc_fourcc_t
163  */
164 bool IsChromaSupported( vlc_fourcc_t i_chroma );
165
166 /*****************************************************************************
167  * video filter2 functions
168  *****************************************************************************/
169
170 /**
171  * Top-level filtering method.
172  *
173  * Open() sets this up as the processing method (pf_video_filter)
174  * in the filter structure.
175  *
176  * Note that there is no guarantee that the returned picture directly
177  * corresponds to p_pic. The first few times, the filter may not even
178  * return a picture, if it is still filling the history for temporal
179  * filtering (although such filters often return *something* also
180  * while starting up). It should be assumed that N input pictures map to
181  * M output pictures, with no restrictions for N and M (except that there
182  * is not much delay).
183  *
184  * Also, there is no guarantee that the PTS of the frame stays untouched.
185  * In fact, framerate doublers automatically compute the proper PTSs for the
186  * two output frames for each input frame, and IVTC does a nontrivial
187  * framerate conversion (29.97 > 23.976 fps).
188  *
189  * Yadif has an offset of one frame between input and output, but introduces
190  * no delay: the returned frame is the *previous* input frame deinterlaced,
191  * complete with its original PTS.
192  *
193  * Finally, note that returning NULL sometimes can be normal behaviour for some
194  * algorithms (e.g. IVTC).
195  *
196  * Currently:
197  *   Most algorithms:        1 -> 1, no offset
198  *   All framerate doublers: 1 -> 2, no offset
199  *   Yadif:                  1 -> 1, offset of one frame
200  *   IVTC:                   1 -> 1 or 0 (depends on whether a drop was needed)
201  *                                with an offset of one frame (in most cases)
202  *                                and framerate conversion.
203  *
204  * @param p_filter The filter instance.
205  * @param p_pic The latest input picture.
206  * @return Deinterlaced picture(s). Linked list of picture_t's or NULL.
207  * @see Open()
208  * @see filter_t
209  * @see filter_sys_t
210  */
211 picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic );
212
213 /**
214  * Reads the configuration, sets up and starts the filter.
215  *
216  * Possible reasons for returning VLC_EGENERIC:
217  *  - Unsupported input chroma. See IsChromaSupported().
218  *  - Caller has set p_filter->b_allow_fmt_out_change to false,
219  *    but the algorithm chosen in the configuration
220  *    wants to convert the output to a format different
221  *    from the input. See SetFilterMethod().
222  *
223  * Open() is atomic: if an error occurs, the state of p_this
224  * is left as it was before the call to this function.
225  *
226  * @param p_this The filter instance as vlc_object_t.
227  * @return VLC error code
228  * @retval VLC_SUCCESS All ok, filter set up and started.
229  * @retval VLC_ENOMEM Memory allocation error, initialization aborted.
230  * @retval VLC_EGENERIC Something went wrong, initialization aborted.
231  * @see IsChromaSupported()
232  * @see SetFilterMethod()
233  */
234 int Open( vlc_object_t *p_this );
235
236 /**
237  * Resets the filter state, including resetting all algorithm-specific state
238  * and discarding all histories, but does not stop the filter.
239  *
240  * Open() sets this up as the flush method (pf_video_flush)
241  * in the filter structure.
242  *
243  * @param p_filter The filter instance.
244  * @see Open()
245  * @see filter_t
246  * @see filter_sys_t
247  * @see metadata_history_t
248  * @see phosphor_sys_t
249  * @see ivtc_sys_t
250  */
251 void Flush( filter_t *p_filter );
252
253 /**
254  * Mouse callback for the deinterlace filter.
255  *
256  * Open() sets this up as the mouse callback method (pf_video_mouse)
257  * in the filter structure.
258  *
259  * Currently, this handles the scaling of the y coordinate for algorithms
260  * that halve the output height.
261  *
262  * @param p_filter The filter instance.
263  * @param[out] p_mouse Updated mouse position data.
264  * @param[in] p_old Previous mouse position data. Unused in this filter.
265  * @param[in] p_new Latest mouse position data.
266  * @return VLC error code; currently always VLC_SUCCESS.
267  * @retval VLC_SUCCESS All ok.
268  * @see Open()
269  * @see filter_t
270  * @see vlc_mouse_t
271  */
272 int Mouse( filter_t *p_filter,
273            vlc_mouse_t *p_mouse,
274            const vlc_mouse_t *p_old,
275            const vlc_mouse_t *p_new );
276
277 /**
278  * Stops and uninitializes the filter, and deallocates memory.
279  * @param p_this The filter instance as vlc_object_t.
280  */
281 void Close( vlc_object_t *p_this );
282
283 /*****************************************************************************
284  * Extra documentation
285  *****************************************************************************/
286
287 /**
288  * \file
289  * Deinterlacer plugin for vlc. Data structures and video filter2 functions.
290  *
291  * Note on i_frame_offset:
292  *
293  * This value indicates the offset between input and output frames in the
294  * currently active deinterlace algorithm. See the rationale below for why
295  * this is needed and how it is used.
296  *
297  * Valid range: 0 <= i_frame_offset < METADATA_SIZE, or
298  *              i_frame_offset = CUSTOM_PTS.
299  *              The special value CUSTOM_PTS is only allowed
300  *              if b_double_rate is false.
301  *
302  *              If CUSTOM_PTS is used, the algorithm must compute the outgoing
303  *              PTSs itself, and additionally, read the TFF/BFF information
304  *              itself (if it needs it) from the incoming frames.
305  *
306  * Meaning of values:
307  * 0 = output frame corresponds to the current input frame
308  *     (no frame offset; default if not set),
309  * 1 = output frame corresponds to the previous input frame
310  *     (e.g. Yadif and Yadif2x work like this),
311  * ...
312  *
313  * If necessary, i_frame_offset should be updated by the active deinterlace
314  * algorithm to indicate the correct delay for the *next* input frame.
315  * It does not matter at which i_order the algorithm updates this information,
316  * but the new value will only take effect upon the next call to Deinterlace()
317  * (i.e. at the next incoming frame).
318  *
319  * The first-ever frame that arrives to the filter after Open() is always
320  * handled as having i_frame_offset = 0. For the second and all subsequent
321  * frames, each algorithm is responsible for setting the offset correctly.
322  * (The default is 0, so if that is correct, there's no need to do anything.)
323  *
324  * This solution guarantees that i_frame_offset:
325  *   1) is up to date at the start of each frame,
326  *   2) does not change (as far as Deinterlace() is concerned) during
327  *      a frame, and
328  *   3) does not need a special API for setting the value at the start of each
329  *      input frame, before the algorithm starts rendering the (first) output
330  *      frame for that input frame.
331  *
332  * The deinterlace algorithm is allowed to behave differently for different
333  * input frames. This is especially important for startup, when full history
334  * (as defined by each algorithm) is not yet available. During the first-ever
335  * input frame, it is clear that it is the only possible source for
336  * information, so i_frame_offset = 0 is necessarily correct. After that,
337  * what to do is up to each algorithm.
338  *
339  * Having the correct offset at the start of each input frame is critically
340  * important in order to:
341  *   1) Allocate the correct number of output frames for framerate doublers,
342  *      and to
343  *   2) Pass correct TFF/BFF information to the algorithm.
344  *
345  * These points are important for proper soft field repeat support. This
346  * feature is used in some streams (especially NTSC) originating from film.
347  * For example, in soft NTSC telecine, the number of fields alternates
348  * as 3,2,3,2,... and the video field dominance flips every two frames (after
349  * every "3"). Also, some streams request an occasional field repeat
350  * (nb_fields = 3), after which the video field dominance flips.
351  * To render such streams correctly, the nb_fields and TFF/BFF information
352  * must be taken from the specific input frame that the algorithm intends
353  * to render.
354  *
355  * Additionally, the output PTS is automatically computed by Deinterlace()
356  * from i_frame_offset and i_order.
357  *
358  * It is possible to use the special value CUSTOM_PTS to indicate that the
359  * algorithm computes the output PTSs itself. In this case, Deinterlace()
360  * will pass them through. This special value is not valid for framerate
361  * doublers, as by definition they are field renderers, so they need to
362  * use the original field timings to work correctly. Basically, this special
363  * value is only intended for algorithms that need to perform nontrivial
364  * framerate conversions (such as IVTC).
365  */
366
367 #endif