[PATCH v6 5/5] winegstreamer: Replace source pad interface with GstAppSrc.

Derek Lesho dlesho at codeweavers.com
Tue Sep 28 03:08:06 CDT 2021


On 9/28/21 07:23, Zebediah Figura (she/her) wrote:
> On 9/24/21 14:23, Derek Lesho wrote:
>>
>> On 9/24/21 12:38, Zebediah Figura wrote:
>>> On 9/24/21 3:05 AM, Derek Lesho wrote:
>>>> On 9/21/21 13:02, Zebediah Figura wrote:
>>>>
>>>>>
>>>>>
>>>>> 1. Rely on the fact that seek-data is sent during a seek, and use it
>>>>> to effectively invalidate any buffers sent before the seek. Unlike 
>>>>> the
>>>>> aforementioned problem with validation, this will actually work: at
>>>>> the time that seek-data is sent appsrc should be flushing, so any
>>>>> buffers we send before it will be discarded by appsrc, and any 
>>>>> buffers
>>>>> we send afterward can be discarded by us if they aren't valid. 
>>>>> This is
>>>>> very fragile, though. There's really no reason for appsrc to send
>>>>> seek-data for random-access streams in the first place, and this kind
>>>>> of synchronization is easy to get wrong if I haven't already.
>>>>
>>>> This sounds like the best way forward in my opinion, how is it 
>>>> fragile?
>>>
>>> It's fragile in general because we're making a lot of assumptions, 
>>> that aren't documented, about when and from which thread gstappsrc 
>>> will send these signals, and what synchronization guarantees it 
>>> applies when doing so.
>>
>> My perspective is that if we can get it working, documenting the two 
>> required quirks to the GStreamer project, eventually the problem will 
>> be be cleared up and/or fixed, and we can remove the quirks then.
>
> The problem is that we're still going to have to keep those 
> workarounds for a long time. Not to mention that clearly filing a bug 
> is not enough to get the attention of the GStreamer developers.
>
> As the maintainer of this code, I don't think I feel very comfortable 
> relying this much on the internals of appsrc, whether as workarounds 
> or not.
>
>>
>>>
>>>> It seems that if we just ensure that a pushed buffer takes into 
>>>> account
>>>> the latest seek/need data pair, not much can go wrong.
>>>>
>>>
>>> That's not enough by itself. We can, generally speaking, send a 
>>> buffer after a seek-data/need-data is triggered but before it is 
>>> actually sent. 
>> Before what is sent?
>
> Before the seek-data or need-data signal is sent. There is a window 
> there, however short.

I'm not sure exactly what the difference between triggering a signal and 
sending a signal is, but assuming you mean that if seek-data doesn't 
acquire the mutex, it would be possible to push-buffer to not see the 
seek, then send the buffer after seek-data, then yeah, we do need to put 
seek-data and push-buffer in the same mutex to make sure that 
push-buffer is responding to the latest seek/need data callbacks.

>
>>> This happens in practice with flushes.
>>>
>>> In order to get around that, you need the hack I mentioned: assume 
>>> that a flush will be accompanied by a seek-data signal. This is 
>>> especially fragile because there's no reason for appsrc to even be 
>>> sending this signal in the first place (it only really makes sense 
>>> in "seekable" mode), and they could easily decide to not do that.
>>
>> I'm not sure I understand, whenever the next buffer app source wants 
>> is not consecutively after the last, seek-data is required (and 
>> sent). What does "assume the flush will be accompanied by a seek-data 
>> signal" mean?  The app source client doesn't have any conception of a 
>> flush, just seek-data and need-data, and to fix this problem all we 
>> need to do is add a quite rational check that push_data is responding 
>> to the latest seek/need data pair.
>
> Let me try to explain more clearly. At least one race, the one I've 
> been trying to describe, looks like this:
>
>
> read thread         main thread
> -------------------------------------
>                     push seek event
> retrieve data
> validate offset
>                     send flush-start
>                     emit seek-data
>                     send flush-stop
> push-buffer
>
>
> At which point appsrc will get the wrong buffer.
>
> Solution 1 has us rely on the seek-data signal to effectively wait for 
> the read thread (most likely using the parser mutex) and, in a sense, 
> put a barrier between reads occuring before and after the flush.


I mean, yeah, but from the perspective of the interface, all we are 
doing is making sure that buffers that are responding to requests from 
before a seek-data don't get sent, which I really don't think should be 
too controversial.  That the seek happens to be caused by a flush 
shouldn't matter, we're putting a barrier between buffers sent for a 
different offset, and the current offset we've gotten from seek-data.  
Honestly, I'm not even sure this is a GStreamer bug, should they really 
have to handle a case where the client responds with an incorrect buffer 
after a seek?





More information about the wine-devel mailing list