Commit ce071202 authored by Yuudai Yamashigi's avatar Yuudai Yamashigi Committed by Videolan

demux: ts: add support for ARIB STD-B25

parent 55a03066
...@@ -307,6 +307,7 @@ typedef struct ...@@ -307,6 +307,7 @@ typedef struct
struct demux_sys_t struct demux_sys_t
{ {
stream_t *stream;
vlc_mutex_t csa_lock; vlc_mutex_t csa_lock;
/* TS packet size (188, 192, 204) */ /* TS packet size (188, 192, 204) */
...@@ -334,6 +335,7 @@ struct demux_sys_t ...@@ -334,6 +335,7 @@ struct demux_sys_t
#ifdef HAVE_ARIBB24 #ifdef HAVE_ARIBB24
arib_instance_t *p_instance; arib_instance_t *p_instance;
#endif #endif
stream_t *b25stream;
} arib; } arib;
/* All pid */ /* All pid */
...@@ -620,6 +622,9 @@ static int Open( vlc_object_t *p_this ) ...@@ -620,6 +622,9 @@ static int Open( vlc_object_t *p_this )
p_sys->i_dvb_start = 0; p_sys->i_dvb_start = 0;
p_sys->i_dvb_length = 0; p_sys->i_dvb_length = 0;
p_sys->arib.b25stream = NULL;
p_sys->stream = p_demux->s;
p_sys->b_broken_charset = false; p_sys->b_broken_charset = false;
for( int i = 0; i < 8192; i++ ) for( int i = 0; i < 8192; i++ )
...@@ -807,7 +812,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -807,7 +812,7 @@ static int Open( vlc_object_t *p_this )
} }
bool can_seek = false; bool can_seek = false;
stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &can_seek ); stream_Control( p_sys->stream, STREAM_CAN_FASTSEEK, &can_seek );
if( can_seek ) if( can_seek )
{ {
GetFirstPCR( p_demux ); GetFirstPCR( p_demux );
...@@ -913,6 +918,12 @@ static void Close( vlc_object_t *p_this ) ...@@ -913,6 +918,12 @@ static void Close( vlc_object_t *p_this )
arib_instance_destroy( p_sys->arib.p_instance ); arib_instance_destroy( p_sys->arib.p_instance );
#endif #endif
if ( p_sys->arib.b25stream )
{
p_sys->arib.b25stream->p_source = NULL; /* don't chain kill demuxer's source */
stream_Delete( p_sys->arib.b25stream );
}
vlc_mutex_destroy( &p_sys->csa_lock ); vlc_mutex_destroy( &p_sys->csa_lock );
free( p_sys ); free( p_sys );
} }
...@@ -960,7 +971,7 @@ static int Demux( demux_t *p_demux ) ...@@ -960,7 +971,7 @@ static int Demux( demux_t *p_demux )
if( p_sys->b_start_record ) if( p_sys->b_start_record )
{ {
/* Enable recording once synchronized */ /* Enable recording once synchronized */
stream_Control( p_demux->s, STREAM_SET_RECORD_STATE, true, "ts" ); stream_Control( p_sys->stream, STREAM_SET_RECORD_STATE, true, "ts" );
p_sys->b_start_record = false; p_sys->b_start_record = false;
} }
...@@ -1059,9 +1070,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1059,9 +1070,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
int64_t i_time, i_length; int64_t i_time, i_length;
if( !DVBEventInformation( p_demux, &i_time, &i_length ) && i_length > 0 ) if( !DVBEventInformation( p_demux, &i_time, &i_length ) && i_length > 0 )
*pf = (double)i_time/(double)i_length; *pf = (double)i_time/(double)i_length;
else if( (i64 = stream_Size( p_demux->s) ) > 0 ) else if( (i64 = stream_Size( p_sys->stream) ) > 0 )
{ {
int64_t offset = stream_Tell( p_demux->s ); int64_t offset = stream_Tell( p_sys->stream );
*pf = (double)offset / (double)i64; *pf = (double)offset / (double)i64;
} }
...@@ -1081,8 +1092,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1081,8 +1092,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
(p_sys->b_dvb_meta && p_sys->b_access_control) || (p_sys->b_dvb_meta && p_sys->b_access_control) ||
p_sys->i_last_pcr - p_sys->i_first_pcr <= 0 ) p_sys->i_last_pcr - p_sys->i_first_pcr <= 0 )
{ {
i64 = stream_Size( p_demux->s ); i64 = stream_Size( p_sys->stream );
if( stream_Seek( p_demux->s, (int64_t)(i64 * f) ) ) if( stream_Seek( p_sys->stream, (int64_t)(i64 * f) ) )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
else else
...@@ -1188,17 +1199,17 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1188,17 +1199,17 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
*va_arg( args, int* ) = 0; /* Title offset */ *va_arg( args, int* ) = 0; /* Title offset */
*va_arg( args, int* ) = 0; /* Chapter offset */ *va_arg( args, int* ) = 0; /* Chapter offset */
return stream_Control( p_demux->s, STREAM_GET_TITLE_INFO, v, c ); return stream_Control( p_sys->stream, STREAM_GET_TITLE_INFO, v, c );
} }
case DEMUX_SET_TITLE: case DEMUX_SET_TITLE:
return stream_vaControl( p_demux->s, STREAM_SET_TITLE, args ); return stream_vaControl( p_sys->stream, STREAM_SET_TITLE, args );
case DEMUX_SET_SEEKPOINT: case DEMUX_SET_SEEKPOINT:
return stream_vaControl( p_demux->s, STREAM_SET_SEEKPOINT, args ); return stream_vaControl( p_sys->stream, STREAM_SET_SEEKPOINT, args );
case DEMUX_GET_META: case DEMUX_GET_META:
return stream_vaControl( p_demux->s, STREAM_GET_META, args ); return stream_vaControl( p_sys->stream, STREAM_GET_META, args );
case DEMUX_CAN_RECORD: case DEMUX_CAN_RECORD:
pb_bool = (bool*)va_arg( args, bool * ); pb_bool = (bool*)va_arg( args, bool * );
...@@ -1209,12 +1220,12 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1209,12 +1220,12 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
b_bool = (bool)va_arg( args, int ); b_bool = (bool)va_arg( args, int );
if( !b_bool ) if( !b_bool )
stream_Control( p_demux->s, STREAM_SET_RECORD_STATE, false ); stream_Control( p_sys->stream, STREAM_SET_RECORD_STATE, false );
p_sys->b_start_record = b_bool; p_sys->b_start_record = b_bool;
return VLC_SUCCESS; return VLC_SUCCESS;
case DEMUX_GET_SIGNAL: case DEMUX_GET_SIGNAL:
return stream_vaControl( p_demux->s, STREAM_GET_SIGNAL, args ); return stream_vaControl( p_sys->stream, STREAM_GET_SIGNAL, args );
default: default:
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -1371,7 +1382,7 @@ static int SetPIDFilter( demux_t *p_demux, int i_pid, bool b_selected ) ...@@ -1371,7 +1382,7 @@ static int SetPIDFilter( demux_t *p_demux, int i_pid, bool b_selected )
if( !p_sys->b_access_control ) if( !p_sys->b_access_control )
return VLC_EGENERIC; return VLC_EGENERIC;
return stream_Control( p_demux->s, STREAM_SET_PRIVATE_ID_STATE, return stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_STATE,
i_pid, b_selected ); i_pid, b_selected );
} }
...@@ -1989,7 +2000,7 @@ static block_t* ReadTSPacket( demux_t *p_demux ) ...@@ -1989,7 +2000,7 @@ static block_t* ReadTSPacket( demux_t *p_demux )
block_t *p_pkt; block_t *p_pkt;
/* Get a new TS packet */ /* Get a new TS packet */
if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) ) if( !( p_pkt = stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
{ {
msg_Dbg( p_demux, "eof ?" ); msg_Dbg( p_demux, "eof ?" );
return NULL; return NULL;
...@@ -2012,7 +2023,7 @@ static block_t* ReadTSPacket( demux_t *p_demux ) ...@@ -2012,7 +2023,7 @@ static block_t* ReadTSPacket( demux_t *p_demux )
const uint8_t *p_peek; const uint8_t *p_peek;
int i_peek, i_skip = 0; int i_peek, i_skip = 0;
i_peek = stream_Peek( p_demux->s, &p_peek, i_peek = stream_Peek( p_sys->stream, &p_peek,
p_sys->i_packet_size * 10 ); p_sys->i_packet_size * 10 );
if( i_peek < p_sys->i_packet_size + 1 ) if( i_peek < p_sys->i_packet_size + 1 )
{ {
...@@ -2030,14 +2041,14 @@ static block_t* ReadTSPacket( demux_t *p_demux ) ...@@ -2030,14 +2041,14 @@ static block_t* ReadTSPacket( demux_t *p_demux )
i_skip++; i_skip++;
} }
msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip ); msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip );
stream_Read( p_demux->s, NULL, i_skip ); stream_Read( p_sys->stream, NULL, i_skip );
if( i_skip < i_peek - p_sys->i_packet_size ) if( i_skip < i_peek - p_sys->i_packet_size )
{ {
break; break;
} }
} }
if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) ) if( !( p_pkt = stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
{ {
msg_Dbg( p_demux, "eof ?" ); msg_Dbg( p_demux, "eof ?" );
return NULL; return NULL;
...@@ -2054,7 +2065,7 @@ static mtime_t AdjustPCRWrapAround( demux_t *p_demux, mtime_t i_pcr ) ...@@ -2054,7 +2065,7 @@ static mtime_t AdjustPCRWrapAround( demux_t *p_demux, mtime_t i_pcr )
* So, need to add 0x1FFFFFFFF, for calculating duration or current position. * So, need to add 0x1FFFFFFFF, for calculating duration or current position.
*/ */
mtime_t i_adjust = 0; mtime_t i_adjust = 0;
int64_t i_pos = stream_Tell( p_demux->s ); int64_t i_pos = stream_Tell( p_sys->stream );
int i; int i;
for( i = 1; i < p_sys->i_pcrs_num && p_sys->p_pos[i] <= i_pos; ++i ) for( i = 1; i < p_sys->i_pcrs_num && p_sys->p_pos[i] <= i_pos; ++i )
{ {
...@@ -2092,16 +2103,16 @@ static int SeekToPCR( demux_t *p_demux, int64_t i_pos ) ...@@ -2092,16 +2103,16 @@ static int SeekToPCR( demux_t *p_demux, int64_t i_pos )
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
mtime_t i_pcr = -1; mtime_t i_pcr = -1;
const int64_t i_initial_pos = stream_Tell( p_demux->s ); const int64_t i_initial_pos = stream_Tell( p_sys->stream );
if( i_pos < 0 ) if( i_pos < 0 )
return VLC_EGENERIC; return VLC_EGENERIC;
int64_t i_last_pos = stream_Size( p_demux->s ) - p_sys->i_packet_size; int64_t i_last_pos = stream_Size( p_sys->stream ) - p_sys->i_packet_size;
if( i_pos > i_last_pos ) if( i_pos > i_last_pos )
i_pos = i_last_pos; i_pos = i_last_pos;
if( stream_Seek( p_demux->s, i_pos ) ) if( stream_Seek( p_sys->stream, i_pos ) )
return VLC_EGENERIC; return VLC_EGENERIC;
while( vlc_object_alive( p_demux ) ) while( vlc_object_alive( p_demux ) )
...@@ -2119,13 +2130,13 @@ static int SeekToPCR( demux_t *p_demux, int64_t i_pos ) ...@@ -2119,13 +2130,13 @@ static int SeekToPCR( demux_t *p_demux, int64_t i_pos )
block_Release( p_pkt ); block_Release( p_pkt );
if( i_pcr >= 0 ) if( i_pcr >= 0 )
break; break;
if( stream_Tell( p_demux->s ) >= i_last_pos ) if( stream_Tell( p_sys->stream ) >= i_last_pos )
break; break;
} }
if( i_pcr < 0 ) if( i_pcr < 0 )
{ {
stream_Seek( p_demux->s, i_initial_pos ); stream_Seek( p_sys->stream, i_initial_pos );
assert( i_initial_pos == stream_Tell( p_demux->s ) ); assert( i_initial_pos == stream_Tell( p_sys->stream ) );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -2137,7 +2148,7 @@ static int Seek( demux_t *p_demux, double f_percent ) ...@@ -2137,7 +2148,7 @@ static int Seek( demux_t *p_demux, double f_percent )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
int64_t i_initial_pos = stream_Tell( p_demux->s ); int64_t i_initial_pos = stream_Tell( p_sys->stream );
mtime_t i_initial_pcr = p_sys->i_current_pcr; mtime_t i_initial_pcr = p_sys->i_current_pcr;
/* /*
...@@ -2158,7 +2169,7 @@ static int Seek( demux_t *p_demux, double f_percent ) ...@@ -2158,7 +2169,7 @@ static int Seek( demux_t *p_demux, double f_percent )
break; break;
} }
i_head_pos = p_sys->p_pos[i-1]; i_head_pos = p_sys->p_pos[i-1];
i_tail_pos = ( i < p_sys->i_pcrs_num ) ? p_sys->p_pos[i] : stream_Size( p_demux->s ); i_tail_pos = ( i < p_sys->i_pcrs_num ) ? p_sys->p_pos[i] : stream_Size( p_sys->stream );
} }
msg_Dbg( p_demux, "Seek():i_head_pos:%"PRId64", i_tail_pos:%"PRId64, i_head_pos, i_tail_pos); msg_Dbg( p_demux, "Seek():i_head_pos:%"PRId64", i_tail_pos:%"PRId64, i_head_pos, i_tail_pos);
...@@ -2193,7 +2204,7 @@ static int Seek( demux_t *p_demux, double f_percent ) ...@@ -2193,7 +2204,7 @@ static int Seek( demux_t *p_demux, double f_percent )
if( !b_found ) if( !b_found )
{ {
msg_Dbg( p_demux, "Seek():cannot find a time position. i_cnt:%d", i_cnt ); msg_Dbg( p_demux, "Seek():cannot find a time position. i_cnt:%d", i_cnt );
stream_Seek( p_demux->s, i_initial_pos ); stream_Seek( p_sys->stream, i_initial_pos );
p_sys->i_current_pcr = i_initial_pcr; p_sys->i_current_pcr = i_initial_pcr;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -2208,9 +2219,9 @@ static void GetFirstPCR( demux_t *p_demux ) ...@@ -2208,9 +2219,9 @@ static void GetFirstPCR( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
int64_t i_initial_pos = stream_Tell( p_demux->s ); int64_t i_initial_pos = stream_Tell( p_sys->stream );
if( stream_Seek( p_demux->s, 0 ) ) if( stream_Seek( p_sys->stream, 0 ) )
return; return;
while( vlc_object_alive (p_demux) ) while( vlc_object_alive (p_demux) )
...@@ -2232,17 +2243,17 @@ static void GetFirstPCR( demux_t *p_demux ) ...@@ -2232,17 +2243,17 @@ static void GetFirstPCR( demux_t *p_demux )
if( p_sys->i_first_pcr >= 0 ) if( p_sys->i_first_pcr >= 0 )
break; break;
} }
stream_Seek( p_demux->s, i_initial_pos ); stream_Seek( p_sys->stream, i_initial_pos );
} }
static void GetLastPCR( demux_t *p_demux ) static void GetLastPCR( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
const int64_t i_initial_pos = stream_Tell( p_demux->s ); const int64_t i_initial_pos = stream_Tell( p_sys->stream );
mtime_t i_initial_pcr = p_sys->i_current_pcr; mtime_t i_initial_pcr = p_sys->i_current_pcr;
int64_t i_stream_size = stream_Size( p_demux->s ); int64_t i_stream_size = stream_Size( p_sys->stream );
int64_t i_last_pos = i_stream_size - p_sys->i_packet_size; int64_t i_last_pos = i_stream_size - p_sys->i_packet_size;
/* Round i_pos to a multiple of p_sys->i_packet_size */ /* Round i_pos to a multiple of p_sys->i_packet_size */
int64_t i_pos = i_last_pos - p_sys->i_packet_size * 4500; /* FIXME if the value is not reasonable, please change it. */ int64_t i_pos = i_last_pos - p_sys->i_packet_size * 4500; /* FIXME if the value is not reasonable, please change it. */
...@@ -2259,12 +2270,12 @@ static void GetLastPCR( demux_t *p_demux ) ...@@ -2259,12 +2270,12 @@ static void GetLastPCR( demux_t *p_demux )
if( SeekToPCR( p_demux, i_pos ) ) if( SeekToPCR( p_demux, i_pos ) )
break; break;
p_sys->i_last_pcr = AdjustPCRWrapAround( p_demux, p_sys->i_current_pcr ); p_sys->i_last_pcr = AdjustPCRWrapAround( p_demux, p_sys->i_current_pcr );
if( ( i_pos = stream_Tell( p_demux->s ) ) >= i_last_pos ) if( ( i_pos = stream_Tell( p_sys->stream ) ) >= i_last_pos )
break; break;
} }
if( p_sys->i_last_pcr >= 0 ) if( p_sys->i_last_pcr >= 0 )
{ {
int64_t i_size = stream_Size( p_demux->s ); int64_t i_size = stream_Size( p_sys->stream );
mtime_t i_duration_msec = ( p_sys->i_last_pcr - p_sys->i_first_pcr ) * 100 / 9 / 1000; mtime_t i_duration_msec = ( p_sys->i_last_pcr - p_sys->i_first_pcr ) * 100 / 9 / 1000;
int64_t i_rate = ( i_size < 0 || i_duration_msec <= 0 ) ? 0 : i_size * 1000 * 8 / i_duration_msec; int64_t i_rate = ( i_size < 0 || i_duration_msec <= 0 ) ? 0 : i_size * 1000 * 8 / i_duration_msec;
const int64_t TS_SUPPOSED_MAXRATE = 55 * 1000 * 1000; //FIXME I think it's enough. const int64_t TS_SUPPOSED_MAXRATE = 55 * 1000 * 1000; //FIXME I think it's enough.
...@@ -2276,8 +2287,8 @@ static void GetLastPCR( demux_t *p_demux ) ...@@ -2276,8 +2287,8 @@ static void GetLastPCR( demux_t *p_demux )
p_sys->i_last_pcr = -1; p_sys->i_last_pcr = -1;
} }
} }
stream_Seek( p_demux->s, i_initial_pos ); stream_Seek( p_sys->stream, i_initial_pos );
assert( i_initial_pos == stream_Tell( p_demux->s ) ); assert( i_initial_pos == stream_Tell( p_sys->stream ) );
p_sys->i_current_pcr = i_initial_pcr; p_sys->i_current_pcr = i_initial_pcr;
} }
...@@ -2285,10 +2296,10 @@ static void CheckPCR( demux_t *p_demux ) ...@@ -2285,10 +2296,10 @@ static void CheckPCR( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
int64_t i_initial_pos = stream_Tell( p_demux->s ); int64_t i_initial_pos = stream_Tell( p_sys->stream );
mtime_t i_initial_pcr = p_sys->i_current_pcr; mtime_t i_initial_pcr = p_sys->i_current_pcr;
int64_t i_size = stream_Size( p_demux->s ); int64_t i_size = stream_Size( p_sys->stream );
int i = 0; int i = 0;
p_sys->p_pcrs[0] = p_sys->i_first_pcr; p_sys->p_pcrs[0] = p_sys->i_first_pcr;
...@@ -2303,7 +2314,7 @@ static void CheckPCR( demux_t *p_demux ) ...@@ -2303,7 +2314,7 @@ static void CheckPCR( demux_t *p_demux )
if( SeekToPCR( p_demux, i_pos ) ) if( SeekToPCR( p_demux, i_pos ) )
break; break;
p_sys->p_pcrs[i] = p_sys->i_current_pcr; p_sys->p_pcrs[i] = p_sys->i_current_pcr;
p_sys->p_pos[i] = stream_Tell( p_demux->s ); p_sys->p_pos[i] = stream_Tell( p_sys->stream );
if( p_sys->p_pcrs[i-1] > p_sys->p_pcrs[i] ) if( p_sys->p_pcrs[i-1] > p_sys->p_pcrs[i] )
{ {
msg_Dbg( p_demux, "PCR Wrap Around found between %d%% and %d%% (pcr:%"PRId64"(0x%09"PRIx64") pcr:%"PRId64"(0x%09"PRIx64"))", msg_Dbg( p_demux, "PCR Wrap Around found between %d%% and %d%% (pcr:%"PRId64"(0x%09"PRIx64") pcr:%"PRId64"(0x%09"PRIx64"))",
...@@ -2316,7 +2327,7 @@ static void CheckPCR( demux_t *p_demux ) ...@@ -2316,7 +2327,7 @@ static void CheckPCR( demux_t *p_demux )
p_sys->b_force_seek_per_percent = true; p_sys->b_force_seek_per_percent = true;
} }
stream_Seek( p_demux->s, i_initial_pos ); stream_Seek( p_sys->stream, i_initial_pos );
p_sys->i_current_pcr = i_initial_pcr; p_sys->i_current_pcr = i_initial_pcr;
} }
...@@ -4769,10 +4780,21 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_pmt ) ...@@ -4769,10 +4780,21 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_pmt )
} }
/* Set CAM descrambling */ /* Set CAM descrambling */
if( !ProgramIsSelected( p_demux, prg->i_number ) if( !ProgramIsSelected( p_demux, prg->i_number ) )
|| stream_Control( p_demux->s, STREAM_SET_PRIVATE_ID_CA, {
dvbpsi_DeletePMT( p_pmt );
}
else if( stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_CA,
p_pmt ) != VLC_SUCCESS ) p_pmt ) != VLC_SUCCESS )
{
if ( p_sys->arib.e_mode == ARIBMODE_ENABLED )
{
p_sys->arib.b25stream = stream_FilterNew( p_demux->s, "aribcam" );
p_sys->stream = ( p_sys->arib.b25stream ) ? p_sys->arib.b25stream : p_demux->s;
if (!p_sys->arib.b25stream)
dvbpsi_DeletePMT( p_pmt ); dvbpsi_DeletePMT( p_pmt );
} else dvbpsi_DeletePMT( p_pmt );
}
for( int i = 0; i < i_clean; i++ ) for( int i = 0; i < i_clean; i++ )
{ {
......
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