[Sumover-dev] [svn commit] r3961 - in vic/branches/mpeg4: tcl video
sumover-dev at cs.ucl.ac.uk
sumover-dev at cs.ucl.ac.uk
Thu Jan 18 15:36:32 GMT 2007
Author: barz
Date: Thu Jan 18 15:36:21 2007
New Revision: 3961
Added:
vic/branches/mpeg4/video/grabber-macosx.cpp
Modified:
vic/branches/mpeg4/configure
vic/branches/mpeg4/tcl/ui-windows.tcl
Log:
import grabber-macosx.cpp
Modified: vic/branches/mpeg4/configure
==============================================================================
--- vic/branches/mpeg4/configure (original)
+++ vic/branches/mpeg4/configure Thu Jan 18 15:36:21 2007
@@ -981,7 +981,7 @@
else
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi
- cd "$ac_popdir"
+ cd $ac_popdir
done
fi
@@ -2038,7 +2038,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2096,7 +2097,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2212,7 +2214,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2266,7 +2269,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2311,7 +2315,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2355,7 +2360,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2539,7 +2545,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2597,7 +2604,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2668,7 +2676,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2712,7 +2721,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3029,7 +3039,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3199,7 +3210,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3267,7 +3279,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3425,7 +3438,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3492,7 +3506,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3562,7 +3577,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3801,7 +3817,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3888,7 +3905,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4124,7 +4142,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4398,7 +4417,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4649,7 +4669,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4795,7 +4816,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4941,7 +4963,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5105,7 +5128,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5177,7 +5201,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5249,7 +5274,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5322,7 +5348,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5436,7 +5463,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5547,7 +5575,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5620,7 +5649,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5793,7 +5823,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5868,7 +5899,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5942,7 +5974,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6470,7 +6503,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6541,7 +6575,8 @@
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -7481,6 +7516,11 @@
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
@@ -7519,12 +7559,6 @@
fi;;
esac
done` || { (exit 1); exit 1; }
-
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
sed "$ac_vpsub
Modified: vic/branches/mpeg4/tcl/ui-windows.tcl
==============================================================================
--- vic/branches/mpeg4/tcl/ui-windows.tcl (original)
+++ vic/branches/mpeg4/tcl/ui-windows.tcl Thu Jan 18 15:36:21 2007
@@ -188,11 +188,11 @@
toplevel $w -class Vic \
-visual "[winfo visual .top] [winfo depth .top]" \
-colormap .top
- #catch "wm resizable $w false false"
+ catch "wm resizable $w false false"
#
# make windows become x-y resizeable
#
- catch "wm resizable $w true false"
+ #catch "wm resizable $w true false"
frame $w.frame
Added: vic/branches/mpeg4/video/grabber-macosx.cpp
==============================================================================
--- (empty file)
+++ vic/branches/mpeg4/video/grabber-macosx.cpp Thu Jan 18 15:36:21 2007
@@ -0,0 +1,784 @@
+/*
+ * grabber-macosx.cpp --
+ *
+ * Video capture support for Mac OS X.
+ *
+ * Imported from OpenMash vic. Updated to use SGGetChannelDeviceList to list
+ * all of the available SequenceGrabber video capture devices and corresponding
+ * inputs, instead of using just the default capture device and input.
+ * - Douglas Kosovic <douglask at itee.uq.edu.au>
+ *
+ * Updated to work with the iSight camera (and others) using the
+ * SequenceGrabber API - Bruce Williams <netmaster_bruce at mac.com>
+ *
+ * It would be nicer to do the image conversion by calling DecompressImage with
+ * a GWorld as that will scale and resample the image instead of cropping which
+ * the YUV conversion functions do.
+ *
+ * Copyright (c) 2000-2002 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * A. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * B. 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.
+ * C. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include <QuickTime/QuickTime.h>
+#include <Carbon/Carbon.h>
+#include <stdio.h>
+
+#include "grabber.h"
+#include "vic_tcl.h"
+#include "device-input.h"
+#include "module.h"
+#include "bsd-endian.h"
+
+/***************************************************************************/
+// FIXME: This is definitely *not* the place to define video sizes
+#define PAL 0
+#define NTSC 1
+
+// CIF
+#define CIF_WIDTH 352
+#define CIF_HEIGHT 288
+// QCIF
+#define QCIF_WIDTH 176
+#define QCIF_HEIGHT 144
+// Square-pixel CCIR-601 format, digitally-encoded NTSC resolution
+#define SP601_NTSC_WIDTH 640
+#define SP601_NTSC_HEIGHT 480
+// Square-pixel CCIR-601 format, digitally-encoded PAL resolution
+#define SP601_PAL_WIDTH 768
+#define SP601_PAL_HEIGHT 576
+// Square-pixel SIF format, digitally-encoded NTSC resolution
+#define SPSIF_NTSC_WIDTH 320
+#define SPSIF_NTSC_HEIGHT 240
+// Square-pixel SIF format, digitally-encoded PAL resolution
+#define SPSIF_PAL_WIDTH 384
+#define SPSIF_PAL_HEIGHT 288
+
+// Color subsampling options.
+#define CF_422 422
+#define CF_411 411
+#define CF_CIF 4112
+
+typedef struct {
+ GWorldPtr gWorld;
+ ImageSequence decomSeq;
+} SGDataProcRefCon;
+
+#define BailErr(x) {err = x; if(err != noErr) goto bail;}
+
+/***************************************************************************/
+// The video capture class.
+class MacOSXGrabber : public Grabber {
+public:
+ // Constructor.
+ MacOSXGrabber(const char* format, const char* dev);
+
+ // Destructor.
+ virtual ~MacOSXGrabber();
+
+ // Minimum necessary functions.
+ virtual void start();
+ virtual void stop();
+ virtual int grab();
+
+ // Overridden functions.
+ virtual int command(int argc, const char*const* argv);
+
+protected:
+ // sequence grabber support requires a callback function
+ static OSErr seqGrabberDataProc(SGChannel, Ptr, long, long *, long, TimeValue, short, long);
+
+ // Supplemental functions.
+ void format();
+ int setport(const char *port);
+ int capture();
+ int setupDecom(void);
+
+ // YUV conversion functions.
+ void packedYUYV422_to_planarYUYV422(char *dest, char *src);
+ void packedYUYV422_to_planarYUYV411(char *dest, char *src);
+
+ // The frame information.
+ int decimate_;
+ int width_, height_;
+
+ int imageSize;
+
+ // True if sequence grabbing is possible.
+ Boolean quicktime_;
+
+ // sequence grabber
+ SeqGrabComponent seqGrab;
+ SGChannel sgchanVideo;
+
+ /*
+ * A graphics world would be a nicer way to convert and resample the image.
+ */
+ ImageDescriptionHandle desc_;
+ GWorldPtr gWorld_;
+ Rect frameRect_;
+
+ SGDataProcRefCon *sgDataProcRefCon;
+
+ // The capture format.
+ int format_;
+
+ // Name of the video capture device
+ const char *dev_;
+
+ // the capture port
+ char port_[64];
+
+ // Video input standard - ntscIn, palIn or secamIn
+ short input_standard_;
+
+ // Use SequenceGrabber config dialog box
+ bool useconfig_;
+
+ // A simple exception handler class.
+ class Exception {
+ public:
+ Exception(char* s) {
+ string = s;
+ }
+
+ char* string;
+ };
+};
+
+MacOSXGrabber::MacOSXGrabber(const char* format, const char* dev) {
+ OSErr err = noErr;
+ quicktime_ = true;
+ decimate_ = 0;
+ gWorld_ = NULL;
+ seqGrab = NULL;
+ dev_ = dev;
+ input_standard_ = ntscIn;
+ port_[0] = 0;
+ useconfig_ = false;
+
+ // allocate prezeroed nonrelocatable block of memory
+ sgDataProcRefCon = (SGDataProcRefCon *)NewPtrClear(sizeof(SGDataProcRefCon));
+
+ InitCursor();
+ EnterMovies();
+
+ try {
+ // Remember the format.
+ if (strcmp(format, "422") == 0) format_ = CF_422;
+ else if (strcmp(format, "411") == 0) format_ = CF_411;
+ else if (strcmp(format, "cif") == 0) format_ = CF_CIF;
+ else throw Exception("Unrecognized format");
+ } catch (Exception e) {
+ quicktime_ = false;
+ fprintf(stderr, "QuickTime error[%d]: %s\n", err, e.string);
+ }
+}
+
+MacOSXGrabber::~MacOSXGrabber() {
+ /*
+ * Graphics worlds must be disposed of if used.
+ */
+ // Dipose of the GWorld.
+ if (gWorld_ != NULL) DisposeGWorld(gWorld_);
+
+ // Close the video digitizer component.
+ CloseComponent(seqGrab);
+
+ // Dispose of nonrelocatable block of memory
+ if (sgDataProcRefCon != NULL) DisposePtr((char *)sgDataProcRefCon);
+}
+
+void MacOSXGrabber::start() {
+ OSErr err = noErr;
+
+ // Don't do anything if QuickTime failed.
+ if (!quicktime_) return;
+
+ // start the sequencer
+ err = SGStartRecord(seqGrab);
+
+ // Start capturing.
+ Grabber::start();
+}
+
+void MacOSXGrabber::stop() {
+ // Don't do anything if QuickTime failed.
+ if (!quicktime_) return;
+
+ // stop the sequencer
+ SGStop(seqGrab);
+
+ // Stop capturing.
+ Grabber::stop();
+}
+
+int MacOSXGrabber::grab() {
+ if (sgDataProcRefCon->decomSeq == 0) {
+ if (setupDecom()) {
+ return 0;
+ }
+ }
+ if (capture() == 0) return 0;
+ suppress(frame_);
+ saveblks(frame_);
+ YuvFrame f(media_ts(), frame_, crvec_, outw_, outh_, format_);
+
+ if(target_)
+ return(target_->consume(&f));
+ return 0;
+}
+
+int MacOSXGrabber::capture() {
+ OSErr err = noErr;
+ Ptr theData;
+ long dataSize;
+
+ /*
+ * Needed if decompressing to a graphics world.
+ */
+ GWorldPtr currentGWorld;
+ GDHandle currentGDevice;
+
+ try {
+ /*
+ * this does the work of grabbing from the camera
+ */
+ err = SGIdle(seqGrab);
+
+ // Save the current graphics port.
+ GetGWorld(¤tGWorld, ¤tGDevice);
+ SetGWorld(gWorld_, NULL);
+
+ theData = GetPixBaseAddr(GetGWorldPixMap(gWorld_));
+ dataSize = imageSize;
+
+ // Restore the graphics port.
+ SetGWorld(currentGWorld, currentGDevice);
+
+ // Copy the frame.
+ /*
+ * i'd like to be able to use Quicktime to do the colour space
+ * conversions here, or remove the need for them totally!
+ */
+ switch (format_) {
+ case CF_422:
+ packedYUYV422_to_planarYUYV422((char*)frame_, theData);
+ break;
+ case CF_411:
+ case CF_CIF:
+ packedYUYV422_to_planarYUYV411((char*)frame_, theData);
+ break;
+ }
+
+ } catch (Exception e) {
+ fprintf(stderr, "QuickTime error[%d]: %s\n", err, e.string);
+ return 0;
+ }
+
+ // Return success.
+ return 1;
+}
+
+void MacOSXGrabber::format() {
+ OSErr err = noErr;
+
+ // Set the image size.
+ switch (decimate_) {
+ case 1: // full-sized
+ width_ = SP601_NTSC_WIDTH;
+ height_ = SP601_NTSC_HEIGHT;
+ break;
+ case 2: // CIF-sized
+ width_ = CIF_WIDTH;
+ height_ = CIF_HEIGHT;
+ break;
+ case 4: // QCIF - may not work
+ width_ = QCIF_WIDTH;
+ height_ = QCIF_HEIGHT;
+ break;
+ }
+ switch (format_) {
+ case CF_422:
+ set_size_422(width_, height_);
+ break;
+ case CF_411:
+ set_size_411(width_, height_);
+ break;
+ case CF_CIF:
+ set_size_cif(width_, height_);
+ break;
+ }
+
+ try {
+ // Set the frame rect.
+ SetRect(&frameRect_, 0, 0, width_, height_);
+
+ if (gWorld_ == NULL) {
+ // Create or update an offscreen GWorld for the frame pixel map.
+ err = QTNewGWorld(&gWorld_, kYUVSPixelFormat, &frameRect_, 0, NULL, 0);
+ if (err != noErr) throw Exception("QTNewGWorld");
+ sgDataProcRefCon->gWorld = gWorld_;
+ if (!LockPixels(GetGWorldPixMap(gWorld_))) throw Exception("LockPixels");
+
+ /*
+ * ref: MakeSequenceGrabber()
+ * need better error checking here
+ */
+ seqGrab = OpenDefaultComponent(SeqGrabComponentType, 0);
+ if (seqGrab != NULL)
+ err = SGInitialize(seqGrab);
+ if (err == noErr)
+ err = SGSetGWorld(seqGrab, NULL, NULL);
+ if (err == noErr)
+ err = SGSetDataRef(seqGrab, 0, 0, seqGrabDontMakeMovie);
+
+ /* ref: MakeSequenceGrabChannel */
+ err = SGNewChannel(seqGrab, VideoMediaType, &sgchanVideo);
+ if (err == noErr) {
+ Str63 devPStr;
+ c2pstrcpy(devPStr, dev_);
+
+ SGSetChannelDevice(sgchanVideo, (StringPtr)&devPStr);
+
+ setport(port_);
+
+ VideoDigitizerComponent vdigComponent = SGGetVideoDigitizerComponent(sgchanVideo);
+ DigitizerInfo digitizerInfo;
+ err = VDGetDigitizerInfo(vdigComponent, &digitizerInfo);
+ if (err == noErr) {
+ if ((digitizerInfo.inputCapabilityFlags & digiInDoesNTSC) && (input_standard_ == ntscIn)) {
+ err = VDSetInputStandard(vdigComponent, ntscIn);
+ } else if ((digitizerInfo.inputCapabilityFlags & digiInDoesPAL) && (input_standard_ == palIn)) {
+ err = VDSetInputStandard(vdigComponent, palIn);
+ } else if ((digitizerInfo.inputCapabilityFlags & digiInDoesSECAM) && (input_standard_ == secamIn)) {
+ err = VDSetInputStandard(vdigComponent, secamIn);
+ }
+ }
+
+ /* set sg to gworld */
+ err = SGSetGWorld(seqGrab, gWorld_, GetMainDevice());
+
+ err = SGSetChannelBounds(sgchanVideo, (const Rect *)&frameRect_);
+
+ if (err == noErr)
+ err = SGSetChannelUsage(sgchanVideo, seqGrabRecord);
+ if (err != noErr) {
+ SGDisposeChannel(seqGrab, sgchanVideo);
+ sgchanVideo = NULL;
+ }
+ }
+ err = SGSetDataProc(seqGrab, NewSGDataUPP(&seqGrabberDataProc), (long)sgDataProcRefCon);
+ err = SGPrepare(seqGrab, false, true);
+
+ } else {
+ fprintf(stderr, " format() - reformat not implemented!\n");
+ // UnlockPixels(GetGWorldPixMap(gWorld_));
+ // UpdateGWorld(&gWorld_, kYUVUPixelFormat, &frameRect_, 0, NULL, 0);
+ // if (!LockPixels(GetGWorldPixMap(gWorld_))) throw Exception("LockPixels");
+ }
+ } catch (Exception e) {
+ fprintf(stderr, "QuickTime error[%d]: %s\n", err, e.string);
+ }
+ // Allocate the reference buffer.
+ allocref();
+}
+
+int MacOSXGrabber::setport(const char *port) {
+ OSErr err = noErr;
+ int inputNumber = 0;
+
+ if (strcmp(port_, port) == 0) {
+ return 0;
+ }
+
+ SGDeviceList sgdeviceList;
+ err = SGGetChannelDeviceList(sgchanVideo, sgDeviceListIncludeInputs, &sgdeviceList);
+ if (err != noErr) {
+ return TCL_ERROR;
+ }
+ char port_str[64];
+ int selectedIndex = (*sgdeviceList)->selectedIndex;
+ for (int i = 0; i < (*(((*sgdeviceList)->entry[selectedIndex]).inputs))->count; i++) {
+ p2cstrcpy(port_str, (*(((*sgdeviceList)->entry[selectedIndex]).inputs))->entry[i].name);
+ if (strcmp(port, port_str) == 0) {
+ inputNumber = i;
+ }
+ }
+ SGDisposeDeviceList(seqGrab, sgdeviceList);
+
+ if (running_) {
+ stop();
+ }
+
+ err = SGSetChannelDeviceInput(sgchanVideo, inputNumber);
+ if (err != noErr) {
+ strcpy((char*)port, port_);
+ return TCL_ERROR;
+ }
+}
+
+int MacOSXGrabber::command(int argc, const char*const* argv) {
+ // fprintf(stderr,"### MacOSXGrabber::command : argv[1] = %s\n", argv[1]);
+ if (argc == 3) {
+ if (strcmp(argv[1], "decimate") == 0) {
+ decimate_ = atoi(argv[2]);
+ if (running_) {
+ stop();
+ }
+ format();
+ start();
+ return(TCL_OK);
+
+ } else if (strcmp(argv[1], "port") == 0) {
+ if (seqGrab == NULL) {
+ strcpy((char *)argv[2], port_);
+ } else {
+ setport(argv[2]);
+ start();
+ return(TCL_OK);
+ }
+ } else if (strcmp(argv[1], "type") == 0) {
+ if (strcmp(argv[2], "pal") == 0)
+ input_standard_ = palIn;
+ else if (strcmp(argv[2], "secam") == 0)
+ input_standard_ = secamIn;
+ else
+ input_standard_ = ntscIn;
+
+ return(TCL_OK);
+
+ } else if (strcmp(argv[1], "useconfig") == 0) {
+ if (strcmp(argv[2], "1") == 0) useconfig_ = true;
+ if (strcmp(argv[2], "0") == 0) useconfig_ = false;
+
+ } else if (strcmp(argv[1], "send") == 0) {
+ if (useconfig_ && running_ == 0) {
+ Component *panelListPtr = NULL;
+ UInt8 numberOfPanels = 0;
+
+ ComponentDescription cd = { SeqGrabPanelType, VideoMediaType, 0, 0, 0 };
+ Component c = 0;
+ Component *cPtr = NULL;
+
+ // set up the settings panel list removing the "Compression" and "Source" panels
+ numberOfPanels = CountComponents(&cd);
+ if (numberOfPanels == 0)
+ return TCL_ERROR;
+
+ panelListPtr = (Component *)NewPtr(sizeof(Component) * (numberOfPanels + 1));
+ if (MemError() || panelListPtr == NULL)
+ return TCL_ERROR;
+
+ cPtr = panelListPtr;
+ numberOfPanels = 0;
+ char panel_name[255];
+ do {
+ ComponentDescription compInfo;
+ c = FindNextComponent(c, &cd);
+ if (c) {
+ Handle hName = NewHandle(0);
+ if (MemError() || hName == NULL)
+ return TCL_ERROR;
+ GetComponentInfo(c, &compInfo, hName, NULL, NULL);
+ p2cstrcpy(panel_name, (unsigned char*)(*hName));
+ if (strcmp(panel_name, "Compression") != 0 && strcmp(panel_name, "Source") != 0) {
+ *cPtr++ = c;
+ numberOfPanels++;
+ }
+ DisposeHandle(hName);
+ }
+ } while (c);
+
+ SGSettingsDialog(seqGrab, sgchanVideo, numberOfPanels, panelListPtr, 0, NULL, 0);
+ }
+ }
+
+ } else if (argc == 2) {
+ if (strcmp(argv[1], "decimate") == 0) {
+ Tcl& tcl = Tcl::instance();
+ tcl.resultf("%d", decimate_);
+ return (TCL_OK);
+ }
+ }
+ return Grabber::command(argc, argv);
+}
+
+int MacOSXGrabber::setupDecom(void) {
+ ComponentResult err = noErr;
+ Rect sourceRect = { 0, 0 };
+ MatrixRecord scaleMatrix;
+ ImageDescriptionHandle imageDesc = (ImageDescriptionHandle)NewHandle(0);
+
+ err = SGGetChannelSampleDescription(sgchanVideo, (Handle)imageDesc);
+ BailErr(err);
+
+ sourceRect.right = (**imageDesc).width;
+ sourceRect.bottom = (**imageDesc).height;
+ RectMatrix(&scaleMatrix, &sourceRect, &frameRect_);
+
+ err = DecompressSequenceBegin(&(sgDataProcRefCon->decomSeq),
+ imageDesc,
+ sgDataProcRefCon->gWorld,
+ NULL,
+ NULL,
+ &scaleMatrix,
+ srcCopy,
+ NULL,
+ 0,
+ codecNormalQuality,
+ bestSpeedCodec);
+ BailErr(err);
+
+ imageSize = ((*imageDesc)->width * (*imageDesc)->height);
+
+ DisposeHandle ((Handle)imageDesc);
+ imageDesc = NULL;
+
+bail:
+ if (imageDesc)
+ DisposeHandle((Handle)imageDesc);
+ return(err);
+}
+
+/*
+ * video sequence data proc
+ */
+OSErr MacOSXGrabber::seqGrabberDataProc(SGChannel c, Ptr p, long len, long *offset, long chRefCon, TimeValue time, short writeType, long refCon) {
+
+#pragma unused (c, offset, chRefCon, time, writeType)
+
+ ComponentResult err = noErr;
+ CodecFlags ignore;
+
+ SGDataProcRefCon *sgDataProcRefCon = (SGDataProcRefCon *)refCon;
+
+ if (!sgDataProcRefCon->gWorld) return(err);
+ err = DecompressSequenceFrameS(sgDataProcRefCon->decomSeq,
+ p,
+ len,
+ 0,
+ &ignore,
+ NULL);
+ return(err);
+}
+
+/***************************************************************************/
+// The hybrid class providing Tcl with access to the video capture device.
+class MacOSXDevice : public InputDevice {
+public:
+ MacOSXDevice(const char* device, char *attr);
+ virtual int command(int argc, const char*const* argv);
+};
+
+MacOSXDevice::MacOSXDevice(const char* device, char *attr) : InputDevice(device) {
+ attributes_ = attr;
+ fprintf(stderr,"OSX Capture: ==> %s\n", attr);
+}
+
+int MacOSXDevice::command(int argc, const char*const* argv)
+{
+ //fprintf(stderr,"### MacOSXDevice::command : argv[1] = %s\n", argv[1]);
+ Tcl& tcl = Tcl::instance();
+ if (argc == 3) {
+ if (strcmp(argv[1], "open") == 0) {
+ TclObject* o = 0;
+ o = new MacOSXGrabber(argv[2], nickname_);
+ if (o != 0)
+ tcl.result(o->name());
+ return(TCL_OK);
+ }
+ }
+ return(InputDevice::command(argc, argv));
+}
+
+
+class MacOSXScanner {
+public:
+ MacOSXScanner();
+};
+
+// Instantiate the video capture device.
+#if 0
+// this doesn't work with MacOS X 10.3 (QuickTime pthread problem),
+// but works fine with 10.4
+static MacOSXScanner find_capture_devices;
+#else
+// this C function is called from main as a workaround for MacOS X 10.3
+extern "C" void find_macosx_capture_devices(void) {
+ MacOSXScanner macOSXScanner;
+}
+#endif
+
+MacOSXScanner::MacOSXScanner()
+{
+ char *attr;
+ SeqGrabComponent seqGrab;
+ SGChannel sgchanVideo;
+ SGDeviceList sgdeviceList;
+ OSErr err = noErr;
+
+ char *myDev = getenv("VIC_DEVICE");
+ if (myDev != 0) {
+
+ }
+ seqGrab = OpenDefaultComponent(SeqGrabComponentType, 0);
+ if (seqGrab != NULL)
+ err = SGInitialize(seqGrab);
+ if (err == noErr)
+ err = SGSetGWorld(seqGrab, NULL, NULL);
+ if (err == noErr)
+ err = SGSetDataRef(seqGrab, 0, 0, seqGrabDontMakeMovie);
+ err = SGNewChannel(seqGrab, VideoMediaType, &sgchanVideo);
+ if (err != noErr) {
+ // clean up on failure
+ SGDisposeChannel(seqGrab, sgchanVideo);
+ return;
+ }
+ if (err == noErr) {
+ SGGetChannelDeviceList(sgchanVideo, sgDeviceListIncludeInputs, &sgdeviceList);
+ char dev_str[64];
+ char port_str[64];
+ for (int i = 0; i < (*sgdeviceList)->count; i++) {
+ // ignore devices that are currently unavailable
+ if ((sgDeviceNameFlagDeviceUnavailable & (*sgdeviceList)->entry[i].flags) == 0) {
+ attr = new char[512];
+ strcpy(attr, "size {large small cif} format {411 422 cif} type {ntsc pal secam} port {");
+ p2cstrcpy(dev_str, (*sgdeviceList)->entry[i].name);
+ if ((*sgdeviceList)->entry[i].inputs != NULL) {
+ fprintf(stderr,"OSX Capture: \"%s\" has %i input(s)\n", dev_str, (*(((*sgdeviceList)->entry[i]).inputs))->count);
+ for (int j = 0; j < (*(((*sgdeviceList)->entry[i]).inputs))->count; j++) {
+ p2cstrcpy(port_str, (*(((*sgdeviceList)->entry[i]).inputs))->entry[j].name);
+ if (strchr(port_str, ' ')) {
+ strcat(attr, "\"");
+ strcat(attr, port_str);
+ strcat(attr, "\" ");
+ } else {
+ strcat(attr, port_str);
+ strcat(attr, " ");
+ }
+ }
+ } else {
+ fprintf(stderr,"OSX Capture: \"%s\" has no inputs\n", dev_str);
+ }
+ strcat(attr, "}");
+
+ char *device = new char[strlen(dev_str) + 1];
+ strcpy(device, dev_str);
+ new MacOSXDevice(device, attr);
+ //delete [] device;
+ //delete [] attr;
+ } else {
+ fprintf(stderr,"OSX Capture: \"%s\" unavailable, ignoring\n", dev_str);
+ }
+ }
+
+ }
+
+ SGDisposeDeviceList(seqGrab, sgdeviceList);
+ SGDisposeChannel(seqGrab, sgchanVideo);
+ CloseComponent(seqGrab);
+}
+
+
+void MacOSXGrabber::packedYUYV422_to_planarYUYV422(char *dest, char *src)
+{
+ int i;
+ char *s, *y,*u,*v;
+ unsigned int a, *srca;
+
+ srca = (unsigned int *)src;
+
+ i = (width_ * height_)/2;
+ s = src;
+ y = dest;
+ u = y + width_ * height_;
+ v = u + width_ * height_ / 2;
+
+ while (--i) {
+ a = *(srca++);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ *(y++) = a & 0xff;
+ a >>= 8;
+ *(u++) = a & 0xff;
+ a >>= 8;
+ *(y++) = a & 0xff;
+ a >>= 8;
+ *(v++) = a & 0xff;
+#else
+ *(v++) = a & 0xff;
+ a >>= 8;
+ *(y++) = a & 0xff;
+ a >>= 8;
+ *(u++) = a & 0xff;
+ a >>= 8;
+ *(y++) = a & 0xff;
+#endif
+ }
+}
+
+void MacOSXGrabber::packedYUYV422_to_planarYUYV411(char *dest, char *src)
+{
+ int a1,b;
+ char *s, *y,*u,*v;
+ unsigned int a, *srca;
+
+ srca = (unsigned int *)src;
+
+ s = src;
+ y = dest;
+ u = y + width_ * height_;
+ v = u + width_ * height_ / 4;
+
+ for (a1 = height_; a1 > 0; a1 -= 2) {
+ for (b = width_; b > 0; b -= 2) {
+ a = *(srca++);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ *(y++) = a & 0xff; a >>= 8;
+ *(u++) = a & 0xff; a >>= 8;
+ *(y++) = a & 0xff; a >>= 8;
+ *(v++) = a & 0xff;
+#else
+ *(v++) = a & 0xff; a >>= 8;
+ *(y+1) = a & 0xff; a >>= 8;
+ *(u++) = a & 0xff; a >>= 8;
+ *(y) = a; y += 2;
+#endif
+ }
+ for (b = width_; b > 0; b -= 2) {
+ a = *(srca++);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ *(y++) = a & 0xff; a >>= 16;
+ *(y++) = a & 0xff;
+#else
+ a >>= 8;
+ *(y+1) = a & 0xff; a >>= 16;
+ *(y) = a; y += 2;
+#endif
+ }
+ }
+}
+
More information about the Sumover-dev
mailing list