Provide a backtrace of the leaked region with valgrind. And yes, who knows.Any help how i can catch it ?
Is it possible for the leak to be in libdvbpsi ?
Yes, I can remove teh enable optimize memory flag and rebuild and try again, however, I think it will just verify that the problem is still there as I have observed this behaviour prior to rebuilding with enable optimize memory.Can you remove the --enable-optimize-memory and try again?
Can you provide a full valgrind log and post it here or send it to me by mail?
Yes, I had gathered that, and when running this "for real" I'll be doing that, however, I wanted to see memory useage for the two different processes with one running the transcoding to mpeg4 part10 and the other not doing any transcoding at all.VLC only follows one RTP stream by default. You can increase the limit, but you will get two videos at the same time... Normally, you'd rather want to not send two streams to the same destination...
Darn, that's inconvenient! It's going to be hard to find a memory leak, then, if the tool that lets us find it takes up most of the cpu's time. Perhaps what is needed here is someone who has a latest greatest up to datest cpu running linux who can possibly try running these experiments to see if the problem is reproducible on their machine, and then, if so, run valgrind against vlc and hopefully have enough processing power to be able to do that as well as encode the mpeg4part10 video stream with vlc so that it can find the memory leak?valgrind is very CPU intensive, yes. I never managed to decode video under valgrind.
Code: Select all
/*****************************************************************************
* Mux: Call each time there is new data for at least one stream
*****************************************************************************
*
*****************************************************************************/
static int Mux( sout_mux_t *p_mux )
{
sout_mux_sys_t *p_sys = p_mux->p_sys;
ts_stream_t *p_pcr_stream;
if( p_sys->i_pcr_pid == 0x1fff )
{
int i;
for( i = 0; i < p_mux->i_nb_inputs; i++ )
{
block_FifoEmpty( p_mux->pp_inputs[i]->p_fifo );
}
msg_Dbg( p_mux, "waiting for PCR streams" );
msleep( 1000 );
return VLC_SUCCESS;
}
p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
for( ;; )
{
sout_buffer_chain_t chain_ts;
int i_packet_count;
int i_packet_pos;
mtime_t i_pcr_dts;
mtime_t i_pcr_length;
mtime_t i_shaping_delay;
int i, j;
if( p_pcr_stream->b_key_frame )
{
i_shaping_delay = p_pcr_stream->i_pes_length;
}
else
{
i_shaping_delay = p_sys->i_shaping_delay;
}
/* 1: get enough PES packet for all input */
for( ;; )
{
bool b_ok = true;
block_t *p_data;
/* Accumulate enough data in the pcr stream (>i_shaping_delay) */
/* Accumulate enough data in all other stream ( >= length of pcr)*/
for( i = -1; i < p_mux->i_nb_inputs; i++ )
{
sout_input_t *p_input;
ts_stream_t *p_stream;
int64_t i_spu_delay = 0;
if( i == -1 )
p_input = p_sys->p_pcr_input;
else if( p_mux->pp_inputs[i]->p_sys == p_pcr_stream )
continue;
else
p_input = p_mux->pp_inputs[i];
p_stream = (ts_stream_t*)p_input->p_sys;
if( ( ( p_stream == p_pcr_stream ) &&
( p_stream->i_pes_length < i_shaping_delay ) ) ||
( p_stream->i_pes_dts + p_stream->i_pes_length <
p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length ) )
{
for( j = 0; j < p_mux->i_nb_inputs; j++ )
{
if ( ( ( p_mux->pp_inputs[j]->p_fmt->i_cat == AUDIO_ES ) ||
( p_mux->pp_inputs[j]->p_fmt->i_cat == VIDEO_ES ) ) &&
block_FifoCount( p_mux->pp_inputs[j]->p_fifo ) > 1)
{
break;
}
}
if ( j == p_mux->i_nb_inputs )
{
/* We need more data */
return VLC_SUCCESS;
}
/* Need more data */
if( block_FifoCount( p_input->p_fifo ) <= 1 )
{
if( !(( p_input->p_fmt->i_cat == AUDIO_ES ) ||
( p_input->p_fmt->i_cat == VIDEO_ES )) &&
(block_FifoCount( p_input->p_fifo ) <= 0))
{
/* spu, only one packet is needed */
continue;
}
else if( p_input->p_fmt->i_cat == SPU_ES )
{
/* Don't mux the SPU yet if it is too early */
block_t *p_spu = block_FifoShow( p_input->p_fifo );
i_spu_delay =
p_spu->i_dts - p_pcr_stream->i_pes_dts;
if( ( i_spu_delay > i_shaping_delay ) &&
( i_spu_delay < INT64_C(100000000) ) )
continue;
if ( ( i_spu_delay >= INT64_C(100000000) ) ||
( i_spu_delay < INT64_C(10000) ) )
{
BufferChainClean( &p_stream->chain_pes );
p_stream->i_pes_dts = 0;
p_stream->i_pes_used = 0;
p_stream->i_pes_length = 0;
continue;
}
}
}
b_ok = false;
if( p_stream == p_pcr_stream || p_sys->b_data_alignment
|| p_input->p_fmt->i_codec !=
VLC_FOURCC('m', 'p', 'g', 'a') )
{
p_data = NULL;
if ( ( block_FifoCount( p_input->p_fifo ) > 0 ) ||
( p_input->p_fmt->i_cat == SPU_ES) )
{
p_data = block_FifoGet( p_input->p_fifo );
}
if( p_input->p_fmt->i_codec ==
VLC_FOURCC('m', 'p', '4', 'a' ) )
p_data = Add_ADTS( p_data, p_input->p_fmt );
}
else
p_data = FixPES( p_mux, p_input->p_fifo );
if (p_data)
{
if( block_FifoCount( p_input->p_fifo ) > 0 &&
p_input->p_fmt->i_cat != SPU_ES )
{
block_t *p_next = block_FifoShow( p_input->p_fifo );
p_data->i_length = p_next->i_dts - p_data->i_dts;
}
else if( p_input->p_fmt->i_codec !=
VLC_FOURCC('s', 'u', 'b', 't' ) )
p_data->i_length = 1000;
if( ( p_pcr_stream->i_pes_dts > 0 &&
p_data->i_dts - 10000000 > p_pcr_stream->i_pes_dts +
p_pcr_stream->i_pes_length ) ||
p_data->i_dts < p_stream->i_pes_dts ||
( p_stream->i_pes_dts > 0 &&
p_input->p_fmt->i_cat != SPU_ES &&
p_data->i_dts - 10000000 > p_stream->i_pes_dts +
p_stream->i_pes_length ) )
{
msg_Warn( p_mux, "packet with too strange dts "
"(dts=%"PRId64",old=%"PRId64",pcr=%"PRId64")",
p_data->i_dts, p_stream->i_pes_dts,
p_pcr_stream->i_pes_dts );
block_Release( p_data );
BufferChainClean( &p_stream->chain_pes );
p_stream->i_pes_dts = 0;
p_stream->i_pes_used = 0;
p_stream->i_pes_length = 0;
if( p_input->p_fmt->i_cat != SPU_ES )
{
BufferChainClean( &p_pcr_stream->chain_pes );
p_pcr_stream->i_pes_dts = 0;
p_pcr_stream->i_pes_used = 0;
p_pcr_stream->i_pes_length = 0;
}
}
else
{
int i_header_size = 0;
int b_data_alignment = 0;
if( p_input->p_fmt->i_cat == SPU_ES )
{
if( p_input->p_fmt->i_codec ==
VLC_FOURCC('s','u','b','t') )
{
/* Prepend header */
p_data = block_Realloc( p_data, 2,
p_data->i_buffer );
p_data->p_buffer[0] =
( (p_data->i_buffer - 2) >> 8) & 0xff;
p_data->p_buffer[1] =
( (p_data->i_buffer - 2) ) & 0xff;
/* remove trailling \0 if any */
if( p_data->i_buffer > 2 &&
p_data->p_buffer[p_data->i_buffer -1] ==
'\0' )
p_data->i_buffer--;
/* Append a empty sub (sub text only) */
if( p_data->i_length > 0 &&
!( p_data->i_buffer == 1 &&
*p_data->p_buffer == ' ' ) )
{
block_t *p_spu = block_New( p_mux, 3 );
p_spu->i_dts = p_spu->i_pts =
p_data->i_dts + p_data->i_length;
p_spu->i_length = 1000;
p_spu->p_buffer[0] = 0;
p_spu->p_buffer[1] = 1;
p_spu->p_buffer[2] = ' ';
EStoPES( p_mux->p_sout, &p_spu, p_spu,
p_input->p_fmt,
p_stream->i_stream_id, 1,
0, 0, 0 );
p_data->p_next = p_spu;
}
}
else if( p_input->p_fmt->i_codec ==
VLC_FOURCC('t','e','l','x') )
{
/* EN 300 472 */
i_header_size = 0x24;
b_data_alignment = 1;
}
else if( p_input->p_fmt->i_codec ==
VLC_FOURCC('d','v','b','s') )
{
/* EN 300 743 */
b_data_alignment = 1;
}
}
else if( p_data->i_length < 0 ||
p_data->i_length > 2000000 )
{
/* FIXME choose a better value, but anyway we
* should never have to do that */
p_data->i_length = 1000;
}
p_stream->i_pes_length += p_data->i_length;
if( p_stream->i_pes_dts == 0 )
{
p_stream->i_pes_dts = p_data->i_dts;
}
/* Convert to pes */
if( p_stream->i_stream_id == 0xa0 &&
p_data->i_pts <= 0 )
{
/* XXX yes I know, it's awful, but it's needed,
* so don't remove it ... */
p_data->i_pts = p_data->i_dts;
}
EStoPES ( p_mux->p_sout, &p_data, p_data,
p_input->p_fmt, p_stream->i_stream_id,
1, b_data_alignment, i_header_size, 0 );
BufferChainAppend( &p_stream->chain_pes, p_data );
if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
&& (p_data->i_flags & BLOCK_FLAG_TYPE_I)
&& !(p_data->i_flags & BLOCK_FLAG_NO_KEYFRAME)
&& (p_stream->i_pes_length > 400000) )
{
i_shaping_delay = p_stream->i_pes_length;
p_stream->b_key_frame = 1;
}
}
}
}
}
for( j = 0; j < p_mux->i_nb_inputs; j++ )
{
if ( ( ( p_mux->pp_inputs[j]->p_fmt->i_cat == AUDIO_ES ) ||
( p_mux->pp_inputs[j]->p_fmt->i_cat == VIDEO_ES ) ) &&
block_FifoCount( p_mux->pp_inputs[j]->p_fifo ) <= 1)
{
/* We need more data */
return VLC_SUCCESS;
}
}
if( b_ok )
{
break;
}
}
/* save */
i_pcr_dts = p_pcr_stream->i_pes_dts;
i_pcr_length = p_pcr_stream->i_pes_length;
p_pcr_stream->b_key_frame = 0;
/* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
/* 2: calculate non accurate total size of muxed ts */
i_packet_count = 0;
for( i = 0; i < p_mux->i_nb_inputs; i++ )
{
ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
block_t *p_pes;
/* False for pcr stream but it will be enough to do PCR algo */
for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL;
p_pes = p_pes->p_next )
{
int i_size = p_pes->i_buffer;
if( p_pes->i_dts + p_pes->i_length >
p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
{
mtime_t i_frag = p_pcr_stream->i_pes_dts +
p_pcr_stream->i_pes_length - p_pes->i_dts;
if( i_frag < 0 )
{
/* Next stream */
break;
}
i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
}
i_packet_count += ( i_size + 183 ) / 184;
}
}
/* add overhead for PCR (not really exact) */
i_packet_count += (8 * i_pcr_length / p_sys->i_pcr_delay + 175) / 176;
/* 3: mux PES into TS */
BufferChainInit( &chain_ts );
/* append PAT/PMT -> FIXME with big pcr delay it won't have enough pat/pmt */
GetPAT( p_mux, &chain_ts );
GetPMT( p_mux, &chain_ts );
i_packet_pos = 0;
i_packet_count += chain_ts.i_depth;
/* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
for( ;; )
{
int i_stream;
mtime_t i_dts;
ts_stream_t *p_stream;
sout_input_t *p_input;
block_t *p_ts;
bool b_pcr;
/* Select stream (lowest dts) */
for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
{
p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
if( p_stream->i_pes_dts == 0 )
{
continue;
}
if( i_stream == -1 ||
p_stream->i_pes_dts < i_dts )
{
i_stream = i;
i_dts = p_stream->i_pes_dts;
}
}
if( i_stream == -1 || i_dts > i_pcr_dts + i_pcr_length )
{
break;
}
p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
p_input = p_mux->pp_inputs[i_stream];
/* do we need to issue pcr */
b_pcr = false;
if( p_stream == p_pcr_stream &&
i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >=
p_sys->i_pcr + p_sys->i_pcr_delay )
{
b_pcr = true;
p_sys->i_pcr = i_pcr_dts + i_packet_pos *
i_pcr_length / i_packet_count;
}
/* Build the TS packet */
p_ts = TSNew( p_mux, p_stream, b_pcr );
if( p_sys->csa != NULL &&
(p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) &&
(p_input->p_fmt->i_cat != VIDEO_ES || p_sys->b_crypt_video) )
{
p_ts->i_flags |= BLOCK_FLAG_SCRAMBLED;
}
i_packet_pos++;
/* */
BufferChainAppend( &chain_ts, p_ts );
}
/* 4: date and send */
TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
}
}
Return to “VLC stream-output (sout)”
Users browsing this forum: No registered users and 4 guests