diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp index 558f34c61a..a50627cfa3 100644 --- a/src/apps/mediaplayer/Controller.cpp +++ b/src/apps/mediaplayer/Controller.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "Controller.h" #include "VideoView.h" @@ -37,12 +39,29 @@ HandleError(const char *text, status_t err) Controller::Controller() : fVideoView(NULL) + , fPaused(false) + , fStopped(true) + , fMediaFile(0) + , fAudioTrack(0) + , fVideoTrack(0) + , fAudioTrackList(new BList) + , fVideoTrackList(new BList) + , fPosition(0) + , fAudioPlaySem(create_sem(1, "audio playing")) + , fVideoPlaySem(create_sem(1, "video playing")) { } Controller::~Controller() { + if (fMediaFile) + fMediaFile->ReleaseAllTracks(); + delete fMediaFile; + delete fAudioTrackList; + delete fVideoTrackList; + delete_sem(fVideoPlaySem); + delete_sem(fAudioPlaySem); } @@ -56,6 +75,80 @@ Controller::SetVideoView(VideoView *view) status_t Controller::SetTo(const entry_ref &ref) { + acquire_sem(fAudioPlaySem); + acquire_sem(fVideoPlaySem); + + fAudioTrackList->MakeEmpty(); + fVideoTrackList->MakeEmpty(); + if (fMediaFile) + fMediaFile->ReleaseAllTracks(); + delete fMediaFile; + fAudioTrack = 0; + fVideoTrack = 0; + fMediaFile = 0; + fPosition = 0; + fPaused = false; + fStopped = true; + + status_t err; + + BMediaFile *mf = new BMediaFile(&ref); + err = mf->InitCheck(); + if (err != B_OK) { + printf("Controller::SetTo: initcheck failed\n"); + delete mf; + release_sem(fAudioPlaySem); + release_sem(fVideoPlaySem); + return err; + } + + int trackcount = mf->CountTracks(); + if (trackcount <= 0) { + printf("Controller::SetTo: trackcount %d\n", trackcount); + delete mf; + release_sem(fAudioPlaySem); + release_sem(fVideoPlaySem); + return B_MEDIA_NO_HANDLER; + } + + for (int i = 0; i < trackcount; i++) { + BMediaTrack *t = mf->TrackAt(i); + media_format f; + err = t->EncodedFormat(&f); + if (err != B_OK) { + printf("Controller::SetTo: EncodedFormat failed for track index %d, error 0x%08lx (%s)\n", + i, err, strerror(err)); + mf->ReleaseTrack(t); + continue; + } + if (f.IsAudio()) { + fAudioTrackList->AddItem(t); + } else if (f.IsVideo()) { + fVideoTrackList->AddItem(t); + } else { + printf("Controller::SetTo: track index %d has unknown type\n", i); + mf->ReleaseTrack(t); + } + } + + if (AudioTrackCount() == 0 && VideoTrackCount() == 0) { + printf("Controller::SetTo: no audio or video tracks found\n"); + delete mf; + release_sem(fAudioPlaySem); + release_sem(fVideoPlaySem); + return B_MEDIA_NO_HANDLER; + } + + printf("Controller::SetTo: %d audio track, %d video track\n", AudioTrackCount(), VideoTrackCount()); + + fMediaFile = mf; + + SelectAudioTrack(0); + SelectVideoTrack(0); + + release_sem(fAudioPlaySem); + release_sem(fVideoPlaySem); + return B_OK; } @@ -63,14 +156,62 @@ Controller::SetTo(const entry_ref &ref) int Controller::VideoTrackCount() { - return 3; + return fVideoTrackList->CountItems(); } int Controller::AudioTrackCount() { - return 6; + return fAudioTrackList->CountItems(); +} + + +status_t +Controller::SelectAudioTrack(int n) +{ + BMediaTrack *t = (BMediaTrack *)fAudioTrackList->ItemAt(n); + if (!t) + return B_ERROR; + fAudioTrack = t; + + return B_OK; +} + + +status_t +Controller::SelectVideoTrack(int n) +{ + BMediaTrack *t = (BMediaTrack *)fVideoTrackList->ItemAt(n); + if (!t) + return B_ERROR; + fVideoTrack = t; + + return B_OK; +} + + +bigtime_t +Controller::Duration() +{ + bigtime_t a = fAudioTrack ? fAudioTrack->Duration() : 0; + bigtime_t v = fVideoTrack ? fVideoTrack->Duration() : 0; + printf("Controller::Duration: audio %.6f, video %.6f", a / 1000000.0, v / 1000000.0); + return max_c(a, v); +} + + +bigtime_t +Controller::Position() +{ + return fPosition; +} + + +status_t +Controller::Seek(bigtime_t pos) +{ + return B_OK; } @@ -115,23 +256,47 @@ Controller::Bitmap() void Controller::Stop() { + if (fStopped) + return; + + acquire_sem(fAudioPlaySem); + acquire_sem(fVideoPlaySem); + + fPaused = false; + fStopped = true; + fPosition = 0; } void Controller::Play() { + if (!fPaused && !fStopped) + return; + + fStopped = + fPaused = false; + + release_sem(fAudioPlaySem); + release_sem(fVideoPlaySem); } void Controller::Pause() { + if (fStopped || fPaused) + return; + + acquire_sem(fAudioPlaySem); + acquire_sem(fVideoPlaySem); + + fPaused = true; } bool Controller::IsPaused() { - return false; + return fPaused; } diff --git a/src/apps/mediaplayer/Controller.h b/src/apps/mediaplayer/Controller.h index 0c5130f2db..b0c2ee03bd 100644 --- a/src/apps/mediaplayer/Controller.h +++ b/src/apps/mediaplayer/Controller.h @@ -34,6 +34,17 @@ public: status_t SetTo(const entry_ref &ref); + int AudioTrackCount(); + int VideoTrackCount(); + + status_t SelectAudioTrack(int n); + status_t SelectVideoTrack(int n); + + bigtime_t Duration(); + bigtime_t Position(); + + status_t Seek(bigtime_t pos); + void Stop(); void Play(); void Pause(); @@ -49,14 +60,24 @@ public: void VolumeUp(); void VolumeDown(); - - int VideoTrackCount(); - int AudioTrackCount(); private: private: VideoView * fVideoView; + + bool fPaused; + bool fStopped; + BMediaFile * fMediaFile; + BMediaTrack * fAudioTrack; + BMediaTrack * fVideoTrack; + BList * fAudioTrackList; + BList * fVideoTrackList; + bigtime_t fPosition; + media_format fAudioFormat; + media_format fVideoFormat; + sem_id fAudioPlaySem; + sem_id fVideoPlaySem; };