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