This is similar to https://gitlab.winehq.org/wine/wine/-/merge_requests/2684, https://gitlab.winehq.org/wine/wine/-/merge_requests/3004 or https://gitlab.winehq.org/wine/wine/-/merge_requests/3139 but it validates the session transform node behavior with tests.
The tests are added after the changes because they otherwise don't pass and making them pass would be unnecessarily complicated.
I also have some local tests for MF_TOPONODE_WORKQUEUE_ID attributes and how it is supposed to behave. It basically creates new serialized work queues for every source node and assign them to every node downstream. Any sample request or processing operation is done in the associated queue.
When joining streams, queues are assigned downstream one after another and the last assigned queue is used when requesting samples upstream, but when samples are received and processed downstream it looks like the current queue of the source node is used for every downstream operations.
The request behavior seems to be the same when work queues are used, with round robin input requests, and single ProcessInput call followed by ProcessOutput loop until it fails.
This is yet not optimally efficient, and could be improved, for the following reasons:
1) All session operations are serialized together, even unrelated streams, and ProcessInput / ProcessOutput calls may be costly and stalling the pipeline. I believe that native probably allows parallel processing of unrelated stream requests, this needs to be confirmed.
2) MFT_MESSAGE_COMMAND_DRAIN message use isn't ideal, the message forces the transform to process all queued input synchronously, which can take a long time. I haven't checked exactly what native does but I believe it instead uses MFT_MESSAGE_NOTIFY_END_OF_STREAM messages, which would allow us to notify and drain the GStreamer decoder asynchronously.
3) MFT_MESSAGE_COMMAND_DRAIN also doesn't distinguish between input streams and needs to be sent globally. It's unclear how it should be used when multiple input streams are involved, and when one stream ends its segment then start a new segment while other streams don't have yet reached EOS. MFT_MESSAGE_NOTIFY_END_OF_STREAM messages have a stream ID parameter and would be more appropriate to handle separate input streams independently.
-- v3: mf/tests: Add more media session transform tests with multiple inputs. mf/tests: Add more media session transform tests with multiple outputs. mf/tests: Add some media session transform call pattern tests. mf/session: Increase the stream request count when requests are already queued. mf/session: Request more samples from upstream when necessary. mf/session: Push transform input samples one by one to ProcessInput. mf/session: Use helpers to push and pop samples for transform streams. mf/session: Flush requests in transform_node_deliver_samples when drained. mf/session: Use a helper to deliver transform node requested samples. mf/session: Use local variables to access transform node streams.