563 lines
20 KiB
C
Executable File
563 lines
20 KiB
C
Executable File
/*
|
|
* 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;
|
|
}
|