/*
 * 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_malloc(
            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_malloc(
            sizeof(VideoBrowserContext),
            VIDEOBROWSER, (M4OSA_Char*)"Video browser context");

    CHECK_PTR(videoBrowserCreate, pContext,err, M4ERR_ALLOC);
    M4OSA_memset((M4OSA_MemAddr8)pContext, sizeof(VideoBrowserContext), 0);

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

    /*--- Copy the file reader functions ---*/
    M4OSA_memcpy((M4OSA_MemAddr8)&pContext->m_fileReadPtr,
                 (M4OSA_MemAddr8)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_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_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
* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
******************************************************************************/
M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime)
{
    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
    M4OSA_ERR err = M4NO_ERROR;
    M4OSA_UInt32 targetTime = 0;
    M4OSA_UInt32 jumpTime = 0;
    M4_MediaTime timeMS = 0;
    M4OSA_Int32 rapTime = 0;
    M4OSA_Bool isBackward = M4OSA_FALSE;
    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;
    }

    /*--- Check the duration ---*/
    /*--- If we jump backward, we need to jump ---*/
    if (targetTime < pC->m_currentCTS)
    {
        isBackward = M4OSA_TRUE;
        bJumpNeeded = M4OSA_TRUE;
    }
    /*--- If we jumpt to a time greater than "currentTime" + "predecodeTime"
          we need to jump ---*/
    else if (targetTime > (pC->m_currentCTS + VIDEO_BROWSER_PREDECODE_TIME))
    {
        bJumpNeeded = M4OSA_TRUE;
    }

    if (M4OSA_TRUE == bJumpNeeded)
    {
        rapTime = targetTime;
        /*--- Retrieve the previous RAP time ---*/
        err = pC->m_3gpReader->m_pFctGetPrevRapTime(
                pC->m_pReaderCtx, pC->m_pStreamHandler, &rapTime);

        CHECK_ERR(videoBrowserPrepareFrame, err);

        jumpTime = rapTime;

        err = pC->m_3gpReader->m_pFctJump(pC->m_pReaderCtx,
                                          pC->m_pStreamHandler,
                                          (M4OSA_Int32*)&jumpTime);
        CHECK_ERR(videoBrowserPrepareFrame, err);
    }

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

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

    // FIXME:
    // Not sure that I understand why we need a second jump logic here
    if ((timeMS >= pC->m_currentCTS) && (M4OSA_TRUE == isBackward))
    {
        jumpTime = rapTime;
        err = pC->m_3gpReader->m_pFctJump(
            pC->m_pReaderCtx, pC->m_pStreamHandler, (M4OSA_Int32*)&jumpTime);

        CHECK_ERR(videoBrowserPrepareFrame, err);

        timeMS = (M4_MediaTime)rapTime;
        err = pC->m_pDecoder->m_pFctDecode(
            pC->m_pDecoderCtx, &timeMS, M4OSA_TRUE);

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