summaryrefslogtreecommitdiff
path: root/media_player.c
diff options
context:
space:
mode:
Diffstat (limited to 'media_player.c')
-rw-r--r--media_player.c703
1 files changed, 350 insertions, 353 deletions
diff --git a/media_player.c b/media_player.c
index d1d44a6d..b8e9a1e8 100644
--- a/media_player.c
+++ b/media_player.c
@@ -1,10 +1,10 @@
/*
* media_player.c:
*
- * See the main source file '.c' for copyright information and
+ * See the main source file 'xineliboutput.c' for copyright information and
* how to reach the author.
*
- * $Id: media_player.c,v 1.14 2006-12-02 23:35:31 phintuka Exp $
+ * $Id: media_player.c,v 1.15 2006-12-24 21:08:32 phintuka Exp $
*
*/
@@ -18,9 +18,11 @@
#include "config.h"
#include "media_player.h"
#include "device.h"
+#include "tools/playlist.h"
#include "logdefs.h"
+
#if VDRVERSNUM < 10400
// Dirty hack to bring menu back ...
#include <vdr/remote.h>
@@ -50,158 +52,21 @@ static void BackToMenu(void)
}
#endif
-#define MAX_FILES 256
-static char **ScanDir(const char *DirName)
-{
- static int depth = 0;
- DIR *d = opendir(DirName);
- if (d) {
- LOGDBG("ScanDir(%s)", DirName);
- struct dirent *e;
- int n = 0, warn = -1;
- char **result = (char**)malloc(sizeof(char*)*(MAX_FILES+1));
- char **current = result;
- *current = NULL;
- while ((e = readdir(d)) != NULL) {
- char *buffer = NULL;
- asprintf(&buffer, "%s/%s", DirName, e->d_name);
- struct stat st;
- if (stat(buffer, &st) == 0) {
- if(S_ISDIR(st.st_mode)) {
- if (! S_ISLNK(st.st_mode)) { /* don't want to loop ... */
- if(depth > 4) {
- LOGMSG("ScanDir: Too deep directory tree");
- } else if(e->d_name[0]=='.') {
- } else {
- char **tmp;
- int ind = 0;
- depth++; /* limit depth */
- if(NULL != (tmp = ScanDir(buffer)))
- while(tmp[ind]) {
- n++;
- if(n<MAX_FILES) {
- *current = tmp[ind];
- *(++current) = NULL;
- } else {
- if(!++warn)
- LOGMSG("ScanDir: Found over %d matching files, list truncated!", n);
- free(tmp[ind]);
- }
- ind++;
- }
- free(tmp);
- depth--;
- }
- }
- } else /* == if(!S_ISDIR(st.st_mode))*/ {
- // check symlink destination
- if (S_ISLNK(st.st_mode)) {
- char *old = buffer;
- buffer = ReadLink(buffer);
- free(old);
- if (!buffer)
- continue;
- if (stat(buffer, &st) != 0) {
- free(buffer);
- continue;
- }
- }
- if(xc.IsVideoFile(buffer)) {
- n++;
- if(n<MAX_FILES) {
- *current = buffer;
- *(++current) = NULL;
- buffer = NULL;
- LOGDBG("ScanDir: %s", e->d_name);
- } else {
- if(!++warn)
- LOGMSG("ScanDir: Found over %d matching files, list truncated!", n);
- free(buffer);
- break;
- }
- }
- }
- }
- free(buffer);
- }
- LOGDBG("ScanDir: Found %d matching files", n);
- closedir(d);
- return result;
- }
-
- LOGERR("ScanDir: Error opening %s", DirName);
- return NULL;
-}
-
-static char **Read_m3u(const char *file)
-{
- FILE *f = fopen(file, "r");
- if(f) {
- LOGDBG("Read_m3u(%s)", file);
- int n = 0;
- char **result = (char**)malloc(sizeof(char*)*(MAX_FILES+1));
- char **current = result, *pt;
- char *base = strdup(file);
- *current = NULL;
- if(NULL != (pt=strrchr(base,'/')))
- pt[1]=0;
- cReadLine r;
- while(NULL != (pt=r.Read(f)) && n < MAX_FILES) {
- if(*pt == '#' || !*pt)
- continue;
- if(*pt == '/' ||
- (strstr(pt,"://")+1 == strchr(pt,'/') &&
- strchr(pt,'/') - pt < 8))
- *current = strdup(pt);
- else
- asprintf(current, "%s/%s", base, pt);
- LOGDBG("Read_m3u: %s", *current);
- *(++current) = NULL;
- n++;
- }
- free(base);
- if(n >= MAX_FILES)
- LOGMSG("Read_m3u: Found over %d matching files, list truncated!", n);
- LOGDBG("Read_m3u: Found %d matching files", n);
- return result;
- }
- LOGERR("Read_m3u: Error opening %s", file);
- return NULL;
-}
//
// cXinelibPlayer
//
-class cPlaylistMenu : public cOsdMenu {
- public:
- cPlaylistMenu(const char **items, int current) : cOsdMenu(tr("Now playing"))
- {
- const char *pt;
- int i = -1;
-
- SetHasHotkeys();
-
- while(items && items[++i])
- Add(new cOsdItem((pt=strrchr(items[i],'/')) ? pt+1 : items[i],
- (eOSState)(os_User + i)));
- if(current>=0 && current < i)
- SetCurrent(Get(current));
- Display();
- }
- void SetCurrentExt(int i) { SetCurrent(Get(i)); Display(); }
-};
-
-class cXinelibPlayer : public cPlayer {
+class cXinelibPlayer : public cPlayer
+{
private:
- char *m_File;
- char *m_ResumeFile;
- char *m_Title;
+ cString m_File;
+ cString m_ResumeFile;
- char **m_Playlist;
- int m_CurrInd;
+ cPlaylist m_Playlist;
bool m_Replaying;
+ int m_Speed;
protected:
virtual void Activate(bool On);
@@ -210,142 +75,151 @@ class cXinelibPlayer : public cPlayer {
cXinelibPlayer(const char *file);
virtual ~cXinelibPlayer();
- virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
- {
- /*LOGMSG("cXinelibPlayer::SetAudioTrack(%d)",(int)Type);*/
- char tmp[64];
- if(IS_DOLBY_TRACK(Type))
- sprintf(tmp, "AUDIOSTREAM AC3 %d", (int)(Type - ttDolbyFirst));
- if(IS_AUDIO_TRACK(Type))
- sprintf(tmp, "AUDIOSTREAM AC3 %d", (int)(Type - ttAudioFirst));
- cXinelibDevice::Instance().PlayFileCtrl(tmp);
- };
-
- const char *Title(void);
- const char *File(void);
- const char **Playlist(void) { return (const char**)m_Playlist; }
- int CurrentFile(void) { return m_CurrInd; }
- int Files(void);
+ // cPlayer
+ virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId);
+ virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
+ virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
+
+ // cXinelibPlayer
+ void Control(const char *s) { (void)cXinelibDevice::Instance().PlayFileCtrl(s); }
+ void Control(const char *s, int i) {
+ cString cmd = cString::sprintf(s, i);
+ Control(cmd);
+ }
+ void SetSpeed(int Speed);
+ int Speed(void) { return m_Speed; };
+
+ bool m_UseResume;
+ /* Playlist access */
+/* TODO: move playlist to player control */
+ cPlaylist& Playlist(void) { return m_Playlist; }
+ const cString& File(void) { return m_File; }
+ int CurrentFile(void) { return m_Playlist.Current()->Index(); }
+ int Files(void) { return m_Playlist.Count(); }
bool NextFile(int step);
bool Replaying(void) { return m_Replaying; }
- bool m_UseResume;
};
cXinelibPlayer::cXinelibPlayer(const char *file)
{
int len = strlen(file);
- m_Playlist = NULL;
m_ResumeFile = NULL;
m_UseResume = true;
- m_Title = NULL;
- m_CurrInd = 0;
m_Replaying = false;
- if(len && file[len-1] == '/') {
- m_Playlist = ScanDir(file);
- } else if(len>4 && !strncasecmp(file+len-4, ".m3u", 4)) {
- m_Playlist = Read_m3u(file);
- }
- if(m_Playlist && !m_Playlist[0]) {
- free(m_Playlist);
- m_Playlist = NULL;
- }
+ m_Speed = 1;
- if(m_Playlist) {
- /* sort (slow but simple) */
- int a, b;
- for(a=0; m_Playlist[a]; a++)
- for(b=a+1; m_Playlist[b]; b++) {
- int r = strcmp(m_Playlist[a], m_Playlist[b]);
- if(r>0) {
- char *tmp = m_Playlist[a];
- m_Playlist[a] = m_Playlist[b];
- m_Playlist[b] = tmp;
- }
- }
+ if(len && file[len-1] == '/') {
+ // whole directory, create temporary playlist
+ m_Playlist.Read(file);
+ m_Playlist.Sort();
+ } else if(xc.IsPlaylistFile(file)) {
+ m_Playlist.Read(file);
+ } else if(xc.IsAudioFile(file)) {
+ // one audio file, create temporary playlist
+ cString folder(file);
+ *(strrchr(*folder, '/') + 1) = 0;
+ m_Playlist.Read(*folder, false);
+ m_Playlist.Sort();
+ // search start position
+ m_Playlist.SetCurrent(NULL);
+ for(cPlaylistItem *i = m_Playlist.First(); i; i = m_Playlist.Next(i))
+ if(!strcmp(file, *(i->Filename)))
+ m_Playlist.SetCurrent(i);
+ } else {
+ // not audio or playlist file, create playlist with only one item
+ m_Playlist.Read(file);
}
- m_File = strdup(m_Playlist ? m_Playlist[m_CurrInd] : file);
+ if(m_Playlist.Count() < 1)
+ LOGMSG("cXinelibPlayer: nothing to play !");
+
+ if(m_Playlist.Count() > 1)
+ m_Playlist.StartScanner();
+
+ m_File = m_Playlist.Current()->Filename;
}
cXinelibPlayer::~cXinelibPlayer()
{
Activate(false);
Detach();
+}
- if(m_Playlist) {
- int i=0;
- while(m_Playlist[i])
- free(m_Playlist[i++]);
- free(m_Playlist);
- }
- free(m_File);
- m_File = NULL;
- free(m_ResumeFile);
- m_ResumeFile = NULL;
- free(m_Title);
- m_Title = NULL;
+void cXinelibPlayer::SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
+{
+ /*LOGMSG("cXinelibPlayer::SetAudioTrack(%d)",(int)Type);*/
+ if(IS_DOLBY_TRACK(Type))
+ Control("AUDIOSTREAM AC3 %d", (int)(Type - ttDolbyFirst));
+ if(IS_AUDIO_TRACK(Type))
+ Control("AUDIOSTREAM AC3 %d", (int)(Type - ttAudioFirst));
}
-int cXinelibPlayer::Files(void)
+bool cXinelibPlayer::GetIndex(int &Current, int &Total, bool SnapToIFrame)
{
- if(!m_Playlist)
- return 1;
- int n=0;
- while(m_Playlist[n]) n++;
- return n;
+ // Returns the current and total frame index, optionally snapped to the
+ // nearest I-frame.
+ int msCurrent = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
+ int msTotal = cXinelibDevice::Instance().PlayFileCtrl("GETLENGTH");
+ if(msCurrent>=0 && msTotal>=0) {
+ Current = msCurrent * 25 / 1000;
+ Total = msTotal * 25 / 1000;
+ return true;
+ }
+ return false;
}
-const char *cXinelibPlayer::Title(void)
+bool cXinelibPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
{
- char *pt;
-
- if(!m_Title) {
- if(NULL != (pt=strrchr(m_File,'/')))
- m_Title = strdup(pt+1);
- else
- m_Title = strdup(m_File);
-
- if(NULL != (pt=strrchr(m_Title,'.')))
- *pt = 0;
- }
+ // Returns the current replay mode (if applicable).
+ // 'Play' tells whether we are playing or pausing, 'Forward' tells whether
+ // we are going forward or backward and 'Speed' is -1 if this is normal
+ // play/pause mode, 0 if it is single speed fast/slow forward/back mode
+ // and >0 if this is multi speed mode.
+ Play = (m_Speed>0);
+ Forward = true;
+ Speed = abs(m_Speed) - 2;
+ if(Speed<-1) Speed=-1;
- return m_Title;
+ return true;
}
-const char *cXinelibPlayer::File(void)
+void cXinelibPlayer::SetSpeed(int Speed)
{
- return m_File;
+ m_Speed = Speed;
+ switch(Speed) {
+ case -4: Control("TRICKSPEED 8"); break;
+ case -3: Control("TRICKSPEED 4"); break;
+ case -2: Control("TRICKSPEED 2"); break;
+ case 0: Control("TRICKSPEED 0"); break;
+ default:
+ case 1: Control("TRICKSPEED 1"); break;
+ case 2: Control("TRICKSPEED -2"); break;
+ case 3: Control("TRICKSPEED -4"); break;
+ case 4: Control("TRICKSPEED -12"); break;
+ }
}
bool cXinelibPlayer::NextFile(int step)
{
- if(m_Playlist) {
- if(step>0)
- while(step && m_Playlist[m_CurrInd+1]) {
- m_CurrInd++;
- step--;
- }
- else if(m_CurrInd + step < 0)
- m_CurrInd = 0;
- else
- m_CurrInd += step;
-
- free(m_File);
- free(m_ResumeFile);
- free(m_Title);
+ if(m_Playlist.Count()>1) {
+ for(;step < 0; step++)
+ m_Playlist.Prev();
+ for(;step > 0; step--)
+ m_Playlist.Next();
+
+ if(!m_Playlist.Current())
+ LOGERR("!m_Playlist.Get(m_CurrInd)");
+ m_File = *m_Playlist.Current()->Filename;
m_ResumeFile = NULL;
- m_Title = NULL;
-
- m_File = strdup(m_Playlist[m_CurrInd]);
-
+
Activate(true);
if(!m_Replaying)
return false;
return true;
}
-
+
return false;
}
@@ -353,36 +227,45 @@ void cXinelibPlayer::Activate(bool On)
{
int pos = 0, fd = -1;
if(On) {
- if(m_UseResume && !m_ResumeFile)
- asprintf(&m_ResumeFile, "%s.resume", m_File);
- if(m_UseResume && 0 <= (fd = open(m_ResumeFile,O_RDONLY))) {
+ if(m_UseResume && !*m_ResumeFile)
+ m_ResumeFile = cString::sprintf("%s.resume", *m_File);
+ if(m_UseResume && 0 <= (fd = open(m_ResumeFile, O_RDONLY))) {
if(read(fd, &pos, sizeof(int)) != sizeof(int))
pos = 0;
close(fd);
}
m_Replaying = cXinelibDevice::Instance().PlayFile(m_File, pos);
- LOGDBG("cXinelibPlayer playing %s (%s)", m_File, m_Replaying?"OK":"FAIL");
+ LOGDBG("cXinelibPlayer playing %s (%s)", *m_File, m_Replaying?"OK":"FAIL");
+
+ if(m_Replaying) {
+ // update playlist metainfo
+ const char *tr = cXinelibDevice::Instance().GetMetaInfo(miTrack);
+ const char *al = cXinelibDevice::Instance().GetMetaInfo(miAlbum);
+ const char *ar = cXinelibDevice::Instance().GetMetaInfo(miArtist);
+ if(tr && tr[0] && (!*m_Playlist.Current()->Track || !strstr(m_Playlist.Current()->Track, tr)))
+ m_Playlist.Current()->Track = tr;
+ if(al && al[0])
+ m_Playlist.Current()->Album = al;
+ if(ar && ar[0])
+ m_Playlist.Current()->Artist = ar;
+ }
} else {
- if(m_UseResume && m_ResumeFile) {
+ if(m_UseResume && *m_ResumeFile) {
pos = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
- if(strcasecmp(m_File+strlen(m_File)-4,".ram")) {
- if(pos>=0) {
- pos /= 1000;
- if(0 <= (fd = open(m_ResumeFile, O_WRONLY | O_CREAT,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
- if(write(fd, &pos, sizeof(int)) != sizeof(int)) {
- Skins.QueueMessage(mtInfo, "Error writing resume position !", 5, 30);
- }
- close(fd);
- } else {
- Skins.QueueMessage(mtInfo, "Error creating resume file !", 5, 30);
+ if(pos>=0) {
+ pos /= 1000;
+ if(0 <= (fd = open(m_ResumeFile, O_WRONLY | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
+ if(write(fd, &pos, sizeof(int)) != sizeof(int)) {
+ Skins.QueueMessage(mtInfo, "Error writing resume position !", 5, 30);
}
+ close(fd);
} else {
- unlink(m_ResumeFile);
+ Skins.QueueMessage(mtInfo, "Error creating resume file !", 5, 30);
}
+ } else {
+ unlink(m_ResumeFile);
}
- free(m_ResumeFile);
- m_ResumeFile = NULL;
}
cXinelibDevice::Instance().PlayFile(NULL,0);
m_Replaying = false;
@@ -390,6 +273,54 @@ void cXinelibPlayer::Activate(bool On)
}
//
+// cPlaylistMenu
+//
+
+class cPlaylistMenu : public cOsdMenu, cPlaylistChangeNotify
+{
+ protected:
+
+ cPlaylist& m_Playlist;
+ bool m_NeedsUpdate;
+
+ public:
+
+ virtual void PlaylistChanged(const cPlaylistItem *item) { m_NeedsUpdate = true; }
+
+ eOSState ProcessKey(eKeys Key) {
+ if(m_NeedsUpdate)
+ Set();
+ return cOsdMenu::ProcessKey(Key);
+ }
+
+ cPlaylistMenu(cPlaylist &Playlist) : cOsdMenu(*Playlist.Name()), m_Playlist(Playlist)
+ {
+ Set();
+ }
+
+ void Set(void)
+ {
+ m_NeedsUpdate = false;
+
+ Clear();
+ SetHasHotkeys();
+
+ int j = 0;
+ for(cPlaylistItem *i = m_Playlist.First(); i; i = m_Playlist.Next(i), j++)
+ Add(new cOsdItem( (const char *) (*(i->Track)),
+ (eOSState)(os_User + j)));
+
+ if(m_Playlist.Current())
+ SetCurrent(Get(m_Playlist.Current()->Index()));
+
+ Display();
+ }
+
+ void SetCurrentExt(int i) { SetCurrent(Get(i)); Display(); }
+};
+
+
+//
// cXinelibPlayerControl
//
@@ -405,16 +336,17 @@ cXinelibPlayerControl::cXinelibPlayerControl(eMainMenuMode Mode, const char *Fil
m_DisplayReplay = NULL;
m_PlaylistMenu = NULL;
m_ShowModeOnly = true;
- m_Speed = 1;
m_Mode = Mode;
m_RandomPlay = false;
+ m_AutoShowStart = 0;
+ m_BlinkState = true;
m_Player->m_UseResume = (Mode==ShowFiles);
#if VDRVERSNUM < 10338
- cStatus::MsgReplaying(this, m_Player->File());
+ cStatus::MsgReplaying(this, *m_Player->File());
#else
- cStatus::MsgReplaying(this, m_Player->Title(), m_Player->File(), true);
+ cStatus::MsgReplaying(this, *m_Player->Playlist().Current()->Track, *m_Player->File(), true);
#endif
}
@@ -424,15 +356,17 @@ cXinelibPlayerControl::~cXinelibPlayerControl()
delete m_PlaylistMenu;
m_PlaylistMenu = NULL;
}
- if(m_DisplayReplay)
+ if(m_DisplayReplay) {
delete m_DisplayReplay;
- m_DisplayReplay = NULL;
+ m_DisplayReplay = NULL;
+ }
#if VDRVERSNUM < 10338
cStatus::MsgReplaying(this, NULL);
#else
cStatus::MsgReplaying(this, NULL, NULL, false);
#endif
+
Close();
}
@@ -456,8 +390,9 @@ void cXinelibPlayerControl::Close(void)
void cXinelibPlayerControl::Show()
{
- bool Play = (m_Speed>0), Forward = true;
- int Speed = abs(m_Speed) - 2;
+ bool Play = (m_Player->Speed() > 0);
+ bool Forward = true;
+ int Speed = abs(m_Player->Speed()) - 2;
if(Speed<-1) Speed=-1;
if(!m_DisplayReplay)
@@ -465,18 +400,30 @@ void cXinelibPlayerControl::Show()
if(!m_ShowModeOnly) {
char t[128] = "";
- int Current, Total;
- Current = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
- Total = cXinelibDevice::Instance().PlayFileCtrl("GETLENGTH");
- if(Current>=0 && Total>=0) {
- Total = (Total+500)/1000;
- Current = (Current+500)/1000;
- m_DisplayReplay->SetTitle(m_Player->Title());
+ int Current = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
+ int Total = cXinelibDevice::Instance().PlayFileCtrl("GETLENGTH");
+ if(Current>=0) m_CurrentPos = Current;
+ if(Total>=0) m_CurrentLen = Total;
+
+ if(m_CurrentLen >= 0 /*&& Total >= 0*/) {
+ Total = (m_CurrentLen + 500) / 1000; // ms --> s
+ Current = (m_CurrentPos + 500) / 1000;
+
+ cString Title = m_Player->Playlist().Current()->Track;
+ if(*m_Player->Playlist().Current()->Artist ||
+ *m_Player->Playlist().Current()->Album)
+ Title = cString::sprintf("%s (%s%s%s)", *Title,
+ *m_Player->Playlist().Current()->Artist ?: "",
+ *m_Player->Playlist().Current()->Artist ? ": " : "",
+ *m_Player->Playlist().Current()->Album ?: "");
+ m_DisplayReplay->SetTitle(Title);
+
m_DisplayReplay->SetProgress(Current, Total);
sprintf(t, "%d:%02d:%02d", Total/3600, (Total%3600)/60, Total%60);
m_DisplayReplay->SetTotal( t );
sprintf(t, "%d:%02d:%02d", Current/3600, (Current%3600)/60, Current%60);
- m_DisplayReplay->SetCurrent( t );
+ m_BlinkState = (m_Player->Speed() != 0) || (!m_BlinkState);
+ m_DisplayReplay->SetCurrent( m_BlinkState ? t : "");
}
}
@@ -497,6 +444,12 @@ void cXinelibPlayerControl::Hide()
}
}
+cOsdObject *cXinelibPlayerControl::GetInfo(void)
+{
+ /* ??? */
+ return NULL;
+}
+
eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
{
if (cXinelibDevice::Instance().EndOfStreamReached() ||
@@ -508,15 +461,47 @@ eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
srand((unsigned int)time(NULL));
Jump = (random() % m_Player->Files()) - m_Player->CurrentFile();
}
- if(!m_Player->NextFile(Jump)) {
+ if(m_Player->Files() < 2 || !m_Player->NextFile(Jump)) {
Hide();
return osEnd;
}
- if(m_PlaylistMenu)
+ if(m_PlaylistMenu) {
+ m_PlaylistMenu->PlaylistChanged(m_Player->Playlist().Current());
m_PlaylistMenu->SetCurrentExt(m_Player->CurrentFile());
+ }
+
+ if(!m_DisplayReplay)
+ m_AutoShowStart = time(NULL);
+
+#if VDRVERSNUM < 10338
+ cStatus::MsgReplaying(this, *m_Player->File());
+#else
+ cStatus::MsgReplaying(this, *m_Player->Playlist().Current()->Track, *m_Player->File(), true);
+#endif
+ }
+
+ else {
+ // metainfo may change during playback (DVD titles, CDDA tracks)
+ const char *tr = cXinelibDevice::Instance().GetMetaInfo(miTrack);
+ if(tr && tr[0] && (!*m_Player->Playlist().Current()->Track ||
+ !strstr(m_Player->Playlist().Current()->Track, tr))) {
+ const char *al = cXinelibDevice::Instance().GetMetaInfo(miAlbum);
+ const char *ar = cXinelibDevice::Instance().GetMetaInfo(miArtist);
+ LOGDBG("metainfo changed: %s->%s %s->%s %s->%s",
+ *m_Player->Playlist().Current()->Artist?:"-", ar?:"-",
+ *m_Player->Playlist().Current()->Album ?:"-", al?:"-",
+ *m_Player->Playlist().Current()->Track ?:"-", tr?:"-");
+ m_Player->Playlist().Current()->Track = tr;
+ if(al && al[0])
+ m_Player->Playlist().Current()->Album = al;
+ if(ar && ar[0])
+ m_Player->Playlist().Current()->Artist = ar;
+ }
}
if(m_PlaylistMenu) {
+ m_AutoShowStart = 0;
+
if(Key == kRed) {
Hide();
return osContinue;
@@ -538,8 +523,6 @@ eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
if (m_DisplayReplay)
Show();
- int r;
- char *tmp = NULL;
switch(Key) {
case kBack: xc.main_menu_mode = m_Mode;
Hide();
@@ -550,14 +533,14 @@ eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
case kBlue: Hide();
Close();
return osEnd;
- case kRed: if(m_Player->Playlist()) {
+ case kRed: if(m_Player->Playlist().Count() > 1) {
Hide();
- m_PlaylistMenu = new cPlaylistMenu(m_Player->Playlist(), m_Player->CurrentFile());
+ m_PlaylistMenu = new cPlaylistMenu(m_Player->Playlist());
} else {
- r = cXinelibDevice::Instance().PlayFileCtrl("SEEK 0"); break;
+ m_Player->Control("SEEK 0"); break;
}
break;
- case k0: if(m_Player->Playlist()) {
+ case k0: if(m_Player->Playlist().Count()>1) {
m_RandomPlay = !m_RandomPlay;
if(m_RandomPlay)
Skins.Message(mtInfo, tr("Random play"));
@@ -565,17 +548,15 @@ eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
Skins.Message(mtInfo, tr("Normal play"));
}
break;
- case kGreen: r = cXinelibDevice::Instance().PlayFileCtrl("SEEK -60"); break;
- case kYellow: r = cXinelibDevice::Instance().PlayFileCtrl("SEEK +60"); break;
+ case kGreen: m_Player->Control("SEEK -60"); break;
+ case kYellow: m_Player->Control("SEEK +60"); break;
case k1:
- case kUser8: r = cXinelibDevice::Instance().PlayFileCtrl("SEEK -20"); break;
+ case kUser8: m_Player->Control("SEEK -20"); break;
case k3:
- case kUser9: r = cXinelibDevice::Instance().PlayFileCtrl("SEEK +20"); break;
+ case kUser9: m_Player->Control("SEEK +20"); break;
case k2: m_SubtitlePos -= 10;
case k5: m_SubtitlePos += 5;
- asprintf(&tmp,"SUBTITLES %d",m_SubtitlePos);
- r = cXinelibDevice::Instance().PlayFileCtrl(tmp);
- free(tmp);
+ m_Player->Control("SUBTITLES %d", m_SubtitlePos);
break;
case kNext:
case kRight: m_Player->NextFile(1);
@@ -584,18 +565,16 @@ eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
case kLeft: m_Player->NextFile(-1);
break;
case kDown:
- case kPause: if(m_Speed != 0) {
- r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 0");
+ case kPause: if(m_Player->Speed()) {
+ m_Player->SetSpeed(0);
if(!m_DisplayReplay)
m_ShowModeOnly = true;
- m_Speed = 0;
Show();
break;
}
// fall thru
case kUp:
- case kPlay: r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 1");
- m_Speed = 1;
+ case kPlay: m_Player->SetSpeed(1);
if(m_ShowModeOnly && m_DisplayReplay)
Hide();
else if(m_DisplayReplay)
@@ -603,7 +582,8 @@ eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
m_ShowModeOnly = false;
break;
case kOk:
- if(m_Speed != 1) {
+ m_AutoShowStart = 0;
+ if(m_Player->Speed() != 1) {
Hide();
m_ShowModeOnly = !m_ShowModeOnly;
Show();
@@ -621,11 +601,24 @@ eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
default: break;
}
+ if(m_DisplayReplay &&
+ m_AutoShowStart &&
+ time(NULL) - m_AutoShowStart > 5) {
+ m_AutoShowStart = 0;
+ Hide();
+ }
+
+ if(!m_DisplayReplay &&
+ m_AutoShowStart) {
+ m_ShowModeOnly = false;
+ Show();
+ }
+
return osContinue;
}
//
-// cXinelibDvdPlayerControl
+// cDvdMenu
//
class cDvdMenu : public cOsdMenu {
@@ -642,6 +635,11 @@ class cDvdMenu : public cOsdMenu {
}
};
+
+//
+// cXinelibDvdPlayerControl
+//
+
cXinelibDvdPlayerControl::~cXinelibDvdPlayerControl()
{
if(Menu) {
@@ -675,12 +673,14 @@ eOSState cXinelibDvdPlayerControl::ProcessKey(eKeys Key)
}
if(Menu) {
- switch(Menu->ProcessKey(Key)) {
- case osUser1: Hide(); cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_MENU1"); break;
- case osUser2: Hide(); cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_MENU2"); break;
- case osUser3: Hide(); cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_MENU3"); break;
- case osUser4: Hide(); cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_MENU4"); break;
- case osUser5: Hide(); cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_MENU5"); break;
+ if(Key == kRed)
+ Hide();
+ else switch(Menu->ProcessKey(Key)) {
+ case osUser1: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU1"); break;
+ case osUser2: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU2"); break;
+ case osUser3: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU3"); break;
+ case osUser4: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU4"); break;
+ case osUser5: Hide(); m_Player->Control("EVENT XINE_EVENT_INPUT_MENU5"); break;
case osBack:
case osEnd: Hide(); break;
default: break;
@@ -695,26 +695,29 @@ eOSState cXinelibDvdPlayerControl::ProcessKey(eKeys Key)
if(Key != kNone) {
const char *l0 = cXinelibDevice::Instance().GetDvdSpuLang(0);
const char *l1 = cXinelibDevice::Instance().GetDvdSpuLang(1);
- if((l0 && !strcmp("menu", l0)) ||
+ const char *t = cXinelibDevice::Instance().GetMetaInfo(miTitle);
+ const char *dt = cXinelibDevice::Instance().GetMetaInfo(miDvdTitleNo);
+
+ if((dt && !strcmp("0", dt)) ||
+ (l0 && !strcmp("menu", l0)) ||
(l1 && !strcmp("menu", l1))) {
- /*LOGMSG(" *** menu domain %s %s", l0, l1);*/
MenuDomain = true;
+ //LOGMSG(" *** menu domain %s %s %s %s", l0, l1, t, dt);
} else {
- /*LOGMSG(" *** replay domain %s %s", l0, l1);*/
+ //LOGMSG(" *** replay domain %s %s %s %s", l0, l1, t, dt);
}
}
- int r;
if(MenuDomain) {
switch(Key) {
// DVD navigation
- case kUp: r = cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_UP"); return osContinue;
- case kDown: r = cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_DOWN"); return osContinue;
- case kLeft: r = cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_LEFT"); return osContinue;
- case kRight: r = cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_RIGHT"); return osContinue;
- case kOk: r = cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_SELECT"); return osContinue;
- case kBack: r = cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_MENU1"); return osContinue;
- default: break;
+ case kUp: m_Player->Control("EVENT XINE_EVENT_INPUT_UP"); return osContinue;
+ case kDown: m_Player->Control("EVENT XINE_EVENT_INPUT_DOWN"); return osContinue;
+ case kLeft: m_Player->Control("EVENT XINE_EVENT_INPUT_LEFT"); return osContinue;
+ case kRight: m_Player->Control("EVENT XINE_EVENT_INPUT_RIGHT"); return osContinue;
+ case kOk: m_Player->Control("EVENT XINE_EVENT_INPUT_SELECT"); return osContinue;
+ case kBack: m_Player->Control("EVENT XINE_EVENT_INPUT_MENU1"); return osContinue;
+ default: break;
}
}
@@ -726,7 +729,7 @@ eOSState cXinelibDvdPlayerControl::ProcessKey(eKeys Key)
case kLeft: Key = kFastRew; break;
case kRight: Key = kFastFwd; break;
case kOk:
- if(m_Speed != 1) {
+ if(m_Player->Speed() != 1) {
Hide();
m_ShowModeOnly = !m_ShowModeOnly;
Show();
@@ -765,54 +768,54 @@ eOSState cXinelibDvdPlayerControl::ProcessKey(eKeys Key)
break;
// Playback control
- case kGreen: r = cXinelibDevice::Instance().PlayFileCtrl("SEEK -60"); break;
- case kYellow: r = cXinelibDevice::Instance().PlayFileCtrl("SEEK +60"); break;
+ case kGreen: m_Player->Control("SEEK -60"); break;
+ case kYellow: m_Player->Control("SEEK +60"); break;
case kUser8:
- case k1: r = cXinelibDevice::Instance().PlayFileCtrl("SEEK -20"); break;
+ case k1: m_Player->Control("SEEK -20"); break;
case kUser9:
- case k3: r = cXinelibDevice::Instance().PlayFileCtrl("SEEK +20"); break;
+ case k3: m_Player->Control("SEEK +20"); break;
case kStop:
case kBlue: Hide();
Close();
return osEnd;
- case k9: cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_NEXT TITLE"); break;
- case k7: cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_PREVIOUS TITLE"); break;
+ case k9: m_Player->Control("EVENT XINE_EVENT_INPUT_NEXT TITLE"); break;
+ case k7: m_Player->Control("EVENT XINE_EVENT_INPUT_PREVIOUS TITLE"); break;
case k6:
- case kNext: cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_NEXT CHAPTER"); break;
+ case kNext: m_Player->Control("EVENT XINE_EVENT_INPUT_NEXT CHAPTER"); break;
case k4:
- case kPrev: cXinelibDevice::Instance().PlayFileCtrl("EVENT XINE_EVENT_INPUT_PREVIOUS CHAPTER"); break;
+ case kPrev: m_Player->Control("EVENT XINE_EVENT_INPUT_PREVIOUS CHAPTER"); break;
- case kFastFwd:switch(m_Speed) {
- case 0: m_Speed=-4; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 8"); break;
- case -4: m_Speed=-3; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 4"); break;
- case -3: m_Speed=-2; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 2"); break;
+ case kFastFwd:switch(m_Player->Speed()) {
+ case 0: m_Player->SetSpeed(-4); break;
+ case -4: m_Player->SetSpeed(-3); break;
+ case -3: m_Player->SetSpeed(-2); break;
default:
- case -2: m_Speed= 1; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 1"); break;
- case 1: m_Speed= 2; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED -2"); break;
- case 2: m_Speed= 3; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED -4"); break;
+ case -2: m_Player->SetSpeed( 1); break;
+ case 1: m_Player->SetSpeed( 2); break;
+ case 2: m_Player->SetSpeed( 3); break;
case 3:
- case 4: m_Speed= 4; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED -12"); break;
+ case 4: m_Player->SetSpeed( 4); break;
}
- if(m_Speed != 1) {
+ if(m_Player->Speed() != 1) {
Show();
} else {
Hide();
}
break;
- case kFastRew:switch(m_Speed) {
+ case kFastRew:switch(m_Player->Speed()) {
case 0:
- case -4: m_Speed= 0; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 0"); break;
- case -3: m_Speed=-4; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 8"); break;
- case -2: m_Speed=-3; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 4"); break;
- case 1: m_Speed=-2; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 2"); break;
+ case -4: m_Player->SetSpeed( 0); break;
+ case -3: m_Player->SetSpeed(-4); break;
+ case -2: m_Player->SetSpeed(-3); break;
+ case 1: m_Player->SetSpeed(-2); break;
default:
- case 2: m_Speed= 1; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 1"); break;
- case 3: m_Speed= 2; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED -2"); break;
- case 4: m_Speed= 3; r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED -4"); break;
+ case 2: m_Player->SetSpeed( 1); break;
+ case 3: m_Player->SetSpeed( 2); break;
+ case 4: m_Player->SetSpeed( 3); break;
}
- if(m_Speed != 1 || !m_ShowModeOnly) {
+ if(m_Player->Speed() != 1 || !m_ShowModeOnly) {
Show();
} else {
Hide();
@@ -825,17 +828,15 @@ eOSState cXinelibDvdPlayerControl::ProcessKey(eKeys Key)
Show();
}
break;
- case kPause: if(m_Speed != 0) {
- r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 0");
+ case kPause: if(m_Player->Speed()) {
+ m_Player->SetSpeed(0);
m_ShowModeOnly = false;
- m_Speed = 0;
Show();
break;
}
// fall thru
- case kPlay: r = cXinelibDevice::Instance().PlayFileCtrl("TRICKSPEED 1");
+ case kPlay: m_Player->SetSpeed(1);
m_ShowModeOnly = true;
- m_Speed = 1;
Hide();
break;
default: break;
@@ -850,8 +851,8 @@ eOSState cXinelibDvdPlayerControl::ProcessKey(eKeys Key)
class cXinelibImagePlayer : public cPlayer {
private:
- char *m_File;
- bool m_Active;
+ cString m_File;
+ bool m_Active;
protected:
virtual void Activate(bool On);
@@ -865,7 +866,7 @@ class cXinelibImagePlayer : public cPlayer {
cXinelibImagePlayer::cXinelibImagePlayer(const char *file)
{
- m_File = strdup(file);
+ m_File = file;
m_Active = false;
}
@@ -873,9 +874,6 @@ cXinelibImagePlayer::~cXinelibImagePlayer()
{
Activate(false);
Detach();
-
- free(m_File);
- m_File = NULL;
}
void cXinelibImagePlayer::Activate(bool On)
@@ -885,14 +883,13 @@ void cXinelibImagePlayer::Activate(bool On)
cXinelibDevice::Instance().PlayFile(m_File, 0, true);
} else {
m_Active = false;
- cXinelibDevice::Instance().PlayFile(NULL,0);
+ cXinelibDevice::Instance().PlayFile(NULL, 0);
}
}
bool cXinelibImagePlayer::ShowImage(char *file)
{
- free(m_File);
- m_File = strdup(file);
+ m_File = file;
if(m_Active)
return cXinelibDevice::Instance().PlayFile(m_File, 0, true);
return true;