i420_ymga.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:7k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * i420_ymga.c : YUV to YUV conversion module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2001 the VideoLAN team
  5.  * $Id: 6e0f77c8a102be984216bd5ce28b9884b66f10f5 $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  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.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <errno.h>                                                 /* ENOMEM */
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include <vlc_filter.h>
  33. #include <vlc_vout.h>
  34. #define SRC_FOURCC  "I420,IYUV,YV12"
  35. #define DEST_FOURCC "YMGA"
  36. /*****************************************************************************
  37.  * Local and extern prototypes.
  38.  *****************************************************************************/
  39. static int  Activate   ( vlc_object_t * );
  40. static void I420_YMGA  ( filter_t *, picture_t *, picture_t * );
  41. static picture_t *I420_YMGA_Filter( filter_t *, picture_t * );
  42. /*****************************************************************************
  43.  * Module descriptor
  44.  *****************************************************************************/
  45. vlc_module_begin ()
  46. #if defined (MODULE_NAME_IS_i420_ymga)
  47.     set_description( N_("Conversions from " SRC_FOURCC " to " DEST_FOURCC) )
  48.     set_capability( "video filter2", 80 )
  49. #elif defined (MODULE_NAME_IS_i420_ymga_mmx)
  50.     set_description( N_("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) )
  51.     set_capability( "video filter2", 100 )
  52.     add_requirement( MMX )
  53. #endif
  54.     set_callbacks( Activate, NULL )
  55. vlc_module_end ()
  56. /*****************************************************************************
  57.  * Activate: allocate a chroma function
  58.  *****************************************************************************
  59.  * This function allocates and initializes a chroma function
  60.  *****************************************************************************/
  61. static int Activate( vlc_object_t *p_this )
  62. {
  63.     filter_t *p_filter = (filter_t *)p_this;
  64.     if( p_filter->fmt_in.video.i_width & 1
  65.      || p_filter->fmt_in.video.i_height & 1 )
  66.     {
  67.         return -1;
  68.     }
  69.     if( p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width
  70.      || p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height )
  71.         return -1;
  72.     switch( p_filter->fmt_in.video.i_chroma )
  73.     {
  74.         case VLC_FOURCC('Y','V','1','2'):
  75.         case VLC_FOURCC('I','4','2','0'):
  76.         case VLC_FOURCC('I','Y','U','V'):
  77.             switch( p_filter->fmt_out.video.i_chroma )
  78.             {
  79.                 case VLC_FOURCC('Y','M','G','A'):
  80.                     p_filter->pf_video_filter = I420_YMGA_Filter;
  81.                     break;
  82.                 default:
  83.                     return -1;
  84.             }
  85.             break;
  86.         default:
  87.             return -1;
  88.     }
  89.     return 0;
  90. }
  91. /* Following functions are local */
  92. VIDEO_FILTER_WRAPPER( I420_YMGA )
  93. /*****************************************************************************
  94.  * I420_YMGA: planar YUV 4:2:0 to Matrox's planar/packed YUV 4:2:0
  95.  *****************************************************************************/
  96. static void I420_YMGA( filter_t *p_filter, picture_t *p_source,
  97.                                            picture_t *p_dest )
  98. {
  99.     uint8_t *p_uv = p_dest->U_PIXELS;
  100.     uint8_t *p_u = p_source->U_PIXELS;
  101.     uint8_t *p_v = p_source->V_PIXELS;
  102.     int i_x;
  103.     /* Copy the Y part */
  104.     vlc_memcpy( p_dest->Y_PIXELS, p_source->Y_PIXELS,
  105.                 p_dest->p[Y_PLANE].i_pitch * p_dest->p[Y_PLANE].i_visible_lines );
  106.     /* Copy the U:V part */
  107.     for( i_x = p_dest->p[U_PLANE].i_pitch * p_dest->p[U_PLANE].i_visible_lines / 64;
  108.          i_x--; )
  109.     {
  110. #if defined (MODULE_NAME_IS_i420_ymga)
  111.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  112.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  113.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  114.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  115.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  116.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  117.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  118.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  119. #else
  120.         __asm__( ".p2align 5 n
  121.         movd       (%0), %%mm0  # Load 4 Cr   00 00 00 00 v3 v2 v1 v0     n
  122.         movd      4(%0), %%mm2  # Load 4 Cr   00 00 00 00 v3 v2 v1 v0     n
  123.         movd      8(%0), %%mm4  # Load 4 Cr   00 00 00 00 v3 v2 v1 v0     n
  124.         movd     12(%0), %%mm6  # Load 4 Cr   00 00 00 00 v3 v2 v1 v0     n
  125.         movd       (%1), %%mm1  # Load 4 Cb   00 00 00 00 u3 u2 u1 u0     n
  126.         movd      4(%1), %%mm3  # Load 4 Cb   00 00 00 00 u3 u2 u1 u0     n
  127.         movd      8(%1), %%mm5  # Load 4 Cb   00 00 00 00 u3 u2 u1 u0     n
  128.         movd     12(%1), %%mm7  # Load 4 Cb   00 00 00 00 u3 u2 u1 u0     n
  129.         punpcklbw %%mm1, %%mm0  #             u3 v3 u2 v2 u1 v1 u0 v0     n
  130.         punpcklbw %%mm3, %%mm2  #             u3 v3 u2 v2 u1 v1 u0 v0     n
  131.         punpcklbw %%mm5, %%mm4  #             u3 v3 u2 v2 u1 v1 u0 v0     n
  132.         punpcklbw %%mm7, %%mm6  #             u3 v3 u2 v2 u1 v1 u0 v0     n
  133.         movq      %%mm0, (%2)   # Store CrCb                              n
  134.         movq      %%mm2, 8(%2)  # Store CrCb                              n
  135.         movq      %%mm4, 16(%2) # Store CrCb                              n
  136.         movq      %%mm6, 24(%2) # Store CrCb"
  137.         : : "r" (p_v), "r" (p_u), "r" (p_uv) );
  138.         p_v += 16; p_u += 16; p_uv += 32;
  139. #endif
  140.     }
  141. }