/*
** Copyright (c) 2011 The Linux Foundation. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

/*#error uncomment this for compiler test!*/

//#define ALOG_NDEBUG 0
#define ALOG_NIDEBUG 0
#define LOG_TAG "QCameraHWI_Record"
#include <utils/Log.h>
#include <utils/threads.h>
#include <cutils/properties.h>
#include <fcntl.h>
#include <sys/mman.h>

#include "QCameraStream.h"

#define LIKELY(exp)   __builtin_expect(!!(exp), 1)
#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)

/* QCameraStream_record class implementation goes here*/
/* following code implement the video streaming capture & encoding logic of this class*/
// ---------------------------------------------------------------------------
// QCameraStream_record createInstance()
// ---------------------------------------------------------------------------
namespace android {


QCameraStream* QCameraStream_record::createInstance(int cameraId,
                                      camera_mode_t mode)
{
  ALOGV("%s: BEGIN", __func__);
  QCameraStream* pme = new QCameraStream_record(cameraId, mode);
  ALOGV("%s: END", __func__);
  return pme;
}

// ---------------------------------------------------------------------------
// QCameraStream_record deleteInstance()
// ---------------------------------------------------------------------------
void QCameraStream_record::deleteInstance(QCameraStream *ptr)
{
  ALOGV("%s: BEGIN", __func__);
  if (ptr){
    ptr->release();
    delete ptr;
    ptr = NULL;
  }
  ALOGV("%s: END", __func__);
}

// ---------------------------------------------------------------------------
// QCameraStream_record Constructor
// ---------------------------------------------------------------------------
QCameraStream_record::QCameraStream_record(int cameraId,
                                           camera_mode_t mode)
  :QCameraStream(cameraId,mode),
  mDebugFps(false)
{
  mHalCamCtrl = NULL;
  char value[PROPERTY_VALUE_MAX];
  ALOGV("%s: BEGIN", __func__);

  property_get("persist.debug.sf.showfps", value, "0");
  mDebugFps = atoi(value);

  ALOGV("%s: END", __func__);
}

// ---------------------------------------------------------------------------
// QCameraStream_record Destructor
// ---------------------------------------------------------------------------
QCameraStream_record::~QCameraStream_record() {
  ALOGV("%s: BEGIN", __func__);
  if(mActive) {
    stop();
  }
  if(mInit) {
    release();
  }
  mInit = false;
  mActive = false;
  ALOGV("%s: END", __func__);

}

// ---------------------------------------------------------------------------
// QCameraStream_record Callback from mm_camera
// ---------------------------------------------------------------------------
static void record_notify_cb(mm_camera_ch_data_buf_t *bufs_new,
                              void *user_data)
{
  QCameraStream_record *pme = (QCameraStream_record *)user_data;
  mm_camera_ch_data_buf_t *bufs_used = 0;
  ALOGV("%s: BEGIN", __func__);

  /*
  * Call Function Process Video Data
  */
  pme->processRecordFrame(bufs_new);
  ALOGV("%s: END", __func__);
}

// ---------------------------------------------------------------------------
// QCameraStream_record
// ---------------------------------------------------------------------------
status_t QCameraStream_record::init()
{
  status_t ret = NO_ERROR;
  ALOGV("%s: BEGIN", __func__);

  /*
  *  Acquiring Video Channel
  */
  ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_VIDEO_MASK);
  if (NO_ERROR!=ret) {
    ALOGE("%s ERROR: Can't init native cammera preview ch\n",__func__);
    return ret;
  }

  /*
  * Register the Callback with camera
  */
  (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
                                            record_notify_cb,
                                            MM_CAMERA_REG_BUF_CB_INFINITE,
                                            0,
                                            this);

  mInit = true;
  ALOGV("%s: END", __func__);
  return ret;
}
// ---------------------------------------------------------------------------
// QCameraStream_record
// ---------------------------------------------------------------------------

status_t QCameraStream_record::start()
{
  status_t ret = NO_ERROR;
  ALOGV("%s: BEGIN", __func__);

  Mutex::Autolock lock(mStopCallbackLock);
  if(!mInit) {
    ALOGE("%s ERROR: Record buffer not registered",__func__);
    return BAD_VALUE;
  }

  setFormat(MM_CAMERA_CH_VIDEO_MASK , (cam_format_t)0);
  //mRecordFreeQueueLock.lock();
  //mRecordFreeQueue.clear();
  //mRecordFreeQueueLock.unlock();
  /*
  *  Allocating Encoder Frame Buffers
  */
  ret = initEncodeBuffers();
  if (NO_ERROR!=ret) {
    ALOGE("%s ERROR: Buffer Allocation Failed\n",__func__);
    goto error;
  }

  ret = cam_config_prepare_buf(mCameraId, &mRecordBuf);
  if(ret != MM_CAMERA_OK) {
    ALOGE("%s ERROR: Reg Record buf err=%d\n", __func__, ret);
    ret = BAD_VALUE;
    goto error;
  }else{
    ret = NO_ERROR;
  }

  /*
  * Start Video Streaming
  */
  ret = cam_ops_action(mCameraId, true, MM_CAMERA_OPS_VIDEO, 0);
  if (MM_CAMERA_OK != ret) {
    ALOGE ("%s ERROR: Video streaming start err=%d\n", __func__, ret);
    ret = BAD_VALUE;
    goto error;
  }else{
    ALOGV("%s : Video streaming Started",__func__);
    ret = NO_ERROR;
  }
  mActive = true;
  ALOGV("%s: END", __func__);
  return ret;

error:
  releaseEncodeBuffer();
  ALOGV("%s: END", __func__);
  return ret;
}

void QCameraStream_record::releaseEncodeBuffer() {
  for(int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
    if (NO_ERROR !=
      mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_VIDEO, cnt,
      mCameraId, CAM_SOCK_MSG_TYPE_FD_UNMAPPING))
      ALOGE("%s: Unmapping Video Data Failed", __func__);

    if (mHalCamCtrl->mStoreMetaDataInFrame) {
      struct encoder_media_buffer_type * packet =
          (struct encoder_media_buffer_type  *)
          mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
      native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
      mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->release(
        mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]);

    }
    mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->release(
      mHalCamCtrl->mRecordingMemory.camera_memory[cnt]);
    close(mHalCamCtrl->mRecordingMemory.fd[cnt]);
    mHalCamCtrl->mRecordingMemory.fd[cnt] = -1;

#ifdef USE_ION
    mHalCamCtrl->deallocate_ion_memory(&mHalCamCtrl->mRecordingMemory, cnt);
#endif
  }
  memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
  //mNumRecordFrames = 0;
  delete[] recordframes;
  if (mRecordBuf.video.video.buf.mp)
    delete[] mRecordBuf.video.video.buf.mp;
}

// ---------------------------------------------------------------------------
// QCameraStream_record
// ---------------------------------------------------------------------------
void QCameraStream_record::stop()
{
  status_t ret = NO_ERROR;
  ALOGV("%s: BEGIN", __func__);

  if(!mActive) {
    ALOGE("%s : Record stream not started",__func__);
    return;
  }
  mActive =  false;
  Mutex::Autolock lock(mStopCallbackLock);
#if 0 //mzhu, when stop recording, all frame will be dirty. no need to queue frame back to kernel any more
  mRecordFreeQueueLock.lock();
  while(!mRecordFreeQueue.isEmpty()) {
    ALOGV("%s : Pre-releasing of Encoder buffers!\n", __FUNCTION__);
    mm_camera_ch_data_buf_t releasedBuf = mRecordFreeQueue.itemAt(0);
    mRecordFreeQueue.removeAt(0);
    mRecordFreeQueueLock.unlock();
    ALOGV("%s (%d): releasedBuf.idx = %d\n", __FUNCTION__, __LINE__,
                                              releasedBuf.video.video.idx);
    if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId,&releasedBuf))
        ALOGE("%s : Buf Done Failed",__func__);
  }
  mRecordFreeQueueLock.unlock();
#if 0
  while (!mRecordFreeQueue.isEmpty()) {
        ALOGE("%s : Waiting for Encoder to release all buffer!\n", __FUNCTION__);
  }
#endif
#endif // mzhu
  /* unregister the notify fn from the mmmm_camera_t object
   *  call stop() in parent class to stop the monitor thread */

  ret = cam_ops_action(mCameraId, false, MM_CAMERA_OPS_VIDEO, 0);
  if (MM_CAMERA_OK != ret) {
    ALOGE ("%s ERROR: Video streaming Stop err=%d\n", __func__, ret);
  }

  ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_VIDEO);
  if(ret != MM_CAMERA_OK){
    ALOGE("%s ERROR: Ureg video buf \n", __func__);
  }

  releaseEncodeBuffer();

  mActive = false;
  ALOGV("%s: END", __func__);

}
// ---------------------------------------------------------------------------
// QCameraStream_record
// ---------------------------------------------------------------------------
void QCameraStream_record::release()
{
  status_t ret = NO_ERROR;
  ALOGV("%s: BEGIN", __func__);

  if(mActive) {
    stop();
  }
  if(!mInit) {
    ALOGE("%s : Record stream not initialized",__func__);
    return;
  }

  ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_VIDEO);
  if(ret != MM_CAMERA_OK) {
    ALOGE("%s:Deinit Video channel failed=%d\n", __func__, ret);
  }
  (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
                                            NULL,
                                            (mm_camera_register_buf_cb_type_t)NULL,
                                            NULL,
                                            NULL);
  mInit = false;
  ALOGV("%s: END", __func__);
}

status_t QCameraStream_record::processRecordFrame(void *data)
{
    ALOGV("%s : BEGIN",__func__);
    mm_camera_ch_data_buf_t* frame = (mm_camera_ch_data_buf_t*) data;

    Mutex::Autolock lock(mStopCallbackLock);
    if(!mActive) {
      ALOGE("Recording Stopped. Returning callback");
      return NO_ERROR;
    }

    if (UNLIKELY(mDebugFps)) {
        debugShowVideoFPS();
    }

    mHalCamCtrl->dumpFrameToFile(frame->video.video.frame, HAL_DUMP_FRM_VIDEO);
    mHalCamCtrl->mCallbackLock.lock();
    camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
    void *rdata = mHalCamCtrl->mCallbackCookie;
    mHalCamCtrl->mCallbackLock.unlock();

	nsecs_t timeStamp = nsecs_t(frame->video.video.frame->ts.tv_sec)*1000000000LL + \
                      frame->video.video.frame->ts.tv_nsec;

  ALOGV("Send Video frame to services/encoder TimeStamp : %lld",timeStamp);
  mRecordedFrames[frame->video.video.idx] = *frame;

#ifdef USE_ION
  struct ion_flush_data cache_inv_data;
  int ion_fd;
  ion_fd = frame->video.video.frame->ion_dev_fd;
  cache_inv_data.vaddr = (void *)frame->video.video.frame->buffer;
  cache_inv_data.fd = frame->video.video.frame->fd;
  cache_inv_data.handle = frame->video.video.frame->fd_data.handle;
  cache_inv_data.length = frame->video.video.frame->ion_alloc.len;

  if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_CACHES) < 0)
    ALOGE("%s: Cache clean for Video buffer %p fd = %d failed", __func__,
      cache_inv_data.vaddr, cache_inv_data.fd);
#endif

  if (mHalCamCtrl->mStoreMetaDataInFrame) {
    mStopCallbackLock.unlock();
    if(mActive && (rcb != NULL) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
      rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
              mHalCamCtrl->mRecordingMemory.metadata_memory[frame->video.video.idx],
              0, mHalCamCtrl->mCallbackCookie);
    }
  } else {
    mStopCallbackLock.unlock();
    if(mActive && (rcb != NULL) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
      rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
              mHalCamCtrl->mRecordingMemory.camera_memory[frame->video.video.idx],
              0, mHalCamCtrl->mCallbackCookie);
    }
  }

  ALOGV("%s : END",__func__);
  return NO_ERROR;
}

//Record Related Functions
status_t QCameraStream_record::initEncodeBuffers()
{
  ALOGV("%s : BEGIN",__func__);
  status_t ret = NO_ERROR;
  const char *pmem_region;
  uint32_t frame_len;
  uint8_t num_planes;
  uint32_t planes[VIDEO_MAX_PLANES];
  //cam_ctrl_dimension_t dim;
  int width = 0;  /* width of channel  */
  int height = 0; /* height of channel */
  int buf_cnt;
  pmem_region = "/dev/pmem_adsp";


  memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
  memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
  ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
  if (MM_CAMERA_OK != ret) {
    ALOGE("%s: ERROR - can't get camera dimension!", __func__);
    return BAD_VALUE;
  }
  else {
    width =  dim.video_width;
    height = dim.video_height;
  }
  num_planes = 2;
  planes[0] = dim.video_frame_offset.mp[0].len;
  planes[1] = dim.video_frame_offset.mp[1].len;
  frame_len = dim.video_frame_offset.frame_len;

  buf_cnt = VIDEO_BUFFER_COUNT;
  if(mHalCamCtrl->isLowPowerCamcorder()) {
    ALOGV("%s: lower power camcorder selected", __func__);
    buf_cnt = VIDEO_BUFFER_COUNT_LOW_POWER_CAMCORDER;
  }
    recordframes = new msm_frame[buf_cnt];
    memset(recordframes,0,sizeof(struct msm_frame) * buf_cnt);

		mRecordBuf.video.video.buf.mp = new mm_camera_mp_buf_t[buf_cnt *
                                  sizeof(mm_camera_mp_buf_t)];
		if (!mRecordBuf.video.video.buf.mp) {
			ALOGE("%s Error allocating memory for mplanar struct ", __func__);
			return BAD_VALUE;
		}
		memset(mRecordBuf.video.video.buf.mp, 0,
					 buf_cnt * sizeof(mm_camera_mp_buf_t));

    memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
    for (int i=0; i<MM_CAMERA_MAX_NUM_FRAMES;i++) {
        mHalCamCtrl->mRecordingMemory.main_ion_fd[i] = -1;
        mHalCamCtrl->mRecordingMemory.fd[i] = -1;
    }

    mHalCamCtrl->mRecordingMemory.buffer_count = buf_cnt;

		mHalCamCtrl->mRecordingMemory.size = frame_len;
		mHalCamCtrl->mRecordingMemory.cbcr_offset = planes[0];

    for (int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
#ifdef USE_ION
      if(mHalCamCtrl->allocate_ion_memory(&mHalCamCtrl->mRecordingMemory, cnt,
        ((0x1 << CAMERA_ION_HEAP_ID) | (0x1 << CAMERA_ION_FALLBACK_HEAP_ID))) < 0) {
        ALOGE("%s ION alloc failed\n", __func__);
        return UNKNOWN_ERROR;
      }
#else
		  mHalCamCtrl->mRecordingMemory.fd[cnt] = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
		  if(mHalCamCtrl->mRecordingMemory.fd[cnt] <= 0) {
			  ALOGE("%s: no pmem for frame %d", __func__, cnt);
			  return UNKNOWN_ERROR;
		  }
#endif
		  mHalCamCtrl->mRecordingMemory.camera_memory[cnt] =
		    mHalCamCtrl->mGetMemory(mHalCamCtrl->mRecordingMemory.fd[cnt],
		    mHalCamCtrl->mRecordingMemory.size, 1, (void *)this);

      if (mHalCamCtrl->mStoreMetaDataInFrame) {
        mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] =
          mHalCamCtrl->mGetMemory(-1,
          sizeof(struct encoder_media_buffer_type), 1, (void *)this);
        struct encoder_media_buffer_type * packet =
          (struct encoder_media_buffer_type  *)
          mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
        packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
        packet->buffer_type = kMetadataBufferTypeCameraSource;
        native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
        nh->data[0] = mHalCamCtrl->mRecordingMemory.fd[cnt];
        nh->data[1] = 0;
        nh->data[2] = mHalCamCtrl->mRecordingMemory.size;
      }
    	recordframes[cnt].fd = mHalCamCtrl->mRecordingMemory.fd[cnt];
    	recordframes[cnt].buffer = (uint32_t)mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->data;
	    recordframes[cnt].y_off = 0;
	    recordframes[cnt].cbcr_off = mHalCamCtrl->mRecordingMemory.cbcr_offset;
	    recordframes[cnt].path = OUTPUT_TYPE_V;
      recordframes[cnt].fd_data = mHalCamCtrl->mRecordingMemory.ion_info_fd[cnt];
      recordframes[cnt].ion_alloc = mHalCamCtrl->mRecordingMemory.alloc[cnt];
      recordframes[cnt].ion_dev_fd = mHalCamCtrl->mRecordingMemory.main_ion_fd[cnt];

      if (NO_ERROR !=
        mHalCamCtrl->sendMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_VIDEO, cnt,
        recordframes[cnt].fd, mHalCamCtrl->mRecordingMemory.size, mCameraId,
        CAM_SOCK_MSG_TYPE_FD_MAPPING))
        ALOGE("%s: sending mapping data Msg Failed", __func__);

      ALOGV("initRecord :  record heap , video buffers  buffer=%lu fd=%d y_off=%d cbcr_off=%d\n",
		    (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].y_off,
		    recordframes[cnt].cbcr_off);
	    //mNumRecordFrames++;

			mRecordBuf.video.video.buf.mp[cnt].frame = recordframes[cnt];
      mRecordBuf.video.video.buf.mp[cnt].frame_offset = 0;
      mRecordBuf.video.video.buf.mp[cnt].num_planes = num_planes;
      /* Plane 0 needs to be set seperately. Set other planes
       * in a loop. */
      mRecordBuf.video.video.buf.mp[cnt].planes[0].reserved[0] =
        mRecordBuf.video.video.buf.mp[cnt].frame_offset;
      mRecordBuf.video.video.buf.mp[cnt].planes[0].length = planes[0];
      mRecordBuf.video.video.buf.mp[cnt].planes[0].m.userptr =
        recordframes[cnt].fd;
      for (int j = 1; j < num_planes; j++) {
        mRecordBuf.video.video.buf.mp[cnt].planes[j].length = planes[j];
        mRecordBuf.video.video.buf.mp[cnt].planes[j].m.userptr =
          recordframes[cnt].fd;
        mRecordBuf.video.video.buf.mp[cnt].planes[j].reserved[0] =
          mRecordBuf.video.video.buf.mp[cnt].planes[j-1].reserved[0] +
          mRecordBuf.video.video.buf.mp[cnt].planes[j-1].length;
      }
    }

    //memset(&mRecordBuf, 0, sizeof(mRecordBuf));
    mRecordBuf.ch_type = MM_CAMERA_CH_VIDEO;
    mRecordBuf.video.video.num = mHalCamCtrl->mRecordingMemory.buffer_count;//kRecordBufferCount;
    //mRecordBuf.video.video.frame_offset = &record_offset[0];
    //mRecordBuf.video.video.frame = &recordframes[0];
    ALOGV("%s : END",__func__);
    return NO_ERROR;
}

void QCameraStream_record::releaseRecordingFrame(const void *opaque)
{
    ALOGV("%s : BEGIN, opaque = 0x%p",__func__, opaque);
    if(!mActive)
    {
        ALOGE("%s : Recording already stopped!!! Leak???",__func__);
        return;
    }
    for(int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
      if (mHalCamCtrl->mStoreMetaDataInFrame) {
        if(mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] &&
                mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data == opaque) {
            /* found the match */
            if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mRecordedFrames[cnt]))
                ALOGE("%s : Buf Done Failed",__func__);
            ALOGV("%s : END",__func__);
            return;
        }
      } else {
        if(mHalCamCtrl->mRecordingMemory.camera_memory[cnt] &&
                mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->data == opaque) {
            /* found the match */
            if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mRecordedFrames[cnt]))
                ALOGE("%s : Buf Done Failed",__func__);
            ALOGV("%s : END",__func__);
            return;
        }
      }
    }
	ALOGE("%s: cannot find the matched frame with opaue = 0x%p", __func__, opaque);
}

void QCameraStream_record::debugShowVideoFPS() const
{
  static int mFrameCount;
  static int mLastFrameCount = 0;
  static nsecs_t mLastFpsTime = 0;
  static float mFps = 0;
  mFrameCount++;
  nsecs_t now = systemTime();
  nsecs_t diff = now - mLastFpsTime;
  if (diff > ms2ns(250)) {
    mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
    ALOGV("Video Frames Per Second: %.4f", mFps);
    mLastFpsTime = now;
    mLastFrameCount = mFrameCount;
  }
}

#if 0
sp<IMemoryHeap> QCameraStream_record::getHeap() const
{
  return mRecordHeap != NULL ? mRecordHeap->mHeap : NULL;
}

#endif
status_t  QCameraStream_record::takeLiveSnapshot(){
	return true;
}

}//namespace android

