Path: blob/master/modules/videoio/src/cap_mjpeg_decoder.cpp
16354 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2015, OpenCV Foundation, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of Intel Corporation may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/4041#include "precomp.hpp"42#include "opencv2/videoio/container_avi.private.hpp"4344namespace cv45{4647class MotionJpegCapture: public IVideoCapture48{49public:50virtual ~MotionJpegCapture() CV_OVERRIDE;51virtual double getProperty(int) const CV_OVERRIDE;52virtual bool setProperty(int, double) CV_OVERRIDE;53virtual bool grabFrame() CV_OVERRIDE;54virtual bool retrieveFrame(int, OutputArray) CV_OVERRIDE;55virtual bool isOpened() const CV_OVERRIDE;56virtual int getCaptureDomain() CV_OVERRIDE { return CAP_OPENCV_MJPEG; }57MotionJpegCapture(const String&);5859bool open(const String&);60void close();61protected:6263inline uint64_t getFramePos() const;6465Ptr<AVIReadContainer> m_avi_container;66bool m_is_first_frame;67frame_list m_mjpeg_frames;6869frame_iterator m_frame_iterator;70Mat m_current_frame;7172//frame width/height and fps could be different for73//each frame/stream. At the moment we suppose that they74//stays the same within single avi file.75uint32_t m_frame_width;76uint32_t m_frame_height;77double m_fps;78};7980uint64_t MotionJpegCapture::getFramePos() const81{82if(m_is_first_frame)83return 0;8485if(m_frame_iterator == m_mjpeg_frames.end())86return m_mjpeg_frames.size();8788return m_frame_iterator - m_mjpeg_frames.begin() + 1;89}9091bool MotionJpegCapture::setProperty(int property, double value)92{93if(property == CAP_PROP_POS_FRAMES)94{95if(int(value) == 0)96{97m_is_first_frame = true;98m_frame_iterator = m_mjpeg_frames.end();99return true;100}101else if(m_mjpeg_frames.size() > value)102{103m_frame_iterator = m_mjpeg_frames.begin() + int(value - 1);104m_is_first_frame = false;105return true;106}107}108109return false;110}111112double MotionJpegCapture::getProperty(int property) const113{114switch(property)115{116case CAP_PROP_POS_FRAMES:117return (double)getFramePos();118case CAP_PROP_POS_AVI_RATIO:119return double(getFramePos())/m_mjpeg_frames.size();120case CAP_PROP_FRAME_WIDTH:121return (double)m_frame_width;122case CAP_PROP_FRAME_HEIGHT:123return (double)m_frame_height;124case CAP_PROP_FPS:125return m_fps;126case CAP_PROP_FOURCC:127return (double)CV_FOURCC('M','J','P','G');128case CAP_PROP_FRAME_COUNT:129return (double)m_mjpeg_frames.size();130case CAP_PROP_FORMAT:131return 0;132default:133return 0;134}135}136137bool MotionJpegCapture::grabFrame()138{139if(isOpened())140{141if(m_is_first_frame)142{143m_is_first_frame = false;144m_frame_iterator = m_mjpeg_frames.begin();145}146else147{148if (m_frame_iterator == m_mjpeg_frames.end())149return false;150151++m_frame_iterator;152}153}154155return m_frame_iterator != m_mjpeg_frames.end();156}157158bool MotionJpegCapture::retrieveFrame(int, OutputArray output_frame)159{160if(m_frame_iterator != m_mjpeg_frames.end())161{162std::vector<char> data = m_avi_container->readFrame(m_frame_iterator);163164if(data.size())165{166m_current_frame = imdecode(data, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_COLOR | IMREAD_IGNORE_ORIENTATION);167}168169m_current_frame.copyTo(output_frame);170171return true;172}173174return false;175}176177MotionJpegCapture::~MotionJpegCapture()178{179close();180}181182MotionJpegCapture::MotionJpegCapture(const String& filename)183{184m_avi_container = makePtr<AVIReadContainer>();185m_avi_container->initStream(filename);186open(filename);187}188189bool MotionJpegCapture::isOpened() const190{191return m_mjpeg_frames.size() > 0;192}193194void MotionJpegCapture::close()195{196m_avi_container->close();197m_frame_iterator = m_mjpeg_frames.end();198}199200bool MotionJpegCapture::open(const String& filename)201{202close();203204m_avi_container = makePtr<AVIReadContainer>();205m_avi_container->initStream(filename);206207m_frame_iterator = m_mjpeg_frames.end();208m_is_first_frame = true;209210if(!m_avi_container->parseRiff(m_mjpeg_frames))211{212close();213} else214{215m_frame_width = m_avi_container->getWidth();216m_frame_height = m_avi_container->getHeight();217m_fps = m_avi_container->getFps();218}219220return isOpened();221}222223Ptr<IVideoCapture> createMotionJpegCapture(const String& filename)224{225Ptr<MotionJpegCapture> mjdecoder(new MotionJpegCapture(filename));226if( mjdecoder->isOpened() )227return mjdecoder;228return Ptr<MotionJpegCapture>();229}230231}232233234