1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2015, OpenCV Foundation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
42 #include "precomp.hpp"
43 #include "opencv2/videoio/container_avi.private.hpp"
48 class MotionJpegCapture: public IVideoCapture
51 virtual ~MotionJpegCapture() CV_OVERRIDE;
52 virtual double getProperty(int) const CV_OVERRIDE;
53 virtual bool setProperty(int, double) CV_OVERRIDE;
54 virtual bool grabFrame() CV_OVERRIDE;
55 virtual bool retrieveFrame(int, OutputArray) CV_OVERRIDE;
56 virtual bool isOpened() const CV_OVERRIDE;
57 virtual int getCaptureDomain() CV_OVERRIDE { return CAP_OPENCV_MJPEG; }
58 MotionJpegCapture(const String&);
60 bool open(const String&);
64 inline uint64_t getFramePos() const;
66 Ptr<AVIReadContainer> m_avi_container;
67 bool m_is_first_frame;
68 frame_list m_mjpeg_frames;
70 frame_iterator m_frame_iterator;
73 //frame width/height and fps could be different for
74 //each frame/stream. At the moment we suppose that they
75 //stays the same within single avi file.
76 uint32_t m_frame_width;
77 uint32_t m_frame_height;
81 uint64_t MotionJpegCapture::getFramePos() const
86 if(m_frame_iterator == m_mjpeg_frames.end())
87 return m_mjpeg_frames.size();
89 return m_frame_iterator - m_mjpeg_frames.begin() + 1;
92 bool MotionJpegCapture::setProperty(int property, double value)
94 if(property == CAP_PROP_POS_FRAMES)
98 m_is_first_frame = true;
99 m_frame_iterator = m_mjpeg_frames.end();
102 else if(m_mjpeg_frames.size() > value)
104 m_frame_iterator = m_mjpeg_frames.begin() + int(value - 1);
105 m_is_first_frame = false;
113 double MotionJpegCapture::getProperty(int property) const
117 case CAP_PROP_POS_FRAMES:
118 return (double)getFramePos();
119 case CAP_PROP_POS_MSEC:
120 return (double)getFramePos() * (1000. / m_fps);
121 case CAP_PROP_POS_AVI_RATIO:
122 return double(getFramePos())/m_mjpeg_frames.size();
123 case CAP_PROP_FRAME_WIDTH:
124 return (double)m_frame_width;
125 case CAP_PROP_FRAME_HEIGHT:
126 return (double)m_frame_height;
129 case CAP_PROP_FOURCC:
130 return (double)CV_FOURCC('M','J','P','G');
131 case CAP_PROP_FRAME_COUNT:
132 return (double)m_mjpeg_frames.size();
133 case CAP_PROP_FORMAT:
140 bool MotionJpegCapture::grabFrame()
146 m_is_first_frame = false;
147 m_frame_iterator = m_mjpeg_frames.begin();
151 if (m_frame_iterator == m_mjpeg_frames.end())
158 return m_frame_iterator != m_mjpeg_frames.end();
161 bool MotionJpegCapture::retrieveFrame(int, OutputArray output_frame)
163 if(m_frame_iterator != m_mjpeg_frames.end())
165 std::vector<char> data = m_avi_container->readFrame(m_frame_iterator);
169 m_current_frame = imdecode(data, IMREAD_ANYDEPTH | IMREAD_COLOR | IMREAD_IGNORE_ORIENTATION);
172 m_current_frame.copyTo(output_frame);
180 MotionJpegCapture::~MotionJpegCapture()
185 MotionJpegCapture::MotionJpegCapture(const String& filename)
187 m_avi_container = makePtr<AVIReadContainer>();
188 m_avi_container->initStream(filename);
192 bool MotionJpegCapture::isOpened() const
194 return m_mjpeg_frames.size() > 0;
197 void MotionJpegCapture::close()
199 m_avi_container->close();
200 m_frame_iterator = m_mjpeg_frames.end();
203 bool MotionJpegCapture::open(const String& filename)
207 m_avi_container = makePtr<AVIReadContainer>();
208 m_avi_container->initStream(filename);
210 m_frame_iterator = m_mjpeg_frames.end();
211 m_is_first_frame = true;
213 if(!m_avi_container->parseRiff(m_mjpeg_frames))
218 m_frame_width = m_avi_container->getWidth();
219 m_frame_height = m_avi_container->getHeight();
220 m_fps = m_avi_container->getFps();
226 Ptr<IVideoCapture> createMotionJpegCapture(const String& filename)
228 Ptr<MotionJpegCapture> mjdecoder(new MotionJpegCapture(filename));
229 if( mjdecoder->isOpened() )
231 return Ptr<MotionJpegCapture>();