int main() { ogg_sync_state oy; ogg_stream_state os; int init=0; ogg_packet op; kate_state k; kate_info ki; kate_comment kc; const kate_event *ev; /* for the benefit of windows, which mangles data otherwise */ set_binary_file(stdin); /* we initialize ogg and kate info/comment structures */ ogg_sync_init(&oy); kate_info_init(&ki); kate_comment_init(&kc); /* First, read the headers, which must appear first in a Kate stream. When kate_decode_header returns a positive number, all headers have been seen and we're ready to decode data. */ do { get_packet(&oy,&os,&init,&op); } while (kate_ogg_decode_headerin(&ki,&kc,&op)==0); /* We now have all the information we need from the headers, so we can initialize kate for decoding */ kate_decode_init(&k,&ki); /* We can now read data, until kate_decode_packetin returns a positive number, signaling the end of the stream */ while (1) { if (get_packet(&oy,&os,&init,&op)) break; if (kate_ogg_decode_packetin(&k,&op)>0) break; /* we may have an event (eg, text) */ if (kate_decode_eventout(&k,&ev)==0) { printf("Kate stream has text: %s\n",ev->text); } } /* That's it, we can now cleanup */ ogg_stream_clear(&os); ogg_sync_clear(&oy); kate_clear(&k); kate_info_clear(&ki); kate_comment_clear(&kc); return 0; }
/***************************************************************************** * ProcessHeaders: process Kate headers. *****************************************************************************/ static int ProcessHeaders( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; kate_packet kp; unsigned pi_size[XIPH_MAX_HEADER_COUNT]; void *pp_data[XIPH_MAX_HEADER_COUNT]; unsigned i_count; if( xiph_SplitHeaders( pi_size, pp_data, &i_count, p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra) ) return VLC_EGENERIC; int i_ret = VLC_SUCCESS; if( i_count < 1 ) { i_ret = VLC_EGENERIC; goto end; } /* Take care of the initial Kate header */ kp.nbytes = pi_size[0]; kp.data = pp_data[0]; i_ret = kate_decode_headerin( &p_sys->ki, &p_sys->kc, &kp ); if( i_ret < 0 ) { msg_Err( p_dec, "this bitstream does not contain Kate data (%d)", i_ret ); goto end; } msg_Dbg( p_dec, "%s %s text, granule rate %f, granule shift %d", p_sys->ki.language, p_sys->ki.category, (double)p_sys->ki.gps_numerator/p_sys->ki.gps_denominator, p_sys->ki.granule_shift); /* parse all remaining header packets */ for( unsigned i_headeridx = 1; i_headeridx < i_count; i_headeridx++ ) { kp.nbytes = pi_size[i_headeridx]; kp.data = pp_data[i_headeridx]; i_ret = kate_decode_headerin( &p_sys->ki, &p_sys->kc, &kp ); if( i_ret < 0 ) { msg_Err( p_dec, "Kate header %d is corrupted: %d", i_headeridx, i_ret ); goto end; } /* header 1 is comments */ if( i_headeridx == 1 ) { ParseKateComments( p_dec ); } } #ifdef ENABLE_PACKETIZER if( !p_sys->b_packetizer ) #endif { /* We have all the headers, initialize decoder */ msg_Dbg( p_dec, "we have all headers, initialize libkate for decoding" ); i_ret = kate_decode_init( &p_sys->k, &p_sys->ki ); if (i_ret < 0) { msg_Err( p_dec, "Kate failed to initialize for decoding: %d", i_ret ); return VLC_EGENERIC; } p_sys->b_ready = true; } #ifdef ENABLE_PACKETIZER else { p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra; p_dec->fmt_out.p_extra = xrealloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra ); memcpy( p_dec->fmt_out.p_extra, p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra ); } #endif end: for( unsigned i = 0; i < i_count; i++ ) free( pp_data[i] ); return i_ret < 0 ? VLC_EGENERIC : VLC_SUCCESS; }