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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * i422_yuy2.c : YUV to YUV conversion module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2001 VideoLAN
  5.  * $Id: i422_yuy2.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 <string.h>                                            /* strerror() */
  27. #include <stdlib.h>                                      /* malloc(), free() */
  28. #include <vlc/vlc.h>
  29. #include <vlc/vout.h>
  30. #include "i422_yuy2.h"
  31. #define SRC_FOURCC  "I422"
  32. #if defined (MODULE_NAME_IS_i422_yuy2)
  33. #    define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv,Y211"
  34. #else
  35. #    define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv"
  36. #endif
  37. /*****************************************************************************
  38.  * Local and extern prototypes.
  39.  *****************************************************************************/
  40. static int  Activate ( vlc_object_t * );
  41. static void I422_YUY2           ( vout_thread_t *, picture_t *, picture_t * );
  42. static void I422_YVYU           ( vout_thread_t *, picture_t *, picture_t * );
  43. static void I422_UYVY           ( vout_thread_t *, picture_t *, picture_t * );
  44. static void I422_IUYV           ( vout_thread_t *, picture_t *, picture_t * );
  45. static void I422_cyuv           ( vout_thread_t *, picture_t *, picture_t * );
  46. #if defined (MODULE_NAME_IS_i422_yuy2)
  47. static void I422_Y211           ( vout_thread_t *, picture_t *, picture_t * );
  48. static void I422_Y211           ( vout_thread_t *, picture_t *, picture_t * );
  49. static void I422_YV12           ( vout_thread_t *, picture_t *, picture_t * );
  50. #endif
  51. /*****************************************************************************
  52.  * Module descriptor
  53.  *****************************************************************************/
  54. vlc_module_begin();
  55. #if defined (MODULE_NAME_IS_i422_yuy2)
  56.     set_description( _("Conversions from " SRC_FOURCC " to " DEST_FOURCC) );
  57.     set_capability( "chroma", 80 );
  58. #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
  59.     set_description( _("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) );
  60.     set_capability( "chroma", 100 );
  61.     add_requirement( MMX );
  62. #endif
  63.     set_callbacks( Activate, NULL );
  64. vlc_module_end();
  65. /*****************************************************************************
  66.  * Activate: allocate a chroma function
  67.  *****************************************************************************
  68.  * This function allocates and initializes a chroma function
  69.  *****************************************************************************/
  70. static int Activate( vlc_object_t *p_this )
  71. {
  72.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  73.     if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
  74.     {
  75.         return -1;
  76.     }
  77.     switch( p_vout->render.i_chroma )
  78.     {
  79.         case VLC_FOURCC('I','4','2','2'):
  80.             switch( p_vout->output.i_chroma )
  81.             {
  82.                 case VLC_FOURCC('Y','U','Y','2'):
  83.                 case VLC_FOURCC('Y','U','N','V'):
  84.                     p_vout->chroma.pf_convert = I422_YUY2;
  85.                     break;
  86.                 case VLC_FOURCC('Y','V','Y','U'):
  87.                     p_vout->chroma.pf_convert = I422_YVYU;
  88.                     break;
  89.                 case VLC_FOURCC('U','Y','V','Y'):
  90.                 case VLC_FOURCC('U','Y','N','V'):
  91.                 case VLC_FOURCC('Y','4','2','2'):
  92.                     p_vout->chroma.pf_convert = I422_UYVY;
  93.                     break;
  94.                 case VLC_FOURCC('I','U','Y','V'):
  95.                     p_vout->chroma.pf_convert = I422_IUYV;
  96.                     break;
  97.                 case VLC_FOURCC('c','y','u','v'):
  98.                     p_vout->chroma.pf_convert = I422_cyuv;
  99.                     break;
  100. #if defined (MODULE_NAME_IS_i422_yuy2)
  101.                 case VLC_FOURCC('Y','2','1','1'):
  102.                     p_vout->chroma.pf_convert = I422_Y211;
  103.                     break;
  104.                 case VLC_FOURCC('Y','V','1','2'):
  105.                     p_vout->chroma.pf_convert = I422_YV12;
  106.                     break;
  107. #endif
  108.                 default:
  109.                     return -1;
  110.             }
  111.             break;
  112.         default:
  113.             return -1;
  114.     }
  115.     
  116.     return 0; 
  117. }
  118. /* Following functions are local */
  119. /*****************************************************************************
  120.  * I422_YUY2: planar YUV 4:2:2 to packed YUY2 4:2:2
  121.  *****************************************************************************/
  122. static void I422_YUY2( vout_thread_t *p_vout, picture_t *p_source,
  123.                                               picture_t *p_dest )
  124. {
  125.     uint8_t *p_line = p_dest->p->p_pixels;
  126.     uint8_t *p_y = p_source->Y_PIXELS;
  127.     uint8_t *p_u = p_source->U_PIXELS;
  128.     uint8_t *p_v = p_source->V_PIXELS;
  129.     int i_x, i_y;
  130.     for( i_y = p_vout->render.i_height ; i_y-- ; )
  131.     {
  132.         for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
  133.         {
  134. #if defined (MODULE_NAME_IS_i422_yuy2)
  135.             C_YUV422_YUYV( p_line, p_y, p_u, p_v );
  136.             C_YUV422_YUYV( p_line, p_y, p_u, p_v );
  137.             C_YUV422_YUYV( p_line, p_y, p_u, p_v );
  138.             C_YUV422_YUYV( p_line, p_y, p_u, p_v );
  139. #else
  140.             __asm__( ".align 8" MMX_YUV422_YUYV
  141.                      : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) ); 
  142.             p_line += 16; p_y += 8; p_u += 4; p_v += 4;
  143. #endif
  144.         }
  145.     }
  146. }
  147. /*****************************************************************************
  148.  * I422_YVYU: planar YUV 4:2:2 to packed YVYU 4:2:2
  149.  *****************************************************************************/
  150. static void I422_YVYU( vout_thread_t *p_vout, picture_t *p_source,
  151.                                               picture_t *p_dest )
  152. {
  153.     uint8_t *p_line = p_dest->p->p_pixels;
  154.     uint8_t *p_y = p_source->Y_PIXELS;
  155.     uint8_t *p_u = p_source->U_PIXELS;
  156.     uint8_t *p_v = p_source->V_PIXELS;
  157.     int i_x, i_y;
  158.     for( i_y = p_vout->render.i_height ; i_y-- ; )
  159.     {
  160.         for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
  161.         {
  162. #if defined (MODULE_NAME_IS_i422_yuy2)
  163.             C_YUV422_YVYU( p_line, p_y, p_u, p_v );
  164.             C_YUV422_YVYU( p_line, p_y, p_u, p_v );
  165.             C_YUV422_YVYU( p_line, p_y, p_u, p_v );
  166.             C_YUV422_YVYU( p_line, p_y, p_u, p_v );
  167. #else
  168.             __asm__( ".align 8" MMX_YUV422_YVYU
  169.                      : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) ); 
  170.             p_line += 16; p_y += 8; p_u += 4; p_v += 4;
  171. #endif
  172.         }
  173.     }
  174. }
  175. /*****************************************************************************
  176.  * I422_UYVY: planar YUV 4:2:2 to packed UYVY 4:2:2
  177.  *****************************************************************************/
  178. static void I422_UYVY( vout_thread_t *p_vout, picture_t *p_source,
  179.                                               picture_t *p_dest )
  180. {
  181.     uint8_t *p_line = p_dest->p->p_pixels;
  182.     uint8_t *p_y = p_source->Y_PIXELS;
  183.     uint8_t *p_u = p_source->U_PIXELS;
  184.     uint8_t *p_v = p_source->V_PIXELS;
  185.     int i_x, i_y;
  186.     for( i_y = p_vout->render.i_height ; i_y-- ; )
  187.     {
  188.         for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
  189.         {
  190. #if defined (MODULE_NAME_IS_i422_yuy2)
  191.             C_YUV422_UYVY( p_line, p_y, p_u, p_v );
  192.             C_YUV422_UYVY( p_line, p_y, p_u, p_v );
  193.             C_YUV422_UYVY( p_line, p_y, p_u, p_v );
  194.             C_YUV422_UYVY( p_line, p_y, p_u, p_v );
  195. #else
  196.             __asm__( ".align 8" MMX_YUV422_UYVY
  197.                      : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) ); 
  198.             p_line += 16; p_y += 8; p_u += 4; p_v += 4;
  199. #endif
  200.         }
  201.     }
  202. }
  203. /*****************************************************************************
  204.  * I422_IUYV: planar YUV 4:2:2 to interleaved packed IUYV 4:2:2
  205.  *****************************************************************************/
  206. static void I422_IUYV( vout_thread_t *p_vout, picture_t *p_source,
  207.                                               picture_t *p_dest )
  208. {
  209.     /* FIXME: TODO ! */
  210.     msg_Err( p_vout, "I422_IUYV unimplemented, please harass <sam@zoy.org>" );
  211. }
  212. /*****************************************************************************
  213.  * I422_cyuv: planar YUV 4:2:2 to upside-down packed UYVY 4:2:2
  214.  *****************************************************************************/
  215. static void I422_cyuv( vout_thread_t *p_vout, picture_t *p_source,
  216.                                               picture_t *p_dest )
  217. {
  218.     uint8_t *p_line = p_dest->p->p_pixels + p_dest->p->i_visible_lines * p_dest->p->i_pitch;
  219.     uint8_t *p_y = p_source->Y_PIXELS;
  220.     uint8_t *p_u = p_source->U_PIXELS;
  221.     uint8_t *p_v = p_source->V_PIXELS;
  222.     int i_x, i_y;
  223.     for( i_y = p_vout->render.i_height ; i_y-- ; )
  224.     {
  225.         for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
  226.         {
  227.             p_line -= 2 * p_dest->p->i_pitch;
  228. #if defined (MODULE_NAME_IS_i422_yuy2)
  229.             C_YUV422_UYVY( p_line, p_y, p_u, p_v );
  230.             C_YUV422_UYVY( p_line, p_y, p_u, p_v );
  231.             C_YUV422_UYVY( p_line, p_y, p_u, p_v );
  232.             C_YUV422_UYVY( p_line, p_y, p_u, p_v );
  233. #else
  234.             __asm__( ".align 8" MMX_YUV422_UYVY
  235.                      : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) ); 
  236.             p_line += 16; p_y += 8; p_u += 4; p_v += 4;
  237. #endif
  238.         }
  239.     }
  240. }
  241. /*****************************************************************************
  242.  * I422_Y211: planar YUV 4:2:2 to packed YUYV 2:1:1
  243.  *****************************************************************************/
  244. #if defined (MODULE_NAME_IS_i422_yuy2)
  245. static void I422_Y211( vout_thread_t *p_vout, picture_t *p_source,
  246.                                               picture_t *p_dest )
  247. {
  248.     uint8_t *p_line = p_dest->p->p_pixels + p_dest->p->i_visible_lines * p_dest->p->i_pitch;
  249.     uint8_t *p_y = p_source->Y_PIXELS;
  250.     uint8_t *p_u = p_source->U_PIXELS;
  251.     uint8_t *p_v = p_source->V_PIXELS;
  252.     int i_x, i_y;
  253.     for( i_y = p_vout->render.i_height ; i_y-- ; )
  254.     {
  255.         for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
  256.         {
  257.             C_YUV422_Y211( p_line, p_y, p_u, p_v );
  258.             C_YUV422_Y211( p_line, p_y, p_u, p_v );
  259.         }
  260.     }
  261. }
  262. #endif
  263. /*****************************************************************************
  264.  * I422_YV12: planar YUV 4:2:2 to planar YV12
  265.  *****************************************************************************/
  266. #if defined (MODULE_NAME_IS_i422_yuy2)
  267. static void I422_YV12( vout_thread_t *p_vout, picture_t *p_source,
  268.                                               picture_t *p_dest )
  269. {
  270.     uint16_t i_dpy = p_dest->p[Y_PLANE].i_pitch;
  271.     uint16_t i_spy = p_source->p[Y_PLANE].i_pitch;
  272.     uint16_t i_dpuv = p_dest->p[U_PLANE].i_pitch;
  273.     uint16_t i_spuv = p_source->p[U_PLANE].i_pitch;
  274.     uint16_t i_width = p_vout->render.i_width;
  275.     uint16_t i_y = p_vout->render.i_height;
  276.     uint8_t *p_dy = p_dest->Y_PIXELS + (i_y-1)*i_dpy;
  277.     uint8_t *p_y = p_source->Y_PIXELS + (i_y-1)*i_spy;
  278.     uint8_t *p_du = p_dest->U_PIXELS + (i_y/2-1)*i_dpuv;
  279.     uint8_t *p_u = p_source->U_PIXELS + (i_y-1)*i_spuv;
  280.     uint8_t *p_dv = p_dest->V_PIXELS + (i_y/2-1)*i_dpuv;
  281.     uint8_t *p_v = p_source->V_PIXELS + (i_y-1)*i_spuv;
  282.     i_y /= 2;
  283.     for ( ; i_y--; )
  284.     {
  285.         memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy;
  286.         memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy;
  287.         memcpy(p_du, p_u, i_width/2); p_du -= i_dpuv; p_u -= 2*i_spuv;
  288.         memcpy(p_dv, p_v, i_width/2); p_dv -= i_dpuv; p_v -= 2*i_spuv;
  289.     }
  290. }
  291. #endif