diff --git a/src/add-ons/media/media-add-ons/Jamfile b/src/add-ons/media/media-add-ons/Jamfile index 8e5594b557..5319ab2f2e 100644 --- a/src/add-ons/media/media-add-ons/Jamfile +++ b/src/add-ons/media/media-add-ons/Jamfile @@ -14,4 +14,5 @@ SubInclude HAIKU_TOP src add-ons media media-add-ons tone_producer_demo ; SubInclude HAIKU_TOP src add-ons media media-add-ons usb_vision ; SubInclude HAIKU_TOP src add-ons media media-add-ons usb_webcam ; SubInclude HAIKU_TOP src add-ons media media-add-ons video_producer_demo ; +SubInclude HAIKU_TOP src add-ons media media-add-ons videowindow ; diff --git a/src/add-ons/media/media-add-ons/videowindow/Jamfile b/src/add-ons/media/media-add-ons/videowindow/Jamfile new file mode 100644 index 0000000000..6067f9fee4 --- /dev/null +++ b/src/add-ons/media/media-add-ons/videowindow/Jamfile @@ -0,0 +1,9 @@ +SubDir HAIKU_TOP src add-ons media media-add-ons videowindow ; + +Addon video_window_demo.media_addon : + VideoAddOn.cpp + VideoNode.cpp + VideoView.cpp + VideoWindow.cpp + : be media +; diff --git a/src/add-ons/media/media-add-ons/videowindow/VideoAddOn.cpp b/src/add-ons/media/media-add-ons/videowindow/VideoAddOn.cpp index a70366d6c0..d1edd82b29 100644 --- a/src/add-ons/media/media-add-ons/videowindow/VideoAddOn.cpp +++ b/src/add-ons/media/media-add-ons/videowindow/VideoAddOn.cpp @@ -1,6 +1,102 @@ /* - * Copyright (C) 2006 Marcus Overhagen . All rights reserved. + * Copyright (C) 2006-2008 Marcus Overhagen . All rights reserved. + * Copyright (C) 2008 Maurice Kalinowski . All rights reserved. * * Distributed under the terms of the MIT License. */ #include "VideoAddOn.h" +#include "VideoNode.h" +#include "VideoView.h" +#include "debug.h" + + +#include +#include + + +VideoWindowAddOn::VideoWindowAddOn(image_id id) + : BMediaAddOn(id) +{ + CALLED(); + fInfo.internal_id = 0; + fInfo.name = strdup("VideoWindow Consumer"); + fInfo.info = strdup("This node displays a simple video window"); + fInfo.kinds = B_BUFFER_CONSUMER; + fInfo.flavor_flags = 0; + fInfo.possible_count = 0; + fInfo.in_format_count = 1; + media_format *inFormat = new media_format; + inFormat->type = B_MEDIA_RAW_VIDEO; + inFormat->u.raw_video = media_raw_video_format::wildcard; + fInfo.in_formats = inFormat; +} + + +VideoWindowAddOn::~VideoWindowAddOn() +{ +} + + + +bool +VideoWindowAddOn::WantsAutoStart() +{ + CALLED(); + return false; +} + + +int32 +VideoWindowAddOn::CountFlavors() +{ + CALLED(); + return 1; +} + + +status_t +VideoWindowAddOn::GetFlavorAt(int32 cookie, const flavor_info **flavorInfo) +{ + CALLED(); + if (cookie != 0) + return B_BAD_INDEX; + if (!flavorInfo || !*flavorInfo) + return B_ERROR; + + *flavorInfo = &fInfo; + return B_OK; +} + + +BMediaNode* +VideoWindowAddOn::InstantiateNodeFor(const flavor_info *info, BMessage*, status_t *outError) +{ + CALLED(); + if (!outError) + return NULL; + + if (info->in_formats[0].type != B_MEDIA_RAW_VIDEO) { + *outError = B_MEDIA_BAD_FORMAT; + return NULL; + } + + BRect size; + if (info->in_formats[0].u.raw_video.display.line_width != 0) + size.right = info->in_formats[0].u.raw_video.display.line_width; + else + size.right = 320; + if (info->in_formats[0].u.raw_video.display.line_count != 0) + size.bottom = info->in_formats[0].u.raw_video.display.line_count; + else + size.bottom = 240; + + VideoNode* node = new VideoNode("Video Node", this, info->internal_id); + + return node; +} + + +extern "C" BMediaAddOn *make_media_addon(image_id id) +{ + return new VideoWindowAddOn(id); +} diff --git a/src/add-ons/media/media-add-ons/videowindow/VideoAddOn.h b/src/add-ons/media/media-add-ons/videowindow/VideoAddOn.h index a08a31120c..ef6b85ec55 100644 --- a/src/add-ons/media/media-add-ons/videowindow/VideoAddOn.h +++ b/src/add-ons/media/media-add-ons/videowindow/VideoAddOn.h @@ -1,18 +1,29 @@ /* - * Copyright (C) 2006 Marcus Overhagen . All rights reserved. + * Copyright (C) 2006-2008 Marcus Overhagen . All rights reserved. + * Copyright (C) 2008 Maurice Kalinowski . All rights reserved. * * Distributed under the terms of the MIT License. */ #ifndef __VIDEO_ADD_ON_H #define __VIDEO_ADD_ON_H + #include -class MediaAddOn : public BMediaAddOn + +class VideoWindowAddOn : public BMediaAddOn { public: + VideoWindowAddOn(image_id); + ~VideoWindowAddOn(); + + bool WantsAutoStart(); + int32 CountFlavors(); + status_t GetFlavorAt(int32, const flavor_info**); + BMediaNode* InstantiateNodeFor(const flavor_info*, BMessage*, status_t*); private: + flavor_info fInfo; }; extern "C" BMediaAddOn *make_media_addon(image_id id); diff --git a/src/add-ons/media/media-add-ons/videowindow/VideoNode.cpp b/src/add-ons/media/media-add-ons/videowindow/VideoNode.cpp index 3c41efb0c9..d6029a472d 100644 --- a/src/add-ons/media/media-add-ons/videowindow/VideoNode.cpp +++ b/src/add-ons/media/media-add-ons/videowindow/VideoNode.cpp @@ -1,51 +1,78 @@ /* * Copyright (C) 2006 Marcus Overhagen . All rights reserved. + * Copyright (C) 2008 Maurice Kalinowski . All rights reserved. * * Distributed under the terms of the MIT License. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "VideoNode.h" #include "VideoView.h" +#include "VideoWindow.h" -VideoNode::VideoNode(const char *name, VideoView *view) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +VideoNode::VideoNode(const char *name) : BMediaNode(name) , BMediaEventLooper() , BBufferConsumer(B_MEDIA_RAW_VIDEO) - , fVideoView(view) + , fWindow(0) + , fVideoView(0) , fInput() , fOverlayEnabled(true) , fOverlayActive(false) , fDirectOverlayBuffer(false) , fBitmap(0) , fBitmapLocker(new BLocker("Video Node Locker")) + , fAddOn(0) + , fInternalFlavorId(0) { + _InitDisplay(); } +VideoNode::VideoNode(const char *name, BMediaAddOn* addon, int32 id) + : BMediaNode(name) + , BMediaEventLooper() + , BBufferConsumer(B_MEDIA_RAW_VIDEO) + , fWindow(0) + , fVideoView(0) + , fInput() + , fOverlayEnabled(true) + , fOverlayActive(false) + , fDirectOverlayBuffer(false) + , fBitmap(0) + , fBitmapLocker(new BLocker("Video Node Locker")) + , fAddOn(addon) + , fInternalFlavorId(id) +{ + _InitDisplay(); +} + VideoNode::~VideoNode() { Quit(); DeleteBuffers(); delete fBitmapLocker; + if (fWindow) + fWindow->Quit(); } BMediaAddOn * VideoNode::AddOn(int32 *internal_id) const { - *internal_id = 0; - return NULL; + *internal_id = fInternalFlavorId; + return fAddOn; } @@ -127,7 +154,7 @@ VideoNode::HandleEvent(const media_timed_event *event, HandleBuffer((BBuffer *)event->pointer); break; default: - printf("VideoNode::HandleEvent unknown event"); + fprintf(stderr, "VideoNode::HandleEvent unknown event"); break; } } @@ -149,12 +176,13 @@ VideoNode::GetLatencyFor(const media_destination &dst, { if (dst != fInput.destination) return B_MEDIA_BAD_DESTINATION; - + *out_latency = 10000; *out_id = TimeSource()->ID(); return B_OK; } + status_t VideoNode::AcceptFormat(const media_destination &dst, media_format *format) @@ -166,17 +194,15 @@ VideoNode::AcceptFormat(const media_destination &dst, * BBufferConsumer::Connected * BBufferProducer::Connect */ - if (dst != fInput.destination) return B_MEDIA_BAD_DESTINATION; - + if (format->type == B_MEDIA_NO_TYPE) format->type = B_MEDIA_RAW_VIDEO; - + if (format->type != B_MEDIA_RAW_VIDEO) return B_MEDIA_BAD_FORMAT; - return B_OK; } @@ -210,15 +236,19 @@ VideoNode::Connected(const media_source &src, DeleteBuffers(); err = CreateBuffers(frame, colorspace, fOverlayEnabled); + if (err && fOverlayEnabled) { + SetOverlayEnabled(false); + err = CreateBuffers(frame, colorspace, fOverlayEnabled); + } + if (err) { - printf("VideoNode::Connected failed, fOverlayEnabled = %d\n", fOverlayEnabled); + fprintf(stderr, "VideoNode::Connected failed, fOverlayEnabled = %d\n", fOverlayEnabled); return err; } *out_input = fInput; return B_OK; - } @@ -244,7 +274,6 @@ VideoNode::FormatChanged(const media_source &src, int32 from_change_count, const media_format &format) { - printf("VideoNode::FormatChanged enter\n"); if (src != fInput.source) return B_MEDIA_BAD_SOURCE; if (dst != fInput.destination) @@ -259,20 +288,20 @@ VideoNode::FormatChanged(const media_source &src, fVideoView->RemoveOverlay(); err = CreateBuffers(frame, colorspace, true); // try overlay if (err) { - printf("VideoNode::FormatChanged creating overlay buffer failed\n"); + fprintf(stderr, "VideoNode::FormatChanged creating overlay buffer failed\n"); err = CreateBuffers(frame, colorspace, false); // no overlay } } else { err = CreateBuffers(frame, colorspace, false); // no overlay } + if (err) { - printf("VideoNode::FormatChanged failed (lost buffer group!)\n"); + fprintf(stderr, "VideoNode::FormatChanged failed (lost buffer group!)\n"); return B_MEDIA_BAD_FORMAT; } fInput.format = format; - printf("VideoNode::FormatChanged leave\n"); return B_OK; } @@ -280,10 +309,8 @@ VideoNode::FormatChanged(const media_source &src, void VideoNode::HandleBuffer(BBuffer *buffer) { -// printf("VideoNode::HandleBuffer\n"); - LockBitmap(); - if (fBitmap) { + if (fBitmap && fWindow && fVideoView) { // bigtime_t start = system_time(); if (fOverlayActive) { if (B_OK == fBitmap->LockBits()) { @@ -341,8 +368,8 @@ VideoNode::IsOverlayActive() status_t VideoNode::CreateBuffers(BRect frame, color_space cspace, bool overlay) { - printf("VideoNode::CreateBuffers: frame %d,%d,%d,%d colorspace 0x%08x, overlay %d\n", - int(frame.left), int(frame.top), int(frame.right), int(frame.bottom), int(cspace), overlay); + //printf("VideoNode::CreateBuffers: frame %d,%d,%d,%d colorspace 0x%08x, overlay %d\n", + // int(frame.left), int(frame.top), int(frame.right), int(frame.bottom), int(cspace), overlay); LockBitmap(); ASSERT(fBitmap == 0); @@ -353,12 +380,12 @@ VideoNode::CreateBuffers(BRect frame, color_space cspace, bool overlay) fBitmap = 0; fOverlayActive = false; UnlockBitmap(); - printf("VideoNode::CreateBuffers failed\n"); + fprintf(stderr, "VideoNode::CreateBuffers failed\n"); return B_ERROR; } fOverlayActive = overlay; UnlockBitmap(); - printf("VideoNode::CreateBuffers success\n"); + return B_OK; } @@ -371,3 +398,16 @@ VideoNode::DeleteBuffers() fBitmap = NULL; UnlockBitmap(); } + + +void +VideoNode::_InitDisplay() +{ + // TODO: Get rid of hardcoded values + BRect size(0,0,320,240); + fVideoView = new VideoView(size, "Video View", B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE, this); + + size.OffsetBy(40.f, 40.f); + fWindow = new VideoWindow(size, fVideoView); + fWindow->Show(); +} diff --git a/src/add-ons/media/media-add-ons/videowindow/VideoNode.h b/src/add-ons/media/media-add-ons/videowindow/VideoNode.h index 5b18b5bd94..e4d649739e 100644 --- a/src/add-ons/media/media-add-ons/videowindow/VideoNode.h +++ b/src/add-ons/media/media-add-ons/videowindow/VideoNode.h @@ -1,25 +1,34 @@ /* * Copyright (C) 2006 Marcus Overhagen . All rights reserved. + * Copyright (C) 2008 Maurice Kalinowski . All rights reserved. * * Distributed under the terms of the MIT License. */ #ifndef __VIDEO_NODE_H_ #define __VIDEO_NODE_H_ + #include #include + +class BBitmap; +class BLocker; +class BWindow; class VideoView; +class VideoWindow; + class VideoNode : public BMediaEventLooper, public BBufferConsumer { public: - VideoNode(const char *name, VideoView *view); + VideoNode(const char *name); + VideoNode(const char *name, BMediaAddOn* addon, int32 id); ~VideoNode(); void SetOverlayEnabled(bool yesno); bool IsOverlayActive(); - + void LockBitmap(); BBitmap * Bitmap(); void UnlockBitmap(); @@ -52,7 +61,7 @@ protected: const media_destination &dst, int32 status, bigtime_t at_media_time); - + status_t GetLatencyFor( const media_destination &dst, bigtime_t *out_latency, @@ -74,12 +83,13 @@ protected: int32 from_change_count, const media_format &format); -protected: void HandleBuffer(BBuffer *buffer); status_t CreateBuffers(BRect frame, color_space cspace, bool overlay); void DeleteBuffers(); -protected: +private: + void _InitDisplay(); + VideoWindow * fWindow; VideoView * fVideoView; media_input fInput; bool fOverlayEnabled; @@ -87,6 +97,8 @@ protected: bool fDirectOverlayBuffer; // If the overlay memory is directly written by the producer node. BBitmap * fBitmap; BLocker * fBitmapLocker; + BMediaAddOn* fAddOn; + int32 fInternalFlavorId; }; #endif diff --git a/src/add-ons/media/media-add-ons/videowindow/VideoView.cpp b/src/add-ons/media/media-add-ons/videowindow/VideoView.cpp index 946a974c3e..9e1e3e385e 100644 --- a/src/add-ons/media/media-add-ons/videowindow/VideoView.cpp +++ b/src/add-ons/media/media-add-ons/videowindow/VideoView.cpp @@ -3,39 +3,32 @@ * * Distributed under the terms of the MIT License. */ -#include -#include -#include "VideoView.h" #include "VideoNode.h" +#include "VideoView.h" +#include "debug.h" + +#include +#include +#include +#include + #include +#include #include -VideoView::VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags) + +VideoView::VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags, VideoNode *node) : BView(frame, name, resizeMask, flags) - , fVideoNode(0) + , fVideoNode(node) , fOverlayActive(false) { SetViewColor(B_TRANSPARENT_COLOR); - - status_t err = B_OK; - BMediaRoster *mroster = BMediaRoster::Roster(&err); - if (!mroster || err) { - printf("VideoView::VideoView: media_server is dead\n"); - exit(1); - } else { - fVideoNode = new VideoNode("video in", this); - err = mroster->RegisterNode(fVideoNode); - } } VideoView::~VideoView() { - if (fVideoNode) { - BMediaRoster::Roster()->UnregisterNode(fVideoNode); - delete fVideoNode; - } } @@ -55,14 +48,14 @@ VideoView::Node() void VideoView::OverlayLockAcquire() { - printf("VideoView::OverlayLockAcquire\n"); + CALLED(); } void VideoView::OverlayLockRelease() { - printf("VideoView::OverlayLockRelease\n"); + CALLED(); // overlaybitmap->UnlockBits } @@ -70,7 +63,7 @@ VideoView::OverlayLockRelease() void VideoView::OverlayScreenshotPrepare() { - printf("OverlayScreenshotPrepare enter\n"); + CALLED(); /* fVideoNode->LockBitmap(); if (fOverlayActive) { @@ -88,14 +81,13 @@ VideoView::OverlayScreenshotPrepare() } fVideoNode->UnlockBitmap(); */ - printf("OverlayScreenshotPrepare leave\n"); } void VideoView::OverlayScreenshotCleanup() { - printf("OverlayScreenshotCleanup enter\n"); + CALLED(); /* snooze(50000); // give app server some time to take the screenshot fVideoNode->LockBitmap(); @@ -110,15 +102,14 @@ VideoView::OverlayScreenshotCleanup() } fVideoNode->UnlockBitmap(); */ - printf("OverlayScreenshotCleanup leave\n"); } void VideoView::RemoveVideoDisplay() { - printf("VideoView::RemoveVideoDisplay\n"); - + CALLED(); + if (fOverlayActive) { ClearViewOverlay(); fOverlayActive = false; @@ -130,7 +121,7 @@ VideoView::RemoveVideoDisplay() void VideoView::RemoveOverlay() { - printf("VideoView::RemoveOverlay\n"); + CALLED(); if (LockLooperWithTimeout(50000) == B_OK) { ClearViewOverlay(); fOverlayActive = false; @@ -148,7 +139,10 @@ VideoView::Draw(BRect updateRect) } else { fVideoNode->LockBitmap(); BBitmap *bmp = fVideoNode->Bitmap(); - if (bmp) + if (!bmp) { + SetHighColor(0, 0, 0, 0); + FillRect(updateRect); + } else DrawBitmap(bmp, Bounds()); fVideoNode->UnlockBitmap(); } @@ -158,8 +152,8 @@ VideoView::Draw(BRect updateRect) void VideoView::DrawFrame() { -// printf("VideoView::DrawFrame\n"); - + //CALLED(); + bool want_overlay = fVideoNode->IsOverlayActive(); if (!want_overlay && fOverlayActive) { @@ -168,9 +162,10 @@ VideoView::DrawFrame() UnlockLooper(); fOverlayActive = false; } else { - printf("can't ClearViewOverlay, as LockLooperWithTimeout failed\n"); + fprintf(stderr, "VideoView::DrawFrame: cannot ClearViewOverlay, as LockLooperWithTimeout failed\n"); } } + if (want_overlay && !fOverlayActive) { fVideoNode->LockBitmap(); BBitmap *bmp = fVideoNode->Bitmap(); @@ -247,4 +242,3 @@ VideoView::IsOverlaySupported() } return supported; } - diff --git a/src/add-ons/media/media-add-ons/videowindow/VideoView.h b/src/add-ons/media/media-add-ons/videowindow/VideoView.h index aa37b8201f..0d046a4d93 100644 --- a/src/add-ons/media/media-add-ons/videowindow/VideoView.h +++ b/src/add-ons/media/media-add-ons/videowindow/VideoView.h @@ -6,19 +6,23 @@ #ifndef __VIDEO_VIEW_H #define __VIDEO_VIEW_H + #include + +class BMediaAddOn; class VideoNode; + class VideoView : public BView { public: - VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags); + VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags, VideoNode *node); ~VideoView(); - + void RemoveVideoDisplay(); void RemoveOverlay(); - + VideoNode * Node(); bool IsOverlaySupported(); @@ -28,14 +32,14 @@ public: void OverlayScreenshotPrepare(); void OverlayScreenshotCleanup(); - + void DrawFrame(); private: void AttachedToWindow(); void MessageReceived(BMessage *msg); void Draw(BRect updateRect); - + private: VideoNode * fVideoNode; bool fOverlayActive; diff --git a/src/add-ons/media/media-add-ons/videowindow/VideoWindow.cpp b/src/add-ons/media/media-add-ons/videowindow/VideoWindow.cpp index b988429949..d583ae9af6 100644 --- a/src/add-ons/media/media-add-ons/videowindow/VideoWindow.cpp +++ b/src/add-ons/media/media-add-ons/videowindow/VideoWindow.cpp @@ -1,11 +1,30 @@ /* - * Copyright (C) 2006 Marcus Overhagen . All rights reserved. + * Copyright (C) 2006-2008 Marcus Overhagen . All rights reserved. + * Copyright (C) 2008 Maurice Kalinowski . All rights reserved. * * Distributed under the terms of the MIT License. */ -#include "VideoView.h" -#include "VideoNode.h" #include "VideoWindow.h" +#include "VideoView.h" -#include -#include + +VideoWindow::VideoWindow(BRect size, VideoView* view) + : BWindow(size, "Video Window", B_TITLED_WINDOW, 0) + , fVideoView(view) +{ + if (fVideoView) + AddChild(fVideoView); +} + + +VideoWindow::~VideoWindow() +{ +} + + +void +VideoWindow::MessageReceived(BMessage *msg) +{ + if (msg) + BWindow::MessageReceived(msg); +} diff --git a/src/add-ons/media/media-add-ons/videowindow/VideoWindow.h b/src/add-ons/media/media-add-ons/videowindow/VideoWindow.h index b72c2666db..6638215057 100644 --- a/src/add-ons/media/media-add-ons/videowindow/VideoWindow.h +++ b/src/add-ons/media/media-add-ons/videowindow/VideoWindow.h @@ -1,24 +1,27 @@ /* - * Copyright (C) 2006 Marcus Overhagen . All rights reserved. + * Copyright (C) 2006-2008 Marcus Overhagen . All rights reserved. + * Copyright (C) 2008 Maurice Kalinowski . All rights reserved. * * Distributed under the terms of the MIT License. */ #ifndef __VIDEO_WINDOW_H #define __VIDEO_WINDOW_H + #include -class VideoNode; + class VideoView; + class VideoWindow : public BWindow { public: + VideoWindow(BRect size, VideoView* view); + ~VideoWindow(); + void MessageReceived(BMessage *msg); private: - -private: - VideoNode * fVideoNode; VideoView * fVideoView; }; diff --git a/src/add-ons/media/media-add-ons/videowindow/debug.h b/src/add-ons/media/media-add-ons/videowindow/debug.h new file mode 100644 index 0000000000..835882f2e8 --- /dev/null +++ b/src/add-ons/media/media-add-ons/videowindow/debug.h @@ -0,0 +1,34 @@ + +#include + +#ifndef NDEBUG + + #ifndef DEBUG + #define DEBUG 2 + #endif + + #if DEBUG >= 1 + #define UNIMPLEMENTED() printf("UNIMPLEMENTED %s\n",__PRETTY_FUNCTION__) + #else + #define UNIMPLEMENTED() ((void)0) + #endif + + #if DEBUG >= 2 + #define BROKEN() printf("BROKEN %s\n",__PRETTY_FUNCTION__) + #else + #define BROKEN() ((void)0) + #endif + + #if DEBUG >= 3 + #define CALLED() printf("CALLED %s\n",__PRETTY_FUNCTION__) + #else + #define CALLED() ((void)0) + #endif + +#else + + #define UNIMPLEMENTED() ((void)0) + #define BROKEN() ((void)0) + #define CALLED() ((void)0) + +#endif