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