/*
 *  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 char* deviceUniqueIdUTF8)
{

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

    // Store the device name
    _deviceUniqueId = new char[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;
    _captureDelay = 120;

    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
