VideoBrowserMain.c revision cd196d3727db641e581d4223815367a5ca5d5637
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 ******************************************************************************/
50M4OSA_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_malloc(
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
113videoBrowserSetWindow_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******************************************************************************/
129M4OSA_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_malloc(
158            sizeof(VideoBrowserContext),
159            VIDEOBROWSER, (M4OSA_Char*)"Video browser context");
160
161    CHECK_PTR(videoBrowserCreate, pContext,err, M4ERR_ALLOC);
162    M4OSA_memset((M4OSA_MemAddr8)pContext, sizeof(VideoBrowserContext), 0);
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    M4OSA_memcpy((M4OSA_MemAddr8)&pContext->m_fileReadPtr,
170                 (M4OSA_MemAddr8)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 == M4ERR_READER_UNKNOWN_STREAM_TYPE) ||
210            (err == 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                    err = VideoEditorVideoDecoder_getInterface_MPEG4(
250                        &decoderType, &pContext->m_pDecoder);
251
252                    CHECK_ERR(videoBrowserCreate, err) ;
253
254                    err = pContext->m_pDecoder->m_pFctCreate(
255                            &pContext->m_pDecoderCtx,
256                            pContext->m_pStreamHandler,
257                            pContext->m_3gpData,
258                            &pContext->m_accessUnit,
259                            pContext->m_pCodecLoaderContext) ;
260
261                    CHECK_ERR(videoBrowserCreate, err) ;
262                }
263                break;
264
265                case M4DA_StreamTypeVideoMpeg4Avc:
266                {
267                    pContext->m_pCodecLoaderContext = M4OSA_NULL;
268
269                    decoderType = M4DECODER_kVideoTypeAVC;
270                    err = VideoEditorVideoDecoder_getInterface_H264(
271                        &decoderType, &pContext->m_pDecoder);
272                   CHECK_ERR(videoBrowserCreate, err) ;
273
274                    err = pContext->m_pDecoder->m_pFctCreate(
275                            &pContext->m_pDecoderCtx,
276                            pContext->m_pStreamHandler,
277                            pContext->m_3gpData,
278                            &pContext->m_accessUnit,
279                            pContext->m_pCodecLoaderContext) ;
280
281                    CHECK_ERR(videoBrowserCreate, err) ;
282                }
283                break;
284
285                default:
286                    err = M4ERR_VB_MEDIATYPE_NOT_SUPPORTED;
287                    goto videoBrowserCreate_cleanUp;
288            }
289        }
290    }
291
292    if (err == M4WAR_NO_MORE_STREAM)
293    {
294        err = M4NO_ERROR ;
295    }
296
297    if (M4OSA_NULL == pContext->m_pStreamHandler)
298    {
299        err = M4ERR_VB_NO_VIDEO ;
300        goto videoBrowserCreate_cleanUp ;
301    }
302
303    err = pContext->m_pDecoder->m_pFctSetOption(
304            pContext->m_pDecoderCtx,
305            M4DECODER_kOptionID_DeblockingFilter,
306            (M4OSA_DataOption)&deb);
307
308    if (err == M4WAR_DEBLOCKING_FILTER_NOT_IMPLEMENTED)
309    {
310        err = M4NO_ERROR;
311    }
312    CHECK_ERR(videoBrowserCreate, err);
313
314    FilterOption.m_pFilterUserData = M4OSA_NULL;
315
316
317    if (pContext->m_frameColorType == VideoBrowser_kGB565) {
318        FilterOption.m_pFilterFunction =
319            (M4OSA_Void*)M4VIFI_ResizeBilinearYUV420toBGR565;
320    }
321    else if (pContext->m_frameColorType == VideoBrowser_kYUV420) {
322        FilterOption.m_pFilterFunction =
323            (M4OSA_Void*)M4VIFI_ResizeBilinearYUV420toYUV420;
324    }
325    else {
326        err = M4ERR_PARAMETER;
327        goto videoBrowserCreate_cleanUp;
328    }
329
330    err = pContext->m_pDecoder->m_pFctSetOption(
331            pContext->m_pDecoderCtx,
332            M4DECODER_kOptionID_OutputFilter,
333            (M4OSA_DataOption)&FilterOption);
334
335    CHECK_ERR(videoBrowserCreate, err);
336
337    /* store the callback details */
338    pContext->m_pfCallback = pfCallback;
339    pContext->m_pCallbackUserData = pCallbackData;
340    /* store the callback details */
341
342    pContext->m_state = VideoBrowser_kVBOpened;
343    *ppContext = pContext;
344
345    M4OSA_TRACE1_0("videoBrowserCreate returned NO ERROR");
346    return M4NO_ERROR;
347
348videoBrowserCreate_cleanUp:
349
350    if (M4OSA_NULL != pContext)
351    {
352        if (M4OSA_NULL != pContext->m_pDecoderCtx)
353        {
354            pContext->m_pDecoder->m_pFctDestroy(pContext->m_pDecoderCtx);
355            pContext->m_pDecoderCtx = M4OSA_NULL;
356        }
357
358        if (M4OSA_NULL != pContext->m_pReaderCtx)
359        {
360            pContext->m_3gpReader->m_pFctClose(pContext->m_pReaderCtx);
361            pContext->m_3gpReader->m_pFctDestroy(pContext->m_pReaderCtx);
362            pContext->m_pReaderCtx = M4OSA_NULL;
363        }
364        SAFE_FREE(pContext->m_pDecoder);
365        SAFE_FREE(pContext->m_3gpReader);
366        SAFE_FREE(pContext->m_3gpData);
367        SAFE_FREE(pContext);
368    }
369
370    M4OSA_TRACE2_1("videoBrowserCreate returned 0x%x", err);
371    return err;
372}
373
374/******************************************************************************
375* M4OSA_ERR     videoBrowserCleanUp(M4OSA_Context pContext);
376* @brief        This function frees the resources needed for browsing a
377*               video file.
378* @param        pContext     (IN) : Video browser context
379* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE
380******************************************************************************/
381M4OSA_ERR videoBrowserCleanUp(M4OSA_Context pContext)
382{
383    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
384    M4OSA_ERR err = M4NO_ERROR;
385
386    M4OSA_TRACE2_1("videoBrowserCleanUp: entering with 0x%x", pContext);
387
388    /*--- Sanity checks ---*/
389    CHECK_PTR(videoBrowserCleanUp, pContext, err, M4ERR_PARAMETER);
390
391    if (M4OSA_NULL != pC->m_pDecoderCtx)
392    {
393        pC->m_pDecoder->m_pFctDestroy(pC->m_pDecoderCtx);
394        pC->m_pDecoderCtx = M4OSA_NULL ;
395    }
396
397    if (M4OSA_NULL != pC->m_pReaderCtx)
398    {
399        pC->m_3gpReader->m_pFctClose(pC->m_pReaderCtx) ;
400        pC->m_3gpReader->m_pFctDestroy(pC->m_pReaderCtx);
401        pC->m_pReaderCtx = M4OSA_NULL;
402    }
403
404    SAFE_FREE(pC->m_pDecoder);
405    SAFE_FREE(pC->m_3gpReader);
406    SAFE_FREE(pC->m_3gpData);
407
408    if (pC->m_frameColorType != VideoBrowser_kYUV420) {
409        SAFE_FREE(pC->m_outputPlane[0].pac_data);
410    }
411    SAFE_FREE(pC);
412
413    M4OSA_TRACE2_0("videoBrowserCleanUp returned NO ERROR");
414    return M4NO_ERROR;
415
416videoBrowserCleanUp_cleanUp:
417
418    M4OSA_TRACE2_1("videoBrowserCleanUp returned 0x%x", err);
419    return err;
420}
421/******************************************************************************
422* M4OSA_ERR     videoBrowserPrepareFrame(
423*       M4OSA_Context pContext, M4OSA_UInt32* pTime);
424* @brief        This function prepares the frame.
425* @param        pContext     (IN) : Video browser context
426* @param        pTime        (IN/OUT) : Pointer on the time to reach. Updated
427*                                       by this function with the reached time
428* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
429******************************************************************************/
430M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime)
431{
432    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
433    M4OSA_ERR err = M4NO_ERROR;
434    M4OSA_UInt32 targetTime = 0;
435    M4OSA_UInt32 jumpTime = 0;
436    M4_MediaTime timeMS = 0;
437    M4OSA_Int32 rapTime = 0;
438    M4OSA_Bool isBackward = M4OSA_FALSE;
439    M4OSA_Bool bJumpNeeded = M4OSA_FALSE;
440
441
442    /*--- Sanity checks ---*/
443    CHECK_PTR(videoBrowserPrepareFrame, pContext, err, M4ERR_PARAMETER);
444    CHECK_PTR(videoBrowserPrepareFrame, pTime,  err, M4ERR_PARAMETER);
445
446    targetTime = *pTime ;
447
448    /*--- Check the state, if this is the first call to this function
449          we move to the state "browsing" ---*/
450    if (VideoBrowser_kVBOpened == pC->m_state)
451    {
452        pC->m_state = VideoBrowser_kVBBrowsing;
453    }
454    else if (VideoBrowser_kVBBrowsing != pC->m_state)
455    {
456        err = M4ERR_STATE ;
457        goto videoBrowserPrepareFrame_cleanUp;
458    }
459
460    /*--- Check the duration ---*/
461    /*--- If we jump backward, we need to jump ---*/
462    if (targetTime < pC->m_currentCTS)
463    {
464        isBackward = M4OSA_TRUE;
465        bJumpNeeded = M4OSA_TRUE;
466    }
467    /*--- If we jumpt to a time greater than "currentTime" + "predecodeTime"
468          we need to jump ---*/
469    else if (targetTime > (pC->m_currentCTS + VIDEO_BROWSER_PREDECODE_TIME))
470    {
471        bJumpNeeded = M4OSA_TRUE;
472    }
473
474    if (M4OSA_TRUE == bJumpNeeded)
475    {
476        rapTime = targetTime;
477        /*--- Retrieve the previous RAP time ---*/
478        err = pC->m_3gpReader->m_pFctGetPrevRapTime(
479                pC->m_pReaderCtx, pC->m_pStreamHandler, &rapTime);
480
481        CHECK_ERR(videoBrowserPrepareFrame, err);
482
483        jumpTime = rapTime;
484
485        err = pC->m_3gpReader->m_pFctJump(pC->m_pReaderCtx,
486                                          pC->m_pStreamHandler,
487                                          (M4OSA_Int32*)&jumpTime);
488        CHECK_ERR(videoBrowserPrepareFrame, err);
489    }
490
491    timeMS = (M4_MediaTime)targetTime;
492    err = pC->m_pDecoder->m_pFctDecode(
493        pC->m_pDecoderCtx, &timeMS, bJumpNeeded);
494
495    if ((err != M4NO_ERROR) && (err != M4WAR_NO_MORE_AU))
496    {
497        return err;
498    }
499
500    // FIXME:
501    // Not sure that I understand why we need a second jump logic here
502    if ((timeMS >= pC->m_currentCTS) && (M4OSA_TRUE == isBackward))
503    {
504        jumpTime = rapTime;
505        err = pC->m_3gpReader->m_pFctJump(
506            pC->m_pReaderCtx, pC->m_pStreamHandler, (M4OSA_Int32*)&jumpTime);
507
508        CHECK_ERR(videoBrowserPrepareFrame, err);
509
510        timeMS = (M4_MediaTime)rapTime;
511        err = pC->m_pDecoder->m_pFctDecode(
512            pC->m_pDecoderCtx, &timeMS, M4OSA_TRUE);
513
514        if ((err != M4NO_ERROR) && (err != M4WAR_NO_MORE_AU))
515        {
516            return err;
517        }
518    }
519
520    err = pC->m_pDecoder->m_pFctRender(
521        pC->m_pDecoderCtx, &timeMS, pC->m_outputPlane, M4OSA_TRUE);
522
523    if (M4WAR_VIDEORENDERER_NO_NEW_FRAME == err)
524    {
525        err = M4NO_ERROR;
526    }
527    CHECK_ERR(videoBrowserPrepareFrame, err) ;
528
529    pC->m_currentCTS = (M4OSA_UInt32)timeMS;
530
531    *pTime = pC->m_currentCTS;
532
533    return M4NO_ERROR;
534
535videoBrowserPrepareFrame_cleanUp:
536
537    if ((M4WAR_INVALID_TIME == err) || (M4WAR_NO_MORE_AU == err))
538    {
539        err = M4NO_ERROR;
540    }
541    else if (M4OSA_NULL != pC)
542    {
543        pC->m_currentCTS = 0;
544    }
545
546    M4OSA_TRACE2_1("videoBrowserPrepareFrame returned 0x%x", err);
547    return err;
548}
549
550/******************************************************************************
551* M4OSA_ERR     videoBrowserDisplayCurrentFrame(M4OSA_Context pContext);
552* @brief        This function displays the current frame.
553* @param        pContext     (IN) : Video browser context
554* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
555******************************************************************************/
556M4OSA_ERR videoBrowserDisplayCurrentFrame(M4OSA_Context pContext)
557{
558    VideoBrowserContext* pC = (VideoBrowserContext*)pContext ;
559    M4OSA_ERR err = M4NO_ERROR ;
560
561    /*--- Sanity checks ---*/
562    CHECK_PTR(videoBrowserDisplayCurrentFrame, pContext, err, M4ERR_PARAMETER);
563
564    // Request display of the frame
565    pC->m_pfCallback((M4OSA_Context) pC,             // VB context
566        VIDEOBROWSER_DISPLAY_FRAME,                  // action requested
567        M4NO_ERROR,                                  // error code
568        (M4OSA_Void*) &(pC->m_outputPlane[0]),       // image to be displayed
569        (M4OSA_Void*) pC->m_pCallbackUserData);      // user-provided data
570
571#ifdef DUMPTOFILE
572    {
573        M4OSA_Context fileContext;
574        M4OSA_Char* fileName = "/sdcard/textBuffer_RGB565.rgb";
575        M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,
576            M4OSA_kFileWrite | M4OSA_kFileCreate);
577
578        M4OSA_fileWriteData(fileContext,
579            (M4OSA_MemAddr8) pC->m_outputPlane[0].pac_data,
580            pC->m_outputPlane[0].u_height*pC->m_outputPlane[0].u_width*2);
581
582        M4OSA_fileWriteClose(fileContext);
583    }
584#endif
585
586    M4OSA_TRACE2_0("videoBrowserDisplayCurrentFrame returned NO ERROR") ;
587    return M4NO_ERROR;
588
589videoBrowserDisplayCurrentFrame_cleanUp:
590
591    M4OSA_TRACE2_1("videoBrowserDisplayCurrentFrame returned 0x%x", err) ;
592    return err;
593}
594