1 /*****************************************************************************
2 * kate.c : a decoder for the kate bitstream format
3 *****************************************************************************
4 * Copyright (C) 2000-2006 the VideoLAN team
7 * Authors: Vincent Penquerc'h <ogg.k.ogg.k@googlemail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_input.h>
34 #include <vlc_codec.h>
37 #include <kate/kate.h>
39 /* #define ENABLE_PACKETIZER */
40 #define ENABLE_FORMATTING
41 #define ENABLE_BITMAPS
43 /*****************************************************************************
44 * decoder_sys_t : decoder descriptor
45 *****************************************************************************/
48 #ifdef ENABLE_PACKETIZER
75 #ifdef ENABLE_FORMATTING
80 /*****************************************************************************
82 *****************************************************************************/
83 static int OpenDecoder ( vlc_object_t * );
84 static void CloseDecoder ( vlc_object_t * );
85 #ifdef ENABLE_PACKETIZER
86 static int OpenPacketizer( vlc_object_t *p_this );
89 static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block );
90 static int ProcessHeaders( decoder_t *p_dec );
91 static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
93 static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp,
95 static void ParseKateComments( decoder_t * );
97 #define DEFAULT_NAME "Default"
100 /*****************************************************************************
102 *****************************************************************************/
104 #ifdef ENABLE_FORMATTING
105 #define FORMAT_TEXT N_("Formatted Subtitles")
106 #define FORMAT_LONGTEXT N_("Kate streams allow for text formatting. " \
107 "VLC partly implements this, but you can choose to disable all formatting.")
112 set_shortname( N_("Kate"));
113 set_description( N_("Kate text subtitles decoder") );
114 set_capability( "decoder", 50 );
115 set_callbacks( OpenDecoder, CloseDecoder );
116 set_category( CAT_INPUT );
117 set_subcategory( SUBCAT_INPUT_SCODEC );
118 add_shortcut( "kate" );
120 #ifdef ENABLE_PACKETIZER
122 set_description( N_("Kate text subtitles packetizer") );
123 set_capability( "packetizer", 100 );
124 set_callbacks( OpenPacketizer, CloseDecoder );
125 add_shortcut( "kate" );
128 #ifdef ENABLE_FORMATTING
129 add_bool( "kate-formatted", true, NULL, FORMAT_TEXT, FORMAT_LONGTEXT,
134 /*****************************************************************************
135 * OpenDecoder: probe the decoder and return score
136 *****************************************************************************
137 * Tries to launch a decoder and return score so that the interface is able
139 *****************************************************************************/
140 static int OpenDecoder( vlc_object_t *p_this )
142 decoder_t *p_dec = (decoder_t*)p_this;
143 decoder_sys_t *p_sys;
145 msg_Dbg( p_dec, "kate: OpenDecoder");
147 if( p_dec->fmt_in.i_codec != VLC_FOURCC('k','a','t','e') )
153 p_dec->pf_decode_sub = (subpicture_t *(*)(decoder_t *, block_t **))
155 p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
158 /* Allocate the memory needed to store the decoder's structure */
159 if( ( p_dec->p_sys = p_sys =
160 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
164 #ifdef ENABLE_PACKETIZER
165 p_sys->b_packetizer = false;
167 p_sys->b_ready = false;
170 kate_comment_init( &p_sys->kc );
171 kate_info_init( &p_sys->ki );
173 p_sys->i_num_headers = 0;
174 p_sys->i_headers = 0;
176 /* retrieve options */
177 #ifdef ENABLE_FORMATTING
178 p_sys->b_formatted = var_CreateGetBool( p_dec, "kate-formatted" );
184 #ifdef ENABLE_PACKETIZER
185 static int OpenPacketizer( vlc_object_t *p_this )
187 decoder_t *p_dec = (decoder_t*)p_this;
189 int i_ret = OpenDecoder( p_this );
191 if( i_ret == VLC_SUCCESS )
193 p_dec->p_sys->b_packetizer = true;
194 p_dec->fmt_out.i_codec = VLC_FOURCC( 'k', 'a', 't', 'e' );
201 /****************************************************************************
202 * DecodeBlock: the whole thing
203 ****************************************************************************
204 * This function must be fed with kate packets.
205 ****************************************************************************/
206 static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
208 decoder_sys_t *p_sys = p_dec->p_sys;
212 if( !pp_block || !*pp_block )
216 if( p_block->i_rate != 0 )
217 p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;
219 /* Block to Kate packet */
220 kate_packet_wrap(&kp, p_block->i_buffer, p_block->p_buffer);
222 if( p_sys->i_headers == 0 && p_dec->fmt_in.i_extra )
224 /* Headers already available as extra data */
225 p_sys->i_num_headers = ((unsigned char*)p_dec->fmt_in.p_extra)[0];
226 p_sys->i_headers = p_sys->i_num_headers;
228 else if( kp.nbytes && (p_sys->i_headers==0 || p_sys->i_headers < p_sys->ki.num_headers ))
230 /* Backup headers as extra data */
233 p_dec->fmt_in.p_extra =
234 realloc( p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra + kp.nbytes + 2 );
235 p_extra = (void*)(((unsigned char*)p_dec->fmt_in.p_extra) + p_dec->fmt_in.i_extra);
236 *(p_extra++) = kp.nbytes >> 8;
237 *(p_extra++) = kp.nbytes & 0xFF;
239 memcpy( p_extra, kp.data, kp.nbytes );
240 p_dec->fmt_in.i_extra += kp.nbytes + 2;
242 block_Release( *pp_block );
243 p_sys->i_num_headers = ((unsigned char*)p_dec->fmt_in.p_extra)[0];
248 if( p_sys->i_headers == p_sys->i_num_headers && p_sys->i_num_headers>0 )
250 if( ProcessHeaders( p_dec ) != VLC_SUCCESS )
252 p_sys->i_headers = 0;
253 p_dec->fmt_in.i_extra = 0;
254 block_Release( *pp_block );
257 else p_sys->i_headers++;
260 return ProcessPacket( p_dec, &kp, pp_block );
263 /*****************************************************************************
264 * ProcessHeaders: process Kate headers.
265 *****************************************************************************/
266 static int ProcessHeaders( decoder_t *p_dec )
268 decoder_sys_t *p_sys = p_dec->p_sys;
275 if( !p_dec->fmt_in.i_extra ) return VLC_EGENERIC;
277 p_extra = p_dec->fmt_in.p_extra;
278 i_extra = p_dec->fmt_in.i_extra;
280 /* skip number of headers */
284 /* Take care of the initial Kate header */
285 kp.nbytes = *(p_extra++) << 8;
286 kp.nbytes |= (*(p_extra++) & 0xFF);
288 p_extra += kp.nbytes;
289 i_extra -= (kp.nbytes + 2);
292 msg_Err( p_dec, "header data corrupted");
296 ret = kate_decode_headerin( &p_sys->ki, &p_sys->kc, &kp );
299 msg_Err( p_dec, "this bitstream does not contain Kate data (%d)", ret );
303 msg_Dbg( p_dec, "%s %s text, granule rate %f, granule shift %d",
304 p_sys->ki.language, p_sys->ki.category,
305 (double)p_sys->ki.gps_numerator/p_sys->ki.gps_denominator,
306 p_sys->ki.granule_shift);
308 /* parse all remaining header packets */
309 for (headeridx=1; headeridx<p_sys->ki.num_headers; ++headeridx)
311 kp.nbytes = *(p_extra++) << 8;
312 kp.nbytes |= (*(p_extra++) & 0xFF);
314 p_extra += kp.nbytes;
315 i_extra -= (kp.nbytes + 2);
318 msg_Err( p_dec, "header %d data corrupted", headeridx);
322 ret = kate_decode_headerin( &p_sys->ki, &p_sys->kc, &kp );
325 msg_Err( p_dec, "Kate header %d is corrupted: %d", headeridx, ret);
329 /* header 1 is comments */
332 ParseKateComments( p_dec );
336 #ifdef ENABLE_PACKETIZER
337 if( !p_sys->b_packetizer )
340 /* We have all the headers, initialize decoder */
341 msg_Dbg( p_dec, "we have all headers, initialize libkate for decoding" );
342 ret = kate_decode_init( &p_sys->k, &p_sys->ki );
345 msg_Err( p_dec, "Kate failed to initialize for decoding: %d", ret );
348 p_sys->b_ready = true;
350 #ifdef ENABLE_PACKETIZER
353 p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
354 p_dec->fmt_out.p_extra =
355 realloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
356 memcpy( p_dec->fmt_out.p_extra,
357 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
364 /*****************************************************************************
365 * ProcessPacket: processes a kate packet.
366 *****************************************************************************/
367 static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
370 decoder_sys_t *p_sys = p_dec->p_sys;
371 block_t *p_block = *pp_block;
372 subpicture_t *p_buf = NULL;
374 /* Date management */
375 if( p_block->i_pts > 0 && p_block->i_pts != p_sys->i_pts )
377 p_sys->i_pts = p_block->i_pts;
380 *pp_block = NULL; /* To avoid being fed the same packet again */
382 #ifdef ENABLE_PACKETIZER
383 if( p_sys->b_packetizer )
385 /* Date management */
386 p_block->i_dts = p_block->i_pts = p_sys->i_pts;
388 if( p_sys->i_headers >= p_sys->i_num_headers )
389 p_block->i_length = p_sys->i_pts - p_block->i_pts;
391 p_block->i_length = 0;
398 if( p_sys->i_headers >= p_sys->i_num_headers )
399 p_buf = DecodePacket( p_dec, p_kp, p_block );
403 if( p_block ) block_Release( p_block );
409 #ifdef ENABLE_BITMAPS
410 /* nicked off blend.c */
411 static inline void rgb_to_yuv( uint8_t *y, uint8_t *u, uint8_t *v,
412 int r, int g, int b )
414 *y = ( ( ( 66 * r + 129 * g + 25 * b + 128 ) >> 8 ) + 16 );
415 *u = ( ( -38 * r - 74 * g + 112 * b + 128 ) >> 8 ) + 128 ;
416 *v = ( ( 112 * r - 94 * g - 18 * b + 128 ) >> 8 ) + 128 ;
421 This retrieves the size of the video.
422 The best case is when the original video size is known, as we can then
423 scale images to match. In this case, since VLC autoscales, we want to
424 return the original size and let VLC scale everything.
425 if the original size is not known, then VLC can't resize, so we return
426 the size of the incoming video. If sizes in the Kate stream are in
427 relative units, it works fine. If they are absolute, you get what you
428 ask for. Images aren't rescaled.
430 static void GetVideoSize( decoder_t *p_dec, int *w, int *h )
432 /* searching for vout to get its size is frowned upon, so we don't and
433 use a default size if the original canvas size is not specified. */
435 decoder_sys_t *p_sys = p_dec->p_sys;
436 if( p_sys->ki.original_canvas_width > 0 && p_sys->ki.original_canvas_height > 0 )
438 *w = p_sys->ki.original_canvas_width;
439 *h = p_sys->ki.original_canvas_height;
440 msg_Dbg( p_dec, "original canvas %zu %zu\n",
441 p_sys->ki.original_canvas_width, p_sys->ki.original_canvas_height );
445 /* nothing, leave defaults */
446 msg_Dbg( p_dec, "original canvas size unknown\n");
449 /* keep this just in case it might be allowed one day ;) */
450 vout_thread_t *p_vout;
451 p_vout = vlc_object_find( (vlc_object_t*)p_dec, VLC_OBJECT_VOUT, FIND_CHILD );
454 decoder_sys_t *p_sys = p_dec->p_sys;
455 if( p_sys->ki.original_canvas_width > 0 && p_sys->ki.original_canvas_height > 0 )
457 *w = p_sys->ki.original_canvas_width;
458 *h = p_sys->ki.original_canvas_height;
462 *w = p_vout->fmt_in.i_width;
463 *h = p_vout->fmt_in.i_height;
465 msg_Dbg( p_dec, "video: in %d %d, out %d %d, original canvas %zu %zu\n",
466 p_vout->fmt_in.i_width, p_vout->fmt_in.i_height,
467 p_vout->fmt_out.i_width, p_vout->fmt_out.i_height,
468 p_sys->ki.original_canvas_width, p_sys->ki.original_canvas_height );
469 vlc_object_release( p_vout );
474 #ifdef ENABLE_BITMAPS
476 static void CreateKateBitmap( picture_t *pic, const kate_bitmap *bitmap )
480 for( y=0; y<bitmap->height; ++y )
482 uint8_t *dest = pic->Y_PIXELS+pic->Y_PITCH*y;
483 const uint8_t *src = bitmap->pixels+y*bitmap->width;
484 memcpy( dest, src, bitmap->width );
488 static void CreateKatePalette( video_palette_t *fmt_palette, const kate_palette *palette )
492 fmt_palette->i_entries = palette->ncolors;
493 for( n=0; n<palette->ncolors; ++n )
496 &fmt_palette->palette[n][0], &fmt_palette->palette[n][1], &fmt_palette->palette[n][2],
497 palette->colors[n].r, palette->colors[n].g, palette->colors[n].b
499 fmt_palette->palette[n][3] = palette->colors[n].a;
505 static void SetupText( decoder_t *p_dec, subpicture_t *p_spu, const kate_event *ev )
507 decoder_sys_t *p_sys = p_dec->p_sys;
509 if( ev->text_encoding != kate_utf8 )
511 msg_Warn( p_dec, "Text isn't UTF-8, unsupported, ignored" );
515 switch( ev->text_markup_type )
517 case kate_markup_none:
518 p_spu->p_region->psz_text = strdup( ev->text ); /* no leak, this actually gets killed by the core */
520 case kate_markup_simple:
521 if( p_sys->b_formatted )
523 /* the HTML renderer expects a top level text tag pair */
525 if( asprintf( &buffer, "<text>%s</text>", ev->text ) >= 0 )
527 p_spu->p_region->psz_html = buffer;
531 /* if not formatted, we fall through */
533 /* we don't know about this one, so remove markup and display as text */
535 char *copy = strdup( ev->text );
536 size_t len0 = strlen( copy ) + 1;
537 kate_text_remove_markup( ev->text_encoding, copy, &len0 );
538 p_spu->p_region->psz_text = copy;
544 /*****************************************************************************
545 * DecodePacket: decodes a Kate packet.
546 *****************************************************************************/
547 static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t *p_block )
549 decoder_sys_t *p_sys = p_dec->p_sys;
550 const kate_event *ev = NULL;
551 subpicture_t *p_spu = NULL;
552 subpicture_region_t *p_bitmap_region = NULL;
556 bool tracker_valid = false;
558 ret = kate_decode_packetin( &p_sys->k, p_kp );
561 msg_Err( p_dec, "Kate failed to decode packet: %d", ret );
565 ret = kate_decode_eventout( &p_sys->k, &ev );
568 msg_Err( p_dec, "Kate failed to retrieve event: %d", ret );
573 /* no event to go with this packet, this is normal */
577 /* we have an event */
580 p_spu = p_dec->pf_spu_buffer_new( p_dec );
583 msg_Err( p_dec, "Failed to allocate spu buffer" );
587 p_spu->b_pausable = true;
589 /* these may be 0 for "not specified" */
590 p_spu->i_original_picture_width = p_sys->ki.original_canvas_width;
591 p_spu->i_original_picture_height = p_sys->ki.original_canvas_height;
593 /* Create a new subpicture region */
594 memset( &fmt, 0, sizeof(video_format_t) );
596 #ifdef ENABLE_FORMATTING
597 if (p_sys->b_formatted)
599 ret = kate_tracker_init( &kin, &p_sys->ki, ev );
602 msg_Err( p_dec, "failed to initialize kate tracker, event will be unformatted: %d", ret );
606 int w = 720, h = 576; /* give sensible defaults just in case we fail to get the actual size */
607 GetVideoSize(p_dec, &w, &h);
608 ret = kate_tracker_update(&kin, 0, w, h, 0, 0, w, h);
611 kate_tracker_clear(&kin);
612 msg_Err( p_dec, "failed to update kate tracker, event will be unformatted: %d", ret );
616 // TODO: parse tracker and set style, init fmt
617 tracker_valid = true;
623 #ifdef ENABLE_BITMAPS
624 if (ev->bitmap && ev->bitmap->type==kate_bitmap_type_paletted && ev->palette) {
625 /* create a separate region for the bitmap */
626 memset( &fmt, 0, sizeof(video_format_t) );
627 fmt.i_chroma = VLC_FOURCC('Y','U','V','P');
629 fmt.i_width = fmt.i_visible_width = ev->bitmap->width;
630 fmt.i_height = fmt.i_visible_height = ev->bitmap->height;
631 fmt.i_x_offset = fmt.i_y_offset = 0;
633 p_bitmap_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
634 if( !p_bitmap_region )
636 msg_Err( p_dec, "cannot allocate SPU region" );
637 p_dec->pf_spu_buffer_del( p_dec, p_spu );
641 /* create the palette */
642 CreateKatePalette( fmt.p_palette, ev->palette );
644 /* create the bitmap */
645 CreateKateBitmap( &p_bitmap_region->picture, ev->bitmap );
647 msg_Dbg(p_dec, "Created bitmap, %zux%zu, %zu colors\n", ev->bitmap->width, ev->bitmap->height, ev->palette->ncolors);
652 fmt.i_chroma = VLC_FOURCC('T','E','X','T');
654 fmt.i_width = fmt.i_height = 0;
655 fmt.i_x_offset = fmt.i_y_offset = 0;
656 p_spu->p_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
657 if( !p_spu->p_region )
659 msg_Err( p_dec, "cannot allocate SPU region" );
660 p_dec->pf_spu_buffer_del( p_dec, p_spu );
664 SetupText( p_dec, p_spu, ev );
666 p_spu->i_start = p_block->i_pts;
667 p_spu->i_stop = p_block->i_pts + INT64_C(1000000)*ev->duration*p_sys->ki.gps_denominator/p_sys->ki.gps_numerator;
668 p_spu->b_ephemer = (p_block->i_length == 0);
669 p_spu->b_absolute = false;
671 /* default positioning */
672 p_spu->p_region->i_align = SUBPICTURE_ALIGN_BOTTOM;
675 p_bitmap_region->i_align = SUBPICTURE_ALIGN_BOTTOM;
680 /* override if tracker info present */
686 p_spu->i_x = kin.region_x;
687 p_spu->i_y = kin.region_y;
688 p_spu->b_absolute = true;
691 kate_tracker_clear(&kin);
694 #ifdef ENABLE_BITMAPS
695 /* if we have a bitmap, chain it before the text */
698 p_bitmap_region->p_next = p_spu->p_region;
699 p_spu->p_region = p_bitmap_region;
706 /*****************************************************************************
707 * ParseKateComments: FIXME should be done in demuxer
708 *****************************************************************************/
709 static void ParseKateComments( decoder_t *p_dec )
711 input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;
712 char *psz_name, *psz_value, *psz_comment;
715 if( p_input->i_object_type != VLC_OBJECT_INPUT ) return;
717 while ( i < p_dec->p_sys->kc.comments )
719 psz_comment = strdup( p_dec->p_sys->kc.user_comments[i] );
722 msg_Warn( p_dec, "out of memory" );
725 psz_name = psz_comment;
726 psz_value = strchr( psz_comment, '=' );
731 input_Control( p_input, INPUT_ADD_INFO, _("Kate comment"),
732 psz_name, "%s", psz_value );
739 /*****************************************************************************
740 * CloseDecoder: clean up the decoder
741 *****************************************************************************/
742 static void CloseDecoder( vlc_object_t *p_this )
744 decoder_t *p_dec = (decoder_t *)p_this;
745 decoder_sys_t *p_sys = p_dec->p_sys;
748 kate_clear( &p_sys->k );
749 kate_info_clear( &p_sys->ki );
750 kate_comment_clear( &p_sys->kc );