Ticket #1051: 2006-01-16.uvc.mythphone.patch
File 2006-01-16.uvc.mythphone.patch, 28.6 KB (added by , 20 years ago) |
---|
-
webcam.h
19 19 #include <sys/types.h> 20 20 #include <sys/stat.h> 21 21 #include <fcntl.h> 22 #include "mjpeg.h" 22 23 23 24 #ifndef WIN32 24 25 #include <sys/ioctl.h> … … 30 31 #include <vfw.h> 31 32 #endif 32 33 33 34 #define RGB24_LEN(w,h) ((w) * (h) * 3)35 #define RGB32_LEN(w,h) ((w) * (h) * 4)36 #define YUV420P_LEN(w,h) (((w) * (h) * 3) / 2)37 #define YUV422P_LEN(w,h) ((w) * (h) * 2)38 39 34 // YUV --> RGB Conversion macros 40 35 #define _S(a) (a)>255 ? 255 : (a)<0 ? 0 : (a) 41 36 #define _R(y,u,v) (0x2568*(y) + 0x3343*(u)) /0x2000 … … 43 38 #define _B(y,u,v) (0x2568*(y) + 0x40cf*(v)) /0x2000 44 39 45 40 #ifdef WIN32 46 #define VIDEO_PALETTE_YUV420P 0 47 #define VIDEO_PALETTE_YUV422 1 48 #define VIDEO_PALETTE_YUV422P 2 49 #define VIDEO_PALETTE_RGB32 3 50 #define VIDEO_PALETTE_RGB24 4 51 #define VIDEO_PALETTE_GREY 5 41 #define V4L2_PIX_FMT_YVU420 0 42 #define V4L2_PIX_FMT_YUYV 1 43 #define V4L2_PIX_FMT_YUV422P 2 44 #define V4L2_PIX_FMT_BGR32 3 45 #define V4L2_PIX_FMT_BGR24 4 46 #define V4L2_PIX_FMT_GREY 5 47 #define V4L2_PIX_FMT_MJPEG 6 52 48 #endif 53 49 54 50 … … 56 52 #define WCHEIGHT bitmapInfo.bmiHeader.biHeight 57 53 #define WCWIDTH bitmapInfo.bmiHeader.biWidth 58 54 #else 59 #define WCWIDTH v Win.width60 #define WCHEIGHT v Win.height55 #define WCWIDTH vFormat.fmt.pix.width 56 #define WCHEIGHT vFormat.fmt.pix.height 61 57 #endif 62 58 63 59 64 60 #define WC_CLIENT_BUFFERS 2 61 #define WC_MMAP_BUFFERS 4 65 62 66 63 struct wcClient 67 64 { … … 117 114 int SetContrast(int v); 118 115 int SetColour(int v); 119 116 int SetHue(int v); 120 int GetBrightness(void) { return ( vPic.brightness);};121 int GetColour(void) { return ( vPic.colour);};122 int GetContrast(void) { return ( vPic.contrast);};123 int GetHue(void) { return ( vPic.hue);};124 QString GetName(void) { return vCaps.name; };117 int GetBrightness(void) { return (brightness.value);}; 118 int GetColour(void) { return (colour.value);}; 119 int GetContrast(void) { return (contrast.value);}; 120 int GetHue(void) { return (hue.value);}; 121 QString GetName(void) { return (char *) vCaps.card; }; 125 122 #else 126 123 HWND GetHwnd() { return hwndCap; }; 127 124 #endif … … 130 127 131 128 int SetTargetFps(wcClient *client, int fps); 132 129 int GetActualFps(); 133 void GetMaxSize(int *x, int *y);134 void GetMinSize(int *x, int *y);135 130 void GetCurSize(int *x, int *y); 136 131 int isGreyscale(void); 137 132 … … 147 142 void StartThread(); 148 143 void KillThread(); 149 144 void WebcamThreadWorker(); 145 void SetupMMAP(); 146 int ReadFrame(unsigned char *outbuf); 150 147 151 148 #ifdef WIN32 152 149 HWND hwndCap; … … 166 163 int hDev; 167 164 QString DevName; 168 165 unsigned char *picbuff1; 166 unsigned char *workbuff; 169 167 int imageLen; 170 168 int frameSize; 171 169 int fps; 172 170 int actualFps; 173 171 bool killWebcamThread; 174 int wcFormat;175 172 bool wcFlip; 176 173 177 174 QTime cameraTime; 178 175 int frameCount; 179 176 int totalCaptureMs; 180 177 178 MJPEGContainer *decoder; 179 181 180 // OS specific data structures 182 181 #ifdef WIN32 183 182 CAPTUREPARMS capParams; 184 183 BITMAPINFO bitmapInfo; 185 184 #else 186 struct video_capability vCaps; 187 struct video_window vWin; 188 struct video_picture vPic; 189 struct video_clip vClips; 185 struct v4l2_capability vCaps; 186 struct v4l2_format vFormat; 187 struct v4l2_control brightness; 188 struct v4l2_control contrast; 189 struct v4l2_control colour; 190 struct v4l2_control hue; 191 struct v4l2_clip vClips; 192 void *mmapBuf[WC_MMAP_BUFFERS]; 193 v4l2_buffer mmapBufDesc[WC_MMAP_BUFFERS]; 190 194 #endif 191 195 192 196 }; -
phoneui.cpp
140 140 camBrightness = webcam->GetBrightness(); 141 141 camContrast = webcam->GetContrast(); 142 142 camColour = webcam->GetColour(); 143 localClient = webcam->RegisterClient(V IDEO_PALETTE_RGB32, 20, this);143 localClient = webcam->RegisterClient(V4L2_PIX_FMT_BGR32, 20, this); 144 144 } 145 145 } 146 146 … … 545 545 if (h263->H263StartEncoder(txWidth, txHeight, txFps) && 546 546 h263->H263StartDecoder(rxWidth, rxHeight)) 547 547 { 548 txClient = webcam->RegisterClient(V IDEO_PALETTE_YUV420P, txFps, this);548 txClient = webcam->RegisterClient(V4L2_PIX_FMT_YVU420, txFps, this); 549 549 wcDeliveredFrames = 0; 550 550 wcDroppedFrames = 0; 551 551 VideoOn = true; -
mjpeg.h
1 /* 2 mjpeg.h 3 4 (c) 2006 Nick Kralevich 5 6 header for the mjpeg Container class 7 */ 8 9 #ifndef MJPEG_CONTAINER_H_ 10 #define MJPEG_CONTAINER_H_ 11 12 #ifndef WIN32 13 #include <mythtv/dialogbox.h> 14 #endif 15 16 17 extern "C" { 18 #ifdef WIN32 19 #include "libavcodec/avcodec.h" 20 #else 21 #include "mythtv/ffmpeg/avcodec.h" 22 #endif 23 } 24 25 26 class MJPEGContainer 27 { 28 public: 29 MJPEGContainer(void); 30 virtual ~MJPEGContainer(void); 31 32 bool MJPEGStartDecoder(int w, int h); 33 uchar *MJPEGDecodeFrame(const uchar *mjpegFrame, int mjpegFrameLen, uchar *outbuf, int outbufSize); 34 void MJPEGStopDecoder(); 35 int getPixFmt(); 36 37 private: 38 AVFrame *pictureIn; 39 AVCodec *mjpegDecoder; 40 AVCodecContext *mjpegDecContext; 41 }; 42 43 #endif -
webcam.cpp
3 3 4 4 (c) 2003 Paul Volkaerts 5 5 6 Modifications to support MJPEG, v4l2, and mmaped devices by Nick Kralevich 7 6 8 Webcam control and capture 7 9 */ 8 10 #include <qapplication.h> … … 20 22 #include <fcntl.h> 21 23 #include <linux/videodev.h> 22 24 #include <mythtv/mythcontext.h> 25 #include <sys/mman.h> 23 26 24 27 #include "config.h" 25 28 #else … … 40 43 { 41 44 hDev = 0; 42 45 DevName = ""; 43 picbuff1 = 0; 46 picbuff1 = NULL; 47 workbuff = NULL; 44 48 imageLen = 0; 45 49 frameSize = 0; 46 50 fps = 5; 47 51 killWebcamThread = true; // Leave true whilst its not running 48 wcFormat = 0;49 52 wcFlip = false; 53 decoder = NULL; 50 54 51 55 #ifndef WIN32 52 56 (void)parent; 53 57 (void)localVideoWidget; 54 vCaps.name[0] = 0; 55 vCaps.maxwidth = 0; 56 vCaps.maxheight = 0; 57 vCaps.minwidth = 0; 58 vCaps.minheight = 0; 59 memset(&vWin, 0, sizeof(struct video_window)); 60 vWin.width = 0; 61 vWin.height = 0; 62 vPic.brightness = 0; 63 vPic.depth = 0; 64 vPic.palette = 0; 65 vPic.colour = 0; 66 vPic.contrast = 0; 67 vPic.hue = 0; 58 memset(&vCaps, 0, sizeof(vCaps)); 68 59 60 memset(&vFormat, 0, sizeof(vFormat)); 61 vFormat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 62 vFormat.fmt.pix.width = 0; 63 vFormat.fmt.pix.height = 0; 64 vFormat.fmt.pix.pixelformat = 0; 65 vFormat.fmt.pix.field = V4L2_FIELD_ANY; 66 vFormat.fmt.pix.bytesperline = 0; 67 68 memset(&brightness, 0, sizeof(brightness)); 69 brightness.id = V4L2_CID_BRIGHTNESS; 70 brightness.value = 0; 71 72 memset(&colour, 0, sizeof(colour)); 73 colour.id = V4L2_CID_SATURATION; 74 colour.value = 0; 75 76 memset(&contrast, 0, sizeof(contrast)); 77 contrast.id = V4L2_CID_CONTRAST; 78 contrast.value = 0; 79 80 memset(&hue, 0, sizeof(hue)); 81 hue.id = V4L2_CID_HUE; 82 hue.value = 0; 83 84 for (int i = 0; i < WC_MMAP_BUFFERS; i++) { 85 mmapBuf[i] = NULL; 86 memset(&mmapBufDesc[i], 0, sizeof(mmapBufDesc[i])); 87 } 69 88 #else 70 89 wcMainWidget = parent; 71 90 hwndWebcam = localVideoWidget->winId(); … … 90 109 if (handle <= 0) 91 110 return ""; 92 111 93 struct v ideo_capability tempCaps;94 ioctl(handle, VIDIOC GCAP, &tempCaps);112 struct v4l2_capability tempCaps; 113 ioctl(handle, VIDIOC_QUERYCAP, &tempCaps); 95 114 ::close(handle); 96 return tempCaps.name;115 return ((char *) tempCaps.card); 97 116 #else 98 117 return "WIN32 Webcam (TODO)"; // TODO 99 118 #endif … … 132 151 { 133 152 readCaps(); 134 153 135 if (!SetPalette(VIDEO_PALETTE_YUV420P) && 136 !SetPalette(VIDEO_PALETTE_YUV422P) && 137 !SetPalette(VIDEO_PALETTE_RGB24)) 154 if (!SetPalette(V4L2_PIX_FMT_YUV420) && 155 !SetPalette(V4L2_PIX_FMT_YUV422P) && 156 !SetPalette(V4L2_PIX_FMT_BGR24) && 157 !SetPalette(V4L2_PIX_FMT_MJPEG)) 138 158 { 139 cout << "Webcam does not support YUV420P, YUV422P, or RGB24modes; these are the only ones currently supported. Closing webcam.\n";159 cout << "Webcam does not support YUV420P, YUV422P, RGB24, or MJPEG modes; these are the only ones currently supported. Closing webcam.\n"; 140 160 camClose(); 141 161 return false; 142 162 } … … 153 173 cout << "Could not set webcam to " << width << "x" << height << "; got " << actWidth << "x" << actHeight << " instead.\n"; 154 174 } 155 175 176 if (GetPalette() == V4L2_PIX_FMT_MJPEG) { 177 decoder = new MJPEGContainer; 178 decoder->MJPEGStartDecoder(WCWIDTH, WCHEIGHT); 179 } 180 156 181 //Allocate picture buffer memory 157 182 if (isGreyscale()) 158 183 { … … 165 190 { 166 191 switch (GetPalette()) 167 192 { 168 case VIDEO_PALETTE_RGB24: frameSize = RGB24_LEN(WCWIDTH, WCHEIGHT); break; 169 case VIDEO_PALETTE_RGB32: frameSize = RGB32_LEN(WCWIDTH, WCHEIGHT); break; 170 case VIDEO_PALETTE_YUV420P: frameSize = YUV420P_LEN(WCWIDTH, WCHEIGHT); break; 171 case VIDEO_PALETTE_YUV422P: frameSize = YUV422P_LEN(WCWIDTH, WCHEIGHT); break; 193 case V4L2_PIX_FMT_BGR24: 194 frameSize = avpicture_get_size(PIX_FMT_BGR24, WCWIDTH, WCHEIGHT); 195 break; 196 case V4L2_PIX_FMT_BGR32: 197 frameSize = avpicture_get_size(PIX_FMT_RGBA32, WCWIDTH, WCHEIGHT); 198 break; 199 case V4L2_PIX_FMT_YVU420: 200 frameSize = avpicture_get_size(PIX_FMT_YUV420P, WCWIDTH, WCHEIGHT); 201 break; 202 case V4L2_PIX_FMT_MJPEG: 203 frameSize = avpicture_get_size(PIX_FMT_YUV422P, WCWIDTH, WCHEIGHT); //FIXME 204 break; 205 case V4L2_PIX_FMT_YUV422P: 206 frameSize = avpicture_get_size(PIX_FMT_YUV422P, WCWIDTH, WCHEIGHT); 207 break; 172 208 default: 173 174 175 176 209 cerr << "Palette mode " << GetPalette() << " not yet supported" << endl; 210 camClose(); 211 return false; 212 break; 177 213 } 178 214 179 215 picbuff1 = new unsigned char [frameSize]; 216 workbuff = new unsigned char [frameSize]; 180 217 } 181 218 182 switch(GetPalette()) 183 { 184 case VIDEO_PALETTE_YUV420P: wcFormat = PIX_FMT_YUV420P; break; 185 case VIDEO_PALETTE_YUV422P: wcFormat = PIX_FMT_YUV422P; break; 186 case VIDEO_PALETTE_RGB24: wcFormat = PIX_FMT_BGR24; break; 187 case VIDEO_PALETTE_RGB32: wcFormat = PIX_FMT_RGBA32; break; 188 default: 189 cerr << "Webcam: Unsupported palette mode " << GetPalette() << endl; // Should not get here, caught earlier 190 camClose(); 191 return false; 192 break; 193 } 219 SetupMMAP(); 194 220 195 221 StartThread(); 196 222 } 197 223 return opened; 198 224 } 199 225 226 void Webcam::SetupMMAP() { 227 #ifndef WIN32 228 if ((vCaps.capabilities & V4L2_CAP_READWRITE) || 229 (!vCaps.capabilities & V4L2_CAP_STREAMING)) { 230 return; 231 } 200 232 233 struct v4l2_requestbuffers req; 234 memset(&req, 0, sizeof(req)); 235 req.count = WC_MMAP_BUFFERS; 236 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 237 req.memory = V4L2_MEMORY_MMAP; 238 if (ioctl(hDev, VIDIOC_REQBUFS, &req) != 0) { 239 cerr << "Webcam: VIDIOC_REQBUFS failed" << endl; 240 return; 241 } 242 for (int i = 0; i < WC_MMAP_BUFFERS; i++) { 243 mmapBufDesc[i].index = i; 244 mmapBufDesc[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 245 mmapBufDesc[i].memory = V4L2_MEMORY_MMAP; 246 if (ioctl(hDev, VIDIOC_QUERYBUF, &mmapBufDesc[i]) != 0) { 247 cerr << "Webcam: VIDIOC_QUERYBUF failed" << endl; 248 return; 249 } 250 mmapBuf[i] = mmap(0, /* start anywhere */ 251 mmapBufDesc[i].length, 252 PROT_READ, 253 MAP_SHARED, 254 hDev, 255 mmapBufDesc[i].m.offset); 256 if (mmapBuf[i] == MAP_FAILED) { 257 cerr << "Webcam: Unable to mmap buffers" << endl; 258 mmapBuf[i] = NULL; 259 return; 260 } 261 } 262 263 for (int i = 0; i < WC_MMAP_BUFFERS; i++) { 264 if (ioctl(hDev, VIDIOC_QBUF, &mmapBufDesc[i]) != 0) { 265 cerr << "Webcam: failed to initially queue buffers" << endl; 266 } 267 } 268 269 int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 270 if (ioctl(hDev, VIDIOC_STREAMON, &type) != 0) { 271 cerr << "Webcam: Unable to start streaming. ioctl(VIDIOC_STREAMON) failed" << endl; 272 } 273 #endif /* !WIN32 */ 274 } 275 276 201 277 void Webcam::camClose() 202 278 { 203 279 KillThread(); … … 212 288 ::close(hDev); 213 289 hDev = 0; 214 290 } 291 292 int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 293 if (ioctl(hDev, VIDIOC_STREAMOFF, &type) != 0) { 294 cerr << "Webcam: Unable to stop streaming. ioctl(VIDIOC_STREAMOFF) failed" << endl; 295 } 296 for(int i = 0; i < WC_MMAP_BUFFERS; i++) { 297 if (mmapBuf[i] != NULL) { 298 if (munmap(mmapBuf[i], mmapBufDesc[i].m.offset) != 0) { 299 cerr << "Webcam: munmap() " << i << " failed" << endl; 300 } 301 } 302 mmapBuf[i] = NULL; 303 memset(&mmapBufDesc[i], 0, sizeof(mmapBufDesc[i])); 304 } 215 305 #else 216 306 capCaptureStop(hwndCap); 217 307 capPreview(hwndCap, false); … … 220 310 if (picbuff1) 221 311 delete picbuff1; 222 312 223 picbuff1 = 0; 313 picbuff1 = NULL; 314 315 if (workbuff) 316 delete workbuff; 317 318 workbuff = NULL; 319 320 if (decoder) { 321 decoder->MJPEGStopDecoder(); 322 delete decoder; 323 } 324 decoder = NULL; 224 325 } 225 326 226 327 … … 261 362 #ifndef WIN32 262 363 if (hDev > 0) 263 364 { 264 ioctl(hDev, VIDIOCGCAP, &vCaps); 265 ioctl(hDev, VIDIOCGWIN, &vWin); 266 ioctl(hDev, VIDIOCGPICT, &vPic); 365 if (ioctl(hDev, VIDIOC_QUERYCAP, &vCaps) != 0) { 366 cerr << "Webcam: Error getting webcam capabilities" << endl; 367 } 368 if (ioctl(hDev, VIDIOC_G_FMT, &vFormat) != 0) { 369 cerr << "Webcam: Error getting webcam format" << endl; 370 } 267 371 } 268 372 #else 269 373 capCaptureGetSetup(hwndCap, &capParams, sizeof(capParams)); … … 276 380 { 277 381 // Note you can't call this whilst the webcam is open because all the buffers will be the wrong size 278 382 #ifndef WIN32 279 memset(&vWin, 0, sizeof(struct video_window)); 280 vWin.width = width; 281 vWin.height = height; 383 vFormat.fmt.pix.width = width; 384 vFormat.fmt.pix.height = height; 282 385 283 if (ioctl(hDev, VIDIOC SWIN, &vWin) == -1)284 386 if (ioctl(hDev, VIDIOC_S_FMT, &vFormat) != 0) 387 cerr << "Webcam: Error setting capture size " << width << "x" << height << endl; 285 388 #else 286 389 bitmapInfo.bmiHeader.biHeight = height; 287 390 bitmapInfo.bmiHeader.biWidth = width; … … 294 397 295 398 bool Webcam::SetPalette(unsigned int palette) 296 399 { 400 #ifndef WIN32 401 vFormat.fmt.pix.pixelformat = palette; 402 ioctl(hDev, VIDIOC_S_FMT, &vFormat); 403 #else 297 404 int depth; 298 405 299 406 switch(palette) 300 407 { 301 case V IDEO_PALETTE_YUV420P:depth = 12; break;302 case V IDEO_PALETTE_YUV422:depth = 16; break;303 case V IDEO_PALETTE_YUV422P: depth = 16; break;304 case V IDEO_PALETTE_RGB32: depth = 32; break;305 case V IDEO_PALETTE_RGB24: depth = 24; break;306 default: 408 case V4L2_PIX_FMT_YVU420: depth = 12; break; 409 case V4L2_PIX_FMT_YUYV: depth = 16; break; 410 case V4L2_PIX_FMT_YUV422P: depth = 16; break; 411 case V4L2_PIX_FMT_BGR32: depth = 32; break; 412 case V4L2_PIX_FMT_BGR24: depth = 24; break; 413 default: depth = 0; break; 307 414 } 308 415 309 #ifndef WIN32310 vPic.palette = palette;311 vPic.depth = depth;312 ioctl(hDev, VIDIOCSPICT, &vPic);313 #else314 416 int winPalette = 0; 315 417 switch(palette) 316 418 { 317 419 default: 318 case VIDEO_PALETTE_YUV420P: winPalette = (MAKEFOURCC('I', 'Y', 'U', 'V')); break; 319 case VIDEO_PALETTE_YUV422: winPalette = (MAKEFOURCC('U', 'Y', 'V', 'Y')); break; 320 case VIDEO_PALETTE_YUV422P: winPalette = (MAKEFOURCC('Y', 'V', '1', '6')); break; 321 case VIDEO_PALETTE_RGB32: winPalette = 0; break; 322 case VIDEO_PALETTE_RGB24: winPalette = 0; break; 420 case V4L2_PIX_FMT_YVU420: winPalette = (MAKEFOURCC('I', 'Y', 'U', 'V')); break; 421 case V4L2_PIX_FMT_YUYV: winPalette = (MAKEFOURCC('U', 'Y', 'V', 'Y')); break; 422 case V4L2_PIX_FMT_YUV422P: winPalette = (MAKEFOURCC('Y', 'V', '1', '6')); break; 423 case V4L2_PIX_FMT_BGR32: winPalette = 0; break; 424 case V4L2_PIX_FMT_BGR24: winPalette = 0; break; 425 case V4L2_PIX_FMT_MJPEG: winPalette = 0; break; 323 426 } 324 427 bitmapInfo.bmiHeader.biCompression = winPalette; 325 428 bitmapInfo.bmiHeader.biBitCount = depth; … … 329 432 readCaps(); 330 433 331 434 #ifndef WIN32 332 return (v Pic.palette== palette ? true : false);435 return (vFormat.fmt.pix.pixelformat == palette ? true : false); 333 436 #else 334 437 return ((bitmapInfo.bmiHeader.biCompression == winPalette) && (bitmapInfo.bmiHeader.biBitCount == depth) ? true : false); 335 438 #endif … … 339 442 unsigned int Webcam::GetPalette(void) 340 443 { 341 444 #ifndef WIN32 342 return (v Pic.palette);445 return (vFormat.fmt.pix.pixelformat); 343 446 #else 344 447 int winPalette = 0; 345 448 switch(bitmapInfo.bmiHeader.biCompression) 346 449 { 347 case MAKEFOURCC('I', 'Y', 'U', 'V'): return V IDEO_PALETTE_YUV420P;348 case MAKEFOURCC('U', 'Y', 'V', 'Y'): return V IDEO_PALETTE_YUV422;349 case MAKEFOURCC('Y', 'V', '1', '6'): return V IDEO_PALETTE_YUV422P;450 case MAKEFOURCC('I', 'Y', 'U', 'V'): return V4L2_PIX_FMT_YVU420; 451 case MAKEFOURCC('U', 'Y', 'V', 'Y'): return V4L2_PIX_FMT_YUYV; 452 case MAKEFOURCC('Y', 'V', '1', '6'): return V4L2_PIX_FMT_YUV422P; 350 453 default: 351 454 case 0: 352 455 if (bitmapInfo.bmiHeader.biBitCount == 24) 353 return V IDEO_PALETTE_RGB24;456 return V4L2_PIX_FMT_BGR24; 354 457 else if (bitmapInfo.bmiHeader.biBitCount == 32) 355 return V IDEO_PALETTE_RGB32;458 return V4L2_PIX_FMT_BGR32; 356 459 } 357 460 return 0; 358 461 #endif … … 367 470 { 368 471 if (hDev > 0) 369 472 { 370 vPic.brightness = v; 473 brightness.id = V4L2_CID_BRIGHTNESS; 474 brightness.value = v; 371 475 372 if (ioctl(hDev, VIDIOC SPICT, &vPic) == -1)476 if (ioctl(hDev, VIDIOC_S_CTRL, &brightness) == -1) 373 477 cerr << "Error setting brightness" << endl; 374 478 375 479 readCaps(); … … 377 481 } 378 482 else 379 483 cerr << "Invalid Brightness parameter" << endl; 380 return vPic.brightness;484 return brightness.value; 381 485 } 382 486 383 487 int Webcam::SetContrast(int v) … … 386 490 { 387 491 if (hDev > 0) 388 492 { 389 vPic.contrast = v ; 493 contrast.id = V4L2_CID_CONTRAST; 494 contrast.value = v ; 390 495 391 if (ioctl(hDev, VIDIOC SPICT, &vPic) == -1)496 if (ioctl(hDev, VIDIOC_S_CTRL, &contrast) == -1) 392 497 cerr << "Error setting contrast" << endl; 393 498 394 499 readCaps(); … … 396 501 } 397 502 else 398 503 cerr << "Invalid contrast parameter" << endl; 399 return vPic.contrast;504 return contrast.value; 400 505 } 401 506 402 507 … … 406 511 { 407 512 if (hDev > 0) 408 513 { 409 vPic.colour = v; 514 colour.id = V4L2_CID_SATURATION; 515 colour.value = v; 410 516 411 if (ioctl(hDev, VIDIOC SPICT, &vPic) == -1)517 if (ioctl(hDev, VIDIOC_S_CTRL, &colour) == -1) 412 518 cerr << "Error setting colour" << endl; 413 519 414 520 readCaps(); … … 416 522 } 417 523 else 418 524 cerr << "Invalid colour parameter" << endl; 419 return vPic.colour;525 return colour.value; 420 526 } 421 527 422 528 … … 426 532 { 427 533 if (hDev > 0) 428 534 { 429 vPic.hue = v; 535 hue.id = V4L2_CID_HUE; 536 hue.value = v; 430 537 431 if (ioctl(hDev, VIDIOC SPICT, &vPic) == -1)538 if (ioctl(hDev, VIDIOC_S_CTRL, &hue) == -1) 432 539 cerr << "Error setting hue" << endl; 433 540 434 541 readCaps(); … … 436 543 } 437 544 else 438 545 cerr << "Invalid hue parameter" << endl; 439 return vPic.hue;546 return hue.value; 440 547 } 441 548 442 549 #endif … … 463 570 return actualFps; 464 571 } 465 572 466 void Webcam::GetMaxSize(int *x, int *y)467 {468 #ifdef WIN32469 *y=bitmapInfo.bmiHeader.biHeight; *x=bitmapInfo.bmiHeader.biWidth;470 #else471 *y=vCaps.maxheight; *x=vCaps.maxwidth;472 #endif473 };474 475 void Webcam::GetMinSize(int *x, int *y)476 {477 #ifdef WIN32478 *y=bitmapInfo.bmiHeader.biHeight; *x=bitmapInfo.bmiHeader.biWidth;479 #else480 *y=vCaps.minheight; *x=vCaps.minwidth;481 #endif482 };483 484 573 void Webcam::GetCurSize(int *x, int *y) 485 574 { 486 575 *y = WCHEIGHT; … … 492 581 #ifdef WIN32 493 582 return false; 494 583 #else 495 return ((vCaps.type & VID_TYPE_MONOCHROME) ? true : false); 584 struct v4l2_fmtdesc fmt; 585 int i = 0; 586 int greyonly = true; 587 while (1) { 588 memset(&fmt, 0, sizeof(fmt)); 589 fmt.index = i; 590 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 591 if (ioctl(hDev, VIDIOC_ENUM_FMT, (void *) &fmt) != 0) { 592 return greyonly; 593 } 594 if (fmt.pixelformat != V4L2_PIX_FMT_GREY) { 595 greyonly = false; 596 } 597 i++; 598 } 599 /* never reached */ 600 return false; 496 601 #endif 497 602 }; 498 603 … … 517 622 518 623 switch (format) 519 624 { 520 case VIDEO_PALETTE_RGB24: client->frameSize = RGB24_LEN(WCWIDTH, WCHEIGHT); client->format = PIX_FMT_BGR24; break; 521 case VIDEO_PALETTE_RGB32: client->frameSize = RGB32_LEN(WCWIDTH, WCHEIGHT); client->format = PIX_FMT_RGBA32; break; 522 case VIDEO_PALETTE_YUV420P: client->frameSize = YUV420P_LEN(WCWIDTH, WCHEIGHT); client->format = PIX_FMT_YUV420P; break; 523 case VIDEO_PALETTE_YUV422P: client->frameSize = YUV422P_LEN(WCWIDTH, WCHEIGHT); client->format = PIX_FMT_YUV422P; break; 625 case V4L2_PIX_FMT_BGR24: 626 client->format = PIX_FMT_BGR24; 627 break; 628 case V4L2_PIX_FMT_BGR32: 629 client->format = PIX_FMT_RGBA32; 630 break; 631 case V4L2_PIX_FMT_YVU420: 632 client->format = PIX_FMT_YUV420P; 633 break; 634 case V4L2_PIX_FMT_YUV422P: 635 client->format = PIX_FMT_YUV422P; 636 break; 524 637 default: 525 638 cerr << "SIP: Attempt to register unsupported Webcam format\n"; 526 639 delete client; 527 640 return 0; 528 641 } 642 client->frameSize = avpicture_get_size(client->format, WCWIDTH, WCHEIGHT); 529 643 530 644 // Create some buffers for the client 531 645 for (int i=0; i<WC_CLIENT_BUFFERS; i++) … … 630 744 WebcamThreadWorker(); 631 745 } 632 746 747 int Webcam::ReadFrame(unsigned char *outbuf) { 748 #ifndef WIN32 749 int len; 750 if ((!(vCaps.capabilities & V4L2_CAP_READWRITE)) && 751 (!(vCaps.capabilities & V4L2_CAP_STREAMING))) { 752 cerr << "webcam: no supported mechanisms for reading image data" << endl; 753 return -1; 754 } 755 756 memset(outbuf, 0, frameSize); 757 758 if (vCaps.capabilities & V4L2_CAP_READWRITE) { 759 len = read(hDev, outbuf, frameSize); 760 return len; 761 } 762 763 if (vCaps.capabilities & V4L2_CAP_STREAMING) { 764 v4l2_buffer readBuf; 765 memset(&readBuf, 0, sizeof(readBuf)); 766 readBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 767 readBuf.memory = V4L2_MEMORY_MMAP; 768 if (ioctl(hDev, VIDIOC_DQBUF, &readBuf) != 0) { 769 cerr << "Webcam: Unable to fetch streaming buffer" << endl; 770 return -1; 771 } 772 len = readBuf.bytesused; 773 if (len > frameSize) { 774 cerr << "Webcam: outbuf not big enough" << endl; 775 return -1; 776 } 777 memcpy(outbuf, mmapBuf[readBuf.index], len); 778 if (ioctl(hDev, VIDIOC_QBUF, &readBuf) != 0) { 779 cerr << "Webcam: Unable to requeue buffer" << endl; 780 } 781 return len; 782 } 783 784 #endif /* !WIN32 */ 785 return -1; 786 } 787 633 788 void Webcam::WebcamThreadWorker() 634 789 { 635 790 #ifndef WIN32 … … 637 792 638 793 while((!killWebcamThread) && (hDev > 0)) 639 794 { 640 if ((len = read(hDev, picbuff1, frameSize)) == frameSize) 641 { 642 if (killWebcamThread) 643 break; 644 645 ProcessFrame(picbuff1, frameSize); 646 } 647 else 648 cerr << "Error reading from webcam; got " << len << " bytes; expected " << frameSize << endl; 795 int len = ReadFrame(workbuff); 796 797 /* 798 * See if any special handling (decompression) is required 799 * for this frame 800 */ 801 if (GetPalette() == V4L2_PIX_FMT_MJPEG) { 802 if (!decoder->MJPEGDecodeFrame(workbuff, len, picbuff1, frameSize)) { 803 cerr << "Unable to decode MJPEG frame" << endl; 804 len = -1; 805 } else { 806 len = frameSize; 807 } 808 } else { 809 memcpy(picbuff1, workbuff, frameSize); 810 } 811 812 if (len == frameSize) { 813 if (killWebcamThread) 814 break; 815 816 ProcessFrame(picbuff1, frameSize); 817 } 818 else 819 cerr << "Error reading from webcam; got " << len << " bytes; expected " << frameSize << endl; 649 820 } 650 821 #endif 651 822 } … … 663 834 if (totalCaptureMs != 0) 664 835 actualFps = (frameCount*1000)/totalCaptureMs; 665 836 837 int wcFormat = PIX_FMT_NONE; 838 switch(GetPalette()) 839 { 840 case V4L2_PIX_FMT_YVU420: wcFormat = PIX_FMT_YUV420P; break; 841 case V4L2_PIX_FMT_MJPEG: wcFormat = decoder->getPixFmt(); break; 842 case V4L2_PIX_FMT_YUV422P: wcFormat = PIX_FMT_YUV422P; break; 843 case V4L2_PIX_FMT_BGR24: wcFormat = PIX_FMT_BGR24; break; 844 case V4L2_PIX_FMT_BGR32: wcFormat = PIX_FMT_RGBA32; break; 845 default: 846 cerr << "Webcam: Unsupported palette mode " << GetPalette() << endl; 847 } 848 666 849 // Check if the webcam needs flipped (some webcams deliver pics upside down) 667 if (wcFlip )850 if (wcFlip && wcFormat != PIX_FMT_NONE) 668 851 { 669 852 switch(wcFormat) 670 853 { -
mjpeg.cpp
1 /* 2 mjpeg.cpp 3 4 (c) 2006 Nick Kralevich 5 6 Container class for the mjpeg Video Codec, which just interfaces to the libavcodec routines 7 8 TODO:- 9 These are non reentrant so need a mutex implemented, if they are to be used elsewhere in the Myth frontend 10 */ 11 12 #include <iostream> 13 using namespace std; 14 15 #ifndef WIN32 16 #include "config.h" 17 #endif 18 19 #include "mjpeg.h" 20 21 MJPEGContainer::MJPEGContainer() 22 { 23 mjpegDecoder = NULL; 24 mjpegDecContext = NULL; 25 pictureIn = NULL; 26 27 avcodec_init(); 28 avcodec_register_all(); 29 } 30 31 MJPEGContainer::~MJPEGContainer() 32 { 33 } 34 35 bool MJPEGContainer::MJPEGStartDecoder(int w, int h) 36 { 37 mjpegDecoder = avcodec_find_decoder(CODEC_ID_MJPEG); 38 if (!mjpegDecoder) 39 { 40 cerr << "Could not find MJPEG decoder\n"; 41 return false; 42 } 43 44 mjpegDecContext = avcodec_alloc_context(); 45 pictureIn = avcodec_alloc_frame(); 46 47 mjpegDecContext->codec_id = CODEC_ID_MJPEG; 48 mjpegDecContext->width = w; 49 mjpegDecContext->height = h; 50 51 /* open it */ 52 if (avcodec_open(mjpegDecContext, mjpegDecoder) < 0) 53 { 54 cerr << "Could not open MJPEG Decoder\n"; 55 return false; 56 } 57 58 return true; 59 } 60 61 int MJPEGContainer::getPixFmt() { 62 return mjpegDecContext->pix_fmt; 63 } 64 65 uchar *MJPEGContainer::MJPEGDecodeFrame(const uchar *mjpegFrame, int mjpegFrameLen, uchar *outbuf, int outbufSize) 66 { 67 int got_picture; 68 69 memset(outbuf, 0, outbufSize); 70 71 int len = avcodec_decode_video(mjpegDecContext, 72 pictureIn, 73 &got_picture, 74 (uint8_t *) mjpegFrame, 75 mjpegFrameLen); 76 77 if (!got_picture) { 78 cerr << "Webcam: expected picture but didn't get it..." << endl; 79 return NULL; 80 } 81 82 // int wrap = pictureIn->linesize[0]; 83 int xsize = mjpegDecContext->width; 84 int ysize = mjpegDecContext->height; 85 int pic_size = avpicture_get_size(mjpegDecContext->pix_fmt, xsize, ysize); 86 if (pic_size != outbufSize) { 87 cerr << "outbuf size mismatch. pic_size: " << pic_size << " bufsize: " << outbufSize << endl; 88 return NULL; 89 } 90 91 int size = avpicture_layout((AVPicture *)pictureIn, 92 mjpegDecContext->pix_fmt, 93 xsize, 94 ysize, 95 outbuf, 96 outbufSize); 97 if (size != outbufSize) { 98 cerr << "webcam: avpicture_layout error: " << size << endl; 99 return NULL; 100 } 101 return outbuf; 102 } 103 104 void MJPEGContainer::MJPEGStopDecoder() 105 { 106 int got_picture; 107 108 // See if there is a last frame 109 avcodec_decode_video(mjpegDecContext, pictureIn, &got_picture, NULL, 0); 110 111 if (mjpegDecContext) 112 { 113 avcodec_close(mjpegDecContext); 114 av_free(mjpegDecContext); 115 mjpegDecContext = 0; 116 } 117 118 if (pictureIn) 119 av_free(pictureIn); 120 pictureIn = 0; 121 } -
h263.cpp
15 15 using namespace std; 16 16 17 17 #ifndef WIN32 18 #include <linux/videodev.h>19 18 #include "config.h" 20 19 #endif 21 20