0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 12:02:23 +02:00

Make audio stream index handling saner in stream switching

The handling of audio stream numbering was handled in the stream
selection property was a total mess. The most important issue was
confusion between values used as index for demuxer->audio_streams[]
array (consistently stored in demuxer->audio->id) and values stored
in sh_audio->aid and used as "-aid N" option values. Now demuxer audio
switch control functions and demuxer_switch_audio() are supposed to
return the new value for the "-aid" option (internal MPEG demuxers
still don't; the demuxer requirement could perhaps be dropped as it
can be easily calculated afterwards). That is also the value
returned for the "switch_audio" property. The main changes are:

 - Make command.c mp_property_audio() consistently use and return the
   "-aid" values. Before it used that as input but the array index as
   output, with extra mess related to demuxer_switch_audio() return
   value. Don't modify the audio_id option field any more.

 - Make demuxer_switch_audio() always return "-aid" values (like it
   takes as input). There are two changes for this: picking this
   return value in case the demuxer doesn't support switching, and
   overriding demuxer return value (for internal MPEG demuxers).

 - Make demux_lavf return "-aid" values from DEMUXER_CTRL_SWITCH_AUDIO
   code. This isn't actually necessary because of the override part
   above.

Here's some history of the relevant behavior that I looked up:
* For most demuxers array index and "-aid" values are the same. At
  least demux_mkv, (some of?) the internal MPEG demuxers and demux_ogg
  have differed for a long time. demux_ogg doesn't matter because it
  doesn't support stream switching.
* Old code seemed to assume that demuxer_switch_audio() return value was
  array index, but this wasn't true at least for demux_mkv.
* In svn r19951 reimar mostly removed use of the return value.
* In r20162 ptt added mp_property_audio(). This set the global
  audio_id variable (-aid option value) to the return value of
  demuxer_switch_audio() and treated the global as the persistent
  value of the property, apparently assuming that it would be set to
  the "-aid" value, not array index. This was false for internal
  MPEG.
* In r30124 reimar changed the property code so that even though it
  still modified the option value it didn't use that as the value of
  the property any more; instead it incorrectly used the array index.
  This meant that for demux_mkv the return value didn't match -aid any
  more (though input still did, so setting the property and querying
  it didn't match as they used different value systems).
* In r31129 aurel made demux_lavf changes that resulted in its -aid
  and array index values no longer matching either. He didn't change
  the return value from audio switch when changing -aid, so it now
  matched array index only. The latter part didn't cause additional
  problems from r20162 though because either choice would have been
  broken anyway after r30124 as long as they weren't the same value.
This commit is contained in:
Uoti Urpala 2010-05-22 08:19:23 +03:00
parent e2f894852c
commit 90bedd0b87
3 changed files with 23 additions and 22 deletions

View File

@ -851,11 +851,10 @@ static int mp_property_balance(m_option_t *prop, int action, void *arg,
static int mp_property_audio(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
int current_id, tmp;
if (!mpctx->demuxer || !mpctx->demuxer->audio)
return M_PROPERTY_UNAVAILABLE;
current_id = mpctx->demuxer->audio->id;
current_id = mpctx->sh_audio ? mpctx->sh_audio->aid : -2;
switch (action) {
case M_PROPERTY_GET:
@ -901,21 +900,17 @@ static int mp_property_audio(m_option_t *prop, int action, void *arg,
tmp = *((int *) arg);
else
tmp = -1;
opts->audio_id = demuxer_switch_audio(mpctx->demuxer, tmp);
if (opts->audio_id == -2
|| (opts->audio_id > -1
&& mpctx->demuxer->audio->id != current_id && current_id != -2))
int new_id = demuxer_switch_audio(mpctx->demuxer, tmp);
if (new_id != current_id)
uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC);
if (opts->audio_id > -1 && mpctx->demuxer->audio->id != current_id) {
if (new_id != current_id && new_id >= 0) {
sh_audio_t *sh2;
sh2 = mpctx->demuxer->a_streams[mpctx->demuxer->audio->id];
if (sh2) {
sh2->ds = mpctx->demuxer->audio;
mpctx->sh_audio = sh2;
reinit_audio_chain(mpctx);
}
sh2->ds = mpctx->demuxer->audio;
mpctx->sh_audio = sh2;
reinit_audio_chain(mpctx);
}
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_TRACK=%d\n", opts->audio_id);
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_TRACK=%d\n", new_id);
return M_PROPERTY_OK;
default:
return M_PROPERTY_NOT_IMPLEMENTED;

View File

@ -737,14 +737,15 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
newid = pstreams[i];
}
}
if(i == curridx)
return DEMUXER_CTRL_NOTIMPL;
else
{
if (i == curridx) {
*(int *) arg = curridx;
return DEMUXER_CTRL_OK;
} else {
ds_free_packs(ds);
if(ds->id >= 0)
priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
*((int*)arg) = ds->id = newid;
ds->id = newid;
*(int *) arg = i < 0 ? -2 : i;
if(newid >= 0)
priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
return DEMUXER_CTRL_OK;

View File

@ -1407,10 +1407,15 @@ int demuxer_get_percent_pos(demuxer_t *demuxer)
int demuxer_switch_audio(demuxer_t *demuxer, int index)
{
int res = demux_control(demuxer, DEMUXER_CTRL_SWITCH_AUDIO, &index);
if (res == DEMUXER_CTRL_NOTIMPL)
index = demuxer->audio->id;
if (demuxer->audio->id >= 0)
demuxer->audio->sh = demuxer->a_streams[demuxer->audio->id];
if (res == DEMUXER_CTRL_NOTIMPL) {
struct sh_audio *sh_audio = demuxer->audio->sh;
return sh_audio ? sh_audio->aid : -2;
}
if (demuxer->audio->id >= 0) {
struct sh_audio *sh_audio = demuxer->a_streams[demuxer->audio->id];
demuxer->audio->sh = sh_audio;
index = sh_audio->aid; // internal MPEG demuxers don't set it right
}
else
demuxer->audio->sh = NULL;
return index;