diff --git a/azbox/e2mruainclude.h b/azbox/e2mruainclude.h index 23c091a..27a1859 100644 --- a/azbox/e2mruainclude.h +++ b/azbox/e2mruainclude.h @@ -80,4 +80,4 @@ EVENT_MSG_EOS, EVENT_MSG_SUB_CHANGED, }; -int fd_cmd, fd_in, fd_out, fd_event, msg; +//int fd_cmd, fd_in, fd_out, fd_event, msg; diff --git a/azbox/playback.cpp b/azbox/playback.cpp index 7e1d294..f7c922e 100644 --- a/azbox/playback.cpp +++ b/azbox/playback.cpp @@ -1,3 +1,30 @@ +/* + * cPlayback implementation for azbox + * this is actually just a wrapper around rmfp_player which does + * all the heavy listing + * + * based on the original aztrino implementation, but almost + * completely rewritten since then + * + * some of the methods and constants were found by stracing the + * AZPlay enigma2 plugin... + * + * (C) 2012 Stefan Seyfried + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include @@ -11,12 +38,17 @@ #include #include +#include "lt_debug.h" +#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PLAYBACK, this, args) +#define lt_info(args...) _lt_info(TRIPLE_DEBUG_PLAYBACK, this, args) +#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_PLAYBACK, NULL, args) + #include -#define FIFO_CMD "/tmp/rmfp.cmd" -#define FIFO_IN "/tmp/rmfp.in" -#define FIFO_OUT "/tmp/rmfp.out" -//#define FIFO_EVENT "/tmp/rmfp.event" +/* the file-based commands work better than the FIFOs... */ +#define CMD_FILE "/tmp/rmfp.cmd2" +#define IN_FILE "/tmp/rmfp.in2" +#define OUT_FILE "/tmp/rmfp.out2" #include "playback.h" @@ -24,13 +56,8 @@ extern "C"{ #include "e2mruainclude.h" } -static const char * FILENAME = "playback_cs.cpp"; - -static bool open_success = false; -static int last_pos; -static time_t last_pos_time; - - +#if 0 +/* useful for debugging */ static time_t monotonic_ms(void) { struct timespec t; @@ -44,40 +71,90 @@ static time_t monotonic_ms(void) ret += t.tv_nsec / 1000000; return ret; } +#endif -int cPlayback::rmfp_command(int cmd, int param, bool has_param, int reply_len) +/* the mutex makes sure that commands are not interspersed */ +bool cPlayback::rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen) { - 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) + lt_info("%s: %d %d %d %d\n", __func__, cmd, param, has_param, buflen); + bool ret = true; + int fd; + if (cmd == 222) { - int n = 0; - while (n <= 0) - n = read(fd_out, &reply, 100); - reply[reply_len - 1] = '\0'; - ret = atoi(reply); + if (pthread_mutex_trylock(&rmfp_cmd_mutex)) + return false; } - pthread_mutex_unlock(&mutex); + else + pthread_mutex_lock(&rmfp_cmd_mutex); + unlink(OUT_FILE); + if (has_param) + { + fd = open(IN_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666); + dprintf(fd, "%i", param); + close(fd); + } + fd = open(CMD_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666); + dprintf(fd, "%i", cmd); + close(fd); + int n = 0, m = 0; + if (buflen > 0) + { + while ((fd = open(OUT_FILE, O_RDONLY)) == -1) { + if (++m > 500) { /* don't wait more than 5 seconds */ + lt_info("%s: timed out waiting for %s (cmd %d par %d buflen %d\n", + __func__, OUT_FILE, cmd, param, buflen); + ret = false; + goto out; + } + usleep(10000); + } + unlink(OUT_FILE); + n = read(fd, buf, buflen); + close(fd); + /* some commands (CUSTOM_COMMAND_GET_AUDIO_BY_ID for example) actually + * return the answer in two successive writes, as we are not using the + * FIFO, we need to make sure that the file is deleted immediately, because + * rmfp_player will not overwrite it if it exists */ + while ((fd = open(OUT_FILE, O_RDONLY)) == -1) { + if (++m > 10) + break; + usleep(1000); + } + if (fd > -1) + { + read(fd, buf + n, buflen - n); + unlink(OUT_FILE); + close(fd); + } + buf[buflen - 1] = '0'; + } + out: + pthread_mutex_unlock(&rmfp_cmd_mutex); + if (cmd != 222) /* called tooo often :-) */ + lt_info("%s: reply: '%s' ret: %d m:%d\n", __func__, buf?buf:"(none)", ret, m); return ret; } -void cPlayback::RuaThread() +/* + * runs the rmfp_player in a terminal + * just doing popen() or similar does not work because then + * the output will be buffered after starting up and we will only + * see "Playback has started..." after the player exits + */ +void cPlayback::run_rmfp() { - printf("Starting RUA thread\n"); + lt_debug("%s: starting\n", __func__); + thread_started = true; //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) + if (playMode == PLAYMODE_TS && mduration != 0) { std::stringstream duration; - duration << (mduration * 60000); + duration << (mduration /** 60000LL*/); final = base + "-duration " + duration.str() + " " + file; } @@ -86,7 +163,7 @@ void cPlayback::RuaThread() pid = forkpty(&master, NULL, NULL, NULL); if (! pid) { execl("/bin/sh", "sh", "-c", final.c_str(), (char *)0); - perror("exec"); + lt_info("%s: execl returned: %m\n", __func__); exit(0); } @@ -104,18 +181,17 @@ void cPlayback::RuaThread() break; output[len] = '\0'; } - printf("rmfp: '%s'\n", output); - if (!strcmp(output, "Playback has started...")) + lt_info("%s out: '%s'\n", __func__, output); + if (strstr(output, "Playback has started...")) { - fd_cmd = open(FIFO_CMD, O_WRONLY); - fd_in = open(FIFO_IN, O_WRONLY); playing = true; - printf("===================> playing = true\n"); + lt_info("%s: ===================> playing = true\n", __func__); } - else if (!strcmp(output, "End of file...")) + else if (strstr(output, "End of file...")) { + playing = true; /* this can happen without "Playback has started..." */ eof_reached = true; - printf("===================> eof_reached = true\n"); + lt_info("%s: ===================> eof_reached = true\n", __func__); } } fclose(f); @@ -125,114 +201,38 @@ void cPlayback::RuaThread() free(output); } - printf("Terminating RUA thread\n"); - thread_active = 0; + lt_info("%s: terminating\n", __func__); playing = false; - eof_reached = 1; + eof_reached = true; pthread_exit(NULL); } /* helper function to call the cpp thread loop */ -void* execute_rua_thread(void *c) +void *execute_rua_thread(void *c) { - cPlayback *obj=(cPlayback*)c; - - printf("Executing RUA Thread\n"); - - obj->RuaThread(); - - free(obj); + cPlayback *obj = (cPlayback *)c; + lt_info_c("%s\n", __func__); + obj->run_rmfp(); + /* free(obj); // this is most likely wrong */ return NULL; } -#if 0 -void cPlayback::EventThread() -{ - - printf("Starting Event thread\n"); - - thread_active = 1; - eof_reached = 0; - while (thread_active == 1) - { - struct timeval tv; - fd_set readfds; - int retval; - - tv.tv_sec = 1; - tv.tv_usec = 0; - - FD_ZERO(&readfds); - FD_SET(fd_event, &readfds); - retval = select(fd_event + 1, &readfds, NULL, NULL, &tv); - - //printf("retval is %i\n", retval); - if (retval) - { - - char eventstring[4]; - int event; - - read(fd_event, &eventstring, 3); - eventstring[3] = '\0'; - event = atoi(eventstring); - - printf("Got event message %i\n", event); - - switch(event) - { - case EVENT_MSG_FDOPEN: - fd_cmd = open(FIFO_CMD, O_WRONLY); - fd_in = open(FIFO_IN, O_WRONLY); - printf("Message FD Opened %i", fd_in); - break; - case EVENT_MSG_PLAYBACK_STARTED: - printf("Got playing event \n"); - playing = true; - break; - case EVENT_MSG_EOS: - printf("Got EOF event \n"); - eof_reached = 1; - break; - } - } - usleep(100000); - } - - printf("Terminating Event thread\n"); - playing = false; - pthread_exit(NULL); -} - -/* helper function to call the cpp thread loop */ -void* execute_event_thread(void *c) -{ - cPlayback *obj=(cPlayback*)c; - - printf("Executing Event Thread\n"); - - obj->EventThread(); - - return NULL; -} -#endif - //Used by Fileplay bool cPlayback::Open(playmode_t PlayMode) { - const char *aPLAYMODE[] = { + static const char *aPLAYMODE[] = { "PLAYMODE_TS", "PLAYMODE_FILE" }; - - setduration = 0; - if (PlayMode == 0) + playMode = PlayMode; + if (playMode > 1) { - printf("RECORDING PLAYING BACK\n"); - setduration = 1; + lt_info("%s: PlayMode %d out of range!\n", __func__, PlayMode); + playMode = PLAYMODE_FILE; } + lt_info("%s: mode %d (%s)\n", __func__, PlayMode, aPLAYMODE[PlayMode]); #if 0 while (access("/tmp/continue", R_OK)) sleep(1); @@ -249,7 +249,7 @@ bool cPlayback::Open(playmode_t PlayMode) i++; if (i > 10) { - printf("player is not getting idle after 10 seconds!\n"); + lt_info("%s: ERROR - player is not idle after 10 seconds!\n", __func__); open_success = false; return false; } @@ -257,430 +257,248 @@ bool cPlayback::Open(playmode_t PlayMode) } proc_put("/proc/player", "2", 2); + lt_info("%s: /proc/player switched to '2'\n", __func__); - printf("%s:%s - PlayMode=%s\n", FILENAME, __FUNCTION__, aPLAYMODE[PlayMode]); - - //Making Fifo's for message pipes - mknod(FIFO_CMD, S_IFIFO | 0666, 0); - mknod(FIFO_IN, S_IFIFO | 0666, 0); - mknod(FIFO_OUT, 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 - fd_out = open(FIFO_OUT, O_RDONLY | O_NONBLOCK); -// fd_event = open(FIFO_EVENT, O_RDONLY | O_NONBLOCK); + unlink(CMD_FILE); + unlink(IN_FILE); + unlink(OUT_FILE); open_success = true; return 0; } //Used by Fileplay -void cPlayback::Close(void) -{ - printf("%s:%s\n", FILENAME, __FUNCTION__); - -//Dagobert: movieplayer does not call stop, it calls close ;) - Stop(); -} - -//Used by Fileplay -bool cPlayback::Start(char * filename, unsigned short vpid, int vtype, unsigned short apid, bool ac3, int duration) +bool cPlayback::Start(char *filename, unsigned short vpid, int vtype, unsigned short _apid, + int ac3, unsigned int duration) { bool ret = true; - - printf("%s:%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d duration=%i\n", - FILENAME, __FUNCTION__, filename, vpid, vtype, apid, ac3, duration); + + lt_info("%s: filename=%s\n", __func__, filename); + lt_info("%s: vpid=%u vtype=%d apid=%u ac3=%d duration=%i open_success=%d\n", + __func__, vpid, vtype, _apid, ac3, duration, open_success); if (!open_success) return false; - eof_reached = 0; + eof_reached = false; //create playback path - mAudioStream=0; + apid = 0; + subpid = 0; mfilename = filename; mduration = duration; - if (pthread_create(&rua_thread, 0, execute_rua_thread, this) != 0) + if (pthread_create(&thread, 0, execute_rua_thread, this) != 0) { - printf("[movieplayer]: error creating file_thread! (out of memory?)\n"); + lt_info("%s: error creating rmfp_player thread! (out of memory?)\n", __func__); ret = false; } -#if 0 - if (pthread_create(&event_thread, 0, execute_event_thread, this) != 0) - { - printf("[movieplayer]: error creating file_thread! (out of memory?)\n"); - ret = false; - } -#endif while (! playing) sleep(1); return ret; } -//Used by Fileplay -bool cPlayback::Stop(void) +void cPlayback::Close(void) { - printf("%s:%s playing %d %d\n", FILENAME, __FUNCTION__, playing, thread_active); - if(playing==false && thread_active == 0) return false; + lt_info("%s: playing %d thread_started %d\n", __func__, playing, thread_started); - rmfp_command(KEY_COMMAND_QUIT_ALL, 0, false, 0); + if (thread_started) + { + rmfp_command(KEY_COMMAND_QUIT_ALL, 0, false, NULL, 0); - if (pthread_join(rua_thread, NULL)) - { - printf("error joining rua thread\n"); + if (pthread_join(thread, NULL)) + lt_info("%s: error joining rmfp thread (%m)\n", __func__); + playing = false; + thread_started = false; } -#if 0 - if (pthread_join(event_thread, NULL)) - { - printf("error joining event thread\n"); - } -#endif - playing = false; + else + lt_info("%s: Warning: thread_started == false!\n", __func__); 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; + lt_info("%s: /proc/player switched to '1'\n", __func__); + usleep(1000000); + } } -bool cPlayback::SetAPid(unsigned short pid, bool /*ac3*/) +bool cPlayback::SetAPid(unsigned short pid, int /*ac3*/) { - printf("%s:%s pid %i\n", FILENAME, __FUNCTION__, pid); - if (pid != mAudioStream) { - rmfp_command(KEY_COMMAND_SWITCH_AUDIO, pid, true, 0); - mAudioStream = pid; + lt_info("%s: pid %i\n", __func__, pid); + if (pid != apid) { + rmfp_command(KEY_COMMAND_SWITCH_AUDIO, pid, true, NULL, 0); + apid = pid; } return true; } bool cPlayback::SetSPid(int pid) { - printf("%s:%s pid %i\n", FILENAME, __FUNCTION__, pid); - if(pid!=mSubStream) + lt_info("%s: pid %i\n", __func__, pid); + if (pid != subpid) { - rmfp_command(KEY_COMMAND_SWITCH_SUBS, pid, true, 0); -/* - msg = KEY_COMMAND_SWITCH_SUBS; - dprintf(fd_cmd, "%i", msg); - dprintf(fd_in, "%i", pid); -*/ - mSubStream=pid; + rmfp_command(KEY_COMMAND_SWITCH_SUBS, pid, true, NULL, 0); + subpid = pid; } return true; } bool cPlayback::SetSpeed(int speed) { - printf("%s:%s playing %d speed %d\n", FILENAME, __FUNCTION__, playing, speed); + lt_info("%s: playing %d speed %d\n", __func__, playing, speed); - if(playing==false) - return false; + if (!playing) + return false; -// int result = 0; + playback_speed = speed; - nPlaybackSpeed = speed; - if (speed > 1 || speed < 0) - { - rmfp_command(CUSTOM_COMMAND_TRICK_SEEK, speed, true, 0); -/* - msg = CUSTOM_COMMAND_TRICK_SEEK; - dprintf(fd_cmd, "%i", msg); - dprintf(fd_in, "%i", speed); -*/ - } + rmfp_command(CUSTOM_COMMAND_TRICK_SEEK, speed, true, NULL, 0); else if (speed == 0) - { - rmfp_command(KEY_COMMAND_PAUSE, 0, false, 0); -/* - msg = KEY_COMMAND_PAUSE; - dprintf(fd_cmd, "%i", msg); -*/ - } + rmfp_command(KEY_COMMAND_PAUSE, 0, false, NULL, 0); else - { - rmfp_command(KEY_COMMAND_PLAY, 0, false, 0); -/* - msg = KEY_COMMAND_PLAY; - dprintf(fd_cmd, "%i", msg); - _GetPosition(); -*/ - } - -// if (result != 0) -// { -// printf("returning false\n"); -// return false; -// } + rmfp_command(KEY_COMMAND_PLAY, 0, false, NULL, 0); return true; } bool cPlayback::GetSpeed(int &/*speed*/) const { -/* printf("%s:%s\n", FILENAME, __FUNCTION__); - speed = nPlaybackSpeed; -*/ 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, ×tring, 100) <= 0){}; + lt_info("%s:\n", __func__); + speed = playback_speed; #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; + return true; } - // in milliseconds bool cPlayback::GetPosition(int &position, int &duration) { - printf("%s:%s pos %d dur %d play %d\n", FILENAME, __FUNCTION__, position, duration, playing); - - //Azbox eof - if (eof_reached == 1) - { - if (setduration) - { - position = mduration; - duration = mduration; - return true; - } - position = -5; - duration = -5; - return true; - } - - if(playing==false) return false; + lt_debug("%s: playing %d\n", __func__, playing); - if (nPlaybackSpeed == 1 && setduration) { - time_t time_diff = monotonic_ms() - last_pos_time; - position = last_pos + time_diff; - } - else - position = __GetPosition(); - - if (setduration) + if (eof_reached) { + position = mduration; duration = mduration; return true; } - //Duration - int length; -/* - char durationstring[11]; - - msg = CUSTOM_COMMAND_GETLENGTH; - dprintf(fd_cmd, "%i", msg); - - int n = 0; - while ( n <= 0 ) { - n = read(fd_out, &durationstring, 10); + + if (!playing) + return false; + + char buf[32]; + /* custom command 222 returns "12345\n1234\n", + * first line is duration, second line is position */ + if (! rmfp_command(222, 0, false, buf, 32)) + return false; + duration = atoi(buf); + char *p = strchr(buf, '\n'); + if (!p) + return false; + position = atoi(++p); + + if (playMode == PLAYMODE_TS) + { + if (position > mduration) + mduration = position + 1000; + duration = mduration; + return true; } - durationstring[10] = '\0'; - length = atoi(durationstring); -*/ - length = rmfp_command(CUSTOM_COMMAND_GETLENGTH, 0, false, 11); - if(length <= 0) { - duration = duration+1000; - } else { - duration = length; - } - return true; } bool cPlayback::SetPosition(int position, bool absolute) { - printf("%s:%s %d playing %d\n", FILENAME, __FUNCTION__,position, playing); - if(playing==false) return false; - + lt_info("%s: pos %d abs %d playing %d\n", __func__, position, absolute, playing); + + if (!playing) + return false; + int seconds = position / 1000;; - - if (absolute == true) + + if (absolute) { - rmfp_command(KEY_COMMAND_SEEK_TO_TIME, seconds, true, 0); -/* - msg = KEY_COMMAND_SEEK_TO_TIME; - seconds = position / 1000; - dprintf(fd_cmd, "%i", msg); - dprintf(fd_in, "%i", seconds); -*/ - } - else - { - if (position > 0 ) - { - rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_FWD, seconds, true, 0); -/* - msg = CUSTOM_COMMAND_SEEK_RELATIVE_FWD; - seconds = position / 1000; - dprintf(fd_cmd, "%i", msg); - dprintf(fd_in, "%i", seconds); -*/ - } - else if ( position < 0 ) - { - rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_BWD, seconds, true, 0); -/* - msg = CUSTOM_COMMAND_SEEK_RELATIVE_BWD; - seconds = position / 1000; - seconds *= -1; - printf("sending seconds %i\n", seconds); - dprintf(fd_cmd, "%i", msg); - dprintf(fd_in, "%i", seconds); -*/ - } + rmfp_command(KEY_COMMAND_SEEK_TO_TIME, seconds, true, NULL, 0); + return true; } + + if (position > 0) + rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_FWD, seconds, true, NULL, 0); + else if (position < 0) + rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_BWD, seconds, true, NULL, 0); return true; } void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language) { - printf("%s:%s\n", FILENAME, __FUNCTION__); + lt_info("%s\n", __func__); + char buf[32]; + rmfp_command(CUSTOM_COMMAND_AUDIO_COUNT, 0, false, buf, 3); + unsigned int audio_count = atoi(buf); - unsigned int audio_count = 0; -// char audio_countstring[3]; - - audio_count = rmfp_command(CUSTOM_COMMAND_AUDIO_COUNT, 0, false, 3); -/* - msg = CUSTOM_COMMAND_AUDIO_COUNT; - dprintf(fd_cmd, "%i", msg); - - int n = 0; - while ( n <= 0 ) { - n = read(fd_out, &audio_countstring, 2); - } - audio_countstring[2] = '\0'; - audio_count = atoi(audio_countstring); -*/ *numpida = audio_count; - if (audio_count > 0 ) + if (audio_count > 0) { - for ( unsigned int audio_id = 0; audio_id < audio_count; audio_id++ ) + for (unsigned int aid = 0; aid < audio_count; aid++) { char streamidstring[11]; char audio_lang[21]; - pthread_mutex_lock(&mutex); - msg = CUSTOM_COMMAND_GET_AUDIO_BY_ID; - dprintf(fd_cmd, "%i", msg); - dprintf(fd_in, "%i", audio_id); - - int n = 0; - while ( n <= 0 ) { - n = read(fd_out, &streamidstring, 10); - } - read(fd_out, &audio_lang, 20); - pthread_mutex_unlock(&mutex); + memset(buf, 0, sizeof(buf)); + rmfp_command(CUSTOM_COMMAND_GET_AUDIO_BY_ID, aid, true, buf, 32); + memcpy(streamidstring, buf, 10); streamidstring[10] = '\0'; + memcpy(audio_lang, buf + 10, 20); audio_lang[20] = '\0'; - - apids[audio_id] = atoi(streamidstring); - ac3flags[audio_id] = 0; - language[audio_id] = audio_lang; + apids[aid] = atoi(streamidstring); + ac3flags[aid] = 0; + language[aid] = audio_lang; + lt_info("%s: #%d apid:%d lang: %s\n", __func__, aid, apids[aid], audio_lang); } } } void cPlayback::FindAllSPids(int *spids, uint16_t *numpids, std::string *language) { - printf("%s:%s\n", FILENAME, __FUNCTION__); + lt_info("%s\n", __func__); + char buf[32]; - unsigned int spu_count = 0; - spu_count = rmfp_command(CUSTOM_COMMAND_SUBS_COUNT, 0, false, 3); -/* - char spu_countstring[3]; - - msg = CUSTOM_COMMAND_SUBS_COUNT; - dprintf(fd_cmd, "%i", msg); - - int n = 0; - while ( n <= 0 ) { - n = read(fd_out, &spu_countstring, 2); - } - spu_countstring[2] = '\0'; - spu_count = atoi(spu_countstring); -*/ + rmfp_command(CUSTOM_COMMAND_SUBS_COUNT, 0, false, buf, 3); + unsigned int spu_count = atoi(buf); *numpids = spu_count; - if (spu_count > 0 ) + if (spu_count > 0) { - - for ( unsigned int spu_id = 0; spu_id < spu_count; spu_id++ ) + for (unsigned int sid = 0; sid < spu_count; sid++) { - //int streamid; char streamidstring[11]; char spu_lang[21]; - - pthread_mutex_lock(&mutex); - msg = CUSTOM_COMMAND_GET_SUB_BY_ID; - dprintf(fd_cmd, "%i", msg); - dprintf(fd_in, "%i", spu_id); - - int n = 0; - while ( n <= 0 ) { - n = read(fd_out, &streamidstring, 10); - } - read(fd_out, &spu_lang, 20); - pthread_mutex_unlock(&mutex); + memset(buf, 0, sizeof(buf)); + rmfp_command(CUSTOM_COMMAND_GET_SUB_BY_ID, sid, true, buf, 32); + memcpy(streamidstring, buf, 10); streamidstring[10] = '\0'; + memcpy(spu_lang, buf + 10, 20); spu_lang[20] = '\0'; - - spids[spu_id] = atoi(streamidstring); - language[spu_id] = spu_lang; + spids[sid] = atoi(streamidstring); + language[sid] = spu_lang; + lt_info("%s: #%d apid:%d lang: %s\n", __func__, sid, spids[sid], spu_lang); } } - //Add streamid -1 to be able to disable subtitles - *numpids = spu_count + 1; - spids[spu_count] = -1; - language[spu_count] = "Disable"; - + //Add streamid -1 to be able to disable subtitles + *numpids = spu_count + 1; + spids[spu_count] = -1; + language[spu_count] = "Disable"; } - cPlayback::cPlayback(int /*num*/) { - printf("%s:%s\n", FILENAME, __FUNCTION__); + lt_info("%s: constructor\n", __func__); playing = false; - thread_active = 0; - eof_reached = 0; - fd_in = -1; - fd_out = -1; - fd_cmd = -1; - pthread_mutex_init(&mutex, NULL); + thread_started = false; + eof_reached = false; + open_success = false; + pthread_mutex_init(&rmfp_cmd_mutex, NULL); } cPlayback::~cPlayback() { - printf("%s:%s\n", FILENAME, __FUNCTION__); -} - -bool cPlayback::IsEOF(void) const -{ -// printf("%s:%s\n", FILENAME, __FUNCTION__); - return eof_reached; -} - -int cPlayback::GetCurrPlaybackSpeed(void) const -{ - printf("%s:%s\n", FILENAME, __FUNCTION__); - return nPlaybackSpeed; + lt_info("%s\n", __func__); + pthread_mutex_destroy(&rmfp_cmd_mutex); } diff --git a/azbox/playback.h b/azbox/playback.h index a3acf2b..32c15c9 100644 --- a/azbox/playback.h +++ b/azbox/playback.h @@ -4,79 +4,58 @@ #include #include -#ifndef CS_PLAYBACK_PDATA -typedef struct { - int nothing; -} CS_PLAYBACK_PDATA; -#endif - typedef enum { PLAYMODE_TS = 0, PLAYMODE_FILE, -} playmode_t; +} playmode_t; class cPlayback { private: - int timeout; - pthread_cond_t read_cond; - pthread_mutex_t mutex; - CS_PLAYBACK_PDATA * privateData; - - pthread_t rua_thread; - // pthread_t event_thread; - - bool enabled; - bool paused; + pthread_mutex_t rmfp_cmd_mutex; bool playing; - int unit; - int nPlaybackFD; - int video_type; - int nPlaybackSpeed; - int mSpeed; - int mAudioStream; - int mSubStream; - char* mfilename; - int thread_active; - int eof_reached; - int setduration; - int mduration; - + bool eof_reached; + int playback_speed; playmode_t playMode; - int __GetPosition(void); - int rmfp_command(int cmd, int param, bool has_param, int reply_len); - // + bool open_success; + uint16_t apid; + uint16_t subpid; + char *mfilename; + int mduration; + pthread_t thread; + bool thread_started; + /* private functions */ + bool rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen); public: - bool Open(playmode_t PlayMode); - void Close(void); - bool Start(char * filename, unsigned short vpid, int vtype, unsigned short apid, bool ac3, int duration); - bool Stop(void); - bool SetAPid(unsigned short pid, bool ac3); - bool SetSPid(int pid); - bool SetSpeed(int speed); - bool GetSpeed(int &speed) const; - bool GetPosition(int &position, int &duration); - bool SetPosition(int position, bool absolute = false); - bool IsEOF(void) const; - int GetCurrPlaybackSpeed(void) const; - void FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language); - void FindAllSPids(int *spids, uint16_t *numpids, std::string *language); - // cPlayback(int num = 0); ~cPlayback(); - void RuaThread(); - void EventThread(); + void run_rmfp(); + + bool Open(playmode_t PlayMode); + void Close(void); + bool Start(char *filename, unsigned short vpid, int vtype, unsigned short apid, + int ac3, unsigned int duration); + bool SetAPid(unsigned short pid, int ac3); + bool SetSpeed(int speed); + bool GetSpeed(int &speed) const; + bool GetPosition(int &position, int &duration); /* pos: current time in ms, dur: file length in ms */ + bool SetPosition(int position, bool absolute = false); /* position: jump in ms */ + void FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language); + // AZbox specific + void FindAllSPids(int *spids, uint16_t *numpids, std::string *language); + bool SetSPid(int pid); #if 0 - /* not used */ + // Functions that are not used by movieplayer.cpp: + bool Stop(void); bool GetOffset(off64_t &offset); - void PlaybackNotify (int Event, void *pData, void *pTag); - void DMNotify(int Event, void *pTsBuf, void *Tag); - bool IsPlaying(void) const; - bool IsEnabled(void) const; + bool IsPlaying(void) const { return playing; } + bool IsEnabled(void) const { return enabled; } void * GetHandle(void); void * GetDmHandle(void); + int GetCurrPlaybackSpeed(void) const { return nPlaybackSpeed; } + void PlaybackNotify (int Event, void *pData, void *pTag); + void DMNotify(int Event, void *pTsBuf, void *Tag); #endif }; - #endif