1 /* 2 * Copyright (C) 2006 Marcus Overhagen <marcus@overhagen.de>. All rights reserved. 3 * 4 * Distributed under the terms of the MIT License. 5 */ 6 #include "VideoNode.h" 7 #include "VideoView.h" 8 #include "debug.h" 9 10 #include <Bitmap.h> 11 #include <Locker.h> 12 #include <MediaRoster.h> 13 #include <Message.h> 14 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 20 21 VideoView::VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags, VideoNode *node) 22 : BView(frame, name, resizeMask, flags) 23 , fVideoNode(node) 24 , fOverlayActive(false) 25 { 26 SetViewColor(B_TRANSPARENT_COLOR); 27 } 28 29 30 VideoView::~VideoView() 31 { 32 } 33 34 35 void 36 VideoView::AttachedToWindow() 37 { 38 } 39 40 41 VideoNode * 42 VideoView::Node() 43 { 44 return fVideoNode; 45 } 46 47 48 void 49 VideoView::OverlayLockAcquire() 50 { 51 CALLED(); 52 } 53 54 55 void 56 VideoView::OverlayLockRelease() 57 { 58 CALLED(); 59 // overlaybitmap->UnlockBits 60 } 61 62 63 void 64 VideoView::OverlayScreenshotPrepare() 65 { 66 CALLED(); 67 /* 68 fVideoNode->LockBitmap(); 69 if (fOverlayActive) { 70 BBitmap *bmp = fVideoNode->Bitmap(); 71 if (bmp) { 72 // Window()->UpdateIfNeeded(); 73 // Sync(); 74 BBitmap *tmp = new BBitmap(bmp->Bounds(), 0, B_RGB32); 75 // ConvertBitmap(tmp, bmp); 76 ClearViewOverlay(); 77 DrawBitmap(tmp, Bounds()); 78 delete tmp; 79 // Sync(); 80 } 81 } 82 fVideoNode->UnlockBitmap(); 83 */ 84 } 85 86 87 void 88 VideoView::OverlayScreenshotCleanup() 89 { 90 CALLED(); 91 /* 92 snooze(50000); // give app server some time to take the screenshot 93 fVideoNode->LockBitmap(); 94 if (fOverlayActive) { 95 BBitmap *bmp = fVideoNode->Bitmap(); 96 if (bmp) { 97 DrawBitmap(bmp, Bounds()); 98 SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor, 99 B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL); 100 Invalidate(); 101 } 102 } 103 fVideoNode->UnlockBitmap(); 104 */ 105 } 106 107 108 void 109 VideoView::RemoveVideoDisplay() 110 { 111 CALLED(); 112 113 if (fOverlayActive) { 114 ClearViewOverlay(); 115 fOverlayActive = false; 116 } 117 Invalidate(); 118 } 119 120 121 void 122 VideoView::RemoveOverlay() 123 { 124 CALLED(); 125 if (LockLooperWithTimeout(50000) == B_OK) { 126 ClearViewOverlay(); 127 fOverlayActive = false; 128 UnlockLooper(); 129 } 130 } 131 132 133 void 134 VideoView::Draw(BRect updateRect) 135 { 136 if (fOverlayActive) { 137 SetHighColor(fOverlayKeyColor); 138 FillRect(updateRect); 139 } else { 140 fVideoNode->LockBitmap(); 141 BBitmap *bmp = fVideoNode->Bitmap(); 142 if (!bmp) { 143 SetHighColor(0, 0, 0, 0); 144 FillRect(updateRect); 145 } else 146 DrawBitmap(bmp, Bounds()); 147 fVideoNode->UnlockBitmap(); 148 } 149 } 150 151 152 void 153 VideoView::DrawFrame() 154 { 155 //CALLED(); 156 157 bool want_overlay = fVideoNode->IsOverlayActive(); 158 159 if (!want_overlay && fOverlayActive) { 160 if (LockLooperWithTimeout(50000) == B_OK) { 161 ClearViewOverlay(); 162 UnlockLooper(); 163 fOverlayActive = false; 164 } else { 165 fprintf(stderr, "VideoView::DrawFrame: cannot ClearViewOverlay, as LockLooperWithTimeout failed\n"); 166 } 167 } 168 169 if (want_overlay && !fOverlayActive) { 170 fVideoNode->LockBitmap(); 171 BBitmap *bmp = fVideoNode->Bitmap(); 172 if (bmp && LockLooperWithTimeout(50000) == B_OK) { 173 SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor, 174 B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL); 175 fOverlayActive = true; 176 177 Invalidate(); 178 UnlockLooper(); 179 } 180 fVideoNode->UnlockBitmap(); 181 } 182 if (!fOverlayActive) { 183 if (LockLooperWithTimeout(50000) != B_OK) 184 return; 185 Invalidate(); 186 UnlockLooper(); 187 } 188 } 189 190 191 void 192 VideoView::MessageReceived(BMessage *msg) 193 { 194 switch (msg->what) { 195 196 default: 197 BView::MessageReceived(msg); 198 } 199 } 200 201 202 bool 203 VideoView::IsOverlaySupported() 204 { 205 struct colorcombo { 206 color_space colspace; 207 const char *name; 208 } colspace[] = { 209 { B_RGB32, "B_RGB32"}, 210 { B_RGBA32, "B_RGBA32"}, 211 { B_RGB24, "B_RGB24"}, 212 { B_RGB16, "B_RGB16"}, 213 { B_RGB15, "B_RGB15"}, 214 { B_RGBA15, "B_RGBA15"}, 215 { B_RGB32_BIG, "B_RGB32_BIG"}, 216 { B_RGBA32_BIG, "B_RGBA32_BIG "}, 217 { B_RGB24_BIG, "B_RGB24_BIG "}, 218 { B_RGB16_BIG, "B_RGB16_BIG "}, 219 { B_RGB15_BIG, "B_RGB15_BIG "}, 220 { B_RGBA15_BIG, "B_RGBA15_BIG "}, 221 { B_YCbCr422, "B_YCbCr422"}, 222 { B_YCbCr411, "B_YCbCr411"}, 223 { B_YCbCr444, "B_YCbCr444"}, 224 { B_YCbCr420, "B_YCbCr420"}, 225 { B_YUV422, "B_YUV422"}, 226 { B_YUV411, "B_YUV411"}, 227 { B_YUV444, "B_YUV444"}, 228 { B_YUV420, "B_YUV420"}, 229 { B_NO_COLOR_SPACE, NULL} 230 }; 231 232 bool supported = false; 233 for (int i = 0; colspace[i].name; i++) { 234 BBitmap *test = new BBitmap(BRect(0,0,320,240), B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL, colspace[i].colspace); 235 if (test->InitCheck() == B_OK) { 236 printf("Display supports %s (0x%08x) overlay\n", colspace[i].name, colspace[i].colspace); 237 supported = true; 238 } 239 delete test; 240 // if (supported) 241 // break; 242 } 243 return supported; 244 } 245