* 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:
@@ -245,14 +245,21 @@ Controller::SetTo(const entry_ref &ref)
|
|||||||
SelectAudioTrack(0);
|
SelectAudioTrack(0);
|
||||||
SelectVideoTrack(0);
|
SelectVideoTrack(0);
|
||||||
|
|
||||||
|
// prevent blocking the creation of new overlay buffers
|
||||||
fVideoView->DisableOverlay();
|
fVideoView->DisableOverlay();
|
||||||
|
|
||||||
|
// get video properties (if there is video at all)
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
GetSize(&width, &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,
|
Init(BRect(0, 0, width - 1, height - 1), fVideoFrameRate,
|
||||||
LOOPING_ALL, false);
|
preferredVideoFormat, LOOPING_ALL, false);
|
||||||
|
|
||||||
SetCurrentFrame(0);
|
SetCurrentFrame(0);
|
||||||
|
|
||||||
@@ -339,8 +346,7 @@ Controller::SelectVideoTrack(int n)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
ObjectDeleter<VideoTrackSupplier> deleter(fVideoTrackSupplier);
|
ObjectDeleter<VideoTrackSupplier> deleter(fVideoTrackSupplier);
|
||||||
fVideoTrackSupplier = new MediaTrackVideoSupplier(track,
|
fVideoTrackSupplier = new MediaTrackVideoSupplier(track);
|
||||||
IsOverlayActive() ? B_YCbCr422 : B_RGB32);
|
|
||||||
|
|
||||||
bigtime_t a = fAudioTrackSupplier ? fAudioTrackSupplier->Duration() : 0;
|
bigtime_t a = fAudioTrackSupplier ? fAudioTrackSupplier->Duration() : 0;
|
||||||
bigtime_t v = fVideoTrackSupplier->Duration();
|
bigtime_t v = fVideoTrackSupplier->Duration();
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ NodeManager::~NodeManager()
|
|||||||
|
|
||||||
// Init
|
// Init
|
||||||
status_t
|
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)
|
bool loopingEnabled, float speed)
|
||||||
{
|
{
|
||||||
// init base class
|
// init base class
|
||||||
@@ -80,7 +81,8 @@ NodeManager::Init(BRect videoBounds, float videoFrameRate, int32 loopingMode,
|
|||||||
if (!fAudioSupplier)
|
if (!fAudioSupplier)
|
||||||
fAudioSupplier = CreateAudioSupplier();
|
fAudioSupplier = CreateAudioSupplier();
|
||||||
|
|
||||||
return FormatChanged(videoBounds, videoFrameRate, true);
|
return FormatChanged(videoBounds, videoFrameRate, preferredVideoFormat,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitCheck
|
// InitCheck
|
||||||
@@ -114,7 +116,8 @@ NodeManager::CleanupNodes()
|
|||||||
|
|
||||||
// FormatChanged
|
// FormatChanged
|
||||||
status_t
|
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()
|
if (!force && videoBounds == VideoBounds()
|
||||||
&& videoFrameRate == FramesPerSecond())
|
&& videoFrameRate == FramesPerSecond())
|
||||||
@@ -130,7 +133,7 @@ NodeManager::FormatChanged(BRect videoBounds, float videoFrameRate, bool force)
|
|||||||
|
|
||||||
SetVideoBounds(videoBounds);
|
SetVideoBounds(videoBounds);
|
||||||
|
|
||||||
status_t ret = _SetUpNodes();
|
status_t ret = _SetUpNodes(preferredVideoFormat);
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
_StartNodes();
|
_StartNodes();
|
||||||
else
|
else
|
||||||
@@ -225,7 +228,7 @@ NodeManager::SetVolume(float percent)
|
|||||||
|
|
||||||
// _SetUpNodes
|
// _SetUpNodes
|
||||||
status_t
|
status_t
|
||||||
NodeManager::_SetUpNodes()
|
NodeManager::_SetUpNodes(color_space preferredVideoFormat)
|
||||||
{
|
{
|
||||||
printf("NodeManager::_SetUpNodes()\n");
|
printf("NodeManager::_SetUpNodes()\n");
|
||||||
|
|
||||||
@@ -250,7 +253,7 @@ printf("NodeManager::_SetUpNodes()\n");
|
|||||||
|
|
||||||
// setup the video nodes
|
// setup the video nodes
|
||||||
if (fVideoBounds.IsValid()) {
|
if (fVideoBounds.IsValid()) {
|
||||||
fStatus = _SetUpVideoNodes();
|
fStatus = _SetUpVideoNodes(preferredVideoFormat);
|
||||||
if (fStatus != B_OK) {
|
if (fStatus != B_OK) {
|
||||||
print_error("Error setting up video nodes", fStatus);
|
print_error("Error setting up video nodes", fStatus);
|
||||||
fMediaRoster->Unlock();
|
fMediaRoster->Unlock();
|
||||||
@@ -277,7 +280,7 @@ printf("NodeManager::_SetUpNodes()\n");
|
|||||||
|
|
||||||
// _SetUpVideoNodes
|
// _SetUpVideoNodes
|
||||||
status_t
|
status_t
|
||||||
NodeManager::_SetUpVideoNodes()
|
NodeManager::_SetUpVideoNodes(color_space preferredVideoFormat)
|
||||||
{
|
{
|
||||||
// create the video producer node
|
// create the video producer node
|
||||||
fVideoProducer = new VideoProducer(NULL, "MediaPlayer Video Out", 0,
|
fVideoProducer = new VideoProducer(NULL, "MediaPlayer Video Out", 0,
|
||||||
@@ -342,7 +345,7 @@ NodeManager::_SetUpVideoNodes()
|
|||||||
fVideoBounds.IntegerWidth(),
|
fVideoBounds.IntegerWidth(),
|
||||||
B_VIDEO_TOP_LEFT_RIGHT, 1, 1,
|
B_VIDEO_TOP_LEFT_RIGHT, 1, 1,
|
||||||
{
|
{
|
||||||
B_YCbCr422,
|
preferredVideoFormat,
|
||||||
fVideoBounds.IntegerWidth() + 1,
|
fVideoBounds.IntegerWidth() + 1,
|
||||||
fVideoBounds.IntegerHeight() + 1,
|
fVideoBounds.IntegerHeight() + 1,
|
||||||
0, 0, 0
|
0, 0, 0
|
||||||
@@ -354,7 +357,7 @@ NodeManager::_SetUpVideoNodes()
|
|||||||
fStatus = fMediaRoster->Connect(videoOutput.source, videoInput.destination,
|
fStatus = fMediaRoster->Connect(videoOutput.source, videoInput.destination,
|
||||||
&format, &videoOutput, &videoInput);
|
&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... "
|
print_error("Can't connect the video source to the video window... "
|
||||||
"trying B_RGB32", fStatus);
|
"trying B_RGB32", fStatus);
|
||||||
format.u.raw_video.display.format = B_RGB32;
|
format.u.raw_video.display.format = B_RGB32;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class NodeManager : public PlaybackManager {
|
|||||||
|
|
||||||
// NodeManager
|
// NodeManager
|
||||||
status_t Init(BRect videoBounds, float videoFrameRate,
|
status_t Init(BRect videoBounds, float videoFrameRate,
|
||||||
|
color_space preferredVideoFormat,
|
||||||
int32 loopingMode = LOOPING_ALL,
|
int32 loopingMode = LOOPING_ALL,
|
||||||
bool loopingEnabled = true,
|
bool loopingEnabled = true,
|
||||||
float speed = 1.0);
|
float speed = 1.0);
|
||||||
@@ -42,7 +43,9 @@ class NodeManager : public PlaybackManager {
|
|||||||
status_t CleanupNodes();
|
status_t CleanupNodes();
|
||||||
|
|
||||||
status_t FormatChanged(BRect videoBounds,
|
status_t FormatChanged(BRect videoBounds,
|
||||||
float videoFrameRate, bool force = false);
|
float videoFrameRate,
|
||||||
|
color_space preferredVideoFormat,
|
||||||
|
bool force = false);
|
||||||
virtual void SetPlayMode(int32 mode,
|
virtual void SetPlayMode(int32 mode,
|
||||||
bool continuePlaying = true);
|
bool continuePlaying = true);
|
||||||
|
|
||||||
@@ -60,8 +63,9 @@ class NodeManager : public PlaybackManager {
|
|||||||
virtual void SetVolume(float percent);
|
virtual void SetVolume(float percent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _SetUpNodes();
|
status_t _SetUpNodes(color_space preferredVideoFormat);
|
||||||
status_t _SetUpVideoNodes();
|
status_t _SetUpVideoNodes(
|
||||||
|
color_space preferredVideoFormat);
|
||||||
status_t _SetUpAudioNodes();
|
status_t _SetUpAudioNodes();
|
||||||
status_t _TearDownNodes(bool disconnect = true);
|
status_t _TearDownNodes(bool disconnect = true);
|
||||||
status_t _StartNodes();
|
status_t _StartNodes();
|
||||||
|
|||||||
@@ -225,7 +225,8 @@ VideoConsumer::CreateBuffers(const media_format& format)
|
|||||||
for (uint32 i = 0; i < kBufferCount; i++) {
|
for (uint32 i = 0; i < kBufferCount; i++) {
|
||||||
// figure out the bitmap creation flags
|
// figure out the bitmap creation flags
|
||||||
uint32 bitmapFlags = 0;
|
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
|
// try to use hardware overlay
|
||||||
bitmapFlags |= B_BITMAP_WILL_OVERLAY;
|
bitmapFlags |= B_BITMAP_WILL_OVERLAY;
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
@@ -262,6 +263,7 @@ VideoConsumer::CreateBuffers(const media_format& format)
|
|||||||
info.size = (size_t)fBitmap[i]->BitsLength();
|
info.size = (size_t)fBitmap[i]->BitsLength();
|
||||||
info.flags = 0;
|
info.flags = 0;
|
||||||
info.buffer = 0;
|
info.buffer = 0;
|
||||||
|
// the media buffer id
|
||||||
|
|
||||||
BBuffer *buffer = NULL;
|
BBuffer *buffer = NULL;
|
||||||
if ((status = fBuffers->AddBuffer(info, &buffer)) != B_OK) {
|
if ((status = fBuffers->AddBuffer(info, &buffer)) != B_OK) {
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ static const char* string_for_color_space(color_space format);
|
|||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track,
|
MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track)
|
||||||
color_space format)
|
|
||||||
: VideoTrackSupplier()
|
: VideoTrackSupplier()
|
||||||
, fVideoTrack(track)
|
, fVideoTrack(track)
|
||||||
|
|
||||||
@@ -41,7 +40,7 @@ MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_SwitchFormat(format, 0);
|
_SwitchFormat(B_NO_COLOR_SPACE, 0);
|
||||||
|
|
||||||
fDuration = fVideoTrack->Duration();
|
fDuration = fVideoTrack->Duration();
|
||||||
|
|
||||||
@@ -320,6 +319,18 @@ MediaTrackVideoSupplier::_SwitchFormat(color_space format, int32 bytesPerRow)
|
|||||||
// get ouput video frame size
|
// get ouput video frame size
|
||||||
uint32 width = fFormat.u.encoded_video.output.display.line_width;
|
uint32 width = fFormat.u.encoded_video.output.display.line_width;
|
||||||
uint32 height = fFormat.u.encoded_video.output.display.line_count;
|
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
|
// specifiy the decoded format. we derive this information from
|
||||||
// the encoded format (width & height).
|
// 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_width = width;
|
||||||
fFormat.u.raw_video.display.line_count = height;
|
fFormat.u.raw_video.display.line_count = height;
|
||||||
int32 minBytesPerRow;
|
int32 minBytesPerRow;
|
||||||
if (format == B_RGB32 || format == B_RGBA32)
|
if (format == B_YCbCr422)
|
||||||
minBytesPerRow = width * 4;
|
|
||||||
else if (format == B_YCbCr422)
|
|
||||||
minBytesPerRow = ((width * 2 + 3) / 4) * 4;
|
minBytesPerRow = ((width * 2 + 3) / 4) * 4;
|
||||||
|
else
|
||||||
|
minBytesPerRow = width * 4;
|
||||||
fFormat.u.raw_video.display.bytes_per_row = max_c(minBytesPerRow,
|
fFormat.u.raw_video.display.bytes_per_row = max_c(minBytesPerRow,
|
||||||
bytesPerRow);
|
bytesPerRow);
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ class BMediaTrack;
|
|||||||
|
|
||||||
class MediaTrackVideoSupplier : public VideoTrackSupplier {
|
class MediaTrackVideoSupplier : public VideoTrackSupplier {
|
||||||
public:
|
public:
|
||||||
MediaTrackVideoSupplier(BMediaTrack* track,
|
MediaTrackVideoSupplier(BMediaTrack* track);
|
||||||
color_space preferredFormat);
|
|
||||||
virtual ~MediaTrackVideoSupplier();
|
virtual ~MediaTrackVideoSupplier();
|
||||||
|
|
||||||
virtual const media_format& Format() const;
|
virtual const media_format& Format() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user