summaryrefslogtreecommitdiff
path: root/media_player.c
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2009-10-21 00:02:02 +0000
committercvs2svn <admin@example.com>2009-10-21 00:02:02 +0000
commit97a97ca3358eb48de3eb7a222e487e800566569f (patch)
tree97c920d0225a1c9773a3bce2207f261d7d230123 /media_player.c
parenta61961358c5a2ec92340b3f8e056bab55438f103 (diff)
downloadxineliboutput-CVS.tar.gz
xineliboutput-CVS.tar.bz2
This commit was manufactured by cvs2svn to create branch 'CVS'.CVS
Diffstat (limited to 'media_player.c')
-rw-r--r--media_player.c1346
1 files changed, 0 insertions, 1346 deletions
diff --git a/media_player.c b/media_player.c
deleted file mode 100644
index f3901fca..00000000
--- a/media_player.c
+++ /dev/null
@@ -1,1346 +0,0 @@
-/*
- * media_player.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: media_player.c,v 1.68 2009-06-02 08:59:45 phintuka Exp $
- *
- */
-
-#include <unistd.h>
-
-#include <vdr/config.h>
-#include <vdr/status.h>
-#include <vdr/interface.h>
-#include <vdr/tools.h>
-
-#include "config.h"
-#include "media_player.h"
-#include "device.h"
-#include "tools/playlist.h"
-#include "tools/metainfo_menu.h"
-#include "menu.h"
-
-#include "logdefs.h"
-
-static void BackToMenu(void)
-{
- cRemote::CallPlugin("xineliboutput");
-}
-
-
-//
-// cXinelibPlayer
-//
-
-class cXinelibPlayer : public cPlayer
-{
- private:
- cString m_File;
- cString m_ResumeFile;
- cString m_SubFile;
-
- cPlaylist m_Playlist;
-
- bool m_Error;
- bool m_UseResumeFile;
- int m_Speed;
-
- void UpdateNumTracks(void);
-
- protected:
- virtual void Activate(bool On);
-
- public:
- cXinelibPlayer(const char *File, bool Queue = false, const char *SubFile = NULL);
- virtual ~cXinelibPlayer();
-
- // cPlayer
- virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId);
- virtual void SetSubtitleTrack(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 NextFile(int step);
- bool Playing(void) { return !(m_Error || cXinelibDevice::Instance().EndOfStreamReached()); }
- bool Error(void) { return m_Error; }
- void UseResumeFile(bool Val) { m_UseResumeFile = Val; }
-
- /* Playlist access */
- 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(); }
-};
-
-cXinelibPlayer::cXinelibPlayer(const char *File, bool Queue, const char *SubFile)
-{
- m_ResumeFile = NULL;
- m_UseResumeFile = true;
- m_Error = false;
- m_Speed = 1;
-
- if(File) {
- size_t len = strlen(File);
- if(len && File[len-1] == '/') {
- // whole directory, create temporary playlist
- m_Playlist.Read(File, true);
- m_Playlist.Sort();
- } else if(xc.IsPlaylistFile(File)) {
- m_Playlist.Read(File);
- } else {
- // a single file but not a playlist file, create playlist with only one item
- m_Playlist.Read(File);
- }
-
- if(m_Playlist.Count() < 1)
- LOGMSG("cXinelibPlayer: nothing to play !");
-
- if(m_Playlist.Count() > 0)
- m_Playlist.StartScanner();
-
- m_File = m_Playlist.Current()->Filename;
- m_SubFile = SubFile;
- }
-}
-
-cXinelibPlayer::~cXinelibPlayer()
-{
- Activate(false);
- Detach();
-}
-
-void cXinelibPlayer::SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
-{
- if(IS_DOLBY_TRACK(Type))
- Control("AUDIOSTREAM AC3 %d", (int)(Type - ttDolbyFirst));
- if(IS_AUDIO_TRACK(Type))
- Control("AUDIOSTREAM AC3 %d", (int)(Type - ttAudioFirst));
-}
-
-void cXinelibPlayer::SetSubtitleTrack(eTrackType Type, const tTrackId *TrackId)
-{
- cXinelibDevice::Instance().SetSubtitleTrackDevice(Type);
-}
-
-bool cXinelibPlayer::GetIndex(int &Current, int &Total, bool SnapToIFrame)
-{
- // 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;
-}
-
-bool cXinelibPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
-{
- // 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 true;
-}
-
-void cXinelibPlayer::SetSpeed(int Speed)
-{
- 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: m_Speed = 1;
- 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.Count()>0) {
- 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_SubFile = NULL;
-
- Activate(true);
- return !m_Error;
- }
-
- return false;
-}
-
-void cXinelibPlayer::UpdateNumTracks(void)
-{
- // cdda tracks
- if(m_Playlist.Count() == 1 && !strcmp("cdda:/", m_Playlist.First()->Filename)) {
- int count = cXinelibDevice::Instance().PlayFileCtrl("GETAUTOPLAYSIZE CD", 10000);
- if(count>0) {
- for(int i=0; i<count; i++)
- m_Playlist.Read(cString::sprintf("cdda:/%d", i+1));
- m_Playlist.Del(m_Playlist.First());
- }
- }
-}
-
-void cXinelibPlayer::Activate(bool On)
-{
- int pos = 0, len = 0, fd = -1;
- if(On) {
- if(m_UseResumeFile && !*m_ResumeFile)
- m_ResumeFile = cString::sprintf("%s.resume", *m_File);
- if(m_UseResumeFile && 0 <= (fd = open(m_ResumeFile, O_RDONLY))) {
- if(read(fd, &pos, sizeof(int)) != sizeof(int))
- pos = 0;
- close(fd);
- }
- // escape file name and join subtitle file
- // Maybe mrls from playlist files should not be escaped ?
- // (those may contain #subtitle, #volnorm etc. directives)
- cString mrl;
- if(*m_SubFile)
- mrl = cString::sprintf("%s%s#subtitle:%s%s",
- m_File[0] == '/' ? "file:" : "",
- *cPlaylist::EscapeMrl(m_File),
- m_SubFile[0] == '/' ? "file:" : "",
- *cPlaylist::EscapeMrl(m_SubFile));
- else if((*m_File)[0] == '/')
- mrl = cString::sprintf("%s%s",
- m_File[0] == '/' ? "file:" : "",
- *cPlaylist::EscapeMrl(m_File));
- else
- mrl = cPlaylist::EscapeMrl(m_File);
-
- // Start replay
- UpdateNumTracks();
- m_Error = !cXinelibDevice::Instance().PlayFile(mrl, pos);
- LOGDBG("cXinelibPlayer playing %s (%s)", *m_File, m_Error ? "FAIL" : "OK");
-
- if(!m_Error) {
- // update playlist metainfo
- const char *ti = cXinelibDevice::Instance().GetMetaInfo(miTitle);
- const char *tr = cXinelibDevice::Instance().GetMetaInfo(miTracknumber);
- const char *al = cXinelibDevice::Instance().GetMetaInfo(miAlbum);
- const char *ar = cXinelibDevice::Instance().GetMetaInfo(miArtist);
- if(ti && ti[0] && (!*m_Playlist.Current()->Title || !strstr(m_Playlist.Current()->Title, ti)))
- m_Playlist.Current()->Title = ti;
- if(tr && tr[0])
- m_Playlist.Current()->Tracknumber = tr;
- if(al && al[0])
- m_Playlist.Current()->Album = al;
- if(ar && ar[0])
- m_Playlist.Current()->Artist = ar;
-
- UpdateNumTracks();
- }
- } else {
- if(m_UseResumeFile && *m_ResumeFile) {
- pos = cXinelibDevice::Instance().PlayFileCtrl("GETPOS");
- len = cXinelibDevice::Instance().PlayFileCtrl("GETLENGTH");
- if(pos>10000 && pos < (len-10000)) {
- pos = (pos/1000) - 10; // skip back 10 seconds ("VDR style")
- 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);
- }
- } else {
- unlink(m_ResumeFile);
- }
- m_ResumeFile = NULL;
- }
- cXinelibDevice::Instance().PlayFile(NULL);
- m_Error = false;
- }
-}
-
-//
-// cPlaylistMenu
-//
-
-
-class cPlaylistMenu : public cOsdMenu, cPlaylistChangeNotify
-{
- protected:
-
- cPlaylist& m_Playlist;
- bool m_NeedsUpdate;
- bool& m_RandomPlay;
- cCharSetConv m_IC;
-
- public:
-
- cPlaylistMenu(cPlaylist &Playlist, bool& RandomPlay);
- virtual ~cPlaylistMenu();
-
- void Set(bool setCurrentPlaying = false);
- void SetCurrentExt(int i);
- void SetHelpButtons(void);
-
- // cOsdMenu
- virtual eOSState ProcessKey(eKeys Key);
-
- // cPlaylistChangeNotify
- virtual void PlaylistChanged(const cPlaylistItem *item);
-};
-
-cPlaylistMenu::cPlaylistMenu(cPlaylist &Playlist, bool& RandomPlay) :
- cOsdMenu(tr("Playlist")),
- m_Playlist(Playlist),
- m_RandomPlay(RandomPlay),
- m_IC("UTF-8", cCharSetConv::SystemCharacterTable())
-{
- SetTitle(cString::sprintf("%s: %s", tr("Playlist"), m_IC.Convert(*Playlist.Name())));
- Playlist.Listen(this);
- Set(true);
-}
-
-cPlaylistMenu::~cPlaylistMenu()
-{
- m_Playlist.Listen(NULL);
-}
-
-void cPlaylistMenu::PlaylistChanged(const cPlaylistItem *item)
-{
- m_NeedsUpdate = true;
-}
-
-eOSState cPlaylistMenu::ProcessKey(eKeys Key)
-{
- bool hadSubMenu = HasSubMenu();
-
- if(m_NeedsUpdate)
- Set();
-
- eOSState state = cOsdMenu::ProcessKey(Key);
-
- if(state == osUnknown) {
- switch(Key) {
- case kBack:
- return osEnd;
- case kRed:
- m_RandomPlay = !m_RandomPlay;
- SetHelpButtons();
- return osContinue;
- case kGreen:
- return AddSubMenu(cMenuXinelib::CreateMenuBrowseFiles(ShowMusic));
- case kYellow: if(m_Playlist.Count() > 1) {
- eOSState result = osContinue;
- cPlaylistItem *i = m_Playlist.Current();
- if(i->Index() == Current()) {
- if(i->Next())
- result = (eOSState)(os_User + i->Index()); /* forces jump to next item */
- else
- result = (eOSState)(os_User + i->Index() - 1);/* forces jump to last item */
- }
- for(i = m_Playlist.First(); i && i->Index() != Current(); i = m_Playlist.Next(i));
- if(i)
- m_Playlist.Del(i);
- if(Current() == Count()-1)
- SetCurrent(Get(Current()-1));
- Set();
- return result;
- }
- case kBlue:
- m_Playlist.Sort();
- Set();
- return osContinue;
- default: break;
- }
- }
-
- if(hadSubMenu && !HasSubMenu())
- Set();
-
- return state;
-}
-
-void cPlaylistMenu::SetCurrentExt(int i)
-{
- SetCurrent(Get(i));
- Set();
-}
-
-void cPlaylistMenu::SetHelpButtons(void)
-{
- SetHelp(!m_RandomPlay ? tr("Button$Random") : tr("Button$Normal"),
- tr("Button$Add files"),
- m_Playlist.Count()>1 ? tr("Button$Remove") : NULL,
- tr("Button$Sort"));
- Display();
-}
-
-void cPlaylistMenu::Set(bool setCurrentPlaying)
-{
- m_NeedsUpdate = false;
-
- int currentItem = Current();
- Clear();
- SetHasHotkeys();
- SetCols(2, 30);
- SetHelpButtons();
-
- int currentPlaying = m_Playlist.Current()->Index();
- int j = 0;
-
- for(cPlaylistItem *i = m_Playlist.First(); i; i = m_Playlist.Next(i), j++) {
- cString Title = cPlaylist::GetEntry(i, true, j==currentPlaying);
- Add(new cOsdItem(m_IC.Convert(*Title), (eOSState)(os_User + j)));
- }
-
- if(setCurrentPlaying)
- SetCurrent(Get(currentPlaying));
- else
- SetCurrent(Get(currentItem));
-
- Display();
-}
-
-
-//
-// cXinelibPlayerControl
-//
-
-#include <vdr/skins.h>
-
-cXinelibPlayer *cXinelibPlayerControl::m_Player = NULL;
-cMutex cXinelibPlayerControl::m_Lock;
-
-cXinelibPlayerControl::cXinelibPlayerControl(eMainMenuMode Mode, const char *File, const char *SubFile) :
- cControl(OpenPlayer(File, false, SubFile))
-{
- m_DisplayReplay = NULL;
- m_PlaylistMenu = NULL;
- m_ShowModeOnly = true;
- m_Mode = Mode;
- m_RandomPlay = false;
- m_AutoShowStart = time(NULL);
- m_BlinkState = true;
-
- number = 0;
- lastTime.Set();
-
- m_Player->UseResumeFile( (Mode==ShowFiles) );
-
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
-}
-
-cXinelibPlayerControl::~cXinelibPlayerControl()
-{
- if(m_PlaylistMenu) {
- delete m_PlaylistMenu;
- m_PlaylistMenu = NULL;
- }
- if(m_DisplayReplay) {
- delete m_DisplayReplay;
- m_DisplayReplay = NULL;
- }
-
- MsgReplaying(NULL, NULL);
- Close();
-}
-
-void cXinelibPlayerControl::MsgReplaying(const char *Title, const char *File)
-{
- cStatus::MsgReplaying(this, NULL, NULL, false);
- if(Title || File)
- cStatus::MsgReplaying(this, Title, File, true);
-}
-
-void cXinelibPlayerControl::Queue(const char *File)
-{
- if(!File)
- return;
-
- m_Lock.Lock();
-
- LOGMSG("cXinelibPlayerControl::Queue(%s)", File);
-
- if(!m_Player) {
- OpenPlayer(File, true);
- cControl::Launch(new cXinelibPlayerControl(ShowMusic, NULL));
- } else {
- size_t len = strlen(File);
- if(len && File[len-1] == '/')
- m_Player->Playlist().Read(File, true);
- else
- m_Player->Playlist().Read(File);
- }
-
- Skins.Message(mtInfo, tr("Queued to playlist"));
-
- m_Lock.Unlock();
-
- if(m_Player->Playlist().Count() > 0)
- m_Player->Playlist().StartScanner();
-
-}
-
-cXinelibPlayer *cXinelibPlayerControl::OpenPlayer(const char *File, bool Queue, const char *SubFile)
-{
- m_Lock.Lock();
- if(!m_Player)
- m_Player = new cXinelibPlayer(File, Queue, SubFile);
- m_Lock.Unlock();
- return m_Player;
-}
-
-void cXinelibPlayerControl::Close(void)
-{
- m_Lock.Lock();
- if(m_Player)
- delete m_Player;
- m_Player = NULL;
- m_Lock.Unlock();
-}
-
-void cXinelibPlayerControl::Show()
-{
- bool Play = (m_Player->Speed() > 0);
- bool Forward = true;
- int Speed = abs(m_Player->Speed()) - 2;
- if(Speed<-1) Speed=-1;
-
- if(!m_DisplayReplay) {
- if(cOsd::IsOpen())
- return;
- m_DisplayReplay = Skins.Current()->DisplayReplay(m_ShowModeOnly);
- }
-
- if(!m_ShowModeOnly) {
- char t[128] = "";
- 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 = cPlaylist::GetEntry(m_Player->Playlist().Current());
- cCharSetConv ic("UTF-8", cCharSetConv::SystemCharacterTable());
- m_DisplayReplay->SetTitle(ic.Convert(*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_BlinkState = (m_Player->Speed() != 0) || (!m_BlinkState);
- m_DisplayReplay->SetCurrent( m_BlinkState ? t : "");
- }
- }
-
- m_DisplayReplay->SetMode(Play, Forward, Speed);
-
- m_DisplayReplay->Flush();
-}
-
-void cXinelibPlayerControl::Hide()
-{
- if(m_PlaylistMenu) {
- delete m_PlaylistMenu;
- m_PlaylistMenu = NULL;
- }
- if(m_DisplayReplay) {
- delete m_DisplayReplay;
- m_DisplayReplay = NULL;
- }
-}
-
-cOsdObject *cXinelibPlayerControl::GetInfo(void)
-{
- return new cMetainfoMenu(m_Player->Playlist().Current()->Filename);
-}
-
-eOSState cXinelibPlayerControl::ProcessKey(eKeys Key)
-{
- if ( !m_Player->Playing() ) {
- LOGDBG("cXinelibPlayerControl: EndOfStreamReached");
- if (m_Mode == ShowMusic && m_Player->Files() == 1 && !m_Player->Error()) {
- m_Player->NextFile(0);
- return osContinue;
- }
- int Jump = 1;
- if(m_RandomPlay) {
- srand((unsigned int)time(NULL));
- Jump = (random() % m_Player->Files()) - m_Player->CurrentFile();
- }
- if(m_Player->Files() < 2 || !m_Player->NextFile(Jump)) {
- Hide();
- return osEnd;
- }
- if(m_PlaylistMenu) {
- m_PlaylistMenu->PlaylistChanged(m_Player->Playlist().Current());
- m_PlaylistMenu->SetCurrentExt(m_Player->CurrentFile());
- }
-
- if(!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
-
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- }
-
- else {
- // metainfo may change during playback (DVD titles, CDDA tracks)
- const char *ti = cXinelibDevice::Instance().GetMetaInfo(miTitle);
- if(ti && ti[0] && (!*m_Player->Playlist().Current()->Title ||
- !strstr(m_Player->Playlist().Current()->Title, ti))) {
- const char *tr = cXinelibDevice::Instance().GetMetaInfo(miTracknumber);
- const char *al = cXinelibDevice::Instance().GetMetaInfo(miAlbum);
- const char *ar = cXinelibDevice::Instance().GetMetaInfo(miArtist);
- LOGDBG("metainfo changed: %s->%s %s->%s %s->%s %s->%s",
- *m_Player->Playlist().Current()->Artist?:"-", ar?:"-",
- *m_Player->Playlist().Current()->Album ?:"-", al?:"-",
- *m_Player->Playlist().Current()->Tracknumber ?:"-", tr?:"-",
- *m_Player->Playlist().Current()->Title ?:"-", ti?:"-");
- m_Player->Playlist().Current()->Title = ti;
- if(tr && tr[0])
- m_Player->Playlist().Current()->Tracknumber = tr;
- if(al && al[0])
- m_Player->Playlist().Current()->Album = al;
- if(ar && ar[0])
- m_Player->Playlist().Current()->Artist = ar;
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- }
- }
-
- if(m_PlaylistMenu) {
- m_AutoShowStart = 0;
-
- eOSState state = osUnknown;
-
- switch(state=m_PlaylistMenu->ProcessKey(Key)) {
- case osBack:
- case osEnd: Hide(); break;
- default: if(state >= os_User) {
- m_Player->NextFile( (int)state - (int)os_User - m_Player->CurrentFile());
- m_PlaylistMenu->SetCurrentExt(m_Player->CurrentFile());
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- }
- break;
- }
-
- if(state != osUnknown)
- return osContinue;
- }
-
- if (m_DisplayReplay)
- Show();
-
- if ( m_Mode == ShowFiles ) {
- switch(Key) {
- case kRed: if(m_Player->Playlist().Count() > 1) {
- Hide();
- m_PlaylistMenu = new cPlaylistMenu(m_Player->Playlist(), m_RandomPlay);
- m_AutoShowStart = 0;
- } else {
- m_Player->Control("SEEK 0"); break;
- }
- break;
- case kUser8:
- case k1: m_Player->Control("SEEK -20"); break;
- case kUser9:
- case k3: m_Player->Control("SEEK +20"); break;
- case k2: xc.subtitle_vpos -= 10;
- case k5: xc.subtitle_vpos += 5;
- m_Player->Control("SUBTITLES %d", xc.subtitle_vpos);
- break;
- case kRight:
- {
- static const int speeds[] = { -3, -2, 1, 2, -4, 2, 3, 4, 4 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1)
- Show();
- else
- Hide();
- break;
- }
- case kLeft:
- {
- static const int speeds[] = { 0, -4, -3, -2, 0, -2, 1, 2, 3 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1 || !m_ShowModeOnly)
- Show();
- else
- Hide();
- break;
- }
- default: break;
- }
- }
- if ( m_Mode == ShowMusic ) {
- switch(Key) {
- case kRed: Hide();
- m_PlaylistMenu = new cPlaylistMenu(m_Player->Playlist(), m_RandomPlay);
- m_AutoShowStart = 0;
- break;
- case kNext:
- case kRight: if(m_RandomPlay) {
- srand((unsigned int)time(NULL));
- m_Player->NextFile((random() % m_Player->Files()) - m_Player->CurrentFile());
- }
- else {
- m_Player->NextFile(1);
- }
- if(!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- break;
- case kPrev:
- case kLeft: if(cXinelibDevice::Instance().PlayFileCtrl("GETPOS") < 3000) {
- m_Player->NextFile(-1);
- if(!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- }
- else {
- m_Player->NextFile(0);
- if(!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
- }
- break;
- case k0 ... k9:
- if (number >= 0) {
- if (number * 10 + Key - k0 > m_Player->Files())
- number = m_Player->Files();
- else
- number = number * 10 + Key - k0;
- }
- break;
- case kNone:
- if (number > 0 && int(lastTime.Elapsed()) > 3000) {
- m_Player->NextFile( number - (m_Player->CurrentFile() + 1) );
- if (!m_DisplayReplay)
- m_AutoShowStart = time(NULL);
- MsgReplaying(*m_Player->Playlist().Current()->Title, *m_Player->File());
- number = 0;
- lastTime.Set();
- }
- break;
- default: break;
- }
- }
- switch(Key) { // key bindings common for both players
- case kBack: xc.main_menu_mode = m_Mode;
- Hide();
- BackToMenu();
- break;
- case kStop:
- case kBlue: Hide();
- Close();
- return osEnd;
- case kUser7: if(m_Player->Playlist().Count()>1) {
- m_RandomPlay = !m_RandomPlay;
- if(m_RandomPlay)
- Skins.Message(mtInfo, tr("Random play"));
- else
- Skins.Message(mtInfo, tr("Normal play"));
- }
- break;
- case kGreen: m_Player->Control("SEEK -60"); break;
- case kYellow: m_Player->Control("SEEK +60"); break;
- case kUser8: m_Player->Control("SEEK -20"); break;
- case kUser9: m_Player->Control("SEEK +20"); break;
- case kDown:
- case kPause: if(m_Player->Speed()) {
- m_Player->SetSpeed(0);
- if(!m_DisplayReplay)
- m_ShowModeOnly = true;
- Show();
- break;
- }
- // fall thru
- case kUp:
- case kPlay: m_Player->SetSpeed(1);
- if(m_ShowModeOnly && m_DisplayReplay)
- Hide();
- else if(m_DisplayReplay)
- Show();
- m_ShowModeOnly = false;
- break;
- case kFastFwd:
- {
- static const int speeds[] = { -3, -2, 1, 2, -4, 2, 3, 4, 4 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1)
- Show();
- else
- Hide();
- break;
- }
- case kFastRew:
- {
- static const int speeds[] = { 0, -4, -3, -2, 0, -2, 1, 2, 3 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1 || !m_ShowModeOnly)
- Show();
- else
- Hide();
- break;
- }
- case kOk:
- m_AutoShowStart = 0;
- if(m_Player->Speed() != 1) {
- Hide();
- m_ShowModeOnly = !m_ShowModeOnly;
- Show();
- } else {
- if(m_DisplayReplay) {
- m_ShowModeOnly = true;
- Hide();
- } else {
- Hide();
- m_ShowModeOnly = false;
- Show();
- }
- }
- break;
- 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;
-}
-
-//
-// cDvdMenu
-//
-
-class cDvdMenu : public cOsdMenu {
- public:
- cDvdMenu(void) : cOsdMenu("DVD Menu")
- {
- Add(new cOsdItem("Exit DVD menu", osUser1));
- Add(new cOsdItem("DVD Root menu", osUser2));
- Add(new cOsdItem("DVD Title menu", osUser3));
- Add(new cOsdItem("DVD SPU menu", osUser4));
- Add(new cOsdItem("DVD Audio menu", osUser5));
- Add(new cOsdItem("Close menu", osEnd));
- Display();
- }
-};
-
-
-//
-// cXinelibDvdPlayerControl
-//
-
-cXinelibDvdPlayerControl::~cXinelibDvdPlayerControl()
-{
- if(Menu) {
- delete Menu;
- Menu = NULL;
- }
-}
-
-void cXinelibDvdPlayerControl::Hide(void)
-{
- if(Menu) {
- delete Menu;
- Menu = NULL;
- }
- cXinelibPlayerControl::Hide();
-}
-
-void cXinelibDvdPlayerControl::Show(void)
-{
- if(!Menu)
- cXinelibPlayerControl::Show();
- else
- cXinelibPlayerControl::Hide();
-}
-
-eOSState cXinelibDvdPlayerControl::ProcessKey(eKeys Key)
-{
- // Check for end of stream and failed open
- if ( !m_Player->Playing() ) {
- LOGDBG("cXinelibDvdPlayerControl: EndOfStreamReached");
- Hide();
- return osEnd;
- }
-
- // Update DVD title information
- const char *ti = cXinelibDevice::Instance().GetMetaInfo(miTitle);
- if (ti && ti[0] && (!m_CurrentDVDTitle || !strstr(m_CurrentDVDTitle, ti))) {
- memset(m_CurrentDVDTitle, 0, 63);
- strn0cpy(m_CurrentDVDTitle, ti, 63);
- m_Player->Playlist().Current()->Title = m_CurrentDVDTitle;
- MsgReplaying(m_CurrentDVDTitle, NULL);
- }
-
- // Handle menu selection
- if(Menu) {
- 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;
- }
- return osContinue;
- }
-
- // Update progress bar display
- if (m_DisplayReplay)
- Show();
-
- // Handle menu navigation
-
- bool MenuDomain = !xc.dvd_arrow_keys_control_playback;
- if(Key != kNone || m_DisplayReplay) {
- const char *dt = cXinelibDevice::Instance().GetMetaInfo(miDvdTitleNo);
- if(dt && !strcmp("0", dt))
- MenuDomain = true;
- else {
- dt = cXinelibDevice::Instance().GetMetaInfo(miDvdButtons);
- if(dt && *dt && *dt != '0')
- MenuDomain = true;
- }
- }
-
- if(MenuDomain) {
- if(m_DisplayReplay)
- Hide();
-
- switch(Key) {
- // DVD navigation
- 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;
- }
- }
-
- // Handle normal keys
-
- if(!MenuDomain) {
- switch(Key) {
- // Replay control
- case kUp: Key = kPlay; break;
- case kDown: Key = kPause; break;
- case kLeft: Key = kFastRew; break;
- case kRight: Key = kFastFwd; break;
- case kOk:
- if(m_Player->Speed() != 1) {
- Hide();
- m_ShowModeOnly = !m_ShowModeOnly;
- Show();
- break;
- }
- if(m_DisplayReplay) {
- Hide();
- m_ShowModeOnly = true;
- } else {
- Hide();
- m_ShowModeOnly = false;
- Show();
- }
- break;
- case kInfo: Hide();
- if(m_DisplayReplay && !m_ShowModeOnly) {
- m_ShowModeOnly = true;
- } else {
- m_ShowModeOnly = false;
- Show();
- }
- break;
- case kBack: xc.main_menu_mode = m_Mode;
- Hide();
- Close();
- return osEnd;
- default: break;
- }
- }
-
- switch(Key) {
- // DVD menus
- case kRed: Hide();
- Menu = new cDvdMenu();
- break;
- // Playback control
- case kGreen: m_Player->Control("SEEK -60"); break;
- case kYellow: m_Player->Control("SEEK +60"); break;
- case kUser8:
- case k1: m_Player->Control("SEEK -20"); break;
- case kUser9:
- case k3: m_Player->Control("SEEK +20"); break;
-
- case kStop:
- case kBlue: Hide();
- Close();
- return osEnd;
-
- 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: m_Player->Control("EVENT XINE_EVENT_INPUT_NEXT CHAPTER"); break;
- case k4:
- case kPrev: m_Player->Control("EVENT XINE_EVENT_INPUT_PREVIOUS CHAPTER"); break;
-
- case kFastFwd:
- {
- static const int speeds[] = { -3, -2, 1, 2, -4, 2, 3, 4, 4 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1)
- Show();
- else
- Hide();
- break;
- }
- case kFastRew:
- {
- static const int speeds[] = { 0, -4, -3, -2, 0, -2, 1, 2, 3 };
- m_Player->SetSpeed(speeds[m_Player->Speed() + 4]);
- if(m_Player->Speed() != 1 || !m_ShowModeOnly)
- Show();
- else
- Hide();
- break;
- }
- case kInfo: if(m_DisplayReplay) {
- Hide();
- } else {
- m_ShowModeOnly = false;
- Show();
- }
- break;
- case kPause: if(m_Player->Speed()) {
- m_Player->SetSpeed(0);
- m_ShowModeOnly = false;
- Show();
- break;
- }
- // fall thru
- case kPlay: m_Player->SetSpeed(1);
- m_ShowModeOnly = true;
- Hide();
- break;
- default: break;
- }
-
- return osContinue;
-}
-
-//
-// cXinelibImagePlayer
-//
-
-class cXinelibImagePlayer : public cPlayer {
- private:
- cString m_Mrl;
- bool m_Active;
- bool m_Error;
- cXinelibDevice *m_Dev;
-
- bool Play(void);
-
- protected:
- virtual void Activate(bool On);
-
- public:
- cXinelibImagePlayer(const char *File);
- virtual ~cXinelibImagePlayer();
-
- bool ShowImage(const char *File);
- bool Error(void) { return m_Error; }
-};
-
-cXinelibImagePlayer::cXinelibImagePlayer(const char *File)
-{
- m_Mrl = File;
- m_Active = false;
- m_Error = false;
- m_Dev = &(cXinelibDevice::Instance());
-}
-
-cXinelibImagePlayer::~cXinelibImagePlayer()
-{
- Activate(false);
- Detach();
-}
-
-bool cXinelibImagePlayer::Play(void)
-{
- if ((*m_Mrl)[0] == '/')
- m_Mrl = cString::sprintf("file:%s", *cPlaylist::EscapeMrl(m_Mrl));
-
- return m_Dev->PlayFile(m_Mrl, 0, true);
-}
-
-void cXinelibImagePlayer::Activate(bool On)
-{
- m_Active = On;
- m_Error = false;
- if (On)
- Play();
- else
- m_Dev->PlayFile(NULL);
-}
-
-bool cXinelibImagePlayer::ShowImage(const char *File)
-{
- m_Mrl = File;
- if (m_Active)
- return Play();
- return true;
-}
-
-
-//
-// cXinelibImagesControl
-//
-
-cXinelibImagePlayer *cXinelibImagesControl::m_Player = NULL;
-cMutex cXinelibImagesControl::m_Lock;
-
-cXinelibImagesControl::cXinelibImagesControl(char **Files, int Index, int Count) :
- cControl(OpenPlayer(Files[Index]))
-{
- m_DisplayReplay = NULL;
- m_Files = Files;
- m_File = NULL;
- m_Index = Index;
- m_Count = Count;
- m_Speed = 0;
- m_ShowModeOnly = false;
-
- Seek(0);
-}
-
-cXinelibImagesControl::~cXinelibImagesControl()
-{
- if(m_DisplayReplay)
- delete m_DisplayReplay;
- m_DisplayReplay = NULL;
-
- cStatus::MsgReplaying(this, NULL, NULL, false);
- Close();
-
- if(m_Files) {
- int i=0;
- while(m_Files[i]) {
- free(m_Files[i]);
- m_Files[i] = NULL;
- i++;
- }
- delete [] m_Files;
- m_Files = NULL;
- }
-}
-
-cXinelibImagePlayer *cXinelibImagesControl::OpenPlayer(const char *File)
-{
- m_Lock.Lock();
- if(!m_Player)
- m_Player = new cXinelibImagePlayer(File);
- m_Lock.Unlock();
- return m_Player;
-}
-
-void cXinelibImagesControl::Close(void)
-{
- m_Lock.Lock();
- if(m_Player)
- delete m_Player;
- m_Player = NULL;
- m_Lock.Unlock();
-}
-
-void cXinelibImagesControl::Delete(void)
-{
- if(Interface->Confirm(tr("Delete image ?"))) {
- if(!unlink(m_Files[m_Index])) {
- free(m_Files[m_Index]);
- for(int i=m_Index; i<m_Count; i++)
- m_Files[i] = m_Files[i+1];
- m_Count--;
- m_Files[m_Count] = NULL;
- Seek(0);
- }
- }
-}
-
-cOsdObject *cXinelibImagesControl::GetInfo(void)
-{
- return new cMetainfoMenu(m_Files[m_Index]);
-}
-
-void cXinelibImagesControl::Seek(int Rel)
-{
- if(m_Index == m_Count-1 && Rel>0)
- m_Index = 0;
- else if(m_Index == 0 && Rel<0)
- m_Index = m_Count-1;
- else
- m_Index += Rel;
-
- if(m_Index < 0)
- m_Index = 0;
- else if(m_Index >= m_Count)
- m_Index = m_Count;
-
- char *pt;
- free(m_File);
- m_File = strdup(m_Files[m_Index]);
- if(NULL != (pt=strrchr(m_File, '/')))
- strcpy(m_File, pt+1);
- if(NULL != (pt=strrchr(m_File, '.')))
- *pt = 0;
-
- cStatus::MsgReplaying(this, m_File, m_Files[m_Index], true);
-
- m_Player->ShowImage(m_Files[m_Index]);
- m_LastShowTime = time(NULL);
- strn0cpy(xc.browse_images_dir, m_Files[m_Index], sizeof(xc.browse_images_dir));
-}
-
-void cXinelibImagesControl::Show(void)
-{
- bool Play = (m_Speed!=0), Forward = m_Speed>=0;
- int Speed = abs(m_Speed);
-
- if(!m_DisplayReplay) {
- m_DisplayReplay = Skins.Current()->DisplayReplay(m_ShowModeOnly);
- }
-
- if(!m_ShowModeOnly) {
- char t[128] = "";
- m_DisplayReplay->SetTitle(m_File);
- m_DisplayReplay->SetProgress(m_Index, m_Count);
- sprintf(t, "%d", m_Count);
- m_DisplayReplay->SetTotal( t );
- sprintf(t, "%d", m_Index+1);
- m_DisplayReplay->SetCurrent( t );
- }
-
- m_DisplayReplay->SetMode(Play, Forward, Speed);
- m_DisplayReplay->Flush();
-}
-
-void cXinelibImagesControl::Hide(void)
-{
- if(m_DisplayReplay) {
- delete m_DisplayReplay;
- m_DisplayReplay = NULL;
- }
-}
-
-eOSState cXinelibImagesControl::ProcessKey(eKeys Key)
-{
- switch(Key) {
- case kBack: xc.main_menu_mode = ShowImages;
- Hide();
- Close();
- BackToMenu();
- //return osPlugin;
- return osEnd;
- case kYellow: Delete();
- break;
- case kStop:
- case kBlue: Hide();
- Close();
- return osEnd;
- case kPrev:
- case kLeft: Seek(-1);
- break;
- case kNext:
- case kRight: Seek(1);
- break;
- case kUp: Seek(5);
- break;
- case kDown: Seek(-5);
- break;
- case kPause: m_Speed = 0;
- break;
- case kPlay: m_Speed = 2;
- break;
- case kFastFwd: m_Speed++;
- break;
- case kFastRew: m_Speed--;
- break;
- case kOk: if(m_DisplayReplay) {
- if(m_ShowModeOnly) {
- Hide();
- m_ShowModeOnly = false;
- Show();
- } else {
- Hide();
- }
- } else {
- m_ShowModeOnly = true;
- Show();
- }
- break;
- default: break;
- }
-
- static const int Speed2Time[] = { 0, 5, 3, 1 };
- if(m_Speed > 3)
- m_Speed = 3;
- if(m_Speed < -3)
- m_Speed = -3;
-
- if(Key == kNone && m_Speed != 0) {
- if(m_LastShowTime + Speed2Time[m_Speed<0 ? -m_Speed : m_Speed] <= time(NULL))
- Seek(sgn(m_Speed));
- }
-
- if (m_DisplayReplay)
- Show();
-
- return osContinue;
-}