Home | History | Annotate | Download | only in mediaeditor
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #include "VideoEditorVideoDecoder.h"
     17 #include "VideoEditor3gpReader.h"
     18 
     19 #include <utils/Log.h>
     20 #include "VideoBrowserInternal.h"
     21 #include "LVOSA_FileReader_optim.h"
     22 
     23 //#define M4OSA_TRACE_LEVEL 1
     24 #if (M4OSA_TRACE_LEVEL >= 1)
     25 #undef M4OSA_TRACE1_0
     26 #undef M4OSA_TRACE1_1
     27 #undef M4OSA_TRACE1_2
     28 #undef M4OSA_TRACE1_3
     29 
     30 #define M4OSA_TRACE1_0(a)       __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a);
     31 #define M4OSA_TRACE1_1(a,b)     __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b);
     32 #define M4OSA_TRACE1_2(a,b,c)   __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c);
     33 #define M4OSA_TRACE1_3(a,b,c,d) __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c,d);
     34 #endif
     35 
     36 /******************************************************************************
     37  * M4OSA_ERR     videoBrowserSetWindow(
     38  *          M4OSA_Context pContext, M4OSA_UInt32 x,
     39  *          M4OSA_UInt32 y, M4OSA_UInt32 dx, M4OSA_UInt32 dy);
     40  * @brief        This function sets the size and the position of the display.
     41  * @param        pContext       (IN) : Video Browser context
     42  * @param        pPixelArray    (IN) : Array to hold the video frame.
     43  * @param        x              (IN) : Horizontal position of the top left
     44  *                                     corner
     45  * @param        y              (IN) : Vertical position of the top left corner
     46  * @param        dx             (IN) : Width of the display window
     47  * @param        dy             (IN) : Height of the video window
     48  * @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
     49  ******************************************************************************/
     50 M4OSA_ERR videoBrowserSetWindow(
     51         M4OSA_Context pContext,
     52         M4OSA_Int32 *pPixelArray,
     53         M4OSA_UInt32 x, M4OSA_UInt32 y,
     54         M4OSA_UInt32 dx, M4OSA_UInt32 dy)
     55 {
     56     VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
     57     M4OSA_ERR err = M4NO_ERROR;
     58 
     59     M4OSA_TRACE2_5("videoBrowserSetWindow: entering with 0x%x %d %d %d %d ",
     60             pContext, x, y, dx, dy);
     61 
     62     /*--- Sanity checks ---*/
     63     CHECK_PTR(videoBrowserSetWindow, pContext, err, M4ERR_PARAMETER);
     64     CHECK_PTR(videoBrowserSetWindow, pPixelArray, err, M4ERR_PARAMETER);
     65     CHECK_STATE(videoBrowserSetWindow, VideoBrowser_kVBOpened, pC);
     66 
     67     pC->m_outputPlane[0].u_topleft = 0;
     68 
     69     pC->m_outputPlane[0].u_height = dy;
     70     pC->m_outputPlane[0].u_width = dx;
     71     pC->m_x = x;
     72     pC->m_y = y;
     73 
     74     if (pC->m_frameColorType == VideoBrowser_kGB565) {
     75         pC->m_outputPlane[0].u_stride = pC->m_outputPlane[0].u_width << 1;
     76         pC->m_outputPlane[0].pac_data = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
     77             pC->m_outputPlane[0].u_stride * pC->m_outputPlane[0].u_height,
     78             VIDEOBROWSER, (M4OSA_Char *)"output plane");
     79 
     80         CHECK_PTR(videoBrowserSetWindow,
     81             pC->m_outputPlane[0].pac_data, err, M4ERR_ALLOC);
     82     }
     83     else if (pC->m_frameColorType == VideoBrowser_kYUV420) {
     84         pC->m_outputPlane[0].u_stride = pC->m_outputPlane[0].u_width;
     85         pC->m_outputPlane[1].u_height = pC->m_outputPlane[0].u_height >> 1;
     86         pC->m_outputPlane[1].u_width = pC->m_outputPlane[0].u_width >> 1;
     87         pC->m_outputPlane[1].u_topleft = 0;
     88         pC->m_outputPlane[1].u_stride = pC->m_outputPlane[1].u_width;
     89 
     90         pC->m_outputPlane[2].u_height = pC->m_outputPlane[0].u_height >> 1;
     91         pC->m_outputPlane[2].u_width = pC->m_outputPlane[0].u_width >> 1;
     92         pC->m_outputPlane[2].u_topleft = 0;
     93         pC->m_outputPlane[2].u_stride = pC->m_outputPlane[2].u_width;
     94 
     95         pC->m_outputPlane[0].pac_data = (M4OSA_UInt8*)pPixelArray;
     96 
     97         CHECK_PTR(videoBrowserSetWindow,
     98             pC->m_outputPlane[0].pac_data, err, M4ERR_ALLOC);
     99 
    100         pC->m_outputPlane[1].pac_data =
    101             pC->m_outputPlane[0].pac_data +
    102             (pC->m_outputPlane[0].u_stride * pC->m_outputPlane[0].u_height);
    103 
    104         pC->m_outputPlane[2].pac_data =
    105             pC->m_outputPlane[1].pac_data +
    106             (pC->m_outputPlane[1].u_stride * pC->m_outputPlane[1].u_height);
    107     }
    108 
    109 
    110     M4OSA_TRACE2_0("videoBrowserSetWindow returned NO ERROR");
    111     return M4NO_ERROR;
    112 
    113 videoBrowserSetWindow_cleanUp:
    114 
    115     M4OSA_TRACE2_1("videoBrowserSetWindow returned 0x%x", err);
    116     return err;
    117 }
    118 
    119 /******************************************************************************
    120 * @brief  This function allocates the resources needed for browsing a video file
    121 * @param   ppContext     (OUT): Pointer on a context filled by this function.
    122 * @param   pURL          (IN) : Path of File to browse
    123 * @param   DrawMode      (IN) : Indicate which method is used to draw (Direct draw etc...)
    124 * @param   pfCallback    (IN) : Callback function to be called when a frame must be displayed
    125 * @param   pCallbackData (IN) : User defined data that will be passed as parameter of the callback
    126 * @param   clrType       (IN) : Required color type.
    127 * @return  M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
    128 ******************************************************************************/
    129 M4OSA_ERR videoBrowserCreate(
    130         M4OSA_Context* ppContext,
    131         M4OSA_Char* pURL,
    132         M4OSA_UInt32 DrawMode,
    133         M4OSA_FileReadPointer* ptrF,
    134         videoBrowser_Callback pfCallback,
    135         M4OSA_Void* pCallbackData,
    136         VideoBrowser_VideoColorType clrType)
    137 {
    138     VideoBrowserContext* pContext = M4OSA_NULL;
    139     M4READER_MediaFamily mediaFamily = M4READER_kMediaFamilyUnknown;
    140     M4_StreamHandler* pStreamHandler = M4OSA_NULL;
    141     M4_VideoStreamHandler* pVideoStreamHandler = M4OSA_NULL;
    142     M4DECODER_VideoType decoderType;
    143     M4DECODER_OutputFilter FilterOption;
    144 
    145     M4OSA_Bool deb = M4OSA_TRUE;
    146     M4OSA_ERR err = M4NO_ERROR;
    147 
    148     M4OSA_TRACE1_2(
    149         "videoBrowserCreate: entering with 0x%x 0x%x", ppContext, pURL);
    150 
    151     /*--- Sanity checks ---*/
    152     CHECK_PTR(videoBrowserCreate, ppContext, err, M4ERR_PARAMETER);
    153     *ppContext = M4OSA_NULL ;
    154     CHECK_PTR(videoBrowserCreate, pURL,  err, M4ERR_PARAMETER);
    155 
    156     /*--- Create context ---*/
    157     pContext = (VideoBrowserContext*)M4OSA_32bitAlignedMalloc(
    158             sizeof(VideoBrowserContext),
    159             VIDEOBROWSER, (M4OSA_Char*)"Video browser context");
    160 
    161     CHECK_PTR(videoBrowserCreate, pContext,err, M4ERR_ALLOC);
    162     memset((void *)pContext, 0,sizeof(VideoBrowserContext));
    163 
    164     /*--- Initialize the context parameters ---*/
    165     pContext->m_state = VideoBrowser_kVBCreating ;
    166     pContext->m_frameColorType = clrType;
    167 
    168     /*--- Copy the file reader functions ---*/
    169     memcpy((void *)&pContext->m_fileReadPtr,
    170                  (void *)ptrF,
    171                  sizeof(M4OSA_FileReadPointer)) ;
    172 
    173     /* PR#SP00013 DGR bug 13 : first frame is not visible */
    174     pContext->m_drawmode = DrawMode;
    175 
    176 
    177     /* Retrieve the 3gp reader interface */
    178     VideoEditor3gpReader_getInterface(&pContext->m_mediaType,
    179         &pContext->m_3gpReader, &pContext->m_3gpData);
    180 
    181     CHECK_PTR(videoBrowserCreate, pContext->m_3gpReader,  err, M4ERR_ALLOC);
    182     CHECK_PTR(videoBrowserCreate, pContext->m_3gpData,    err, M4ERR_ALLOC);
    183 
    184     /*--- Create the file reader ---*/
    185     err = pContext->m_3gpReader->m_pFctCreate(&pContext->m_pReaderCtx);
    186     CHECK_ERR(videoBrowserCreate, err);
    187     CHECK_PTR(videoBrowserCreate, pContext->m_pReaderCtx, err, M4ERR_ALLOC);
    188     pContext->m_3gpData->m_readerContext = pContext->m_pReaderCtx;
    189 
    190     /*--- Set the OSAL file reader functions ---*/
    191     err = pContext->m_3gpReader->m_pFctSetOption(
    192             pContext->m_pReaderCtx,
    193             M4READER_kOptionID_SetOsaFileReaderFctsPtr,
    194             (M4OSA_DataOption)(&pContext->m_fileReadPtr));
    195 
    196     CHECK_ERR(videoBrowserCreate, err) ;
    197 
    198     /*--- Open the file ---*/
    199     err = pContext->m_3gpReader->m_pFctOpen(pContext->m_pReaderCtx, pURL);
    200     CHECK_ERR(videoBrowserCreate, err) ;
    201 
    202     /*--- Try to find a video stream ---*/
    203     while (err == M4NO_ERROR)
    204     {
    205         err = pContext->m_3gpReader->m_pFctGetNextStream(
    206                 pContext->m_pReaderCtx, &mediaFamily, &pStreamHandler);
    207 
    208         /*in case we found a bifs stream or something else...*/
    209         if ((err == (M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE) ||
    210             (err == (M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS))
    211         {
    212             err = M4NO_ERROR;
    213             continue;
    214         }
    215 
    216         if (err != M4WAR_NO_MORE_STREAM)
    217         {
    218             if (M4READER_kMediaFamilyVideo != mediaFamily)
    219             {
    220                 err = M4NO_ERROR;
    221                 continue;
    222             }
    223 
    224             pContext->m_pStreamHandler = pStreamHandler;
    225 
    226             err = pContext->m_3gpReader->m_pFctReset(
    227                     pContext->m_pReaderCtx, pContext->m_pStreamHandler);
    228 
    229             CHECK_ERR(videoBrowserCreate, err);
    230 
    231             err = pContext->m_3gpReader->m_pFctFillAuStruct(
    232                     pContext->m_pReaderCtx,
    233                     pContext->m_pStreamHandler,
    234                     &pContext->m_accessUnit);
    235 
    236             CHECK_ERR(videoBrowserCreate, err);
    237 
    238             pVideoStreamHandler =
    239                 (M4_VideoStreamHandler*)pContext->m_pStreamHandler;
    240 
    241             switch (pContext->m_pStreamHandler->m_streamType)
    242             {
    243                 case M4DA_StreamTypeVideoMpeg4:
    244                 case M4DA_StreamTypeVideoH263:
    245                 {
    246                     pContext->m_pCodecLoaderContext = M4OSA_NULL;
    247                     decoderType = M4DECODER_kVideoTypeMPEG4;
    248 
    249 #ifdef USE_SOFTWARE_DECODER
    250                         err = VideoEditorVideoDecoder_getSoftwareInterface_MPEG4(
    251                             &decoderType, &pContext->m_pDecoder);
    252 #else
    253                         err = VideoEditorVideoDecoder_getInterface_MPEG4(
    254                             &decoderType, (void **)&pContext->m_pDecoder);
    255 #endif
    256                     CHECK_ERR(videoBrowserCreate, err) ;
    257 
    258                     err = pContext->m_pDecoder->m_pFctCreate(
    259                             &pContext->m_pDecoderCtx,
    260                             pContext->m_pStreamHandler,
    261                             pContext->m_3gpReader,
    262                             pContext->m_3gpData,
    263                             &pContext->m_accessUnit,
    264                             pContext->m_pCodecLoaderContext) ;
    265 
    266                     CHECK_ERR(videoBrowserCreate, err) ;
    267                 }
    268                 break;
    269 
    270                 case M4DA_StreamTypeVideoMpeg4Avc:
    271                 {
    272                     pContext->m_pCodecLoaderContext = M4OSA_NULL;
    273 
    274                     decoderType = M4DECODER_kVideoTypeAVC;
    275 
    276 #ifdef USE_SOFTWARE_DECODER
    277                         err = VideoEditorVideoDecoder_getSoftwareInterface_H264(
    278                             &decoderType, &pContext->m_pDecoder);
    279 #else
    280                         err = VideoEditorVideoDecoder_getInterface_H264(
    281                             &decoderType, (void **)&pContext->m_pDecoder);
    282 #endif
    283                    CHECK_ERR(videoBrowserCreate, err) ;
    284 
    285                     err = pContext->m_pDecoder->m_pFctCreate(
    286                             &pContext->m_pDecoderCtx,
    287                             pContext->m_pStreamHandler,
    288                             pContext->m_3gpReader,
    289                             pContext->m_3gpData,
    290                             &pContext->m_accessUnit,
    291                             pContext->m_pCodecLoaderContext) ;
    292 
    293                     CHECK_ERR(videoBrowserCreate, err) ;
    294                 }
    295                 break;
    296 
    297                 default:
    298                     err = M4ERR_VB_MEDIATYPE_NOT_SUPPORTED;
    299                     goto videoBrowserCreate_cleanUp;
    300             }
    301         }
    302     }
    303 
    304     if (err == M4WAR_NO_MORE_STREAM)
    305     {
    306         err = M4NO_ERROR ;
    307     }
    308 
    309     if (M4OSA_NULL == pContext->m_pStreamHandler)
    310     {
    311         err = M4ERR_VB_NO_VIDEO ;
    312         goto videoBrowserCreate_cleanUp ;
    313     }
    314 
    315     err = pContext->m_pDecoder->m_pFctSetOption(
    316             pContext->m_pDecoderCtx,
    317             M4DECODER_kOptionID_DeblockingFilter,
    318             (M4OSA_DataOption)&deb);
    319 
    320     if (err == M4WAR_DEBLOCKING_FILTER_NOT_IMPLEMENTED)
    321     {
    322         err = M4NO_ERROR;
    323     }
    324     CHECK_ERR(videoBrowserCreate, err);
    325 
    326     FilterOption.m_pFilterUserData = M4OSA_NULL;
    327 
    328 
    329     if (pContext->m_frameColorType == VideoBrowser_kGB565) {
    330         FilterOption.m_pFilterFunction =
    331             (M4OSA_Void*)M4VIFI_ResizeBilinearYUV420toBGR565;
    332     }
    333     else if (pContext->m_frameColorType == VideoBrowser_kYUV420) {
    334         FilterOption.m_pFilterFunction =
    335             (M4OSA_Void*)M4VIFI_ResizeBilinearYUV420toYUV420;
    336     }
    337     else {
    338         err = M4ERR_PARAMETER;
    339         goto videoBrowserCreate_cleanUp;
    340     }
    341 
    342     err = pContext->m_pDecoder->m_pFctSetOption(
    343             pContext->m_pDecoderCtx,
    344             M4DECODER_kOptionID_OutputFilter,
    345             (M4OSA_DataOption)&FilterOption);
    346 
    347     CHECK_ERR(videoBrowserCreate, err);
    348 
    349     /* store the callback details */
    350     pContext->m_pfCallback = pfCallback;
    351     pContext->m_pCallbackUserData = pCallbackData;
    352     /* store the callback details */
    353 
    354     pContext->m_state = VideoBrowser_kVBOpened;
    355     *ppContext = pContext;
    356 
    357     M4OSA_TRACE1_0("videoBrowserCreate returned NO ERROR");
    358     return M4NO_ERROR;
    359 
    360 videoBrowserCreate_cleanUp:
    361 
    362     if (M4OSA_NULL != pContext)
    363     {
    364         if (M4OSA_NULL != pContext->m_pDecoderCtx)
    365         {
    366             pContext->m_pDecoder->m_pFctDestroy(pContext->m_pDecoderCtx);
    367             pContext->m_pDecoderCtx = M4OSA_NULL;
    368         }
    369 
    370         if (M4OSA_NULL != pContext->m_pReaderCtx)
    371         {
    372             pContext->m_3gpReader->m_pFctClose(pContext->m_pReaderCtx);
    373             pContext->m_3gpReader->m_pFctDestroy(pContext->m_pReaderCtx);
    374             pContext->m_pReaderCtx = M4OSA_NULL;
    375         }
    376         SAFE_FREE(pContext->m_pDecoder);
    377         SAFE_FREE(pContext->m_3gpReader);
    378         SAFE_FREE(pContext->m_3gpData);
    379         SAFE_FREE(pContext);
    380     }
    381 
    382     M4OSA_TRACE2_1("videoBrowserCreate returned 0x%x", err);
    383     return err;
    384 }
    385 
    386 /******************************************************************************
    387 * M4OSA_ERR     videoBrowserCleanUp(M4OSA_Context pContext);
    388 * @brief        This function frees the resources needed for browsing a
    389 *               video file.
    390 * @param        pContext     (IN) : Video browser context
    391 * @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE
    392 ******************************************************************************/
    393 M4OSA_ERR videoBrowserCleanUp(M4OSA_Context pContext)
    394 {
    395     VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
    396     M4OSA_ERR err = M4NO_ERROR;
    397 
    398     M4OSA_TRACE2_1("videoBrowserCleanUp: entering with 0x%x", pContext);
    399 
    400     /*--- Sanity checks ---*/
    401     CHECK_PTR(videoBrowserCleanUp, pContext, err, M4ERR_PARAMETER);
    402 
    403     if (M4OSA_NULL != pC->m_pDecoderCtx)
    404     {
    405         pC->m_pDecoder->m_pFctDestroy(pC->m_pDecoderCtx);
    406         pC->m_pDecoderCtx = M4OSA_NULL ;
    407     }
    408 
    409     if (M4OSA_NULL != pC->m_pReaderCtx)
    410     {
    411         pC->m_3gpReader->m_pFctClose(pC->m_pReaderCtx) ;
    412         pC->m_3gpReader->m_pFctDestroy(pC->m_pReaderCtx);
    413         pC->m_pReaderCtx = M4OSA_NULL;
    414     }
    415 
    416     SAFE_FREE(pC->m_pDecoder);
    417     SAFE_FREE(pC->m_3gpReader);
    418     SAFE_FREE(pC->m_3gpData);
    419 
    420     if (pC->m_frameColorType != VideoBrowser_kYUV420) {
    421         SAFE_FREE(pC->m_outputPlane[0].pac_data);
    422     }
    423     SAFE_FREE(pC);
    424 
    425     M4OSA_TRACE2_0("videoBrowserCleanUp returned NO ERROR");
    426     return M4NO_ERROR;
    427 
    428 videoBrowserCleanUp_cleanUp:
    429 
    430     M4OSA_TRACE2_1("videoBrowserCleanUp returned 0x%x", err);
    431     return err;
    432 }
    433 /******************************************************************************
    434 * M4OSA_ERR     videoBrowserPrepareFrame(
    435 *       M4OSA_Context pContext, M4OSA_UInt32* pTime);
    436 * @brief        This function prepares the frame.
    437 * @param        pContext     (IN) : Video browser context
    438 * @param        pTime        (IN/OUT) : Pointer on the time to reach. Updated
    439 *                                       by this function with the reached time
    440 * @param        tolerance    (IN) :  We may decode an earlier frame within the tolerance.
    441 *                                    The time difference is specified in milliseconds.
    442 * @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
    443 ******************************************************************************/
    444 M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime,
    445     M4OSA_UInt32 tolerance)
    446 {
    447     VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
    448     M4OSA_ERR err = M4NO_ERROR;
    449     M4OSA_UInt32 targetTime = 0;
    450     M4_MediaTime timeMS = 0;
    451     M4OSA_Bool bJumpNeeded = M4OSA_FALSE;
    452 
    453     /*--- Sanity checks ---*/
    454     CHECK_PTR(videoBrowserPrepareFrame, pContext, err, M4ERR_PARAMETER);
    455     CHECK_PTR(videoBrowserPrepareFrame, pTime,  err, M4ERR_PARAMETER);
    456 
    457     targetTime = *pTime ;
    458 
    459     /*--- Check the state, if this is the first call to this function
    460           we move to the state "browsing" ---*/
    461     if (VideoBrowser_kVBOpened == pC->m_state)
    462     {
    463         pC->m_state = VideoBrowser_kVBBrowsing;
    464     }
    465     else if (VideoBrowser_kVBBrowsing != pC->m_state)
    466     {
    467         err = M4ERR_STATE ;
    468         goto videoBrowserPrepareFrame_cleanUp;
    469     }
    470 
    471     // If we jump backward or forward to a time greater than current position by
    472     // 85ms (~ 2 frames), we want to jump.
    473     if (pC->m_currentCTS == 0 ||
    474         targetTime < pC->m_currentCTS ||
    475         targetTime > (pC->m_currentCTS + 85))
    476     {
    477         bJumpNeeded = M4OSA_TRUE;
    478     }
    479 
    480     timeMS = (M4_MediaTime)targetTime;
    481     err = pC->m_pDecoder->m_pFctDecode(
    482         pC->m_pDecoderCtx, &timeMS, bJumpNeeded, tolerance);
    483 
    484     if ((err != M4NO_ERROR) && (err != M4WAR_NO_MORE_AU))
    485     {
    486         return err;
    487     }
    488 
    489     err = pC->m_pDecoder->m_pFctRender(
    490         pC->m_pDecoderCtx, &timeMS, pC->m_outputPlane, M4OSA_TRUE);
    491 
    492     if (M4WAR_VIDEORENDERER_NO_NEW_FRAME == err)
    493     {
    494         return err;
    495     }
    496     CHECK_ERR(videoBrowserPrepareFrame, err) ;
    497 
    498     pC->m_currentCTS = (M4OSA_UInt32)timeMS;
    499 
    500     *pTime = pC->m_currentCTS;
    501 
    502     return M4NO_ERROR;
    503 
    504 videoBrowserPrepareFrame_cleanUp:
    505 
    506     if ((M4WAR_INVALID_TIME == err) || (M4WAR_NO_MORE_AU == err))
    507     {
    508         err = M4NO_ERROR;
    509     }
    510     else if (M4OSA_NULL != pC)
    511     {
    512         pC->m_currentCTS = 0;
    513     }
    514 
    515     M4OSA_TRACE2_1("videoBrowserPrepareFrame returned 0x%x", err);
    516     return err;
    517 }
    518 
    519 /******************************************************************************
    520 * M4OSA_ERR     videoBrowserDisplayCurrentFrame(M4OSA_Context pContext);
    521 * @brief        This function displays the current frame.
    522 * @param        pContext     (IN) : Video browser context
    523 * @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
    524 ******************************************************************************/
    525 M4OSA_ERR videoBrowserDisplayCurrentFrame(M4OSA_Context pContext)
    526 {
    527     VideoBrowserContext* pC = (VideoBrowserContext*)pContext ;
    528     M4OSA_ERR err = M4NO_ERROR ;
    529 
    530     /*--- Sanity checks ---*/
    531     CHECK_PTR(videoBrowserDisplayCurrentFrame, pContext, err, M4ERR_PARAMETER);
    532 
    533     // Request display of the frame
    534     pC->m_pfCallback((M4OSA_Context) pC,             // VB context
    535         VIDEOBROWSER_DISPLAY_FRAME,                  // action requested
    536         M4NO_ERROR,                                  // error code
    537         (M4OSA_Void*) &(pC->m_outputPlane[0]),       // image to be displayed
    538         (M4OSA_Void*) pC->m_pCallbackUserData);      // user-provided data
    539 
    540 #ifdef DUMPTOFILE
    541     {
    542         M4OSA_Context fileContext;
    543         M4OSA_Char* fileName = "/sdcard/textBuffer_RGB565.rgb";
    544         M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,
    545             M4OSA_kFileWrite | M4OSA_kFileCreate);
    546 
    547         M4OSA_fileWriteData(fileContext,
    548             (M4OSA_MemAddr8) pC->m_outputPlane[0].pac_data,
    549             pC->m_outputPlane[0].u_height*pC->m_outputPlane[0].u_width*2);
    550 
    551         M4OSA_fileWriteClose(fileContext);
    552     }
    553 #endif
    554 
    555     M4OSA_TRACE2_0("videoBrowserDisplayCurrentFrame returned NO ERROR") ;
    556     return M4NO_ERROR;
    557 
    558 videoBrowserDisplayCurrentFrame_cleanUp:
    559 
    560     M4OSA_TRACE2_1("videoBrowserDisplayCurrentFrame returned 0x%x", err) ;
    561     return err;
    562 }
    563