/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

/*
 *  video_capture_quick_time.cc
 *
 */


#include "video_capture_quick_time.h"

#include "CriticalSectionWrapper.h"
#include "event_wrapper.h"
#include "thread_wrapper.h"
#include "tick_util.h"
#include "trace.h"
#include <unistd.h>

namespace webrtc
{

VideoCaptureMacQuickTime::VideoCaptureMacQuickTime(WebRtc_Word32 iID) :
    VideoCaptureImpl(iID), // super class constructor
    _id(iID),
    _isCapturing(false),
    _captureCapability(),
    _grabberCritsect(CriticalSectionWrapper::CreateCriticalSection()),
    _videoMacCritsect(CriticalSectionWrapper::CreateCriticalSection()),
    _terminated(true), _grabberUpdateThread(NULL),
    _grabberUpdateEvent(NULL), _captureGrabber(NULL), _captureDevice(NULL),
    _captureVideoType(kVideoUnknown), _captureIsInitialized(false),
    _gWorld(NULL), _captureChannel(0), _captureSequence(NULL),
    _sgPrepared(false), _sgStarted(false), _trueCaptureWidth(0),
    _trueCaptureHeight(0), _captureDeviceList(),
    _captureDeviceListTime(0), _captureCapabilityList()

{
    _captureCapability.width = START_CODEC_WIDTH;
    _captureCapability.height = START_CODEC_HEIGHT;
    memset(_captureDeviceDisplayName, 0, sizeof(_captureDeviceDisplayName));
}

VideoCaptureMacQuickTime::~VideoCaptureMacQuickTime()
{


    VideoCaptureTerminate();

    if (_videoMacCritsect)
    {
        delete _videoMacCritsect;
    }
    if (_grabberCritsect)
    {
        delete _grabberCritsect;
    }

}

WebRtc_Word32 VideoCaptureMacQuickTime::Init(
    const WebRtc_Word32 id, const WebRtc_UWord8* deviceUniqueIdUTF8)
{

    const WebRtc_Word32 nameLength =
        (WebRtc_Word32) strlen((char*) deviceUniqueIdUTF8);
    if (nameLength > kVideoCaptureUniqueNameLength)
        return -1;

    // Store the device name
    _deviceUniqueId = new WebRtc_UWord8[nameLength + 1];
    memset(_deviceUniqueId, 0, nameLength + 1);
    memcpy(_deviceUniqueId, deviceUniqueIdUTF8, nameLength + 1);

    // Check OSX version
    OSErr err = noErr;
    long version;

    _videoMacCritsect->Enter();
    if (!_terminated)
    {
        _videoMacCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Already Initialized", __FUNCTION__, __LINE__);
        return -1;
    }

    err = Gestalt(gestaltSystemVersion, &version);
    if (err != noErr)
    {
        _videoMacCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Could not retrieve OS version", __FUNCTION__,
                     __LINE__);
        return -1;
    }

    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d OS X version: %x,", __FUNCTION__, __LINE__, version);
    if (version < 0x00001040) // Older version than Mac OSX 10.4
    {
        _videoMacCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d OS version not supported", __FUNCTION__, __LINE__);
        return -1;
    }

    err = Gestalt(gestaltQuickTime, &version);
    if (err != noErr)
    {
        _videoMacCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Could not retrieve QuickTime version",
                     __FUNCTION__, __LINE__);
        return -1;
    }

    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d QuickTime version: %x", __FUNCTION__, __LINE__,
                 version);
    if (version < 0x07000000) // QT v. 7.x or newer (QT 5.0.2 0x05020000)
    {
        _videoMacCritsect->Leave();
        return -1;
    }

    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                 "%s:%d EnterMovies()", __FUNCTION__, __LINE__);
    EnterMovies();

    if (VideoCaptureSetCaptureDevice((char*) deviceUniqueIdUTF8,
                                   kVideoCaptureProductIdLength) == -1)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d failed to set capture device: %s", __FUNCTION__,
                     __LINE__, deviceUniqueIdUTF8);
        _videoMacCritsect->Leave();
        return -1;
    }

    _terminated = false;

    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d successful initialization", __FUNCTION__, __LINE__);
    _videoMacCritsect->Leave();

    return 0;
}

WebRtc_Word32 VideoCaptureMacQuickTime::StartCapture(
    const VideoCaptureCapability& capability)
{
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, "%s:%d "
        "capability.width=%d, capability.height=%d ,capability.maxFPS=%d "
        "capability.expectedCaptureDelay=%d, capability.interlaced=%d",
        __FUNCTION__, __LINE__, capability.width, capability.height,
        capability.maxFPS, capability.expectedCaptureDelay,
        capability.interlaced);

    _captureCapability.width = capability.width;
    _captureCapability.height = capability.height;

    if (VideoCaptureRun() == -1)
    {
        return -1;
    }

    return 0;
}

WebRtc_Word32 VideoCaptureMacQuickTime::StopCapture()
{

    if (VideoCaptureStop() == -1)
    {
        return -1;
    }

    return 0;
}

bool VideoCaptureMacQuickTime::CaptureStarted()
{
    return _isCapturing;
}

WebRtc_Word32 VideoCaptureMacQuickTime::CaptureSettings(
    VideoCaptureCapability& settings)
{
	settings.width = _captureCapability.width;
	settings.height = _captureCapability.height;
	settings.maxFPS = 0;
    return 0;
}

int VideoCaptureMacQuickTime::VideoCaptureTerminate()
{
    VideoCaptureStop();

    _videoMacCritsect->Enter();
    if (_terminated)
    {
        _videoMacCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Already terminated", __FUNCTION__, __LINE__);
        return -1;
    }

    _grabberCritsect->Enter();

    // Stop the camera/sequence grabber
    // Resets: _captureSequence, _sgStarted
    StopQuickTimeCapture();

    // Remove local video settings
    // Resets: _gWorld, _captureCapability.width, _captureCapability.height
    RemoveLocalGWorld();
    DisconnectCaptureDevice();

    if (_grabberUpdateThread)
        _grabberUpdateThread->SetNotAlive();

    _grabberCritsect->Leave();

    if (_grabberUpdateEvent)
        _grabberUpdateEvent->Set();

    SLEEP(1);
    _grabberCritsect->Enter();

    if (_grabberUpdateThread)
    {
        _grabberUpdateThread->Stop();
        delete _grabberUpdateThread;
        _grabberUpdateThread = NULL;
    }
    if (_grabberUpdateEvent)
    {
        delete _grabberUpdateEvent;
        _grabberUpdateEvent = NULL;
    }

    // Close the sequence grabber
    if (_captureGrabber)
    {
        SGRelease(_captureGrabber);
        _captureGrabber = NULL;
        CloseComponent(_captureGrabber);
        _captureDevice = NULL;
    }
    _captureVideoType = kVideoUnknown;

    // Delete capture device list
    ListItem* item = _captureDeviceList.First();
    while (item)
    {
        delete static_cast<unsigned char*> (item->GetItem());
        _captureDeviceList.Erase(item);
        item = _captureDeviceList.First();
    }
    _captureDeviceListTime = 0;

    _terminated = true;

    _grabberCritsect->Leave();
    _videoMacCritsect->Leave();

    return 0;
}

int VideoCaptureMacQuickTime::UpdateCaptureSettings(int channel,
                                                    webrtc::VideoCodec& inst,
                                                    bool def)
{

    if (channel < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Invalid channel number: %d", __FUNCTION__,
                     __LINE__, channel);
        return -1;
    }

    // the size has changed, we need to change our setup
    _videoMacCritsect->Enter();

    // Stop capturing, if we are...
    _grabberCritsect->Enter();

    bool wasCapturing = false;
    StopQuickTimeCapture(&wasCapturing);

    // Create a new offline GWorld to receive captured frames
    RemoveLocalGWorld();

    if (CreateLocalGWorld(inst.width, inst.height) == -1)
    {
        _grabberCritsect->Leave();
        _videoMacCritsect->Leave();
        // Error already logged
        return -1;
    }
    _captureCapability.width = inst.width;
    _captureCapability.height = inst.height;

    // Connect the capture device to our offline GWorld
    // if we already have a capture device selected.
    if (_captureDevice)
    {
        DisconnectCaptureDevice();
        if (ConnectCaptureDevice() == -1)
        {
            // Error already logged
            _grabberCritsect->Leave();
            _videoMacCritsect->Leave();
            return -1;
        }
    }

    // Start capture if we did before
    if (wasCapturing)
    {
        if (StartQuickTimeCapture() == -1)
        {
            _grabberCritsect->Leave();
            _videoMacCritsect->Leave();
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "%s:%d Failed to start capturing", __FUNCTION__,
                         __LINE__);
            return -1;
        }
    }
    _grabberCritsect->Leave();
    _videoMacCritsect->Leave();

    return 0;
}

// Creates an off screen graphics world used for converting
// captured video frames if we can't get a format we want.
// Assumed protected by critsects
int VideoCaptureMacQuickTime::CreateLocalGWorld(int width, int height)
{
    if (_gWorld)
    {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                     "%s:%d GWorld already created", __FUNCTION__, __LINE__);
        return -1;
    }
    if (width == 0 || height == 0)
    {
        return -1;
    }

    Rect captureRect;
    captureRect.left = 0;
    captureRect.top = 0;
    captureRect.right = width;
    captureRect.bottom = height;

    // Create a GWorld in same size as we want to send to the codec
    if (QTNewGWorld(&(_gWorld), k2vuyPixelFormat, &captureRect, 0, NULL, 0)
        != noErr)
    {
        return -1;
    }
    _captureCapability.width = width;
    _captureCapability.height = height;

    if (!LockPixels(GetGWorldPixMap(_gWorld)))
    {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Could not lock pixmap. Continuing anyhow",
                     __FUNCTION__, __LINE__);
    }

    CGrafPtr theOldPort;
    GDHandle theOldDevice;
    GetGWorld(&theOldPort, &theOldDevice); // Gets the result from QTGetNewGWorld
    SetGWorld(_gWorld, NULL); // Sets the new GWorld
    BackColor( blackColor); // Changes the color on the graphic port
    ForeColor( whiteColor);
    EraseRect(&captureRect);
    SetGWorld(theOldPort, theOldDevice);

    return 0;
}

// Assumed critsect protected
int VideoCaptureMacQuickTime::RemoveLocalGWorld()
{
    if (!_gWorld)
    {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                     "%s:%d !gWorld", __FUNCTION__, __LINE__);
        return -1;
    }

    DisposeGWorld(_gWorld);
    _gWorld = NULL;
    _captureCapability.width = START_CODEC_WIDTH;
    _captureCapability.height = START_CODEC_HEIGHT;

    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d GWorld has been removed", __FUNCTION__, __LINE__);
    return 0;
}

// ConnectCaptureDevice
// This function prepares the capture device
// with the wanted settings, but the capture
// device isn't started.
//
// Assumed critsect protected
int VideoCaptureMacQuickTime::ConnectCaptureDevice()
{
    // Prepare the capture grabber if a capture device is already set
    if (!_captureGrabber)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d No capture device is selected", __FUNCTION__,
                     __LINE__);
        return -1;
    }
    if (_captureIsInitialized)
    {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Capture device is already initialized",
                     __FUNCTION__, __LINE__);
        return -1;
    }
    if (!_gWorld)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d No GWorld is created", __FUNCTION__, __LINE__);
        return -1;
    }

    OSErr err = noErr;
    long flags = 0;

    // Connect the camera to our offline GWorld
    // We won't use the GWorld if we get the format we want
    // from the camera.
    if (SGSetGWorld(_captureGrabber, _gWorld, NULL ) != noErr)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Could not connect capture device", __FUNCTION__,
                     __LINE__);
        return -1;
    }
    if (SGSetDataRef(_captureGrabber, 0, 0, seqGrabDontMakeMovie) != noErr)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Could not configure capture device", __FUNCTION__,
                     __LINE__);
        return -1;
    }

    // Set our capture callback
    if (SGSetDataProc(_captureGrabber, NewSGDataUPP(SendProcess), (long) this)
        != noErr)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Could not set capture callback. Unable to receive "
                     "frames", __FUNCTION__, __LINE__);
        return -1;
    }

    // Create a video channel to the sequence grabber
    if (SGNewChannel(_captureGrabber, VideoMediaType, &_captureChannel)
        != noErr) // Takes time!!!
    {
        return -1;
    }

    // Get a list with all capture devices to choose the one we want.
    SGDeviceList deviceList = NULL;
    if (SGGetChannelDeviceList(_captureChannel, sgDeviceListIncludeInputs,
                               &deviceList) != noErr)
    {

    }

    int numDevicesTypes = (*deviceList)->count;
    bool captureDeviceFound = false;
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                 "%s:%d Found %d channel devices", __FUNCTION__, __LINE__,
                 numDevicesTypes);

    // Loop through all devices to get the one we want.
    for (int i = 0; i < numDevicesTypes; i++)
    {
        SGDeviceName deviceTypeName = (*deviceList)->entry[i];
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Inspecting device number: %d", __FUNCTION__,
                     __LINE__, i);
        // Get the list with input devices
        if (deviceTypeName.inputs)
        {
            SGDeviceInputList inputList = deviceTypeName.inputs;
            int numInputDev = (*inputList)->count;
            WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                         "%s:%d Device has %d inputs", __FUNCTION__, __LINE__,
                         numInputDev);
            for (int inputDevIndex = 0;
                 inputDevIndex < numInputDev;
                 inputDevIndex++)
            {
                WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture,
                             _id, "%s:%d Inspecting input number: %d",
                             __FUNCTION__, __LINE__, inputDevIndex);
                SGDeviceInputName deviceInputName =
                    (*inputList)->entry[inputDevIndex];
                char devInName[64];
                memset(devInName, 0, 64);

                // SGDeviceInputName::name is a Str63, defined as a Pascal string.
                // (Refer to MacTypes.h)
                CFIndex devInNameLength =
                    PascalStringToCString(deviceInputName.name, devInName,
                                          sizeof(devInName));
                WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture,
                             _id,
                             "%s:%d Converted pascal string with length:%d  "
                             "to: %s", __FUNCTION__, __LINE__,
                             sizeof(devInName), devInName);
                if (devInNameLength < 0)
                {
                    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture,
                                 _id,
                                 "%s:%d Failed to convert device name from "
                                 "pascal string to c string", __FUNCTION__,
                                 __LINE__);
                    return -1;
                }

                if (!strcmp(devInName, _captureDeviceDisplayName))
                {
                    WEBRTC_TRACE(webrtc::kTraceDebug,
                                 webrtc::kTraceVideoCapture, _id,
                                 "%s:%d We have found our device: %s",
                                 __FUNCTION__, __LINE__,
                                 _captureDeviceDisplayName);

                    if (SGSetChannelDevice(_captureChannel, deviceTypeName.name)
                        != noErr)
                    {
                        WEBRTC_TRACE(webrtc::kTraceError,
                                     webrtc::kTraceVideoCapture, _id,
                                     "%s:%d Could not set capture device type: "
                                     "%s",__FUNCTION__, __LINE__,
                                     deviceTypeName.name);
                        return -1;
                    }

                    WEBRTC_TRACE(webrtc::kTraceInfo,
                                 webrtc::kTraceVideoCapture, _id,
                                 "%s:%d Capture device type is: %s",
                                 __FUNCTION__, __LINE__, deviceTypeName.name);
                    if (SGSetChannelDeviceInput(_captureChannel, inputDevIndex)
                        != noErr)
                    {
                        WEBRTC_TRACE(webrtc::kTraceError,
                                     webrtc::kTraceVideoCapture, _id,
                                     "%s:%d Could not set SG device",
                                     __FUNCTION__, __LINE__);
                        return -1;
                    }

                    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture,
                                 _id,
                                 "%s:%d Capture device: %s has successfully "
                                 "been set", __FUNCTION__, __LINE__,
                                 _captureDeviceDisplayName);
                    captureDeviceFound = true;
                    break;
                }
            }
            if (captureDeviceFound)
            {
                WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture,
                             _id,
                             "%s:%d Capture device found, breaking from loops",
                             __FUNCTION__, __LINE__);
                break;
            }
        }
    }
    err = SGDisposeDeviceList(_captureGrabber, deviceList);

    if (!captureDeviceFound)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Failed to find capture device: %s. Returning -1",
                     __FUNCTION__, __LINE__, _captureDeviceDisplayName);
        return -1;
    }

    // Set the size we want from the capture device
    Rect captureSize;
    captureSize.left = 0;
    captureSize.top = 0;
    captureSize.right = _captureCapability.width;
    captureSize.bottom = _captureCapability.height;

    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d Using capture rect: l:%d t:%d r:%d b:%d", __FUNCTION__,
                 __LINE__, captureSize.left, captureSize.top,
                 captureSize.right, captureSize.bottom);

    err = SGSetChannelBounds(_captureChannel, &captureSize);
    if (err == noErr)
    {
        err = SGSetChannelUsage(_captureChannel, flags | seqGrabRecord);
    }
    if (err != noErr)
    {
        SGDisposeChannel(_captureGrabber, _captureChannel);
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Error setting SG channel to device", __FUNCTION__,
                     __LINE__);
        return -1;
    }

    // Find out what video format we'll get from the capture device.
    OSType compType;
    err = SGGetVideoCompressorType(_captureChannel, &compType);

    // Convert the Apple video format name to a VideoCapture name.
    if (compType == k2vuyPixelFormat)
    {
        _captureVideoType = kVideoUYVY;
        WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Device delivers UYUV formatted frames",
                     __FUNCTION__, __LINE__);
    }
    else if (compType == kYUVSPixelFormat)
    {
        WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Device delivers YUY2 formatted frames",
                     __FUNCTION__, __LINE__);
        _captureVideoType = kVideoYUY2;
    }
    else
    {
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Device delivers frames in an unknown format: 0x%x. "
                     "Consult QuickdrawTypes.h",
                     __FUNCTION__, __LINE__, compType);
        WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Device delivers frames in an unknown format.",
                     __FUNCTION__, __LINE__);
        _captureVideoType = kVideoUnknown;
    }

    if (SGPrepare(_captureGrabber, false, true) != noErr)
    {
        _grabberCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Error starting sequence grabber", __FUNCTION__,
                     __LINE__);
        return -1;
    }

    // Try to set the codec size as capture size.
    err = SGSetChannelBounds(_captureChannel, &captureSize);

    // Check if we really will get the size we asked for.
    ImageDescriptionHandle imageDesc = (ImageDescriptionHandle) NewHandle(0);
    err = SGGetChannelSampleDescription(_captureChannel, (Handle) imageDesc);

    _trueCaptureWidth = (**imageDesc).width;
    _trueCaptureHeight = (**imageDesc).height;

    DisposeHandle((Handle) imageDesc);

    _captureIsInitialized = true;
    _sgPrepared = true;

    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d Success starting sequence grabber", __FUNCTION__,
                 __LINE__);

    return 0;
}

// Assumed critsect protected
int VideoCaptureMacQuickTime::DisconnectCaptureDevice()
{
    if (_sgStarted)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Capture device is still running. Returning -1",
                     __FUNCTION__, __LINE__);
        return -1;
    }
    if (!_sgPrepared)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d No capture device connected", __FUNCTION__,
                     __LINE__);
        return -1;
    }

    // Close the capture channel
    SGStop(_captureGrabber);
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                 "%s:%d !!!! releasing sg stuff", __FUNCTION__, __LINE__);
    SGDisposeChannel(_captureGrabber, _captureChannel);
    SGRelease(_captureGrabber);
    CloseComponent(_captureGrabber);

    // Reset all values
    _captureChannel = NULL;
    _captureVideoType = kVideoUnknown;
    _trueCaptureWidth = 0;
    _trueCaptureHeight = 0;
    _captureIsInitialized = false;
    _sgPrepared = false;

    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d Sequence grabber removed", __FUNCTION__, __LINE__);

    return 0;
}

// StartQuickTimeCapture
//
// Actually starts the camera
// 
int VideoCaptureMacQuickTime::StartQuickTimeCapture()
{
    _grabberCritsect->Enter();
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d Attempting to start sequence grabber", __FUNCTION__,
                 __LINE__);

    if (_sgStarted)
    {
        _grabberCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Sequence grabber already started", __FUNCTION__,
                     __LINE__);
        return 0;
    }
    if (!_sgPrepared)
    {
        _grabberCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Sequence grabber not prepared properly",
                     __FUNCTION__, __LINE__);
        return 0;
    }

    if (SGStartRecord(_captureGrabber) != noErr)
    {
        _grabberCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Error starting sequence grabber", __FUNCTION__,
                     __LINE__);
        return -1;
    }

    Rect captureRect = { 0, 0, 0, 0 };
    MatrixRecord scaleMatrix;
    ImageDescriptionHandle imageDesc = (ImageDescriptionHandle) NewHandle(0);

    // Get the sample description for the channel, which is the same as for the
    // capture device
    if (SGGetChannelSampleDescription(_captureChannel, (Handle) imageDesc)
        != noErr)
    {
        _grabberCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Error accessing device properties", __FUNCTION__,
                     __LINE__);
        return -1;
    }

    // Create a scale matrix to scale the captured image
    // Needed if we don't get the size wanted from the camera
    captureRect.right = (**imageDesc).width;
    captureRect.bottom = (**imageDesc).height;

    Rect codecRect;
    codecRect.left = 0;
    codecRect.top = 0;
    codecRect.right = _captureCapability.width;
    codecRect.bottom = _captureCapability.height;
    RectMatrix(&scaleMatrix, &captureRect, &codecRect);

    // Start grabbing images from the capture device to _gWorld
    if (DecompressSequenceBegin(&_captureSequence, imageDesc, _gWorld, NULL,
                                NULL, &scaleMatrix, srcCopy, (RgnHandle) NULL,
                                NULL, codecNormalQuality, bestSpeedCodec)
        != noErr)
    {
        _grabberCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Error starting decompress sequence", __FUNCTION__,
                     __LINE__);
        return -1;
    }
    DisposeHandle((Handle) imageDesc);
    _sgStarted = true;
    _grabberCritsect->Leave();
    return 0;
}

int VideoCaptureMacQuickTime::StopQuickTimeCapture(bool* wasCapturing)
{
    _grabberCritsect->Enter();
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "%s:%d wasCapturing=%d", __FUNCTION__, __LINE__, wasCapturing);

    if (!_sgStarted)
    {
        if (wasCapturing)
            *wasCapturing = false;

        _grabberCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Sequence grabber was never started", __FUNCTION__,
                     __LINE__);
        return 0;
    }

    if (wasCapturing)
        *wasCapturing = true;

    OSErr error = noErr;
    error = SGStop(_captureGrabber);
    CDSequenceEnd(_captureSequence);
    _captureSequence = NULL;
    _sgStarted = false;

    _grabberCritsect->Leave();
    if (error != noErr)
    {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Could not stop sequence grabber", __FUNCTION__,
                     __LINE__);
        return -1;
    }

    return 0;
}

//-------------------------------------------------
//
//  Thread/function to keep capture device working
//
//-------------------------------------------------


//
// GrabberUpdateThread / GrabberUpdateProcess
//
// Called at a certain time interval to tell
// the capture device / SequenceGrabber to
// actually work.
bool VideoCaptureMacQuickTime::GrabberUpdateThread(void* obj)
{
    return static_cast<VideoCaptureMacQuickTime*> (obj)->GrabberUpdateProcess();
}

bool VideoCaptureMacQuickTime::GrabberUpdateProcess()
{
    _grabberUpdateEvent->Wait(30);

    if (_isCapturing == false)
        return false;

    _grabberCritsect->Enter();
    if (_captureGrabber)
    {
        if (SGIdle(_captureGrabber) != noErr)
        {
        }
    }
    _grabberCritsect->Leave();
    return true;
}

//
// VideoCaptureStop
//
// Stops the capture device
//
int VideoCaptureMacQuickTime::VideoCaptureStop()
{
    if (_grabberUpdateThread)
    {
        _grabberUpdateThread->Stop();
    }

    _videoMacCritsect->Enter();
    _grabberCritsect->Enter();
    int retVal = StopQuickTimeCapture();
    _grabberCritsect->Leave();
    _videoMacCritsect->Leave();
    if (retVal == -1)
    {
        return -1;
    }

    _isCapturing = false;
    return 0;
}

//
// VideoCaptureRun
//
// Starts the capture device and creates
// the update thread.
//
int VideoCaptureMacQuickTime::VideoCaptureRun()
{
    _videoMacCritsect->Enter();
    _grabberCritsect->Enter();

    int res = StartQuickTimeCapture();

    // Create the thread for updating sequence grabber if not created earlier
    if (!_grabberUpdateThread)
    {
        _grabberUpdateEvent = EventWrapper::Create();
        _grabberUpdateThread = ThreadWrapper::CreateThread(
            VideoCaptureMacQuickTime::GrabberUpdateThread, this, kHighPriority);
        unsigned int id;
        _grabberUpdateThread->Start(id);
    }
    else
    {
        unsigned int id;
        _grabberUpdateThread->Start(id);
    }

    _grabberCritsect->Leave();
    _videoMacCritsect->Leave();

    _isCapturing = true;
    return res;
}

// ---------------------------------------------------------------------- 
//
// SendProcess
// sequence grabber data procedure
//
// This function is called by the capture device as soon as a new
// frame is available.
//
//
// SendFrame
//
// The non-static function used by the capture device callback
//
// Input:
//        sgChannel: the capture device channel generating the callback
//        data:      the video frame
//        length:    the data length in bytes
//        grabTime:  time stamp generated by the capture device / sequece grabber
//
// ----------------------------------------------------------------------

OSErr VideoCaptureMacQuickTime::SendProcess(SGChannel sgChannel, Ptr p,
                                            long len, long* /*offset*/,
                                            long /*chRefCon*/, TimeValue time,
                                            short /*writeType*/, long refCon)
{
    VideoCaptureMacQuickTime* videoEngine =
        reinterpret_cast<VideoCaptureMacQuickTime*> (refCon);
    return videoEngine->SendFrame(sgChannel, (char*) p, len, time);
}

int VideoCaptureMacQuickTime::SendFrame(SGChannel /*sgChannel*/, char* data,
                                        long length, TimeValue /*grabTime*/)
{
    if (!_sgPrepared)
    {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Sequence Grabber is not initialized", __FUNCTION__,
                     __LINE__);
        return 0;
    }

    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                 "%s:%d Frame has been delivered\n", __FUNCTION__, __LINE__);

    CodecFlags ignore;
    _grabberCritsect->Enter();
    if (_gWorld)
    {
        // Will be set to true if we don't recognize the size and/or video
        // format.
        bool convertFrame = false;
        WebRtc_Word32 width = 352;
        WebRtc_Word32 height = 288;
        WebRtc_Word32 frameSize = 0;

        VideoCaptureCapability captureCapability;
        captureCapability.width = width;
        captureCapability.height = height;
        captureCapability.maxFPS = 30;

        switch (_captureVideoType)
        {
            case kVideoUYVY:
                captureCapability.rawType = kVideoUYVY;
                break;
            case kVideoYUY2:
                captureCapability.rawType = kVideoYUY2;
                break;
            case kVideoI420:
                captureCapability.rawType = kVideoI420;
                break;
            default:
                captureCapability.rawType = kVideoI420;
                WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture,
                             _id, "%s:%d raw = I420 by default\n",
                             __FUNCTION__, __LINE__);
                break;
        }

        // Convert the camera video type to something VideoEngine can work with
        // Check if we need to downsample the incomming frame.
        switch (_captureVideoType)
        {
            case kVideoUYVY:
            case kVideoYUY2:
                frameSize = (width * height * 16) >> 3; // 16 is for YUY2 format
                if (width == _captureCapability.width || height
                    == _captureCapability.height)
                {
                    // Ok format and size, send the frame to super class
                    IncomingFrame((WebRtc_UWord8*) data,
                                  (WebRtc_Word32) frameSize, captureCapability,
                                  TickTime::MillisecondTimestamp());

                }
                else if (width == _trueCaptureWidth && height
                    == _trueCaptureHeight)
                {
                    // We need to scale the picture to correct size...
                    // This happens for cameras not supporting all sizes.
                    // E.g. older built-in iSight doesn't support QCIF.

                    // Convert the incoming frame into our GWorld.
                    int res =
                        DecompressSequenceFrameS(_captureSequence, data,
                                                 length, 0, &ignore, NULL);
                    if (res != noErr && res != -8976) // 8796 ==  black frame
                    {
                        WEBRTC_TRACE(webrtc::kTraceWarning,
                                     webrtc::kTraceVideoCapture, _id,
                                     "%s:%d Captured black frame. Not "
                                     "processing it", __FUNCTION__, __LINE__);
                        _grabberCritsect->Leave();
                        return 0;
                    }

                    // Copy the frame from the PixMap to our video buffer
                    PixMapHandle pixMap = GetGWorldPixMap(_gWorld);

                    // Lock the image data in the GWorld.
                    LockPixels(pixMap);

                    // Get a pointer to the pixel data.
                    Ptr capturedFrame = GetPixBaseAddr(pixMap);

                    // Send the converted frame out to super class
                    IncomingFrame((WebRtc_UWord8*) data,
                                  (WebRtc_Word32) frameSize, captureCapability,
                                  TickTime::MillisecondTimestamp());

                    // Unlock the image data to get ready for the next frame.
                    UnlockPixels(pixMap);
                }
                else
                {
                    // Not a size we recognize, use the Mac internal scaling...
                    convertFrame = true;
                    WEBRTC_TRACE(webrtc::kTraceDebug,
                                 webrtc::kTraceVideoCapture, _id,
                                 "%s:%d Not correct incoming stream size for "
                                 "the format and configured size",
                                 __FUNCTION__, __LINE__);
                }
                break;
            default:

                // Not a video format we recognize, use the Mac internal scaling
                WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture,
                             _id, "%s:%d Unknown video frame format (default)",
                             __FUNCTION__, __LINE__);
                convertFrame = true;
                break;
        }

        if (convertFrame)
        {
            WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                         "%s:%d Unrecognized frame format. Converting frame",
                         __FUNCTION__, __LINE__);

            // We don't recognise the input format. Convert to UYVY, I420 is not
            // supported on osx. Decompress the grabbed frame into the GWorld,
            // i.e from webcam format to ARGB (RGB24), and extract the frame.
            int res = DecompressSequenceFrameS(_captureSequence, data, length,
                                               0, &ignore, NULL);
            if (res != noErr && res != -8976) // 8796 means a black frame
            {
                _grabberCritsect->Leave();
                return 0;
            }

            // Copy the frame from the PixMap to our video buffer
            PixMapHandle rgbPixMap = GetGWorldPixMap(_gWorld);
            LockPixels(rgbPixMap);
            Ptr capturedFrame = GetPixBaseAddr(rgbPixMap);

            // Get the picture size
            int width = (*rgbPixMap)->bounds.right;
            int height = (*rgbPixMap)->bounds.bottom;

            // 16 is for YUY2 format.
            WebRtc_Word32 frameSize = (width * height * 16) >> 3;

            // Ok format and size, send the frame to super class
            IncomingFrame((WebRtc_UWord8*) data, (WebRtc_Word32) frameSize,
                          captureCapability, TickTime::MillisecondTimestamp());

            UnlockPixels(rgbPixMap);
        }

        // Tell the capture device it's ok to update.
        SGUpdate(_captureGrabber, NULL);
    }
    else
    {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                     "%s:%d No GWorld created, but frames are being delivered",
                     __FUNCTION__, __LINE__);
    }

    _grabberCritsect->Leave();
    return 0;
}

int VideoCaptureMacQuickTime::VideoCaptureInitThreadContext()
{
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                 "%s:%d ", __FUNCTION__, __LINE__);
    _videoMacCritsect->Enter();
    EnterMoviesOnThread( kQTEnterMoviesFlagDontSetComponentsThreadMode);
    _videoMacCritsect->Leave();
    return 0;
}

//
//
//  Functions for handling capture devices
//
//

VideoCaptureMacQuickTime::VideoCaptureMacName::VideoCaptureMacName() :
    _size(0)
{
    memset(_name, 0, kVideoCaptureMacNameMaxSize);
}

int VideoCaptureMacQuickTime::VideoCaptureSetCaptureDevice(
    const char* deviceName, int size)
{


    _videoMacCritsect->Enter();
    bool wasCapturing = false;

    _grabberCritsect->Enter();
    if (_captureGrabber)
    {
        // Stop grabbing, disconnect and close the old capture device
        StopQuickTimeCapture(&wasCapturing);
        DisconnectCaptureDevice();
        CloseComponent(_captureGrabber);
        _captureDevice = NULL;
        _captureGrabber = NULL;
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d Old capture device removed", __FUNCTION__,
                     __LINE__);
    }

    if (deviceName == NULL || size == 0)
    {
        _grabberCritsect->Leave();
        _videoMacCritsect->Leave();
        return 0;
    }

    if (size < 0)
    {
        _grabberCritsect->Leave();
        _videoMacCritsect->Leave();
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "%s:%d 'size' is not valid", __FUNCTION__, __LINE__);
        return 0;
    }

    ComponentDescription compCaptureType;

    // Define the component we want to open
    compCaptureType.componentType = SeqGrabComponentType;
    compCaptureType.componentSubType = 0;
    compCaptureType.componentManufacturer = 0;
    compCaptureType.componentFlags = 0;
    compCaptureType.componentFlagsMask = 0;

    long numSequenceGrabbers = CountComponents(&compCaptureType);

    // loop through the available grabbers and open the first possible
    for (int i = 0; i < numSequenceGrabbers; i++)
    {
        _captureDevice = FindNextComponent(0, &compCaptureType);
        _captureGrabber = OpenComponent(_captureDevice);
        if (_captureGrabber != NULL)
        {
            // We've found a sequencegrabber that we could open
            if (SGInitialize(_captureGrabber) != noErr)
            {
                _grabberCritsect->Leave();
                _videoMacCritsect->Leave();
                WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture,
                             _id,
                             "%s:%d Could not initialize sequence grabber",
                             __FUNCTION__, __LINE__);
                return -1;
            }
            break;
        }
        if (i == numSequenceGrabbers - 1)
        {
            // Couldn't open a sequence grabber
            _grabberCritsect->Leave();
            _videoMacCritsect->Leave();
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "%s:%d Could not open a sequence grabber",
                         __FUNCTION__, __LINE__);
            return -1;
        }
    }

    if (!_gWorld)
    {
        // We don't have a GWorld. Create one to enable early preview
        // without calling SetSendCodec
        if (CreateLocalGWorld(_captureCapability.width,
                              _captureCapability.height) == -1)
        {
            // Error already logged
            _grabberCritsect->Leave();
            _videoMacCritsect->Leave();
            return -1;
        }
    }
    // Connect the camera with our GWorld
    int cpySize = size;
    if ((unsigned int) size > sizeof(_captureDeviceDisplayName))
    {
        cpySize = sizeof(_captureDeviceDisplayName);
    }
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                 "%s:%d Copying %d chars from deviceName to "
                 "_captureDeviceDisplayName (size=%d)\n",
                 __FUNCTION__, __LINE__, cpySize, size);
    memcpy(_captureDeviceDisplayName, deviceName, cpySize);
    if (ConnectCaptureDevice() == -1)
    {
        // Error already logged
        _grabberCritsect->Leave();
        _videoMacCritsect->Leave();
        return -1;
    }

    if (StartQuickTimeCapture() == -1)
    {
        // Error already logged
        _grabberCritsect->Leave();
        _videoMacCritsect->Leave();
        return -1;
    }
    _grabberCritsect->Leave();
    _videoMacCritsect->Leave();
    return 0;
}

bool VideoCaptureMacQuickTime::IsCaptureDeviceSelected()
{
    _grabberCritsect->Leave();
    return (_captureIsInitialized) ? true : false;
    _grabberCritsect->Leave();
}

/**
 Convert a Pascal string to a C string.
 
 \param[in]  pascalString
 Pascal string to convert. Pascal strings contain the number of 
 characters in the first byte and are not null-terminated.
 
 \param[out] cString
 The C string buffer into which to copy the converted string.
 
 \param[in]  bufferSize
 The size of the C string buffer in bytes.
 
 \return The number of characters in the string on success and -1 on failure.
 */
CFIndex VideoCaptureMacQuickTime::PascalStringToCString(
    const unsigned char* pascalString, char* cString, CFIndex bufferSize)
{

    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, 0,
                 "%s:%d Converting pascal string to c string", __FUNCTION__,
                 __LINE__);
    if (pascalString == NULL)
    {
        return -1;
    }

    if (cString == NULL)
    {
        return -1;
    }

    if (bufferSize == 0)
    {
        return -1;
    }

    CFIndex cStringLength = 0;
    CFIndex maxStringLength = bufferSize - 1;

    CFStringRef cfString = CFStringCreateWithPascalString(
        NULL, pascalString, kCFStringEncodingMacRoman);
    if (cfString == NULL)
    {
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, 0,
                     "%s:%d Error in CFStringCreateWithPascalString()",
                     __FUNCTION__, __LINE__);
        CFRelease(cfString);
        return -1;
    }

    CFIndex cfLength = CFStringGetLength(cfString);
    cStringLength = cfLength;
    if (cfLength > maxStringLength)
    {
        cStringLength = maxStringLength;
    }

    Boolean success = CFStringGetCString(cfString, cString, bufferSize,
                                         kCFStringEncodingMacRoman);

    // Ensure the problem isn't insufficient buffer length.
    // This is fine; we will return a partial string.
    if (success == false && cfLength <= maxStringLength)
    {
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, 0,
                     "%s:%d Error in CFStringGetCString()", __FUNCTION__,
                     __LINE__);
        CFRelease(cfString);
        return -1;
    }

    CFRelease(cfString);
    return cStringLength;
}
}  // namespace webrtc
