]> git.sesse.net Git - vlc/blob - modules/codec/kate.c
input: Expose input_ItemHasErrorWhenReading.
[vlc] / modules / codec / kate.c
1 /*****************************************************************************
2  * kate.c : a decoder for the kate bitstream format
3  *****************************************************************************
4  * Copyright (C) 2000-2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Vincent Penquerc'h <ogg.k.ogg.k@googlemail.com>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_input.h>
34 #include <vlc_codec.h>
35
36 #include <kate/kate.h>
37
38 #include "vlc_osd.h"
39
40 /* #define ENABLE_PACKETIZER */
41 /* #define ENABLE_FORMATTING */
42 #define ENABLE_BITMAPS
43
44 /*****************************************************************************
45  * decoder_sys_t : decoder descriptor
46  *****************************************************************************/
47 struct decoder_sys_t
48 {
49 #ifdef ENABLE_PACKETIZER
50     /* Module mode */
51     bool b_packetizer;
52 #endif
53
54     /*
55      * Input properties
56      */
57     int i_num_headers;
58     int i_headers;
59
60     /*
61      * Kate properties
62      */
63     bool           b_ready;
64     kate_info      ki;
65     kate_comment   kc;
66     kate_state     k;
67
68     /*
69      * Common properties
70      */
71     mtime_t i_pts;
72
73     /*
74      * Options
75      */
76 #ifdef ENABLE_FORMATTING
77     bool   b_formatted;
78 #endif
79 };
80
81 /*****************************************************************************
82  * Local prototypes
83  *****************************************************************************/
84 static int  OpenDecoder   ( vlc_object_t * );
85 static void CloseDecoder  ( vlc_object_t * );
86 #ifdef ENABLE_PACKETIZER
87 static int OpenPacketizer( vlc_object_t *p_this );
88 #endif
89
90 static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block );
91 static int ProcessHeaders( decoder_t *p_dec );
92 static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
93                             block_t **pp_block );
94 static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp,
95                             block_t *p_block );
96 static void ParseKateComments( decoder_t * );
97
98 #define DEFAULT_NAME "Default"
99 #define MAX_LINE 8192
100
101 /*****************************************************************************
102  * Module descriptor.
103  *****************************************************************************/
104
105 #ifdef ENABLE_FORMATTING
106 #define FORMAT_TEXT N_("Formatted Subtitles")
107 #define FORMAT_LONGTEXT N_("Kate streams allow for text formatting. " \
108  "VLC partly implements this, but you can choose to disable all formatting.")
109 #endif
110
111
112 vlc_module_begin();
113     set_shortname( N_("Kate"));
114     set_description( N_("Kate text subtitles decoder") );
115     set_capability( "decoder", 50 );
116     set_callbacks( OpenDecoder, CloseDecoder );
117     set_category( CAT_INPUT );
118     set_subcategory( SUBCAT_INPUT_SCODEC );
119     add_shortcut( "kate" );
120
121 #ifdef ENABLE_PACKETIZER
122     add_submodule();
123     set_description( N_("Kate text subtitles packetizer") );
124     set_capability( "packetizer", 100 );
125     set_callbacks( OpenPacketizer, CloseDecoder );
126     add_shortcut( "kate" );
127 #endif
128
129 #ifdef ENABLE_FORMATTING
130     add_bool( "kate-formatted", true, NULL, FORMAT_TEXT, FORMAT_LONGTEXT,
131                  false );
132 #endif
133 vlc_module_end();
134
135 /*****************************************************************************
136  * OpenDecoder: probe the decoder and return score
137  *****************************************************************************
138  * Tries to launch a decoder and return score so that the interface is able
139  * to chose.
140  *****************************************************************************/
141 static int OpenDecoder( vlc_object_t *p_this )
142 {
143     decoder_t     *p_dec = (decoder_t*)p_this;
144     decoder_sys_t *p_sys;
145
146     msg_Dbg( p_dec, "kate: OpenDecoder");
147
148     if( p_dec->fmt_in.i_codec != VLC_FOURCC('k','a','t','e') )
149     {
150         return VLC_EGENERIC;
151     }
152
153     /* Set callbacks */
154     p_dec->pf_decode_sub = (subpicture_t *(*)(decoder_t *, block_t **))
155         DecodeBlock;
156     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
157         DecodeBlock;
158
159     /* Allocate the memory needed to store the decoder's structure */
160     if( ( p_dec->p_sys = p_sys =
161           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
162         return VLC_ENOMEM;
163
164     /* init of p_sys */
165 #ifdef ENABLE_PACKETIZER
166     p_sys->b_packetizer = false;
167 #endif
168     p_sys->b_ready = false;
169     p_sys->i_pts = 0;
170
171     kate_comment_init( &p_sys->kc );
172     kate_info_init( &p_sys->ki );
173
174     p_sys->i_num_headers = 0;
175     p_sys->i_headers = 0;
176
177     /* retrieve options */
178 #ifdef ENABLE_FORMATTING
179     p_sys->b_formatted = var_CreateGetBool( p_dec, "kate-formatted" );
180 #endif
181
182     return VLC_SUCCESS;
183 }
184
185 #ifdef ENABLE_PACKETIZER
186 static int OpenPacketizer( vlc_object_t *p_this )
187 {
188     decoder_t *p_dec = (decoder_t*)p_this;
189
190     int i_ret = OpenDecoder( p_this );
191
192     if( i_ret == VLC_SUCCESS )
193     {
194         p_dec->p_sys->b_packetizer = true;
195         p_dec->fmt_out.i_codec = VLC_FOURCC( 'k', 'a', 't', 'e' );
196     }
197
198     return i_ret;
199 }
200 #endif
201
202 /****************************************************************************
203  * DecodeBlock: the whole thing
204  ****************************************************************************
205  * This function must be fed with kate packets.
206  ****************************************************************************/
207 static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
208 {
209     decoder_sys_t *p_sys = p_dec->p_sys;
210     block_t *p_block;
211     kate_packet kp;
212
213     if( !pp_block || !*pp_block )
214         return NULL;
215
216     p_block = *pp_block;
217     if( p_block->i_rate != 0 )
218         p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;
219
220     /* Block to Kate packet */
221     kate_packet_wrap(&kp, p_block->i_buffer, p_block->p_buffer);
222
223     if( p_sys->i_headers == 0 && p_dec->fmt_in.i_extra )
224     {
225         /* Headers already available as extra data */
226         p_sys->i_num_headers = ((unsigned char*)p_dec->fmt_in.p_extra)[0];
227         p_sys->i_headers = p_sys->i_num_headers;
228     }
229     else if( kp.nbytes && (p_sys->i_headers==0 || p_sys->i_headers < p_sys->ki.num_headers ))
230     {
231         /* Backup headers as extra data */
232         uint8_t *p_extra;
233
234         p_dec->fmt_in.p_extra =
235             realloc( p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra + kp.nbytes + 2 );
236         p_extra = (void*)(((unsigned char*)p_dec->fmt_in.p_extra) + p_dec->fmt_in.i_extra);
237         *(p_extra++) = kp.nbytes >> 8;
238         *(p_extra++) = kp.nbytes & 0xFF;
239
240         memcpy( p_extra, kp.data, kp.nbytes );
241         p_dec->fmt_in.i_extra += kp.nbytes + 2;
242
243         block_Release( *pp_block );
244         p_sys->i_num_headers = ((unsigned char*)p_dec->fmt_in.p_extra)[0];
245         p_sys->i_headers++;
246         return NULL;
247     }
248
249     if( p_sys->i_headers == p_sys->i_num_headers && p_sys->i_num_headers>0 )
250     {
251         if( ProcessHeaders( p_dec ) != VLC_SUCCESS )
252         {
253             p_sys->i_headers = 0;
254             p_dec->fmt_in.i_extra = 0;
255             block_Release( *pp_block );
256             return NULL;
257         }
258         else p_sys->i_headers++;
259     }
260
261     return ProcessPacket( p_dec, &kp, pp_block );
262 }
263
264 /*****************************************************************************
265  * ProcessHeaders: process Kate headers.
266  *****************************************************************************/
267 static int ProcessHeaders( decoder_t *p_dec )
268 {
269     decoder_sys_t *p_sys = p_dec->p_sys;
270     kate_packet kp;
271     uint8_t *p_extra;
272     int i_extra;
273     int headeridx;
274     int ret;
275
276     if( !p_dec->fmt_in.i_extra ) return VLC_EGENERIC;
277
278     p_extra = p_dec->fmt_in.p_extra;
279     i_extra = p_dec->fmt_in.i_extra;
280
281     /* skip number of headers */
282     ++p_extra;
283     --i_extra;
284
285     /* Take care of the initial Kate header */
286     kp.nbytes = *(p_extra++) << 8;
287     kp.nbytes |= (*(p_extra++) & 0xFF);
288     kp.data = p_extra;
289     p_extra += kp.nbytes;
290     i_extra -= (kp.nbytes + 2);
291     if( i_extra < 0 )
292     {
293         msg_Err( p_dec, "header data corrupted");
294         return VLC_EGENERIC;
295     }
296
297     ret = kate_decode_headerin( &p_sys->ki, &p_sys->kc, &kp );
298     if( ret < 0 )
299     {
300         msg_Err( p_dec, "this bitstream does not contain Kate data (%d)", ret );
301         return VLC_EGENERIC;
302     }
303
304     msg_Dbg( p_dec, "%s %s text, granule rate %f, granule shift %d",
305              p_sys->ki.language, p_sys->ki.category,
306              (double)p_sys->ki.gps_numerator/p_sys->ki.gps_denominator,
307              p_sys->ki.granule_shift);
308
309     /* we want markup to be removed for now */
310     kate_info_remove_markup( &p_sys->ki, 1 );
311
312     /* parse all remaining header packets */
313     for (headeridx=1; headeridx<p_sys->ki.num_headers; ++headeridx)
314     {
315         kp.nbytes = *(p_extra++) << 8;
316         kp.nbytes |= (*(p_extra++) & 0xFF);
317         kp.data = p_extra;
318         p_extra += kp.nbytes;
319         i_extra -= (kp.nbytes + 2);
320         if( i_extra < 0 )
321         {
322             msg_Err( p_dec, "header %d data corrupted", headeridx);
323             return VLC_EGENERIC;
324         }
325
326         ret = kate_decode_headerin( &p_sys->ki, &p_sys->kc, &kp );
327         if( ret < 0 )
328         {
329             msg_Err( p_dec, "Kate header %d is corrupted: %d", headeridx, ret);
330             return VLC_EGENERIC;
331         }
332
333         /* header 1 is comments */
334         if( headeridx == 1 )
335         {
336             ParseKateComments( p_dec );
337         }
338     }
339
340 #ifdef ENABLE_PACKETIZER
341     if( !p_sys->b_packetizer )
342 #endif
343     {
344         /* We have all the headers, initialize decoder */
345         msg_Dbg( p_dec, "we have all headers, initialize libkate for decoding" );
346         ret = kate_decode_init( &p_sys->k, &p_sys->ki );
347         if (ret < 0)
348         {
349             msg_Err( p_dec, "Kate failed to initialize for decoding: %d", ret );
350             return VLC_EGENERIC;
351         }
352         p_sys->b_ready = true;
353     }
354 #ifdef ENABLE_PACKETIZER
355     else
356     {
357         p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
358         p_dec->fmt_out.p_extra =
359             realloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
360         memcpy( p_dec->fmt_out.p_extra,
361                 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
362     }
363 #endif
364
365     return VLC_SUCCESS;
366 }
367
368 /*****************************************************************************
369  * ProcessPacket: processes a kate packet.
370  *****************************************************************************/
371 static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
372                             block_t **pp_block )
373 {
374     decoder_sys_t *p_sys = p_dec->p_sys;
375     block_t *p_block = *pp_block;
376     subpicture_t *p_buf = NULL;
377
378     /* Date management */
379     if( p_block->i_pts > 0 && p_block->i_pts != p_sys->i_pts )
380     {
381         p_sys->i_pts = p_block->i_pts;
382     }
383
384     *pp_block = NULL; /* To avoid being fed the same packet again */
385
386 #ifdef ENABLE_PACKETIZER
387     if( p_sys->b_packetizer )
388     {
389         /* Date management */
390         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
391
392         if( p_sys->i_headers >= p_sys->i_num_headers )
393             p_block->i_length = p_sys->i_pts - p_block->i_pts;
394         else
395             p_block->i_length = 0;
396
397         p_buf = p_block;
398     }
399     else
400 #endif
401     {
402         if( p_sys->i_headers >= p_sys->i_num_headers )
403             p_buf = DecodePacket( p_dec, p_kp, p_block );
404         else
405             p_buf = NULL;
406
407         if( p_block ) block_Release( p_block );
408     }
409
410     return p_buf;
411 }
412
413 #ifdef ENABLE_BITMAPS
414 /* nicked off blend.c */
415 static inline void rgb_to_yuv( uint8_t *y, uint8_t *u, uint8_t *v,
416                                int r, int g, int b )
417 {
418     *y = ( ( (  66 * r + 129 * g +  25 * b + 128 ) >> 8 ) + 16 );
419     *u =   ( ( -38 * r -  74 * g + 112 * b + 128 ) >> 8 ) + 128 ;
420     *v =   ( ( 112 * r -  94 * g -  18 * b + 128 ) >> 8 ) + 128 ;
421 }
422 #endif
423
424 /*****************************************************************************
425  * DecodePacket: decodes a Kate packet.
426  *****************************************************************************/
427 static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t *p_block )
428 {
429     decoder_sys_t *p_sys = p_dec->p_sys;
430     const kate_event *ev=NULL;
431     subpicture_t *p_spu = NULL;
432     subpicture_region_t *p_bitmap_region = NULL;
433     int ret;
434 #ifdef ENABLE_BITMAPS
435     size_t n, y;
436     picture_t *pic = NULL;
437 #endif
438     video_format_t fmt;
439     kate_tracker kin;
440     bool tracker_valid = false;
441
442     ret = kate_decode_packetin( &p_sys->k, p_kp );
443     if( ret < 0 )
444     {
445         msg_Err( p_dec, "Kate failed to decode packet: %d", ret );
446         return NULL;
447     }
448
449     ret = kate_decode_eventout( &p_sys->k, &ev );
450     if( ret < 0 )
451     {
452         msg_Err( p_dec, "Kate failed to retrieve event: %d", ret );
453         return NULL;
454     }
455     if( ret > 0 )
456     {
457         /* no event to go with this packet, this is normal */
458         return NULL;
459     }
460
461     /* we have an event */
462
463     /* Get a new spu */
464     p_spu = p_dec->pf_spu_buffer_new( p_dec );
465     if( !p_spu )
466     {
467         msg_Err( p_dec, "Failed to allocate spu buffer" );
468         return NULL;
469     }
470
471     p_spu->b_pausable = true;
472
473 #ifdef ENABLE_BITMAPS
474     if (ev->bitmap && ev->bitmap->type==kate_bitmap_type_paletted && ev->palette) {
475         /* create a separate region for the bitmap */
476         memset( &fmt, 0, sizeof(video_format_t) );
477         fmt.i_chroma = VLC_FOURCC('Y','U','V','P');
478         fmt.i_aspect = 0;
479         fmt.i_width = fmt.i_visible_width = ev->bitmap->width;
480         fmt.i_height = fmt.i_visible_height = ev->bitmap->height;
481         fmt.i_x_offset = fmt.i_y_offset = 0;
482
483         p_bitmap_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
484         if( !p_bitmap_region )
485         {
486             msg_Err( p_dec, "cannot allocate SPU region" );
487             p_dec->pf_spu_buffer_del( p_dec, p_spu );
488             return NULL;
489         }
490
491         /* create the palette */
492         fmt.p_palette->i_entries = ev->palette->ncolors;
493         for (n=0; n<ev->palette->ncolors; ++n)
494         {
495             rgb_to_yuv(
496                 &fmt.p_palette->palette[n][0], &fmt.p_palette->palette[n][1], &fmt.p_palette->palette[n][2],
497                 ev->palette->colors[n].r, ev->palette->colors[n].g, ev->palette->colors[n].b
498             );
499             fmt.p_palette->palette[n][3] = ev->palette->colors[n].a;
500         }
501
502         /* create the bitmap */
503         pic = &p_bitmap_region->picture;
504         for (y=0; y<ev->bitmap->height; ++y) {
505           uint8_t *dest=pic->Y_PIXELS+pic->Y_PITCH*y;
506           const uint8_t *src=ev->bitmap->pixels+y*ev->bitmap->width;
507           memcpy(dest, src, ev->bitmap->width);
508         }
509
510         msg_Dbg(p_dec, "Created bitmap, %zux%zu, %zu colors\n", ev->bitmap->width, ev->bitmap->height, ev->palette->ncolors);
511     }
512 #endif
513
514     /* Create a new subpicture region */
515     memset( &fmt, 0, sizeof(video_format_t) );
516     fmt.i_chroma = VLC_FOURCC('T','E','X','T');
517     fmt.i_aspect = 0;
518     fmt.i_width = fmt.i_height = 0;
519     fmt.i_x_offset = fmt.i_y_offset = 0;
520
521 #ifdef ENABLE_FORMATTING
522     if (p_sys->b_formatted)
523     {
524         ret = kate_tracker_init( &kin, &p_sys->ki, ev);
525         if( ret < 0)
526         {
527             msg_Err( p_dec, "failed to initialize kate tracker, event will be unformatted: %d", ret );
528         }
529         else
530         {
531             // TODO: get window/video sizes/pos - can't find where to get those !
532             int w = 640;
533             int h = 480;
534             ret = kate_tracker_update(&kin, 0, w, h, 0, 0, w, h);
535             if( ret < 0)
536             {
537                 kate_tracker_clear(&kin);
538                 msg_Err( p_dec, "failed to update kate tracker, event will be unformatted: %d", ret );
539             }
540             else
541             {
542                 if (kin.has.region)
543                 {
544                     fmt.i_width = kin.region_w;
545                     fmt.i_height = kin.region_h;
546                 }
547
548                 // TODO: parse tracker and set style, init fmt
549                 tracker_valid = true;
550             }
551         }
552     }
553 #endif
554
555
556
557     p_spu->p_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
558     if( !p_spu->p_region )
559     {
560         msg_Err( p_dec, "cannot allocate SPU region" );
561         p_dec->pf_spu_buffer_del( p_dec, p_spu );
562         return NULL;
563     }
564
565     p_spu->p_region->psz_text = strdup(ev->text); /* no leak, this actually gets killed by the core */
566     p_spu->i_start = p_block->i_pts;
567     p_spu->i_stop = p_block->i_pts + INT64_C(1000000)*ev->duration*p_sys->ki.gps_denominator/p_sys->ki.gps_numerator;
568     p_spu->b_ephemer = (p_block->i_length == 0);
569     p_spu->b_absolute = false;
570
571     if (tracker_valid)
572     {
573         p_spu->i_flags = 0;
574         if (kin.has.region)
575         {
576             p_spu->p_region->i_x = kin.region_x;
577             p_spu->p_region->i_y = kin.region_y;
578             if (p_bitmap_region) {
579                 p_bitmap_region->i_x = kin.region_x;
580                 p_bitmap_region->i_y = kin.region_y;
581             }
582         }
583
584         kate_tracker_clear(&kin);
585     }
586     else
587     {
588         /* Normal text subs, easy markup */
589         p_spu->p_region->i_align = SUBPICTURE_ALIGN_BOTTOM;
590         if (p_bitmap_region) {
591             p_bitmap_region->i_align = SUBPICTURE_ALIGN_BOTTOM;
592         }
593         p_spu->i_x = 0;
594         p_spu->i_y = 10;
595     }
596
597 #ifdef ENABLE_BITMAPS
598     /* if we have a bitmap, chain it before the text */
599     if (p_bitmap_region)
600     {
601         p_bitmap_region->p_next = p_spu->p_region;
602         p_spu->p_region = p_bitmap_region;
603     }
604 #endif
605
606     return p_spu;
607 }
608
609 /*****************************************************************************
610  * ParseKateComments: FIXME should be done in demuxer
611  *****************************************************************************/
612 static void ParseKateComments( decoder_t *p_dec )
613 {
614     input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;
615     char *psz_name, *psz_value, *psz_comment;
616     int i = 0;
617
618     if( p_input->i_object_type != VLC_OBJECT_INPUT ) return;
619
620     while ( i < p_dec->p_sys->kc.comments )
621     {
622         psz_comment = strdup( p_dec->p_sys->kc.user_comments[i] );
623         if( !psz_comment )
624         {
625             msg_Warn( p_dec, "out of memory" );
626             break;
627         }
628         psz_name = psz_comment;
629         psz_value = strchr( psz_comment, '=' );
630         if( psz_value )
631         {
632             *psz_value = '\0';
633             psz_value++;
634             input_Control( p_input, INPUT_ADD_INFO, _("Kate comment"),
635                            psz_name, "%s", psz_value );
636         }
637         free( psz_comment );
638         i++;
639     }
640 }
641
642 /*****************************************************************************
643  * CloseDecoder: clean up the decoder
644  *****************************************************************************/
645 static void CloseDecoder( vlc_object_t *p_this )
646 {
647     decoder_t *p_dec = (decoder_t *)p_this;
648     decoder_sys_t *p_sys = p_dec->p_sys;
649
650     if (p_sys->b_ready)
651         kate_clear( &p_sys->k );
652     kate_info_clear( &p_sys->ki );
653     kate_comment_clear( &p_sys->kc );
654
655     free( p_sys );
656 }
657