support muxing and demuxing of dual mono mpeg ts streams if libdvbpsi is up to date

parent 665d0ef4
...@@ -156,9 +156,15 @@ struct es_format_t ...@@ -156,9 +156,15 @@ struct es_format_t
-1 : mean not selected by default even -1 : mean not selected by default even
when no other stream when no other stream
>=0: priority */ >=0: priority */
char *psz_language; char *psz_language;
char *psz_description; char *psz_description;
int i_extra_languages;
struct {
char *psz_language;
char *psz_description;
} *p_extra_languages;
audio_format_t audio; audio_format_t audio;
video_format_t video; video_format_t video;
subs_format_t subs; subs_format_t subs;
...@@ -190,6 +196,9 @@ static inline void es_format_Init( es_format_t *fmt, ...@@ -190,6 +196,9 @@ static inline void es_format_Init( es_format_t *fmt,
fmt->psz_language = NULL; fmt->psz_language = NULL;
fmt->psz_description = NULL; fmt->psz_description = NULL;
fmt->i_extra_languages = 0;
fmt->p_extra_languages = NULL;
memset( &fmt->audio, 0, sizeof(audio_format_t) ); memset( &fmt->audio, 0, sizeof(audio_format_t) );
memset( &fmt->video, 0, sizeof(video_format_t) ); memset( &fmt->video, 0, sizeof(video_format_t) );
memset( &fmt->subs, 0, sizeof(subs_format_t) ); memset( &fmt->subs, 0, sizeof(subs_format_t) );
...@@ -202,6 +211,7 @@ static inline void es_format_Init( es_format_t *fmt, ...@@ -202,6 +211,7 @@ static inline void es_format_Init( es_format_t *fmt,
static inline void es_format_Copy( es_format_t *dst, es_format_t *src ) static inline void es_format_Copy( es_format_t *dst, es_format_t *src )
{ {
int i;
memcpy( dst, src, sizeof( es_format_t ) ); memcpy( dst, src, sizeof( es_format_t ) );
if( src->psz_language ) if( src->psz_language )
dst->psz_language = strdup( src->psz_language ); dst->psz_language = strdup( src->psz_language );
...@@ -229,6 +239,19 @@ static inline void es_format_Copy( es_format_t *dst, es_format_t *src ) ...@@ -229,6 +239,19 @@ static inline void es_format_Copy( es_format_t *dst, es_format_t *src )
memcpy( dst->video.p_palette, src->video.p_palette, memcpy( dst->video.p_palette, src->video.p_palette,
sizeof( video_palette_t ) ); sizeof( video_palette_t ) );
} }
dst->i_extra_languages = src->i_extra_languages;
dst->p_extra_languages = malloc( dst->i_extra_languages * sizeof(*dst->p_extra_languages ) );
for( i = 0; i < dst->i_extra_languages; i++ ) {
if( src->p_extra_languages[i].psz_language )
dst->p_extra_languages[i].psz_language = strdup(src->p_extra_languages[i].psz_language);
else
dst->p_extra_languages[i].psz_language = NULL;
if( src->p_extra_languages[i].psz_description )
dst->p_extra_languages[i].psz_description = strdup(src->p_extra_languages[i].psz_description);
else
dst->p_extra_languages[i].psz_description = NULL;
}
} }
static inline void es_format_Clean( es_format_t *fmt ) static inline void es_format_Clean( es_format_t *fmt )
...@@ -247,6 +270,18 @@ static inline void es_format_Clean( es_format_t *fmt ) ...@@ -247,6 +270,18 @@ static inline void es_format_Clean( es_format_t *fmt )
if( fmt->subs.psz_encoding ) free( fmt->subs.psz_encoding ); if( fmt->subs.psz_encoding ) free( fmt->subs.psz_encoding );
fmt->subs.psz_encoding = NULL; fmt->subs.psz_encoding = NULL;
if( fmt->i_extra_languages && fmt->p_extra_languages ) {
int i = 0;
while( i < fmt->i_extra_languages ) {
if( fmt->p_extra_languages[i].psz_language )
free( fmt->p_extra_languages[i].psz_language );
if( fmt->p_extra_languages[i].psz_description )
free( fmt->p_extra_languages[i].psz_description );
i++;
}
free(fmt->p_extra_languages);
}
} }
#endif #endif
...@@ -3122,10 +3122,76 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) ...@@ -3122,10 +3122,76 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
if( p_decoded ) if( p_decoded )
{ {
#if 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 );
pid->es->fmt.psz_language[3] = 0;
msg_Dbg( p_demux, "found language: %s", pid->es->fmt.psz_language);
switch( p_decoded->code[0].i_audio_type ) {
case 0:
pid->es->fmt.psz_description = NULL;
break;
case 1:
pid->es->fmt.psz_description =
strdup(_("clean effects"));
break;
case 2:
pid->es->fmt.psz_description =
strdup(_("hearing impaired"));
break;
case 3:
pid->es->fmt.psz_description =
strdup(_("visual impaired commentary"));
break;
default:
msg_Dbg( p_demux, "unknown audio type: %d",
p_decoded->code[0].i_audio_type);
pid->es->fmt.psz_description = NULL;
break;
}
pid->es->fmt.i_extra_languages = p_decoded->i_code_count-1;
pid->es->fmt.p_extra_languages =
malloc( sizeof(*pid->es->fmt.p_extra_languages) *
pid->es->fmt.i_extra_languages );
for( i = 0; i < pid->es->fmt.i_extra_languages; i++ ) {
msg_Dbg( p_demux, "bang" );
pid->es->fmt.p_extra_languages[i].psz_language =
malloc(4);
memcpy(pid->es->fmt.p_extra_languages[i].psz_language,
p_decoded->code[i+1].iso_639_code, 3 );
pid->es->fmt.p_extra_languages[i].psz_language[3] = '\0';
switch( p_decoded->code[i].i_audio_type ) {
case 0:
pid->es->fmt.p_extra_languages[i].psz_description =
NULL;
break;
case 1:
pid->es->fmt.p_extra_languages[i].psz_description =
strdup(_("clean effects"));
break;
case 2:
pid->es->fmt.p_extra_languages[i].psz_description =
strdup(_("hearing impaired"));
break;
case 3:
pid->es->fmt.p_extra_languages[i].psz_description =
strdup(_("visual impaired commentary"));
break;
default:
msg_Dbg( p_demux, "unknown audio type: %d",
p_decoded->code[i].i_audio_type);
pid->es->fmt.psz_description = NULL;
break;
}
}
#else
pid->es->fmt.psz_language = malloc( 4 ); pid->es->fmt.psz_language = malloc( 4 );
memcpy( pid->es->fmt.psz_language, memcpy( pid->es->fmt.psz_language,
p_decoded->i_iso_639_code, 3 ); p_decoded->i_iso_639_code, 3 );
pid->es->fmt.psz_language[3] = 0; pid->es->fmt.psz_language[3] = 0;
#endif
} }
} }
} }
......
...@@ -337,7 +337,8 @@ typedef struct ts_stream_t ...@@ -337,7 +337,8 @@ typedef struct ts_stream_t
uint8_t *p_decoder_specific_info; uint8_t *p_decoder_specific_info;
/* language is iso639-2T */ /* language is iso639-2T */
uint8_t lang[3]; int i_langs;
uint8_t *lang;
sout_buffer_chain_t chain_pes; sout_buffer_chain_t chain_pes;
mtime_t i_pes_dts; mtime_t i_pes_dts;
...@@ -885,6 +886,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) ...@@ -885,6 +886,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{ {
sout_mux_sys_t *p_sys = p_mux->p_sys; sout_mux_sys_t *p_sys = p_mux->p_sys;
ts_stream_t *p_stream; ts_stream_t *p_stream;
int i;
p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) ); p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) );
...@@ -1013,6 +1015,9 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) ...@@ -1013,6 +1015,9 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_stream->i_langs = 1+p_input->p_fmt->i_extra_languages;
p_stream->lang = malloc(p_stream->i_langs*3);
i = 1;
p_stream->lang[0] = p_stream->lang[0] =
p_stream->lang[1] = p_stream->lang[1] =
p_stream->lang[2] = '\0'; p_stream->lang[2] = '\0';
...@@ -1040,9 +1045,41 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) ...@@ -1040,9 +1045,41 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
p_stream->lang[2] = pl->psz_iso639_2T[2]; p_stream->lang[2] = pl->psz_iso639_2T[2];
msg_Dbg( p_mux, " - lang=%c%c%c", msg_Dbg( p_mux, " - lang=%c%c%c",
p_stream->lang[0], p_stream->lang[1], p_stream->lang[2] ); p_stream->lang[0], p_stream->lang[1],
p_stream->lang[2] );
} }
} }
while( i < p_stream->i_langs ) {
if( p_input->p_fmt->p_extra_languages[i-1].psz_language )
{
char *psz = p_input->p_fmt->p_extra_languages[i-1].psz_language;
const iso639_lang_t *pl = NULL;
if( strlen( psz ) == 2 )
{
pl = GetLang_1( psz );
}
else if( strlen( psz ) == 3 )
{
pl = GetLang_2B( psz );
if( !strcmp( pl->psz_iso639_1, "??" ) )
{
pl = GetLang_2T( psz );
}
}
if( pl && strcmp( pl->psz_iso639_1, "??" ) )
{
p_stream->lang[i*3+0] = pl->psz_iso639_2T[0];
p_stream->lang[i*3+1] = pl->psz_iso639_2T[1];
p_stream->lang[i*3+2] = pl->psz_iso639_2T[2];
msg_Dbg( p_mux, " - lang=%c%c%c",
p_stream->lang[i*3+0], p_stream->lang[i*3+1],
p_stream->lang[i*3+2] );
}
}
i++;
}
/* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */ /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra; p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
...@@ -1183,6 +1220,10 @@ static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input ) ...@@ -1183,6 +1220,10 @@ static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
/* Empty all data in chain_pes */ /* Empty all data in chain_pes */
BufferChainClean( p_mux->p_sout, &p_stream->chain_pes ); BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
if( p_stream->lang )
{
free(p_stream->lang);
}
if( p_stream->p_decoder_specific_info ) if( p_stream->p_decoder_specific_info )
{ {
free( p_stream->p_decoder_specific_info ); free( p_stream->p_decoder_specific_info );
...@@ -2485,16 +2526,18 @@ static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c ) ...@@ -2485,16 +2526,18 @@ static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c )
if( p_stream->lang[0] != 0 ) if( p_stream->lang[0] != 0 )
{ {
uint8_t data[4]; uint8_t data[4*p_stream->i_langs];
/* I construct the content myself, way faster than looking at /* I construct the content myself, way faster than looking at
* over complicated/mind broken libdvbpsi way */ * over complicated/mind broken libdvbpsi way */
data[0] = p_stream->lang[0]; for(i = 0; i < p_stream->i_langs; i++ )
data[1] = p_stream->lang[1]; {
data[2] = p_stream->lang[2]; data[i*4+0] = p_stream->lang[i*3+0];
data[3] = 0x00; /* audio type: 0x00 undefined */ data[i*4+1] = p_stream->lang[i*3+1];
data[i*4+2] = p_stream->lang[i*3+2];
dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data ); data[i*4+3] = 0x00; /* audio type: 0x00 undefined */
}
dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4*p_stream->i_langs, data );
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment