* Move the color_space_to_string() function into it's own file.

* On BeOS "bitmaps_support_space()" returns false for YCbCr color spaces. :-(
* Refactor the code which sets up the decoded format in the MediaTrack-
  VideoSupplier to always start with a clean format for multiple calls to
  BMediaTrack::DecodedFormat().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25824 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-06-06 12:40:10 +00:00
parent b1385bc32d
commit 9639f1bf6c
6 changed files with 156 additions and 116 deletions
+1
View File
@@ -76,6 +76,7 @@ Application MediaPlayer :
# support
AbstractLOAdapter.cpp
ColorSpaceToString.cpp
Command.cpp
CommandStack.cpp
Event.cpp
@@ -21,6 +21,7 @@
#include <TimeSource.h>
#include <MediaRoster.h>
#include "ColorSpaceToString.h"
#include "NodeManager.h"
#include "VideoTarget.h"
@@ -440,15 +441,32 @@ VideoConsumer::AcceptFormat(const media_destination& dest, media_format* format)
uint32 flags = 0;
bool supported = bitmaps_support_space(
format->u.raw_video.display.format, &flags);
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
// GRRR! BeOS implementation claims not
// to support these formats, while they work just fine.
switch (format->u.raw_video.display.format) {
case B_YCbCr422:
case B_YCbCr411:
case B_YCbCr444:
case B_YCbCr420:
supported = true;
break;
default:
break;
}
#endif
if (!supported) {
// cannot create bitmaps with such a color space
ERROR("AcceptFormat - unsupported color space for BBitmaps!\n");
ERROR("AcceptFormat - unsupported color space for BBitmaps "
"(%s)!\n",
color_space_to_string(format->u.raw_video.display.format));
return B_MEDIA_BAD_FORMAT;
}
if (!fTryOverlay && (flags & B_VIEWS_SUPPORT_DRAW_BITMAP) == 0) {
// BViews do not support drawing such a bitmap
ERROR("AcceptFormat - BViews cannot draw bitmaps in given "
"colorspace!\n");
"colorspace (%s)!\n",
color_space_to_string(format->u.raw_video.display.format));
return B_MEDIA_BAD_FORMAT;
}
}
@@ -1,9 +1,6 @@
/*
* Copyright 2007, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
* Copyright 2007-2008, Haiku. Stephan Aßmus <[email protected]>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "MediaTrackVideoSupplier.h"
@@ -13,6 +10,8 @@
#include <MediaTrack.h>
#include "ColorSpaceToString.h"
using std::nothrow;
#define DEBUG_DECODED_FRAME 0
@@ -23,9 +22,6 @@ using std::nothrow;
# include <TranslatorRoster.h>
#endif // DEBUG_DECODED_FRAME
static const char* string_for_color_space(color_space format);
// constructor
MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track,
status_t& initStatus)
@@ -232,83 +228,8 @@ MediaTrackVideoSupplier::BytesPerRow() const
// #pragma mark -
const char*
string_for_color_space(color_space format)
{
const char* name = "<unkown format>";
switch (format) {
case B_RGB32:
name = "B_RGB32";
break;
case B_RGBA32:
name = "B_RGBA32";
break;
case B_RGB32_BIG:
name = "B_RGB32_BIG";
break;
case B_RGBA32_BIG:
name = "B_RGBA32_BIG";
break;
case B_RGB24:
name = "B_RGB24";
break;
case B_RGB24_BIG:
name = "B_RGB24_BIG";
break;
case B_CMAP8:
name = "B_CMAP8";
break;
case B_GRAY8:
name = "B_GRAY8";
break;
case B_GRAY1:
name = "B_GRAY1";
break;
// YCbCr
case B_YCbCr422:
name = "B_YCbCr422";
break;
case B_YCbCr411:
name = "B_YCbCr411";
break;
case B_YCbCr444:
name = "B_YCbCr444";
break;
case B_YCbCr420:
name = "B_YCbCr420";
break;
// YUV
case B_YUV422:
name = "B_YUV422";
break;
case B_YUV411:
name = "B_YUV411";
break;
case B_YUV444:
name = "B_YUV444";
break;
case B_YUV420:
name = "B_YUV420";
break;
case B_YUV9:
name = "B_YUV9";
break;
case B_YUV12:
name = "B_YUV12";
break;
default:
break;
}
return name;
}
status_t
MediaTrackVideoSupplier::_SwitchFormat(color_space format, int32 bytesPerRow)
MediaTrackVideoSupplier::_SwitchFormat(color_space format, uint32 bytesPerRow)
{
// get the encoded format
memset(&fFormat, 0, sizeof(media_format));
@@ -331,41 +252,26 @@ MediaTrackVideoSupplier::_SwitchFormat(color_space format, int32 bytesPerRow)
} else {
printf("MediaTrackVideoSupplier::_SwitchFormat() - "
"preferred color space: %s\n",
string_for_color_space(format));
color_space_to_string(format));
}
}
// specifiy the decoded format. we derive this information from
// the encoded format (width & height).
memset(&fFormat, 0, sizeof(media_format));
// fFormat.u.raw_video.last_active = height - 1;
// fFormat.u.raw_video.orientation = B_VIDEO_TOP_LEFT_RIGHT;
// fFormat.u.raw_video.pixel_width_aspect = 1;
// fFormat.u.raw_video.pixel_height_aspect = 1;
fFormat.u.raw_video.display.format = format;
fFormat.u.raw_video.display.line_width = width;
fFormat.u.raw_video.display.line_count = height;
int32 minBytesPerRow;
uint32 minBytesPerRow;
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);
ret = fVideoTrack->DecodedFormat(&fFormat);
bytesPerRow = max_c(bytesPerRow, minBytesPerRow);
ret = _SetDecodedFormat(width, height, format, bytesPerRow);
if (ret < B_OK) {
printf("MediaTrackVideoSupplier::_SwitchFormat() - "
"fVideoTrack->DecodedFormat(): %s - retrying with B_RGB32\n",
strerror(ret));
format = B_RGB32;
fFormat.u.raw_video.display.format = format;
minBytesPerRow = width * 4;
fFormat.u.raw_video.display.bytes_per_row = max_c(minBytesPerRow,
bytesPerRow);
bytesPerRow = max_c(bytesPerRow, width * 4);
ret = fVideoTrack->DecodedFormat(&fFormat);
ret = _SetDecodedFormat(width, height, format, bytesPerRow);
if (ret < B_OK) {
printf("MediaTrackVideoSupplier::_SwitchFormat() - "
"fVideoTrack->DecodedFormat(): %s - giving up\n",
@@ -377,19 +283,18 @@ MediaTrackVideoSupplier::_SwitchFormat(color_space format, int32 bytesPerRow)
if (fFormat.u.raw_video.display.format != format) {
printf("MediaTrackVideoSupplier::_SwitchFormat() - "
" codec changed colorspace of decoded format (%s -> %s)!\n",
string_for_color_space(format),
string_for_color_space(fFormat.u.raw_video.display.format));
color_space_to_string(format),
color_space_to_string(fFormat.u.raw_video.display.format));
// check if the codec forgot to adjust bytes_per_row
uint32 minBPR;
format = fFormat.u.raw_video.display.format;
if (format == B_YCbCr422)
minBPR = ((width * 2 + 3) / 4) * 4;
minBytesPerRow = ((width * 2 + 3) / 4) * 4;
else
minBPR = width * 4;
if (minBPR > fFormat.u.raw_video.display.bytes_per_row) {
minBytesPerRow = width * 4;
if (minBytesPerRow > fFormat.u.raw_video.display.bytes_per_row) {
printf(" -> stupid codec forgot to adjust bytes_per_row!\n");
fFormat.u.raw_video.display.bytes_per_row = minBPR;
ret = fVideoTrack->DecodedFormat(&fFormat);
ret = _SetDecodedFormat(width, height, format, minBytesPerRow);
}
}
@@ -400,3 +305,24 @@ MediaTrackVideoSupplier::_SwitchFormat(color_space format, int32 bytesPerRow)
return ret;
}
status_t
MediaTrackVideoSupplier::_SetDecodedFormat(uint32 width, uint32 height,
color_space format, uint32 bytesPerRow)
{
// specifiy the decoded format. we derive this information from
// the encoded format (width & height).
memset(&fFormat, 0, sizeof(media_format));
// fFormat.u.raw_video.last_active = height - 1;
// fFormat.u.raw_video.orientation = B_VIDEO_TOP_LEFT_RIGHT;
// fFormat.u.raw_video.pixel_width_aspect = 1;
// fFormat.u.raw_video.pixel_height_aspect = 1;
fFormat.u.raw_video.display.format = format;
fFormat.u.raw_video.display.line_width = width;
fFormat.u.raw_video.display.line_count = height;
fFormat.u.raw_video.display.bytes_per_row = bytesPerRow;
return fVideoTrack->DecodedFormat(&fFormat);
}
@@ -44,7 +44,9 @@ class MediaTrackVideoSupplier : public VideoTrackSupplier {
private:
status_t _SwitchFormat(color_space format,
int32 bytesPerRow);
uint32 bytesPerRow);
status_t _SetDecodedFormat(uint32 width, uint32 height,
color_space format, uint32 bytesPerRow);
BMediaTrack* fVideoTrack;
@@ -0,0 +1,80 @@
/*
* Copyright 2007-2008, Haiku. Stephan Aßmus <[email protected]>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "ColorSpaceToString.h"
const char*
color_space_to_string(color_space format)
{
const char* name = "<unkown format>";
switch (format) {
case B_RGB32:
name = "B_RGB32";
break;
case B_RGBA32:
name = "B_RGBA32";
break;
case B_RGB32_BIG:
name = "B_RGB32_BIG";
break;
case B_RGBA32_BIG:
name = "B_RGBA32_BIG";
break;
case B_RGB24:
name = "B_RGB24";
break;
case B_RGB24_BIG:
name = "B_RGB24_BIG";
break;
case B_CMAP8:
name = "B_CMAP8";
break;
case B_GRAY8:
name = "B_GRAY8";
break;
case B_GRAY1:
name = "B_GRAY1";
break;
// YCbCr
case B_YCbCr422:
name = "B_YCbCr422";
break;
case B_YCbCr411:
name = "B_YCbCr411";
break;
case B_YCbCr444:
name = "B_YCbCr444";
break;
case B_YCbCr420:
name = "B_YCbCr420";
break;
// YUV
case B_YUV422:
name = "B_YUV422";
break;
case B_YUV411:
name = "B_YUV411";
break;
case B_YUV444:
name = "B_YUV444";
break;
case B_YUV420:
name = "B_YUV420";
break;
case B_YUV9:
name = "B_YUV9";
break;
case B_YUV12:
name = "B_YUV12";
break;
default:
break;
}
return name;
}
@@ -0,0 +1,13 @@
/*
* Copyright 2007-2008, Haiku. Stephan Aßmus <[email protected]>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef COLOR_SPACE_TO_STRING_H
#define COLOR_SPACE_TO_STRING_H
#include <GraphicsDefs.h>
const char* color_space_to_string(color_space format);
#endif // COLOR_SPACE_TO_STRING_H