Commit 069f260a authored by Laurent Aimar's avatar Laurent Aimar

Fixed input slave reading of a52/dts/flac/m4a/mpga (close #1818).

Input slave method needs that PCR of master and slave input use the same origin.
parent b1cea0a3
...@@ -66,6 +66,9 @@ struct demux_sys_t ...@@ -66,6 +66,9 @@ struct demux_sys_t
/* Packetizer */ /* Packetizer */
decoder_t *p_packetizer; decoder_t *p_packetizer;
mtime_t i_pts;
mtime_t i_time_offset;
int i_mux_rate; int i_mux_rate;
bool b_big_endian; bool b_big_endian;
}; };
...@@ -73,7 +76,8 @@ struct demux_sys_t ...@@ -73,7 +76,8 @@ struct demux_sys_t
static int CheckSync( const uint8_t *p_peek, bool *p_big_endian ); static int CheckSync( const uint8_t *p_peek, bool *p_big_endian );
#define PCM_FRAME_SIZE (1536 * 4) #define PCM_FRAME_SIZE (1536 * 4)
#define A52_PACKET_SIZE (4 * PCM_FRAME_SIZE) #define A52_PACKET_SIZE (1024)
#define A52_PEEK_SIZE (4 * PCM_FRAME_SIZE)
#define A52_PROBE_SIZE (512*1024) #define A52_PROBE_SIZE (512*1024)
#define A52_MAX_HEADER_SIZE 10 #define A52_MAX_HEADER_SIZE 10
...@@ -109,7 +113,7 @@ static int Open( vlc_object_t * p_this ) ...@@ -109,7 +113,7 @@ static int Open( vlc_object_t * p_this )
/* Some A52 wav files don't begin with a sync code so we do a more /* Some A52 wav files don't begin with a sync code so we do a more
* extensive search */ * extensive search */
int i_size = stream_Peek( p_demux->s, &p_peek, i_peek + A52_PACKET_SIZE * 2); int i_size = stream_Peek( p_demux->s, &p_peek, i_peek + A52_PEEK_SIZE * 2);
i_size -= (PCM_FRAME_SIZE + A52_MAX_HEADER_SIZE); i_size -= (PCM_FRAME_SIZE + A52_MAX_HEADER_SIZE);
while( i_peek < i_size ) while( i_peek < i_size )
...@@ -150,6 +154,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -150,6 +154,8 @@ static int Open( vlc_object_t * p_this )
p_sys->b_start = true; p_sys->b_start = true;
p_sys->i_mux_rate = 0; p_sys->i_mux_rate = 0;
p_sys->b_big_endian = b_big_endian; p_sys->b_big_endian = b_big_endian;
p_sys->i_pts = 0;
p_sys->i_time_offset = 0;
/* Load the A52 packetizer */ /* Load the A52 packetizer */
INIT_APACKETIZER( p_sys->p_packetizer, 'a', '5', '2', ' ' ); INIT_APACKETIZER( p_sys->p_packetizer, 'a', '5', '2', ' ' );
...@@ -233,6 +239,11 @@ static int Demux( demux_t *p_demux ) ...@@ -233,6 +239,11 @@ static int Demux( demux_t *p_demux )
p_sys->i_mux_rate = p_sys->i_mux_rate =
p_block_out->i_buffer * INT64_C(1000000)/p_block_out->i_length; p_block_out->i_buffer * INT64_C(1000000)/p_block_out->i_length;
} }
p_sys->i_pts = p_block_out->i_pts;
/* Correct timestamp */
p_block_out->i_pts += p_sys->i_time_offset;
p_block_out->i_dts += p_sys->i_time_offset;
/* set PCR */ /* set PCR */
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
...@@ -252,21 +263,39 @@ static int Demux( demux_t *p_demux ) ...@@ -252,21 +263,39 @@ static int Demux( demux_t *p_demux )
static int Control( demux_t *p_demux, int i_query, va_list args ) static int Control( demux_t *p_demux, int i_query, va_list args )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
if( i_query == DEMUX_SET_TIME ) bool *pb_bool;
{ int64_t *pi64;
return VLC_EGENERIC; int i_ret;
}
else if( i_query == DEMUX_HAS_UNSUPPORTED_META ) switch( i_query )
{ {
bool *pb_bool = (bool*)va_arg( args, bool* ); case DEMUX_HAS_UNSUPPORTED_META:
pb_bool = (bool*)va_arg( args, bool* );
*pb_bool = true; *pb_bool = true;
return VLC_SUCCESS; return VLC_SUCCESS;
}
else case DEMUX_GET_TIME:
{ pi64 = (int64_t*)va_arg( args, int64_t * );
return demux_vaControlHelper( p_demux->s, *pi64 = p_sys->i_pts + p_sys->i_time_offset;
return VLC_SUCCESS;
case DEMUX_SET_TIME: /* TODO implement a high precicsion seek */
default:
i_ret = demux_vaControlHelper( p_demux->s,
0, -1, 0, -1,
8*p_sys->i_mux_rate, 1, i_query, args ); 8*p_sys->i_mux_rate, 1, i_query, args );
if( !i_ret && p_sys->i_mux_rate > 0 &&
( i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME ) )
{
const int64_t i_time = INT64_C(1000000) * stream_Tell(p_demux->s) /
p_sys->i_mux_rate;
/* Fix time_offset */
if( i_time >= 0 )
p_sys->i_time_offset = i_time - p_sys->i_pts;
}
return i_ret;
} }
} }
......
...@@ -62,6 +62,9 @@ struct demux_sys_t ...@@ -62,6 +62,9 @@ struct demux_sys_t
/* Packetizer */ /* Packetizer */
decoder_t *p_packetizer; decoder_t *p_packetizer;
mtime_t i_pts;
mtime_t i_time_offset;
int i_mux_rate; int i_mux_rate;
}; };
...@@ -156,6 +159,9 @@ static int Open( vlc_object_t * p_this ) ...@@ -156,6 +159,9 @@ static int Open( vlc_object_t * p_this )
} }
DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys; DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys;
p_sys->i_mux_rate = 0;
p_sys->i_pts = 0;
p_sys->i_time_offset = 0;
INIT_APACKETIZER( p_sys->p_packetizer, 'd','t','s',' ' ); INIT_APACKETIZER( p_sys->p_packetizer, 'd','t','s',' ' );
LOAD_PACKETIZER_OR_FAIL( p_sys->p_packetizer, "DTS" ); LOAD_PACKETIZER_OR_FAIL( p_sys->p_packetizer, "DTS" );
...@@ -214,6 +220,10 @@ static int Demux( demux_t *p_demux ) ...@@ -214,6 +220,10 @@ static int Demux( demux_t *p_demux )
p_block_out->i_buffer * INT64_C(1000000) / p_block_out->i_length; p_block_out->i_buffer * INT64_C(1000000) / p_block_out->i_length;
} }
/* Correct timestamp */
p_block_out->i_pts += p_sys->i_time_offset;
p_block_out->i_dts += p_sys->i_time_offset;
/* set PCR */ /* set PCR */
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
...@@ -232,12 +242,40 @@ static int Demux( demux_t *p_demux ) ...@@ -232,12 +242,40 @@ static int Demux( demux_t *p_demux )
static int Control( demux_t *p_demux, int i_query, va_list args ) static int Control( demux_t *p_demux, int i_query, va_list args )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
if( i_query == DEMUX_SET_TIME ) bool *pb_bool;
return VLC_EGENERIC; int64_t *pi64;
else int i_ret;
return demux_vaControlHelper( p_demux->s,
switch( i_query )
{
case DEMUX_HAS_UNSUPPORTED_META:
pb_bool = (bool*)va_arg( args, bool* );
*pb_bool = true;
return VLC_SUCCESS;
case DEMUX_GET_TIME:
pi64 = (int64_t*)va_arg( args, int64_t * );
*pi64 = p_sys->i_pts + p_sys->i_time_offset;
return VLC_SUCCESS;
case DEMUX_SET_TIME: /* TODO implement a high precicsion seek */
default:
i_ret = demux_vaControlHelper( p_demux->s,
0, -1, 0, -1,
8*p_sys->i_mux_rate, 1, i_query, args ); 8*p_sys->i_mux_rate, 1, i_query, args );
if( !i_ret && p_sys->i_mux_rate > 0 &&
( i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME ) )
{
const int64_t i_time = INT64_C(1000000) * stream_Tell(p_demux->s) /
p_sys->i_mux_rate;
/* Fix time_offset */
if( i_time >= 0 )
p_sys->i_time_offset = i_time - p_sys->i_pts;
}
return i_ret;
}
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -230,13 +230,18 @@ static int Demux( demux_t *p_demux ) ...@@ -230,13 +230,18 @@ static int Demux( demux_t *p_demux )
p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out); p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out);
} }
p_sys->i_pts = p_block_out->i_dts;
/* Correct timestamp */
p_block_out->i_pts += p_sys->i_time_offset;
p_block_out->i_dts += p_sys->i_time_offset;
/* set PCR */ /* set PCR */
if( p_block_out->i_dts >= p_sys->i_pts_start ) if( p_block_out->i_dts >= p_sys->i_pts_start + p_sys->i_time_offset )
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
else else
es_out_Control( p_demux->out, ES_OUT_RESET_PCR ); es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
p_sys->i_pts = p_block_out->i_dts;
es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
p_block_out = p_next; p_block_out = p_next;
...@@ -309,7 +314,7 @@ static int ControlSetTime( demux_t *p_demux, int64_t i_time ) ...@@ -309,7 +314,7 @@ static int ControlSetTime( demux_t *p_demux, int64_t i_time )
p_sys->i_time_offset = p_sys->seekpoint[i]->i_time_offset - p_sys->i_pts; p_sys->i_time_offset = p_sys->seekpoint[i]->i_time_offset - p_sys->i_pts;
p_sys->i_pts_start = p_sys->i_pts+i_delta_time; p_sys->i_pts_start = p_sys->i_pts+i_delta_time;
es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, p_sys->p_es, p_sys->i_pts_start ); es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, p_sys->p_es, p_sys->i_pts_start + p_sys->i_time_offset );
} }
else else
{ {
......
...@@ -160,16 +160,20 @@ static int Demux( demux_t *p_demux) ...@@ -160,16 +160,20 @@ static int Demux( demux_t *p_demux)
&p_sys->p_packetizer->fmt_out); &p_sys->p_packetizer->fmt_out);
} }
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
p_block_out->p_next = NULL;
p_sys->i_pts = p_block_out->i_pts; p_sys->i_pts = p_block_out->i_pts;
if( p_sys->i_pts > M4A_PTS_START + INT64_C(500000) ) if( p_sys->i_pts > M4A_PTS_START + INT64_C(500000) )
p_sys->i_bitrate_avg = p_sys->i_bitrate_avg =
8*INT64_C(1000000)*p_sys->i_bytes/(p_sys->i_pts-M4A_PTS_START); 8*INT64_C(1000000)*p_sys->i_bytes/(p_sys->i_pts-M4A_PTS_START);
p_sys->i_bytes += p_block_out->i_buffer; p_sys->i_bytes += p_block_out->i_buffer;
/* Correct timestamp */
p_block_out->i_pts += p_sys->i_time_offset;
p_block_out->i_dts += p_sys->i_time_offset;
/* */
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
p_block_out = p_next; p_block_out = p_next;
......
...@@ -303,10 +303,14 @@ static int Demux( demux_t *p_demux ) ...@@ -303,10 +303,14 @@ static int Demux( demux_t *p_demux )
{ {
block_t *p_next = p_block_out->p_next; block_t *p_next = p_block_out->p_next;
p_sys->i_pts = p_block_out->i_pts;
/* Correct timestamp */
p_block_out->i_pts += p_sys->i_time_offset;
p_block_out->i_dts += p_sys->i_time_offset;
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
p_block_out->p_next = NULL;
p_sys->i_pts = p_block_out->i_pts;
es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
p_block_out = p_next; p_block_out = p_next;
...@@ -393,7 +397,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -393,7 +397,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
p_sys->i_bitrate_avg; p_sys->i_bitrate_avg;
/* Fix time_offset */ /* Fix time_offset */
if( i_time >= 0 ) p_sys->i_time_offset = i_time - p_sys->i_pts; if( i_time >= 0 )
p_sys->i_time_offset = i_time - p_sys->i_pts;
} }
return i_ret; return i_ret;
} }
......
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