/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2011-20XX
 *					All rights reserved
 *
 *  This file is part of GPAC / AVCAP video input module
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */


#include <avcap/avcap.h>


#ifdef __cplusplus
extern "C" {
#endif

#include <gpac/modules/service.h>
#include <gpac/modules/codec.h>
/*for GF_STREAM_PRIVATE_SCENE definition*/
#include <gpac/constants.h>
#include <gpac/download.h>

#ifdef __cplusplus
}
#endif


#if !defined(__GNUC__)&& (defined(_WIN32_WCE) || defined (WIN32))
#  pragma comment(lib, "strmiids")
#ifdef _DEBUG
#  pragma comment(lib, "avcapd")
#  pragma comment(lib, "strmbasd")
#else
#  pragma comment(lib, "avcap")
#  pragma comment(lib, "strmbase")
#endif
#  pragma comment(lib, "winmm")
#endif


using namespace avcap;

class GPACCaptureHandler : public CaptureHandler
{
public:
	GPACCaptureHandler(GF_ClientService *service, LPNETCHANNEL channel)
		: m_pService(service), m_pChannel(channel), m_data(NULL)
	{
		memset(&m_pSLHeader, 0, sizeof(GF_SLHeader));
		m_pSLHeader.compositionTimeStampFlag = 1;
	}
	virtual ~GPACCaptureHandler() {
		if (m_data != NULL) {
			gf_free(m_data);
			m_data=NULL;
		}
	}

	GF_ClientService *m_pService;
	LPNETCHANNEL m_pChannel;
	GF_SLHeader m_pSLHeader;

	u32 m_height;
	u32 m_stride;

	char* m_data;

public:
	void AllocData(u32 height, u32 stride) {
		m_height = height;
		m_stride = stride;
		m_data = (char*)gf_malloc(m_height * m_stride);
	}
	/* This method is called by the CaptureManager, when new data was captured.
	 * \param io_buf The buffer, that contains the captured data. */
	void handleCaptureEvent(IOBuffer* io_buf);
};


void GPACCaptureHandler::handleCaptureEvent(IOBuffer* io_buf)
{
	m_pSLHeader.compositionTimeStamp = io_buf->getTimestamp();

	if (m_data) {
		char* data = (char*)io_buf->getPtr();
		for (u32 i=0; i<m_height; i++) {
			memcpy(m_data + (m_height - 1 - i) * m_stride, data + i*m_stride, m_stride);
		}
		gf_service_send_packet(m_pService, m_pChannel, m_data, (u32)io_buf->getValidBytes(), &m_pSLHeader, GF_OK);
	} else {
		gf_service_send_packet(m_pService, m_pChannel, (char *) io_buf->getPtr(), (u32)io_buf->getValidBytes(), &m_pSLHeader, GF_OK);
	}
	io_buf->release();
}

DeviceDescriptor* get_device_descriptor(char *name)
{
	// find the descriptor of the device in the device-list by index
	const DeviceCollector::DeviceList& dl = DEVICE_COLLECTOR::instance().getDeviceList();
	DeviceDescriptor* dd = 0;
	int index = 0;

	for(DeviceCollector::DeviceList::const_iterator i = dl.begin(); i != dl.end(); i++, index++) {
		dd = *i;

		if (!name || !stricmp(name, "default") )
			return dd;
		if (strstr((char *) dd->getName().c_str(), name) != NULL)
			return dd;
	}
	GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[VideoCapture] Cannot find capture driver %s\n", name));
	return NULL;
}


#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
	/*the service we're responsible for*/
	GF_ClientService *service;
	u32 state;

	DeviceDescriptor *device_desc;
	CaptureDevice* device;

	GPACCaptureHandler *video_handler;
	GPACCaptureHandler *audio_handler;

	u32 width, height, pixel_format, stride, out_size, fps;
	u32 default_4cc;
	Bool flip_video;
} AVCapIn;


Bool AVCap_CanHandleURL(GF_InputService *plug, const char *url)
{
	if (!strnicmp(url, "camera://", 9)) return GF_TRUE;
	if (!strnicmp(url, "video://", 8)) return GF_TRUE;
	return GF_FALSE;
}


GF_Err AVCap_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
	GF_ESD *esd;
	GF_BitStream *bs;
	GF_ObjectDescriptor *od;
	const char *opt;
	AVCapIn *vcap = (AVCapIn *) plug->priv;

	if (!vcap || !serv || !url) return GF_BAD_PARAM;

	vcap->state = 0;
	vcap->service = serv;

	opt = gf_opts_get_key("AVCap", "FlipVideo");
	if (opt && !strcmp(opt, "yes"))	vcap->flip_video = GF_TRUE;

	if (!vcap->device_desc) {
		Format *format;
		u32 default_4cc;
		char *name;
		char *params = (char *) strchr(url, '?');
		if (params) params[0] = 0;
		name = (char *) strstr(url, "://");
		if (name) name += 3;
		/* get device by name  */
		vcap->device_desc = get_device_descriptor(name);
		if (params) {
			params[0] = '?';
			params ++;
		}

		if (!vcap->device_desc) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[VideoCapture] Failed to instanciate AVCap\n"));
			gf_service_connect_ack(serv, NULL, GF_REMOTE_SERVICE_ERROR);
			return GF_OK;
		}

		vcap->device_desc->open();
		if ( (!strnicmp(url, "camera://", 9) || !strnicmp(url, "video://", 8)) && !vcap->device_desc->isVideoCaptureDev()) {
			vcap->device_desc->close();
			gf_service_connect_ack(serv, NULL, GF_URL_ERROR);
			return GF_OK;
		}
		else if (!strnicmp(url, "audio://", 8) && !vcap->device_desc->isAudioDev()) {
			vcap->device_desc->close();
			gf_service_connect_ack(serv, NULL, GF_URL_ERROR);
			return GF_OK;
		}
		vcap->device = vcap->device_desc->getDevice();
		if (!vcap->device) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[VideoCapture] Failed to initialize capture device\n"));
			vcap->device_desc->close();
			gf_service_connect_ack(serv, NULL, GF_SERVICE_ERROR);
			return GF_OK;
		}
		vcap->device->getFormatMgr()->setFramerate(30);

		default_4cc = 0;
		opt = gf_opts_get_key("AVCap", "Default4CC");
		if (opt) {
			default_4cc = GF_4CC(opt[0], opt[1], opt[2], opt[3]);
			vcap->device->getFormatMgr()->setFormat(default_4cc);
		}


		while (params) {
			char *sep = (char *) strchr(params, '&');
			if (sep) sep[0] = 0;

			GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[VideoCapture] Set camera option %s\n", params));

			if (!strnicmp(params, "resolution=", 11)) {
				u32 w, h;
				if (sscanf(params+11, "%dx%d", &w, &h)==2) {
					vcap->device->getFormatMgr()->setResolution(w, h);
					GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[VideoCapture] Set resolution to %dx%d\n", w, h));
				}
			}
			else if (!strnicmp(params, "fps=", 4)) {
				u32 fps;
				if (sscanf(params+4, "%d", &fps)==1) {
					vcap->device->getFormatMgr()->setFramerate(fps);
					GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[VideoCapture] Set framerate to %d\n", fps));
				}
			}
			else if (!strnicmp(params, "stereo=", 7)) {
			}
			else if (!strnicmp(params, "mode=", 5)) {
			}
			else if (!strnicmp(params, "fmt=", 4)) {
				if (!strnicmp(params+4, "rgb", 3)) {
					default_4cc = GF_4CC('3', 'B', 'G', 'R');
				}
				else if (!strnicmp(params+4, "yuv", 3)) {
					default_4cc = GF_4CC('V', 'Y', 'U', 'Y');
				}
				else if (strlen(params+4)>=4) {
					default_4cc = GF_4CC(params[4], params[5], params[6], params[7]);
				}
			}

			if (!sep) break;
			sep[0] = '&';
			params = sep+1;
		}

		vcap->width = vcap->device->getFormatMgr()->getWidth();
		vcap->height = vcap->device->getFormatMgr()->getHeight();
		vcap->fps = vcap->device->getFormatMgr()->getFramerate();

		if (default_4cc )
			vcap->device->getFormatMgr()->setFormat(default_4cc );

		format = vcap->device->getFormatMgr()->getFormat();
		switch (format->getFourcc()) {
		case GF_4CC('V', 'Y', 'U', 'Y'):
		case GF_4CC('2', 'Y', 'U', 'Y'):
			vcap->pixel_format = GF_PIXEL_YUY2;
			vcap->stride = 2*vcap->width;
			vcap->out_size = 2*vcap->width*vcap->height;
			break;
		case GF_4CC('2', '1', 'U', 'Y'):
			vcap->pixel_format = GF_PIXEL_I420;
			vcap->stride = (u32)vcap->device->getFormatMgr()->getBytesPerLine();//1.5*vcap->width;//
			vcap->out_size = (u32)vcap->device->getFormatMgr()->getImageSize();//1.5*vcap->width*vcap->height;//
			break;
		case GF_4CC('3', 'B', 'G', 'R'):
			vcap->pixel_format = GF_PIXEL_BGR_24;
			vcap->stride = vcap->device->getFormatMgr()->getBytesPerLine();//1.5*vcap->width;//
			vcap->out_size = (u32)vcap->device->getFormatMgr()->getImageSize();//1.5*vcap->width*vcap->height;//
			break;
		default:
			GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[VideoCapture] Unsupported 4CC %s (%08x) from capture device\n", gf_4cc_to_str(format->getFourcc()), format->getFourcc()));
			vcap->device_desc->close();
			gf_service_connect_ack(serv, NULL, GF_NOT_SUPPORTED);
			return GF_OK;
		}
		GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[VideoCapture] Device configured - resolution %dx%d - Frame Rate %d - Pixel Format %s (Device 4CC %08x) \n", vcap->width, vcap->height, vcap->fps, gf_4cc_to_str(vcap->pixel_format), format->getFourcc()));
	}

	/*ACK connection is OK*/
	gf_service_connect_ack(serv, NULL, GF_OK);


	/*setup object descriptor*/
	od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);

	esd = gf_odf_desc_esd_new(0);
	esd->slConfig->timestampResolution = 1000;
	if (!strnicmp(url, "camera://", 9) || !strnicmp(url, "video://", 8)) {
		od->objectDescriptorID = 1;
		esd->ESID = 1;
		esd->decoderConfig->streamType = GF_STREAM_VISUAL;
	} else {
		od->objectDescriptorID = 2;
		esd->ESID = 2;
		esd->decoderConfig->streamType = GF_STREAM_AUDIO;
	}
	esd->decoderConfig->objectTypeIndication = GPAC_OTI_RAW_MEDIA_STREAM;

	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
	gf_bs_write_u32(bs, vcap->pixel_format);
	gf_bs_write_u16(bs, vcap->width);
	gf_bs_write_u16(bs, vcap->height);
	gf_bs_write_u32(bs, vcap->out_size);
	gf_bs_write_u32(bs, vcap->stride);
	gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength);
	gf_bs_del(bs);

	gf_list_add(od->ESDescriptors, esd);
	gf_service_declare_media(vcap->service, (GF_Descriptor*)od, GF_FALSE);

	return GF_OK;
}

GF_Err AVCap_CloseService(GF_InputService *plug)
{
	AVCapIn *vcap = (AVCapIn *) plug->priv;
	if (vcap->device_desc) {
		vcap->device_desc->close();
		vcap->device_desc = NULL;
	}

	vcap->state = 0;
	gf_service_disconnect_ack(vcap->service, NULL, GF_OK);
	return GF_OK;
}

/*Dummy input just send a file name, no multitrack to handle so we don't need to check sub_url nor expected type*/
static GF_Descriptor *AVCap_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url)
{
	return NULL;
}


GF_Err AVCap_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)
{
	AVCapIn *vcap = (AVCapIn *) plug->priv;

	if (!com->base.on_channel) return GF_NOT_SUPPORTED;

	switch (com->command_type) {
	case GF_NET_CHAN_SET_PULL:
		return GF_NOT_SUPPORTED;
	case GF_NET_CHAN_INTERACTIVE:
		return GF_OK;
	/*since data is file-based, no padding is needed (decoder plugin will handle it itself)*/
	case GF_NET_CHAN_SET_PADDING:
		return GF_OK;
	case GF_NET_CHAN_BUFFER:
		com->buffer.max = com->buffer.min = 500;
		return GF_OK;
	case GF_NET_CHAN_DURATION:
		/*this module is not made for updates, use undefined duration*/
		com->duration.duration = 0;
		return GF_OK;
	case GF_NET_CHAN_PLAY:
		if (vcap->state==0) {
			/*start capture*/
			if (vcap->video_handler)
				vcap->device->getVidCapMgr()->registerCaptureHandler(vcap->video_handler);

			if (vcap->device->getVidCapMgr()->startCapture() != -1)
				vcap->state = 1;
			else
				vcap->device->getVidCapMgr()->removeCaptureHandler();
		}
		return GF_OK;
	case GF_NET_CHAN_STOP:
		if (vcap->state==1) {
			/*stop capture*/
			vcap->device->getVidCapMgr()->removeCaptureHandler();
			vcap->device->getVidCapMgr()->stopCapture();
			vcap->state = 0;
		}
		return GF_OK;
	case GF_NET_CHAN_CONFIG:
		return GF_OK;
	case GF_NET_CHAN_GET_DSI:
		com->get_dsi.dsi = NULL;
		com->get_dsi.dsi_len = 0;
		return GF_OK;
	default:
		break;
	}
	return GF_OK;
}

GF_Err AVCap_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream)
{
	u32 ESID;
	AVCapIn *vcap = (AVCapIn *) plug->priv;

	sscanf(url, "ES_ID=%u", &ESID);
	if (ESID == 1) {
		/*video connect*/
		vcap->video_handler = new GPACCaptureHandler(vcap->service, channel);

		if (vcap->flip_video)
			vcap->video_handler->AllocData(vcap->height, vcap->stride);

		gf_service_connect_ack(vcap->service, channel, GF_OK);
	} else if (ESID == 2) {
		/*audio connect*/
		vcap->audio_handler = new GPACCaptureHandler(vcap->service, channel);
		gf_service_connect_ack(vcap->service, channel, GF_OK);
	} else {
		gf_service_connect_ack(vcap->service, channel, GF_STREAM_NOT_FOUND);
	}
	return GF_OK;
}

GF_Err AVCap_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel)
{
	AVCapIn *vcap = (AVCapIn *) plug->priv;
	if (vcap->video_handler && vcap->video_handler->m_pChannel==channel) {
		delete vcap->video_handler;
		vcap->video_handler = NULL;
	}
	else if (vcap->audio_handler && vcap->audio_handler->m_pChannel==channel) {
		delete vcap->audio_handler;
		vcap->audio_handler = NULL;
	}
	gf_service_disconnect_ack(vcap->service, channel, GF_OK);
	return GF_OK;
}

Bool AVCap_CanHandleURLInService(GF_InputService *plug, const char *url)
{
	return GF_FALSE;
}


GPAC_MODULE_EXPORT
const u32 *QueryInterfaces()
{
	static u32 si [] = {
		GF_NET_CLIENT_INTERFACE,
		0
	};
	return si;
}

GPAC_MODULE_EXPORT
GF_BaseInterface *LoadInterface(u32 InterfaceType)
{
	if (InterfaceType == GF_NET_CLIENT_INTERFACE) {
		AVCapIn *vcap;
		GF_InputService *plug;
		GF_SAFEALLOC(plug, GF_InputService);
		memset(plug, 0, sizeof(GF_InputService));
		GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "Video Capture using libavcap", "gpac distribution")

		plug->RegisterMimeTypes = NULL;
		plug->CanHandleURL = AVCap_CanHandleURL;
		plug->ConnectService = AVCap_ConnectService;
		plug->CloseService = AVCap_CloseService;
		plug->GetServiceDescriptor = AVCap_GetServiceDesc;
		plug->ConnectChannel = AVCap_ConnectChannel;
		plug->DisconnectChannel = AVCap_DisconnectChannel;
		plug->ServiceCommand = AVCap_ServiceCommand;
		plug->CanHandleURLInService = AVCap_CanHandleURLInService;

		GF_SAFEALLOC(vcap, AVCapIn);
		plug->priv = vcap;
		return (GF_BaseInterface *)plug;
	}
	return NULL;
}

GPAC_MODULE_EXPORT
void ShutdownInterface(GF_BaseInterface *bi)
{
	if (bi->InterfaceType==GF_NET_CLIENT_INTERFACE) {
		GF_InputService *ifcn = (GF_InputService*)bi;
		AVCapIn *vcap = (AVCapIn*)ifcn->priv;
		gf_free(vcap);
		gf_free(bi);
	}
}

GPAC_MODULE_STATIC_DECLARATION( avcap )

#ifdef __cplusplus
}
#endif
