cvd_parse.c
来自「VLC媒体播放程序」· C语言 代码 · 共 549 行 · 第 1/2 页
C
549 行
/***************************************************************************** * parse.c: Philips OGT (SVCD subtitle) packet parser ***************************************************************************** * Copyright (C) 2003, 2004 VideoLAN * $Id: cvd_parse.c,v 1.14 2004/01/22 04:46:19 rocky Exp $ * * Authors: Rocky Bernstein * based on code from: * Julio Sanchez Fernandez (http://subhandler.sourceforge.net) * Sam Hocevar <sam@zoy.org> * Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <vlc/vlc.h>#include <vlc/vout.h>#include <vlc/decoder.h>#include "subtitle.h"#include "render.h"#include "cvd.h"#include "common.h"#ifdef HAVE_LIBPNG#include <png.h>#endif/* An image color is a two-bit palette entry: 0..3 */ typedef uint8_t ogt_color_t;/***************************************************************************** * Local prototypes. *****************************************************************************/static int ParseImage ( decoder_t *, subpicture_t * );/* We do not have information on the subtitle format used on CVD's except the submux sample code and a couple of samples of dubious origin. Thus, this is the result of reading some code whose correctness is not known and some experimentation. CVD subtitles are different in several ways from SVCD OGT subtitles. Image comes first and metadata is at the end. So that the metadata can be found easily, the subtitle packet starts with two bytes (everything is big-endian again) that give the total size of the subtitle data and the offset to the metadata - i.e. size of the image data plus the four bytes at the beginning. Image data comes interlaced is run-length encoded. Each field is a four-bit nibble. Each nibble contains a two-bit repeat count and a two-bit color number so that up to three pixels can be described in four bits. The function of a 0 repeat count is unknown; it might be used for RLE extension. However 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.*/void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block ){ decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *p = p_buffer+1; dbg_print( (DECODE_DBG_CALL|DECODE_DBG_PACKET), "header: 0x%02x 0x%02x 0x%02x 0x%02x, 0x%02x, 0x%02x, size: %i", p_buffer[0], p_buffer[1], p_buffer[2], p_buffer[3], p_buffer[4], p_buffer[5], p_block->i_buffer); dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , ""); p_sys->i_pts = p_block->i_pts; p_sys->i_spu_size = (p[0] << 8) + p[1] + 4; p += 2; /* FIXME: check data sanity */ p_sys->metadata_offset = GETINT16(p); p_sys->metadata_length = p_sys->i_spu_size - p_sys->metadata_offset; p_sys->i_image_offset = 4; p_sys->i_image_length = p_sys->metadata_offset - p_sys->i_image_offset; dbg_print(DECODE_DBG_PACKET, "total size: %d image size: %d\n", p_sys->i_spu_size, p_sys->i_image_length);}#define ExtractXY(x, y) \ x = ((p[1]&0x0f)<<6) + (p[2]>>2); \ y = ((p[2]&0x03)<<8) + p[3];/* 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.*/void E_(ParseMetaInfo)( decoder_t *p_dec ){ /* last packet in subtitle block. */ decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *p = p_sys->subtitle_data + p_sys->metadata_offset; uint8_t *p_end = p + p_sys->metadata_length; dbg_print( (DECODE_DBG_PACKET), "subtitle packet complete, size=%d", p_sys->i_spu ); p_sys->state = SUBTITLE_BLOCK_COMPLETE; p_sys->i_image++; for ( ; p < p_end; p += 4 ) { switch ( p[0] ) { case 0x04: /* subtitle duration in 1/90000ths of a second */ { mtime_t i_duration = (p[1]<<16) + (p[2]<<8) + p[3]; mtime_t i_duration_scale = config_GetInt( p_dec, MODULE_STRING "-duration-scaling" ); dbg_print( DECODE_DBG_PACKET, "subtitle display duration %lu secs (scaled %lu secs)", (long unsigned int) (i_duration / 90000), (long unsigned int) (i_duration * i_duration_scale / 90000) ); p_sys->i_duration = i_duration * i_duration_scale ; break; } case 0x0c: /* unknown */ dbg_print( DECODE_DBG_PACKET, "subtitle command unknown 0x%0x 0x%0x 0x%0x 0x%0x\n", p[0], p[1], p[2], p[3]); break; case 0x17: /* coordinates of subtitle upper left x, y position */ ExtractXY(p_sys->i_x_start, p_sys->i_y_start); 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; dbg_print( DECODE_DBG_PACKET, "end position: (%d,%d): %.2x %.2x %.2x, w x h: %dx%d", lastx, lasty, p[1], p[2], p[3], p_sys->i_width, p_sys->i_height ); break; } case 0x24: case 0x25: case 0x26: case 0x27: { uint8_t v = p[0]-0x24; /* Primary Palette */ dbg_print( DECODE_DBG_PACKET, "primary palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)", v, p[1], p[2], p[3]); p_sys->p_palette[v].s.y = p[1]; p_sys->p_palette[v].s.u = p[2]; p_sys->p_palette[v].s.v = p[3]; break; } case 0x2c: case 0x2d: case 0x2e: case 0x2f: { uint8_t v = p[0]-0x2c; dbg_print( DECODE_DBG_PACKET, "highlight palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)", v, p[1], p[2], p[3]); /* Highlight Palette */ p_sys->p_palette_highlight[v].s.y = p[1]; p_sys->p_palette_highlight[v].s.u = p[2]; p_sys->p_palette_highlight[v].s.v = p[3]; break; } case 0x37: /* transparency for primary palette */ p_sys->p_palette[0].s.t = p[3] & 0x0f; p_sys->p_palette[1].s.t = p[3] >> 4; p_sys->p_palette[2].s.t = p[2] & 0x0f; p_sys->p_palette[3].s.t = p[2] >> 4; dbg_print( DECODE_DBG_PACKET, "transparency for primary palette 0..3: " "0x%0x 0x%0x 0x%0x 0x%0x", p_sys->p_palette[0].s.t, p_sys->p_palette[1].s.t, p_sys->p_palette[2].s.t, p_sys->p_palette[3].s.t ); break; case 0x3f: /* transparency for highlight palette */ p_sys->p_palette_highlight[0].s.t = p[2] & 0x0f; p_sys->p_palette_highlight[1].s.t = p[2] >> 4; p_sys->p_palette_highlight[2].s.t = p[1] & 0x0f; p_sys->p_palette_highlight[3].s.t = p[1] >> 4; dbg_print( DECODE_DBG_PACKET, "transparency for primary palette 0..3: " "0x%0x 0x%0x 0x%0x 0x%0x", p_sys->p_palette_highlight[0].s.t, p_sys->p_palette_highlight[1].s.t, p_sys->p_palette_highlight[2].s.t, p_sys->p_palette_highlight[3].s.t ); 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; dbg_print( DECODE_DBG_PACKET, "first_field_offset %d", p_sys->first_field_offset); 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; dbg_print( DECODE_DBG_PACKET, "second_field_offset %d", p_sys->second_field_offset); break; default: 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]); p_sys->subtitle_data_pos = 0; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?