struct demux_sys_t
{
+ stream_t *stream;
+ bool b_canseek;
vlc_mutex_t csa_lock;
/* TS packet size (188, 192, 204) */
#ifdef HAVE_ARIBB24
arib_instance_t *p_instance;
#endif
+ stream_t *b25stream;
} arib;
/* All pid */
p_sys->i_dvb_start = 0;
p_sys->i_dvb_length = 0;
+ p_sys->arib.b25stream = NULL;
+ p_sys->stream = p_demux->s;
+
p_sys->b_broken_charset = false;
for( int i = 0; i < 8192; i++ )
p_sys->b_split_es = var_InheritBool( p_demux, "ts-split-es" );
+ p_sys->b_canseek = false;
p_sys->i_pid_ref_pcr = -1;
p_sys->i_first_pcr = -1;
p_sys->i_current_pcr = -1;
return VLC_ENOMEM;
}
- bool can_seek = false;
- stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &can_seek );
- if( can_seek )
- {
- GetFirstPCR( p_demux );
- CheckPCR( p_demux );
- GetLastPCR( p_demux );
- }
- if( p_sys->i_first_pcr < 0 || p_sys->i_last_pcr < 0 )
+ bool b_can_fastseek = false;
+ stream_Control( p_sys->stream, STREAM_CAN_SEEK, &p_sys->b_canseek );
+ stream_Control( p_sys->stream, STREAM_CAN_FASTSEEK, &b_can_fastseek );
+ if ( p_sys->b_canseek )
{
- msg_Dbg( p_demux, "Force Seek Per Percent: PCR's not found,");
- p_sys->b_force_seek_per_percent = true;
+ if( b_can_fastseek )
+ {
+ GetFirstPCR( p_demux );
+ CheckPCR( p_demux );
+ GetLastPCR( p_demux );
+ }
+
+ if( p_sys->i_first_pcr < 0 || p_sys->i_last_pcr < 0 )
+ {
+ msg_Dbg( p_demux, "Force Seek Per Percent: PCR's not found,");
+ p_sys->b_force_seek_per_percent = true;
+ }
}
while( p_sys->i_pmt_es <= 0 && vlc_object_alive( p_demux ) )
arib_instance_destroy( p_sys->arib.p_instance );
#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 );
free( p_sys );
}
if( p_sys->b_start_record )
{
/* 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;
}
int64_t i_time, i_length;
if( !DVBEventInformation( p_demux, &i_time, &i_length ) && i_length > 0 )
*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;
}
case DEMUX_SET_POSITION:
f = (double) va_arg( args, double );
+ if(!p_sys->b_canseek)
+ return VLC_EGENERIC;
+
if( p_sys->b_force_seek_per_percent ||
(p_sys->b_dvb_meta && p_sys->b_access_control) ||
p_sys->i_last_pcr - p_sys->i_first_pcr <= 0 )
{
- i64 = stream_Size( p_demux->s );
- if( stream_Seek( p_demux->s, (int64_t)(i64 * f) ) )
+ i64 = stream_Size( p_sys->stream );
+ if( stream_Seek( p_sys->stream, (int64_t)(i64 * f) ) )
return VLC_EGENERIC;
}
else
*va_arg( args, int* ) = 0; /* Title 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:
- return stream_vaControl( p_demux->s, STREAM_SET_TITLE, args );
+ return stream_vaControl( p_sys->stream, STREAM_SET_TITLE, args );
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:
- return stream_vaControl( p_demux->s, STREAM_GET_META, args );
+ return stream_vaControl( p_sys->stream, STREAM_GET_META, args );
case DEMUX_CAN_RECORD:
pb_bool = (bool*)va_arg( args, bool * );
b_bool = (bool)va_arg( args, int );
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;
return VLC_SUCCESS;
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:
return VLC_EGENERIC;
if( !p_sys->b_access_control )
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 );
}
block_Duplicate( p_block ) );
}
- if (!p_sys->b_trust_pcr)
+ if (!p_sys->b_trust_pcr && p_block->i_dts > VLC_TS_INVALID )
es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
- pid->i_owner_number, p_block->i_pts);
+ pid->i_owner_number, p_block->i_dts);
es_out_Send( p_demux->out, pid->es->id, p_block );
block_t *p_pkt;
/* 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 ?" );
return NULL;
const uint8_t *p_peek;
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 );
if( i_peek < p_sys->i_packet_size + 1 )
{
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 )
{
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 ?" );
return NULL;
* So, need to add 0x1FFFFFFFF, for calculating duration or current position.
*/
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;
for( i = 1; i < p_sys->i_pcrs_num && p_sys->p_pos[i] <= i_pos; ++i )
{
demux_sys_t *p_sys = p_demux->p_sys;
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 )
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 )
i_pos = i_last_pos;
- if( stream_Seek( p_demux->s, i_pos ) )
+ if( stream_Seek( p_sys->stream, i_pos ) )
return VLC_EGENERIC;
while( vlc_object_alive( p_demux ) )
block_Release( p_pkt );
if( i_pcr >= 0 )
break;
- if( stream_Tell( p_demux->s ) >= i_last_pos )
+ if( stream_Tell( p_sys->stream ) >= i_last_pos )
break;
}
if( i_pcr < 0 )
{
- stream_Seek( p_demux->s, i_initial_pos );
- assert( i_initial_pos == stream_Tell( p_demux->s ) );
+ stream_Seek( p_sys->stream, i_initial_pos );
+ assert( i_initial_pos == stream_Tell( p_sys->stream ) );
return VLC_EGENERIC;
}
{
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;
/*
break;
}
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);
if( !b_found )
{
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;
return VLC_EGENERIC;
}
{
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;
while( vlc_object_alive (p_demux) )
if( p_sys->i_first_pcr >= 0 )
break;
}
- stream_Seek( p_demux->s, i_initial_pos );
+ stream_Seek( p_sys->stream, i_initial_pos );
}
static void GetLastPCR( demux_t *p_demux )
{
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;
- 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;
/* 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. */
if( SeekToPCR( p_demux, i_pos ) )
break;
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;
}
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;
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.
p_sys->i_last_pcr = -1;
}
}
- stream_Seek( p_demux->s, i_initial_pos );
- assert( i_initial_pos == stream_Tell( p_demux->s ) );
+ stream_Seek( p_sys->stream, i_initial_pos );
+ assert( i_initial_pos == stream_Tell( p_sys->stream ) );
p_sys->i_current_pcr = i_initial_pcr;
}
{
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;
- int64_t i_size = stream_Size( p_demux->s );
+ int64_t i_size = stream_Size( p_sys->stream );
int i = 0;
p_sys->p_pcrs[0] = p_sys->i_first_pcr;
if( SeekToPCR( p_demux, i_pos ) )
break;
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] )
{
msg_Dbg( p_demux, "PCR Wrap Around found between %d%% and %d%% (pcr:%"PRId64"(0x%09"PRIx64") pcr:%"PRId64"(0x%09"PRIx64"))",
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;
}
i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
pid->i_cc = i_cc;
- if( pid->es->p_data && pid->es->fmt.i_cat != VIDEO_ES )
+ if( pid->es->p_data && pid->es->fmt.i_cat != VIDEO_ES &&
+ pid->es->fmt.i_cat != AUDIO_ES )
{
- /* Small video artifacts are usually better than
+ /* Small audio/video artifacts are usually better than
* dropping full frames */
pid->es->p_data->i_flags |= BLOCK_FLAG_CORRUPTED;
}
p_fmt->i_codec = VLC_CODEC_A52;
}
else if( (desc = PMTEsFindDescriptor( p_es, 0x7f ) ) && desc->i_length >= 2 &&
- desc->p_data[0] == 0x80)
+ PMTEsHasRegistration(p_demux, p_es, "Opus"))
{
OpusSetup(p_demux, desc->p_data, desc->i_length, p_fmt);
}
break;
}
}
- if ( i_arib_flags == 0b111 )
+ if ( i_arib_flags == 0x07 ) //0b111
p_sys->arib.e_mode = ARIBMODE_ENABLED;
}
}
/* Set CAM descrambling */
- if( !ProgramIsSelected( p_demux, prg->i_number )
- || stream_Control( p_demux->s, STREAM_SET_PRIVATE_ID_CA,
- p_pmt ) != VLC_SUCCESS )
+ if( !ProgramIsSelected( p_demux, prg->i_number ) )
+ {
dvbpsi_DeletePMT( p_pmt );
+ }
+ else if( stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_CA,
+ 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 );
+ } else dvbpsi_DeletePMT( p_pmt );
+ }
for( int i = 0; i < i_clean; i++ )
{