* 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
This commit is contained in:
Stephan Aßmus 2008-05-31 08:46:11 +00:00
parent 8d1699709a
commit d7f2503a08
6 changed files with 49 additions and 24 deletions

View File

@ -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<VideoTrackSupplier> 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();

View File

@ -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;

View File

@ -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();

View File

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

View File

@ -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);

View File

@ -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;