From d7f2503a082c6e32142bca8f396eee002b2ec851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sat, 31 May 2008 08:46:11 +0000 Subject: [PATCH] * Support codecs that don't support B_YCbCrXXX color spaces. * Leave the codec a chance to advertise the best output color space, try B_YCbCr422 as the most widely supported format in case the codec does not advertise. * Support two more overlay colorspace modes in the video consumer. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25731 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/mediaplayer/Controller.cpp | 12 +++++++--- .../media_node_framework/NodeManager.cpp | 21 +++++++++-------- .../media_node_framework/NodeManager.h | 10 +++++--- .../video/VideoConsumer.cpp | 4 +++- .../supplier/MediaTrackVideoSupplier.cpp | 23 ++++++++++++++----- .../supplier/MediaTrackVideoSupplier.h | 3 +-- 6 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp index cc3fa216dd..77085ad027 100644 --- a/src/apps/mediaplayer/Controller.cpp +++ b/src/apps/mediaplayer/Controller.cpp @@ -245,14 +245,21 @@ Controller::SetTo(const entry_ref &ref) SelectAudioTrack(0); SelectVideoTrack(0); + // prevent blocking the creation of new overlay buffers fVideoView->DisableOverlay(); + // get video properties (if there is video at all) int width; int height; GetSize(&width, &height); + color_space preferredVideoFormat = B_NO_COLOR_SPACE; + if (fVideoTrackSupplier) { + const media_format& format = fVideoTrackSupplier->Format(); + preferredVideoFormat = format.u.raw_video.display.format; + } Init(BRect(0, 0, width - 1, height - 1), fVideoFrameRate, - LOOPING_ALL, false); + preferredVideoFormat, LOOPING_ALL, false); SetCurrentFrame(0); @@ -339,8 +346,7 @@ Controller::SelectVideoTrack(int n) return B_ERROR; ObjectDeleter deleter(fVideoTrackSupplier); - fVideoTrackSupplier = new MediaTrackVideoSupplier(track, - IsOverlayActive() ? B_YCbCr422 : B_RGB32); + fVideoTrackSupplier = new MediaTrackVideoSupplier(track); bigtime_t a = fAudioTrackSupplier ? fAudioTrackSupplier->Duration() : 0; bigtime_t v = fVideoTrackSupplier->Duration(); diff --git a/src/apps/mediaplayer/media_node_framework/NodeManager.cpp b/src/apps/mediaplayer/media_node_framework/NodeManager.cpp index 9bb39ca662..e4eac6d861 100644 --- a/src/apps/mediaplayer/media_node_framework/NodeManager.cpp +++ b/src/apps/mediaplayer/media_node_framework/NodeManager.cpp @@ -64,7 +64,8 @@ NodeManager::~NodeManager() // Init status_t -NodeManager::Init(BRect videoBounds, float videoFrameRate, int32 loopingMode, +NodeManager::Init(BRect videoBounds, float videoFrameRate, + color_space preferredVideoFormat, int32 loopingMode, bool loopingEnabled, float speed) { // init base class @@ -80,7 +81,8 @@ NodeManager::Init(BRect videoBounds, float videoFrameRate, int32 loopingMode, if (!fAudioSupplier) fAudioSupplier = CreateAudioSupplier(); - return FormatChanged(videoBounds, videoFrameRate, true); + return FormatChanged(videoBounds, videoFrameRate, preferredVideoFormat, + true); } // InitCheck @@ -114,7 +116,8 @@ NodeManager::CleanupNodes() // FormatChanged status_t -NodeManager::FormatChanged(BRect videoBounds, float videoFrameRate, bool force) +NodeManager::FormatChanged(BRect videoBounds, float videoFrameRate, + color_space preferredVideoFormat, bool force) { if (!force && videoBounds == VideoBounds() && videoFrameRate == FramesPerSecond()) @@ -130,7 +133,7 @@ NodeManager::FormatChanged(BRect videoBounds, float videoFrameRate, bool force) SetVideoBounds(videoBounds); - status_t ret = _SetUpNodes(); + status_t ret = _SetUpNodes(preferredVideoFormat); if (ret == B_OK) _StartNodes(); else @@ -225,7 +228,7 @@ NodeManager::SetVolume(float percent) // _SetUpNodes status_t -NodeManager::_SetUpNodes() +NodeManager::_SetUpNodes(color_space preferredVideoFormat) { printf("NodeManager::_SetUpNodes()\n"); @@ -250,7 +253,7 @@ printf("NodeManager::_SetUpNodes()\n"); // setup the video nodes if (fVideoBounds.IsValid()) { - fStatus = _SetUpVideoNodes(); + fStatus = _SetUpVideoNodes(preferredVideoFormat); if (fStatus != B_OK) { print_error("Error setting up video nodes", fStatus); fMediaRoster->Unlock(); @@ -277,7 +280,7 @@ printf("NodeManager::_SetUpNodes()\n"); // _SetUpVideoNodes status_t -NodeManager::_SetUpVideoNodes() +NodeManager::_SetUpVideoNodes(color_space preferredVideoFormat) { // create the video producer node fVideoProducer = new VideoProducer(NULL, "MediaPlayer Video Out", 0, @@ -342,7 +345,7 @@ NodeManager::_SetUpVideoNodes() fVideoBounds.IntegerWidth(), B_VIDEO_TOP_LEFT_RIGHT, 1, 1, { - B_YCbCr422, + preferredVideoFormat, fVideoBounds.IntegerWidth() + 1, fVideoBounds.IntegerHeight() + 1, 0, 0, 0 @@ -354,7 +357,7 @@ NodeManager::_SetUpVideoNodes() fStatus = fMediaRoster->Connect(videoOutput.source, videoInput.destination, &format, &videoOutput, &videoInput); - if (fStatus != B_OK) { + if (fStatus != B_OK && preferredVideoFormat != B_RGB32) { print_error("Can't connect the video source to the video window... " "trying B_RGB32", fStatus); format.u.raw_video.display.format = B_RGB32; diff --git a/src/apps/mediaplayer/media_node_framework/NodeManager.h b/src/apps/mediaplayer/media_node_framework/NodeManager.h index 2f0c7d0985..0905221d4e 100644 --- a/src/apps/mediaplayer/media_node_framework/NodeManager.h +++ b/src/apps/mediaplayer/media_node_framework/NodeManager.h @@ -33,6 +33,7 @@ class NodeManager : public PlaybackManager { // NodeManager status_t Init(BRect videoBounds, float videoFrameRate, + color_space preferredVideoFormat, int32 loopingMode = LOOPING_ALL, bool loopingEnabled = true, float speed = 1.0); @@ -42,7 +43,9 @@ class NodeManager : public PlaybackManager { status_t CleanupNodes(); status_t FormatChanged(BRect videoBounds, - float videoFrameRate, bool force = false); + float videoFrameRate, + color_space preferredVideoFormat, + bool force = false); virtual void SetPlayMode(int32 mode, bool continuePlaying = true); @@ -60,8 +63,9 @@ class NodeManager : public PlaybackManager { virtual void SetVolume(float percent); private: - status_t _SetUpNodes(); - status_t _SetUpVideoNodes(); + status_t _SetUpNodes(color_space preferredVideoFormat); + status_t _SetUpVideoNodes( + color_space preferredVideoFormat); status_t _SetUpAudioNodes(); status_t _TearDownNodes(bool disconnect = true); status_t _StartNodes(); diff --git a/src/apps/mediaplayer/media_node_framework/video/VideoConsumer.cpp b/src/apps/mediaplayer/media_node_framework/video/VideoConsumer.cpp index aec813fd70..bdc54ffe48 100644 --- a/src/apps/mediaplayer/media_node_framework/video/VideoConsumer.cpp +++ b/src/apps/mediaplayer/media_node_framework/video/VideoConsumer.cpp @@ -225,7 +225,8 @@ VideoConsumer::CreateBuffers(const media_format& format) for (uint32 i = 0; i < kBufferCount; i++) { // figure out the bitmap creation flags uint32 bitmapFlags = 0; - if (colorSpace == B_YCbCr422 || colorSpace == B_YCbCr444) { + if (colorSpace == B_YCbCr420 || colorSpace == B_YCbCr411 + || colorSpace == B_YCbCr422 || colorSpace == B_YCbCr444) { // try to use hardware overlay bitmapFlags |= B_BITMAP_WILL_OVERLAY; if (i == 0) @@ -262,6 +263,7 @@ VideoConsumer::CreateBuffers(const media_format& format) info.size = (size_t)fBitmap[i]->BitsLength(); info.flags = 0; info.buffer = 0; + // the media buffer id BBuffer *buffer = NULL; if ((status = fBuffers->AddBuffer(info, &buffer)) != B_OK) { diff --git a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp index ea0d44f045..e5b717af6d 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp +++ b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp @@ -27,8 +27,7 @@ static const char* string_for_color_space(color_space format); // constructor -MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track, - color_space format) +MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track) : VideoTrackSupplier() , fVideoTrack(track) @@ -41,7 +40,7 @@ MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track, return; } - _SwitchFormat(format, 0); + _SwitchFormat(B_NO_COLOR_SPACE, 0); fDuration = fVideoTrack->Duration(); @@ -320,6 +319,18 @@ MediaTrackVideoSupplier::_SwitchFormat(color_space format, int32 bytesPerRow) // get ouput video frame size uint32 width = fFormat.u.encoded_video.output.display.line_width; uint32 height = fFormat.u.encoded_video.output.display.line_count; + if (format == B_NO_COLOR_SPACE) { + format = fFormat.u.encoded_video.output.display.format; + if (format == B_NO_COLOR_SPACE) { + // if still no preferred format, try the most commonly + // supported overlay format + format = B_YCbCr422; + } else { + printf("MediaTrackVideoSupplier::_SwitchFormat() - " + "preferred color space: %s\n", + string_for_color_space(format)); + } + } // specifiy the decoded format. we derive this information from // the encoded format (width & height). @@ -332,10 +343,10 @@ MediaTrackVideoSupplier::_SwitchFormat(color_space format, int32 bytesPerRow) fFormat.u.raw_video.display.line_width = width; fFormat.u.raw_video.display.line_count = height; int32 minBytesPerRow; - if (format == B_RGB32 || format == B_RGBA32) - minBytesPerRow = width * 4; - else if (format == B_YCbCr422) + if (format == B_YCbCr422) minBytesPerRow = ((width * 2 + 3) / 4) * 4; + else + minBytesPerRow = width * 4; fFormat.u.raw_video.display.bytes_per_row = max_c(minBytesPerRow, bytesPerRow); diff --git a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h index adc97454be..30c94b2b82 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h +++ b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.h @@ -16,8 +16,7 @@ class BMediaTrack; class MediaTrackVideoSupplier : public VideoTrackSupplier { public: - MediaTrackVideoSupplier(BMediaTrack* track, - color_space preferredFormat); + MediaTrackVideoSupplier(BMediaTrack* track); virtual ~MediaTrackVideoSupplier(); virtual const media_format& Format() const;