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 + -
显示快捷键?