azbox: rework cPlayback rmfp_player wrapper

it now actually plays something, but will need more love
This commit is contained in:
Stefan Seyfried
2012-11-16 23:42:45 +01:00
parent 75d4d5021b
commit fea8d10c36
2 changed files with 250 additions and 61 deletions

View File

@@ -1,15 +1,22 @@
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sstream> #include <sstream>
#include <pty.h>
#include <sys/poll.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <proc_tools.h>
#define FIFO_CMD "/tmp/rmfp.cmd" #define FIFO_CMD "/tmp/rmfp.cmd"
#define FIFO_IN "/tmp/rmfp.in" #define FIFO_IN "/tmp/rmfp.in"
#define FIFO_OUT "/tmp/rmfp.out" #define FIFO_OUT "/tmp/rmfp.out"
#define FIFO_EVENT "/tmp/rmfp.event" //#define FIFO_EVENT "/tmp/rmfp.event"
#include "playback.h" #include "playback.h"
@@ -19,34 +26,110 @@ extern "C"{
static const char * FILENAME = "playback_cs.cpp"; static const char * FILENAME = "playback_cs.cpp";
static bool open_success = false;
static int last_pos;
static time_t last_pos_time;
static time_t monotonic_ms(void)
{
struct timespec t;
time_t ret;
if (clock_gettime(CLOCK_MONOTONIC, &t))
{
perror("monotonic_ms clock_gettime");
return -1;
}
ret = ((t.tv_sec + 604800)& 0x01FFFFF) * 1000; /* avoid overflow */
ret += t.tv_nsec / 1000000;
return ret;
}
int cPlayback::rmfp_command(int cmd, int param, bool has_param, int reply_len)
{
char reply[100];
int ret = -1;
pthread_mutex_lock(&mutex);
dprintf(fd_cmd, "%i", cmd);
if (has_param)
dprintf(fd_in, "%i", param);
if (reply_len > 0)
{
int n = 0;
while (n <= 0)
n = read(fd_out, &reply, 100);
reply[reply_len - 1] = '\0';
ret = atoi(reply);
}
pthread_mutex_unlock(&mutex);
return ret;
}
void cPlayback::RuaThread() void cPlayback::RuaThread()
{ {
printf("Starting RUA thread\n"); printf("Starting RUA thread\n");
//Watch for the space at the end
std::string base = "rmfp_player -dram 1 -ve 1 -waitexit ";
std::string filename(mfilename);
std::string file = '"' + filename + '"';
std::string final = base + file;
if (setduration == 1 && mduration != 0)
{
//Watch for the space at the end
std::string base = "/usr/bin/rmfp_player -dram 1 -ve 1 -waitexit ";
std::string filename(mfilename);
std::string file = '"' + filename + '"';
std::string final = base + file;
if ( setduration == 1 && mduration != 0)
{
mduration *= 60000;
std::stringstream duration; std::stringstream duration;
duration << mduration; duration << (mduration * 60000);
final = base + "-duration " + duration.str() + " " + file; final = base + "-duration " + duration.str() + " " + file;
} }
system(final.c_str()); pid_t pid = 0;
int master;
pid = forkpty(&master, NULL, NULL, NULL);
if (! pid) {
execl("/bin/sh", "sh", "-c", final.c_str(), (char *)0);
perror("exec");
exit(0);
}
printf("Terminating RUA thread\n"); if (pid > 0) {
thread_active = 0; char *output=NULL;
playing = false; size_t n = 0;
eof_reached = 1; ssize_t len;
pthread_exit(NULL); FILE *f = fdopen(master, "r");
while ((len = getline(&output, &n, f)) != -1)
{
while (len > 0)
{
len--;
if (!isspace(output[len]))
break;
output[len] = '\0';
}
printf("rmfp: '%s'\n", output);
if (!strcmp(output, "Playback has started..."))
{
fd_cmd = open(FIFO_CMD, O_WRONLY);
fd_in = open(FIFO_IN, O_WRONLY);
playing = true;
printf("===================> playing = true\n");
}
else if (!strcmp(output, "End of file..."))
{
eof_reached = true;
printf("===================> eof_reached = true\n");
}
}
fclose(f);
int s;
while (waitpid(pid, &s, WNOHANG) > 0) {};
if (output)
free(output);
}
printf("Terminating RUA thread\n");
thread_active = 0;
playing = false;
eof_reached = 1;
pthread_exit(NULL);
} }
/* helper function to call the cpp thread loop */ /* helper function to call the cpp thread loop */
@@ -63,6 +146,7 @@ void* execute_rua_thread(void *c)
return NULL; return NULL;
} }
#if 0
void cPlayback::EventThread() void cPlayback::EventThread()
{ {
@@ -126,12 +210,13 @@ void* execute_event_thread(void *c)
{ {
cPlayback *obj=(cPlayback*)c; cPlayback *obj=(cPlayback*)c;
printf("Executing RUA Thread\n"); printf("Executing Event Thread\n");
obj->EventThread(); obj->EventThread();
return NULL; return NULL;
} }
#endif
//Used by Fileplay //Used by Fileplay
bool cPlayback::Open(playmode_t PlayMode) bool cPlayback::Open(playmode_t PlayMode)
@@ -148,18 +233,44 @@ bool cPlayback::Open(playmode_t PlayMode)
setduration = 1; setduration = 1;
} }
#if 0
while (access("/tmp/continue", R_OK))
sleep(1);
#endif
char c[2] = "0";
int i = 0;
for(;;)
{
proc_get("/proc/player", c, 2);
if (c[0] != '0')
break;
i++;
if (i > 10)
{
printf("player is not getting idle after 10 seconds!\n");
open_success = false;
return false;
}
sleep(1);
}
proc_put("/proc/player", "2", 2);
printf("%s:%s - PlayMode=%s\n", FILENAME, __FUNCTION__, aPLAYMODE[PlayMode]); printf("%s:%s - PlayMode=%s\n", FILENAME, __FUNCTION__, aPLAYMODE[PlayMode]);
//Making Fifo's for message pipes //Making Fifo's for message pipes
mknod(FIFO_CMD, S_IFIFO | 0666, 0); mknod(FIFO_CMD, S_IFIFO | 0666, 0);
mknod(FIFO_IN, S_IFIFO | 0666, 0); mknod(FIFO_IN, S_IFIFO | 0666, 0);
mknod(FIFO_OUT, S_IFIFO | 0666, 0); mknod(FIFO_OUT, S_IFIFO | 0666, 0);
mknod(FIFO_EVENT, S_IFIFO | 0666, 0); // mknod(FIFO_EVENT, S_IFIFO | 0666, 0);
//Open pipes we read from. The fd_in pipe will be created once test_rmfp has been started //Open pipes we read from. The fd_in pipe will be created once test_rmfp has been started
fd_out = open(FIFO_OUT, O_RDONLY | O_NONBLOCK); fd_out = open(FIFO_OUT, O_RDONLY | O_NONBLOCK);
fd_event = open(FIFO_EVENT, O_RDONLY | O_NONBLOCK); // fd_event = open(FIFO_EVENT, O_RDONLY | O_NONBLOCK);
open_success = true;
return 0; return 0;
} }
@@ -180,6 +291,10 @@ bool cPlayback::Start(char * filename, unsigned short vpid, int vtype, unsigned
printf("%s:%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d duration=%i\n", printf("%s:%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d duration=%i\n",
FILENAME, __FUNCTION__, filename, vpid, vtype, apid, ac3, duration); FILENAME, __FUNCTION__, filename, vpid, vtype, apid, ac3, duration);
if (!open_success)
return false;
eof_reached = 0;
//create playback path //create playback path
mAudioStream=0; mAudioStream=0;
mfilename = filename; mfilename = filename;
@@ -189,12 +304,15 @@ bool cPlayback::Start(char * filename, unsigned short vpid, int vtype, unsigned
printf("[movieplayer]: error creating file_thread! (out of memory?)\n"); printf("[movieplayer]: error creating file_thread! (out of memory?)\n");
ret = false; ret = false;
} }
#if 0
if (pthread_create(&event_thread, 0, execute_event_thread, this) != 0) if (pthread_create(&event_thread, 0, execute_event_thread, this) != 0)
{ {
printf("[movieplayer]: error creating file_thread! (out of memory?)\n"); printf("[movieplayer]: error creating file_thread! (out of memory?)\n");
ret = false; ret = false;
} }
#endif
while (! playing)
sleep(1);
return ret; return ret;
} }
@@ -204,20 +322,33 @@ bool cPlayback::Stop(void)
printf("%s:%s playing %d %d\n", FILENAME, __FUNCTION__, playing, thread_active); printf("%s:%s playing %d %d\n", FILENAME, __FUNCTION__, playing, thread_active);
if(playing==false && thread_active == 0) return false; if(playing==false && thread_active == 0) return false;
msg = KEY_COMMAND_QUIT_ALL; rmfp_command(KEY_COMMAND_QUIT_ALL, 0, false, 0);
dprintf(fd_cmd, "%i", msg);
if (pthread_join(rua_thread, NULL)) if (pthread_join(rua_thread, NULL))
{ {
printf("error joining rua thread\n"); printf("error joining rua thread\n");
} }
#if 0
if (pthread_join(event_thread, NULL)) if (pthread_join(event_thread, NULL))
{ {
printf("error joining event thread\n"); printf("error joining event thread\n");
} }
#endif
playing = false; playing = false;
if (open_success)
proc_put("/proc/player", "1", 2);
usleep(1000000);
if (fd_in > -1)
close(fd_in);
if (fd_cmd > -1)
close(fd_cmd);
if (fd_out > -1)
close(fd_out);
fd_in = -1;
fd_cmd = -1;
fd_out = -1;
return true; return true;
} }
@@ -225,9 +356,7 @@ bool cPlayback::SetAPid(unsigned short pid, bool /*ac3*/)
{ {
printf("%s:%s pid %i\n", FILENAME, __FUNCTION__, pid); printf("%s:%s pid %i\n", FILENAME, __FUNCTION__, pid);
if (pid != mAudioStream) { if (pid != mAudioStream) {
msg = KEY_COMMAND_SWITCH_AUDIO; rmfp_command(KEY_COMMAND_SWITCH_AUDIO, pid, true, 0);
dprintf(fd_cmd, "%i", msg);
dprintf(fd_in, "%i", pid);
mAudioStream = pid; mAudioStream = pid;
} }
return true; return true;
@@ -238,9 +367,12 @@ bool cPlayback::SetSPid(int pid)
printf("%s:%s pid %i\n", FILENAME, __FUNCTION__, pid); printf("%s:%s pid %i\n", FILENAME, __FUNCTION__, pid);
if(pid!=mSubStream) if(pid!=mSubStream)
{ {
rmfp_command(KEY_COMMAND_SWITCH_SUBS, pid, true, 0);
/*
msg = KEY_COMMAND_SWITCH_SUBS; msg = KEY_COMMAND_SWITCH_SUBS;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
dprintf(fd_in, "%i", pid); dprintf(fd_in, "%i", pid);
*/
mSubStream=pid; mSubStream=pid;
} }
return true; return true;
@@ -259,19 +391,29 @@ bool cPlayback::SetSpeed(int speed)
if (speed > 1 || speed < 0) if (speed > 1 || speed < 0)
{ {
rmfp_command(CUSTOM_COMMAND_TRICK_SEEK, speed, true, 0);
/*
msg = CUSTOM_COMMAND_TRICK_SEEK; msg = CUSTOM_COMMAND_TRICK_SEEK;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
dprintf(fd_in, "%i", speed); dprintf(fd_in, "%i", speed);
*/
} }
else if (speed == 0) else if (speed == 0)
{ {
rmfp_command(KEY_COMMAND_PAUSE, 0, false, 0);
/*
msg = KEY_COMMAND_PAUSE; msg = KEY_COMMAND_PAUSE;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
*/
} }
else else
{ {
rmfp_command(KEY_COMMAND_PLAY, 0, false, 0);
/*
msg = KEY_COMMAND_PLAY; msg = KEY_COMMAND_PLAY;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
_GetPosition();
*/
} }
// if (result != 0) // if (result != 0)
@@ -290,14 +432,38 @@ bool cPlayback::GetSpeed(int &/*speed*/) const
*/ return true; */ return true;
} }
int cPlayback::__GetPosition(void)
{
printf("cPlayback::_GetPosition()--->\n");
#if 0
struct pollfd pfd;
pfd.fd = fd_out;
pfd.events = POLLIN|POLLPRI;
pfd.revents = 0;
if (poll(&pfd, 1, 0) > 0)
while(read(fd_out, &timestring, 100) <= 0){};
#endif
last_pos = rmfp_command(CUSTOM_COMMAND_GETPOSITION, 0, false, 11);
last_pos_time = monotonic_ms();
printf("cPlayback::_GetPosition()<--- %d\n", last_pos);
return last_pos;
}
// in milliseconds // in milliseconds
bool cPlayback::GetPosition(int &position, int &duration) bool cPlayback::GetPosition(int &position, int &duration)
{ {
printf("%s:%s %d %d\n", FILENAME, __FUNCTION__, position, duration); printf("%s:%s pos %d dur %d play %d\n", FILENAME, __FUNCTION__, position, duration, playing);
//Azbox eof //Azbox eof
if (eof_reached == 1) if (eof_reached == 1)
{ {
if (setduration)
{
position = mduration;
duration = mduration;
return true;
}
position = -5; position = -5;
duration = -5; duration = -5;
return true; return true;
@@ -305,33 +471,34 @@ bool cPlayback::GetPosition(int &position, int &duration)
if(playing==false) return false; if(playing==false) return false;
//Position if (nPlaybackSpeed == 1 && setduration) {
char timestring[11]; time_t time_diff = monotonic_ms() - last_pos_time;
position = last_pos + time_diff;
msg = CUSTOM_COMMAND_GETPOSITION;
dprintf(fd_cmd, "%i", msg);
int n = 0;
while ( n <= 0 ) {
n = read(fd_out, &timestring, 100);
} }
timestring[10] = '\0'; else
position = atoi(timestring); position = __GetPosition();
if (setduration)
{
duration = mduration;
return true;
}
//Duration //Duration
int length; int length;
/*
char durationstring[11]; char durationstring[11];
msg = CUSTOM_COMMAND_GETLENGTH; msg = CUSTOM_COMMAND_GETLENGTH;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
n = 0; int n = 0;
while ( n <= 0 ) { while ( n <= 0 ) {
n = read(fd_out, &durationstring, 10); n = read(fd_out, &durationstring, 10);
} }
durationstring[10] = '\0'; durationstring[10] = '\0';
length = atoi(durationstring); length = atoi(durationstring);
*/
length = rmfp_command(CUSTOM_COMMAND_GETLENGTH, 0, false, 11);
if(length <= 0) { if(length <= 0) {
duration = duration+1000; duration = duration+1000;
} else { } else {
@@ -343,35 +510,44 @@ bool cPlayback::GetPosition(int &position, int &duration)
bool cPlayback::SetPosition(int position, bool absolute) bool cPlayback::SetPosition(int position, bool absolute)
{ {
printf("%s:%s %d\n", FILENAME, __FUNCTION__,position); printf("%s:%s %d playing %d\n", FILENAME, __FUNCTION__,position, playing);
if(playing==false) return false; if(playing==false) return false;
int seconds; int seconds = position / 1000;;
if (absolute == true) if (absolute == true)
{ {
rmfp_command(KEY_COMMAND_SEEK_TO_TIME, seconds, true, 0);
/*
msg = KEY_COMMAND_SEEK_TO_TIME; msg = KEY_COMMAND_SEEK_TO_TIME;
seconds = position / 1000; seconds = position / 1000;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
dprintf(fd_in, "%i", seconds); dprintf(fd_in, "%i", seconds);
*/
} }
else else
{ {
if (position > 0 ) if (position > 0 )
{ {
rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_FWD, seconds, true, 0);
/*
msg = CUSTOM_COMMAND_SEEK_RELATIVE_FWD; msg = CUSTOM_COMMAND_SEEK_RELATIVE_FWD;
seconds = position / 1000; seconds = position / 1000;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
dprintf(fd_in, "%i", seconds); dprintf(fd_in, "%i", seconds);
*/
} }
else if ( position < 0 ) else if ( position < 0 )
{ {
rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_BWD, seconds, true, 0);
/*
msg = CUSTOM_COMMAND_SEEK_RELATIVE_BWD; msg = CUSTOM_COMMAND_SEEK_RELATIVE_BWD;
seconds = position / 1000; seconds = position / 1000;
seconds *= -1; seconds *= -1;
printf("sending seconds %i\n", seconds); printf("sending seconds %i\n", seconds);
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
dprintf(fd_in, "%i", seconds); dprintf(fd_in, "%i", seconds);
*/
} }
} }
return true; return true;
@@ -382,8 +558,10 @@ void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t
printf("%s:%s\n", FILENAME, __FUNCTION__); printf("%s:%s\n", FILENAME, __FUNCTION__);
unsigned int audio_count = 0; unsigned int audio_count = 0;
char audio_countstring[3]; // char audio_countstring[3];
audio_count = rmfp_command(CUSTOM_COMMAND_AUDIO_COUNT, 0, false, 3);
/*
msg = CUSTOM_COMMAND_AUDIO_COUNT; msg = CUSTOM_COMMAND_AUDIO_COUNT;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
@@ -393,7 +571,7 @@ void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t
} }
audio_countstring[2] = '\0'; audio_countstring[2] = '\0';
audio_count = atoi(audio_countstring); audio_count = atoi(audio_countstring);
*/
*numpida = audio_count; *numpida = audio_count;
if (audio_count > 0 ) if (audio_count > 0 )
{ {
@@ -401,16 +579,17 @@ void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t
{ {
char streamidstring[11]; char streamidstring[11];
char audio_lang[21]; char audio_lang[21];
pthread_mutex_lock(&mutex);
msg = CUSTOM_COMMAND_GET_AUDIO_BY_ID; msg = CUSTOM_COMMAND_GET_AUDIO_BY_ID;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
dprintf(fd_in, "%i", audio_id); dprintf(fd_in, "%i", audio_id);
n = 0; int n = 0;
while ( n <= 0 ) { while ( n <= 0 ) {
n = read(fd_out, &streamidstring, 10); n = read(fd_out, &streamidstring, 10);
} }
read(fd_out, &audio_lang, 20); read(fd_out, &audio_lang, 20);
pthread_mutex_unlock(&mutex);
streamidstring[10] = '\0'; streamidstring[10] = '\0';
audio_lang[20] = '\0'; audio_lang[20] = '\0';
@@ -426,6 +605,8 @@ void cPlayback::FindAllSPids(int *spids, uint16_t *numpids, std::string *languag
printf("%s:%s\n", FILENAME, __FUNCTION__); printf("%s:%s\n", FILENAME, __FUNCTION__);
unsigned int spu_count = 0; unsigned int spu_count = 0;
spu_count = rmfp_command(CUSTOM_COMMAND_SUBS_COUNT, 0, false, 3);
/*
char spu_countstring[3]; char spu_countstring[3];
msg = CUSTOM_COMMAND_SUBS_COUNT; msg = CUSTOM_COMMAND_SUBS_COUNT;
@@ -437,7 +618,7 @@ void cPlayback::FindAllSPids(int *spids, uint16_t *numpids, std::string *languag
} }
spu_countstring[2] = '\0'; spu_countstring[2] = '\0';
spu_count = atoi(spu_countstring); spu_count = atoi(spu_countstring);
*/
*numpids = spu_count; *numpids = spu_count;
if (spu_count > 0 ) if (spu_count > 0 )
@@ -449,15 +630,17 @@ void cPlayback::FindAllSPids(int *spids, uint16_t *numpids, std::string *languag
char streamidstring[11]; char streamidstring[11];
char spu_lang[21]; char spu_lang[21];
pthread_mutex_lock(&mutex);
msg = CUSTOM_COMMAND_GET_SUB_BY_ID; msg = CUSTOM_COMMAND_GET_SUB_BY_ID;
dprintf(fd_cmd, "%i", msg); dprintf(fd_cmd, "%i", msg);
dprintf(fd_in, "%i", spu_id); dprintf(fd_in, "%i", spu_id);
n = 0; int n = 0;
while ( n <= 0 ) { while ( n <= 0 ) {
n = read(fd_out, &streamidstring, 10); n = read(fd_out, &streamidstring, 10);
} }
read(fd_out, &spu_lang, 20); read(fd_out, &spu_lang, 20);
pthread_mutex_unlock(&mutex);
streamidstring[10] = '\0'; streamidstring[10] = '\0';
spu_lang[20] = '\0'; spu_lang[20] = '\0';
@@ -476,9 +659,13 @@ void cPlayback::FindAllSPids(int *spids, uint16_t *numpids, std::string *languag
cPlayback::cPlayback(int /*num*/) cPlayback::cPlayback(int /*num*/)
{ {
printf("%s:%s\n", FILENAME, __FUNCTION__); printf("%s:%s\n", FILENAME, __FUNCTION__);
playing=false; playing = false;
thread_active = 0; thread_active = 0;
eof_reached=0; eof_reached = 0;
fd_in = -1;
fd_out = -1;
fd_cmd = -1;
pthread_mutex_init(&mutex, NULL);
} }
cPlayback::~cPlayback() cPlayback::~cPlayback()

View File

@@ -24,7 +24,7 @@ class cPlayback
CS_PLAYBACK_PDATA * privateData; CS_PLAYBACK_PDATA * privateData;
pthread_t rua_thread; pthread_t rua_thread;
pthread_t event_thread; // pthread_t event_thread;
bool enabled; bool enabled;
bool paused; bool paused;
@@ -43,6 +43,8 @@ class cPlayback
int mduration; int mduration;
playmode_t playMode; playmode_t playMode;
int __GetPosition(void);
int rmfp_command(int cmd, int param, bool has_param, int reply_len);
// //
public: public:
bool Open(playmode_t PlayMode); bool Open(playmode_t PlayMode);