render.c

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

C
528
字号
                           || i_y < i_y_start || i_y > i_y_end ) )                {                    continue;                }                switch( p_spu->p_sys->pi_alpha[ i_color ] )                {                case 0x00:                    break;                case 0x0f:                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;                         i_ytmp += p_pic->p->i_pitch )                    {                        memset( p_dest - 2 * ( i_x >> 6 ) + i_ytmp,                                p_clut16[ i_color ],                                2 * ( ( i_len >> 6 ) + 1 ) );                    }                    break;                default:                    /* FIXME: we should do transparency */                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;                         i_ytmp += p_pic->p->i_pitch )                    {                        memset( p_dest - 2 * ( i_x >> 6 ) + i_ytmp,                                p_clut16[ i_color ],                                2 * ( ( i_len >> 6 ) + 1 ) );                    }                    break;                }            }        }    }}static void RenderRV32( vout_thread_t *p_vout, picture_t *p_pic,                        const subpicture_t *p_spu, vlc_bool_t b_crop ){    /* Common variables */    uint32_t p_clut32[4];    uint8_t *p_dest;    uint16_t *p_source = (uint16_t *)p_spu->p_sys->p_data;    int i_x, i_y;    int i_len, i_color;    /* RGB-specific */    int i_xscale, i_yscale, i_width, i_height, i_ytmp, i_yreal, i_ynext;    /* Crop-specific */    int i_x_start, i_y_start, i_x_end, i_y_end;    /* XXX: this is a COMPLETE HACK, memcpy is unable to do u32s anyway */    /* FIXME: get this from the DVD */    for( i_color = 0; i_color < 4; i_color++ )    {        p_clut32[i_color] = 0x11111111                             * ( (uint16_t)p_spu->p_sys->pi_yuv[i_color][0] >> 4 );    }    i_xscale = ( p_vout->output.i_width << 6 ) / p_vout->render.i_width;    i_yscale = ( p_vout->output.i_height << 6 ) / p_vout->render.i_height;    i_width  = p_spu->i_width  * i_xscale;    i_height = p_spu->i_height * i_yscale;    i_x_start = i_width - i_xscale * p_spu->p_sys->i_x_end;    i_y_start = i_yscale * p_spu->p_sys->i_y_start;    i_x_end = i_width - i_xscale * p_spu->p_sys->i_x_start;    i_y_end = i_yscale * p_spu->p_sys->i_y_end;    p_dest = p_pic->p->p_pixels + ( i_width >> 6 ) * 4              /* Add the picture coordinates and the SPU coordinates */              + ( (p_spu->i_x * i_xscale) >> 6 ) * 4              + ( (p_spu->i_y * i_yscale) >> 6 ) * p_pic->p->i_pitch;    /* Draw until we reach the bottom of the subtitle */    for( i_y = 0 ; i_y < i_height ; )    {        i_ytmp = i_y >> 6;        i_y += i_yscale;        /* Check whether we need to draw one line or more than one */        if( i_ytmp + 1 >= ( i_y >> 6 ) )        {            /* Just one line : we precalculate i_y >> 6 */            i_yreal = p_pic->p->i_pitch * i_ytmp;            /* Draw until we reach the end of the line */            for( i_x = i_width ; i_x ; i_x -= i_len )            {                /* Get the RLE part, then draw the line */                i_color = *p_source & 0x3;                i_len = i_xscale * ( *p_source++ >> 2 );                if( b_crop                     && ( i_x < i_x_start || i_x > i_x_end                           || i_y < i_y_start || i_y > i_y_end ) )                {                    continue;                }                switch( p_spu->p_sys->pi_alpha[ i_color ] )                {                case 0x00:                    break;                case 0x0f:                    memset( p_dest - 4 * ( i_x >> 6 ) + i_yreal,                            p_clut32[ i_color ], 4 * ( ( i_len >> 6 ) + 1 ) );                    break;                default:                    /* FIXME: we should do transparency */                    memset( p_dest - 4 * ( i_x >> 6 ) + i_yreal,                            p_clut32[ i_color ], 4 * ( ( i_len >> 6 ) + 1 ) );                    break;                }            }        }        else        {            i_yreal = p_pic->p->i_pitch * i_ytmp;            i_ynext = p_pic->p->i_pitch * i_y >> 6;            /* Draw until we reach the end of the line */            for( i_x = i_width ; i_x ; i_x -= i_len )            {                /* Get the RLE part, then draw as many lines as needed */                i_color = *p_source & 0x3;                i_len = i_xscale * ( *p_source++ >> 2 );                if( b_crop                     && ( i_x < i_x_start || i_x > i_x_end                           || i_y < i_y_start || i_y > i_y_end ) )                {                    continue;                }                switch( p_spu->p_sys->pi_alpha[ i_color ] )                {                case 0x00:                    break;                case 0x0f:                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;                         i_ytmp += p_pic->p->i_pitch )                    {                        memset( p_dest - 4 * ( i_x >> 6 ) + i_ytmp,                                p_clut32[ i_color ],                                4 * ( ( i_len >> 6 ) + 1 ) );                    }                    break;                default:                    /* FIXME: we should do transparency */                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;                         i_ytmp += p_pic->p->i_pitch )                    {                        memset( p_dest - 4 * ( i_x >> 6 ) + i_ytmp,                                p_clut32[ i_color ],                                4 * ( ( i_len >> 6 ) + 1 ) );                    }                    break;                }            }        }    }}static void RenderYUY2( vout_thread_t *p_vout, picture_t *p_pic,                        const subpicture_t *p_spu, vlc_bool_t b_crop ){    /* Common variables */    uint8_t *p_dest;    uint16_t *p_source = (uint16_t *)p_spu->p_sys->p_data;    int i_x, i_y;    int i_len, i_color;    uint8_t i_cnt;    /* Crop-specific */    int i_x_start, i_y_start, i_x_end, i_y_end;    p_dest = p_pic->p->p_pixels +              + ( p_spu->i_y + p_spu->i_height ) * p_pic->p->i_pitch  // * bytes per line              + ( p_spu->i_x + p_spu->i_width ) * 2;  // * bytes per pixel    i_x_start = p_spu->i_width - p_spu->p_sys->i_x_end;    i_y_start = (p_spu->i_height - p_spu->p_sys->i_y_end)                  * p_pic->p->i_pitch / 2;    i_x_end = p_spu->i_width - p_spu->p_sys->i_x_start;    i_y_end = (p_spu->i_height - p_spu->p_sys->i_y_start)                * p_pic->p->i_pitch / 2;    /* Draw until we reach the bottom of the subtitle */    for( i_y = p_spu->i_height * p_pic->p->i_pitch / 2;         i_y ;         i_y -= p_pic->p->i_pitch / 2 )    {        /* Draw until we reach the end of the line */        for( i_x = p_spu->i_width ; i_x ; i_x -= i_len )        {            /* Get the RLE part, then draw the line */            i_color = *p_source & 0x3;            i_len = *p_source++ >> 2;            if( b_crop                 && ( i_x < i_x_start || i_x > i_x_end                       || i_y < i_y_start || i_y > i_y_end ) )            {                continue;            }            switch( p_spu->p_sys->pi_alpha[ i_color ] )            {            case 0x00:                break;            case 0x0f:                for( i_cnt = 0; i_cnt < i_len; i_cnt++ )                {                    /* draw a pixel */                    /* Y */                    memset( p_dest - i_x * 2 - i_y * 2 + i_cnt * 2,                            p_spu->p_sys->pi_yuv[i_color][0], 1);                    if (!(i_cnt & 0x01))                    {                        /* U and V */                        memset( p_dest - i_x * 2 - i_y * 2 + i_cnt * 2 + 1,                                0x80, 1);                        memset( p_dest - i_x * 2 - i_y * 2 + i_cnt * 2 + 3,                                0x80, 1);                    }                }                break;            default:                /* FIXME: we should do transparency */                for( i_cnt = 0; i_cnt < i_len; i_cnt++ )                {                    /* draw a pixel */                    /* Y */                    memset( p_dest - i_x * 2 - i_y * 2 + i_cnt * 2,                            p_spu->p_sys->pi_yuv[i_color][0], 1);                    if (!(i_cnt & 0x01))                    {                        /* U and V */                        memset( p_dest - i_x * 2 - i_y * 2 + i_cnt * 2 + 1,                                0x80, 1);                        memset( p_dest - i_x * 2 - i_y * 2 + i_cnt * 2 + 3,                                0x80, 1);                    }                }                break;            }        }    }}

⌨️ 快捷键说明

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