/* $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 <pjmedia-videodev/avi_dev.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/rand.h>
#include <pjmedia/vid_codec.h>

#if defined(PJMEDIA_VIDEO_DEV_HAS_AVI) && PJMEDIA_VIDEO_DEV_HAS_AVI != 0 && \
    defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)

#define THIS_FILE		"avi_dev.c"
#define DRIVER_NAME		"AVIDev"
#define DEFAULT_CLOCK_RATE	90000
#define DEFAULT_WIDTH		640
#define DEFAULT_HEIGHT		480
#define DEFAULT_FPS		25

typedef struct avi_dev_strm avi_dev_strm;

/* avi_ device info */
struct avi_dev_info
{
    pjmedia_vid_dev_info	 info;

    pj_pool_t			*pool;
    pj_str_t			 fpath;
    pj_str_t			 title;
    pjmedia_avi_streams		*avi;
    pjmedia_port                *vid;
    avi_dev_strm		*strm;
    pjmedia_vid_codec           *codec;
    pj_uint8_t                  *enc_buf;
    pj_size_t                    enc_buf_size;
};

/* avi_ factory */
struct avi_factory
{
    pjmedia_vid_dev_factory	 base;
    pj_pool_t			*pool;
    pj_pool_factory		*pf;

    unsigned			 dev_count;
    struct avi_dev_info		*dev_info;
};

/* Video stream. */
struct avi_dev_strm
{
    pjmedia_vid_dev_stream	     base;	    /**< Base stream	    */
    pjmedia_vid_dev_param	     param;	    /**< Settings	    */
    pj_pool_t			    *pool;          /**< Memory pool.       */
    struct avi_dev_info		    *adi;

    pjmedia_vid_dev_cb		     vid_cb;	    /**< Stream callback.   */
    void			    *user_data;	    /**< Application data.  */
};


/* Prototypes */
static pj_status_t avi_factory_init(pjmedia_vid_dev_factory *f);
static pj_status_t avi_factory_destroy(pjmedia_vid_dev_factory *f);
static pj_status_t avi_factory_refresh(pjmedia_vid_dev_factory *f);
static unsigned    avi_factory_get_dev_count(pjmedia_vid_dev_factory *f);
static pj_status_t avi_factory_get_dev_info(pjmedia_vid_dev_factory *f,
					     unsigned index,
					     pjmedia_vid_dev_info *info);
static pj_status_t avi_factory_default_param(pj_pool_t *pool,
                                              pjmedia_vid_dev_factory *f,
					      unsigned index,
					      pjmedia_vid_dev_param *param);
static pj_status_t avi_factory_create_stream(
					pjmedia_vid_dev_factory *f,
					pjmedia_vid_dev_param *param,
					const pjmedia_vid_dev_cb *cb,
					void *user_data,
					pjmedia_vid_dev_stream **p_vid_strm);

static pj_status_t avi_dev_strm_get_param(pjmedia_vid_dev_stream *strm,
					  pjmedia_vid_dev_param *param);
static pj_status_t avi_dev_strm_get_cap(pjmedia_vid_dev_stream *strm,
				        pjmedia_vid_dev_cap cap,
				        void *value);
static pj_status_t avi_dev_strm_set_cap(pjmedia_vid_dev_stream *strm,
				        pjmedia_vid_dev_cap cap,
				        const void *value);
static pj_status_t avi_dev_strm_get_frame(pjmedia_vid_dev_stream *strm,
                                          pjmedia_frame *frame);
static pj_status_t avi_dev_strm_start(pjmedia_vid_dev_stream *strm);
static pj_status_t avi_dev_strm_stop(pjmedia_vid_dev_stream *strm);
static pj_status_t avi_dev_strm_destroy(pjmedia_vid_dev_stream *strm);

static void reset_dev_info(struct avi_dev_info *adi);

/* Operations */
static pjmedia_vid_dev_factory_op factory_op =
{
    &avi_factory_init,
    &avi_factory_destroy,
    &avi_factory_get_dev_count,
    &avi_factory_get_dev_info,
    &avi_factory_default_param,
    &avi_factory_create_stream,
    &avi_factory_refresh
};

static pjmedia_vid_dev_stream_op stream_op =
{
    &avi_dev_strm_get_param,
    &avi_dev_strm_get_cap,
    &avi_dev_strm_set_cap,
    &avi_dev_strm_start,
    &avi_dev_strm_get_frame,
    NULL,
    &avi_dev_strm_stop,
    &avi_dev_strm_destroy
};


/****************************************************************************
 * Factory operations
 */

/* API */
PJ_DEF(pj_status_t) pjmedia_avi_dev_create_factory(
				    pj_pool_factory *pf,
				    unsigned max_dev,
				    pjmedia_vid_dev_factory **p_ret)
{
    struct avi_factory *cf;
    pj_pool_t *pool;
    pj_status_t status;

    pool = pj_pool_create(pf, "avidevfc%p", 512, 512, NULL);
    cf = PJ_POOL_ZALLOC_T(pool, struct avi_factory);
    cf->pf = pf;
    cf->pool = pool;
    cf->dev_count = max_dev;
    cf->base.op = &factory_op;

    cf->dev_info = (struct avi_dev_info*)
 		   pj_pool_calloc(cf->pool, cf->dev_count,
 				  sizeof(struct avi_dev_info));

    if (p_ret) {
	*p_ret = &cf->base;
    }

    status = pjmedia_vid_register_factory(NULL, &cf->base);
    if (status != PJ_SUCCESS)
	return status;

    PJ_LOG(4, (THIS_FILE, "AVI dev factory created with %d virtual device(s)",
	       cf->dev_count));

    return PJ_SUCCESS;
}

/* API: init factory */
static pj_status_t avi_factory_init(pjmedia_vid_dev_factory *f)
{
    struct avi_factory *cf = (struct avi_factory*)f;
    unsigned i;

    for (i=0; i<cf->dev_count; ++i) {
	reset_dev_info(&cf->dev_info[i]);
    }

    return PJ_SUCCESS;
}

/* API: destroy factory */
static pj_status_t avi_factory_destroy(pjmedia_vid_dev_factory *f)
{
    struct avi_factory *cf = (struct avi_factory*)f;
    pj_pool_t *pool = cf->pool;

    cf->pool = NULL;
    pj_pool_release(pool);

    return PJ_SUCCESS;
}

/* API: refresh the list of devices */
static pj_status_t avi_factory_refresh(pjmedia_vid_dev_factory *f)
{
    PJ_UNUSED_ARG(f);
    return PJ_SUCCESS;
}

/* API: get number of devices */
static unsigned avi_factory_get_dev_count(pjmedia_vid_dev_factory *f)
{
    struct avi_factory *cf = (struct avi_factory*)f;
    return cf->dev_count;
}

/* API: get device info */
static pj_status_t avi_factory_get_dev_info(pjmedia_vid_dev_factory *f,
					     unsigned index,
					     pjmedia_vid_dev_info *info)
{
    struct avi_factory *cf = (struct avi_factory*)f;

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

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

    return PJ_SUCCESS;
}

/* API: create default device parameter */
static pj_status_t avi_factory_default_param(pj_pool_t *pool,
                                              pjmedia_vid_dev_factory *f,
					      unsigned index,
					      pjmedia_vid_dev_param *param)
{
    struct avi_factory *cf = (struct avi_factory*)f;
    struct avi_dev_info *di = &cf->dev_info[index];

    PJ_ASSERT_RETURN(index < cf->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;
}

/* reset dev info */
static void reset_dev_info(struct avi_dev_info *adi)
{
    /* Close avi streams */
    if (adi->avi) {
	unsigned i, cnt;

	cnt = pjmedia_avi_streams_get_num_streams(adi->avi);
	for (i=0; i<cnt; ++i) {
	    pjmedia_avi_stream *as;

	    as = pjmedia_avi_streams_get_stream(adi->avi, i);
	    if (as) {
		pjmedia_port *port;
		port = pjmedia_avi_stream_get_port(as);
		pjmedia_port_destroy(port);
	    }
	}
	adi->avi = NULL;
    }

    if (adi->codec) {
        pjmedia_vid_codec_close(adi->codec);
        adi->codec = NULL;
    }

    if (adi->pool)
	pj_pool_release(adi->pool);

    pj_bzero(adi, sizeof(*adi));

    /* Fill up with *dummy" device info */
    pj_ansi_strncpy(adi->info.name, "AVI Player", sizeof(adi->info.name)-1);
    pj_ansi_strncpy(adi->info.driver, DRIVER_NAME, sizeof(adi->info.driver)-1);
    adi->info.dir = PJMEDIA_DIR_CAPTURE;
    adi->info.has_callback = PJ_FALSE;
}

/* API: release resources */
PJ_DEF(pj_status_t) pjmedia_avi_dev_free(pjmedia_vid_dev_index id)
{
    pjmedia_vid_dev_factory *f;
    struct avi_factory *cf;
    unsigned local_idx;
    struct avi_dev_info *adi;
    pj_status_t status;

    /* Lookup the factory and local device index */
    status = pjmedia_vid_dev_get_local_index(id, &f, &local_idx);
    if (status != PJ_SUCCESS)
	return status;

    /* The factory must be AVI factory */
    PJ_ASSERT_RETURN(f->op->init == &avi_factory_init, PJMEDIA_EVID_INVDEV);
    cf = (struct avi_factory*)f;

    /* Device index should be valid */
    PJ_ASSERT_RETURN(local_idx <= cf->dev_count, PJ_EBUG);
    adi = &cf->dev_info[local_idx];

    /* Cannot configure if stream is running */
    if (adi->strm)
	return PJ_EBUSY;

    /* Reset */
    reset_dev_info(adi);
    return PJ_SUCCESS;
}

/* API: get param */
PJ_DEF(pj_status_t) pjmedia_avi_dev_get_param(pjmedia_vid_dev_index id,
                                              pjmedia_avi_dev_param *prm)
{
    pjmedia_vid_dev_factory *f;
    struct avi_factory *cf;
    unsigned local_idx;
    struct avi_dev_info *adi;
    pj_status_t status;

    /* Lookup the factory and local device index */
    status = pjmedia_vid_dev_get_local_index(id, &f, &local_idx);
    if (status != PJ_SUCCESS)
	return status;

    /* The factory must be factory */
    PJ_ASSERT_RETURN(f->op->init == &avi_factory_init, PJMEDIA_EVID_INVDEV);
    cf = (struct avi_factory*)f;

    /* Device index should be valid */
    PJ_ASSERT_RETURN(local_idx <= cf->dev_count, PJ_EBUG);
    adi = &cf->dev_info[local_idx];

    pj_bzero(prm, sizeof(*prm));
    prm->path = adi->fpath;
    prm->title = adi->title;
    prm->avi_streams = adi->avi;

    return PJ_SUCCESS;
}

PJ_DEF(void) pjmedia_avi_dev_param_default(pjmedia_avi_dev_param *p)
{
    pj_bzero(p, sizeof(*p));
}

/* API: configure the AVI */
PJ_DEF(pj_status_t) pjmedia_avi_dev_alloc( pjmedia_vid_dev_factory *f,
                                           pjmedia_avi_dev_param *p,
                                           pjmedia_vid_dev_index *p_id)
{
    pjmedia_vid_dev_index id;
    struct avi_factory *cf = (struct avi_factory*)f;
    unsigned local_idx;
    struct avi_dev_info *adi = NULL;
    pjmedia_format avi_fmt;
    const pjmedia_video_format_info *vfi;
    pj_status_t status;

    PJ_ASSERT_RETURN(f && p && p_id, PJ_EINVAL);

    if (p_id)
	*p_id = PJMEDIA_VID_INVALID_DEV;

    /* Get a free dev */
    for (local_idx=0; local_idx<cf->dev_count; ++local_idx) {
	if (cf->dev_info[local_idx].avi == NULL) {
	    adi = &cf->dev_info[local_idx];
	    break;
	}
    }

    if (!adi)
	return PJ_ETOOMANY;

    /* Convert local ID to global id */
    status = pjmedia_vid_dev_get_global_index(&cf->base, local_idx, &id);
    if (status != PJ_SUCCESS)
	return status;

    /* Reset */
    if (adi->pool) {
	pj_pool_release(adi->pool);
    }
    pj_bzero(adi, sizeof(*adi));

    /* Reinit */
    PJ_ASSERT_RETURN(p->path.slen, PJ_EINVAL);
    adi->pool = pj_pool_create(cf->pf, "avidi%p", 512, 512, NULL);


    /* Open the AVI */
    pj_strdup_with_null(adi->pool, &adi->fpath, &p->path);
    status = pjmedia_avi_player_create_streams(adi->pool, adi->fpath.ptr, 0,
                                               &adi->avi);
    if (status != PJ_SUCCESS) {
	goto on_error;
    }

    adi->vid = pjmedia_avi_streams_get_stream_by_media(adi->avi, 0,
                                                       PJMEDIA_TYPE_VIDEO);
    if (!adi->vid) {
	status = PJMEDIA_EVID_BADFORMAT;
	PJ_LOG(4,(THIS_FILE, "Error: cannot find video in AVI %s",
		adi->fpath.ptr));
	goto on_error;
    }

    pjmedia_format_copy(&avi_fmt, &adi->vid->info.fmt);
    vfi = pjmedia_get_video_format_info(NULL, avi_fmt.id);
    /* Check whether the frame is encoded. */
    if (!vfi || vfi->bpp == 0) {
        /* Yes, prepare codec */
        const pjmedia_vid_codec_info *codec_info;
        pjmedia_vid_codec_param codec_param;
	pjmedia_video_apply_fmt_param vafp;

        /* Lookup codec */
        status = pjmedia_vid_codec_mgr_get_codec_info2(NULL,
                                                       avi_fmt.id,
                                                       &codec_info);
        if (status != PJ_SUCCESS || !codec_info)
            goto on_error;

        status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
                                                         &codec_param);
        if (status != PJ_SUCCESS)
            goto on_error;

        /* Open codec */
        status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
                                                   &adi->codec);
        if (status != PJ_SUCCESS)
            goto on_error;

        status = pjmedia_vid_codec_init(adi->codec, adi->pool);
        if (status != PJ_SUCCESS)
            goto on_error;

        codec_param.dir = PJMEDIA_DIR_DECODING;
        codec_param.packing = PJMEDIA_VID_PACKING_WHOLE;
        status = pjmedia_vid_codec_open(adi->codec, &codec_param);
        if (status != PJ_SUCCESS)
            goto on_error;

	/* Allocate buffer */
        avi_fmt.id = codec_info->dec_fmt_id[0];
        vfi = pjmedia_get_video_format_info(NULL, avi_fmt.id);
	pj_bzero(&vafp, sizeof(vafp));
	vafp.size = avi_fmt.det.vid.size;
	status = vfi->apply_fmt(vfi, &vafp);
	if (status != PJ_SUCCESS)
	    goto on_error;

	adi->enc_buf = pj_pool_alloc(adi->pool, vafp.framebytes);
	adi->enc_buf_size = vafp.framebytes;
    }

    /* Calculate title */
    if (p->title.slen) {
	pj_strdup_with_null(adi->pool, &adi->title, &p->title);
    } else {
	char *start = p->path.ptr + p->path.slen;
	pj_str_t tmp;

	while (start >= p->path.ptr) {
	    if (*start == '/' || *start == '\\')
		break;
	    --start;
	}
	tmp.ptr = start + 1;
	tmp.slen = p->path.ptr + p->path.slen - tmp.ptr;
	pj_strdup_with_null(adi->pool, &adi->title, &tmp);
    }

    /* Init device info */
    pj_ansi_strncpy(adi->info.name, adi->title.ptr, sizeof(adi->info.name)-1);
    pj_ansi_strncpy(adi->info.driver, DRIVER_NAME, sizeof(adi->info.driver)-1);
    adi->info.dir = PJMEDIA_DIR_CAPTURE;
    adi->info.has_callback = PJ_FALSE;

    adi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
    adi->info.fmt_cnt = 1;
    pjmedia_format_copy(&adi->info.fmt[0], &avi_fmt);

    /* Set out vars */
    if (p_id)
	*p_id = id;
    p->avi_streams = adi->avi;
    if (p->title.slen == 0)
	p->title = adi->title;

    return PJ_SUCCESS;

on_error:
    if (adi->codec) {
        pjmedia_vid_codec_close(adi->codec);
        adi->codec = NULL;
    }
    if (adi->pool) {
	pj_pool_release(adi->pool);
	adi->pool = NULL;
    }
    pjmedia_avi_dev_free(id);
    return status;
}


/* API: create stream */
static pj_status_t avi_factory_create_stream(
					pjmedia_vid_dev_factory *f,
					pjmedia_vid_dev_param *param,
					const pjmedia_vid_dev_cb *cb,
					void *user_data,
					pjmedia_vid_dev_stream **p_vid_strm)
{
    struct avi_factory *cf = (struct avi_factory*)f;
    pj_pool_t *pool = NULL;
    struct avi_dev_info *adi;
    struct avi_dev_strm *strm;

    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);

    /* Device must have been configured with pjmedia_avi_dev_set_param() */
    adi = &cf->dev_info[param->cap_id];
    PJ_ASSERT_RETURN(adi->avi != NULL, PJ_EINVALIDOP);

    /* Cannot create while stream is already active */
    PJ_ASSERT_RETURN(adi->strm==NULL, PJ_EINVALIDOP);

    /* Create and initialize basic stream descriptor */
    pool = pj_pool_create(cf->pf, "avidev%p", 512, 512, NULL);
    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);

    strm = PJ_POOL_ZALLOC_T(pool, struct avi_dev_strm);
    pj_memcpy(&strm->param, param, sizeof(*param));
    strm->pool = pool;
    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
    strm->user_data = user_data;
    strm->adi = adi;

    pjmedia_format_copy(&param->fmt, &adi->info.fmt[0]);

    /* Done */
    strm->base.op = &stream_op;
    adi->strm = strm;
    *p_vid_strm = &strm->base;

    return PJ_SUCCESS;
}

/* API: Get stream info. */
static pj_status_t avi_dev_strm_get_param(pjmedia_vid_dev_stream *s,
					 pjmedia_vid_dev_param *pi)
{
    struct avi_dev_strm *strm = (struct avi_dev_strm*)s;

    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);

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

    return PJ_SUCCESS;
}

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

    PJ_UNUSED_ARG(strm);
    PJ_UNUSED_ARG(cap);
    PJ_UNUSED_ARG(pval);

    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);

    return PJMEDIA_EVID_INVCAP;
}

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

    PJ_UNUSED_ARG(strm);
    PJ_UNUSED_ARG(cap);
    PJ_UNUSED_ARG(pval);

    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);

    return PJMEDIA_EVID_INVCAP;
}

/* API: Get frame from stream */
static pj_status_t avi_dev_strm_get_frame(pjmedia_vid_dev_stream *strm,
                                         pjmedia_frame *frame)
{
    struct avi_dev_strm *stream = (struct avi_dev_strm*)strm;
    
    if (stream->adi->codec) {
        pjmedia_frame enc_frame;
        pj_status_t status;

        enc_frame.buf = stream->adi->enc_buf;
        enc_frame.size = stream->adi->enc_buf_size;
        status = pjmedia_port_get_frame(stream->adi->vid, &enc_frame);
        if (status != PJ_SUCCESS)
            return status;

        return pjmedia_vid_codec_decode(stream->adi->codec, 1, &enc_frame,
                                        (unsigned)frame->size, frame);
    } else {
        return pjmedia_port_get_frame(stream->adi->vid, frame);
    }
}

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

    PJ_UNUSED_ARG(stream);

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

    return PJ_SUCCESS;
}

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

    PJ_UNUSED_ARG(stream);

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

    return PJ_SUCCESS;
}


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

    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);

    avi_dev_strm_stop(strm);

    stream->adi->strm = NULL;
    stream->adi = NULL;
    pj_pool_release(stream->pool);

    return PJ_SUCCESS;
}

#endif	/* PJMEDIA_VIDEO_DEV_HAS_AVI */
