PWojnar
PWojnar

Reputation: 121

Mplayer in slave mode - multiple instances

I am developing a Qt application that is showing various media. Currently there is an issue with video files. As there were some problems in using Phonon with ATI graphic card acceleration, we are currently using mplayer with vaapi in slave mode.

There is however an issue with loading the files. Every time the new file is going to be shown, mplayer takes some time (about 2 seconds) to load it, showing only black screen. As most of the files is rather short (10 - 25 seconds) it is quite noticeable. The first question is - does anybody knows how to tell mplayer to start loading one file while playing the previous one? Is it possible?

The second one: I was thinking of creating two instances of mplayer, telling one to load the first file and the other to load the second one then telling the second one to pause. After the first file is finished I would unpause the second one. I am using QProcesses but right now the second mplayer won't start before the second one finishes, even if I am not pausing it. In the code below, player1 and player2 are QProcess objects, and player2 won't start doing anything before player1 is finished. All "readyRead ..." slots are my functions for parsing mplayer output. So far they don't do much, just print the output to qDebug().

Do you have any idea why aren't the two processes starting together? It works ok if I use for example mplayer in player1 and vlc in player2 and I can run two mplayer instances from the command line.

bool Player::run(){
    QStringList args;
    args << "-va" << "vaapi" << "-vo" << "vaapi:gl" << "-noborder" << "-framedrop" << "-v" << "-slave" << "-idle";
    connect(&player1, SIGNAL(readyReadStandardError()), this, SLOT(readyReadErr1()));
    connect(&player1, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadOut1()));
    connect(&player2, SIGNAL(readyReadStandardError()), this, SLOT(readyReadErr2()));
    connect(&player2, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadOut2()));
    player1.start("mplayer", args << "-geometry" << "860x540+0+0");
    player2.start("mplayer", args << "-geometry" << "860x540+800+500");
    player1.write("loadfile w_1.avi 1\n");
    player2.write("loadfile w_2.avi 1\n");

    if (!player1.waitForStarted(5000))
    {
        return false;
    }
    player2.waitForStarted(5000);

    player1.waitForFinished(50000);

    player2.waitForFinished(10000);
    return true;
}        

Upvotes: 2

Views: 2297

Answers (1)

Aktau
Aktau

Reputation: 1917

I don't know if you have found a solution for your problem in the meantime but I'm doing something similar from a bash script and starting multiple instances works just fine with backgrounding. The double mplayer trick is also nice, I think I might have to use that. Anyway, my bash hack after a few hours, but note that the FIFO is currently only created for one of them, I'm thinking of a good naming scheme:

#!/bin/bash

set -e

set -u

# add working directory to $PATH
export PATH=$(dirname "$0"):$PATH

res_tuple=($(xres.sh))
max_width="${res_tuple[0]}"
max_height="${res_tuple[1]}"

echo "w = $max_width, h = $max_height"

mplayer() {
  /home/player/Downloads/vaapi-mplayer/mplayer \
    -vo vaapi \
    -va vaapi \
    -fixed-vo \
    -nolirc \
    -slave \
    -input file="$5"\
    -idle \
    -quiet \
    -noborder \
    -geometry $1x$2+$3+$4 \
    { /home/player/Downloads/*.mov } \
    -loop 0 \
    > /dev/null 2>&1 &
}

mfifo() {
  pipe='/tmp/mplayer.pipe'

  if [[ ! -p $pipe ]]; then
    mkfifo $pipe
  fi
}

half_width=$(($max_width / 2))
half_height=$(($max_height / 2))

mfifo

mplayer $half_width $half_height 0 0 $pipe 
mplayer $half_width $half_height $half_width 0 $pipe
mplayer $half_width $half_height 0 $half_height $pipe
mplayer $half_width $half_height $half_width $half_height $pipe

Upvotes: 1

Related Questions