⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svcdsub.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            return NULL;        }    }    if( p_sys->i_state == SUBTITLE_BLOCK_EMPTY )    {        i_expected_image  = p_sys->i_image + 1;        i_expected_packet = 0;    }    else    {        i_expected_image  = p_sys->i_image;        i_expected_packet = p_sys->i_packet + 1;    }    p_buffer += 2;    if( *p_buffer & 0x80 )    {        p_sys->i_state = SUBTITLE_BLOCK_COMPLETE;        i_packet       = *p_buffer++ & 0x7F;    }    else    {        p_sys->i_state = SUBTITLE_BLOCK_PARTIAL;        i_packet       = *p_buffer++;    }    p_sys->i_image = GETINT16(p_buffer);    if( p_sys->i_image != i_expected_image )    {        msg_Warn( p_dec, "expected subtitle image %u but found %u",                  i_expected_image, p_sys->i_image );    }    if( i_packet != i_expected_packet )    {        msg_Warn( p_dec, "expected subtitle image packet %u but found %u",                  i_expected_packet, i_packet );    }    p_block->p_buffer += SPU_HEADER_LEN;    p_block->i_buffer -= SPU_HEADER_LEN;    p_sys->i_packet = i_packet;    /* First packet in the subtitle block */    if( !p_sys->i_packet ) ParseHeader( p_dec, p_block );    block_ChainAppend( &p_sys->p_spu, p_block );    if( p_sys->i_state == SUBTITLE_BLOCK_COMPLETE )    {        block_t *p_spu = block_ChainGather( p_sys->p_spu );        if( p_spu->i_buffer != p_sys->i_spu_size )        {            msg_Warn( p_dec, "subtitle packets size=%d should be %d",                      p_spu->i_buffer, p_sys->i_spu_size );        }	dbg_print( (DECODE_DBG_PACKET),                 "subtitle packet complete, size=%d", p_spu->i_buffer );        p_sys->i_state = SUBTITLE_BLOCK_EMPTY;        p_sys->p_spu = 0;        return p_spu;    }    return NULL;}/******************************************************************************  The format is roughly as follows (everything is big-endian):    size     description   -------------------------------------------   byte     subtitle channel (0..7) in bits 0-3    byte     subtitle packet number of this subtitle image 0-N,            if the subtitle packet is complete, the top bit of the byte is 1.   u_int16  subtitle image number   u_int16  length in bytes of the rest   byte     option flags, unknown meaning except bit 3 (0x08) indicates            presence of the duration field   byte     unknown    u_int32  duration in 1/90000ths of a second (optional), start time            is as indicated by the PTS in the PES header   u_int32  xpos   u_int32  ypos   u_int32  width (must be even)   u_int32  height (must be even)   byte[16] palette, 4 palette entries, each contains values for            Y, U, V and transparency, 0 standing for transparent   byte     command,            cmd>>6==1 indicates shift            (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)   u_int32  shift duration in 1/90000ths of a second   u_int16  offset of odd-numbered scanlines - subtitle images are             given in interlace order   byte[]   limited RLE image data in interlace order (0,2,4... 1,3,5) with            2-bits per palette number******************************************************************************/static void ParseHeader( decoder_t *p_dec, block_t *p_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    uint8_t *p = p_block->p_buffer;    uint8_t i_options, i_options2, i_cmd, i_cmd_arg;    int i;    p_sys->i_spu_size = GETINT16(p);    i_options  = *p++;    i_options2 = *p++;    if( i_options & 0x08 ) { p_sys->i_duration = GETINT32(p); }    else p_sys->i_duration = 0; /* Ephemer subtitle */    p_sys->i_duration *= 100 / 9;    p_sys->i_x_start = GETINT16(p);    p_sys->i_y_start = GETINT16(p);    p_sys->i_width   = GETINT16(p);    p_sys->i_height  = GETINT16(p);    for( i = 0; i < 4; i++ )    {        p_sys->p_palette[i][0] = *p++; /* Y */        p_sys->p_palette[i][2] = *p++; /* Cr / V */        p_sys->p_palette[i][1] = *p++; /* Cb / U */        p_sys->p_palette[i][3] = *p++; /* T */    }    i_cmd = *p++;    /* We do not really know this, FIXME */    if( i_cmd ) {i_cmd_arg = GETINT32(p);}    /* Actually, this is measured against a different origin, so we have to     * adjust it */    p_sys->second_field_offset = GETINT16(p);    p_sys->i_image_offset  = p - p_block->p_buffer;    p_sys->i_image_length  = p_sys->i_spu_size - p_sys->i_image_offset;    p_sys->metadata_length = p_sys->i_image_offset;  if (p_sys && p_sys->i_debug & DECODE_DBG_PACKET)   {      msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "	       "spu size: %d, duration: %lu (d:%d p:%d)",	       p_sys->i_x_start, p_sys->i_y_start, 	       p_sys->i_width, p_sys->i_height, 	       p_sys->i_spu_size, (long unsigned int) p_sys->i_duration,	       p_sys->i_image_length, p_sys->i_image_offset);            for( i = 0; i < 4; i++ )      {          msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,		   p_sys->p_palette[i][3], p_sys->p_palette[i][0], 		   p_sys->p_palette[i][1], p_sys->p_palette[i][2] );      }  }}/***************************************************************************** * DecodePacket: parse and decode an subtitle packet ***************************************************************************** * This function parses and decodes an SPU packet and, if valid, returns a * subpicture. *****************************************************************************/static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data ){    decoder_sys_t *p_sys = p_dec->p_sys;    subpicture_t  *p_spu;    subpicture_region_t *p_region;    video_format_t fmt;    int i;    /* Allocate the subpicture internal data. */    p_spu = p_dec->pf_spu_buffer_new( p_dec );    if( !p_spu ) return NULL;    p_spu->b_pausable = VLC_TRUE;    p_spu->i_x = p_sys->i_x_start;    p_spu->i_y = p_sys->i_y_start;    p_spu->i_start = p_data->i_pts;    p_spu->i_stop  = p_data->i_pts + p_sys->i_duration;    p_spu->b_ephemer = VLC_TRUE;    /* Create new subtitle region */    memset( &fmt, 0, sizeof(video_format_t) );    fmt.i_chroma = VLC_FOURCC('Y','U','V','P');    /**       The video on which the subtitle sits, is scaled, probably       4:3. However subtitle bitmaps assume an 1:1 aspect ratio.       FIXME: We should get the video aspect ratio from somewhere.       Two candidates are the video and the other possibility would be       the access module.    */    fmt.i_aspect = VOUT_ASPECT_FACTOR;    fmt.i_width = fmt.i_visible_width = p_sys->i_width;    fmt.i_height = fmt.i_visible_height = p_sys->i_height;    fmt.i_x_offset = fmt.i_y_offset = 0;    p_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );    if( !p_region )    {        msg_Err( p_dec, "cannot allocate SVCD subtitle region" );        //goto error;    }    p_region->fmt.i_aspect = VOUT_ASPECT_FACTOR;        p_spu->p_region = p_region;    p_region->i_x = p_region->i_y = 0;    /* Build palette */    fmt.p_palette->i_entries = 4;    for( i = 0; i < fmt.p_palette->i_entries; i++ )    {        fmt.p_palette->palette[i][0] = p_sys->p_palette[i][0];        fmt.p_palette->palette[i][1] = p_sys->p_palette[i][1];        fmt.p_palette->palette[i][2] = p_sys->p_palette[i][2];        fmt.p_palette->palette[i][3] = p_sys->p_palette[i][3];    }    SVCDSubRenderImage( p_dec, p_data, p_region );    return p_spu;}/***************************************************************************** * SVCDSubRenderImage: reorders bytes of image data in subpicture region. ***************************************************************************** The image is encoded using two bits per pixel that select a palette entry except that value 0 starts a limited run-length encoding for color 0.  When 0 is seen, the next two bits encode one less than the number of pixels, so we can encode run lengths from 1 to 4. These get filled with the color in palette entry 0. The encoding of each line is padded to a whole number of bytes.  The first field is padded to an even byte length and the complete subtitle is padded to a 4-byte multiple that always include one zero byte at the end. However we'll transform this so that that the RLE is expanded and interlacing will also be removed. *****************************************************************************/static void SVCDSubRenderImage( decoder_t *p_dec, block_t *p_data,				subpicture_region_t *p_region ){    decoder_sys_t *p_sys = p_dec->p_sys;    uint8_t *p_dest = p_region->picture.Y_PIXELS;    int i_field;            /* The subtitles are interlaced */    int i_row, i_column;    /* scanline row/column number */    uint8_t i_color, i_count;    bs_t bs;    bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset,             p_data->i_buffer - p_sys->i_image_offset );    for( i_field = 0; i_field < 2; i_field++ )    {        for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 )        {            for( i_column = 0; i_column < p_sys->i_width; i_column++ )            {                i_color = bs_read( &bs, 2 );                if( i_color == 0 && (i_count = bs_read( &bs, 2 )) )                {                    i_count = __MIN( i_count, p_sys->i_width - i_column );                    memset( &p_dest[i_row * p_region->picture.Y_PITCH +                                    i_column], 0, i_count + 1 );                    i_column += i_count;                    continue;                }                p_dest[i_row * p_region->picture.Y_PITCH + i_column] = i_color;            }            bs_align( &bs );        }        /* odd field */        bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset +                 p_sys->second_field_offset,                 p_data->i_buffer - p_sys->i_image_offset -                 p_sys->second_field_offset );    }}

⌨️ 快捷键说明

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