/*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* 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.
*
* Description:
*/
#include "aml_vcodec_vfm.h"
#include "aml_vcodec_vfq.h"
#include "aml_vcodec_util.h"
#include "aml_vcodec_adapt.h"
#include <media/v4l2-mem2mem.h>

#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_VIDEO_COMPOSER
#include <trace/events/meson_atrace.h>

#define RECEIVER_NAME	"v4l2-video"
#define PROVIDER_NAME	"v4l2-video"

static struct vframe_s *vdec_vf_peek(void *op_arg)
{
	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;

	return vfq_peek(&vfm->vf_que);
}

static struct vframe_s *vdec_vf_get(void *op_arg)
{
	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;

	return vfq_pop(&vfm->vf_que);
}

static void vdec_vf_put(struct vframe_s *vf, void *op_arg)
{
	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;

	/* If the video frame from amvide that means */
	/* the data has been processed and finished, */
	/* then push back to VDA. thus we don't put the */
	/* buffer to the decoder directly.*/

	//vf_put(vf, vfm->recv_name);
	//vf_notify_provider(vfm->recv_name, VFRAME_EVENT_RECEIVER_PUT, NULL);

	if (vfq_level(&vfm->vf_que_recycle) > POOL_SIZE - 1) {
		v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "vfq full.\n");
		return;
	}

	atomic_set(&vf->use_cnt, 1);

	vfq_push(&vfm->vf_que_recycle, vf);

	/* schedule capture work. */
	vdec_device_vf_run(vfm->ctx);
}

static int vdec_event_cb(int type, void *data, void *private_data)
{

	if (type & VFRAME_EVENT_RECEIVER_PUT) {
	} else if (type & VFRAME_EVENT_RECEIVER_GET) {
	} else if (type & VFRAME_EVENT_RECEIVER_FRAME_WAIT) {
	}
	return 0;
}

static int vdec_vf_states(struct vframe_states *states, void *op_arg)
{
	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;

	states->vf_pool_size	= POOL_SIZE;
	states->buf_recycle_num	= 0;
	states->buf_free_num	= POOL_SIZE - vfq_level(&vfm->vf_que);
	states->buf_avail_num	= vfq_level(&vfm->vf_que);

	return 0;
}

void video_vf_put(char *receiver, struct vdec_v4l2_buffer *fb, int id)
{
	struct vframe_provider_s *vfp = vf_get_provider(receiver);
	struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;

	ATRACE_COUNTER("v4l2_to", vf->index_disp);

	v4l_dbg(0, V4L_DEBUG_CODEC_OUTPUT,
		"[%d]: TO   (%s) vf: %p, idx: %d, "
		"Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
		id, vfp->name, vf, vf->index,
		fb->m.mem[0].addr, fb->m.mem[0].size,
		fb->m.mem[1].addr, fb->m.mem[1].size,
		fb->m.mem[2].addr, fb->m.mem[2].size);

	if (vfp && vf && atomic_dec_and_test(&vf->use_cnt))
		vf_put(vf, receiver);
}

static const struct vframe_operations_s vf_provider = {
	.peek		= vdec_vf_peek,
	.get		= vdec_vf_get,
	.put		= vdec_vf_put,
	.event_cb	= vdec_event_cb,
	.vf_states	= vdec_vf_states,
};

static int video_receiver_event_fun(int type, void *data, void *private_data)
{
	int ret = 0;
	struct vframe_states states;
	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)private_data;

	switch (type) {
	case VFRAME_EVENT_PROVIDER_UNREG: {
		if (vf_get_receiver(vfm->prov_name)) {
			v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
				"unreg %s provider.\n",
				vfm->prov_name);
			vf_unreg_provider(&vfm->vf_prov);
		}

		break;
	}

	case VFRAME_EVENT_PROVIDER_START: {
		if (vf_get_receiver(vfm->prov_name)) {
			v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
				"reg %s provider.\n",
				vfm->prov_name);
			vf_provider_init(&vfm->vf_prov, vfm->prov_name,
				&vf_provider, vfm);
			vf_reg_provider(&vfm->vf_prov);
			vf_notify_receiver(vfm->prov_name,
				VFRAME_EVENT_PROVIDER_START, NULL);
		}

		vfq_init(&vfm->vf_que, POOL_SIZE + 1, &vfm->pool[0]);
		vfq_init(&vfm->vf_que_recycle, POOL_SIZE + 1, &vfm->pool_recycle[0]);

		break;
	}

	case VFRAME_EVENT_PROVIDER_QUREY_STATE: {
		vdec_vf_states(&states, vfm);
		if (states.buf_avail_num > 0)
			ret = RECEIVER_ACTIVE;
		break;
	}

	case VFRAME_EVENT_PROVIDER_VFRAME_READY: {
		if (vfq_level(&vfm->vf_que) > POOL_SIZE - 1)
			ret = -1;

		if (!vf_peek(vfm->recv_name))
			ret = -1;

		vfm->vf = vf_get(vfm->recv_name);
		if (!vfm->vf)
			ret = -1;

		if (ret < 0) {
			v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "receiver vf err.\n");
			break;
		}

		vfq_push(&vfm->vf_que, vfm->vf);

		if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO) {
			vf_notify_receiver(vfm->prov_name,
				VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
			break;
		}

		/* schedule capture work. */
		vdec_device_vf_run(vfm->ctx);

		break;
	}

	default:
		v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
			"the vf event is %d", type);
	}

	return ret;
}

static const struct vframe_receiver_op_s vf_receiver = {
	.event_cb	= video_receiver_event_fun
};

struct vframe_s *peek_video_frame(struct vcodec_vfm_s *vfm)
{
	if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO)
		return vfq_peek(&vfm->vf_que_recycle);
	else
		return vfq_peek(&vfm->vf_que);
}

struct vframe_s *get_video_frame(struct vcodec_vfm_s *vfm)
{
	if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO)
		return vfq_pop(&vfm->vf_que_recycle);
	else
		return vfq_pop(&vfm->vf_que);
}

int vcodec_vfm_init(struct vcodec_vfm_s *vfm)
{
	int ret;

	snprintf(vfm->recv_name, VF_NAME_SIZE, "%s-%d",
		RECEIVER_NAME, vfm->ctx->id);
	snprintf(vfm->prov_name, VF_NAME_SIZE, "%s-%d",
		PROVIDER_NAME, vfm->ctx->id);

	vfm->ada_ctx->recv_name = vfm->recv_name;

	vf_receiver_init(&vfm->vf_recv, vfm->recv_name, &vf_receiver, vfm);
	ret = vf_reg_receiver(&vfm->vf_recv);

	vfm->vfm_initialized = ret ? false : true;

	return ret;
}

void vcodec_vfm_release(struct vcodec_vfm_s *vfm)
{
	if (vfm->vfm_initialized)
		vf_unreg_receiver(&vfm->vf_recv);
}

