[vlc-devel] [PATCH] demux: adaptive: workaround successive setPosition failed by flush EsOutAddCommand

Zhao Zhili quinkblack at foxmail.com
Wed Oct 18 03:51:08 CEST 2017


Hi Francois,


On 2017年10月18日 01:08, Francois Cartegnie wrote:
> Le 07/10/2017 à 08:03, Zhao Zhili a écrit :
>> ---
>>   modules/demux/adaptive/Streams.cpp                |  8 ++++++
>>   modules/demux/adaptive/plumbing/CommandsQueue.cpp | 33 +++++++++++++++++++++++
>>   modules/demux/adaptive/plumbing/CommandsQueue.hpp |  1 +
>>   3 files changed, 42 insertions(+)
>>
>> diff --git a/modules/demux/adaptive/Streams.cpp b/modules/demux/adaptive/Streams.cpp
>> index 96543d3187..d1e97df358 100644
>> --- a/modules/demux/adaptive/Streams.cpp
>> +++ b/modules/demux/adaptive/Streams.cpp
>> @@ -498,7 +498,15 @@ bool AbstractStream::setPosition(mtime_t time, bool tryonly)
>>               setTimeOffset(segmentTracker->getPlaybackTime());
>>   
>>               if( !restartDemux() )
>> +            {
>>                   dead = true;
>> +            }
>> +            else
>> +            {
>> +                /* To avoid a successive setPosition failed because fakeesout is restarting, we
>> +                 * flush EsOutAddCommand here. */
>> +                commandsqueue->flushAddCommand(p_realdemux->out);
>> +            }
>>           }
>>           else commandsqueue->Abort( true );
> I don't understand the issue.
>
> Since modifying commands queue is pretty risky and can easily break
> something and debugging then would take multiple hours,
> that needs a detailed explanation and test case.
>

The issue is like this:

1. AbstractStream::seekAble() check whether fakeesout->restarting()

bool AbstractStream::seekAble() const
{
     return (demuxer &&
             !fakeesout->restarting() &&
             !discontinuity &&
             !commandsqueue->isDraining() );
}

2. AbstractStream::setPosition() --> AbstractStream::restartDemux() -->
fakeesout->recycleAll()

3. If AbstractStream::setPosition() is called again before
FakeESOut::createOrRecycleRealEsID() is called for all es id,
fakeesout->restarting() is true and AbstractStream::seekAble() is false, so
AbstractStream::setPosition() is failed.

4. It's very easy to reproduce this issue by seek again and again, 
especially
for a slow network connection.

My solution is:

After AbstractStream::restartDemux() --> demuxer->create(), 
EsOutAddCommand is
pushed to CommandsQueue. Flush EsOutAddCommand will force
FakeESOut::createOrRecycleRealEsID() to be called. So it has a large 
chance to
prevent the next AbstractStream::seekAble() check fail.




More information about the vlc-devel mailing list