From 64c4d8f6065829193ec0f52d35d2a317cbfae267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 2 Jun 2008 18:28:31 +0000 Subject: [PATCH] I tracked down a problem with a specific clip I have here. In the end, the problem was that no codec was installed for it, but I fixed a bunch of issues on the way to find out. Now the controller will not rely on the number of audio and video tracks, but on the fact that it could instantiate suppliers at all. Made the MediaTrackVideoSupplier return an init error. Should be replicated for the MediaTrackAudioSupplier. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25765 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/mediaplayer/Controller.cpp | 29 ++++++++++++++----- .../supplier/MediaTrackVideoSupplier.cpp | 19 ++++++++++-- .../supplier/MediaTrackVideoSupplier.h | 3 +- .../supplier/ProxyAudioSupplier.cpp | 18 ++++++++++-- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp index 5bcaa26248..b94d5cc291 100644 --- a/src/apps/mediaplayer/Controller.cpp +++ b/src/apps/mediaplayer/Controller.cpp @@ -230,12 +230,6 @@ Controller::SetTo(const entry_ref &ref) } } - if (AudioTrackCount() == 0 && VideoTrackCount() == 0) { - printf("Controller::SetTo: no audio or video tracks found\n"); - _NotifyFileChanged(); - return B_MEDIA_NO_HANDLER; - } - printf("Controller::SetTo: %d audio track, %d video track\n", AudioTrackCount(), VideoTrackCount()); @@ -245,6 +239,15 @@ Controller::SetTo(const entry_ref &ref) SelectAudioTrack(0); SelectVideoTrack(0); + if (fAudioTrackSupplier == NULL && fVideoTrackSupplier == NULL) { + printf("Controller::SetTo: no audio or video tracks found or " + "no decoders\n"); + _NotifyFileChanged(); + delete fMediaFile; + fMediaFile = NULL; + return B_MEDIA_NO_HANDLER; + } + // prevent blocking the creation of new overlay buffers fVideoView->DisableOverlay(); @@ -350,13 +353,25 @@ Controller::SelectVideoTrack(int n) if (!track) return B_ERROR; + status_t initStatus; ObjectDeleter deleter(fVideoTrackSupplier); - fVideoTrackSupplier = new MediaTrackVideoSupplier(track); + fVideoTrackSupplier = new MediaTrackVideoSupplier(track, initStatus); + if (initStatus < B_OK) { + delete fVideoTrackSupplier; + fVideoTrackSupplier = NULL; + return initStatus; + } bigtime_t a = fAudioTrackSupplier ? fAudioTrackSupplier->Duration() : 0; bigtime_t v = fVideoTrackSupplier->Duration(); fDuration = max_c(a, v); fVideoFrameRate = fVideoTrackSupplier->Format().u.raw_video.field_rate; + if (fVideoFrameRate <= 0.0) { + printf("Controller::SelectVideoTrack(%d) - invalid video frame rate: %.1f\n", n, + fVideoFrameRate); + fVideoFrameRate = 25.0; + } + DurationChanged(); // TODO: notify duration changed! diff --git a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp index 31059f6440..60f4469ebe 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp +++ b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp @@ -27,7 +27,8 @@ static const char* string_for_color_space(color_space format); // constructor -MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track) +MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track, + status_t& initStatus) : VideoTrackSupplier() , fVideoTrack(track) @@ -40,7 +41,7 @@ MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track) return; } - _SwitchFormat(B_NO_COLOR_SPACE, 0); + initStatus = _SwitchFormat(B_NO_COLOR_SPACE, 0); fDuration = fVideoTrack->Duration(); @@ -354,7 +355,19 @@ MediaTrackVideoSupplier::_SwitchFormat(color_space format, int32 bytesPerRow) if (ret < B_OK) { printf("MediaTrackVideoSupplier::_SwitchFormat() - " - "fVideoTrack->DecodedFormat(): %s\n", strerror(ret)); + "fVideoTrack->DecodedFormat(): %s - retrying with B_RGB32\n", + strerror(ret)); + fFormat.u.raw_video.display.format = format; + minBytesPerRow = width * 4; + fFormat.u.raw_video.display.bytes_per_row = max_c(minBytesPerRow, + bytesPerRow); + + ret = fVideoTrack->DecodedFormat(&fFormat); + if (ret < B_OK) { + printf("MediaTrackVideoSupplier::_SwitchFormat() - " + "fVideoTrack->DecodedFormat(): %s - giving up\n", + strerror(ret)); + } return ret; } diff --git a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h index 30c94b2b82..ee35f8ae16 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h +++ b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h @@ -16,7 +16,8 @@ class BMediaTrack; class MediaTrackVideoSupplier : public VideoTrackSupplier { public: - MediaTrackVideoSupplier(BMediaTrack* track); + MediaTrackVideoSupplier(BMediaTrack* track, + status_t& initStatus); virtual ~MediaTrackVideoSupplier(); virtual const media_format& Format() const; diff --git a/src/apps/mediaplayer/supplier/ProxyAudioSupplier.cpp b/src/apps/mediaplayer/supplier/ProxyAudioSupplier.cpp index 5f2c5a9d53..f41f79edbd 100644 --- a/src/apps/mediaplayer/supplier/ProxyAudioSupplier.cpp +++ b/src/apps/mediaplayer/supplier/ProxyAudioSupplier.cpp @@ -12,18 +12,20 @@ #include #include -#include "AudioAdapter.h" #include "AudioTrackSupplier.h" +#include "AudioAdapter.h" #include "PlaybackManager.h" using std::nothrow; -//#define TRACE_PROXY_AUDIO_SUPPLIER +#define TRACE_PROXY_AUDIO_SUPPLIER #ifdef TRACE_PROXY_AUDIO_SUPPLIER # define TRACE(x...) printf("ProxyAudioSupplier::"); printf(x) +# define ERROR(x...) fprintf(stderr, "ProxyAudioSupplier::"); fprintf(stderr, x) #else # define TRACE(x...) +# define ERROR(x...) fprintf(stderr, "ProxyAudioSupplier::"); fprintf(stderr, x) #endif @@ -87,9 +89,18 @@ ProxyAudioSupplier::GetFrames(void* buffer, int64 frameCount, interval->start_time, interval->end_time, interval->x_start_time, interval->x_end_time, interval->speed); + if (intervalStartTime == interval->end_time) { + delete interval; + error = B_ERROR; + sLastInvalidStartTime = intervalStartTime; + ERROR("GetFrames() - zero duration audio interval! start " + "time: %lld\n", intervalStartTime); + break; + } if (!playingIntervals.AddItem(interval)) { delete interval; error = B_NO_MEMORY; + ERROR("GetFrames() - Out of memory\n"); break; } intervalStartTime = interval->end_time; @@ -102,6 +113,9 @@ ProxyAudioSupplier::GetFrames(void* buffer, int64 frameCount, BAutolock _(fSupplierLock); + if (!fSupplier) + return B_ERROR; + // retrieve the audio data for each interval. int64 framesRead = 0; while (!playingIntervals.IsEmpty()) {