/* $Id$ */
/*
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <pjmedia-videodev/videodev_imp.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/os.h>

#if PJMEDIA_VIDEO_DEV_HAS_QT

#include <Foundation/NSAutoreleasePool.h>
#include <QTKit/QTKit.h>

#define THIS_FILE		"qt_dev.c"
#define DEFAULT_CLOCK_RATE	9000
#define DEFAULT_WIDTH		640
#define DEFAULT_HEIGHT		480
#define DEFAULT_FPS		15

#define kCVPixelFormatType_422YpCbCr8_yuvs 'yuvs'

typedef struct qt_fmt_info
{
    pjmedia_format_id   pjmedia_format;
    unsigned		qt_format;
} qt_fmt_info;

static qt_fmt_info qt_fmts[] =
{
    {PJMEDIA_FORMAT_YUY2, kCVPixelFormatType_422YpCbCr8_yuvs},
    {PJMEDIA_FORMAT_UYVY, kCVPixelFormatType_422YpCbCr8},
};

/* qt device info */
struct qt_dev_info
{
    pjmedia_vid_dev_info	 info;
    char			 dev_id[192];
};

/* qt factory */
struct qt_factory
{
    pjmedia_vid_dev_factory	 base;
    pj_pool_t			*pool;
    pj_pool_t			*dev_pool;
    pj_pool_factory		*pf;

    unsigned			 dev_count;
    struct qt_dev_info		*dev_info;
};

@interface VOutDelegate: NSObject
{
@public
    struct qt_stream *stream;
}
@end

/* Video stream. */
struct qt_stream
{
    pjmedia_vid_dev_stream  base;	    /**< Base stream	       */
    pjmedia_vid_param	    param;	    /**< Settings	       */
    pj_pool_t		   *pool;           /**< Memory pool.          */

    pj_timestamp	    cap_frame_ts;   /**< Captured frame tstamp */
    unsigned		    cap_ts_inc;	    /**< Increment	       */
    
    pjmedia_vid_cb	    vid_cb;         /**< Stream callback.      */
    void		   *user_data;      /**< Application data.     */

    pj_bool_t		    cap_thread_exited;
    pj_bool_t		    cap_thread_initialized;
    pj_thread_desc	    cap_thread_desc;
    pj_thread_t		   *cap_thread;
    
    NSAutoreleasePool			*apool;
    QTCaptureSession			*cap_session;
    QTCaptureDeviceInput		*dev_input;
    QTCaptureDecompressedVideoOutput	*video_output;
    VOutDelegate			*vout_delegate;
};


/* Prototypes */
static pj_status_t qt_factory_init(pjmedia_vid_dev_factory *f);
static pj_status_t qt_factory_destroy(pjmedia_vid_dev_factory *f);
static pj_status_t qt_factory_refresh(pjmedia_vid_dev_factory *f);
static unsigned    qt_factory_get_dev_count(pjmedia_vid_dev_factory *f);
static pj_status_t qt_factory_get_dev_info(pjmedia_vid_dev_factory *f,
					   unsigned index,
					   pjmedia_vid_dev_info *info);
static pj_status_t qt_factory_default_param(pj_pool_t *pool,
					    pjmedia_vid_dev_factory *f,
					    unsigned index,
					    pjmedia_vid_param *param);
static pj_status_t qt_factory_create_stream(
					pjmedia_vid_dev_factory *f,
					pjmedia_vid_param *param,
					const pjmedia_vid_cb *cb,
					void *user_data,
					pjmedia_vid_dev_stream **p_vid_strm);

static pj_status_t qt_stream_get_param(pjmedia_vid_dev_stream *strm,
				       pjmedia_vid_param *param);
static pj_status_t qt_stream_get_cap(pjmedia_vid_dev_stream *strm,
				     pjmedia_vid_dev_cap cap,
				     void *value);
static pj_status_t qt_stream_set_cap(pjmedia_vid_dev_stream *strm,
				     pjmedia_vid_dev_cap cap,
				     const void *value);
static pj_status_t qt_stream_start(pjmedia_vid_dev_stream *strm);
static pj_status_t qt_stream_stop(pjmedia_vid_dev_stream *strm);
static pj_status_t qt_stream_destroy(pjmedia_vid_dev_stream *strm);

/* Operations */
static pjmedia_vid_dev_factory_op factory_op =
{
    &qt_factory_init,
    &qt_factory_destroy,
    &qt_factory_get_dev_count,
    &qt_factory_get_dev_info,
    &qt_factory_default_param,
    &qt_factory_create_stream,
    &qt_factory_refresh
};

static pjmedia_vid_dev_stream_op stream_op =
{
    &qt_stream_get_param,
    &qt_stream_get_cap,
    &qt_stream_set_cap,
    &qt_stream_start,
    NULL,
    NULL,
    &qt_stream_stop,
    &qt_stream_destroy
};


/****************************************************************************
 * Factory operations
 */
/*
 * Init qt_ video driver.
 */
pjmedia_vid_dev_factory* pjmedia_qt_factory(pj_pool_factory *pf)
{
    struct qt_factory *f;
    pj_pool_t *pool;

    pool = pj_pool_create(pf, "qt video", 4000, 4000, NULL);
    f = PJ_POOL_ZALLOC_T(pool, struct qt_factory);
    f->pf = pf;
    f->pool = pool;
    f->base.op = &factory_op;

    return &f->base;
}


/* API: init factory */
static pj_status_t qt_factory_init(pjmedia_vid_dev_factory *f)
{
    return qt_factory_refresh(f);
}

/* API: destroy factory */
static pj_status_t qt_factory_destroy(pjmedia_vid_dev_factory *f)
{
    struct qt_factory *qf = (struct qt_factory*)f;
    pj_pool_t *pool = qf->pool;

    if (qf->dev_pool)
        pj_pool_release(qf->dev_pool);
    qf->pool = NULL;
    if (pool)
        pj_pool_release(pool);

    return PJ_SUCCESS;
}

/* API: refresh the list of devices */
static pj_status_t qt_factory_refresh(pjmedia_vid_dev_factory *f)
{
    struct qt_factory *qf = (struct qt_factory*)f;
    struct qt_dev_info *qdi;
    unsigned i, dev_count = 0;
    NSAutoreleasePool *apool = [[NSAutoreleasePool alloc]init];
    NSArray *dev_array;
    
    if (qf->dev_pool) {
        pj_pool_release(qf->dev_pool);
        qf->dev_pool = NULL;
    }
    
    dev_array = [QTCaptureDevice inputDevices];
    for (i = 0; i < [dev_array count]; i++) {
	QTCaptureDevice *dev = [dev_array objectAtIndex:i];
	if ([dev hasMediaType:QTMediaTypeVideo] ||
	    [dev hasMediaType:QTMediaTypeMuxed])
	{
	    dev_count++;
	}
    }
    
    /* Initialize input and output devices here */
    qf->dev_count = 0;
    qf->dev_pool = pj_pool_create(qf->pf, "qt video", 500, 500, NULL);
    
    qf->dev_info = (struct qt_dev_info*)
    pj_pool_calloc(qf->dev_pool, dev_count,
                   sizeof(struct qt_dev_info));
    for (i = 0; i < [dev_array count]; i++) {
	QTCaptureDevice *dev = [dev_array objectAtIndex:i];
	if ([dev hasMediaType:QTMediaTypeVideo] ||
	    [dev hasMediaType:QTMediaTypeMuxed])
	{
	    unsigned j, k;
	    
	    qdi = &qf->dev_info[qf->dev_count++];
	    pj_bzero(qdi, sizeof(*qdi));
	    [[dev localizedDisplayName] getCString:qdi->info.name
                                        maxLength:sizeof(qdi->info.name)
                                        encoding:
                                        [NSString defaultCStringEncoding]];
	    [[dev uniqueID] getCString:qdi->dev_id
                            maxLength:sizeof(qdi->dev_id)
                            encoding:[NSString defaultCStringEncoding]];
	    strcpy(qdi->info.driver, "QT");	    
	    qdi->info.dir = PJMEDIA_DIR_CAPTURE;
	    qdi->info.has_callback = PJ_TRUE;
            
	    qdi->info.fmt_cnt = 0;
	    for (k = 0; k < [[dev formatDescriptions] count]; k++) {
		QTFormatDescription *desc = [[dev formatDescriptions]
					     objectAtIndex:k];
		for (j = 0; j < PJ_ARRAY_SIZE(qt_fmts); j++) {
		    if ([desc formatType] == qt_fmts[j].qt_format) {
			qdi->info.fmt_cnt++;
			break;
		    }
		}
	    }
	    
	    qdi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
	    qdi->info.fmt = (pjmedia_format*)
            pj_pool_calloc(qf->dev_pool, qdi->info.fmt_cnt,
                           sizeof(pjmedia_format));
	    for (j = k = 0; k < [[dev formatDescriptions] count]; k++) {
		unsigned l;
		QTFormatDescription *desc = [[dev formatDescriptions]
					     objectAtIndex:k];
		for (l = 0; l < PJ_ARRAY_SIZE(qt_fmts); l++) {
		    if ([desc formatType] == qt_fmts[j].qt_format) {
			pjmedia_format *fmt = &qdi->info.fmt[j++];
			pjmedia_format_init_video(fmt,
						  qt_fmts[l].pjmedia_format,
						  DEFAULT_WIDTH,
						  DEFAULT_HEIGHT,
						  DEFAULT_FPS, 1);
			break;
		    }
		}
	    }
            
	    PJ_LOG(4, (THIS_FILE, " dev_id %d: %s", i, qdi->info.name));    
	}
    }
    
    [apool release];
    
    PJ_LOG(4, (THIS_FILE, "qt video has %d devices",
	       qf->dev_count));
    
    return PJ_SUCCESS;
}

/* API: get number of devices */
static unsigned qt_factory_get_dev_count(pjmedia_vid_dev_factory *f)
{
    struct qt_factory *qf = (struct qt_factory*)f;
    return qf->dev_count;
}

/* API: get device info */
static pj_status_t qt_factory_get_dev_info(pjmedia_vid_dev_factory *f,
					   unsigned index,
					   pjmedia_vid_dev_info *info)
{
    struct qt_factory *qf = (struct qt_factory*)f;

    PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);

    pj_memcpy(info, &qf->dev_info[index].info, sizeof(*info));

    return PJ_SUCCESS;
}

/* API: create default device parameter */
static pj_status_t qt_factory_default_param(pj_pool_t *pool,
					    pjmedia_vid_dev_factory *f,
					    unsigned index,
					    pjmedia_vid_param *param)
{
    struct qt_factory *qf = (struct qt_factory*)f;
    struct qt_dev_info *di = &qf->dev_info[index];

    PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);

    PJ_UNUSED_ARG(pool);

    pj_bzero(param, sizeof(*param));
    param->dir = PJMEDIA_DIR_CAPTURE;
    param->cap_id = index;
    param->rend_id = PJMEDIA_VID_INVALID_DEV;
    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
    param->clock_rate = DEFAULT_CLOCK_RATE;
    pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));

    return PJ_SUCCESS;
}

@implementation VOutDelegate
- (void)captureOutput:(QTCaptureOutput *)captureOutput
		      didOutputVideoFrame:(CVImageBufferRef)videoFrame
		      withSampleBuffer:(QTSampleBuffer *)sampleBuffer
		      fromConnection:(QTCaptureConnection *)connection
{
    unsigned size = [sampleBuffer lengthForAllSamples];
    pjmedia_frame frame;

    if (stream->cap_thread_initialized == 0 || !pj_thread_is_registered())
    {
	pj_thread_register("qt_cap", stream->cap_thread_desc,
			   &stream->cap_thread);
	stream->cap_thread_initialized = 1;
	PJ_LOG(5,(THIS_FILE, "Capture thread started"));
    }
    
    if (!videoFrame)
	return;
    
    frame.type = PJMEDIA_TYPE_VIDEO;
    frame.buf = [sampleBuffer bytesForAllSamples];
    frame.size = size;
    frame.bit_info = 0;
    frame.timestamp.u64 = stream->cap_frame_ts.u64;
    
    if (stream->vid_cb.capture_cb)
        (*stream->vid_cb.capture_cb)(&stream->base, stream->user_data,
				     &frame);
    
    stream->cap_frame_ts.u64 += stream->cap_ts_inc;
}
@end

static qt_fmt_info* get_qt_format_info(pjmedia_format_id id)
{
    unsigned i;
    
    for (i = 0; i < PJ_ARRAY_SIZE(qt_fmts); i++) {
        if (qt_fmts[i].pjmedia_format == id)
            return &qt_fmts[i];
    }
    
    return NULL;
}

/* API: create stream */
static pj_status_t qt_factory_create_stream(
					pjmedia_vid_dev_factory *f,
					pjmedia_vid_param *param,
					const pjmedia_vid_cb *cb,
					void *user_data,
					pjmedia_vid_dev_stream **p_vid_strm)
{
    struct qt_factory *qf = (struct qt_factory*)f;
    pj_pool_t *pool;
    struct qt_stream *strm;
    const pjmedia_video_format_info *vfi;
    pj_status_t status = PJ_SUCCESS;
    BOOL success = NO;
    NSError *error;    

    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
		     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
                     param->dir == PJMEDIA_DIR_CAPTURE,
		     PJ_EINVAL);

    vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
    if (!vfi)
        return PJMEDIA_EVID_BADFORMAT;

    /* Create and Initialize stream descriptor */
    pool = pj_pool_create(qf->pf, "qt-dev", 4000, 4000, NULL);
    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);

    strm = PJ_POOL_ZALLOC_T(pool, struct qt_stream);
    pj_memcpy(&strm->param, param, sizeof(*param));
    strm->pool = pool;
    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
    strm->user_data = user_data;
    strm->apool = [[NSAutoreleasePool alloc]init];
    pjmedia_event_publisher_init(&strm->base.epub, PJMEDIA_SIG_VID_DEV_COLORBAR);

    /* Create capture stream here */
    if (param->dir & PJMEDIA_DIR_CAPTURE) {
	const pjmedia_video_format_detail *vfd;
	qt_fmt_info *qfi = get_qt_format_info(param->fmt.id);
	
	if (!qfi) {
	    status = PJMEDIA_EVID_BADFORMAT;
	    goto on_error;
	}

	strm->cap_session = [[QTCaptureSession alloc] init];
	if (!strm->cap_session) {
	    status = PJ_ENOMEM;
	    goto on_error;
	}
	
	/* Open video device */
	QTCaptureDevice *videoDevice = 
	    [QTCaptureDevice deviceWithUniqueID:
			     [NSString stringWithCString:
				       qf->dev_info[param->cap_id].dev_id
				       encoding:
				       [NSString defaultCStringEncoding]]];
	if (!videoDevice || ![videoDevice open:&error]) {
	    status = PJMEDIA_EVID_SYSERR;
	    goto on_error;
	}
	
	/* Add the video device to the session as a device input */	
	strm->dev_input = [[QTCaptureDeviceInput alloc] 
			   initWithDevice:videoDevice];
	success = [strm->cap_session addInput:strm->dev_input error:&error];
	if (!success) {
	    status = PJMEDIA_EVID_SYSERR;
	    goto on_error;
	}
	
	strm->video_output = [[QTCaptureDecompressedVideoOutput alloc] init];
	success = [strm->cap_session addOutput:strm->video_output
				     error:&error];
	if (!success) {
	    status = PJMEDIA_EVID_SYSERR;
	    goto on_error;
	}
	
	vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt,
						     PJ_TRUE);
	[strm->video_output setPixelBufferAttributes:
			    [NSDictionary dictionaryWithObjectsAndKeys:
					  [NSNumber numberWithInt:
						    qfi->qt_format],
					  kCVPixelBufferPixelFormatTypeKey,
					  [NSNumber numberWithInt:
						    vfd->size.w],
					  kCVPixelBufferWidthKey,
					  [NSNumber numberWithInt:
						    vfd->size.h],
					  kCVPixelBufferHeightKey, nil]];

	pj_assert(vfd->fps.num);
	strm->cap_ts_inc = PJMEDIA_SPF2(strm->param.clock_rate, &vfd->fps, 1);
	
	if ([strm->video_output
	     respondsToSelector:@selector(setMinimumVideoFrameInterval)])
	{
	    [strm->video_output setMinimumVideoFrameInterval:
				(1.0f * vfd->fps.denum /
				 (double)vfd->fps.num)];
	}
	
	strm->vout_delegate = [[VOutDelegate alloc]init];
	strm->vout_delegate->stream = strm;
	[strm->video_output setDelegate:strm->vout_delegate];
    }
    
    /* Apply the remaining settings */
    /*    
     if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_SCALE) {
	qt_stream_set_cap(&strm->base,
			  PJMEDIA_VID_DEV_CAP_INPUT_SCALE,
			  &param->fmt);
     }
     */
    /* Done */
    strm->base.op = &stream_op;
    *p_vid_strm = &strm->base;
    
    return PJ_SUCCESS;
    
on_error:
    qt_stream_destroy((pjmedia_vid_dev_stream *)strm);
    
    return status;
}

/* API: Get stream info. */
static pj_status_t qt_stream_get_param(pjmedia_vid_dev_stream *s,
				       pjmedia_vid_param *pi)
{
    struct qt_stream *strm = (struct qt_stream*)s;

    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);

    pj_memcpy(pi, &strm->param, sizeof(*pi));

/*    if (qt_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_INPUT_SCALE,
                            &pi->fmt.info_size) == PJ_SUCCESS)
    {
        pi->flags |= PJMEDIA_VID_DEV_CAP_INPUT_SCALE;
    }
*/
    return PJ_SUCCESS;
}

/* API: get capability */
static pj_status_t qt_stream_get_cap(pjmedia_vid_dev_stream *s,
				     pjmedia_vid_dev_cap cap,
				     void *pval)
{
    struct qt_stream *strm = (struct qt_stream*)s;

    PJ_UNUSED_ARG(strm);

    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);

    if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
    {
        return PJMEDIA_EVID_INVCAP;
//	return PJ_SUCCESS;
    } else {
	return PJMEDIA_EVID_INVCAP;
    }
}

/* API: set capability */
static pj_status_t qt_stream_set_cap(pjmedia_vid_dev_stream *s,
				     pjmedia_vid_dev_cap cap,
				     const void *pval)
{
    struct qt_stream *strm = (struct qt_stream*)s;

    PJ_UNUSED_ARG(strm);

    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);

    if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
    {
	return PJ_SUCCESS;
    }

    return PJMEDIA_EVID_INVCAP;
}

/* API: Start stream. */
static pj_status_t qt_stream_start(pjmedia_vid_dev_stream *strm)
{
    struct qt_stream *stream = (struct qt_stream*)strm;

    PJ_UNUSED_ARG(stream);

    PJ_LOG(4, (THIS_FILE, "Starting qt video stream"));

    if (stream->cap_session) {
	[stream->cap_session startRunning];
    
	if (![stream->cap_session isRunning])
	    return PJ_EUNKNOWN;
	
	CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
    }

    return PJ_SUCCESS;
}

/* API: Stop stream. */
static pj_status_t qt_stream_stop(pjmedia_vid_dev_stream *strm)
{
    struct qt_stream *stream = (struct qt_stream*)strm;

    PJ_UNUSED_ARG(stream);

    PJ_LOG(4, (THIS_FILE, "Stopping qt video stream"));

    if (stream->cap_session && [stream->cap_session isRunning])
	[stream->cap_session stopRunning];
    
    return PJ_SUCCESS;
}


/* API: Destroy stream. */
static pj_status_t qt_stream_destroy(pjmedia_vid_dev_stream *strm)
{
    struct qt_stream *stream = (struct qt_stream*)strm;

    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);

    qt_stream_stop(strm);
    
    if (stream->dev_input && [[stream->dev_input device] isOpen])
	[[stream->dev_input device] close];
    
    if (stream->cap_session) {
	[stream->cap_session release];
	stream->cap_session = NULL;
    }
    if (stream->dev_input) {
	[stream->dev_input release];
	stream->dev_input = NULL;
    }
    if (stream->vout_delegate) {
	[stream->vout_delegate release];
	stream->vout_delegate = NULL;
    }
    if (stream->video_output) {
	[stream->video_output release];
	stream->video_output = NULL;
    }

//    [stream->apool release];
    pj_pool_release(stream->pool);

    return PJ_SUCCESS;
}

#endif	/* PJMEDIA_VIDEO_DEV_HAS_QT */
