/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.
 */
#include "VideoEditorVideoDecoder.h"
#include "VideoEditor3gpReader.h"

#include <utils/Log.h>
#include "VideoBrowserInternal.h"
#include "LVOSA_FileReader_optim.h"

//#define M4OSA_TRACE_LEVEL 1
#if (M4OSA_TRACE_LEVEL >= 1)
#undef M4OSA_TRACE1_0
#undef M4OSA_TRACE1_1
#undef M4OSA_TRACE1_2
#undef M4OSA_TRACE1_3

#define M4OSA_TRACE1_0(a)       __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a);
#define M4OSA_TRACE1_1(a,b)     __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b);
#define M4OSA_TRACE1_2(a,b,c)   __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c);
#define M4OSA_TRACE1_3(a,b,c,d) __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c,d);
#endif

/******************************************************************************
 * M4OSA_ERR     videoBrowserSetWindow(
 *          M4OSA_Context pContext, M4OSA_UInt32 x,
 *          M4OSA_UInt32 y, M4OSA_UInt32 dx, M4OSA_UInt32 dy);
 * @brief        This function sets the size and the position of the display.
 * @param        pContext       (IN) : Video Browser context
 * @param        pPixelArray    (IN) : Array to hold the video frame.
 * @param        x              (IN) : Horizontal position of the top left
 *                                     corner
 * @param        y              (IN) : Vertical position of the top left corner
 * @param        dx             (IN) : Width of the display window
 * @param        dy             (IN) : Height of the video window
 * @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
 ******************************************************************************/
M4OSA_ERR videoBrowserSetWindow(
        M4OSA_Context pContext,
        M4OSA_Int32 *pPixelArray,
        M4OSA_UInt32 x, M4OSA_UInt32 y,
        M4OSA_UInt32 dx, M4OSA_UInt32 dy)
{
    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
    M4OSA_ERR err = M4NO_ERROR;

    M4OSA_TRACE2_5("videoBrowserSetWindow: entering with 0x%x %d %d %d %d ",
            pContext, x, y, dx, dy);

    /*--- Sanity checks ---*/
    CHECK_PTR(videoBrowserSetWindow, pContext, err, M4ERR_PARAMETER);
    CHECK_PTR(videoBrowserSetWindow, pPixelArray, err, M4ERR_PARAMETER);
    CHECK_STATE(videoBrowserSetWindow, VideoBrowser_kVBOpened, pC);

    pC->m_outputPlane[0].u_topleft = 0;

    pC->m_outputPlane[0].u_height = dy;
    pC->m_outputPlane[0].u_width = dx;
    pC->m_x = x;
    pC->m_y = y;

    if (pC->m_frameColorType == VideoBrowser_kGB565) {
        pC->m_outputPlane[0].u_stride = pC->m_outputPlane[0].u_width << 1;
        pC->m_outputPlane[0].pac_data = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
            pC->m_outputPlane[0].u_stride * pC->m_outputPlane[0].u_height,
            VIDEOBROWSER, (M4OSA_Char *)"output plane");

        CHECK_PTR(videoBrowserSetWindow,
            pC->m_outputPlane[0].pac_data, err, M4ERR_ALLOC);
    }
    else if (pC->m_frameColorType == VideoBrowser_kYUV420) {
        pC->m_outputPlane[0].u_stride = pC->m_outputPlane[0].u_width;
        pC->m_outputPlane[1].u_height = pC->m_outputPlane[0].u_height >> 1;
        pC->m_outputPlane[1].u_width = pC->m_outputPlane[0].u_width >> 1;
        pC->m_outputPlane[1].u_topleft = 0;
        pC->m_outputPlane[1].u_stride = pC->m_outputPlane[1].u_width;

        pC->m_outputPlane[2].u_height = pC->m_outputPlane[0].u_height >> 1;
        pC->m_outputPlane[2].u_width = pC->m_outputPlane[0].u_width >> 1;
        pC->m_outputPlane[2].u_topleft = 0;
        pC->m_outputPlane[2].u_stride = pC->m_outputPlane[2].u_width;

        pC->m_outputPlane[0].pac_data = (M4OSA_UInt8*)pPixelArray;

        CHECK_PTR(videoBrowserSetWindow,
            pC->m_outputPlane[0].pac_data, err, M4ERR_ALLOC);

        pC->m_outputPlane[1].pac_data =
            pC->m_outputPlane[0].pac_data +
            (pC->m_outputPlane[0].u_stride * pC->m_outputPlane[0].u_height);

        pC->m_outputPlane[2].pac_data =
            pC->m_outputPlane[1].pac_data +
            (pC->m_outputPlane[1].u_stride * pC->m_outputPlane[1].u_height);
    }


    M4OSA_TRACE2_0("videoBrowserSetWindow returned NO ERROR");
    return M4NO_ERROR;

videoBrowserSetWindow_cleanUp:

    M4OSA_TRACE2_1("videoBrowserSetWindow returned 0x%x", err);
    return err;
}

/******************************************************************************
* @brief  This function allocates the resources needed for browsing a video file
* @param   ppContext     (OUT): Pointer on a context filled by this function.
* @param   pURL          (IN) : Path of File to browse
* @param   DrawMode      (IN) : Indicate which method is used to draw (Direct draw etc...)
* @param   pfCallback    (IN) : Callback function to be called when a frame must be displayed
* @param   pCallbackData (IN) : User defined data that will be passed as parameter of the callback
* @param   clrType       (IN) : Required color type.
* @return  M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
******************************************************************************/
M4OSA_ERR videoBrowserCreate(
        M4OSA_Context* ppContext,
        M4OSA_Char* pURL,
        M4OSA_UInt32 DrawMode,
        M4OSA_FileReadPointer* ptrF,
        videoBrowser_Callback pfCallback,
        M4OSA_Void* pCallbackData,
        VideoBrowser_VideoColorType clrType)
{
    VideoBrowserContext* pContext = M4OSA_NULL;
    M4READER_MediaFamily mediaFamily = M4READER_kMediaFamilyUnknown;
    M4_StreamHandler* pStreamHandler = M4OSA_NULL;
    M4_VideoStreamHandler* pVideoStreamHandler = M4OSA_NULL;
    M4DECODER_VideoType decoderType;
    M4DECODER_OutputFilter FilterOption;

    M4OSA_Bool deb = M4OSA_TRUE;
    M4OSA_ERR err = M4NO_ERROR;

    M4OSA_TRACE1_2(
        "videoBrowserCreate: entering with 0x%x 0x%x", ppContext, pURL);

    /*--- Sanity checks ---*/
    CHECK_PTR(videoBrowserCreate, ppContext, err, M4ERR_PARAMETER);
    *ppContext = M4OSA_NULL ;
    CHECK_PTR(videoBrowserCreate, pURL,  err, M4ERR_PARAMETER);

    /*--- Create context ---*/
    pContext = (VideoBrowserContext*)M4OSA_32bitAlignedMalloc(
            sizeof(VideoBrowserContext),
            VIDEOBROWSER, (M4OSA_Char*)"Video browser context");

    CHECK_PTR(videoBrowserCreate, pContext,err, M4ERR_ALLOC);
    memset((void *)pContext, 0,sizeof(VideoBrowserContext));

    /*--- Initialize the context parameters ---*/
    pContext->m_state = VideoBrowser_kVBCreating ;
    pContext->m_frameColorType = clrType;

    /*--- Copy the file reader functions ---*/
    memcpy((void *)&pContext->m_fileReadPtr,
                 (void *)ptrF,
                 sizeof(M4OSA_FileReadPointer)) ;

    /* PR#SP00013 DGR bug 13 : first frame is not visible */
    pContext->m_drawmode = DrawMode;


    /* Retrieve the 3gp reader interface */
    VideoEditor3gpReader_getInterface(&pContext->m_mediaType,
        &pContext->m_3gpReader, &pContext->m_3gpData);

    CHECK_PTR(videoBrowserCreate, pContext->m_3gpReader,  err, M4ERR_ALLOC);
    CHECK_PTR(videoBrowserCreate, pContext->m_3gpData,    err, M4ERR_ALLOC);

    /*--- Create the file reader ---*/
    err = pContext->m_3gpReader->m_pFctCreate(&pContext->m_pReaderCtx);
    CHECK_ERR(videoBrowserCreate, err);
    CHECK_PTR(videoBrowserCreate, pContext->m_pReaderCtx, err, M4ERR_ALLOC);
    pContext->m_3gpData->m_readerContext = pContext->m_pReaderCtx;

    /*--- Set the OSAL file reader functions ---*/
    err = pContext->m_3gpReader->m_pFctSetOption(
            pContext->m_pReaderCtx,
            M4READER_kOptionID_SetOsaFileReaderFctsPtr,
            (M4OSA_DataOption)(&pContext->m_fileReadPtr));

    CHECK_ERR(videoBrowserCreate, err) ;

    /*--- Open the file ---*/
    err = pContext->m_3gpReader->m_pFctOpen(pContext->m_pReaderCtx, pURL);
    CHECK_ERR(videoBrowserCreate, err) ;

    /*--- Try to find a video stream ---*/
    while (err == M4NO_ERROR)
    {
        err = pContext->m_3gpReader->m_pFctGetNextStream(
                pContext->m_pReaderCtx, &mediaFamily, &pStreamHandler);

        /*in case we found a bifs stream or something else...*/
        if ((err == (M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE) ||
            (err == (M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS))
        {
            err = M4NO_ERROR;
            continue;
        }

        if (err != M4WAR_NO_MORE_STREAM)
        {
            if (M4READER_kMediaFamilyVideo != mediaFamily)
            {
                err = M4NO_ERROR;
                continue;
            }

            pContext->m_pStreamHandler = pStreamHandler;

            err = pContext->m_3gpReader->m_pFctReset(
                    pContext->m_pReaderCtx, pContext->m_pStreamHandler);

            CHECK_ERR(videoBrowserCreate, err);

            err = pContext->m_3gpReader->m_pFctFillAuStruct(
                    pContext->m_pReaderCtx,
                    pContext->m_pStreamHandler,
                    &pContext->m_accessUnit);

            CHECK_ERR(videoBrowserCreate, err);

            pVideoStreamHandler =
                (M4_VideoStreamHandler*)pContext->m_pStreamHandler;

            switch (pContext->m_pStreamHandler->m_streamType)
            {
                case M4DA_StreamTypeVideoMpeg4:
                case M4DA_StreamTypeVideoH263:
                {
                    pContext->m_pCodecLoaderContext = M4OSA_NULL;
                    decoderType = M4DECODER_kVideoTypeMPEG4;

#ifdef USE_SOFTWARE_DECODER
                        err = VideoEditorVideoDecoder_getSoftwareInterface_MPEG4(
                            &decoderType, &pContext->m_pDecoder);
#else
                        err = VideoEditorVideoDecoder_getInterface_MPEG4(
                            &decoderType, (void **)&pContext->m_pDecoder);
#endif
                    CHECK_ERR(videoBrowserCreate, err) ;

                    err = pContext->m_pDecoder->m_pFctCreate(
                            &pContext->m_pDecoderCtx,
                            pContext->m_pStreamHandler,
                            pContext->m_3gpReader,
                            pContext->m_3gpData,
                            &pContext->m_accessUnit,
                            pContext->m_pCodecLoaderContext) ;

                    CHECK_ERR(videoBrowserCreate, err) ;
                }
                break;

                case M4DA_StreamTypeVideoMpeg4Avc:
                {
                    pContext->m_pCodecLoaderContext = M4OSA_NULL;

                    decoderType = M4DECODER_kVideoTypeAVC;

#ifdef USE_SOFTWARE_DECODER
                        err = VideoEditorVideoDecoder_getSoftwareInterface_H264(
                            &decoderType, &pContext->m_pDecoder);
#else
                        err = VideoEditorVideoDecoder_getInterface_H264(
                            &decoderType, (void **)&pContext->m_pDecoder);
#endif
                   CHECK_ERR(videoBrowserCreate, err) ;

                    err = pContext->m_pDecoder->m_pFctCreate(
                            &pContext->m_pDecoderCtx,
                            pContext->m_pStreamHandler,
                            pContext->m_3gpReader,
                            pContext->m_3gpData,
                            &pContext->m_accessUnit,
                            pContext->m_pCodecLoaderContext) ;

                    CHECK_ERR(videoBrowserCreate, err) ;
                }
                break;

                default:
                    err = M4ERR_VB_MEDIATYPE_NOT_SUPPORTED;
                    goto videoBrowserCreate_cleanUp;
            }
        }
    }

    if (err == M4WAR_NO_MORE_STREAM)
    {
        err = M4NO_ERROR ;
    }

    if (M4OSA_NULL == pContext->m_pStreamHandler)
    {
        err = M4ERR_VB_NO_VIDEO ;
        goto videoBrowserCreate_cleanUp ;
    }

    err = pContext->m_pDecoder->m_pFctSetOption(
            pContext->m_pDecoderCtx,
            M4DECODER_kOptionID_DeblockingFilter,
            (M4OSA_DataOption)&deb);

    if (err == M4WAR_DEBLOCKING_FILTER_NOT_IMPLEMENTED)
    {
        err = M4NO_ERROR;
    }
    CHECK_ERR(videoBrowserCreate, err);

    FilterOption.m_pFilterUserData = M4OSA_NULL;


    if (pContext->m_frameColorType == VideoBrowser_kGB565) {
        FilterOption.m_pFilterFunction =
            (M4OSA_Void*)M4VIFI_ResizeBilinearYUV420toBGR565;
    }
    else if (pContext->m_frameColorType == VideoBrowser_kYUV420) {
        FilterOption.m_pFilterFunction =
            (M4OSA_Void*)M4VIFI_ResizeBilinearYUV420toYUV420;
    }
    else {
        err = M4ERR_PARAMETER;
        goto videoBrowserCreate_cleanUp;
    }

    err = pContext->m_pDecoder->m_pFctSetOption(
            pContext->m_pDecoderCtx,
            M4DECODER_kOptionID_OutputFilter,
            (M4OSA_DataOption)&FilterOption);

    CHECK_ERR(videoBrowserCreate, err);

    /* store the callback details */
    pContext->m_pfCallback = pfCallback;
    pContext->m_pCallbackUserData = pCallbackData;
    /* store the callback details */

    pContext->m_state = VideoBrowser_kVBOpened;
    *ppContext = pContext;

    M4OSA_TRACE1_0("videoBrowserCreate returned NO ERROR");
    return M4NO_ERROR;

videoBrowserCreate_cleanUp:

    if (M4OSA_NULL != pContext)
    {
        if (M4OSA_NULL != pContext->m_pDecoderCtx)
        {
            pContext->m_pDecoder->m_pFctDestroy(pContext->m_pDecoderCtx);
            pContext->m_pDecoderCtx = M4OSA_NULL;
        }

        if (M4OSA_NULL != pContext->m_pReaderCtx)
        {
            pContext->m_3gpReader->m_pFctClose(pContext->m_pReaderCtx);
            pContext->m_3gpReader->m_pFctDestroy(pContext->m_pReaderCtx);
            pContext->m_pReaderCtx = M4OSA_NULL;
        }
        SAFE_FREE(pContext->m_pDecoder);
        SAFE_FREE(pContext->m_3gpReader);
        SAFE_FREE(pContext->m_3gpData);
        SAFE_FREE(pContext);
    }

    M4OSA_TRACE2_1("videoBrowserCreate returned 0x%x", err);
    return err;
}

/******************************************************************************
* M4OSA_ERR     videoBrowserCleanUp(M4OSA_Context pContext);
* @brief        This function frees the resources needed for browsing a
*               video file.
* @param        pContext     (IN) : Video browser context
* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE
******************************************************************************/
M4OSA_ERR videoBrowserCleanUp(M4OSA_Context pContext)
{
    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
    M4OSA_ERR err = M4NO_ERROR;

    M4OSA_TRACE2_1("videoBrowserCleanUp: entering with 0x%x", pContext);

    /*--- Sanity checks ---*/
    CHECK_PTR(videoBrowserCleanUp, pContext, err, M4ERR_PARAMETER);

    if (M4OSA_NULL != pC->m_pDecoderCtx)
    {
        pC->m_pDecoder->m_pFctDestroy(pC->m_pDecoderCtx);
        pC->m_pDecoderCtx = M4OSA_NULL ;
    }

    if (M4OSA_NULL != pC->m_pReaderCtx)
    {
        pC->m_3gpReader->m_pFctClose(pC->m_pReaderCtx) ;
        pC->m_3gpReader->m_pFctDestroy(pC->m_pReaderCtx);
        pC->m_pReaderCtx = M4OSA_NULL;
    }

    SAFE_FREE(pC->m_pDecoder);
    SAFE_FREE(pC->m_3gpReader);
    SAFE_FREE(pC->m_3gpData);

    if (pC->m_frameColorType != VideoBrowser_kYUV420) {
        SAFE_FREE(pC->m_outputPlane[0].pac_data);
    }
    SAFE_FREE(pC);

    M4OSA_TRACE2_0("videoBrowserCleanUp returned NO ERROR");
    return M4NO_ERROR;

videoBrowserCleanUp_cleanUp:

    M4OSA_TRACE2_1("videoBrowserCleanUp returned 0x%x", err);
    return err;
}
/******************************************************************************
* M4OSA_ERR     videoBrowserPrepareFrame(
*       M4OSA_Context pContext, M4OSA_UInt32* pTime);
* @brief        This function prepares the frame.
* @param        pContext     (IN) : Video browser context
* @param        pTime        (IN/OUT) : Pointer on the time to reach. Updated
*                                       by this function with the reached time
* @param        tolerance    (IN) :  We may decode an earlier frame within the tolerance.
*                                    The time difference is specified in milliseconds.
* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
******************************************************************************/
M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime,
    M4OSA_UInt32 tolerance)
{
    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
    M4OSA_ERR err = M4NO_ERROR;
    M4OSA_UInt32 targetTime = 0;
    M4_MediaTime timeMS = 0;
    M4OSA_Bool bJumpNeeded = M4OSA_FALSE;

    /*--- Sanity checks ---*/
    CHECK_PTR(videoBrowserPrepareFrame, pContext, err, M4ERR_PARAMETER);
    CHECK_PTR(videoBrowserPrepareFrame, pTime,  err, M4ERR_PARAMETER);

    targetTime = *pTime ;

    /*--- Check the state, if this is the first call to this function
          we move to the state "browsing" ---*/
    if (VideoBrowser_kVBOpened == pC->m_state)
    {
        pC->m_state = VideoBrowser_kVBBrowsing;
    }
    else if (VideoBrowser_kVBBrowsing != pC->m_state)
    {
        err = M4ERR_STATE ;
        goto videoBrowserPrepareFrame_cleanUp;
    }

    // If we jump backward or forward to a time greater than current position by
    // 85ms (~ 2 frames), we want to jump.
    if (pC->m_currentCTS == 0 ||
        targetTime < pC->m_currentCTS ||
        targetTime > (pC->m_currentCTS + 85))
    {
        bJumpNeeded = M4OSA_TRUE;
    }

    timeMS = (M4_MediaTime)targetTime;
    err = pC->m_pDecoder->m_pFctDecode(
        pC->m_pDecoderCtx, &timeMS, bJumpNeeded, tolerance);

    if ((err != M4NO_ERROR) && (err != M4WAR_NO_MORE_AU))
    {
        return err;
    }

    err = pC->m_pDecoder->m_pFctRender(
        pC->m_pDecoderCtx, &timeMS, pC->m_outputPlane, M4OSA_TRUE);

    if (M4WAR_VIDEORENDERER_NO_NEW_FRAME == err)
    {
        return err;
    }
    CHECK_ERR(videoBrowserPrepareFrame, err) ;

    pC->m_currentCTS = (M4OSA_UInt32)timeMS;

    *pTime = pC->m_currentCTS;

    return M4NO_ERROR;

videoBrowserPrepareFrame_cleanUp:

    if ((M4WAR_INVALID_TIME == err) || (M4WAR_NO_MORE_AU == err))
    {
        err = M4NO_ERROR;
    }
    else if (M4OSA_NULL != pC)
    {
        pC->m_currentCTS = 0;
    }

    M4OSA_TRACE2_1("videoBrowserPrepareFrame returned 0x%x", err);
    return err;
}

/******************************************************************************
* M4OSA_ERR     videoBrowserDisplayCurrentFrame(M4OSA_Context pContext);
* @brief        This function displays the current frame.
* @param        pContext     (IN) : Video browser context
* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
******************************************************************************/
M4OSA_ERR videoBrowserDisplayCurrentFrame(M4OSA_Context pContext)
{
    VideoBrowserContext* pC = (VideoBrowserContext*)pContext ;
    M4OSA_ERR err = M4NO_ERROR ;

    /*--- Sanity checks ---*/
    CHECK_PTR(videoBrowserDisplayCurrentFrame, pContext, err, M4ERR_PARAMETER);

    // Request display of the frame
    pC->m_pfCallback((M4OSA_Context) pC,             // VB context
        VIDEOBROWSER_DISPLAY_FRAME,                  // action requested
        M4NO_ERROR,                                  // error code
        (M4OSA_Void*) &(pC->m_outputPlane[0]),       // image to be displayed
        (M4OSA_Void*) pC->m_pCallbackUserData);      // user-provided data

#ifdef DUMPTOFILE
    {
        M4OSA_Context fileContext;
        M4OSA_Char* fileName = "/sdcard/textBuffer_RGB565.rgb";
        M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,
            M4OSA_kFileWrite | M4OSA_kFileCreate);

        M4OSA_fileWriteData(fileContext,
            (M4OSA_MemAddr8) pC->m_outputPlane[0].pac_data,
            pC->m_outputPlane[0].u_height*pC->m_outputPlane[0].u_width*2);

        M4OSA_fileWriteClose(fileContext);
    }
#endif

    M4OSA_TRACE2_0("videoBrowserDisplayCurrentFrame returned NO ERROR") ;
    return M4NO_ERROR;

videoBrowserDisplayCurrentFrame_cleanUp:

    M4OSA_TRACE2_1("videoBrowserDisplayCurrentFrame returned 0x%x", err) ;
    return err;
}
