From 2a72b9fead28a8cb1cad04c7a8bb023adb41bea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Tue, 5 Jun 2007 23:23:44 +0000 Subject: [PATCH] * re-enabled the InfoWin git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21335 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/mediaplayer/Controller.cpp | 207 +++++--- src/apps/mediaplayer/Controller.h | 14 +- src/apps/mediaplayer/InfoWin.cpp | 474 +++++++++--------- src/apps/mediaplayer/InfoWin.h | 10 +- src/apps/mediaplayer/MainWin.cpp | 6 - src/apps/mediaplayer/supplier/AudioSupplier.h | 6 + .../supplier/MediaTrackAudioSupplier.cpp | 26 + .../supplier/MediaTrackAudioSupplier.h | 3 + .../supplier/MediaTrackVideoSupplier.cpp | 18 + .../supplier/MediaTrackVideoSupplier.h | 3 + src/apps/mediaplayer/supplier/VideoSupplier.h | 5 + 11 files changed, 450 insertions(+), 322 deletions(-) diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp index 7fbe1f3327..b0bebce5d4 100644 --- a/src/apps/mediaplayer/Controller.cpp +++ b/src/apps/mediaplayer/Controller.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "ControllerView.h" #include "PlaybackState.h" @@ -81,17 +82,12 @@ void Controller::Listener::VolumeChanged(float) {} Controller::Controller() : fVideoView(NULL) - , fName() , fPaused(false) , fStopped(true) , fVolume(1.0) , fRef() , fMediaFile(0) -// TODO: remove, InfoWin depends on it but should be fixed -,fAudioTrack(0) -,fVideoTrack(0) -// , fDataLock("controller data lock") , fVideoSupplier(NULL) @@ -225,7 +221,6 @@ Controller::SetTo(const entry_ref &ref) fPauseAtEndOfStream = false; fSeekToStartAfterPause = false; fDuration = 0; - fName = ref.name; _UpdatePosition(0); @@ -292,19 +287,16 @@ Controller::SetTo(const entry_ref &ref) void Controller::GetSize(int *width, int *height) { - // you need to hole the data lock + BAutolock _(fVideoSupplierLock); - media_format format; - format.type = B_MEDIA_RAW_VIDEO; - format.u.raw_video = media_raw_video_format::wildcard; - format.u.raw_video.display.format = IsOverlayActive() ? B_YCbCr422 : B_RGB32; - - if (!fVideoTrack || B_OK != fVideoTrack->DecodedFormat(&format)) { - *height = 480; - *width = 640; - } else { + if (fVideoSupplier) { + media_format format = fVideoSupplier->Format(); + // TODO: take aspect ratio into account! *height = format.u.raw_video.display.line_count; *width = format.u.raw_video.display.line_width; + } else { + *height = 480; + *width = 640; } } @@ -312,7 +304,8 @@ Controller::GetSize(int *width, int *height) int Controller::AudioTrackCount() { - // you need to hole the data lock + BAutolock _(fDataLock); + return fAudioTrackList->CountItems(); } @@ -320,7 +313,8 @@ Controller::AudioTrackCount() int Controller::VideoTrackCount() { - // you need to hole the data lock + BAutolock _(fDataLock); + return fVideoTrackList->CountItems(); } @@ -334,7 +328,6 @@ Controller::SelectAudioTrack(int n) if (!track) return B_ERROR; -fAudioTrack = track; delete fAudioSupplier; fAudioSupplier = new MediaTrackAudioSupplier(track); @@ -356,7 +349,6 @@ Controller::SelectVideoTrack(int n) if (!track) return B_ERROR; -fVideoTrack = track; delete fVideoSupplier; fVideoSupplier = new MediaTrackVideoSupplier(track, IsOverlayActive() ? B_YCbCr422 : B_RGB32); @@ -373,43 +365,6 @@ fVideoTrack = track; // #pragma mark - -void -Controller::SetVolume(float value) -{ - printf("Controller::SetVolume %.4f\n", value); - if (Lock()) { - fVolume = value; - if (fSoundOutput) - fSoundOutput->SetVolume(fVolume); - Unlock(); - } -} - - -float -Controller::Volume() const -{ - BAutolock _(fDataLock); - - return fVolume; -} - - -void -Controller::SetPosition(float value) -{ - printf("Controller::SetPosition %.4f\n", value); - - BAutolock _(fDataLock); - - fSeekPosition = bigtime_t(value * Duration()); - fSeekAudio = true; - fSeekVideo = true; - - fSeekToStartAfterPause = false; -} - - void Controller::Stop() { @@ -532,6 +487,142 @@ Controller::Position() } +void +Controller::SetVolume(float value) +{ + printf("Controller::SetVolume %.4f\n", value); + if (Lock()) { + fVolume = value; + if (fSoundOutput) + fSoundOutput->SetVolume(fVolume); + Unlock(); + } +} + + +float +Controller::Volume() const +{ + BAutolock _(fDataLock); + + return fVolume; +} + + +void +Controller::SetPosition(float value) +{ + printf("Controller::SetPosition %.4f\n", value); + + BAutolock _(fDataLock); + + fSeekPosition = bigtime_t(value * Duration()); + fSeekAudio = true; + fSeekVideo = true; + + fSeekToStartAfterPause = false; +} + + +// #pragma mark - + + +bool +Controller::HasFile() +{ + // you need to hold the data lock + return fMediaFile != NULL; +} + + +status_t +Controller::GetFileFormatInfo(media_file_format* fileFormat) +{ + // you need to hold the data lock + if (!fMediaFile) + return B_NO_INIT; + return fMediaFile->GetFileFormatInfo(fileFormat); +} + + +status_t +Controller::GetCopyright(BString* copyright) +{ + // you need to hold the data lock + if (!fMediaFile) + return B_NO_INIT; + *copyright = fMediaFile->Copyright(); + return B_OK; +} + + +status_t +Controller::GetLocation(BString* location) +{ + // you need to hold the data lock + if (!fMediaFile) + return B_NO_INIT; + BPath path(&fRef); + status_t ret = path.InitCheck(); + if (ret < B_OK) + return ret; + *location = ""; + *location << "file://" << path.Path(); + return B_OK; +} + + +status_t +Controller::GetName(BString* name) +{ + // you need to hold the data lock + if (!fMediaFile) + return B_NO_INIT; + *name = fRef.name; + return B_OK; +} + + +status_t +Controller::GetEncodedVideoFormat(media_format* format) +{ + // you need to hold the data lock + if (fVideoSupplier) + return fVideoSupplier->GetEncodedFormat(format); + return B_NO_INIT; +} + + +status_t +Controller::GetVideoCodecInfo(media_codec_info* info) +{ + // you need to hold the data lock + if (fVideoSupplier) + return fVideoSupplier->GetCodecInfo(info); + return B_NO_INIT; +} + + +status_t +Controller::GetEncodedAudioFormat(media_format* format) +{ + // you need to hold the data lock + if (fAudioSupplier) + return fAudioSupplier->GetEncodedFormat(format); + return B_NO_INIT; +} + + +status_t +Controller::GetAudioCodecInfo(media_codec_info* info) +{ + // you need to hold the data lock + if (fAudioSupplier) + return fAudioSupplier->GetCodecInfo(info); + return B_NO_INIT; +} + + // #pragma mark - @@ -735,7 +826,7 @@ printf("audio play start\n"); if (!fSoundOutput || !(fSoundOutput->Format() == buffer->mediaFormat.u.raw_audio)) { delete fSoundOutput; - fSoundOutput = new (nothrow) SoundOutput(fName.String(), + fSoundOutput = new (nothrow) SoundOutput(fRef.name, buffer->mediaFormat.u.raw_audio); fSoundOutput->SetVolume(fVolume); bufferDuration = bigtime_t(1000000.0 diff --git a/src/apps/mediaplayer/Controller.h b/src/apps/mediaplayer/Controller.h index bbcb3f605f..56f6f65918 100644 --- a/src/apps/mediaplayer/Controller.h +++ b/src/apps/mediaplayer/Controller.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -89,6 +90,16 @@ public: void SetVolume(float value); float Volume() const; void SetPosition(float value); + + bool HasFile(); + status_t GetFileFormatInfo(media_file_format* fileFormat); + status_t GetCopyright(BString* copyright); + status_t GetLocation(BString* location); + status_t GetName(BString* name); + status_t GetEncodedVideoFormat(media_format* format); + status_t GetVideoCodecInfo(media_codec_info* info); + status_t GetEncodedAudioFormat(media_format* format); + status_t GetAudioCodecInfo(media_codec_info* info); // video view void SetVideoView(VideoView *view); @@ -155,15 +166,12 @@ private: }; VideoView * fVideoView; - BString fName; volatile bool fPaused; volatile bool fStopped; float fVolume; entry_ref fRef; BMediaFile * fMediaFile; -BMediaTrack * fAudioTrack; -BMediaTrack * fVideoTrack; mutable BLocker fDataLock; VideoSupplier* fVideoSupplier; diff --git a/src/apps/mediaplayer/InfoWin.cpp b/src/apps/mediaplayer/InfoWin.cpp index 4ff71be285..1971c0495c 100644 --- a/src/apps/mediaplayer/InfoWin.cpp +++ b/src/apps/mediaplayer/InfoWin.cpp @@ -19,22 +19,24 @@ */ #include "InfoWin.h" -#include +#include #include #include -#include + #include #include -#include -#include +#include +#include #include -#include -#include "MainWin.h" + +#include "Controller.h" +#include "ControllerObserver.h" + #define NAME "File Info" #define MIN_WIDTH 350 -#define BASE_HEIGHT (32+32) +#define BASE_HEIGHT (32 + 32) //const rgb_color kGreen = { 152, 203, 152, 255 }; const rgb_color kRed = { 203, 152, 152, 255 }; @@ -47,7 +49,8 @@ const rgb_color kBlack = { 0, 0, 0, 255 }; class InfoView : public BView { public: InfoView(BRect frame, const char *name, float divider) - : BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) + : BView(frame, name, B_FOLLOW_ALL, + B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) , fDivider(divider) { } virtual ~InfoView() @@ -70,27 +73,31 @@ InfoView::Draw(BRect updateRect) } +// #pragma mark - + + InfoWin::InfoWin(BPoint leftTop, Controller* controller) : BWindow(BRect(leftTop.x, leftTop.y, leftTop.x + MIN_WIDTH - 1, leftTop.y + 250), NAME, B_TITLED_WINDOW, - B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE), - fController(controller) + B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE) + , fController(controller) + , fControllerObserver(new ControllerObserver(this, + OBSERVE_FILE_CHANGES | OBSERVE_TRACK_CHANGES | OBSERVE_STAT_CHANGES)) { BRect rect = Bounds(); // accomodate for big fonts - float div; - div = MAX(2*32, be_plain_font->StringWidth("Container") + 5); + float div = max_c(2 * 32, be_plain_font->StringWidth("Container") + 5); fInfoView = new InfoView(rect, "background", div); fInfoView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); AddChild(fInfoView); BFont bigFont(be_plain_font); - bigFont.SetSize(bigFont.Size()+6); + bigFont.SetSize(bigFont.Size() + 6); font_height fh; bigFont.GetHeight(&fh); - fFilenameView = new BStringView(BRect(div+10, 20, + fFilenameView = new BStringView(BRect(div + 10, 20, rect.right - 10, 20 + fh.ascent + 5), "filename", ""); @@ -110,13 +117,13 @@ InfoWin::InfoWin(BPoint leftTop, Controller* controller) lr.right = div - 1; cr.left = div + 1; BRect tr; - tr = lr.OffsetToCopy(0,0).InsetByCopy(1,1); + tr = lr.OffsetToCopy(0, 0).InsetByCopy(5, 1); fLabelsView = new BTextView(lr, "labels", tr, B_FOLLOW_BOTTOM); fLabelsView->SetViewColor(kGreen); fLabelsView->SetAlignment(B_ALIGN_RIGHT); fLabelsView->SetWordWrap(false); AddChild(fLabelsView); - tr = cr.OffsetToCopy(0,0).InsetByCopy(1,1); + tr = cr.OffsetToCopy(0, 0).InsetByCopy(10, 1); fContentsView = new BTextView(cr, "contents", tr, B_FOLLOW_BOTTOM); fContentsView->SetWordWrap(false); AddChild(fContentsView); @@ -124,6 +131,8 @@ InfoWin::InfoWin(BPoint leftTop, Controller* controller) fLabelsView->MakeSelectable(); fContentsView->MakeSelectable(); + fController->AddListener(fControllerObserver); + Update(); Show(); } @@ -131,188 +140,46 @@ InfoWin::InfoWin(BPoint leftTop, Controller* controller) InfoWin::~InfoWin() { - printf("InfoWin::~InfoWin\n"); + fController->RemoveListener(fControllerObserver); + delete fControllerObserver; + //fInfoListView->MakeEmpty(); //delete [] fInfoItems; } +// #pragma mark - + + void -InfoWin::ResizeToPreferred() +InfoWin::FrameResized(float new_width, float new_height) { -#if 0 - int i; - float height = BASE_HEIGHT; - BListItem *li; - for (i = 0; (li = fInfoListView->ItemAt(i)); i++) { - height += li->Height(); - } - ResizeTo(Bounds().Width(), height); -#endif } void -InfoWin::Update(uint32 which) +InfoWin::MessageReceived(BMessage *msg) { -// status_t err; -// //char buf[256]; -// printf("InfoWin::Update(0x%08lx)\n", which); -// rgb_color vFgCol = ui_color(B_DOCUMENT_TEXT_COLOR); -// -// fLabelsView->SelectAll(); -// fContentsView->SelectAll(); -// fLabelsView->Clear(); -// fContentsView->Clear(); -// fLabelsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kBlue); -// fLabelsView->Insert("File Info\n"); -// fContentsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &vFgCol); -// fContentsView->Insert("\n"); -// -// fLabelsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kRed); -// //fContentsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &vFgCol); -// -// // lock the Main Window as we must access some fields there... -// if (fMainWin->LockWithTimeout(500000) < B_OK) -// return; // XXX: resend msg to ourselves ? -// -// Controller *c = fMainWin->fController; -// BMediaFile *mf = c->fMediaFile; -// -// if (which & INFO_VIDEO && c->VideoTrackCount() > 0) { -// fLabelsView->Insert("Video\n\n"); -// BString s; -// media_format fmt; -// media_raw_video_format vfmt; -// float fps; -// err = c->fVideoTrack->EncodedFormat(&fmt); -// //string_for_format(fmt, buf, sizeof(buf)); -// //printf("%s\n", buf); -// if (err < 0) { -// s << "(" << strerror(err) << ")"; -// } else if (fmt.type == B_MEDIA_ENCODED_VIDEO) { -// vfmt = fmt.u.encoded_video.output; -// media_codec_info mci; -// err = c->fVideoTrack->GetCodecInfo(&mci); -// if (err < 0) -// s << "(" << strerror(err) << ")"; -// else -// s << mci.pretty_name; //<< "(" << mci.short_name << ")"; -// } else if (fmt.type == B_MEDIA_RAW_VIDEO) { -// vfmt = fmt.u.raw_video; -// s << "raw video"; -// } else -// s << "unknown format"; -// s << "\n"; -// s << fmt.Width() << " x " << fmt.Height(); -// // encoded has output as 1st field... -// fps = vfmt.field_rate; -// s << ", " << fps << " fps"; -// s << "\n"; -// fContentsView->Insert(s.String()); -// } -// if (which & INFO_AUDIO && c->AudioTrackCount() > 0) { -// fLabelsView->Insert("Sound\n\n"); -// BString s; -// media_format fmt; -// media_raw_audio_format afmt; -// err = c->fAudioTrack->EncodedFormat(&fmt); -// //string_for_format(fmt, buf, sizeof(buf)); -// //printf("%s\n", buf); -// if (err < 0) { -// s << "(" << strerror(err) << ")"; -// } else if (fmt.type == B_MEDIA_ENCODED_AUDIO) { -// afmt = fmt.u.encoded_audio.output; -// media_codec_info mci; -// err = c->fAudioTrack->GetCodecInfo(&mci); -// if (err < 0) -// s << "(" << strerror(err) << ")"; -// else -// s << mci.pretty_name; //<< "(" << mci.short_name << ")"; -// } else if (fmt.type == B_MEDIA_RAW_AUDIO) { -// afmt = fmt.u.raw_audio; -// s << "raw audio"; -// } else -// s << "unknown format"; -// s << "\n"; -// uint32 bitps = 8 * (afmt.format & media_raw_audio_format::B_AUDIO_SIZE_MASK); -// uint32 chans = afmt.channel_count; -// float sr = afmt.frame_rate; -// -// if (bitps) -// s << bitps << " Bit "; -// if (chans == 1) -// s << "Mono"; -// else if (chans == 2) -// s << "Stereo"; -// else -// s << chans << "Channels"; -// s << ", "; -// if (sr) -// s << sr/1000; -// else -// s << "?"; -// s<< " kHz"; -// s << "\n"; -// fContentsView->Insert(s.String()); -// } -// if (which & INFO_STATS && fMainWin->fHasFile) { -// // TODO: check for live streams (no duration) -// fLabelsView->Insert("Duration\n"); -// BString s; -// bigtime_t d = c->Duration(); -// bigtime_t v; -// -// //s << d << "µs; "; -// -// d /= 1000; -// -// v = d / (3600 * 1000); -// d = d % (3600 * 1000); -// if (v) -// s << v << ":"; -// v = d / (60 * 1000); -// d = d % (60 * 1000); -// s << v << ":"; -// v = d / 1000; -// d = d % 1000; -// s << v; -// if (d) -// s << "." << d / 10; -// s << "\n"; -// fContentsView->Insert(s.String()); -// // TODO: demux/video/audio/... perfs (Kb/s) -// } -// if (which & INFO_TRANSPORT) { -// } -// if ((which & INFO_FILE) && fMainWin->fHasFile) { -// media_file_format ff; -// if (mf && (mf->GetFileFormatInfo(&ff) == B_OK)) { -// fLabelsView->Insert("Container\n"); -// BString s; -// s << ff.pretty_name; -// s << "\n"; -// fContentsView->Insert(s.String()); -// } -// fLabelsView->Insert("Location\n"); -// // TODO: make Controller save the entry_ref (url actually). -// fContentsView->Insert("file://\n"); -// fFilenameView->SetText(c->fName.String()); -// } -// if (which & INFO_COPYRIGHT && mf && mf->Copyright()) { -// -// fLabelsView->Insert("Copyright\n\n"); -// BString s; -// s << mf->Copyright(); -// s << "\n\n"; -// fContentsView->Insert(s.String()); -// } -// -// // we can unlock the main window now and let it work -// fMainWin->Unlock(); -// -// // now resize the window to the list view size... -// ResizeToPreferred(); + switch (msg->what) { + case MSG_CONTROLLER_FILE_FINISHED: + break; + case MSG_CONTROLLER_FILE_CHANGED: + Update(INFO_ALL); + break; + case MSG_CONTROLLER_VIDEO_TRACK_CHANGED: + Update(/*INFO_VIDEO | INFO_STATS*/INFO_ALL); + break; + case MSG_CONTROLLER_AUDIO_TRACK_CHANGED: + Update(/*INFO_AUDIO | INFO_STATS*/INFO_ALL); + break; + case MSG_CONTROLLER_VIDEO_STATS_CHANGED: + case MSG_CONTROLLER_AUDIO_STATS_CHANGED: + Update(/*INFO_STATS*/INFO_ALL); + break; + default: + BWindow::MessageReceived(msg); + break; + } } @@ -332,77 +199,188 @@ InfoWin::Pulse() Update(INFO_STATS); } + +// #pragma mark - + + void -InfoWin::FrameResized(float new_width, float new_height) +InfoWin::ResizeToPreferred() { #if 0 - if (new_width != Bounds().Width() || new_height != Bounds().Height()) { - debugger("size wrong\n"); - } - - bool no_menu = fNoMenu || fIsFullscreen; - bool no_controls = fNoControls || fIsFullscreen; - - printf("FrameResized enter: new_width %.0f, new_height %.0f\n", new_width, new_height); - - int max_video_width = int(new_width) + 1; - int max_video_height = int(new_height) + 1 - (no_menu ? 0 : fMenuBarHeight) - (no_controls ? 0 : fControlsHeight); - - ASSERT(max_video_height >= 0); - - int y = 0; - - if (no_menu) { - if (!fMenuBar->IsHidden()) - fMenuBar->Hide(); - } else { -// fMenuBar->MoveTo(0, y); - fMenuBar->ResizeTo(new_width, fMenuBarHeight - 1); - if (fMenuBar->IsHidden()) - fMenuBar->Show(); - y += fMenuBarHeight; - } - - if (max_video_height == 0) { - if (!fVideoView->IsHidden()) - fVideoView->Hide(); - } else { -// fVideoView->MoveTo(0, y); -// fVideoView->ResizeTo(max_video_width - 1, max_video_height - 1); - ResizeVideoView(0, y, max_video_width, max_video_height); - if (fVideoView->IsHidden()) - fVideoView->Show(); - y += max_video_height; - } - - if (no_controls) { - if (!fControls->IsHidden()) - fControls->Hide(); - } else { - fControls->MoveTo(0, y); - fControls->ResizeTo(new_width, fControlsHeight - 1); - if (fControls->IsHidden()) - fControls->Show(); -// y += fControlsHeight; + float height = BASE_HEIGHT; + for (int i = 0; BListItem *li = fInfoListView->ItemAt(i); i++) { + height += li->Height(); } + ResizeTo(Bounds().Width(), height); #endif - - printf("FrameResized leave\n"); } void -InfoWin::MessageReceived(BMessage *msg) +InfoWin::Update(uint32 which) { - uint32 which; - switch (msg->what) { - case M_UPDATE_INFO: - if (msg->FindInt32("which", (int32 *)&which) < B_OK) - which = INFO_ALL; - Update(which); - break; - default: - BWindow::MessageReceived(msg); - break; +printf("InfoWin::Update(0x%08lx)\n", which); + fLabelsView->SetText(""); + fContentsView->SetText(""); + fLabelsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kBlue); + fLabelsView->Insert("\n"); + fContentsView->SetFontAndColor(be_plain_font, B_FONT_ALL); + fContentsView->Insert("\n"); + + fLabelsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kRed); + + status_t err; + // video track format information + if ((which & INFO_VIDEO) && fController->VideoTrackCount() > 0) { + fLabelsView->Insert("Video\n\n\n"); + BString s; + media_format format; + media_raw_video_format videoFormat; + err = fController->GetEncodedVideoFormat(&format); + if (err < B_OK) { + s << "(" << strerror(err) << ")"; + } else if (format.type == B_MEDIA_ENCODED_VIDEO) { + videoFormat = format.u.encoded_video.output; + media_codec_info mci; + err = fController->GetVideoCodecInfo(&mci); + if (err < B_OK) + s << "(" << strerror(err) << ")"; + else + s << mci.pretty_name; //<< "(" << mci.short_name << ")"; + } else if (format.type == B_MEDIA_RAW_VIDEO) { + videoFormat = format.u.raw_video; + s << "raw video"; + } else + s << "unknown format"; + s << "\n"; + s << format.Width() << " x " << format.Height(); + // encoded has output as 1st field... + s << ", " << videoFormat.field_rate << " fps"; + s << "\n\n"; + fContentsView->Insert(s.String()); } + + // audio track format information + if ((which & INFO_AUDIO) && fController->AudioTrackCount() > 0) { + fLabelsView->Insert("Audio\n\n\n"); + BString s; + media_format format; + media_raw_audio_format audioFormat; + err = fController->GetEncodedAudioFormat(&format); + //string_for_format(format, buf, sizeof(buf)); + //printf("%s\n", buf); + if (err < 0) { + s << "(" << strerror(err) << ")"; + } else if (format.type == B_MEDIA_ENCODED_AUDIO) { + audioFormat = format.u.encoded_audio.output; + media_codec_info mci; + err = fController->GetAudioCodecInfo(&mci); + if (err < 0) + s << "(" << strerror(err) << ")"; + else + s << mci.pretty_name; //<< "(" << mci.short_name << ")"; + } else if (format.type == B_MEDIA_RAW_AUDIO) { + audioFormat = format.u.raw_audio; + s << "raw audio"; + } else + s << "unknown format"; + s << "\n"; + uint32 bitsPerSample = 8 * (audioFormat.format + & media_raw_audio_format::B_AUDIO_SIZE_MASK); + uint32 channelCount = audioFormat.channel_count; + float sr = audioFormat.frame_rate; + + if (bitsPerSample > 0) + s << bitsPerSample << " Bit "; + if (channelCount == 1) + s << "Mono"; + else if (channelCount == 2) + s << "Stereo"; + else + s << channelCount << "Channels"; + s << ", "; + if (sr > 0.0) + s << sr / 1000; + else + s << "??"; + s<< " kHz"; + s << "\n\n"; + fContentsView->Insert(s.String()); + } + + // statistics + if ((which & INFO_STATS) && fController->HasFile()) { + fLabelsView->Insert("Duration\n\n"); + BString s; + bigtime_t d = fController->Duration(); + bigtime_t v; + + //s << d << "µs; "; + + d /= 1000; + + v = d / (3600 * 1000); + d = d % (3600 * 1000); + bool hours = v > 0; + if (hours) + s << v << ":"; + v = d / (60 * 1000); + d = d % (60 * 1000); + s << v << ":"; + v = d / 1000; + s << v; + if (hours) + s << " h"; + else + s << " min"; + s << "\n\n"; + fContentsView->Insert(s.String()); + // TODO: demux/video/audio/... perfs (Kb/s) + } + + if (which & INFO_TRANSPORT) { + // what is "Transport"? + } + + if (which & INFO_FILE) { + if (fController->HasFile()) { + media_file_format ff; + BString s; + if (fController->GetFileFormatInfo(&ff) == B_OK) { + fLabelsView->Insert("Container\n\n"); + s << ff.pretty_name; + s << "\n\n"; + fContentsView->Insert(s.String()); + } else + fContentsView->Insert("\n\n"); + fLabelsView->Insert("Location\n"); + if (fController->GetLocation(&s) < B_OK) + s = ""; + s << "\n"; + fContentsView->Insert(s.String()); + if (fController->GetName(&s) < B_OK) + s = ""; + fFilenameView->SetText(s.String()); + } else { + fFilenameView->SetText(""); + } + } + + if ((which & INFO_COPYRIGHT) && fController->HasFile()) { + + BString s; + if (fController->GetCopyright(&s) == B_OK && s.Length() > 0) { + fLabelsView->Insert("Copyright\n\n"); + s << "\n\n"; + fContentsView->Insert(s.String()); + } + } + + fController->Unlock(); + + ResizeToPreferred(); } + + + + diff --git a/src/apps/mediaplayer/InfoWin.h b/src/apps/mediaplayer/InfoWin.h index 187b225ef8..8cc95fe32e 100644 --- a/src/apps/mediaplayer/InfoWin.h +++ b/src/apps/mediaplayer/InfoWin.h @@ -21,16 +21,12 @@ #define __FILE_INFO_WIN_H #include -#include -#include -class MainWin; class Controller; +class ControllerObserver; class InfoView; -#define M_UPDATE_INFO 'upda' - #define INFO_STATS 0x00000001 #define INFO_TRANSPORT 0x00000002 #define INFO_FILE 0x00000004 @@ -53,16 +49,16 @@ public: virtual void Pulse(); void ResizeToPreferred(); - void Update(uint32 which=INFO_ALL); // threadsafe + void Update(uint32 which = INFO_ALL); private: Controller* fController; + ControllerObserver* fControllerObserver; InfoView* fInfoView; BStringView* fFilenameView; BTextView* fLabelsView; BTextView* fContentsView; - }; #endif // __FILE_INFO_WIN_H diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp index e99402b9d9..fe54336d4e 100644 --- a/src/apps/mediaplayer/MainWin.cpp +++ b/src/apps/mediaplayer/MainWin.cpp @@ -680,12 +680,6 @@ MainWin::ShowFileInfo() fInfoWin->Activate(); fInfoWin->Unlock(); } - - BMessenger msgr(fInfoWin); - BMessage m(M_UPDATE_INFO); - m.AddInt32("which", INFO_ALL); - msgr.SendMessage(&m); - msgr.SendMessage(B_WINDOW_ACTIVATED); } diff --git a/src/apps/mediaplayer/supplier/AudioSupplier.h b/src/apps/mediaplayer/supplier/AudioSupplier.h index 57a7246064..6b5e512a73 100644 --- a/src/apps/mediaplayer/supplier/AudioSupplier.h +++ b/src/apps/mediaplayer/supplier/AudioSupplier.h @@ -8,7 +8,9 @@ #ifndef AUDIO_SUPPLIER_H #define AUDIO_SUPPLIER_H + #include +#include class AudioSupplier { public: @@ -16,6 +18,10 @@ class AudioSupplier { virtual ~AudioSupplier(); virtual media_format Format() const = 0; + virtual status_t GetEncodedFormat(media_format* format) + const = 0; + virtual status_t GetCodecInfo(media_codec_info* info) const = 0; + virtual status_t ReadFrames(void* buffer, int64* framesRead, bigtime_t* performanceTime) = 0; virtual status_t SeekToTime(bigtime_t* performanceTime) = 0; diff --git a/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp b/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp index d606eb7588..879e8fac24 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp +++ b/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp @@ -62,6 +62,24 @@ MediaTrackAudioSupplier::Format() const } +status_t +MediaTrackAudioSupplier::GetEncodedFormat(media_format* format) const +{ + if (!fMediaTrack) + return B_NO_INIT; + return fMediaTrack->EncodedFormat(format); +} + + +status_t +MediaTrackAudioSupplier::GetCodecInfo(media_codec_info* info) const +{ + if (!fMediaTrack) + return B_NO_INIT; + return fMediaTrack->GetCodecInfo(info); +} + + status_t MediaTrackAudioSupplier::ReadFrames(void* buffer, int64* framesRead, bigtime_t* performanceTime) @@ -75,6 +93,14 @@ MediaTrackAudioSupplier::ReadFrames(void* buffer, int64* framesRead, status_t ret = fMediaTrack->ReadFrames(buffer, framesRead, &mediaHeader); if (ret < B_OK) { + // further analyse the error + if (fDuration == 0 || (double)fPerformanceTime / fDuration > 0.95) { + // some codecs don't behave well, or maybe somes files are bad, + // they don't report the end of the stream correctly + // NOTE: "more than 95% of the stream" is of course pure guess, + // but it fixed the problem I had with some files + ret = B_LAST_BUFFER_ERROR; + } printf("MediaTrackAudioSupplier::ReadFrame() - " "error while reading frames: %s\n", strerror(ret)); } else { diff --git a/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.h b/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.h index 2f9f3fb279..0676d7734a 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.h +++ b/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.h @@ -18,6 +18,9 @@ class MediaTrackAudioSupplier : public AudioSupplier { virtual ~MediaTrackAudioSupplier(); virtual media_format Format() const; + virtual status_t GetEncodedFormat(media_format* format) const; + virtual status_t GetCodecInfo(media_codec_info* info) const; + virtual status_t ReadFrames(void* buffer, int64* framesRead, bigtime_t* performanceTime); virtual status_t SeekToTime(bigtime_t* performanceTime); diff --git a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp index 700d622472..c3aaa7b1c0 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp +++ b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp @@ -120,6 +120,24 @@ MediaTrackVideoSupplier::Format() const } +status_t +MediaTrackVideoSupplier::GetEncodedFormat(media_format* format) const +{ + if (!fVideoTrack) + return B_NO_INIT; + return fVideoTrack->EncodedFormat(format); +} + + +status_t +MediaTrackVideoSupplier::GetCodecInfo(media_codec_info* info) const +{ + if (!fVideoTrack) + return B_NO_INIT; + return fVideoTrack->GetCodecInfo(info); +} + + status_t MediaTrackVideoSupplier::ReadFrame(void* buffer, bigtime_t* performanceTime) { diff --git a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h index f9de398543..92823ee5d3 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h +++ b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h @@ -19,6 +19,9 @@ class MediaTrackVideoSupplier : public VideoSupplier { virtual ~MediaTrackVideoSupplier(); virtual media_format Format() const; + virtual status_t GetEncodedFormat(media_format* format) const; + virtual status_t GetCodecInfo(media_codec_info* info) const; + virtual status_t ReadFrame(void* buffer, bigtime_t* performanceTime); virtual status_t SeekToTime(bigtime_t* performanceTime); diff --git a/src/apps/mediaplayer/supplier/VideoSupplier.h b/src/apps/mediaplayer/supplier/VideoSupplier.h index b24a8a7dbe..405a1e5342 100644 --- a/src/apps/mediaplayer/supplier/VideoSupplier.h +++ b/src/apps/mediaplayer/supplier/VideoSupplier.h @@ -8,7 +8,9 @@ #ifndef VIDEO_SUPPLIER_H #define VIDEO_SUPPLIER_H + #include +#include class VideoSupplier { public: @@ -16,6 +18,9 @@ class VideoSupplier { virtual ~VideoSupplier(); virtual media_format Format() const = 0; + virtual status_t GetEncodedFormat(media_format* format) + const = 0; + virtual status_t GetCodecInfo(media_codec_info* info) const = 0; virtual status_t ReadFrame(void* buffer, bigtime_t* performanceTime) = 0; virtual status_t SeekToTime(bigtime_t* performanceTime) = 0;