Ticket #1051: 2006-01-22.uvc.mythphone.patch
File 2006-01-22.uvc.mythphone.patch, 30.8 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 void ShutdownMMAP(); 147 int ReadFrame(unsigned char *outbuf); 150 148 151 149 #ifdef WIN32 152 150 HWND hwndCap; … … 166 164 int hDev; 167 165 QString DevName; 168 166 unsigned char *picbuff1; 167 unsigned char *workbuff; 169 168 int imageLen; 170 169 int frameSize; 171 170 int fps; 172 171 int actualFps; 173 172 bool killWebcamThread; 174 int wcFormat;175 173 bool wcFlip; 176 174 177 175 QTime cameraTime; 178 176 int frameCount; 179 177 int totalCaptureMs; 180 178 179 MJPEGContainer *decoder; 180 181 181 // OS specific data structures 182 182 #ifdef WIN32 183 183 CAPTUREPARMS capParams; 184 184 BITMAPINFO bitmapInfo; 185 185 #else 186 struct video_capability vCaps; 187 struct video_window vWin; 188 struct video_picture vPic; 189 struct video_clip vClips; 186 struct v4l2_capability vCaps; 187 struct v4l2_format vFormat; 188 struct v4l2_control brightness; 189 struct v4l2_control contrast; 190 struct v4l2_control colour; 191 struct v4l2_control hue; 192 struct v4l2_clip vClips; 193 void *mmapBuf[WC_MMAP_BUFFERS]; 194 v4l2_buffer mmapBufDesc[WC_MMAP_BUFFERS]; 190 195 #endif 191 196 192 197 }; -
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 void Webcam::ShutdownMMAP() { 277 #ifndef WIN32 278 if ((vCaps.capabilities & V4L2_CAP_READWRITE) || 279 (!vCaps.capabilities & V4L2_CAP_STREAMING)) { 280 return; 281 } 282 283 int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 284 if (ioctl(hDev, VIDIOC_STREAMOFF, &type) != 0) { 285 cerr << "Webcam: Unable to stop streaming. ioctl(VIDIOC_STREAMOFF) failed" << endl; 286 } 287 for (int i = 0; i < WC_MMAP_BUFFERS; i++) { 288 if (mmapBuf[i] != NULL) { 289 if (munmap(mmapBuf[i], mmapBufDesc[i].length) != 0) { 290 cerr << "Webcam: munmap() " << i << " failed" << endl; 291 } 292 } 293 mmapBuf[i] = NULL; 294 memset(&mmapBufDesc[i], 0, sizeof(mmapBufDesc[i])); 295 } 296 #endif /* !WIN32 */ 297 } 298 201 299 void Webcam::camClose() 202 300 { 203 301 KillThread(); 204 302 205 303 #ifndef WIN32 304 305 ShutdownMMAP(); 206 306 if (hDev <= 0) 207 307 cerr << "Can't close a camera that isn't open" << endl; 208 308 else 209 309 { 210 310 // There must be a widget procedure called close so make 211 311 // sure we call the proper one. Screwed me up for ages! 212 ::close(hDev); 213 hDev = 0; 312 if (::close(hDev) != 0) { 313 cerr << "Unable to close webcam" << endl; 314 } 315 hDev = 0; 214 316 } 317 215 318 #else 216 319 capCaptureStop(hwndCap); 217 320 capPreview(hwndCap, false); … … 219 322 220 323 if (picbuff1) 221 324 delete picbuff1; 325 picbuff1 = NULL; 222 326 223 picbuff1 = 0; 327 if (workbuff) 328 delete workbuff; 329 workbuff = NULL; 330 331 if (decoder) { 332 decoder->MJPEGStopDecoder(); 333 delete decoder; 334 } 335 decoder = NULL; 224 336 } 225 337 226 338 … … 261 373 #ifndef WIN32 262 374 if (hDev > 0) 263 375 { 264 ioctl(hDev, VIDIOCGCAP, &vCaps); 265 ioctl(hDev, VIDIOCGWIN, &vWin); 266 ioctl(hDev, VIDIOCGPICT, &vPic); 376 if (ioctl(hDev, VIDIOC_QUERYCAP, &vCaps) != 0) { 377 cerr << "Webcam: Error getting webcam capabilities" << endl; 378 } 379 if (ioctl(hDev, VIDIOC_G_FMT, &vFormat) != 0) { 380 cerr << "Webcam: Error getting webcam format" << endl; 381 } 267 382 } 268 383 #else 269 384 capCaptureGetSetup(hwndCap, &capParams, sizeof(capParams)); … … 276 391 { 277 392 // Note you can't call this whilst the webcam is open because all the buffers will be the wrong size 278 393 #ifndef WIN32 279 memset(&vWin, 0, sizeof(struct video_window)); 280 vWin.width = width; 281 vWin.height = height; 394 vFormat.fmt.pix.width = width; 395 vFormat.fmt.pix.height = height; 282 396 283 if (ioctl(hDev, VIDIOC SWIN, &vWin) == -1)284 397 if (ioctl(hDev, VIDIOC_S_FMT, &vFormat) != 0) 398 cerr << "Webcam: Error setting capture size " << width << "x" << height << endl; 285 399 #else 286 400 bitmapInfo.bmiHeader.biHeight = height; 287 401 bitmapInfo.bmiHeader.biWidth = width; … … 294 408 295 409 bool Webcam::SetPalette(unsigned int palette) 296 410 { 411 #ifndef WIN32 412 vFormat.fmt.pix.pixelformat = palette; 413 ioctl(hDev, VIDIOC_S_FMT, &vFormat); 414 #else 297 415 int depth; 298 416 299 417 switch(palette) 300 418 { 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: 419 case V4L2_PIX_FMT_YVU420: depth = 12; break; 420 case V4L2_PIX_FMT_YUYV: depth = 16; break; 421 case V4L2_PIX_FMT_YUV422P: depth = 16; break; 422 case V4L2_PIX_FMT_BGR32: depth = 32; break; 423 case V4L2_PIX_FMT_BGR24: depth = 24; break; 424 default: depth = 0; break; 307 425 } 308 426 309 #ifndef WIN32310 vPic.palette = palette;311 vPic.depth = depth;312 ioctl(hDev, VIDIOCSPICT, &vPic);313 #else314 427 int winPalette = 0; 315 428 switch(palette) 316 429 { 317 430 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; 431 case V4L2_PIX_FMT_YVU420: winPalette = (MAKEFOURCC('I', 'Y', 'U', 'V')); break; 432 case V4L2_PIX_FMT_YUYV: winPalette = (MAKEFOURCC('U', 'Y', 'V', 'Y')); break; 433 case V4L2_PIX_FMT_YUV422P: winPalette = (MAKEFOURCC('Y', 'V', '1', '6')); break; 434 case V4L2_PIX_FMT_BGR32: winPalette = 0; break; 435 case V4L2_PIX_FMT_BGR24: winPalette = 0; break; 436 case V4L2_PIX_FMT_MJPEG: winPalette = 0; break; 323 437 } 324 438 bitmapInfo.bmiHeader.biCompression = winPalette; 325 439 bitmapInfo.bmiHeader.biBitCount = depth; … … 329 443 readCaps(); 330 444 331 445 #ifndef WIN32 332 return (v Pic.palette== palette ? true : false);446 return (vFormat.fmt.pix.pixelformat == palette ? true : false); 333 447 #else 334 448 return ((bitmapInfo.bmiHeader.biCompression == winPalette) && (bitmapInfo.bmiHeader.biBitCount == depth) ? true : false); 335 449 #endif … … 339 453 unsigned int Webcam::GetPalette(void) 340 454 { 341 455 #ifndef WIN32 342 return (v Pic.palette);456 return (vFormat.fmt.pix.pixelformat); 343 457 #else 344 458 int winPalette = 0; 345 459 switch(bitmapInfo.bmiHeader.biCompression) 346 460 { 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;461 case MAKEFOURCC('I', 'Y', 'U', 'V'): return V4L2_PIX_FMT_YVU420; 462 case MAKEFOURCC('U', 'Y', 'V', 'Y'): return V4L2_PIX_FMT_YUYV; 463 case MAKEFOURCC('Y', 'V', '1', '6'): return V4L2_PIX_FMT_YUV422P; 350 464 default: 351 465 case 0: 352 466 if (bitmapInfo.bmiHeader.biBitCount == 24) 353 return V IDEO_PALETTE_RGB24;467 return V4L2_PIX_FMT_BGR24; 354 468 else if (bitmapInfo.bmiHeader.biBitCount == 32) 355 return V IDEO_PALETTE_RGB32;469 return V4L2_PIX_FMT_BGR32; 356 470 } 357 471 return 0; 358 472 #endif … … 367 481 { 368 482 if (hDev > 0) 369 483 { 370 vPic.brightness = v; 484 brightness.id = V4L2_CID_BRIGHTNESS; 485 brightness.value = v; 371 486 372 if (ioctl(hDev, VIDIOC SPICT, &vPic) == -1)487 if (ioctl(hDev, VIDIOC_S_CTRL, &brightness) == -1) 373 488 cerr << "Error setting brightness" << endl; 374 489 375 490 readCaps(); … … 377 492 } 378 493 else 379 494 cerr << "Invalid Brightness parameter" << endl; 380 return vPic.brightness;495 return brightness.value; 381 496 } 382 497 383 498 int Webcam::SetContrast(int v) … … 386 501 { 387 502 if (hDev > 0) 388 503 { 389 vPic.contrast = v ; 504 contrast.id = V4L2_CID_CONTRAST; 505 contrast.value = v ; 390 506 391 if (ioctl(hDev, VIDIOC SPICT, &vPic) == -1)507 if (ioctl(hDev, VIDIOC_S_CTRL, &contrast) == -1) 392 508 cerr << "Error setting contrast" << endl; 393 509 394 510 readCaps(); … … 396 512 } 397 513 else 398 514 cerr << "Invalid contrast parameter" << endl; 399 return vPic.contrast;515 return contrast.value; 400 516 } 401 517 402 518 … … 406 522 { 407 523 if (hDev > 0) 408 524 { 409 vPic.colour = v; 525 colour.id = V4L2_CID_SATURATION; 526 colour.value = v; 410 527 411 if (ioctl(hDev, VIDIOC SPICT, &vPic) == -1)528 if (ioctl(hDev, VIDIOC_S_CTRL, &colour) == -1) 412 529 cerr << "Error setting colour" << endl; 413 530 414 531 readCaps(); … … 416 533 } 417 534 else 418 535 cerr << "Invalid colour parameter" << endl; 419 return vPic.colour;536 return colour.value; 420 537 } 421 538 422 539 … … 426 543 { 427 544 if (hDev > 0) 428 545 { 429 vPic.hue = v; 546 hue.id = V4L2_CID_HUE; 547 hue.value = v; 430 548 431 if (ioctl(hDev, VIDIOC SPICT, &vPic) == -1)549 if (ioctl(hDev, VIDIOC_S_CTRL, &hue) == -1) 432 550 cerr << "Error setting hue" << endl; 433 551 434 552 readCaps(); … … 436 554 } 437 555 else 438 556 cerr << "Invalid hue parameter" << endl; 439 return vPic.hue;557 return hue.value; 440 558 } 441 559 442 560 #endif … … 463 581 return actualFps; 464 582 } 465 583 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 584 void Webcam::GetCurSize(int *x, int *y) 485 585 { 486 586 *y = WCHEIGHT; … … 492 592 #ifdef WIN32 493 593 return false; 494 594 #else 495 return ((vCaps.type & VID_TYPE_MONOCHROME) ? true : false); 595 struct v4l2_fmtdesc fmt; 596 int i = 0; 597 int greyonly = true; 598 while (1) { 599 memset(&fmt, 0, sizeof(fmt)); 600 fmt.index = i; 601 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 602 if (ioctl(hDev, VIDIOC_ENUM_FMT, (void *) &fmt) != 0) { 603 return greyonly; 604 } 605 if (fmt.pixelformat != V4L2_PIX_FMT_GREY) { 606 greyonly = false; 607 } 608 i++; 609 } 610 /* never reached */ 611 return false; 496 612 #endif 497 613 }; 498 614 … … 517 633 518 634 switch (format) 519 635 { 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; 636 case V4L2_PIX_FMT_BGR24: 637 client->format = PIX_FMT_BGR24; 638 break; 639 case V4L2_PIX_FMT_BGR32: 640 client->format = PIX_FMT_RGBA32; 641 break; 642 case V4L2_PIX_FMT_YVU420: 643 client->format = PIX_FMT_YUV420P; 644 break; 645 case V4L2_PIX_FMT_YUV422P: 646 client->format = PIX_FMT_YUV422P; 647 break; 524 648 default: 525 649 cerr << "SIP: Attempt to register unsupported Webcam format\n"; 526 650 delete client; 527 651 return 0; 528 652 } 653 client->frameSize = avpicture_get_size(client->format, WCWIDTH, WCHEIGHT); 529 654 530 655 // Create some buffers for the client 531 656 for (int i=0; i<WC_CLIENT_BUFFERS; i++) … … 630 755 WebcamThreadWorker(); 631 756 } 632 757 758 int Webcam::ReadFrame(unsigned char *outbuf) { 759 #ifndef WIN32 760 int len; 761 if ((!(vCaps.capabilities & V4L2_CAP_READWRITE)) && 762 (!(vCaps.capabilities & V4L2_CAP_STREAMING))) { 763 cerr << "webcam: no supported mechanisms for reading image data" << endl; 764 return -1; 765 } 766 767 memset(outbuf, 0, frameSize); 768 769 if (vCaps.capabilities & V4L2_CAP_READWRITE) { 770 len = read(hDev, outbuf, frameSize); 771 return len; 772 } 773 774 if (vCaps.capabilities & V4L2_CAP_STREAMING) { 775 v4l2_buffer readBuf; 776 memset(&readBuf, 0, sizeof(readBuf)); 777 readBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 778 readBuf.memory = V4L2_MEMORY_MMAP; 779 if (ioctl(hDev, VIDIOC_DQBUF, &readBuf) != 0) { 780 cerr << "Webcam: Unable to fetch streaming buffer" << endl; 781 return -1; 782 } 783 len = readBuf.bytesused; 784 if (len > frameSize) { 785 cerr << "Webcam: outbuf not big enough" << endl; 786 return -1; 787 } 788 memcpy(outbuf, mmapBuf[readBuf.index], len); 789 if (ioctl(hDev, VIDIOC_QBUF, &readBuf) != 0) { 790 cerr << "Webcam: Unable to requeue buffer" << endl; 791 } 792 return len; 793 } 794 795 #endif /* !WIN32 */ 796 return -1; 797 } 798 633 799 void Webcam::WebcamThreadWorker() 634 800 { 635 801 #ifndef WIN32 636 int len=0;637 638 802 while((!killWebcamThread) && (hDev > 0)) 639 803 { 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; 804 int len = ReadFrame(workbuff); 805 806 /* 807 * See if any special handling (decompression) is required 808 * for this frame 809 */ 810 if (GetPalette() == V4L2_PIX_FMT_MJPEG) { 811 if (!decoder->MJPEGDecodeFrame(workbuff, len, picbuff1, frameSize)) { 812 cerr << "Unable to decode MJPEG frame" << endl; 813 len = -1; 814 } else { 815 len = frameSize; 816 } 817 } else { 818 memcpy(picbuff1, workbuff, frameSize); 819 } 820 821 if (len == frameSize) { 822 if (killWebcamThread) 823 break; 824 825 ProcessFrame(picbuff1, frameSize); 826 } 827 else 828 cerr << "Error reading from webcam; got " << len << " bytes; expected " << frameSize << endl; 649 829 } 650 830 #endif 651 831 } … … 663 843 if (totalCaptureMs != 0) 664 844 actualFps = (frameCount*1000)/totalCaptureMs; 665 845 846 int wcFormat = PIX_FMT_NONE; 847 switch(GetPalette()) 848 { 849 case V4L2_PIX_FMT_YVU420: wcFormat = PIX_FMT_YUV420P; break; 850 case V4L2_PIX_FMT_MJPEG: wcFormat = decoder->getPixFmt(); break; 851 case V4L2_PIX_FMT_YUV422P: wcFormat = PIX_FMT_YUV422P; break; 852 case V4L2_PIX_FMT_BGR24: wcFormat = PIX_FMT_BGR24; break; 853 case V4L2_PIX_FMT_BGR32: wcFormat = PIX_FMT_RGBA32; break; 854 default: 855 cerr << "Webcam: Unsupported palette mode " << GetPalette() << endl; 856 } 857 666 858 // Check if the webcam needs flipped (some webcams deliver pics upside down) 667 if (wcFlip )859 if (wcFlip && wcFormat != PIX_FMT_NONE) 668 860 { 669 861 switch(wcFormat) 670 862 { -
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 -
mythphone.pro
26 26 27 27 LIBS += 28 28 29 HEADERS += config.h PhoneSettings.h webcam.h phoneui.h sipfsm.h directory.h dbcheck.h rtp.h g711.h vxml.h tts.h wavfile.h h263.h tone.h sipstack.h md5digest.h gsm/proto.h gsm/unproto.h gsm/config.h gsm/private.h gsm/gsm.h gsm/k6opt.h dtmffilter.h audiodrv.h 29 HEADERS += config.h PhoneSettings.h webcam.h phoneui.h sipfsm.h directory.h dbcheck.h rtp.h g711.h vxml.h tts.h wavfile.h h263.h tone.h sipstack.h md5digest.h gsm/proto.h gsm/unproto.h gsm/config.h gsm/private.h gsm/gsm.h gsm/k6opt.h dtmffilter.h audiodrv.h mjpeg.h 30 30 31 SOURCES += main.cpp webcam.cpp PhoneSettings.cpp phoneui.cpp sipfsm.cpp directory.cpp dbcheck.cpp rtp.cpp g711.cpp g711tabs.cpp vxml.cpp tts.h wavfile.cpp h263.cpp tone.cpp sipstack.cpp md5digest.cpp gsm.cpp gsm/add.c gsm/code.c gsm/debug.c gsm/decode.c gsm/long_term.c gsm/lpc.c gsm/preprocess.c gsm/rpe.c gsm/gsm_destroy.c gsm/gsm_decode.c gsm/gsm_encode.c gsm/gsm_explode.c gsm/gsm_implode.c gsm/gsm_create.c gsm/gsm_print.c gsm/gsm_option.c gsm/short_term.c gsm/table.c dtmffilter.cpp audiodrv.cpp 31 SOURCES += main.cpp webcam.cpp PhoneSettings.cpp phoneui.cpp sipfsm.cpp directory.cpp dbcheck.cpp rtp.cpp g711.cpp g711tabs.cpp vxml.cpp tts.h wavfile.cpp h263.cpp tone.cpp sipstack.cpp md5digest.cpp gsm.cpp gsm/add.c gsm/code.c gsm/debug.c gsm/decode.c gsm/long_term.c gsm/lpc.c gsm/preprocess.c gsm/rpe.c gsm/gsm_destroy.c gsm/gsm_decode.c gsm/gsm_encode.c gsm/gsm_explode.c gsm/gsm_implode.c gsm/gsm_create.c gsm/gsm_print.c gsm/gsm_option.c gsm/short_term.c gsm/table.c dtmffilter.cpp audiodrv.cpp mjpeg.cpp 32 32 33 33