Page 1 of 1
Direct control of the decoder module
Posted: 24 Apr 2013 08:54
by giantdwarf76
Hello,
i would like to ask you a question about controlling the video decoder when using the libvlc directly. I created my own imem module as demux and access module and create a player with the libvlc_media_player_new_from_media api call. How can i access the decoder directly in order to flush the buffers for example? I have the case that my imem module kind of seeks in the stream which seems to confuse the decoder even that i pass him the BLOCK_FLAG_DISCONTINUITY flag. The effect is that it does not flush its buffers and starts to decode from the new i-frame but waits for a non deterministic amount of time before it calls the demux function of the imem module and decodes the new frame on base of old residuals. Thanks for your help.
versions:
main libvlc VLC media player - 2.1.0-git Rincewind
main libvlc revision 1.3.0-git-5380-g5e6fcec
Re: Direct control of the decoder module
Posted: 24 Apr 2013 11:53
by funman
Hello,
libvlc doesn't permit direct access to the decoder module afaik, imem is a libvlccore module, not libvlc (I think you know it already but it's important to say).
Do you have any source code to share?
Re: Direct control of the decoder module
Posted: 24 Apr 2013 11:54
by TypX
If your demux seeks by itself (without libvlc asking it). It should call ES_OUT_SET_PCR with a new PCR after the seek., this will most likely issue a RESET_PCR (you can call it by hand but it's not really advised for smoothness reasons).
Re: Direct control of the decoder module
Posted: 24 Apr 2013 13:43
by giantdwarf76
Here is the code from my imem module where i handle the incoming data. It is supposed to detect a discontinuity and should reset the decoder accordingly:
Code: Select all
static int Demux(demux_t *demux)
{
imem_sys_t *sys = (imem_sys_t*)demux->p_sys;
for (;;) {
int64_t dts, pts;
unsigned flags;
size_t buffer_size;
void *buffer;
if (sys->source.get(sys->source.data, sys->source.cookie,
&dts, &pts, &flags, &buffer_size, &buffer))
return 0;
if (dts < 0)
dts = pts;
if (buffer_size > 0) {
block_t *block = block_Alloc(buffer_size);
if (block) {
block->i_dts = dts >= 0 ? (1 + dts) : VLC_TS_INVALID;
block->i_pts = pts >= 0 ? (1 + pts) : VLC_TS_INVALID;
memcpy(block->p_buffer, buffer, buffer_size);
if (flags == 1)
{
msg_Dbg(demux,"seek detected (%s)", sys->source.cookie);
((imem_sys_t*)(vDemux->p_sys))->dts = VLC_TS_INVALID;//dts;
((imem_sys_t*)(aDemux->p_sys))->dts = VLC_TS_INVALID;//dts;
block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
es_out_Control(demux->out, ES_OUT_SET_PCR, block->i_dts);
es_out_Send(demux->out, sys->es, block);
}
else
{
//msg_Dbg(demux,"Set PCR to %lld (%s)",block->i_dts, sys->source.cookie);
es_out_Control(demux->out, ES_OUT_SET_PCR, block->i_dts);
es_out_Send(demux->out, sys->es, block);
}
}
}
sys->dts = dts;
sys->source.release(sys->source.data, sys->source.cookie,
buffer_size, buffer);
}
return 1;
}
Re: Direct control of the decoder module
Posted: 24 Apr 2013 15:18
by TypX
And what do the verbose logs say when you have the discontinuity?
If it doesn't work and you really want to restart buffering, you'll have to manually call ES_OUT_RESET_PCR.
Re: Direct control of the decoder module
Posted: 24 Apr 2013 16:04
by giantdwarf76
With the code posted before i get:
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 124992993, discontinuity
W/VLC ( 1306): [0x6817fe1c]: main input clock gap, unexpected stream discontinuity
W/VLC ( 1306): [0x6817fe1c]: main input feeding synchro with a new reference point trying to recover from clock gap
I/TRACE( 1306): Info imem video: pulled buffer with ts: 125000000, discontinuity
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 125016009
I/TRACE( 1306): Info imem video: pulled buffer with ts: 125042000
D/VLC ( 1306): [0x66f57d2c]: main decoder End of audio preroll
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 125039002
W/VLC ( 1306): [0x67654eb4]: main audio output playback way too early (-302217): playing silence
D/VLC ( 1306): [0x67654eb4]: main audio output inserting 13327 zeroes
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 125062993
I/TRACE( 1306): Info imem video: pulled buffer with ts: 125083000
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 125086009
I/TRACE( 1306): Info imem video: pulled buffer with ts: 125125000
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 125109002
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 125131995
I/TRACE( 1306): Info imem video: pulled buffer with ts: 125167000
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 125156009
I/TRACE( 1306): Info imem audio: pulled buffer with ts: 125179002
I/TRACE( 1306): Info imem video: pulled buffer with ts: 125208000
W/VLC ( 1306): [0x67654eb4]: main audio output playback too late (78355): up-sampling
D/VLC ( 1306): [0x67024a6c]: main decoder End of video preroll
i am going to try setting the ES_OUT_RESET_PCR. Thanx for the tip.
Re: Direct control of the decoder module
Posted: 25 Apr 2013 16:36
by giantdwarf76
It seems that i do not get the idea behind it. Now that i played around with several settings of the es_out:
- es_out_Control(demux->out, ES_OUT_RESET_PCR);
- es_out_Control(demux->out, ES_OUT_SET_GROUP_PCR, block->i_dts);
- es_out_Control(demux->out, ES_OUT_RESTART_ES,sys->es);
the video decoder still does not start at the next i-frame. Am i responsible for parsing the nul unit and feed only an i-frame after a seek?
so what i want to achieve is the following:
1 audio stream via imem
1 video stream via imem
both streams receive a discontinuity
the video shall start decoding and displaying with the next i-frame.
But what i see is that the decoded video is probably a p-frame as the displayed frame is concealed.
Can anybody tell me what i do miss here? Thanx in advance.
Re: Direct control of the decoder module
Posted: 25 Apr 2013 17:52
by giantdwarf76
Ok finally i understood it. I am responsible to pass next i-frame after resetting the PCR as i am the demuxer. Thank you all for your help.