Hi Erik,

Well it's been over a year, but I think I have finally gotten this
working in a way that I am happy with.

On Sun, 15 May 2016 21:55:17 +0200
Erik Massop <e...@ixsop.nl> wrote:

> I don't know how heavy your plugin is, but since you want to run your
> code for every track, maybe it's worthwhile to split out the file type
> detection into a separate and more lightweight plugin.

As it turns out, I had to do this anyway in order for the priorities to
work as expected (see below).  I needed my plugin to support more than
one input type, so I required a separate file type detection plugin to
handle the 'application/octet-stream' MIME type and produce MIME types
for all the formats that the main plugin can handle.  This allowed me
to set priorities on individual file formats rather than for the plugin
as a whole.

> > Is it possible for this behaviour to be changed, so that all plugins
> > that handle a given format are tried until a chain is successfully set
> > up, instead of only the highest priority one?  
> 
> Probably, if you implement it :).

This is now implemented!  I sent it as a pull request on GitHub.  Not
sure if that is 'the new way' but happy to put it on Mantis if you'd
prefer.

  https://github.com/xmms2/xmms2-devel/pull/3

If you have the xmms2 git repo cloned locally from GitHub, you can
check out the changes like so:

  git pull origin pull/3/head:xform-priority
  git checkout xform-priority

> If I remember correctly the priority system originally was to allow
> multiple plugins to handle the same format, for instance vorbis vs
> tremor and mpg123 vs mad. When only one of the clashing plugins was
> installed, that one would be used, otherwise the priority system would
> pick the one with highest priority.

The way I have implemented the change will work like this.  However I
ran into one main unforeseen challenge, which I think I have solved.

Take these xform chains for example: (the names are partly made up, but
the priority is in brackets and important)

  file(50):magic(50):mad(50)
  file(50):magic(50):libvorbis(50)
  file(50):example(40):mpg123(40)
  file(50):example(40):ogg123(60)

In this case, the user wants mad(50) instead of mpg123(40).  This is
fine, because magic(50) comes before example(40).  However the user
wants ogg123(60) instead of libvorbis(50).  You might think that ogg123
having a higher priority of 60 would address this, but it does not,
because magic(50) comes before example(40).  Once magic runs, it finds
libvorbis, a goal chain is created, and then libvorbis is always used
instead of ogg123, even though it's a lower priority.

The problem is that the priority of the intermediate xforms (that the
user generally does not care about) can ultimately control which goal
xform gets used.

Making example(40) a higher priority will fix this problem, but it will
cause the reverse problem with mpg123(40) being used in preference to
mad(50).

So using priority numbers alone, the user will encounter situations
where their preferred plugins cannot be used for at least some formats.

To fix this, my proposed patch considers the priority in two separate
ways.  First, when building a chain it builds it in order of priority,
so the highest priority xforms are tried first, and if those don't
work, the next highest one is tried.

However, when a goal xform is found, and a full chain is created, this
chain is stored and the priority of the final xform in the chain is
assigned to the whole chain.  The xform search continues, and if
another full chain is built, the priority of the final xform is
compared, and the new chain replaces the old one if its final xform is
higher priority.

This sounds complicated, but it means that the priority of most xform
plugins only controls the order in which they are assembled when
building a chain, and the priority of goal xforms actually controls
which chains are used for final playback.

This fixes the above example, with mad(50) being used before
mpg123(40), and ogg123(60) being used before libvorbis(50), regardless
of the priority of the other xforms in the chain.

I have been testing the changes for a couple of weeks now, and it seems
to work fine for everything I have tested it with.

One new requirement is that all xforms must be capable of seeking back
to the start of the data.  This is because xform A might read some data
when examining the file, but xform B also needs to read that data, so a
rewind is needed in between xform construction attempts.

I have included a more detailed explanation in the form of some user
documentation in the pull request, so hopefully that will also explain
some of my thinking.  You can see it in the PR or in a nicely formatted
GitHub page here:

  
https://github.com/Malvineous/xmms2-devel/blob/a5d5839cfc77ba1e9299a67466a59ac4c2cd3e93/doc/user/priorities.md

Let me know if you have any questions, and hopefully you will consider
including this patch in XMMS2!

Cheers,
Adam.

--
_______________________________________________
Xmms2-devel mailing list
Xmms2-devel@lists.xmms2.org
https://lists.xmms2.org/cgi-bin/mailman/listinfo/xmms2-devel

Reply via email to