sub.c
来自「VLC媒体播放程序」· C语言 代码 · 共 1,224 行 · 第 1/3 页
C
1,224 行
if( ( s = text_get_line( txt ) ) == NULL ) { return( VLC_EGENERIC ); } i_len = strlen( s ); if( i_len <= 1 ) { /* empty line -> end of this subtitle */ buffer_text[__MAX( i_buffer_text - 1, 0 )] = '\0'; p_subtitle->i_start = i_start; p_subtitle->i_stop = i_stop; p_subtitle->psz_text = strdup( buffer_text ); return( 0 ); } else { if( i_buffer_text + i_len + 1 < 10 * MAX_LINE ) { memcpy( buffer_text + i_buffer_text, s, i_len ); i_buffer_text += i_len; buffer_text[i_buffer_text] = '\n'; i_buffer_text++; } } } } }}static int sub_SSARead( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe ){ char buffer_text[ 10 * MAX_LINE]; char *s; mtime_t i_start; mtime_t i_stop; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; for( ;; ) { int h1, m1, s1, c1, h2, m2, s2, c2; int i_dummy; if( ( s = text_get_line( txt ) ) == NULL ) { return( VLC_EGENERIC ); } p_subtitle->psz_text = malloc( strlen( s ) ); if( sscanf( s, "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d%[^\r\n]", &i_dummy, &h1, &m1, &s1, &c1, &h2, &m2, &s2, &c2, buffer_text ) == 10 ) { i_start = ( (mtime_t)h1 * 3600*1000 + (mtime_t)m1 * 60*1000 + (mtime_t)s1 * 1000 + (mtime_t)c1 * 10 ) * 1000; i_stop = ( (mtime_t)h2 * 3600*1000 + (mtime_t)m2 * 60*1000 + (mtime_t)s2 * 1000 + (mtime_t)c2 * 10 ) * 1000; /* The dec expects: ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text */ if( p_sub->i_sub_type == SUB_TYPE_SSA1 ) { sprintf( p_subtitle->psz_text, ",%d%s", i_dummy, strdup( buffer_text) ); } else { sprintf( p_subtitle->psz_text, ",%d,%s", i_dummy, strdup( buffer_text) ); } p_subtitle->i_start = i_start; p_subtitle->i_stop = i_stop; return( 0 ); } else { /* All the other stuff we add to the header field */ if( p_sub->psz_header != NULL ) { if( !( p_sub->psz_header = realloc( p_sub->psz_header, strlen( p_sub->psz_header ) + strlen( s ) + 2 ) ) ) { msg_Err( p_sub, "out of memory"); return VLC_ENOMEM; } p_sub->psz_header = strcat( p_sub->psz_header, strdup( s ) ); p_sub->psz_header = strcat( p_sub->psz_header, "\n" ); } else { if( !( p_sub->psz_header = malloc( strlen( s ) + 2 ) ) ) { msg_Err( p_sub, "out of memory"); return VLC_ENOMEM; } p_sub->psz_header = strdup( s ); p_sub->psz_header = strcat( p_sub->psz_header, "\n" ); } } }}static int sub_Vplayer( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe){ /* * each line: * h:m:s:Line1|Line2|Line3.... * or * h:m:s Line1|Line2|Line3.... * where n1 and n2 are the video frame number... * */ char *p; char buffer_text[MAX_LINE + 1]; mtime_t i_start; unsigned int i; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; for( ;; ) { int h, m, s; char c; if( ( p = text_get_line( txt ) ) == NULL ) { return( VLC_EGENERIC ); } i_start = 0; memset( buffer_text, '\0', MAX_LINE ); if( sscanf( p, "%d:%d:%d%[ :]%[^\r\n]", &h, &m, &s, &c, buffer_text ) == 5 ) { i_start = ( (mtime_t)h * 3600*1000 + (mtime_t)m * 60*1000 + (mtime_t)s * 1000 ) * 1000; break; } } /* replace | by \n */ for( i = 0; i < strlen( buffer_text ); i++ ) { if( buffer_text[i] == '|' ) { buffer_text[i] = '\n'; } } p_subtitle->i_start = i_start; p_subtitle->i_stop = 0; p_subtitle->psz_text = strndup( buffer_text, MAX_LINE ); return( 0 );}static char *sub_SamiSearch( text_t *txt, char *psz_start, char *psz_str ){ if( psz_start ) { if( local_stristr( psz_start, psz_str ) ) { char *s = local_stristr( psz_start, psz_str ); s += strlen( psz_str ); return( s ); } } for( ;; ) { char *p; if( ( p = text_get_line( txt ) ) == NULL ) { return NULL; } if( local_stristr( p, psz_str ) ) { char *s = local_stristr( p, psz_str ); s += strlen( psz_str ); return( s); } }}static int sub_Sami( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe ){ char *p; int i_start; int i_text; char buffer_text[10*MAX_LINE + 1]; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL;#define ADDC( c ) \ if( i_text < 10*MAX_LINE ) \ { \ buffer_text[i_text++] = c; \ buffer_text[i_text] = '\0'; \ } /* search "Start=" */ if( !( p = sub_SamiSearch( txt, NULL, "Start=" ) ) ) { return VLC_EGENERIC; } /* get start value */ i_start = strtol( p, &p, 0 ); /* search <P */ if( !( p = sub_SamiSearch( txt, p, "<P" ) ) ) { return VLC_EGENERIC; } /* search > */ if( !( p = sub_SamiSearch( txt, p, ">" ) ) ) { return VLC_EGENERIC; } i_text = 0; buffer_text[0] = '\0'; /* now get all txt until a "Start=" line */ for( ;; ) { if( *p ) { if( *p == '<' ) { if( !strncasecmp( p, "<br", 3 ) ) { ADDC( '\n' ); } else if( local_stristr( p, "Start=" ) ) { text_previous_line( txt ); break; } p = sub_SamiSearch( txt, p, ">" ); } else if( !strncmp( p, " ", 6 ) ) { ADDC( ' ' ); p += 6; } else if( *p == '\t' ) { ADDC( ' ' ); p++; } else { ADDC( *p ); p++; } } else { p = text_get_line( txt ); } if( p == NULL ) { break; } } p_subtitle->i_start = i_start * 1000; p_subtitle->i_stop = 0; p_subtitle->psz_text = strndup( buffer_text, 10*MAX_LINE ); return( VLC_SUCCESS );#undef ADDC}static int sub_VobSubIDX( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe){ /* * Parse the idx file. Each line: * timestamp: hh:mm:ss:mss, filepos: loc * hexint is the hex location of the vobsub in the .sub file * */ char *p; char buffer_text[MAX_LINE + 1]; unsigned int i_start, i_location; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; for( ;; ) { unsigned int h, m, s, ms, loc; if( ( p = text_get_line( txt ) ) == NULL ) { return( VLC_EGENERIC ); } i_start = 0; memset( buffer_text, '\0', MAX_LINE ); if( sscanf( p, "timestamp: %d:%d:%d:%d, filepos: %x%[^\r\n]", &h, &m, &s, &ms, &loc, buffer_text ) == 5 ) { i_start = ( (mtime_t)h * 3600*1000 + (mtime_t)m * 60*1000 + (mtime_t)s * 1000 + (mtime_t)ms ) * 1000; i_location = loc; break; } } p_subtitle->i_start = (mtime_t)i_start; p_subtitle->i_stop = 0; p_subtitle->psz_text = NULL; p_subtitle->i_vobsub_location = i_location; fprintf( stderr, "time: %x, location: %x\n", i_start, i_location ); return( 0 );}static int DemuxVobSub( subtitle_demux_t *p_demux, block_t *p_bk ){ uint8_t *p = p_bk->p_buffer; uint8_t *p_end = &p_bk->p_buffer[p_bk->i_buffer]; while( p < p_end ) { int i_size = ps_pkt_size( p, p_end - p ); block_t *p_pkt; int i_id; int i_spu; if( i_size <= 0 ) { break; } if( p[0] != 0 || p[1] != 0 || p[2] != 0x01 ) { msg_Warn( p_demux, "invalid PES" ); break; } if( p[3] != 0xbd ) { msg_Dbg( p_demux, "we don't need these ps packets (id=0x1%2.2x)", p[3] ); p += i_size; continue; } /* Create a block */ p_pkt = block_New( p_demux, i_size ); memcpy( p_pkt->p_buffer, p, i_size); p += i_size; i_id = ps_pkt_id( p_pkt ); if( (i_id&0xffe0) != 0xbd20 || ps_pkt_parse_pes( p_pkt, 1 ) ) { block_Release( p_pkt ); continue; } i_spu = i_id&0x1f; msg_Dbg( p_demux, "SPU track %d size %d", i_spu, i_size ); /* FIXME i_spu == determines which of the spu tracks we will show. */ if( p_demux->p_es && i_spu == 0 ) { p_pkt->i_pts = p_bk->i_pts; p_pkt->i_dts = 0; es_out_Send( p_demux->p_input->p_es_out, p_demux->p_es, p_pkt ); p_bk->i_pts = 0; /* only first packet has a pts */ } else { block_Release( p_pkt ); continue; } } return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?