* 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:
parent
8d1699709a
commit
d7f2503a08
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user