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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * i422_i420.c : Planar YUV 4:2:2 to Planar YUV 4:2:0 conversion module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2001 - 2007 the VideoLAN team
  5.  * $Id: 7cb40e3b90ade7db445468696c89cc151869a197 $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *          Damien Fouilleul <damienf@videolan.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include <vlc_filter.h>
  33. #include <vlc_vout.h>
  34. #define SRC_FOURCC  "I422,J422"
  35. #define DEST_FOURCC "I420,IYUV,J420,YV12,YUVA"
  36. /*****************************************************************************
  37.  * Local and extern prototypes.
  38.  *****************************************************************************/
  39. static int  Activate ( vlc_object_t * );
  40. static void I422_I420( filter_t *, picture_t *, picture_t * );
  41. static void I422_YV12( filter_t *, picture_t *, picture_t * );
  42. static void I422_YUVA( filter_t *, picture_t *, picture_t * );
  43. static picture_t *I422_I420_Filter( filter_t *, picture_t * );
  44. static picture_t *I422_YV12_Filter( filter_t *, picture_t * );
  45. static picture_t *I422_YUVA_Filter( filter_t *, picture_t * );
  46. /*****************************************************************************
  47.  * Module descriptor
  48.  *****************************************************************************/
  49. vlc_module_begin ()
  50.     set_description( N_("Conversions from " SRC_FOURCC " to " DEST_FOURCC) )
  51.     set_capability( "video filter2", 60 )
  52.     set_callbacks( Activate, NULL )
  53. vlc_module_end ()
  54. /*****************************************************************************
  55.  * Activate: allocate a chroma function
  56.  *****************************************************************************
  57.  * This function allocates and initializes a chroma function
  58.  *****************************************************************************/
  59. static int Activate( vlc_object_t *p_this )
  60. {
  61.     filter_t *p_filter = (filter_t *)p_this;
  62.     if( p_filter->fmt_in.video.i_width & 1
  63.      || p_filter->fmt_in.video.i_height & 1 )
  64.     {
  65.         return -1;
  66.     }
  67.     if( p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width
  68.      || p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height )
  69.         return -1;
  70.     switch( p_filter->fmt_in.video.i_chroma )
  71.     {
  72.         case VLC_FOURCC('I','4','2','2'):
  73.         case VLC_FOURCC('J','4','2','2'):
  74.             switch( p_filter->fmt_out.video.i_chroma )
  75.             {
  76.                 case VLC_FOURCC('I','4','2','0'):
  77.                 case VLC_FOURCC('I','Y','U','V'):
  78.                 case VLC_FOURCC('J','4','2','0'):
  79.                     p_filter->pf_video_filter = I422_I420_Filter;
  80.                     break;
  81.                 case VLC_FOURCC('Y','V','1','2'):
  82.                     p_filter->pf_video_filter = I422_YV12_Filter;
  83.                     break;
  84.                 case VLC_FOURCC('Y','U','V','A'):
  85.                     p_filter->pf_video_filter = I422_YUVA_Filter;
  86.                     break;
  87.                 default:
  88.                     return -1;
  89.             }
  90.             break;
  91.         default:
  92.             return -1;
  93.     }
  94.     return 0;
  95. }
  96. /* Following functions are local */
  97. VIDEO_FILTER_WRAPPER( I422_I420 )
  98. VIDEO_FILTER_WRAPPER( I422_YV12 )
  99. VIDEO_FILTER_WRAPPER( I422_YUVA )
  100. /*****************************************************************************
  101.  * I422_I420: planar YUV 4:2:2 to planar I420 4:2:0 Y:U:V
  102.  *****************************************************************************/
  103. static void I422_I420( filter_t *p_filter, picture_t *p_source,
  104.                                            picture_t *p_dest )
  105. {
  106.     uint16_t i_dpy = p_dest->p[Y_PLANE].i_pitch;
  107.     uint16_t i_spy = p_source->p[Y_PLANE].i_pitch;
  108.     uint16_t i_dpuv = p_dest->p[U_PLANE].i_pitch;
  109.     uint16_t i_spuv = p_source->p[U_PLANE].i_pitch;
  110.     uint16_t i_width = p_filter->fmt_in.video.i_width;
  111.     uint16_t i_y = p_filter->fmt_in.video.i_height;
  112.     uint8_t *p_dy = p_dest->Y_PIXELS + (i_y-1)*i_dpy;
  113.     uint8_t *p_y = p_source->Y_PIXELS + (i_y-1)*i_spy;
  114.     uint8_t *p_du = p_dest->U_PIXELS + (i_y/2-1)*i_dpuv;
  115.     uint8_t *p_u = p_source->U_PIXELS + (i_y-1)*i_spuv;
  116.     uint8_t *p_dv = p_dest->V_PIXELS + (i_y/2-1)*i_dpuv;
  117.     uint8_t *p_v = p_source->V_PIXELS + (i_y-1)*i_spuv;
  118.     i_y /= 2;
  119.     for ( ; i_y--; )
  120.     {
  121.         vlc_memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy;
  122.         vlc_memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy;
  123.         vlc_memcpy(p_du, p_u, i_width/2); p_du -= i_dpuv; p_u -= 2*i_spuv;
  124.         vlc_memcpy(p_dv, p_v, i_width/2); p_dv -= i_dpuv; p_v -= 2*i_spuv;
  125.     }
  126. }
  127. /*****************************************************************************
  128.  * I422_YV12: planar YUV 4:2:2 to planar YV12 4:2:0 Y:V:U
  129.  *****************************************************************************/
  130. static void I422_YV12( filter_t *p_filter, picture_t *p_source,
  131.                                            picture_t *p_dest )
  132. {
  133.     uint16_t i_dpy = p_dest->p[Y_PLANE].i_pitch;
  134.     uint16_t i_spy = p_source->p[Y_PLANE].i_pitch;
  135.     uint16_t i_dpuv = p_dest->p[U_PLANE].i_pitch;
  136.     uint16_t i_spuv = p_source->p[U_PLANE].i_pitch;
  137.     uint16_t i_width = p_filter->fmt_in.video.i_width;
  138.     uint16_t i_y = p_filter->fmt_in.video.i_height;
  139.     uint8_t *p_dy = p_dest->Y_PIXELS + (i_y-1)*i_dpy;
  140.     uint8_t *p_y = p_source->Y_PIXELS + (i_y-1)*i_spy;
  141.     uint8_t *p_du = p_dest->V_PIXELS + (i_y/2-1)*i_dpuv; /* U and V are swapped */
  142.     uint8_t *p_u = p_source->U_PIXELS + (i_y-1)*i_spuv;
  143.     uint8_t *p_dv = p_dest->U_PIXELS + (i_y/2-1)*i_dpuv; /* U and V are swapped */
  144.     uint8_t *p_v = p_source->V_PIXELS + (i_y-1)*i_spuv;
  145.     i_y /= 2;
  146.     for ( ; i_y--; )
  147.     {
  148.         vlc_memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy;
  149.         vlc_memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy;
  150.         vlc_memcpy(p_du, p_u, i_width/2); p_du -= i_dpuv; p_u -= 2*i_spuv;
  151.         vlc_memcpy(p_dv, p_v, i_width/2); p_dv -= i_dpuv; p_v -= 2*i_spuv;
  152.     }
  153. }
  154. /*****************************************************************************
  155.  * I422_YUVA: planar YUV 4:2:2 to planar YUVA 4:2:0:4 Y:U:V:A
  156.  *****************************************************************************/
  157. static void I422_YUVA( filter_t *p_filter, picture_t *p_source,
  158.                                            picture_t *p_dest )
  159. {
  160.     I422_I420( p_filter, p_source, p_dest );
  161.     vlc_memset( p_dest->p[A_PLANE].p_pixels, 0xff,
  162.                 p_dest->p[A_PLANE].i_lines * p_dest->p[A_PLANE].i_pitch );
  163. }