[vlc-devel] [PATCH 1/5] vout: update the format after filters

Steve Lhomme robux4 at ycbcr.xyz
Tue Oct 20 16:15:37 CEST 2020


On 2020-10-20 16:04, Thomas Guillem wrote:
> 
> 
> On Tue, Oct 20, 2020, at 14:32, Romain Vimont wrote:
>> The vout is created first, based on the input format. Then filters
>> (filter_t) could be added, possibly producing pictures in a different
>> format.
>>
>>        input ---> filters --->    MISMATCH    [I420] vout
>>              I420         RGBA
>>
>> To avoid a mismatch between the output of the last filter and the
>> expected format of the vout input, a converter was added when necessary
>> to compensate:
>>
>>        input ---> filters ---> converter ---> [I420] vout
>>              I420         RGBA           I420
>>
>> But this was often a waste, and it caused problems for opaque formats.
>>
>> Instead, request the vout to adapt itself to the actual format produced
>> by the last filter. If it can, we can avoid an additional converter.
>>
>>        input ---> filters --->    MISMATCH    [I420] vout
>>              I420         RGBA
>>
>>        input ---> filters ------------------> [RGBA] vout
>>              I420         RGBA
>>
>> If the vout does not support the new format (or does not accept to
>> update its format), a converter is still added as before.
> 
> Thanks for this patch set. That is exactly what we decided in a past workshop (the push one?).
> 

>>   static void ThreadChangeFilters(vout_thread_sys_t *vout)
>>   {
>>       vout_thread_sys_t *sys = vout;
>> @@ -1043,13 +1071,28 @@ static void
>> ThreadChangeFilters(vout_thread_sys_t *vout)
>>       }
>>   
>>       if (!es_format_IsSimilar(p_fmt_current, &fmt_target)) {
>> -        msg_Dbg(&vout->obj, "Adding a filter to compensate for format
>> changes");
>> -        if (filter_chain_AppendConverter(sys->filter.chain_interactive,
>> -                                         &fmt_target) != 0) {
>> -            msg_Err(&vout->obj, "Failed to compensate for the format
>> changes, removing all filters");
>> -            ThreadDelAllFilterCallbacks(vout);
>> -            filter_chain_Reset(sys->filter.chain_static,
>> &fmt_target, vctx_target, &fmt_target);
>> -            filter_chain_Reset(sys->filter.chain_interactive,
>> &fmt_target, vctx_target, &fmt_target);
>> +        msg_Dbg(&vout->obj, "Changing vout format to %4.4s",
>> +                            (const char *)
>> &p_fmt_current->video.i_chroma);
>> +
>> +        int ret = ThreadRequestVoutFormatChange(vout,
>> &p_fmt_current->video,
>> +                                                vctx_current,
>> +                                                &fmt_target.video);
>> +        if (ret == VLC_SUCCESS)
>> +            fmt_target.i_codec = fmt_target.video.i_chroma;
>> +        else
>> +            msg_Dbg(&vout->obj, "Changing vout format to %4.4s failed",
>> +                                (const char *)
>> &p_fmt_current->video.i_chroma);
>> +
>> +        if (!es_format_IsSimilar(p_fmt_current, &fmt_target))
>> +        {
>> +            msg_Dbg(&vout->obj, "Adding a filter to compensate for
>> format changes");
>> +            if
>> (filter_chain_AppendConverter(sys->filter.chain_interactive,
>> +                                             &fmt_target) != 0) {
>> +                msg_Err(&vout->obj, "Failed to compensate for the
>> format changes, removing all filters");
>> +                ThreadDelAllFilterCallbacks(vout);
>> +                filter_chain_Reset(sys->filter.chain_static,
>> &fmt_target, vctx_target, &fmt_target);
>> +                filter_chain_Reset(sys->filter.chain_interactive,
>> &fmt_target, vctx_target, &fmt_target);
>> +            }
> 
> What about destroying and recreating the vout if it can't handle an update?

Yes, we also agreed it would be best. Although this one can be done 
without the other one being done (yet).


More information about the vlc-devel mailing list