Commit 482db580 authored by François Cartegnie's avatar François Cartegnie 🤞

demux: adaptive: rework commands dequeuing (fix #18499)

could not cope with badly muxed late audio
(high dts<->pcr delay)
parent dee5abc1
......@@ -276,33 +276,62 @@ mtime_t CommandsQueue::Process( es_out_t *out, mtime_t barrier )
mtime_t lastdts = barrier;
bool b_datasent = false;
/* We need to filter the current commands list
We need to return on discontinuity or reset events if data was sent
We must lookup every packet until end or PCR matching barrier,
because packets of multiple stream can arrive delayed (with intermidiate pcr)
ex: for a target time of 2, you must dequeue <= 2 until >= PCR2
A0,A1,A2,B0,PCR0,B1,B2,PCR2,B3,A3,PCR3
*/
std::list<AbstractCommand *> output;
std::list<AbstractCommand *> in;
vlc_mutex_lock(&lock);
while( !commands.empty() && commands.front()->getTime() <= barrier )
in.splice( in.end(), commands );
while( !in.empty() )
{
AbstractCommand *command = commands.front();
/* We need to have PCR set for stream before Deleting ES,
* or it will get stuck if any waiting decoder buffer */
if(command->getType() == ES_OUT_PRIVATE_COMMAND_DEL && b_datasent)
AbstractCommand *command = in.front();
if( command->getType() == ES_OUT_PRIVATE_COMMAND_DEL && b_datasent )
break;
if(command->getType() == ES_OUT_PRIVATE_COMMAND_DISCONTINUITY && b_datasent)
if( command->getType() == ES_OUT_PRIVATE_COMMAND_DISCONTINUITY && b_datasent )
break;
if(command->getType() == ES_OUT_PRIVATE_COMMAND_SEND)
{
lastdts = command->getTime();
b_datasent = true;
}
if(command->getType() == ES_OUT_SET_GROUP_PCR && command->getTime() > barrier )
break;
commands.pop_front();
command->Execute( out );
delete command;
in.pop_front();
b_datasent = true;
if( command->getType() == ES_OUT_PRIVATE_COMMAND_SEND && command->getTime() > barrier )
commands.push_back( command );
else
output.push_back( command );
}
pcr = lastdts;
/* push remaining ones if broke above */
commands.splice( commands.end(), in );
if(commands.empty() && b_draining)
b_draining = false;
/* Now execute our selected commands */
while( !output.empty() )
{
AbstractCommand *command = output.front();
output.pop_front();
if( command->getType() == ES_OUT_PRIVATE_COMMAND_SEND )
lastdts = command->getTime();
command->Execute( out );
delete command;
}
pcr = lastdts; /* Warn! no PCR update/lock release until execution */
vlc_mutex_unlock(&lock);
return lastdts;
......
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