1 /* 2 * VideoView.cpp - "Video Window" media add-on. 3 * 4 * Copyright (C) 2006 Marcus Overhagen <marcus@overhagen.de> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * version 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * 19 */ 20 #include <Bitmap.h> 21 #include <MediaRoster.h> 22 #include "VideoView.h" 23 #include "VideoNode.h" 24 25 #include <stdio.h> 26 #include <string.h> 27 28 VideoView::VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags) 29 : BView(frame, name, resizeMask, flags) 30 , fVideoNode(0) 31 , fOverlayActive(false) 32 { 33 SetViewColor(B_TRANSPARENT_COLOR); 34 35 status_t err = B_OK; 36 BMediaRoster *mroster = BMediaRoster::Roster(&err); 37 if (!mroster || err) { 38 printf("VideoView::VideoView: media_server is dead\n"); 39 exit(1); 40 } else { 41 fVideoNode = new VideoNode("video in", this); 42 err = mroster->RegisterNode(fVideoNode); 43 } 44 } 45 46 47 VideoView::~VideoView() 48 { 49 if (fVideoNode) { 50 BMediaRoster::Roster()->UnregisterNode(fVideoNode); 51 delete fVideoNode; 52 } 53 } 54 55 56 void 57 VideoView::AttachedToWindow() 58 { 59 } 60 61 62 VideoNode * 63 VideoView::Node() 64 { 65 return fVideoNode; 66 } 67 68 69 void 70 VideoView::OverlayLockAcquire() 71 { 72 printf("VideoView::OverlayLockAcquire\n"); 73 } 74 75 76 void 77 VideoView::OverlayLockRelease() 78 { 79 printf("VideoView::OverlayLockRelease\n"); 80 // overlaybitmap->UnlockBits 81 } 82 83 84 void 85 VideoView::OverlayScreenshotPrepare() 86 { 87 printf("OverlayScreenshotPrepare enter\n"); 88 /* 89 fVideoNode->LockBitmap(); 90 if (fOverlayActive) { 91 BBitmap *bmp = fVideoNode->Bitmap(); 92 if (bmp) { 93 // Window()->UpdateIfNeeded(); 94 // Sync(); 95 BBitmap *tmp = new BBitmap(bmp->Bounds(), 0, B_RGB32); 96 // ConvertBitmap(tmp, bmp); 97 ClearViewOverlay(); 98 DrawBitmap(tmp, Bounds()); 99 delete tmp; 100 // Sync(); 101 } 102 } 103 fVideoNode->UnlockBitmap(); 104 */ 105 printf("OverlayScreenshotPrepare leave\n"); 106 } 107 108 109 void 110 VideoView::OverlayScreenshotCleanup() 111 { 112 printf("OverlayScreenshotCleanup enter\n"); 113 /* 114 snooze(50000); // give app server some time to take the screenshot 115 fVideoNode->LockBitmap(); 116 if (fOverlayActive) { 117 BBitmap *bmp = fVideoNode->Bitmap(); 118 if (bmp) { 119 DrawBitmap(bmp, Bounds()); 120 SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor, 121 B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL); 122 Invalidate(); 123 } 124 } 125 fVideoNode->UnlockBitmap(); 126 */ 127 printf("OverlayScreenshotCleanup leave\n"); 128 } 129 130 131 void 132 VideoView::RemoveVideoDisplay() 133 { 134 printf("VideoView::RemoveVideoDisplay\n"); 135 136 if (fOverlayActive) { 137 ClearViewOverlay(); 138 fOverlayActive = false; 139 } 140 Invalidate(); 141 } 142 143 144 void 145 VideoView::RemoveOverlay() 146 { 147 printf("VideoView::RemoveOverlay\n"); 148 if (LockLooperWithTimeout(50000) == B_OK) { 149 ClearViewOverlay(); 150 fOverlayActive = false; 151 UnlockLooper(); 152 } 153 } 154 155 156 void 157 VideoView::Draw(BRect updateRect) 158 { 159 if (fOverlayActive) { 160 SetHighColor(fOverlayKeyColor); 161 FillRect(updateRect); 162 } else { 163 fVideoNode->LockBitmap(); 164 BBitmap *bmp = fVideoNode->Bitmap(); 165 if (bmp) 166 DrawBitmap(bmp, Bounds()); 167 fVideoNode->UnlockBitmap(); 168 } 169 } 170 171 172 void 173 VideoView::DrawFrame() 174 { 175 // printf("VideoView::DrawFrame\n"); 176 177 bool want_overlay = fVideoNode->IsOverlayActive(); 178 179 if (!want_overlay && fOverlayActive) { 180 if (LockLooperWithTimeout(50000) == B_OK) { 181 ClearViewOverlay(); 182 UnlockLooper(); 183 fOverlayActive = false; 184 } else { 185 printf("can't ClearViewOverlay, as LockLooperWithTimeout failed\n"); 186 } 187 } 188 if (want_overlay && !fOverlayActive) { 189 fVideoNode->LockBitmap(); 190 BBitmap *bmp = fVideoNode->Bitmap(); 191 if (bmp && LockLooperWithTimeout(50000) == B_OK) { 192 SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor, 193 B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL); 194 fOverlayActive = true; 195 196 Invalidate(); 197 UnlockLooper(); 198 } 199 fVideoNode->UnlockBitmap(); 200 } 201 if (!fOverlayActive) { 202 if (LockLooperWithTimeout(50000) != B_OK) 203 return; 204 Invalidate(); 205 UnlockLooper(); 206 } 207 } 208 209 210 void 211 VideoView::MessageReceived(BMessage *msg) 212 { 213 switch (msg->what) { 214 215 default: 216 BView::MessageReceived(msg); 217 } 218 } 219 220 221 bool 222 VideoView::IsOverlaySupported() 223 { 224 struct colorcombo { 225 color_space colspace; 226 const char *name; 227 } colspace[] = { 228 { B_RGB32, "B_RGB32"}, 229 { B_RGBA32, "B_RGBA32"}, 230 { B_RGB24, "B_RGB24"}, 231 { B_RGB16, "B_RGB16"}, 232 { B_RGB15, "B_RGB15"}, 233 { B_RGBA15, "B_RGBA15"}, 234 { B_RGB32_BIG, "B_RGB32_BIG"}, 235 { B_RGBA32_BIG, "B_RGBA32_BIG "}, 236 { B_RGB24_BIG, "B_RGB24_BIG "}, 237 { B_RGB16_BIG, "B_RGB16_BIG "}, 238 { B_RGB15_BIG, "B_RGB15_BIG "}, 239 { B_RGBA15_BIG, "B_RGBA15_BIG "}, 240 { B_YCbCr422, "B_YCbCr422"}, 241 { B_YCbCr411, "B_YCbCr411"}, 242 { B_YCbCr444, "B_YCbCr444"}, 243 { B_YCbCr420, "B_YCbCr420"}, 244 { B_YUV422, "B_YUV422"}, 245 { B_YUV411, "B_YUV411"}, 246 { B_YUV444, "B_YUV444"}, 247 { B_YUV420, "B_YUV420"}, 248 { B_NO_COLOR_SPACE, NULL} 249 }; 250 251 bool supported = false; 252 for (int i = 0; colspace[i].name; i++) { 253 BBitmap *test = new BBitmap(BRect(0,0,320,240), B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL, colspace[i].colspace); 254 if (test->InitCheck() == B_OK) { 255 printf("Display supports %s (0x%08x) overlay\n", colspace[i].name, colspace[i].colspace); 256 supported = true; 257 } 258 delete test; 259 // if (supported) 260 // break; 261 } 262 return supported; 263 } 264 265