diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp index 26f55db3c9..a4d90e19b7 100644 --- a/src/apps/mediaplayer/Controller.cpp +++ b/src/apps/mediaplayer/Controller.cpp @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #include #include @@ -30,8 +33,10 @@ #include "SoundOutput.h" -#define AUDIO_PRIORITY 10 -#define VIDEO_PRIORITY 10 +#define AUDIO_PLAY_PRIORITY 10 +#define VIDEO_PLAY_PRIORITY 10 +#define AUDIO_DECODE_PRIORITY 10 +#define VIDEO_DECODE_PRIORITY 10 void HandleError(const char *text, status_t err) @@ -53,36 +58,61 @@ Controller::Controller() , fMediaFile(0) , fAudioTrack(0) , fVideoTrack(0) + , fAudioTrackLock("audio track lock") + , fVideoTrackLock("video track lock") , fAudioTrackList(new BList) , fVideoTrackList(new BList) , fPosition(0) - , fAudioPlaySem(create_sem(1, "audio playing")) - , fVideoPlaySem(create_sem(1, "video playing")) + , fAudioDecodeSem(-1) + , fVideoDecodeSem(-1) + , fAudioPlaySem(-1) + , fVideoPlaySem(-1) + , fAudioDecodeThread(-1) + , fVideoDecodeThread(-1) , fAudioPlayThread(-1) , fVideoPlayThread(-1) - , fStopAudioPlayback(false) - , fStopVideoPlayback(false) , fSoundOutput(NULL) , fSeekAudio(false) , fSeekVideo(false) , fSeekPosition(0) , fDuration(0) + , fAudioBufferCount(MAX_AUDIO_BUFFERS) + , fAudioBufferReadIndex(0) + , fAudioBufferWriteIndex(0) + , fVideoBufferCount(MAX_VIDEO_BUFFERS) + , fVideoBufferReadIndex(0) + , fVideoBufferWriteIndex(0) + , fTimeSourceLock("time source lock") + , fTimeSourceSysTime(0) + , fTimeSourcePerfTime(0) + , fAutoplay(true) + , fCurrentBitmap(NULL) { + for (int i = 0; i < MAX_AUDIO_BUFFERS; i++) { + fAudioBuffer[i].bitmap = NULL; + fAudioBuffer[i].buffer = NULL; + fAudioBuffer[i].sizeMax = 0; + } + for (int i = 0; i < MAX_VIDEO_BUFFERS; i++) { + fVideoBuffer[i].bitmap = NULL; + fVideoBuffer[i].buffer = NULL; + fVideoBuffer[i].sizeMax = 0; + } + + fStopped = fAutoplay ? false : true; + } Controller::~Controller() { - StopAudioPlayback(); - StopVideoPlayback(); + StopThreads(); if (fMediaFile) fMediaFile->ReleaseAllTracks(); delete fMediaFile; delete fAudioTrackList; delete fVideoTrackList; - delete_sem(fVideoPlaySem); - delete_sem(fAudioPlaySem); } @@ -90,6 +120,7 @@ void Controller::SetVideoView(VideoView *view) { fVideoView = view; + fVideoView->SetController(this); } @@ -103,11 +134,12 @@ Controller::SetControllerView(ControllerView *view) status_t Controller::SetTo(const entry_ref &ref) { - acquire_sem(fAudioPlaySem); - acquire_sem(fVideoPlaySem); - - StopAudioPlayback(); - StopVideoPlayback(); + StopThreads(); + + UpdatePosition(0); + + BAutolock al(fAudioTrackLock); + BAutolock vl(fVideoTrackLock); fAudioTrackList->MakeEmpty(); fVideoTrackList->MakeEmpty(); @@ -118,11 +150,13 @@ Controller::SetTo(const entry_ref &ref) fVideoTrack = 0; fMediaFile = 0; fPosition = 0; + fSeekAudio = false; + fSeekVideo = false; fPaused = false; - fStopped = true; + fStopped = fAutoplay ? false : true; fDuration = 0; fName = ref.name; - + status_t err; BMediaFile *mf = new BMediaFile(&ref); @@ -130,8 +164,6 @@ Controller::SetTo(const entry_ref &ref) if (err != B_OK) { printf("Controller::SetTo: initcheck failed\n"); delete mf; - release_sem(fAudioPlaySem); - release_sem(fVideoPlaySem); return err; } @@ -139,8 +171,6 @@ Controller::SetTo(const entry_ref &ref) if (trackcount <= 0) { printf("Controller::SetTo: trackcount %d\n", trackcount); delete mf; - release_sem(fAudioPlaySem); - release_sem(fVideoPlaySem); return B_MEDIA_NO_HANDLER; } @@ -167,8 +197,6 @@ Controller::SetTo(const entry_ref &ref) 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; } @@ -178,14 +206,34 @@ Controller::SetTo(const entry_ref &ref) SelectAudioTrack(0); SelectVideoTrack(0); - - release_sem(fAudioPlaySem); - release_sem(fVideoPlaySem); + + StartThreads(); return B_OK; } +void +Controller::GetSize(int *width, int *height) +{ +/* + media_format fmt; + buffer->mediaFormat.type = B_MEDIA_RAW_VIDEO; + buffer->mediaFormat.u.raw_video = media_raw_video_format::wildcard; + buffer->mediaFormat.u.raw_video.display.format = IsOverlayActive() ? B_YCbCr422 : B_RGB32; + if (fVideoTrack || B_OK != fVideoTrack->DecodedFormat(&fmt)) { +*/ + *height = 480; + *width = 640; +/* + } else { + *height = fmt.u.raw_video.display.line_count; + *width = fmt.u.raw_video.display.line_width; + } +*/ +} + + int Controller::VideoTrackCount() { @@ -202,9 +250,9 @@ Controller::AudioTrackCount() status_t Controller::SelectAudioTrack(int n) -{ - StopAudioPlayback(); - +{ + BAutolock al(fAudioTrackLock); + BMediaTrack *t = (BMediaTrack *)fAudioTrackList->ItemAt(n); if (!t) return B_ERROR; @@ -214,7 +262,6 @@ Controller::SelectAudioTrack(int n) bigtime_t v = fVideoTrack ? fVideoTrack->Duration() : 0; fDuration = max_c(a, v); - StartAudioPlayback(); return B_OK; } @@ -222,7 +269,7 @@ Controller::SelectAudioTrack(int n) status_t Controller::SelectVideoTrack(int n) { - StopVideoPlayback(); + BAutolock vl(fVideoTrackLock); BMediaTrack *t = (BMediaTrack *)fVideoTrackList->ItemAt(n); if (!t) @@ -233,7 +280,6 @@ Controller::SelectVideoTrack(int n) bigtime_t v = fVideoTrack ? fVideoTrack->Duration() : 0; fDuration = max_c(a, v); - StartVideoPlayback(); return B_OK; } @@ -307,7 +353,8 @@ Controller::UpdatePosition(float value) bool Controller::IsOverlayActive() { - return true; +// return true; + return false; } @@ -326,47 +373,51 @@ Controller::UnlockBitmap() BBitmap * Controller::Bitmap() { - return NULL; + return fCurrentBitmap; } void Controller::Stop() { + printf("Controller::Stop\n"); + if (fStopped) return; - - acquire_sem(fAudioPlaySem); - acquire_sem(fVideoPlaySem); fPaused = false; fStopped = true; - fPosition = 0; + + // böse... + snooze(30000); + fSeekAudio = true; + fSeekVideo = true; + fSeekPosition = 0; + snooze(30000); + UpdatePosition(0); } void Controller::Play() { + printf("Controller::Play\n"); + if (!fPaused && !fStopped) return; fStopped = fPaused = false; - - release_sem(fAudioPlaySem); - release_sem(fVideoPlaySem); } void Controller::Pause() { + printf("Controller::Pause\n"); + if (fStopped || fPaused) return; - - acquire_sem(fAudioPlaySem); - acquire_sem(fVideoPlaySem); fPaused = true; } @@ -379,6 +430,351 @@ Controller::IsPaused() } +bool +Controller::IsStopped() +{ + return fStopped; +} + + +void +Controller::AudioDecodeThread() +{ + BMediaTrack *lastTrack = 0; + size_t bufferSize = 0; + size_t frameSize = 0; + bool decodeError = false; + status_t status; + +printf("audio decode start\n"); + if (fAudioTrack == 0) { + return; + } + + + while (acquire_sem(fAudioDecodeSem) == B_OK) { +//printf("audio decoding..\n"); + buffer_info *buffer = &fAudioBuffer[fAudioBufferWriteIndex]; + fAudioBufferWriteIndex = (fAudioBufferWriteIndex + 1) % fAudioBufferCount; + BAutolock lock(fAudioTrackLock); + if (lastTrack != fAudioTrack) { +//printf("audio track changed\n"); + lastTrack = fAudioTrack; + buffer->formatChanged = true; + buffer->mediaFormat.type = B_MEDIA_RAW_AUDIO; + buffer->mediaFormat.u.raw_audio = media_multi_audio_format::wildcard; + #ifdef __HAIKU__ + buffer->mediaFormat.u.raw_audio.format = media_multi_audio_format::B_AUDIO_FLOAT; + #endif + status = fAudioTrack->DecodedFormat(&buffer->mediaFormat); + if (status != B_OK) { + printf("audio decoded format status %08x %s\n", status, strerror(status)); + return; + } + bufferSize = buffer->mediaFormat.u.raw_audio.buffer_size; + frameSize = (buffer->mediaFormat.u.raw_audio.format & 0xf) * buffer->mediaFormat.u.raw_audio.channel_count; + } else { + buffer->formatChanged = false; + } + if (buffer->sizeMax < bufferSize) { + delete buffer->buffer; + buffer->buffer = new char [bufferSize]; + buffer->sizeMax = bufferSize;; + } + + if (fSeekAudio) { + bigtime_t pos = fSeekPosition; + fAudioTrack->SeekToTime(&pos); + fSeekAudio = false; + decodeError = false; + } + + int64 frames; + media_header mh; + if (!decodeError) { + decodeError = B_OK != fAudioTrack->ReadFrames(buffer->buffer, &frames, &mh); + } + if (!decodeError) { + buffer->sizeUsed = frames * frameSize; + buffer->startTime = mh.start_time; + } else { + buffer->sizeUsed = 0; + buffer->startTime = 0; + } + + release_sem(fAudioPlaySem); + } +} + + +void +Controller::AudioPlayThread() +{ + SoundOutput *output = NULL; + bigtime_t bufferDuration = 0; + status_t status; + + +printf("audio play start\n"); + if (fAudioTrack == 0) { + fTimeSourceSysTime = 0; + fTimeSourcePerfTime = 0; + return; + } + + while (acquire_sem(fAudioPlaySem) == B_OK) { +//printf("audio playing..\n"); + buffer_info *buffer = &fAudioBuffer[fAudioBufferReadIndex]; + fAudioBufferReadIndex = (fAudioBufferReadIndex + 1) % fAudioBufferCount; + wait: + if (fPaused || fStopped) { +//printf("waiting..\n"); + status = acquire_sem_etc(fThreadWaitSem, 1, B_RELATIVE_TIMEOUT, 50000); + if (status != B_TIMED_OUT) + break; + goto wait; + } + if (buffer->formatChanged) { +//printf("format changed..\n"); + delete output; + output = new SoundOutput(fName.String(), buffer->mediaFormat.u.raw_audio); + bufferDuration = bigtime_t(1000000.0 * (buffer->mediaFormat.u.raw_audio.buffer_size / (buffer->mediaFormat.u.raw_audio.channel_count * (buffer->mediaFormat.u.raw_audio.format & 0xf))) / buffer->mediaFormat.u.raw_audio.frame_rate); + printf("audio format changed, new buffer duration %Ld\n", bufferDuration); + fSoundOutput = output; // hack... + } + if (output) { + if (buffer->sizeUsed) + output->Play(buffer->buffer, buffer->sizeUsed); + BAutolock lock(fTimeSourceLock); + fTimeSourceSysTime = system_time() + output->Latency() - bufferDuration; + fTimeSourcePerfTime = buffer->startTime; +// printf("timesource: sys: %Ld perf: %Ld\n", fTimeSourceSysTime, fTimeSourcePerfTime); + UpdatePosition(buffer->startTime / (float)Duration()); + } else { + debugger("kein SoundOutput"); + } + release_sem(fAudioDecodeSem); + } + delete output; + fSoundOutput = NULL; // hack... +} + + +void +Controller::VideoDecodeThread() +{ + BMediaTrack *lastTrack = 0; + size_t bufferSize = 0; + size_t bytePerRow = 0; + int lineWidth = 0; + int lineCount = 0; + bool decodeError = false; + status_t status; + +printf("video decode start\n"); + if (fVideoTrack == 0) { + return; + } + + while (acquire_sem(fVideoDecodeSem) == B_OK) { + buffer_info *buffer = &fVideoBuffer[fVideoBufferWriteIndex]; + fVideoBufferWriteIndex = (fVideoBufferWriteIndex + 1) % fVideoBufferCount; + BAutolock lock(fVideoTrackLock); + if (lastTrack != fVideoTrack) { +//printf("Video track changed\n"); + lastTrack = fVideoTrack; + buffer->formatChanged = true; + buffer->mediaFormat.type = B_MEDIA_RAW_VIDEO; + buffer->mediaFormat.u.raw_video = media_raw_video_format::wildcard; + buffer->mediaFormat.u.raw_video.display.format = IsOverlayActive() ? B_YCbCr422 : B_RGB32; + status = fVideoTrack->DecodedFormat(&buffer->mediaFormat); + if (status != B_OK) { + printf("video decoded format status %08x %s\n", status, strerror(status)); + return; + } + bytePerRow = buffer->mediaFormat.u.raw_video.display.bytes_per_row; + lineWidth = buffer->mediaFormat.u.raw_video.display.line_width; + lineCount = buffer->mediaFormat.u.raw_video.display.line_count; + bufferSize = lineCount * bytePerRow; + } else { + buffer->formatChanged = false; + } + if (buffer->sizeMax != bufferSize) { + BRect r(0, 0, lineWidth - 1, lineCount - 1); + delete buffer->bitmap; + printf("allocating bitmap %d %d %d\n", lineWidth, lineCount, bytePerRow); + if (IsOverlayActive()) + buffer->bitmap = new BBitmap(r, B_BITMAP_WILL_OVERLAY | (fVideoBufferWriteIndex == 1) ? B_BITMAP_RESERVE_OVERLAY_CHANNEL : 0, IsOverlayActive() ? B_YCbCr422 : B_RGB32, bytePerRow); + else + buffer->bitmap = new BBitmap(r, 0, B_RGB32, bytePerRow); + status = buffer->bitmap->InitCheck(); + if (status != B_OK) { + printf("video decoded format status %08x %s\n", status, strerror(status)); + return; + } + buffer->buffer = (char *)buffer->bitmap->Bits(); + buffer->sizeMax = bufferSize; + } + + if (fSeekVideo) { + bigtime_t pos = fSeekPosition; + fVideoTrack->SeekToTime(&pos); + fSeekVideo = false; + decodeError = false; + } + + int64 frames; + media_header mh; + if (!decodeError) { +// printf("reading video frame...\n"); + decodeError = B_OK != fVideoTrack->ReadFrames(buffer->buffer, &frames, &mh); + } + if (!decodeError) { + buffer->sizeUsed = buffer->sizeMax; + buffer->startTime = mh.start_time; + } else { + buffer->sizeUsed = 0; + buffer->startTime = 0; + } + + release_sem(fVideoPlaySem); + } +} + + +void +Controller::VideoPlayThread() +{ + status_t status; +printf("video decode start\n"); + if (fVideoTrack == 0) { + return; + } + + while (acquire_sem(fVideoPlaySem) == B_OK) { + + buffer_info *buffer = &fVideoBuffer[fVideoBufferReadIndex]; + fVideoBufferReadIndex = (fVideoBufferReadIndex + 1) % fVideoBufferCount; + wait: + if (fPaused || fStopped) { +//printf("waiting..\n"); + status = acquire_sem_etc(fThreadWaitSem, 1, B_RELATIVE_TIMEOUT, 50000); + if (status != B_TIMED_OUT) + break; + goto wait; + } + + bigtime_t waituntil; + bigtime_t waitdelta; + char test[100]; + { + BAutolock lock(fTimeSourceLock); + + waituntil = fTimeSourceSysTime - fTimeSourcePerfTime + buffer->startTime; + waitdelta = waituntil - system_time(); +/* + sprintf(test, "sys %.6f perf %.6f, vid %.6f, waituntil %.6f, waitdelta %.6f", + fTimeSourceSysTime / 1000000.0f, + fTimeSourcePerfTime / 1000000.0f, + buffer->startTime / 1000000.0f, + waituntil / 1000000.0f, + waitdelta / 1000000.0f); + */ +// if (status != B_TIMED_OUT) + } +/* + if (fVideoView->LockLooperWithTimeout(5000) == B_OK) { + fVideoView->Window()->SetTitle(test); + fVideoView->UnlockLooper(); + } +*/ + status = acquire_sem_etc(fThreadWaitSem, 1, B_ABSOLUTE_TIMEOUT, waituntil); + if (status != B_TIMED_OUT) + break; + + fCurrentBitmap = buffer->bitmap; + fVideoView->DrawFrame(); + + // snooze(60000); + release_sem(fVideoDecodeSem); + } + +// status_t status = acquire_sem_etc(fThreadWaitSem, 1, B_ABSOLUTE_TIMEOUT, buffer->startTime); +// if (status != B_TIMED_OUT) +// return; +} + + +void +Controller::StartThreads() +{ + if (fAudioDecodeSem > 0) + return; + + fAudioBufferReadIndex = 0; + fAudioBufferWriteIndex = 0; + fVideoBufferReadIndex = 0; + fVideoBufferWriteIndex = 0; + fAudioDecodeSem = create_sem(fAudioBufferCount, "audio decode sem"); + fVideoDecodeSem = create_sem(fVideoBufferCount - 2, "video decode sem"); + fAudioPlaySem = create_sem(0, "audio play sem"); + fVideoPlaySem = create_sem(0, "video play sem"); + fThreadWaitSem = create_sem(0, "thread wait sem"); + fAudioDecodeThread = spawn_thread(audio_decode_thread, "audio decode", AUDIO_DECODE_PRIORITY, this); + fVideoDecodeThread = spawn_thread(video_decode_thread, "video decode", VIDEO_DECODE_PRIORITY, this); + fAudioPlayThread = spawn_thread(audio_play_thread, "audio play", AUDIO_PLAY_PRIORITY, this); + fVideoPlayThread = spawn_thread(video_play_thread, "video play", VIDEO_PLAY_PRIORITY, this); + resume_thread(fAudioDecodeThread); + resume_thread(fVideoDecodeThread); + resume_thread(fAudioPlayThread); + resume_thread(fVideoPlayThread); +} + + +void +Controller::StopThreads() +{ + if (fAudioDecodeSem < 0) + return; + + delete_sem(fAudioDecodeSem); + delete_sem(fVideoDecodeSem); + delete_sem(fAudioPlaySem); + delete_sem(fVideoPlaySem); + delete_sem(fThreadWaitSem); + + status_t dummy; + wait_for_thread(fAudioDecodeThread, &dummy); + wait_for_thread(fVideoDecodeThread, &dummy); + wait_for_thread(fAudioPlayThread, &dummy); + wait_for_thread(fVideoPlayThread, &dummy); + fAudioDecodeThread = -1; + fVideoDecodeThread = -1; + fAudioPlayThread = -1; + fVideoPlayThread = -1; + fThreadWaitSem = -1; + fAudioDecodeSem = -1; + fVideoDecodeSem = -1; + fAudioPlaySem = -1; + fVideoPlaySem = -1; +} + +int32 +Controller::audio_decode_thread(void *self) +{ + static_cast(self)->AudioDecodeThread(); + return 0; +} + + +int32 +Controller::video_decode_thread(void *self) +{ + static_cast(self)->VideoDecodeThread(); + return 0; +} + + int32 Controller::audio_play_thread(void *self) { @@ -393,96 +789,3 @@ Controller::video_play_thread(void *self) static_cast(self)->VideoPlayThread(); return 0; } - - -void -Controller::AudioPlayThread() -{ - // this is a test... - media_format fmt; - fmt.type = B_MEDIA_RAW_AUDIO; - fmt.u.raw_audio = media_multi_audio_format::wildcard; -#ifdef __HAIKU__ - fmt.u.raw_audio.format = media_multi_audio_format::B_AUDIO_FLOAT; -#endif - fAudioTrack->DecodedFormat(&fmt); - - SoundOutput out(fName.String(), fmt.u.raw_audio); - - out.SetVolume(1.0); - UpdateVolume(1.0); - - - int frame_size = (fmt.u.raw_audio.format & 0xf) * fmt.u.raw_audio.channel_count; - uint8 buffer[fmt.u.raw_audio.buffer_size]; - int64 frames; - media_header mh; - - fSoundOutput = &out; - while (!fStopAudioPlayback) { - if (B_OK == fAudioTrack->ReadFrames(buffer, &frames, &mh)) { - out.Play(buffer, frames * frame_size); - UpdatePosition(mh.start_time / (float)Duration()); - } else { - snooze(50000); - } - if (fSeekAudio) { - bigtime_t pos = fSeekPosition; - fAudioTrack->SeekToTime(&pos); - fSeekAudio = false; - } - } - fSoundOutput = NULL; -} - - -void -Controller::VideoPlayThread() -{ -} - - -void -Controller::StartAudioPlayback() -{ - if (fAudioPlayThread > 0) - return; - fStopAudioPlayback = false; - fAudioPlayThread = spawn_thread(audio_play_thread, "audio playback", AUDIO_PRIORITY, this); - resume_thread(fAudioPlayThread); -} - - -void -Controller::StartVideoPlayback() -{ - if (fVideoPlayThread > 0) - return; - fStopVideoPlayback = false; - fVideoPlayThread = spawn_thread(video_play_thread, "video playback", VIDEO_PRIORITY, this); - resume_thread(fVideoPlayThread); -} - - -void -Controller::StopAudioPlayback() -{ - if (fAudioPlayThread < 0) - return; - fStopAudioPlayback = true; - status_t dummy; - wait_for_thread(fAudioPlayThread, &dummy); - fAudioPlayThread = -1; -} - - -void -Controller::StopVideoPlayback() -{ - if (fVideoPlayThread < 0) - return; - fStopVideoPlayback = true; - status_t dummy; - wait_for_thread(fVideoPlayThread, &dummy); - fVideoPlayThread = -1; -} diff --git a/src/apps/mediaplayer/Controller.h b/src/apps/mediaplayer/Controller.h index d5cdced57c..05a7623194 100644 --- a/src/apps/mediaplayer/Controller.h +++ b/src/apps/mediaplayer/Controller.h @@ -22,6 +22,7 @@ #include #include +#include #include class BBitmap; @@ -38,6 +39,7 @@ public: virtual ~Controller(); status_t SetTo(const entry_ref &ref); + void GetSize(int *width, int *height); int AudioTrackCount(); int VideoTrackCount(); @@ -54,6 +56,7 @@ public: void Play(); void Pause(); bool IsPaused(); + bool IsStopped(); void SetVideoView(VideoView *view); void SetControllerView(ControllerView *view); @@ -75,43 +78,89 @@ public: void UpdatePosition(float value); private: + static int32 audio_decode_thread(void *self); + static int32 video_decode_thread(void *self); static int32 audio_play_thread(void *self); static int32 video_play_thread(void *self); + void AudioDecodeThread(); + void VideoDecodeThread(); void AudioPlayThread(); void VideoPlayThread(); + + void StartThreads(); + void StopThreads(); - void StartAudioPlayback(); - void StartVideoPlayback(); - void StopAudioPlayback(); - void StopVideoPlayback(); - private: + + enum { + MAX_AUDIO_BUFFERS = 8, + MAX_VIDEO_BUFFERS = 3, + }; + + struct buffer_info { + char * buffer; + BBitmap * bitmap; + size_t sizeUsed; + size_t sizeMax; + bigtime_t startTime; + bool formatChanged; + media_format mediaFormat; + }; + VideoView * fVideoView; ControllerView * fControllerView; BString fName; - bool fPaused; - bool fStopped; + volatile bool fPaused; + volatile bool fStopped; BMediaFile * fMediaFile; BMediaTrack * fAudioTrack; BMediaTrack * fVideoTrack; + + BLocker fAudioTrackLock; + BLocker fVideoTrackLock; + BList * fAudioTrackList; BList * fVideoTrackList; bigtime_t fPosition; media_format fAudioFormat; media_format fVideoFormat; + + sem_id fAudioDecodeSem; + sem_id fVideoDecodeSem; sem_id fAudioPlaySem; sem_id fVideoPlaySem; + sem_id fThreadWaitSem; + thread_id fAudioDecodeThread; + thread_id fVideoDecodeThread; thread_id fAudioPlayThread; thread_id fVideoPlayThread; - volatile bool fStopAudioPlayback; - volatile bool fStopVideoPlayback; + SoundOutput * fSoundOutput; volatile bool fSeekAudio; volatile bool fSeekVideo; volatile bigtime_t fSeekPosition; bigtime_t fDuration; + + int32 fAudioBufferCount; + int32 fAudioBufferReadIndex; + int32 fAudioBufferWriteIndex; + int32 fVideoBufferCount; + int32 fVideoBufferReadIndex; + int32 fVideoBufferWriteIndex; + + buffer_info fAudioBuffer[MAX_AUDIO_BUFFERS]; + buffer_info fVideoBuffer[MAX_VIDEO_BUFFERS]; + + BLocker fTimeSourceLock; + bigtime_t fTimeSourceSysTime; + bigtime_t fTimeSourcePerfTime; + bool fAutoplay; + + BBitmap * fCurrentBitmap; + }; #endif + diff --git a/src/apps/mediaplayer/ControllerView.cpp b/src/apps/mediaplayer/ControllerView.cpp index 5098cdfa29..42782237a2 100644 --- a/src/apps/mediaplayer/ControllerView.cpp +++ b/src/apps/mediaplayer/ControllerView.cpp @@ -77,7 +77,7 @@ void ControllerView::TogglePlaying() { printf("ControllerView::TogglePlaying()\n"); - if (fController->IsPaused()) + if (fController->IsPaused() || fController->IsStopped()) fController->Play(); else fController->Pause(); diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp index c1ae350ca2..216cfbbb14 100644 --- a/src/apps/mediaplayer/MainWin.cpp +++ b/src/apps/mediaplayer/MainWin.cpp @@ -199,10 +199,9 @@ MainWin::SetupWindow() fVideoMenu->ItemAt(0)->SetMarked(true); if (fHasVideo) { - fSourceWidth = 320; - fSourceHeight = 240; - fWidthScale = 1.24; - fHeightScale = 1.35; + fController->GetSize(&fSourceWidth, &fSourceHeight); + fWidthScale = 1.0; + fHeightScale = 1.0; } else { fSourceWidth = 0; fSourceHeight = 0; diff --git a/src/apps/mediaplayer/SoundOutput.cpp b/src/apps/mediaplayer/SoundOutput.cpp index 35f96d28e4..6b77e1bcfc 100644 --- a/src/apps/mediaplayer/SoundOutput.cpp +++ b/src/apps/mediaplayer/SoundOutput.cpp @@ -108,7 +108,7 @@ void SoundOutput::PlayBuffer(void *buffer) { if (acquire_sem_etc(fBufferReadable, 1, B_RELATIVE_TIMEOUT, fBufferDuration / 2) != B_OK) { - printf("SoundOutput: buffer not ready, playing silence\n"); +// printf("SoundOutput: buffer not ready, playing silence\n"); memset(buffer, 0, fBufferSize); return; } diff --git a/src/apps/mediaplayer/VideoView.cpp b/src/apps/mediaplayer/VideoView.cpp index b976d7ce28..99ba05defc 100644 --- a/src/apps/mediaplayer/VideoView.cpp +++ b/src/apps/mediaplayer/VideoView.cpp @@ -29,8 +29,10 @@ VideoView::VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 fl , fController(NULL) , fOverlayActive(false) { -// SetViewColor(B_TRANSPARENT_COLOR); - SetViewColor(127,255,127); + SetViewColor(B_TRANSPARENT_COLOR); +// SetViewColor(127,255,127); + rgb_color r = {255, 0, 0, 255}; + fOverlayKeyColor = r; } @@ -39,6 +41,13 @@ VideoView::~VideoView() } +void +VideoView::SetController(Controller *controller) +{ + fController = controller; +} + + void VideoView::AttachedToWindow() { @@ -163,12 +172,13 @@ VideoView::DrawFrame() printf("can't ClearViewOverlay, as LockLooperWithTimeout failed\n"); } } - if (want_overlay && !fOverlayActive) { + if (want_overlay && !fOverlayActive ) { fController->LockBitmap(); - BBitmap *bmp = 0; // fController->Bitmap(); + BBitmap *bmp = fController->Bitmap(); if (bmp && LockLooperWithTimeout(50000) == B_OK) { SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor, - B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL); + B_FOLLOW_ALL, + /*B_OVERLAY_TRANSFER_CHANNEL | */B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL ); fOverlayActive = true; Invalidate(); @@ -228,7 +238,7 @@ VideoView::IsOverlaySupported() bool supported = false; for (int i = 0; colspace[i].name; i++) { - BBitmap *test = new BBitmap(BRect(0,0,320,240), B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL, colspace[i].colspace); + BBitmap *test = new BBitmap(BRect(0,0,319,239), B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL, colspace[i].colspace); if (test->InitCheck() == B_OK) { printf("Display supports %s (0x%08x) overlay\n", colspace[i].name, colspace[i].colspace); supported = true; diff --git a/src/apps/mediaplayer/VideoView.h b/src/apps/mediaplayer/VideoView.h index 979c6bb758..fcfb99fd6c 100644 --- a/src/apps/mediaplayer/VideoView.h +++ b/src/apps/mediaplayer/VideoView.h @@ -28,6 +28,8 @@ class VideoView : public BView public: VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags); ~VideoView(); + + void SetController(Controller *controller); void RemoveVideoDisplay(); void RemoveOverlay();