# define dbg( a )
#endif
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int telx_conf_cb ( vlc_object_t *, /* variable's object */
- char const *, /* variable name */
- vlc_value_t, /* old value */
- vlc_value_t, /* new value */
- void * ); /* callback data */
-
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
static void Close( vlc_object_t * );
static subpicture_t *Decode( decoder_t *, block_t ** );
-
-#define PAGE_TEXT N_("Teletext page")
-#define PAGE_LONGTEXT N_("Set displayed teletext page for subtitles, 0 for all pages, 888 should be a standard value. Just leave it to zero if your stream has only one language for subtitles.")
+#define OVERRIDE_PAGE_TEXT N_("Override page")
+#define OVERRIDE_PAGE_LONGTEXT N_("Override the indicated page, try this if " \
+ "your subtitles don't appear (0 = autodetect, usually 888 or 889).")
#define IGNORE_SUB_FLAG_TEXT N_("Ignore subtitle flag")
-#define IGNORE_SUB_FLAG_LONGTEXT N_("Ignore the subtitle flag, try this if your subtitles don't appear.")
+#define IGNORE_SUB_FLAG_LONGTEXT N_("Ignore the subtitle flag, try this if " \
+ "your subtitles don't appear.")
vlc_module_begin();
set_description( _("Teletext subtitles decoder") );
set_subcategory( SUBCAT_INPUT_SCODEC );
set_callbacks( Open, Close );
- add_integer( "telx-page", 0, telx_conf_cb, PAGE_TEXT, PAGE_LONGTEXT,
- VLC_FALSE );
- add_bool( "telx-ignore-subtitle-flag", 0, telx_conf_cb,
+ add_integer( "telx-override-page", -1, NULL,
+ OVERRIDE_PAGE_TEXT, OVERRIDE_PAGE_LONGTEXT, VLC_TRUE );
+ add_bool( "telx-ignore-subtitle-flag", 0, NULL,
IGNORE_SUB_FLAG_TEXT, IGNORE_SUB_FLAG_LONGTEXT, VLC_TRUE );
vlc_module_end();
int i_page[9];
vlc_bool_t b_erase[9];
uint16_t * pi_active_national_set[9];
+ int i_wanted_page, i_wanted_magazine;
+ vlc_bool_t b_ignore_sub_flag;
};
/****************************************************************************
* Local data
****************************************************************************/
-static int i_conf_wanted_page = 0; /* default 0 = all pages */
-static vlc_bool_t b_ignore_sub_flag = 0;
-
/*
* My doc only mentions 13 national characters, but experiments show there
* are more, in france for example I already found two more (0x9 and 0xb).
for ( i = 0; i < 9; i++ )
p_sys->pi_active_national_set[i] = ppi_national_subsets[1];
- var_Create( p_dec, "telx-page", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
- var_Get( p_dec, "telx-page", &val );
- i_conf_wanted_page = val.i_int;
+ var_Create( p_dec, "telx-override-page",
+ VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
+ var_Get( p_dec, "telx-override-page", &val );
+ if( val.i_int == -1 )
+ {
+ p_sys->i_wanted_magazine = p_dec->fmt_in.subs.dvb.i_id >> 16;
+ if( p_sys->i_wanted_magazine == 0 )
+ p_sys->i_wanted_magazine = 8;
+ p_sys->i_wanted_page = p_dec->fmt_in.subs.dvb.i_id & 0xff;
+ }
+ else if( val.i_int == 0 )
+ {
+ p_sys->i_wanted_magazine = -1;
+ p_sys->i_wanted_page = -1;
+ }
+ else
+ {
+ p_sys->i_wanted_magazine = val.i_int / 100;
+ p_sys->i_wanted_page = (((val.i_int % 100) / 10) << 4)
+ | ((val.i_int % 100) % 10);
+ }
var_Create( p_dec, "telx-ignore-subtitle-flag",
VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Get( p_dec, "telx-ignore-subtitle-flag", &val );
- b_ignore_sub_flag = val.b_bool;
+ p_sys->b_ignore_sub_flag = val.b_bool;
+
+ msg_Dbg( p_dec, "starting telx on magazine %d page %x flag %d",
+ p_sys->i_wanted_magazine, p_sys->i_wanted_page,
+ p_sys->b_ignore_sub_flag );
return VLC_SUCCESS;
/* return VLC_EGENERIC; */
}
-/*****************************************************************************
- * Config callback
- *****************************************************************************/
-static int telx_conf_cb ( vlc_object_t * obj, /* variable's object */
- char const * name, /* variable name */
- vlc_value_t oldv, /* old value */
- vlc_value_t newv, /* new value */
- void * data) /* callback data */
-{
- if ( !strcmp(name, "telx-page") )
- {
- i_conf_wanted_page = newv.i_int;
- dbg((obj, "display teletext page changed to %d\n", i_conf_wanted_page));
- }
- else if ( !strcmp(name, "telx-ignore-subtitle-flag") )
- {
- b_ignore_sub_flag = newv.b_bool;
- dbg((obj, "ignore sub flag changed to %d\n", (int) b_ignore_sub_flag));
- }
-
- return 0;
-}
-
-
/*****************************************************************************
* Close:
*****************************************************************************/
video_format_t fmt;
/* int erase = 0; */
int len, offset;
+#if 0
int i_wanted_magazine = i_conf_wanted_page / 100;
int i_wanted_page = 0x10 * ((i_conf_wanted_page % 100) / 10)
| (i_conf_wanted_page % 10);
+#endif
vlc_bool_t b_update = VLC_FALSE;
char psz_text[512], *pt = psz_text;
char psz_line[256];
magazine = (7 & row) == 0 ? 8 : (7 & row);
row >>= 3;
- if ( i_conf_wanted_page && magazine != i_wanted_magazine ) continue;
+ if ( p_sys->i_wanted_page != -1
+ && magazine != p_sys->i_wanted_magazine )
+ continue;
if ( row == 0 )
{
<< (a * 4);
}
- /* if (!b_ignore_sub_flag && !(1 & flag>>15)) */
+ /* if (!p_sys->b_ignore_sub_flag && !(1 & flag>>15)) */
/* continue; */
p_sys->i_page[magazine] = (0xF0 & bytereverse( hamming_8_4(packet[7]) )) |
p_sys->pi_active_national_set[magazine] =
ppi_national_subsets[7 & (flag >> 21)];
- p_sys->b_is_subtitle[magazine] = b_ignore_sub_flag
+ p_sys->b_is_subtitle[magazine] = p_sys->b_ignore_sub_flag
|| ( (1 & (flag >> 15))
&& (1 & (flag>>16)) );
(1 & (flag>>19))? " inhibit" : "",
(1 & (flag>>20)) ));
- if ( (i_conf_wanted_page && p_sys->i_page[magazine] != i_wanted_page)
+ if ( (p_sys->i_wanted_page != -1
+ && p_sys->i_page[magazine] != p_sys->i_wanted_page)
|| !p_sys->b_is_subtitle[magazine] )
continue;
int i;
/* row 1-23 : normal lines */
- if ( (i_conf_wanted_page && p_sys->i_page[magazine] != i_wanted_page)
+ if ( (p_sys->i_wanted_page != -1
+ && p_sys->i_page[magazine] != p_sys->i_wanted_page)
|| !p_sys->b_is_subtitle[magazine]
- || (!i_conf_wanted_page && p_sys->i_page[magazine] > 0x99) )
+ || (p_sys->i_wanted_page == -1
+ && p_sys->i_page[magazine] > 0x99) )
continue;
decode_string( psz_line, sizeof(psz_line), p_sys, magazine,
else if ( row == 25 )
{
/* row 25 : alternate header line */
- if ( (i_conf_wanted_page && p_sys->i_page[magazine] != i_wanted_page)
+ if ( (p_sys->i_wanted_page != -1
+ && p_sys->i_page[magazine] != p_sys->i_wanted_page)
|| !p_sys->b_is_subtitle[magazine] )
continue;
i_table_id, i_table_id, i_extension, i_extension );
#endif
if( p_demux->p_sys->pid[0].psi->i_pat_version == -1 )
- return;
+ return;
if( i_table_id == 0x42 )
{
msg_Dbg( p_demux, " * EBU Teletext descriptor" );
pid->es->fmt.i_cat = SPU_ES;
pid->es->fmt.i_codec = VLC_FOURCC( 't', 'e', 'l', 'x' );
- pid->es->fmt.psz_description = strdup( "Teletext" );
pid->es->fmt.i_extra = p_dr->i_length;
pid->es->fmt.p_extra = malloc( p_dr->i_length );
memcpy( pid->es->fmt.p_extra, p_dr->p_data,
p_dr->i_length );
+
+#ifdef _DVBPSI_DR_56_H_
+ pid->es->fmt.i_group = p_pmt->i_program_number;
+
+ /* If i_dvb_program == -1 it means the user specified
+ * --sout-all or --programs, so she want to stream, and
+ * she doesn't want to stream several identical ESes
+ * with different language descriptors. So for -1 we
+ * just enable descriptor pass-through. --Meuuh */
+ if( p_sys->i_dvb_program != -1 )
+ {
+ uint16_t n, i = 0;
+ dvbpsi_teletext_dr_t *sub;
+
+ sub = dvbpsi_DecodeTeletextDr( p_dr );
+ if( !sub ) continue;
+
+ /* Each subtitle ES contains n languages,
+ * We are going to create n ES for the n tracks */
+ for( n = 0; n < sub->i_pages_number; n++ )
+ {
+ dvbpsi_teletextpage_t *p_page = &sub->p_pages[n];
+ if( p_page->i_teletext_type == 0x2
+ || p_page->i_teletext_type == 0x5 )
+ {
+ ts_es_t *p_es;
+
+ if( i == 0 )
+ {
+ p_es = pid->es;
+ }
+ else
+ {
+ p_es = malloc( sizeof( ts_es_t ) );
+ p_es->fmt = pid->es->fmt;
+ p_es->id = NULL;
+ p_es->p_pes = NULL;
+ p_es->i_pes_size = 0;
+ p_es->i_pes_gathered = 0;
+ p_es->pp_last = &p_es->p_pes;
+ p_es->p_mpeg4desc = NULL;
+
+ TAB_APPEND( pid->i_extra_es, pid->extra_es,
+ p_es );
+ }
+
+ p_es->fmt.psz_language = malloc( 4 );
+ memcpy( p_es->fmt.psz_language,
+ p_page->i_iso6392_language_code, 3 );
+ p_es->fmt.psz_language[3] = 0;
+
+ switch( p_page->i_teletext_type )
+ {
+ case 0x2:
+ p_es->fmt.psz_description =
+ strdup(_("subtitles"));
+ msg_Dbg( p_demux,
+ " * sub lan=%s page=%d%x",
+ p_es->fmt.psz_language,
+ p_page->i_teletext_magazine_number,
+ p_page->i_teletext_page_number );
+ break;
+
+ case 0x5:
+ p_es->fmt.psz_description =
+ strdup(_("hearing impaired"));
+ msg_Dbg( p_demux,
+ " * hearing impaired lan=%s page=%d%x",
+ p_es->fmt.psz_language,
+ p_page->i_teletext_magazine_number,
+ p_page->i_teletext_page_number );
+ break;
+ default:
+ break;
+ }
+
+ p_es->fmt.subs.dvb.i_id =
+ p_page->i_teletext_page_number;
+ /* Hack, FIXME */
+ p_es->fmt.subs.dvb.i_id |=
+ ((int)p_page->i_teletext_magazine_number << 16);
+
+ i++;
+ }
+ }
+
+ if( !i )
+ pid->es->fmt.i_cat = UNKNOWN_ES;
+ }
+#else
+ pid->es->fmt.psz_description = strdup( "Teletext" );
+#endif
}
-#ifdef _DVBPSI_DR_59_H_
else if( p_dr->i_tag == 0x59 )
{
- uint16_t n;
- dvbpsi_subtitling_dr_t *sub;
-
/* DVB subtitles */
pid->es->fmt.i_cat = SPU_ES;
pid->es->fmt.i_codec = VLC_FOURCC( 'd', 'v', 'b', 's' );
- pid->es->fmt.i_group = p_pmt->i_program_number;
+ pid->es->fmt.i_extra = p_dr->i_length;
+ pid->es->fmt.p_extra = malloc( p_dr->i_length );
+ memcpy( pid->es->fmt.p_extra, p_dr->p_data,
+ p_dr->i_length );
- sub = dvbpsi_DecodeSubtitlingDr( p_dr );
- if( !sub ) continue;
+#ifdef _DVBPSI_DR_59_H_
+ pid->es->fmt.i_group = p_pmt->i_program_number;
- /* Each subtitle ES contains n languages,
- * We are going to create n ES for the n tracks */
- if( sub->i_subtitles_number > 0 )
+ /* If i_dvb_program == -1 it means the user specified
+ * --sout-all or --programs, so she want to stream, and
+ * she doesn't want to stream several identical ESes
+ * with different language descriptors. So for -1 we
+ * just enable descriptor pass-through. --Meuuh */
+ if( p_sys->i_dvb_program != -1 )
{
- pid->es->fmt.psz_language = malloc( 4 );
- memcpy( pid->es->fmt.psz_language,
- sub->p_subtitle[0].i_iso6392_language_code, 3);
- pid->es->fmt.psz_language[3] = 0;
-
- pid->es->fmt.subs.dvb.i_id =
- sub->p_subtitle[0].i_composition_page_id;
- /* Hack, FIXME */
- pid->es->fmt.subs.dvb.i_id |=
- ((int)sub->p_subtitle[0].i_ancillary_page_id << 16);
- }
- else pid->es->fmt.i_cat = UNKNOWN_ES;
+ uint16_t n, i = 0;
+ dvbpsi_subtitling_dr_t *sub;
- for( n = 1; n < sub->i_subtitles_number; n++ )
- {
- ts_es_t *p_es = malloc( sizeof( ts_es_t ) );
- p_es->fmt = pid->es->fmt;
- p_es->id = NULL;
- p_es->p_pes = NULL;
- p_es->i_pes_size = 0;
- p_es->i_pes_gathered = 0;
- p_es->pp_last = &p_es->p_pes;
- p_es->p_mpeg4desc = NULL;
-
- p_es->fmt.psz_language = malloc( 4 );
- memcpy( p_es->fmt.psz_language,
- sub->p_subtitle[n].i_iso6392_language_code, 3);
- p_es->fmt.psz_language[3] = 0;
-
- p_es->fmt.subs.dvb.i_id =
- sub->p_subtitle[n].i_composition_page_id;
- /* Hack, FIXME */
- p_es->fmt.subs.dvb.i_id |=
- ((int)sub->p_subtitle[n].i_ancillary_page_id << 16);
-
- TAB_APPEND( pid->i_extra_es, pid->extra_es, p_es );
+ sub = dvbpsi_DecodeSubtitlingDr( p_dr );
+ if( !sub ) continue;
+
+ for( n = 0; n < sub->i_subtitles_number; n++ )
+ {
+ dvbpsi_subtitle_t *p_sub = &sub->p_subtitle[n];
+ ts_es_t *p_es;
+
+ if( i == 0 )
+ {
+ p_es = pid->es;
+ }
+ else
+ {
+ p_es = malloc( sizeof( ts_es_t ) );
+ p_es->fmt = pid->es->fmt;
+ p_es->id = NULL;
+ p_es->p_pes = NULL;
+ p_es->i_pes_size = 0;
+ p_es->i_pes_gathered = 0;
+ p_es->pp_last = &p_es->p_pes;
+ p_es->p_mpeg4desc = NULL;
+
+ TAB_APPEND( pid->i_extra_es, pid->extra_es,
+ p_es );
+ }
+
+ p_es->fmt.psz_language = malloc( 4 );
+ memcpy( p_es->fmt.psz_language,
+ p_sub->i_iso6392_language_code, 3 );
+ p_es->fmt.psz_language[3] = 0;
+
+ switch( p_sub->i_subtitling_type )
+ {
+ case 0x10:
+ p_es->fmt.psz_description =
+ strdup(_("subtitles"));
+ break;
+ case 0x11:
+ p_es->fmt.psz_description =
+ strdup(_("4:3 subtitles"));
+ break;
+ case 0x12:
+ p_es->fmt.psz_description =
+ strdup(_("16:9 subtitles"));
+ break;
+ case 0x13:
+ p_es->fmt.psz_description =
+ strdup(_("2.21:1 subtitles"));
+ break;
+ case 0x20:
+ p_es->fmt.psz_description =
+ strdup(_("hearing impaired"));
+ break;
+ case 0x21:
+ p_es->fmt.psz_description =
+ strdup(_("4:3 hearing impaired"));
+ break;
+ case 0x22:
+ p_es->fmt.psz_description =
+ strdup(_("16:9 hearing impaired"));
+ break;
+ case 0x23:
+ p_es->fmt.psz_description =
+ strdup(_("2.21:1 hearing impaired"));
+ break;
+ default:
+ break;
+ }
+
+ p_es->fmt.subs.dvb.i_id =
+ p_sub->i_composition_page_id;
+ /* Hack, FIXME */
+ p_es->fmt.subs.dvb.i_id |=
+ ((int)p_sub->i_ancillary_page_id << 16);
+
+ i++;
+ }
+
+ if( !i )
+ pid->es->fmt.i_cat = UNKNOWN_ES;
}
- }
#endif /* _DVBPSI_DR_59_H_ */
+ }
}
}
else if( p_es->i_type == 0xa0 )
if( pid->es->fmt.i_cat == AUDIO_ES ||
( pid->es->fmt.i_cat == SPU_ES &&
- pid->es->fmt.i_codec != VLC_FOURCC('d','v','b','s') ) )
+ pid->es->fmt.i_codec != VLC_FOURCC('d','v','b','s') &&
+ pid->es->fmt.i_codec != VLC_FOURCC('t','e','l','x') ) )
{
/* get language descriptor */
dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
if( p_decoded )
{
-#if DR_0A_API_VER >= 2
+#if defined(DR_0A_API_VER) && (DR_0A_API_VER >= 2)
pid->es->fmt.psz_language = malloc( 4 );
memcpy( pid->es->fmt.psz_language,
p_decoded->code[0].iso_639_code, 3 );
}
else if( p_stream->i_codec == VLC_FOURCC('t','e','l','x') )
{
- dvbpsi_PMTESAddDescriptor( p_es, 0x56,
- p_stream->i_decoder_specific_info,
- p_stream->p_decoder_specific_info );
+ if( p_stream->i_decoder_specific_info )
+ {
+ dvbpsi_PMTESAddDescriptor( p_es, 0x56,
+ p_stream->i_decoder_specific_info,
+ p_stream->p_decoder_specific_info );
+ }
+ continue;
}
-#ifdef _DVBPSI_DR_59_H_
else if( p_stream->i_codec == VLC_FOURCC('d','v','b','s') )
{
/* DVB subtitles */
- dvbpsi_subtitling_dr_t descr;
- dvbpsi_subtitle_t sub;
- dvbpsi_descriptor_t *p_descr;
-
- memcpy( sub.i_iso6392_language_code, p_stream->lang, 3 );
- sub.i_subtitling_type = 0x10; /* no aspect-ratio criticality */
- sub.i_composition_page_id = p_stream->i_es_id & 0xFF;
- sub.i_ancillary_page_id = p_stream->i_es_id >> 16;
-
- descr.i_subtitles_number = 1;
- descr.p_subtitle[0] = sub;
-
- p_descr = dvbpsi_GenSubtitlingDr( &descr, 0 );
- /* Work around bug in old libdvbpsi */ p_descr->i_length = 8;
- dvbpsi_PMTESAddDescriptor( p_es, p_descr->i_tag,
- p_descr->i_length, p_descr->p_data );
+ if( p_stream->i_decoder_specific_info )
+ {
+ /* pass-through from the TS demux */
+ dvbpsi_PMTESAddDescriptor( p_es, 0x59,
+ p_stream->i_decoder_specific_info,
+ p_stream->p_decoder_specific_info );
+ }
+#ifdef _DVBPSI_DR_59_H_
+ else
+ {
+ /* from the dvbsub transcoder */
+ dvbpsi_subtitling_dr_t descr;
+ dvbpsi_subtitle_t sub;
+ dvbpsi_descriptor_t *p_descr;
+
+ memcpy( sub.i_iso6392_language_code, p_stream->lang, 3 );
+ sub.i_subtitling_type = 0x10; /* no aspect-ratio criticality */
+ sub.i_composition_page_id = p_stream->i_es_id & 0xFF;
+ sub.i_ancillary_page_id = p_stream->i_es_id >> 16;
+
+ descr.i_subtitles_number = 1;
+ descr.p_subtitle[0] = sub;
+
+ p_descr = dvbpsi_GenSubtitlingDr( &descr, 0 );
+ /* Work around bug in old libdvbpsi */ p_descr->i_length = 8;
+ dvbpsi_PMTESAddDescriptor( p_es, p_descr->i_tag,
+ p_descr->i_length, p_descr->p_data );
+ }
+#endif /* _DVBPSI_DR_59_H_ */
continue;
}
-#endif /* _DVBPSI_DR_59_H_ */
if( p_stream->lang[0] != 0 )
{