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

📄 cvdsub.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
    p_sys->i_image_offset = 4;    p_sys->i_image_length = p_sys->metadata_offset - p_sys->i_image_offset;  #ifdef DEBUG_CVDSUB    msg_Dbg( p_dec, "total size: %d  image size: %d",             p_sys->i_spu_size, p_sys->i_image_length );#endif}/*   We parse the metadata information here.   Although metadata information does not have to come in a fixed field  order, every metadata field consists of a tag byte followed by  parameters. In all cases known, the size including tag byte is  exactly four bytes in length.*/#define ExtractXY(x, y) x = ((p[1]&0x0f)<<6) + (p[2]>>2); \                        y = ((p[2]&0x03)<<8) + p[3];static void ParseMetaInfo( decoder_t *p_dec, block_t *p_spu  ){    /* Last packet in subtitle block. */    decoder_sys_t *p_sys = p_dec->p_sys;    uint8_t       *p     = p_spu->p_buffer + p_sys->metadata_offset;    uint8_t       *p_end = p + p_sys->metadata_length;      for( ; p < p_end; p += 4 )    {        switch( p[0] )        {        case 0x04: /* subtitle duration in 1/90000ths of a second */            p_sys->i_duration = (p[1]<<16) + (p[2]<<8) + p[3];#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec, "subtitle display duration %lu secs",                     (long unsigned int)(p_sys->i_duration / 90000) );#endif            p_sys->i_duration *= 100 / 9;            break;              case 0x0c: /* unknown */#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec, "subtitle command unknown 0x%0x 0x%0x 0x%0x 0x%0x",                     (int)p[0], (int)p[1], (int)p[2], (int)p[3] );#endif            break;              case 0x17: /* coordinates of subtitle upper left x, y position */            ExtractXY(p_sys->i_x_start, p_sys->i_y_start);#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec, "start position (%d,%d)",                     p_sys->i_x_start, p_sys->i_y_start );#endif            break;              case 0x1f: /* coordinates of subtitle bottom right x, y position */        {            int lastx;            int lasty;            ExtractXY(lastx, lasty);            p_sys->i_width  = lastx - p_sys->i_x_start + 1;            p_sys->i_height = lasty - p_sys->i_y_start + 1;#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec, "end position (%d,%d), w x h: %dx%d",                     lastx, lasty, p_sys->i_width, p_sys->i_height );#endif            break;        }              case 0x24:        case 0x25:        case 0x26:        case 0x27:         {            uint8_t v = p[0] - 0x24;#ifdef DEBUG_CVDSUB            /* Primary Palette */            msg_Dbg( p_dec, "primary palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)",                     (int)v, (int)p[1], (int)p[2], (int)p[3] );#endif            p_sys->p_palette[v][0] = p[1]; /* Y */            p_sys->p_palette[v][1] = p[3]; /* Cr / V */            p_sys->p_palette[v][2] = p[2]; /* Cb / U */            break;        }        case 0x2c:        case 0x2d:        case 0x2e:        case 0x2f:        {            uint8_t v = p[0] - 0x2c;#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec,"highlight palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)",                     (int)v, (int)p[1], (int)p[2], (int)p[3] );#endif            /* Highlight Palette */            p_sys->p_palette_highlight[v][0] = p[1]; /* Y */            p_sys->p_palette_highlight[v][1] = p[3]; /* Cr / V */            p_sys->p_palette_highlight[v][2] = p[2]; /* Cb / U */            break;        }        case 0x37:            /* transparency for primary palette */            p_sys->p_palette[0][3] = (p[3] & 0x0f) << 4;            p_sys->p_palette[1][3] = (p[3] >> 4) << 4;            p_sys->p_palette[2][3] = (p[2] & 0x0f) << 4;            p_sys->p_palette[3][3] = (p[2] >> 4) << 4;#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec, "transparency for primary palette 0..3: "                     "0x%0x 0x%0x 0x%0x 0x%0x",                     (int)p_sys->p_palette[0][3], (int)p_sys->p_palette[1][3],                     (int)p_sys->p_palette[2][3], (int)p_sys->p_palette[3][3]);#endif            break;              case 0x3f:            /* transparency for highlight palette */            p_sys->p_palette_highlight[0][3] = (p[2] & 0x0f) << 4;            p_sys->p_palette_highlight[1][3] = (p[2] >> 4) << 4;            p_sys->p_palette_highlight[2][3] = (p[1] & 0x0f) << 4;            p_sys->p_palette_highlight[3][3] = (p[1] >> 4) << 4;#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec, "transparency for highlight palette 0..3: "                     "0x%0x 0x%0x 0x%0x 0x%0x",                     (int)p_sys->p_palette_highlight[0][3],                     (int)p_sys->p_palette_highlight[1][3],                     (int)p_sys->p_palette_highlight[2][3],                     (int)p_sys->p_palette_highlight[3][3] );#endif            break;        case 0x47:            /* offset to start of even rows of interlaced image, we correct             * to make it relative to i_image_offset (usually 4) */            p_sys->first_field_offset =                (p[2] << 8) + p[3] - p_sys->i_image_offset;#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec, "1st_field_offset %d", p_sys->first_field_offset );#endif            break;        case 0x4f:            /* offset to start of odd rows of interlaced image, we correct             * to make it relative to i_image_offset (usually 4) */            p_sys->second_field_offset =                (p[2] << 8) + p[3] - p_sys->i_image_offset;#ifdef DEBUG_CVDSUB            msg_Dbg( p_dec, "2nd_field_offset %d", p_sys->second_field_offset);#endif            break;        default:#ifdef DEBUG_CVDSUB            msg_Warn( p_dec, "unknown sequence in control header "                       "0x%0x 0x%0x 0x%0x 0x%0x", p[0], p[1], p[2], p[3]);#endif        }    }}/***************************************************************************** * DecodePacket: parse and decode an SPU 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->i_x = p_sys->i_x_start;    p_spu->i_x = p_spu->i_x * 3 / 4; /* FIXME: use aspect ratio for x? */    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 SPU region */    memset( &fmt, 0, sizeof(video_format_t) );    fmt.i_chroma = VLC_FOURCC('Y','U','V','P');    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 SPU region" );        //goto error;    }    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];    }    RenderImage( p_dec, p_data, p_region );    return p_spu;}/***************************************************************************** * ParseImage: parse and render the image part of the subtitle ***************************************************************************** This part parses the subtitle graphical data and renders it.  Image data comes interlaced and is run-length encoded (RLE). Each field is a four-bit nibbles that is further subdivided in a two-bit repeat count and a two-bit color number - up to three pixels can be described in four bits.  What a 0 repeat count means is unknown.  It might be used for RLE extension.  There is a special case of a 0 repeat count though.  When the full nibble is zero, the rest of the line is filled with the color value in the next nibble.  It is unknown what happens if the color value is greater than three.  The rest seems to use a 4-entries palette.  It is not impossible that the fill-line complete case above is not as described and the zero repeat count means fill line.  The sample code never produces this, so it may be untested. However we'll transform this so that that the RLE is expanded and interlacing will also be removed. On output each pixel entry will by  a 4-bit alpha (filling 8 bits), and 8-bit y, u, and v entry. *****************************************************************************/static void RenderImage( 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++ )            {                uint8_t i_val = bs_read( &bs, 4 );                if( i_val == 0 )                {                    /* Fill the rest of the line with next color */                    i_color = bs_read( &bs, 4 );                    memset( &p_dest[i_row * p_region->picture.Y_PITCH +                                    i_column], i_color,                            p_sys->i_width - i_column );                    i_column = p_sys->i_width;                    continue;                }                else                {                    /* Normal case: get color and repeat count */                    i_count = (i_val >> 2);                    i_color = i_val & 0x3;                    i_count = __MIN( i_count, p_sys->i_width - i_column );                    memset( &p_dest[i_row * p_region->picture.Y_PITCH +                                    i_column], i_color, i_count );                    i_column += i_count - 1;                    continue;                }            }            bs_align( &bs );        }    }}

⌨️ 快捷键说明

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