render.c

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

C
1,920
字号
                    yuv2rgb(p_source, rgb);                                        for ( len = i_xlast - i_xdest; len ; len--) {                      put_rgb24_pixel(rgb, p_dest);                      p_dest += BYTES_PER_PIXEL;                    }                                      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 );                      uint32_t len     = i_xlast - i_xdest * BYTES_PER_PIXEL;                                            /* To be able to scale correctly for full                         opaqueness, we add 1 to the transparency.                         This means transparency value 0 won't be                         completely transparent which is not correct.                         But that's handled in a special case above                         anyway. */                                            /* This is the location that's going to get changed. */                      uint8_t *p_dest = p_pixel_base_y + i_xdest;                      uint8_t rgb[RGB_SIZE];                                            yuv2rgb(p_source, rgb);                      for ( len = i_xlast - i_xdest; len ; len--) {                        rv24_pack_blend(p_dest, rgb, p_source->s.t,                                        TRANS_SCALEDOWN);                        p_dest += BYTES_PER_PIXEL;                      }                      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. */		    /* This is the location that's going to get changed. */                    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];                    yuv2rgb(p_source, rgb);                     for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )                    {                      /* Completely opaque. Completely overwrite underlying                         pixel with subtitle pixel. */                                            /* This is the location that's going to get changed. */                      uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;                                            for ( len = i_xlast - i_xdest; len ; len--) {                        put_rgb24_pixel(rgb, p_dest);                        p_dest += BYTES_PER_PIXEL;                      }                    }                    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  rgb[RGB_SIZE];                    yuv2rgb(p_source, rgb);                    for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )                    {		      /* Blend in underlying pixel subtitle pixel. */		                            /* This is the location that's going to get changed. */                      uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;		      /* To be able to scale correctly for full opaqueness, we			 add 1 to the alpha.  This means alpha value 0 won't			 be completely transparent and is not correct, but			 that's handled in a special case above anyway. */                      for ( len = i_xlast - i_xdest; len ; len--) {                        rv24_pack_blend(p_dest, rgb, p_source->s.t,                                        TRANS_SCALEDOWN);                        p_dest += BYTES_PER_PIXEL;                      }                    }                    break;                  }                }            }	}    }}#undef  BYTES_PER_PIXEL#define BYTES_PER_PIXEL 4/*   RV32 format??? Is this just for X11? Or just not for Win32? Is this  the same as RV24?  RV32 format: a pixel is represented by 4 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 BlendRV32( 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;	      }	      	      switch( p_source->s.t )                {                case 0:		  /* Completely transparent. Don't change pixel. */		  break;		                  default:                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;                    yuv2rgb(p_source, rgb);                    for ( len = i_xlast - i_xdest; len ; len--) {                      *p_dest++ = rgb[BLUE_PIXEL];                      *p_dest++ = rgb[GREEN_PIXEL];                      *p_dest++ = rgb[RED_PIXEL];                      *p_dest++;                    }#ifdef TRANSPARENCY_FINISHED                  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 );                      uint32_t len     = i_xlast - i_xdest;                      /* To be able to scale correctly for full opaqueness, we                         add 1 to the alpha.  This means alpha value 0 won't                         be completely transparent and is not correct, but                         that's handled in a special case above anyway. */                                            uint8_t i_destalpha = MAX_TRANS - p_source->s.t;                      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;                                            yuv2rgb(p_source, rgb);                      rv32_pack_blend(p_dest, rgb, dest_alpha,                                       TRANS_SCALEDOWN);                      for ( len = i_xlast - i_xdest; len ; len--) {                        *p_dest++ = rgb[BLUE_PIXEL];                        *p_dest++ = rgb[GREEN_PIXEL];                        *p_dest++ = rgb[RED_PIXEL];                        *p_dest++;                      }                      break;                    }#endif /*TRANSPARENCY_FINISHED*/                  }                }            }        }         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;                default:                case MAX_TRANS: 		  {		    /* Completely opaque. Completely overwrite underlying		       pixel with subtitle pixel. */		    /* This is the location that's going to get changed. */                    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;

⌨️ 快捷键说明

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