Changeset 1374a69a5672071424e2af15bf8e281db7a6e126

Show
Ignore:
Timestamp:
13/08/04 20:58:25 (4 years ago)
Author:
Gildas Bazin <gbazin@videolan.org>
git-committer:
Gildas Bazin <gbazin@videolan.org> 1092423505 +0000
git-parent:

[cb047ed85d96168faa9f826f7d56b1da7938401a]

git-author:
Gildas Bazin <gbazin@videolan.org> 1092423505 +0000
Message:

* modules/codec/spudec/*: automatic cropping of fullscreen subpictures (most of them contain large transparent areas).
* src/video_output/vout_subpictures.c: more correct cropping (cropping coordinates are relative to the video size, not subpicture size).
* include/vlc_es.h, modules/video_filter/blend.c: use the i_entries member of video_palette_t.
* include/vlc_common.h: added SetWBE()/SetDWBE()/SetQWBE() facility.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/vlc_common.h

    r924e05d r1374a69  
    609609 
    610610/* Helper writer functions */ 
    611  
    612611#define SetWLE( p, v ) _SetWLE( (uint8_t*)p, v) 
    613612static inline void _SetWLE( uint8_t *p, uint16_t i_dw ) 
     
    630629    SetDWLE( p,   i_qw&0xffffffff ); 
    631630    SetDWLE( p+4, ( i_qw >> 32)&0xffffffff ); 
     631} 
     632#define SetWBE( p, v ) _SetWBE( (uint8_t*)p, v) 
     633static inline void _SetWBE( uint8_t *p, uint16_t i_dw ) 
     634{ 
     635    p[0] = ( i_dw >>  8 )&0xff; 
     636    p[1] = ( i_dw       )&0xff; 
     637} 
     638 
     639#define SetDWBE( p, v ) _SetDWBE( (uint8_t*)p, v) 
     640static inline void _SetDWBE( uint8_t *p, uint32_t i_dw ) 
     641{ 
     642    p[0] = ( i_dw >> 24 )&0xff; 
     643    p[1] = ( i_dw >> 16 )&0xff; 
     644    p[2] = ( i_dw >>  8 )&0xff; 
     645    p[3] = ( i_dw       )&0xff; 
     646} 
     647#define SetQWBE( p, v ) _SetQWBE( (uint8_t*)p, v) 
     648static inline void _SetQWBE( uint8_t *p, uint64_t i_qw ) 
     649{ 
     650    SetDWBE( p+4,   i_qw&0xffffffff ); 
     651    SetDWBE( p, ( i_qw >> 32)&0xffffffff ); 
    632652} 
    633653 
  • include/vlc_es.h

    r90cccf3 r1374a69  
    3737struct video_palette_t 
    3838{ 
    39     int i_dummy;        /**< to keep the compatibility with ffmpeg's palette */ 
     39    int i_entries;      /**< to keep the compatibility with ffmpeg's palette */ 
    4040    uint8_t palette[256][4];                   /**< 4-byte RGBA/YUVA palette */ 
    4141}; 
  • modules/codec/spudec/parse.c

    r3ea1b0e r1374a69  
    7979    p_spu_data->p_data = (uint8_t *)p_spu_data + sizeof(subpicture_data_t); 
    8080    p_spu_data->b_palette = VLC_FALSE; 
     81    p_spu_data->b_auto_crop = VLC_FALSE; 
     82    p_spu_data->i_y_top_offset = 0; 
     83    p_spu_data->i_y_bottom_offset = 0; 
    8184 
    8285    p_spu_data->pi_alpha[0] = 0x00; 
     
    250253            p_spu->i_height = (((p_sys->buffer[i_index+4]&0x0f)<<8)| 
    251254                              p_sys->buffer[i_index+5]) - p_spu->i_y + 1; 
    252              
     255 
     256            /* Auto crop fullscreen subtitles */ 
     257            if( p_spu->i_height > 250 ) 
     258                p_spu_data->b_auto_crop = VLC_TRUE; 
     259 
    253260            i_index += 6; 
    254261            break; 
     
    343350    unsigned int *pi_offset; 
    344351 
     352    /* Cropping */ 
     353    vlc_bool_t b_empty_top = VLC_TRUE; 
     354    unsigned int i_skipped_top = 0, i_skipped_bottom = 0; 
     355    unsigned int i_transparent_code = 0; 
     356  
    345357    /* Colormap statistics */ 
    346358    int i_border = -1; 
     
    404416            } 
    405417 
    406             *p_dest++ = i_code; 
     418            /* Auto crop subtitles (a lot more optimized) */ 
     419            if( p_spu_data->b_auto_crop ) 
     420            { 
     421                if( !i_y ) 
     422                { 
     423                    /* We assume that if the first line is transparent, then 
     424                     * it is using the palette index for the 
     425                     * (background) transparent color */ 
     426                    if( (i_code >> 2) == i_width && 
     427                        p_spu_data->pi_alpha[ i_code & 0x3 ] == 0x00 ) 
     428                    { 
     429                        i_transparent_code = i_code; 
     430                    } 
     431                    else 
     432                    { 
     433                        p_spu_data->b_auto_crop = VLC_FALSE; 
     434                    } 
     435                } 
     436 
     437                if( i_code == i_transparent_code ) 
     438                { 
     439                    if( b_empty_top ) 
     440                    { 
     441                        /* This is a blank top line, we skip it */ 
     442                      i_skipped_top++; 
     443                    } 
     444                    else 
     445                    { 
     446                        /* We can't be sure the current lines will be skipped, 
     447                         * so we store the code just in case. */ 
     448                      *p_dest++ = i_code; 
     449                      i_skipped_bottom++; 
     450                    } 
     451                } 
     452                else 
     453                { 
     454                    /* We got a valid code, store it */ 
     455                    *p_dest++ = i_code; 
     456 
     457                    /* Valid code means no blank line */ 
     458                    b_empty_top = VLC_FALSE; 
     459                    i_skipped_bottom = 0; 
     460                } 
     461            } 
     462            else 
     463            { 
     464                *p_dest++ = i_code; 
     465            } 
    407466        } 
    408467 
     
    444503             p_spu->i_width, p_spu->i_height, p_spu->i_x, p_spu->i_y ); 
    445504 
     505    /* Crop if necessary */ 
     506    if( i_skipped_top || i_skipped_bottom ) 
     507    { 
     508        int i_y = p_spu->i_y + i_skipped_top; 
     509        int i_height = p_spu->i_height - (i_skipped_top + i_skipped_bottom); 
     510 
     511        p_spu_data->i_y_top_offset = i_skipped_top; 
     512        p_spu_data->i_y_bottom_offset = i_skipped_bottom; 
     513        msg_Dbg( p_dec, "cropped to: %ix%i, position: %i,%i", 
     514                 p_spu->i_width, i_height, p_spu->i_x, i_y ); 
     515    } 
     516  
    446517    /* Handle color if no palette was found */ 
    447518    if( !p_spu_data->b_palette ) 
     
    516587    fmt.i_aspect = VOUT_ASPECT_FACTOR; 
    517588    fmt.i_width = fmt.i_visible_width = p_spu->i_width; 
    518     fmt.i_height = fmt.i_visible_height = p_spu->i_height; 
     589    fmt.i_height = fmt.i_visible_height = p_spu->i_height - 
     590        p_spu_data->i_y_top_offset - p_spu_data->i_y_bottom_offset; 
    519591    fmt.i_x_offset = fmt.i_y_offset = 0; 
    520592    p_spu->p_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt ); 
     
    525597    } 
    526598 
    527     p_spu->p_region->i_x = p_spu->p_region->i_y = 0; 
     599    p_spu->p_region->i_x = 0; 
     600    p_spu->p_region->i_y = p_spu_data->i_y_top_offset; 
    528601    p_p = p_spu->p_region->picture.p->p_pixels; 
    529602    i_pitch = p_spu->p_region->picture.p->i_pitch; 
    530603 
    531604    /* Build palette */ 
    532     for( i_x = 0; i_x < 4; i_x++ ) 
     605    fmt.p_palette->i_entries = 4; 
     606    for( i_x = 0; i_x < fmt.p_palette->i_entries; i_x++ ) 
    533607    { 
    534608        fmt.p_palette->palette[i_x][0] = p_spu_data->pi_yuv[i_x][0]; 
     
    541615 
    542616    /* Draw until we reach the bottom of the subtitle */ 
    543     for( i_y = 0; i_y < p_spu->i_height * i_pitch; i_y += i_pitch ) 
     617    for( i_y = 0; i_y < (int)fmt.i_height * i_pitch; i_y += i_pitch ) 
    544618    { 
    545619        /* Draw until we reach the end of the line */ 
    546         for( i_x = 0 ; i_x < p_spu->i_width; i_x += i_len ) 
     620        for( i_x = 0 ; i_x < (int)fmt.i_width; i_x += i_len ) 
    547621        { 
    548622            /* Get the RLE part, then draw the line */ 
  • modules/codec/spudec/spudec.h

    r3ea1b0e r1374a69  
    4949    uint8_t    pi_yuv[4][3]; 
    5050 
     51    /* Auto crop fullscreen subtitles */ 
     52    vlc_bool_t b_auto_crop; 
     53    int i_y_top_offset; 
     54    int i_y_bottom_offset; 
     55 
    5156} subpicture_data_t; 
    5257 
  • modules/video_filter/blend.c

    r0e949ba r1374a69  
    825825 
    826826    /* Convert palette first */ 
    827     for( i_y = 0; //i_y < p_filter->fmt_in.video.p_palette->i_dummy && 
     827    for( i_y = 0; i_y < p_filter->fmt_in.video.p_palette->i_entries && 
    828828         i_y < 256; i_y++ ) 
    829829    { 
  • src/video_output/vout_subpictures.c

    r8826fb8 r1374a69  
    434434            if( p_vout->b_force_crop ) 
    435435            { 
    436                 p_vout->p_blend->fmt_in.video.i_x_offset = p_vout->i_crop_x; 
    437                 p_vout->p_blend->fmt_in.video.i_y_offset = p_vout->i_crop_y; 
    438                 p_vout->p_blend->fmt_in.video.i_visible_width = 
    439                     p_vout->i_crop_width; 
    440                 p_vout->p_blend->fmt_in.video.i_visible_height = 
    441                     p_vout->i_crop_height; 
    442                 i_x_offset += p_vout->i_crop_x; 
    443                 i_y_offset += p_vout->i_crop_y; 
     436                video_format_t *p_fmt = &p_vout->p_blend->fmt_in.video; 
     437 
     438                /* Find the intersection */ 
     439                if( p_vout->i_crop_x + p_vout->i_crop_width <= i_x_offset || 
     440                    i_x_offset + (int)p_fmt->i_visible_width < 
     441                        p_vout->i_crop_x || 
     442                    p_vout->i_crop_y + p_vout->i_crop_height <= i_y_offset || 
     443                    i_y_offset + (int)p_fmt->i_visible_height < 
     444                        p_vout->i_crop_y ) 
     445                { 
     446                    /* No intersection */ 
     447                    p_fmt->i_visible_width = p_fmt->i_visible_height = 0; 
     448                } 
     449                else 
     450                { 
     451                    int i_x, i_y, i_x_end, i_y_end; 
     452                    i_x = __MAX( p_vout->i_crop_x, i_x_offset ); 
     453                    i_y = __MAX( p_vout->i_crop_y, i_y_offset ); 
     454                    i_x_end = __MIN( p_vout->i_crop_x + p_vout->i_crop_width, 
     455                                   i_x_offset + (int)p_fmt->i_visible_width ); 
     456                    i_y_end = __MIN( p_vout->i_crop_y + p_vout->i_crop_height, 
     457                                   i_y_offset + (int)p_fmt->i_visible_height ); 
     458 
     459                    p_fmt->i_x_offset = i_x - i_x_offset; 
     460                    p_fmt->i_y_offset = i_y - i_y_offset; 
     461                    p_fmt->i_visible_width = i_x_end - i_x; 
     462                    p_fmt->i_visible_height = i_y_end - i_y; 
     463 
     464                    i_x_offset = i_x; 
     465                    i_y_offset = i_y; 
     466                } 
    444467            } 
    445468