mirror of https://code.videolan.org/videolan/vlc
217 lines
6.9 KiB
C
217 lines
6.9 KiB
C
/*****************************************************************************
|
|
* merge.h : Merge (line blending) routines for the VLC deinterlacer
|
|
*****************************************************************************
|
|
* Copyright (C) 2011 VLC authors and VideoLAN
|
|
*
|
|
* Author: Sam Hocevar <sam@zoy.org> (generic C routine)
|
|
* Sigmund Augdal Helberg <sigmunau@videolan.org> (MMXEXT, 3DNow, SSE2)
|
|
* Eric Petit <eric.petit@lapsus.org> (Altivec)
|
|
* Rémi Denis-Courmont (ARM NEON)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser 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_MERGE_H
|
|
#define VLC_DEINTERLACE_MERGE_H 1
|
|
|
|
/**
|
|
* \file
|
|
* Merge (line blending) routines for the VLC deinterlacer.
|
|
*/
|
|
|
|
/*****************************************************************************
|
|
* Macros
|
|
*****************************************************************************/
|
|
|
|
/* Convenient Merge() and EndMerge() macros to pick the most appropriate
|
|
merge implementation automatically.
|
|
|
|
Note that you'll need to include vlc_filter.h and deinterlace.h
|
|
to use these.
|
|
|
|
* Note that the Open() call of the deinterlace filter automatically selects
|
|
* the most appropriate merge routine based on the CPU capabilities.
|
|
* You can call the most appropriate version automatically, from a function
|
|
* in the deinterlace filter, by using the Merge() macro.
|
|
*
|
|
* Note that the filter instance (p_filter) must be available for the Merge()
|
|
* macro to work, because it needs the detection result from the filter's
|
|
* Open().
|
|
*
|
|
* Macro syntax:
|
|
* Merge( _p_dest, _p_s1, _p_s2, i_bytes );
|
|
*
|
|
* i_bytes > 0; no other restrictions. This holds for all versions of the
|
|
* merge routine.
|
|
*
|
|
*/
|
|
#define Merge p_sys->pf_merge
|
|
|
|
/*
|
|
* EndMerge() macro, which must be called after the merge is
|
|
* finished, if the Merge() macro was used to perform the merge.
|
|
*/
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
# define EndMerge() \
|
|
if(p_sys->pf_end_merge) (p_sys->pf_end_merge)()
|
|
#else
|
|
# define EndMerge() (void)0
|
|
#endif
|
|
|
|
/*****************************************************************************
|
|
* Merge routines
|
|
*****************************************************************************/
|
|
|
|
/**
|
|
* Generic routine to blend 8 bit pixels from two picture lines.
|
|
* No inline assembler acceleration.
|
|
*
|
|
* @param _p_dest Target line. Blend result = (A + B)/2.
|
|
* @param _p_s1 Source line A.
|
|
* @param _p_s2 Source line B.
|
|
* @param i_bytes Number of bytes to merge.
|
|
* @see Open()
|
|
*/
|
|
void Merge8BitGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2,
|
|
size_t i_bytes );
|
|
|
|
/**
|
|
* Generic routine to blend 16 bit pixels from two picture lines.
|
|
* No inline assembler acceleration.
|
|
*
|
|
* @param _p_dest Target line. Blend result = (A + B)/2.
|
|
* @param _p_s1 Source line A.
|
|
* @param _p_s2 Source line B.
|
|
* @param i_bytes Number of *bytes* to merge.
|
|
* @see Open()
|
|
*/
|
|
void Merge16BitGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2,
|
|
size_t i_bytes );
|
|
|
|
#if defined(CAN_COMPILE_C_ALTIVEC)
|
|
/**
|
|
* Altivec routine to blend pixels from two picture lines.
|
|
*
|
|
* @param _p_dest Target
|
|
* @param _p_s1 Source line A
|
|
* @param _p_s2 Source line B
|
|
* @param i_bytes Number of bytes to merge
|
|
*/
|
|
void MergeAltivec ( void *, const void *, const void *, size_t );
|
|
#endif
|
|
|
|
#if defined(CAN_COMPILE_MMXEXT)
|
|
/**
|
|
* MMXEXT routine to blend pixels from two picture lines.
|
|
*
|
|
* @param _p_dest Target
|
|
* @param _p_s1 Source line A
|
|
* @param _p_s2 Source line B
|
|
* @param i_bytes Number of bytes to merge
|
|
*/
|
|
void MergeMMXEXT ( void *, const void *, const void *, size_t );
|
|
#endif
|
|
|
|
#if defined(CAN_COMPILE_3DNOW)
|
|
/**
|
|
* 3DNow routine to blend pixels from two picture lines.
|
|
*
|
|
* @param _p_dest Target
|
|
* @param _p_s1 Source line A
|
|
* @param _p_s2 Source line B
|
|
* @param i_bytes Number of bytes to merge
|
|
*/
|
|
void Merge3DNow ( void *, const void *, const void *, size_t );
|
|
#endif
|
|
|
|
#if defined(CAN_COMPILE_SSE)
|
|
/**
|
|
* SSE2 routine to blend pixels from two picture lines.
|
|
*
|
|
* @param _p_dest Target
|
|
* @param _p_s1 Source line A
|
|
* @param _p_s2 Source line B
|
|
* @param i_bytes Number of bytes to merge
|
|
*/
|
|
void Merge8BitSSE2( void *, const void *, const void *, size_t );
|
|
/**
|
|
* SSE2 routine to blend pixels from two picture lines.
|
|
*
|
|
* @param _p_dest Target
|
|
* @param _p_s1 Source line A
|
|
* @param _p_s2 Source line B
|
|
* @param i_bytes Number of bytes to merge
|
|
*/
|
|
void Merge16BitSSE2( void *, const void *, const void *, size_t );
|
|
#endif
|
|
|
|
#if defined(CAN_COMPILE_ARM)
|
|
/**
|
|
* ARM NEON routine to blend pixels from two picture lines.
|
|
*/
|
|
void merge8_arm_neon (void *, const void *, const void *, size_t);
|
|
void merge16_arm_neon (void *, const void *, const void *, size_t);
|
|
|
|
/**
|
|
* ARMv6 SIMD routine to blend pixels from two picture lines.
|
|
*/
|
|
void merge8_armv6 (void *, const void *, const void *, size_t);
|
|
void merge16_armv6 (void *, const void *, const void *, size_t);
|
|
#endif
|
|
|
|
#if defined(CAN_COMPILE_ARM64)
|
|
/**
|
|
* ARM64 NEON routine to blend pixels from two picture lines.
|
|
*/
|
|
void merge8_arm64_neon (void *, const void *, const void *, size_t);
|
|
void merge16_arm64_neon (void *, const void *, const void *, size_t);
|
|
|
|
#endif
|
|
|
|
void merge8_arm_sve(void *, const void *, const void *, size_t);
|
|
void merge16_arm_sve(void *, const void *, const void *, size_t);
|
|
|
|
/*****************************************************************************
|
|
* EndMerge routines
|
|
*****************************************************************************/
|
|
|
|
#if defined(CAN_COMPILE_MMXEXT) || defined(CAN_COMPILE_SSE)
|
|
/**
|
|
* MMX merge finalization routine.
|
|
*
|
|
* Must be called after an MMX merge is finished.
|
|
* This exits MMX mode (by executing the "emms" instruction).
|
|
*
|
|
* The EndMerge() macro detects whether this is needed, and calls if it is,
|
|
* so just use that.
|
|
*/
|
|
void EndMMX ( void );
|
|
#endif
|
|
|
|
#if defined(CAN_COMPILE_3DNOW)
|
|
/**
|
|
* 3DNow merge finalization routine.
|
|
*
|
|
* Must be called after a 3DNow merge is finished.
|
|
* This exits 3DNow mode (by executing the "femms" instruction).
|
|
*
|
|
* The EndMerge() macro detects whether this is needed, and calls if it is,
|
|
* so just use that.
|
|
*/
|
|
void End3DNow ( void );
|
|
#endif
|
|
|
|
#endif
|