From 45c9ca451ec554a2fef431999093cb67f01eb813 Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Wed, 14 Jan 2009 02:52:27 +0000 Subject: [PATCH] Oh baby, I think I fixed it. - It seems that the camera gets fakey "locked" at the size it was set to when the user grants access to it. - Listen for status changes, don't set things up until the camera is unmuted. - record the size at the time of unmuting. This all seems to work, but I worry about what would happen if access to the camera had already been granted when this code runs. There'd be no way to find out what the size was access was granted. Fortunately, I believe we only use this code presently in a standalone appletty-type-thing, so access is always granted in here. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@752 ed5b42cb-e716-0410-a449-f6a68f950b19 --- .../com/threerings/flash/CameraSnapshotter.as | 62 +++++++++++++------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/src/as/com/threerings/flash/CameraSnapshotter.as b/src/as/com/threerings/flash/CameraSnapshotter.as index 851b67ae..8224f055 100644 --- a/src/as/com/threerings/flash/CameraSnapshotter.as +++ b/src/as/com/threerings/flash/CameraSnapshotter.as @@ -19,7 +19,6 @@ import flash.text.TextField; import com.threerings.util.Log; import com.threerings.util.MethodQueue; -// TODO: use PreferredCamera? public class CameraSnapshotter extends Sprite { /** @@ -78,7 +77,7 @@ public class CameraSnapshotter extends Sprite public function setCamera (camera :Camera) :void { if (_video != null) { - if (_bitmap.parent != null) { + if (_bitmap != null && _bitmap.parent != null) { removeChild(_bitmap); } if (_video.parent != null) { @@ -88,14 +87,36 @@ public class CameraSnapshotter extends Sprite detachVideo(); } + if (_camera != null) { + _camera.removeEventListener(StatusEvent.STATUS, handleCameraStatus); + } + _camera = camera; if (_camera == null) { return; } + _camera.addEventListener(StatusEvent.STATUS, handleCameraStatus); + if (_camera.muted) { + return; + + } else if (_correctionWidth == 0) { + setCorrection(); + } attachVideo(); } + protected function handleCameraStatus (event :StatusEvent) :void + { + if (event.code == "Camera.Unmuted") { + setCorrection(); + attachVideo(); + + } else { + detachVideo(); + } + } + public function getCameraName () :String { return (_camera == null) ? null : _camera.name; @@ -108,7 +129,9 @@ public class CameraSnapshotter extends Sprite public function setMode (width :int, height :int, fps :Number, favorArea :Boolean = true) :void { clearSnapshot(); - removeChild(_video); + if (_video != null) { + removeChild(_video); + } detachVideo(); _camera.setMode(width, height, fps, favorArea); @@ -121,19 +144,8 @@ public class CameraSnapshotter extends Sprite return; // throw exception? } - // NOTE: we specify a matrix to scale the video, because no matter what size it really - // is, it will usually snapshot as if it were at the smallest size. STRANGE. - // Note that this stupid hack doesn't always work, but it mostly works, and it's better - // than leaving everything alone, which mostly didn't work. But then again, - // this code is specifically saying: "fuck up the scale", so if Adobe fixes their - // bug in the future, this will cause broken behavior. - _bitmap.bitmapData.draw(_video); - //new Matrix(_camera.width / 160, 0, 0, _camera.height / 120)); - Log.getLog(this).debug("Camera snapshotted", - "camera.width", _camera.width, "camera.height", _camera.height, - "video.width", _video.width, "video.height", _video.height, - "videoWidth", _video.videoWidth, "videoHeight", _video.videoHeight, - "bitmap.width", _bitmap.width, "bitmap.height", _bitmap.height); + _bitmap.bitmapData.draw(_video, + new Matrix(_camera.width / _correctionWidth, 0, 0, _camera.height / _correctionHeight)); if (_video.parent != null) { removeChild(_video); @@ -146,10 +158,10 @@ public class CameraSnapshotter extends Sprite if (_camera == null) { return; } - if (_bitmap.parent != null) { + if (_bitmap != null && _bitmap.parent != null) { removeChild(_bitmap); } - if (_video.parent == null) { + if (_video != null && _video.parent == null) { addChild(_video); } } @@ -162,6 +174,16 @@ public class CameraSnapshotter extends Sprite return _bitmap.bitmapData; } + /** + * There appears to be a bug with the camera that "locks" it to the size it was at when + * it was unmuted. + */ + protected function setCorrection () :void + { + _correctionWidth = _camera.width; + _correctionHeight = _camera.height; + } + protected function attachVideo () :void { // detach any old first @@ -189,5 +211,9 @@ public class CameraSnapshotter extends Sprite protected var _video :Video; protected var _bitmap :Bitmap; + + protected var _correctionWidth :int; + + protected var _correctionHeight :int; } }