1 /*M/////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 // 5 // By downloading, copying, installing or using the software you agree to this license. 6 // If you do not agree to this license, do not download, install, 7 // copy or use the software. 8 // 9 // 10 // Intel License Agreement 11 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2000, Intel Corporation, all rights reserved. 14 // Third party copyrights are property of their respective owners. 15 // 16 // Redistribution and use in source and binary forms, with or without modification, 17 // are permitted provided that the following conditions are met: 18 // 19 // * Redistribution's of source code must retain the above copyright notice, 20 // this list of conditions and the following disclaimer. 21 // 22 // * Redistribution's in binary form must reproduce the above copyright notice, 23 // this list of conditions and the following disclaimer in the documentation 24 // and/or other materials provided with the distribution. 25 // 26 // * The name of Intel Corporation may not be used to endorse or promote products 27 // derived from this software without specific prior written permission. 28 // 29 // This software is provided by the copyright holders and contributors "as is" and 30 // any express or implied warranties, including, but not limited to, the implied 31 // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 // In no event shall the Intel Corporation or contributors be liable for any direct, 33 // indirect, incidental, special, exemplary, or consequential damages 34 // (including, but not limited to, procurement of substitute goods or services; 35 // loss of use, data, or profits; or business interruption) however caused 36 // and on any theory of liability, whether in contract, strict liability, 37 // or tort (including negligence or otherwise) arising in any way out of 38 // the use of this software, even if advised of the possibility of such damage. 39 // 40 //M*/ 41 42 #include "precomp.hpp" 43 #include "cap_intelperc.hpp" 44 #include "cap_dshow.hpp" 45 46 // All WinRT versions older than 8.0 should provide classes used for video support 47 #if defined(WINRT) && !defined(WINRT_8_0) 48 # include "cap_winrt_capture.hpp" 49 # include "cap_winrt_bridge.hpp" 50 # define WINRT_VIDEO 51 #endif 52 53 #if defined _M_X64 && defined _MSC_VER && !defined CV_ICC 54 #pragma optimize("",off) 55 #pragma warning(disable: 4748) 56 #endif 57 58 namespace cv 59 { 60 61 template<> void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const 62 { cvReleaseCapture(&obj); } 63 64 template<> void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const 65 { cvReleaseVideoWriter(&obj); } 66 67 } 68 69 /************************* Reading AVIs & Camera data **************************/ 70 71 static inline double icvGetCaptureProperty( const CvCapture* capture, int id ) 72 { 73 return capture ? capture->getProperty(id) : 0; 74 } 75 76 CV_IMPL void cvReleaseCapture( CvCapture** pcapture ) 77 { 78 if( pcapture && *pcapture ) 79 { 80 delete *pcapture; 81 *pcapture = 0; 82 } 83 } 84 85 CV_IMPL IplImage* cvQueryFrame( CvCapture* capture ) 86 { 87 if(!capture) 88 return 0; 89 if(!capture->grabFrame()) 90 return 0; 91 return capture->retrieveFrame(0); 92 } 93 94 95 CV_IMPL int cvGrabFrame( CvCapture* capture ) 96 { 97 return capture ? capture->grabFrame() : 0; 98 } 99 100 CV_IMPL IplImage* cvRetrieveFrame( CvCapture* capture, int idx ) 101 { 102 return capture ? capture->retrieveFrame(idx) : 0; 103 } 104 105 CV_IMPL double cvGetCaptureProperty( CvCapture* capture, int id ) 106 { 107 return icvGetCaptureProperty(capture, id); 108 } 109 110 CV_IMPL int cvSetCaptureProperty( CvCapture* capture, int id, double value ) 111 { 112 return capture ? capture->setProperty(id, value) : 0; 113 } 114 115 CV_IMPL int cvGetCaptureDomain( CvCapture* capture) 116 { 117 return capture ? capture->getCaptureDomain() : 0; 118 } 119 120 121 /** 122 * Camera dispatching method: index is the camera number. 123 * If given an index from 0 to 99, it tries to find the first 124 * API that can access a given camera index. 125 * Add multiples of 100 to select an API. 126 */ 127 CV_IMPL CvCapture * cvCreateCameraCapture (int index) 128 { 129 int domains[] = 130 { 131 #ifdef HAVE_MSMF 132 CV_CAP_MSMF, 133 #endif 134 #if 1 135 CV_CAP_IEEE1394, // identical to CV_CAP_DC1394 136 #endif 137 #ifdef HAVE_TYZX 138 CV_CAP_STEREO, 139 #endif 140 #ifdef HAVE_PVAPI 141 CV_CAP_PVAPI, 142 #endif 143 #if 1 144 CV_CAP_VFW, // identical to CV_CAP_V4L 145 #endif 146 #ifdef HAVE_MIL 147 CV_CAP_MIL, 148 #endif 149 #if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT) 150 CV_CAP_QT, 151 #endif 152 #ifdef HAVE_UNICAP 153 CV_CAP_UNICAP, 154 #endif 155 #ifdef HAVE_OPENNI 156 CV_CAP_OPENNI, 157 #endif 158 #ifdef HAVE_OPENNI2 159 CV_CAP_OPENNI2, 160 #endif 161 #ifdef HAVE_XIMEA 162 CV_CAP_XIAPI, 163 #endif 164 #ifdef HAVE_AVFOUNDATION 165 CV_CAP_AVFOUNDATION, 166 #endif 167 #ifdef HAVE_GIGE_API 168 CV_CAP_GIGANETIX, 169 #endif 170 #ifdef HAVE_INTELPERC 171 CV_CAP_INTELPERC, 172 #endif 173 -1 174 }; 175 176 // interpret preferred interface (0 = autodetect) 177 int pref = (index / 100) * 100; 178 if (pref) 179 { 180 domains[0]=pref; 181 index %= 100; 182 domains[1]=-1; 183 } 184 185 // try every possibly installed camera API 186 for (int i = 0; domains[i] >= 0; i++) 187 { 188 #if defined(HAVE_MSMF) || \ 189 defined(HAVE_TYZX) || \ 190 defined(HAVE_VFW) || \ 191 defined(HAVE_LIBV4L) || \ 192 defined(HAVE_CAMV4L) || \ 193 defined(HAVE_CAMV4L2) || \ 194 defined(HAVE_VIDEOIO) || \ 195 defined(HAVE_GSTREAMER) || \ 196 defined(HAVE_DC1394_2) || \ 197 defined(HAVE_DC1394) || \ 198 defined(HAVE_CMU1394) || \ 199 defined(HAVE_MIL) || \ 200 defined(HAVE_QUICKTIME) || \ 201 defined(HAVE_QTKIT) || \ 202 defined(HAVE_UNICAP) || \ 203 defined(HAVE_PVAPI) || \ 204 defined(HAVE_OPENNI) || \ 205 defined(HAVE_OPENNI2) || \ 206 defined(HAVE_XIMEA) || \ 207 defined(HAVE_AVFOUNDATION) || \ 208 defined(HAVE_GIGE_API) || \ 209 defined(HAVE_INTELPERC) || \ 210 (0) 211 // local variable to memorize the captured device 212 CvCapture *capture; 213 #endif 214 215 switch (domains[i]) 216 { 217 #ifdef HAVE_MSMF 218 case CV_CAP_MSMF: 219 capture = cvCreateCameraCapture_MSMF (index); 220 if (capture) 221 return capture; 222 break; 223 #endif 224 #ifdef HAVE_TYZX 225 case CV_CAP_STEREO: 226 capture = cvCreateCameraCapture_TYZX (index); 227 if (capture) 228 return capture; 229 break; 230 #endif 231 case CV_CAP_VFW: 232 #ifdef HAVE_VFW 233 capture = cvCreateCameraCapture_VFW (index); 234 if (capture) 235 return capture; 236 #endif 237 #if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO 238 capture = cvCreateCameraCapture_V4L (index); 239 if (capture) 240 return capture; 241 #endif 242 243 #ifdef HAVE_GSTREAMER 244 capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, 0); 245 if (capture) 246 return capture; 247 capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L, 0); 248 if (capture) 249 return capture; 250 #endif 251 break; //CV_CAP_VFW 252 253 case CV_CAP_FIREWIRE: 254 #ifdef HAVE_DC1394_2 255 capture = cvCreateCameraCapture_DC1394_2 (index); 256 if (capture) 257 return capture; 258 #endif 259 260 #ifdef HAVE_DC1394 261 capture = cvCreateCameraCapture_DC1394 (index); 262 if (capture) 263 return capture; 264 #endif 265 266 #ifdef HAVE_CMU1394 267 capture = cvCreateCameraCapture_CMU (index); 268 if (capture) 269 return capture; 270 #endif 271 272 #if defined(HAVE_GSTREAMER) && 0 273 //Re-enable again when gstreamer 1394 support will land in the backend code 274 capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_1394, 0); 275 if (capture) 276 return capture; 277 #endif 278 break; //CV_CAP_FIREWIRE 279 280 #ifdef HAVE_MIL 281 case CV_CAP_MIL: 282 capture = cvCreateCameraCapture_MIL (index); 283 if (capture) 284 return capture; 285 break; 286 #endif 287 288 #if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT) 289 case CV_CAP_QT: 290 capture = cvCreateCameraCapture_QT (index); 291 if (capture) 292 return capture; 293 break; 294 #endif 295 296 #ifdef HAVE_UNICAP 297 case CV_CAP_UNICAP: 298 capture = cvCreateCameraCapture_Unicap (index); 299 if (capture) 300 return capture; 301 break; 302 #endif 303 304 #ifdef HAVE_PVAPI 305 case CV_CAP_PVAPI: 306 capture = cvCreateCameraCapture_PvAPI (index); 307 if (capture) 308 return capture; 309 break; 310 #endif 311 312 #ifdef HAVE_OPENNI 313 case CV_CAP_OPENNI: 314 capture = cvCreateCameraCapture_OpenNI (index); 315 if (capture) 316 return capture; 317 break; 318 #endif 319 320 #ifdef HAVE_OPENNI2 321 case CV_CAP_OPENNI2: 322 capture = cvCreateCameraCapture_OpenNI(index); 323 if (capture) 324 return capture; 325 break; 326 #endif 327 328 #ifdef HAVE_XIMEA 329 case CV_CAP_XIAPI: 330 capture = cvCreateCameraCapture_XIMEA (index); 331 if (capture) 332 return capture; 333 break; 334 #endif 335 336 #ifdef HAVE_AVFOUNDATION 337 case CV_CAP_AVFOUNDATION: 338 capture = cvCreateCameraCapture_AVFoundation (index); 339 if (capture) 340 return capture; 341 break; 342 #endif 343 344 #ifdef HAVE_GIGE_API 345 case CV_CAP_GIGANETIX: 346 capture = cvCreateCameraCapture_Giganetix (index); 347 if (capture) 348 return capture; 349 break; // CV_CAP_GIGANETIX 350 #endif 351 } 352 } 353 354 // failed open a camera 355 return 0; 356 } 357 358 /** 359 * Videoreader dispatching method: it tries to find the first 360 * API that can access a given filename. 361 */ 362 CV_IMPL CvCapture * cvCreateFileCapture (const char * filename) 363 { 364 CvCapture * result = 0; 365 366 #ifdef HAVE_FFMPEG 367 if (! result) 368 result = cvCreateFileCapture_FFMPEG_proxy (filename); 369 #endif 370 371 #ifdef HAVE_VFW 372 if (! result) 373 result = cvCreateFileCapture_VFW (filename); 374 #endif 375 376 #ifdef HAVE_MSMF 377 if (! result) 378 result = cvCreateFileCapture_MSMF (filename); 379 #endif 380 381 #ifdef HAVE_XINE 382 if (! result) 383 result = cvCreateFileCapture_XINE (filename); 384 #endif 385 386 #ifdef HAVE_GSTREAMER 387 if (! result) 388 result = cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename); 389 #endif 390 391 #if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT) 392 if (! result) 393 result = cvCreateFileCapture_QT (filename); 394 #endif 395 396 #ifdef HAVE_AVFOUNDATION 397 if (! result) 398 result = cvCreateFileCapture_AVFoundation (filename); 399 #endif 400 401 #ifdef HAVE_OPENNI 402 if (! result) 403 result = cvCreateFileCapture_OpenNI (filename); 404 #endif 405 406 if (! result) 407 result = cvCreateFileCapture_Images (filename); 408 409 return result; 410 } 411 412 /** 413 * Videowriter dispatching method: it tries to find the first 414 * API that can write a given stream. 415 */ 416 CV_IMPL CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, 417 double fps, CvSize frameSize, int is_color ) 418 { 419 //CV_FUNCNAME( "cvCreateVideoWriter" ); 420 421 CvVideoWriter *result = 0; 422 423 if(!fourcc || !fps) 424 result = cvCreateVideoWriter_Images(filename); 425 426 #ifdef HAVE_FFMPEG 427 if(!result) 428 result = cvCreateVideoWriter_FFMPEG_proxy (filename, fourcc, fps, frameSize, is_color); 429 #endif 430 431 #ifdef HAVE_VFW 432 if(!result) 433 result = cvCreateVideoWriter_VFW(filename, fourcc, fps, frameSize, is_color); 434 #endif 435 436 #ifdef HAVE_MSMF 437 if (!result) 438 result = cvCreateVideoWriter_MSMF(filename, fourcc, fps, frameSize, is_color); 439 #endif 440 441 /* #ifdef HAVE_XINE 442 if(!result) 443 result = cvCreateVideoWriter_XINE(filename, fourcc, fps, frameSize, is_color); 444 #endif 445 */ 446 #ifdef HAVE_AVFOUNDATION 447 if (! result) 448 result = cvCreateVideoWriter_AVFoundation(filename, fourcc, fps, frameSize, is_color); 449 #endif 450 451 #if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT) 452 if(!result) 453 result = cvCreateVideoWriter_QT(filename, fourcc, fps, frameSize, is_color); 454 #endif 455 456 #ifdef HAVE_GSTREAMER 457 if (! result) 458 result = cvCreateVideoWriter_GStreamer(filename, fourcc, fps, frameSize, is_color); 459 #endif 460 461 #if !defined(HAVE_FFMPEG) && \ 462 !defined(HAVE_VFW) && \ 463 !defined(HAVE_MSMF) && \ 464 !defined(HAVE_AVFOUNDATION) && \ 465 !defined(HAVE_QUICKTIME) && \ 466 !defined(HAVE_QTKIT) && \ 467 !defined(HAVE_GSTREAMER) 468 // If none of the writers is used 469 // these statements suppress 'unused parameter' warnings. 470 (void)frameSize; 471 (void)is_color; 472 #endif 473 474 if(!result) 475 result = cvCreateVideoWriter_Images(filename); 476 477 return result; 478 } 479 480 CV_IMPL int cvWriteFrame( CvVideoWriter* writer, const IplImage* image ) 481 { 482 return writer ? writer->writeFrame(image) : 0; 483 } 484 485 CV_IMPL void cvReleaseVideoWriter( CvVideoWriter** pwriter ) 486 { 487 if( pwriter && *pwriter ) 488 { 489 delete *pwriter; 490 *pwriter = 0; 491 } 492 } 493 494 namespace cv 495 { 496 497 static Ptr<IVideoCapture> IVideoCapture_create(int index) 498 { 499 int domains[] = 500 { 501 #ifdef HAVE_DSHOW 502 CV_CAP_DSHOW, 503 #endif 504 #ifdef HAVE_INTELPERC 505 CV_CAP_INTELPERC, 506 #endif 507 #ifdef WINRT_VIDEO 508 CAP_WINRT, 509 #endif 510 #ifdef HAVE_GPHOTO2 511 CV_CAP_GPHOTO2, 512 #endif 513 -1, -1 514 }; 515 516 // interpret preferred interface (0 = autodetect) 517 int pref = (index / 100) * 100; 518 if (pref) 519 { 520 domains[0]=pref; 521 index %= 100; 522 domains[1]=-1; 523 } 524 525 // try every possibly installed camera API 526 for (int i = 0; domains[i] >= 0; i++) 527 { 528 #if defined(HAVE_DSHOW) || \ 529 defined(HAVE_INTELPERC) || \ 530 defined(WINRT_VIDEO) || \ 531 defined(HAVE_GPHOTO2) || \ 532 (0) 533 Ptr<IVideoCapture> capture; 534 535 switch (domains[i]) 536 { 537 #ifdef HAVE_DSHOW 538 case CV_CAP_DSHOW: 539 capture = makePtr<VideoCapture_DShow>(index); 540 break; // CV_CAP_DSHOW 541 #endif 542 #ifdef HAVE_INTELPERC 543 case CV_CAP_INTELPERC: 544 capture = makePtr<VideoCapture_IntelPerC>(); 545 break; // CV_CAP_INTEL_PERC 546 #endif 547 #ifdef WINRT_VIDEO 548 case CAP_WINRT: 549 capture = Ptr<IVideoCapture>(new cv::VideoCapture_WinRT(index)); 550 if (capture) 551 return capture; 552 break; // CAP_WINRT 553 #endif 554 #ifdef HAVE_GPHOTO2 555 case CV_CAP_GPHOTO2: 556 capture = createGPhoto2Capture(index); 557 break; 558 #endif 559 } 560 if (capture && capture->isOpened()) 561 return capture; 562 #endif 563 } 564 565 // failed open a camera 566 return Ptr<IVideoCapture>(); 567 } 568 569 570 static Ptr<IVideoCapture> IVideoCapture_create(const String& filename) 571 { 572 int domains[] = 573 { 574 CV_CAP_ANY, 575 #ifdef HAVE_GPHOTO2 576 CV_CAP_GPHOTO2, 577 #endif 578 -1, -1 579 }; 580 581 // try every possibly installed camera API 582 for (int i = 0; domains[i] >= 0; i++) 583 { 584 Ptr<IVideoCapture> capture; 585 586 switch (domains[i]) 587 { 588 case CV_CAP_ANY: 589 capture = createMotionJpegCapture(filename); 590 break; 591 #ifdef HAVE_GPHOTO2 592 case CV_CAP_GPHOTO2: 593 capture = createGPhoto2Capture(filename); 594 break; 595 #endif 596 } 597 598 if (capture && capture->isOpened()) 599 { 600 return capture; 601 } 602 } 603 // failed open a camera 604 return Ptr<IVideoCapture>(); 605 } 606 607 static Ptr<IVideoWriter> IVideoWriter_create(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor) 608 { 609 Ptr<IVideoWriter> iwriter; 610 if( _fourcc == CV_FOURCC('M', 'J', 'P', 'G') ) 611 iwriter = createMotionJpegWriter(filename, fps, frameSize, isColor); 612 return iwriter; 613 } 614 615 VideoCapture::VideoCapture() 616 {} 617 618 VideoCapture::VideoCapture(const String& filename) 619 { 620 open(filename); 621 } 622 623 VideoCapture::VideoCapture(int device) 624 { 625 open(device); 626 } 627 628 VideoCapture::~VideoCapture() 629 { 630 icap.release(); 631 cap.release(); 632 } 633 634 bool VideoCapture::open(const String& filename) 635 { 636 if (isOpened()) release(); 637 icap = IVideoCapture_create(filename); 638 if (!icap.empty()) 639 return true; 640 641 cap.reset(cvCreateFileCapture(filename.c_str())); 642 return isOpened(); 643 } 644 645 bool VideoCapture::open(int device) 646 { 647 if (isOpened()) release(); 648 icap = IVideoCapture_create(device); 649 if (!icap.empty()) 650 return true; 651 cap.reset(cvCreateCameraCapture(device)); 652 return isOpened(); 653 } 654 655 bool VideoCapture::isOpened() const 656 { 657 return (!cap.empty() || !icap.empty()); 658 } 659 660 void VideoCapture::release() 661 { 662 icap.release(); 663 cap.release(); 664 } 665 666 bool VideoCapture::grab() 667 { 668 if (!icap.empty()) 669 return icap->grabFrame(); 670 return cvGrabFrame(cap) != 0; 671 } 672 673 bool VideoCapture::retrieve(OutputArray image, int channel) 674 { 675 if (!icap.empty()) 676 return icap->retrieveFrame(channel, image); 677 678 IplImage* _img = cvRetrieveFrame(cap, channel); 679 if( !_img ) 680 { 681 image.release(); 682 return false; 683 } 684 if(_img->origin == IPL_ORIGIN_TL) 685 cv::cvarrToMat(_img).copyTo(image); 686 else 687 { 688 Mat temp = cv::cvarrToMat(_img); 689 flip(temp, image, 0); 690 } 691 return true; 692 } 693 694 bool VideoCapture::read(OutputArray image) 695 { 696 if(grab()) 697 retrieve(image); 698 else 699 image.release(); 700 return !image.empty(); 701 } 702 703 VideoCapture& VideoCapture::operator >> (Mat& image) 704 { 705 #ifdef WINRT_VIDEO 706 if (grab()) 707 { 708 if (retrieve(image)) 709 { 710 std::lock_guard<std::mutex> lock(VideoioBridge::getInstance().inputBufferMutex); 711 VideoioBridge& bridge = VideoioBridge::getInstance(); 712 713 // double buffering 714 bridge.swapInputBuffers(); 715 auto p = bridge.frontInputPtr; 716 717 bridge.bIsFrameNew = false; 718 719 // needed here because setting Mat 'image' is not allowed by OutputArray in read() 720 Mat m(bridge.getHeight(), bridge.getWidth(), CV_8UC3, p); 721 image = m; 722 } 723 } 724 #else 725 read(image); 726 #endif 727 728 return *this; 729 } 730 731 VideoCapture& VideoCapture::operator >> (UMat& image) 732 { 733 read(image); 734 return *this; 735 } 736 737 bool VideoCapture::set(int propId, double value) 738 { 739 if (!icap.empty()) 740 return icap->setProperty(propId, value); 741 return cvSetCaptureProperty(cap, propId, value) != 0; 742 } 743 744 double VideoCapture::get(int propId) const 745 { 746 if (!icap.empty()) 747 return icap->getProperty(propId); 748 return icvGetCaptureProperty(cap, propId); 749 } 750 751 752 VideoWriter::VideoWriter() 753 {} 754 755 VideoWriter::VideoWriter(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor) 756 { 757 open(filename, _fourcc, fps, frameSize, isColor); 758 } 759 760 void VideoWriter::release() 761 { 762 iwriter.release(); 763 writer.release(); 764 } 765 766 VideoWriter::~VideoWriter() 767 { 768 release(); 769 } 770 771 bool VideoWriter::open(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor) 772 { 773 if (isOpened()) release(); 774 iwriter = IVideoWriter_create(filename, _fourcc, fps, frameSize, isColor); 775 if (!iwriter.empty()) 776 return true; 777 writer.reset(cvCreateVideoWriter(filename.c_str(), _fourcc, fps, frameSize, isColor)); 778 return isOpened(); 779 } 780 781 bool VideoWriter::isOpened() const 782 { 783 return !iwriter.empty() || !writer.empty(); 784 } 785 786 787 bool VideoWriter::set(int propId, double value) 788 { 789 if (!iwriter.empty()) 790 return iwriter->setProperty(propId, value); 791 return false; 792 } 793 794 double VideoWriter::get(int propId) const 795 { 796 if (!iwriter.empty()) 797 return iwriter->getProperty(propId); 798 return 0.; 799 } 800 801 void VideoWriter::write(const Mat& image) 802 { 803 if( iwriter ) 804 iwriter->write(image); 805 else 806 { 807 IplImage _img = image; 808 cvWriteFrame(writer, &_img); 809 } 810 } 811 812 VideoWriter& VideoWriter::operator << (const Mat& image) 813 { 814 write(image); 815 return *this; 816 } 817 818 int VideoWriter::fourcc(char c1, char c2, char c3, char c4) 819 { 820 return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24); 821 } 822 823 } 824