i420_ymga.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:6k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * i420_ymga.c : YUV to YUV conversion module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2001 VideoLAN
  5.  * $Id: i420_ymga.c 8551 2004-08-28 17:36:02Z gbazin $
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <errno.h>                                                 /* ENOMEM */
  27. #include <string.h>                                            /* strerror() */
  28. #include <stdlib.h>                                      /* malloc(), free() */
  29. #include <vlc/vlc.h>
  30. #include <vlc/vout.h>
  31. #define SRC_FOURCC  "I420,IYUV,YV12"
  32. #define DEST_FOURCC "YMGA"
  33. /*****************************************************************************
  34.  * Local and extern prototypes.
  35.  *****************************************************************************/
  36. static int  Activate   ( vlc_object_t * );
  37. static void I420_YMGA  ( vout_thread_t *, picture_t *, picture_t * );
  38. /*****************************************************************************
  39.  * Module descriptor
  40.  *****************************************************************************/
  41. vlc_module_begin();
  42. #if defined (MODULE_NAME_IS_i420_ymga)
  43.     set_description( _("Conversions from " SRC_FOURCC " to " DEST_FOURCC) );
  44.     set_capability( "chroma", 80 );
  45. #elif defined (MODULE_NAME_IS_i420_ymga_mmx)
  46.     set_description( _("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) );
  47.     set_capability( "chroma", 100 );
  48.     add_requirement( MMX );
  49. #endif
  50.     set_callbacks( Activate, NULL );
  51. vlc_module_end();
  52. /*****************************************************************************
  53.  * Activate: allocate a chroma function
  54.  *****************************************************************************
  55.  * This function allocates and initializes a chroma function
  56.  *****************************************************************************/
  57. static int Activate( vlc_object_t *p_this )
  58. {
  59.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  60.     if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
  61.     {
  62.         return -1;
  63.     }
  64.     switch( p_vout->render.i_chroma )
  65.     {
  66.         case VLC_FOURCC('Y','V','1','2'):
  67.         case VLC_FOURCC('I','4','2','0'):
  68.         case VLC_FOURCC('I','Y','U','V'):
  69.             switch( p_vout->output.i_chroma )
  70.             {
  71.                 case VLC_FOURCC('Y','M','G','A'):
  72.                     p_vout->chroma.pf_convert = I420_YMGA;
  73.                     break;
  74.                 default:
  75.                     return -1;
  76.             }
  77.             break;
  78.         default:
  79.             return -1;
  80.     }
  81.     return 0;
  82. }
  83. /* Following functions are local */
  84. /*****************************************************************************
  85.  * I420_YMGA: planar YUV 4:2:0 to Matrox's planar/packed YUV 4:2:0
  86.  *****************************************************************************/
  87. static void I420_YMGA( vout_thread_t *p_vout, picture_t *p_source,
  88.                                               picture_t *p_dest )
  89. {
  90.     uint8_t *p_uv = p_dest->U_PIXELS;
  91.     uint8_t *p_u = p_source->U_PIXELS;
  92.     uint8_t *p_v = p_source->V_PIXELS;
  93.     int i_x;
  94.     /* Copy the Y part */
  95.     p_vout->p_vlc->pf_memcpy( p_dest->Y_PIXELS, p_source->Y_PIXELS,
  96.                  p_dest->p[Y_PLANE].i_pitch * p_dest->p[Y_PLANE].i_visible_lines );
  97.     /* Copy the U:V part */
  98.     for( i_x = p_dest->p[U_PLANE].i_pitch * p_dest->p[U_PLANE].i_visible_lines / 64;
  99.          i_x--; )
  100.     {
  101. #if defined (MODULE_NAME_IS_i420_ymga)
  102.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  103.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  104.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  105.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  106.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  107.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  108.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  109.         *p_uv++ = *p_u++; *p_uv++ = *p_v++; *p_uv++ = *p_u++; *p_uv++ = *p_v++;
  110. #else
  111.         __asm__( ".align 32 n
  112.         movd       (%0), %%mm0  # Load 4 Cr   00 00 00 00 v3 v2 v1 v0     n
  113.         movd      4(%0), %%mm2  # Load 4 Cr   00 00 00 00 v3 v2 v1 v0     n
  114.         movd      8(%0), %%mm4  # Load 4 Cr   00 00 00 00 v3 v2 v1 v0     n
  115.         movd     12(%0), %%mm6  # Load 4 Cr   00 00 00 00 v3 v2 v1 v0     n
  116.         movd       (%1), %%mm1  # Load 4 Cb   00 00 00 00 u3 u2 u1 u0     n
  117.         movd      4(%1), %%mm3  # Load 4 Cb   00 00 00 00 u3 u2 u1 u0     n
  118.         movd      8(%1), %%mm5  # Load 4 Cb   00 00 00 00 u3 u2 u1 u0     n
  119.         movd     12(%1), %%mm7  # Load 4 Cb   00 00 00 00 u3 u2 u1 u0     n
  120.         punpcklbw %%mm1, %%mm0  #             u3 v3 u2 v2 u1 v1 u0 v0     n
  121.         punpcklbw %%mm3, %%mm2  #             u3 v3 u2 v2 u1 v1 u0 v0     n
  122.         punpcklbw %%mm5, %%mm4  #             u3 v3 u2 v2 u1 v1 u0 v0     n
  123.         punpcklbw %%mm7, %%mm6  #             u3 v3 u2 v2 u1 v1 u0 v0     n
  124.         movq      %%mm0, (%2)   # Store CrCb                              n
  125.         movq      %%mm2, 8(%2)  # Store CrCb                              n
  126.         movq      %%mm4, 16(%2) # Store CrCb                              n
  127.         movq      %%mm6, 24(%2) # Store CrCb"
  128.         : : "r" (p_v), "r" (p_u), "r" (p_uv) );
  129.         p_v += 16; p_u += 16; p_uv += 32;
  130. #endif
  131.     }
  132. }