render.c

来自「VLC媒体播放程序」· C语言 代码 · 共 1,920 行 · 第 1/5 页

C
1,920
字号
    i_x_end   = p_sys->i_x_end;    i_y_end   = i_yscale * p_sys->i_y_end;    p_source = (ogt_yuvt_t *)p_sys->p_data;      /* Draw until we reach the bottom of the subtitle */    i_y = 0;    for( i_y_src = 0 ; i_y_src < p_spu->i_height * p_spu->i_width;          i_y_src += p_spu->i_width )    {	uint8_t *p_pixel_base_y;        i_ytmp = i_y >> ASCALE;        i_y += i_yscale;	p_pixel_base_y = p_pixel_base + (i_ytmp * p_pic->p->i_pitch);	i_x = 0;        if ( b_crop ) {          if ( i_y > i_y_end ) break;          if (i_x_start) {            i_x = i_x_start;            p_source += i_x_start;          }        }        /* Check whether we need to draw one line or more than one */        if( i_ytmp + 1 >= ( i_y >> ASCALE ) )        {          /* Draw until we reach the end of the line */          for( ; i_x < p_spu->i_width;  i_x++, p_source++ )            {#if 0                            uint8_t *p=(uint8_t *) p_source;              printf("+++ %02x %02x %02x %02x\n",                      p[0], p[1], p[2], p[3]);#endif                  if( b_crop ) {                                /* FIXME: y cropping should be dealt with outside of this                    loop.*/                if ( i_y < i_y_start) continue;                                if ( i_x > i_x_end )                  {                    p_source += p_spu->i_width - i_x;                    break;                  }              }	      if (p_source >= p_src_end) {		msg_Err( p_vout, "Trying to access beyond subtitle %dx%d %d",			 i_x, i_y / i_yscale, i_height);		return;	      }	      #ifdef TESTING_TRANSPARENCY              if (p_source->s.t == MAX_TRANS) p_source->s.t >>= 1;#endif	      switch( p_source->s.t )                {                case 0:		  /* Completely transparent. Don't change pixel. */		  break;		                  case MAX_TRANS:		  {		    /* Completely opaque. Completely overwrite underlying		       pixel with subtitle pixel. */		                    uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)                                          * BYTES_PER_PIXEL );                    uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)                                         * BYTES_PER_PIXEL );                    uint32_t len     = i_xlast - i_xdest;                    uint8_t i_rgb1;                    uint8_t i_rgb2;		    /* This is the location that's going to get changed. */		    uint8_t *p_dest = p_pixel_base_y + i_x * BYTES_PER_PIXEL;                    if (b_15bpp)                       yuv2rgb555(p_source, &i_rgb1, &i_rgb2);                    else                       yuv2rgb565(p_source, &i_rgb1, &i_rgb2);                    for ( len = i_xlast - i_xdest; len ; len--) {                      *p_dest++ = i_rgb1;                      *p_dest++ = i_rgb2;                    }		    break;		  }                default:		  {		    /* Blend in underlying pixel subtitle pixel. */		                        uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)                                          * BYTES_PER_PIXEL );                    uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)                                         * BYTES_PER_PIXEL );                    uint8_t i_rgb1;                    uint8_t i_rgb2;                    uint32_t len     = i_xlast - i_xdest;		    /* This is the location that's going to get changed. */		    uint8_t *p_dest = p_pixel_base_y + i_x * BYTES_PER_PIXEL;                    for ( len = i_xlast - i_xdest; len ; len--) {                      rv16_pack_blend(p_dest, p_source, &i_rgb1, &i_rgb2,                                       b_15bpp, p_source->s.t, TRANS_SCALEDOWN);                      *p_dest++ = i_rgb1;                      *p_dest++ = i_rgb2;                    }		    break;		  }                }            }        }        else        {            i_ynext = p_pic->p->i_pitch * i_y >> ASCALE;            /* Draw until we reach the end of the line */            for( ; i_x < p_spu->i_width; i_x++, p_source++ )            {              if( b_crop ) {                                /* FIXME: y cropping should be dealt with outside of this                    loop.*/                if ( i_y < i_y_start) continue;                                if ( i_x > i_x_end )                  {                    p_source += p_spu->i_width - i_x;                    break;                  }              }	      	      if (p_source >= p_src_end) {		msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",			 i_x, i_y / i_yscale, i_height);		return;	      }	      	      switch( p_source->s.t )                {                case 0:		    /* Completely transparent. Don't change pixel. */                    break;                case MAX_TRANS: 		  {		    /* Completely opaque. Completely overwrite underlying		       pixel with subtitle pixel. */                    uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)                                          * BYTES_PER_PIXEL );                    uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)                                         * BYTES_PER_PIXEL );                    uint32_t len     = i_xlast - i_xdest;		    uint8_t *p_pixel_base_x = p_pixel_base + i_xdest;                    for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )                    {		      /* This is the location that's going to get changed. */		      uint8_t *p_dest = p_pixel_base_x + i_ytmp;                      uint8_t i_rgb1, i_rgb2;                      if (b_15bpp)                         yuv2rgb555(p_source, &i_rgb1, &i_rgb2);                      else                         yuv2rgb565(p_source, &i_rgb1, &i_rgb2);                      for ( len = i_xlast - i_xdest; len ; len--) {                        *p_dest++ = i_rgb1;                        *p_dest++ = i_rgb2;                      }                    }                    break;		  }                default:                   {                    uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)                                          * BYTES_PER_PIXEL );                    uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)                                         * BYTES_PER_PIXEL );                    uint32_t len     = i_xlast - i_xdest;                    uint8_t i_rgb1, i_rgb2;                    for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )                    {		      /* Blend in underlying pixel subtitle pixel. */		      uint8_t *p_dest = p_pixel_base + i_ytmp;                      for ( len = i_xlast - i_xdest; len ; len--) {                        rv16_pack_blend(p_dest, p_source, &i_rgb1, &i_rgb2,                                      b_15bpp, p_source->s.t, TRANS_SCALEDOWN);                        *p_dest++ = i_rgb1;                        *p_dest++ = i_rgb2;                      }                    }                    break;                  }		}	    }	}    }}#undef  BYTES_PER_PIXEL#define BYTES_PER_PIXEL 4static inline voidrv24_pack_blend(uint8_t *rgb_vout, const uint8_t *rgb_sub,  uint8_t i_trans,                  int a_scale_down ){#if 0  printf("r,g,b=(%d,%d,%d), source r,g,b=(%d,%d,%d), trans %d\n",         rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL],         rgb_sub[RED_PIXEL], rgb_sub[GREEN_PIXEL],          rgb_sub[BLUE_PIXEL], i_trans);#endif#ifdef WORDS_BIGENDIAN  *rgb_vout++;#endif  avg_8bit_rgb(rgb_vout, rgb_sub, i_trans);  #if 0  printf("avg r,g,b=(%d,%d,%d)\n",         rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL] );#endif}/*   RV24 format??? Is this just for X11? Or just not for Win32? Is this  the same as RV32?  a pixel is represented by 3 bytes containing a red,  blue and green sample with blue stored at the lowest address, green  next then red. One padding byte is added between pixels. Although  this may not be part of a spec, images should be stored with each  line padded to a u_int32 boundary. */static void BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,            const subpicture_t *p_spu, vlc_bool_t b_crop ){  /* Common variables */  uint8_t *p_pixel_base;  ogt_yuvt_t *p_src_start = (ogt_yuvt_t *)p_spu->p_sys->p_data;  ogt_yuvt_t *p_src_end   = &p_src_start[p_spu->i_height * p_spu->i_width];  ogt_yuvt_t *p_source; /* This is the where the subtitle pixels come from */    int i_x, i_y;  int i_y_src;    /* Make sure we start on a word (4-byte) boundary. */  uint32_t i_spu_x;    /* Chroma specific */  uint32_t i_xscale;   /* Amount we scale subtitle in the x direction,                          multiplied by 2**ASCALE. */  uint32_t i_yscale;   /* Amount we scale subtitle in the y direction.                          multiplied by 2**ASCALE. */    int i_width, i_height, i_ytmp, i_ynext;    /* Crop-specific */  int32_t i_x_start, i_y_start, i_x_end, i_y_end;    struct subpicture_sys_t *p_sys = p_spu->p_sys;  unsigned int i_aspect_x, i_aspect_y;    vout_AspectRatio( p_vout->render.i_aspect, &i_aspect_y,                     &i_aspect_x );    i_xscale = (( p_vout->output.i_width << ASCALE ) * i_aspect_x)    / (i_aspect_y * p_vout->render.i_width);  i_yscale = ( p_vout->output.i_height << ASCALE ) / p_vout->render.i_height;    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER),              "spu: %dx%d, scaled: %dx%d, vout render: %dx%d, scale %dx%d",              p_spu->i_width,  p_spu->i_height,              p_vout->output.i_width, p_vout->output.i_height,             p_vout->render.i_width, p_vout->render.i_height,             i_xscale, i_yscale             );    i_width  = p_spu->i_width  * i_xscale;  i_height = p_spu->i_height * i_yscale;    /* Set where we will start blending subtitle from using     the picture coordinates subtitle offsets.  */  i_spu_x = ((p_spu->i_x * i_xscale) >> ASCALE) * BYTES_PER_PIXEL;    p_pixel_base = p_pic->p->p_pixels + i_spu_x    + ( (p_spu->i_y * i_yscale) >> ASCALE ) * p_pic->p->i_pitch;    i_x_start = p_sys->i_x_start;  i_y_start = i_yscale * p_sys->i_y_start;  i_x_end   = p_sys->i_x_end;  i_y_end   = i_yscale * p_sys->i_y_end;    p_source = (ogt_yuvt_t *)p_sys->p_data;    /* Draw until we reach the bottom of the subtitle */  i_y = 0;  for( i_y_src = 0 ; i_y_src < p_spu->i_height * p_spu->i_width;        i_y_src += p_spu->i_width )    {      uint8_t *p_pixel_base_y;      i_ytmp = i_y >> ASCALE;      i_y += i_yscale;      p_pixel_base_y = p_pixel_base + (i_ytmp * p_pic->p->i_pitch);      i_x = 0;            if ( b_crop ) {        if ( i_y > i_y_end ) break;        if (i_x_start) {          i_x = i_x_start;          p_source += i_x_start;        }      }            /* Check whether we need to draw one line or more than one */      if( i_ytmp + 1 >= ( i_y >> ASCALE ) )        {          /* Draw until we reach the end of the line */          for( ; i_x < p_spu->i_width;  i_x++, p_source++ )            {                            if( b_crop ) {                                /* FIXME: y cropping should be dealt with outside of this                    loop.*/                if ( i_y < i_y_start) continue;                                if ( i_x > i_x_end )                  {                    p_source += p_spu->i_width - i_x;                    break;                  }              }              	      if (p_source >= p_src_end) {		msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",			 i_x, i_y / i_yscale, i_height);		return;	      }	      #ifdef TESTING_TRANSPARENCY              if (p_source->s.t == MAX_TRANS) p_source->s.t >>= 2;#endif	      switch( p_source->s.t )                {                case 0:		  /* Completely transparent. Don't change pixel. */		  break;		                  case MAX_TRANS:		  {		    /* Completely opaque. Completely overwrite underlying		       pixel with subtitle pixel. */                                        uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)                                          * BYTES_PER_PIXEL );                    uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)                                         * BYTES_PER_PIXEL );                    uint32_t len     = i_xlast - i_xdest;                                        uint8_t rgb[RGB_SIZE];                    		    /* This is the location that's going to get changed. */		    uint8_t *p_dest = p_pixel_base_y + i_xdest;                    

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?