/* * VideoIterator_Mac * * Author: Andrew Salamon * Date: Tue Feb 27, 2008 * * Copyright (c) 2008 Machine Perception Laboratory * University of California San Diego. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #import #import #include // For system independent path support #include #include #include // For basename and extension namespace bf = boost::filesystem; #include "VideoIterator_Mac.h" #include "rimageFromNSImage.h" #import "NSImageToRimage.h" namespace CERT { VideoIterator_Mac::VideoIterator_Mac( const std::string &_path ) : valid(false), path(_path), frame(0), movie(nil), error(nil) { pool = [[NSAutoreleasePool alloc] init]; [QTMovie movie]; if( path.length() > 0 ) loadVideo(); } VideoIterator_Mac::~VideoIterator_Mac() { [(QTMovie *)movie release]; movie = nil; [(NSError *)error release]; error = nil; [(NSAutoreleasePool *)pool release]; pool = nil; } void VideoIterator_Mac::loadVideo() { NSError *tmpError = nil; NSString *pathString = [NSString stringWithCString:path.c_str()]; QTMovie *tmpMovie = [QTMovie movieWithFile:pathString error:&tmpError]; // If it's a text file we should skip it, even though QT tries to run it. bf::path bfPath(path, bf::native); std::string ext = bf::extension(bfPath); if( ".txt" == ext || ".text" == ext || ".TXT" == ext || ".TEXT" == ext ) { movie = nil; valid = false; return; } if( tmpError ) { movie = nil; valid = false; error = [tmpError retain]; return; } else { valid = true; [tmpMovie retain]; movie = tmpMovie; } [tmpMovie gotoEnd]; QTTime tmpTime =[tmpMovie currentTime]; endTime.timeValue = tmpTime.timeValue; endTime.timeScale = tmpTime.timeScale; endTime.flags = tmpTime.flags; [tmpMovie gotoBeginning]; // we start at zero because of the odd way we keep track of frames. // The user will see frame numbers starting at 1. frame = 0; } bool VideoIterator_Mac::nextFrame( RImage &pixels ) { checkPool(); if( !valid ) return false; QTMovie *tmpMovie = (QTMovie *)movie; QTTime currentTime = [tmpMovie currentTime]; QTTime tmpEndTime; tmpEndTime.timeValue = endTime.timeValue; tmpEndTime.timeScale = endTime.timeScale; tmpEndTime.flags = endTime.flags; if( NSOrderedDescending != QTTimeCompare( tmpEndTime, currentTime ) ) { return false; } // We're not at the end of the movie, so grab the current frame image then step forward bool ok(false); NSImage *frameImage = [tmpMovie currentFrameImage]; if( frameImage ) { RImage *tempImage = [frameImage rimageRep]; if( tempImage ) { pixels = *tempImage; delete tempImage; ok = true; } } [tmpMovie stepForward]; ++frame; return ok; } bool VideoIterator_Mac::isVideo() { return valid; } int VideoIterator_Mac::getFrameNumber() { return frame; } std::string VideoIterator_Mac::getPath() { return path; } void VideoIterator_Mac::setPath( const std::string &_path ) { valid = false; path = _path; frame = 0; [(QTMovie *)movie release]; [(NSError *)error release]; movie = nil; error = nil; if( path.length() > 0 ) loadVideo(); } void VideoIterator_Mac::checkPool() { static int cnt = 0; if( (0 != cnt) && ( 0 == (cnt % 100) ) ) { [(NSAutoreleasePool *)pool release]; pool = [[NSAutoreleasePool alloc] init]; } ++cnt; } } // End namespace CERT