1
mirror of https://code.videolan.org/videolan/vlc synced 2024-09-04 09:11:33 +02:00
vlc/modules/video_filter/deinterlace/algo_phosphor.h
Juha Jeronen c7d289cad5 Refactored deinterlacer module
Signed-off-by: Rémi Denis-Courmont <remi@remlab.net>
2011-05-01 12:38:59 +03:00

175 lines
8.2 KiB
C

/*****************************************************************************
* algo_phosphor.h : Phosphor algorithm for the VLC deinterlacer
*****************************************************************************
* Copyright (C) 2011 the VideoLAN team
* $Id$
*
* Author: Juha Jeronen <juha.jeronen@jyu.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_DEINTERLACE_ALGO_PHOSPHOR_H
#define VLC_DEINTERLACE_ALGO_PHOSPHOR_H 1
/* Forward declarations */
struct filter_t;
struct picture_t;
/*****************************************************************************
* Data structures etc.
*****************************************************************************/
/* These numbers, and phosphor_chroma_list[], should be in the same order
as phosphor_chroma_list_text[]. The value 0 is reserved, because
var_GetInteger() returns 0 in case of error. */
/** Valid Phosphor 4:2:0 chroma handling modes. */
typedef enum { PC_LATEST = 1, PC_ALTLINE = 2,
PC_BLEND = 3, PC_UPCONVERT = 4 } phosphor_chroma_t;
/** Phosphor 4:2:0 chroma handling modes (config item). */
static const int phosphor_chroma_list[] = { PC_LATEST, PC_ALTLINE,
PC_BLEND, PC_UPCONVERT };
/** User labels for Phosphor 4:2:0 chroma handling modes (config item). */
static const char *const phosphor_chroma_list_text[] = { N_("Latest"),
N_("AltLine"),
N_("Blend"),
N_("Upconvert") };
/* Same here. Same order as in phosphor_dimmer_list_text[],
and the value 0 is reserved for config error. */
/** Phosphor dimmer strengths (config item). */
static const int phosphor_dimmer_list[] = { 1, 2, 3, 4 };
/** User labels for Phosphor dimmer strengths (config item). */
static const char *const phosphor_dimmer_list_text[] = { N_("Off"),
N_("Low"),
N_("Medium"),
N_("High") };
/** Algorithm-specific state for Phosphor. */
typedef struct
{
phosphor_chroma_t i_chroma_for_420;
int i_dimmer_strength;
} phosphor_sys_t;
/*****************************************************************************
* Functions
*****************************************************************************/
/**
* "Phosphor" deinterlace algorithm: framerate-doubling CRT TV simulator.
*
* There is no "1x" mode in this filter; only framerate doubling is supported.
*
* There is no input frame parameter, because the input frames
* are taken from the history buffer.
*
* Soft field repeat (repeat_pict) is supported. Note that the generated
* "repeated" output picture is unique because of the simulated light decay.
* Its "old" field comes from the same input frame as the "new" one, unlike
* the first output picture of the same frame.
*
* As many output frames should be requested for each input frame as is
* indicated by p_src->i_nb_fields. This is done by calling this function
* several times, first with i_order = 0, and then with all other parameters
* the same, but a new p_dst, increasing i_order (1 for second field,
* and then if i_nb_fields = 3, also i_order = 2 to get the repeated first
* field), and alternating i_field (starting, at i_order = 0, with the field
* according to p_src->b_top_field_first). See Deinterlace() for an example.
*
* @param p_filter The filter instance. Must be non-NULL.
* @param p_dst Output frame. Must be allocated by caller.
* @param i_order Temporal field number: 0 = first, 1 = second, 2 = rep. first.
* @param i_field Render which field? 0 = top field, 1 = bottom field.
* @return VLC error code (int).
* @retval VLC_SUCCESS The requested field was rendered into p_dst.
* @retval VLC_EGENERIC No pictures in history buffer, cannot render.
* @see RenderBob()
* @see RenderLinear()
* @see Deinterlace()
*/
int RenderPhosphor( filter_t *p_filter,
picture_t *p_dst,
int i_order, int i_field );
/*****************************************************************************
* Extra documentation
*****************************************************************************/
/**
* \file
* "Phosphor" deinterlace algorithm. This simulates the rendering mechanism
* of an interlaced CRT TV, actually producing *interlaced* output.
*
* The main use case for this filter is anime for which IVTC is not applicable.
* This is the case, if 24fps telecined material has been mixed with 60fps
* interlaced effects, such as in Sol Bianca or Silent Mobius. It can also
* be used for true interlaced video, such as most camcorder recordings.
*
* The filter has several modes for handling 4:2:0 chroma for those output
* frames that fall across input frame temporal boundaries (i.e. fields come
* from different frames). Upconvert (to 4:2:2) provides the most accurate
* CRT simulation, but requires more CPU and memory bandwidth than the other
* modes. The other modes keep the chroma at 4:2:0.
*
* About these modes: telecined input (such as NTSC anime DVDs) works better
* with AltLine, while true interlaced input works better with Latest.
* Merge is a compromise, which may or may not look acceptable.
* The mode can be set in the VLC advanced configuration,
* All settings > Video > Filters > Deinterlace
*
* Technically speaking, this is an interlaced field renderer targeted for
* progressive displays. It works by framerate doubling, and simulating one
* step of light output decay of the "old" field during the "new" field,
* until the next new field comes in to replace the "old" one.
*
* While playback is running, the simulated light decay gives the picture an
* appearance of visible "scanlines", much like on a real TV. Only when the
* video is paused, it is clearly visible that one of the fields is actually
* brighter than the other.
*
* The main differences to the Bob algorithm are:
* - in addition to the current field, the previous one (fading out)
* is also rendered
* - some horizontal lines don't seem to flicker as much
* - scanline visual effect (adjustable; the dimmer strength can be set
* in the VLC advanced configuration)
* - the picture appears 25%, 38% or 44% darker on average (for dimmer
* strengths 1, 2 and 3)
* - if the input has 4:2:0 chroma, the colours may look messed up in some
* output frames. This is a limitation of the 4:2:0 chroma format, and due
* to the fact that both fields are present in each output picture. Usually
* this doesn't matter in practice, but see the 4:2:0 chroma mode setting
* in the configuration if needed (it may help a bit).
*
* In addition, when this filter is used on an LCD computer monitor,
* the main differences to a real CRT TV are:
* - Pixel shape and grid layout; CRT TVs were designed for interlaced
* field rendering, while LCD monitors weren't.
* - No scan flicker even though the display runs (usually) at 60Hz.
* (This at least is a good thing.)
*
* The output vertical resolution should be large enough for the scaling
* not to have a too adverse effect on the regular scanline pattern.
* In practice, NTSC video can be acceptably rendered already at 1024x600
* if fullscreen even on an LCD. PAL video requires more.
*
* Just like Bob, this filter works properly only if the input framerate
* is stable. Otherwise the scanline effect breaks down and the picture
* will flicker.
*/
#endif