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()) {