| /* |
| * 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 <jni.h> |
| #include <JNIHelp.h> |
| #include <utils/Log.h> |
| #include "VideoBrowserMain.h" |
| #include "VideoBrowserInternal.h" |
| |
| #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 |
| |
| /* |
| * Memory format of 'ARGB8888' in skia is RGBA, so ABGR in 32bit little-endian packed format |
| * bitmap format is rgb565 |
| */ |
| // RED GREEN BLUE ALPHA |
| #define RGB565toSKCOLOR(c) ( (((c)&0xF800)>>8) | (((c)&0x7E0)<<5) | (((c)&0x1F)<<19) | 0xFF000000) |
| |
| #define GetIntField(env, obj, name) env->GetIntField(obj,\ |
| env->GetFieldID(env->GetObjectClass(obj), name, "I")) |
| |
| extern "C" M4OSA_ERR NXPSW_FileReaderOptim_init(M4OSA_Void *lowLevel_functionPointers, |
| M4OSA_Void *optimized_functionPointers); |
| |
| /* |
| * Video Browser execution context. |
| * Based on request for RGB565 or RGB888, m_dst16 or m_dst32 |
| * will be initialized and used |
| */ |
| typedef struct |
| { |
| M4OSA_Context m_pVideoBrowser; |
| M4OSA_UInt32 m_previousTime; |
| M4OSA_Int32* m_dst32; |
| M4OSA_Int16* m_dst16; |
| unsigned int m_width; |
| unsigned int m_height; |
| M4OSA_Bool m_bRender; |
| } ThumbnailContext; |
| |
| /** |
| ************************************************************************ |
| * @brief Interface to retrieve the thumbnail pixels |
| * @param pContext (IN) Thumbnail Context. |
| * @param width (IN) Width of thumbnail |
| * @param height (IN) Height of thumbnail |
| * @param pTimeMS (IN/OUT)Time stamp at which thumbnail is retrieved. |
| ************************************************************************ |
| */ |
| M4OSA_ERR ThumbnailGetPixels(const M4OSA_Context pContext, |
| M4OSA_Int32* pixelArray, |
| M4OSA_UInt32 width, M4OSA_UInt32 height, |
| M4OSA_UInt32* pTimeMS); |
| |
| |
| /** |
| ************************************************************************ |
| * @brief Video browser callback, called when a frame must be displayed |
| * @param pInstance (IN) Thumbnail context. |
| * @param notificationID (IN) Id of the callback which generated the error |
| * @param errCode (IN) Error code from the Core |
| * @param pCbData (IN) pointer to data associated wit the callback. |
| * @param pCbUserData (IN) pointer to application user data passed in init. |
| * @note This callback mechanism is used to request display of an image |
| ************************************************************************ |
| */ |
| M4OSA_Void VBcallback( M4OSA_Context pInstance, |
| VideoBrowser_Notification notificationID, |
| M4OSA_ERR errCode, M4OSA_Void* pCbData, |
| M4OSA_Void* pCallbackUserData) |
| { |
| M4OSA_UInt32 i, j; |
| M4OSA_ERR err; |
| |
| M4OSA_TRACE3_0("inside VBcallback"); |
| M4VIFI_ImagePlane* pPlane=NULL; |
| M4OSA_UInt16* src=NULL; |
| ThumbnailContext* pC = NULL; |
| |
| CHECK_PTR(VBcallback, pCbData, err, M4ERR_PARAMETER); |
| CHECK_PTR(VBcallback, pInstance,err, M4ERR_PARAMETER); |
| |
| pC = (ThumbnailContext*)pCallbackUserData ; |
| CHECK_PTR(VBcallback, pC->m_pVideoBrowser, err, M4ERR_PARAMETER); |
| |
| pPlane = (M4VIFI_ImagePlane*)pCbData; |
| src = (M4OSA_UInt16*)pPlane->pac_data; |
| |
| if (pC->m_dst32 != NULL) |
| { |
| M4OSA_Int32* dst = pC->m_dst32; |
| |
| for (j = 0; j < pPlane->u_height; j++) |
| { |
| for (i = 0; i < pPlane->u_width; i++) |
| { |
| dst[i] = RGB565toSKCOLOR(src[i]); |
| } |
| for (i = pPlane->u_width; i < pC->m_width; i++) |
| { |
| dst[i] = 0; |
| } |
| src = (M4OSA_UInt16*)((M4OSA_UInt8*)src + pPlane->u_stride); |
| dst += pC->m_width; |
| } |
| } |
| else if (pC->m_dst16 != NULL) |
| { |
| M4OSA_Int16* dst = pC->m_dst16; |
| |
| for (j = 0; j < pPlane->u_height; j++) |
| { |
| memcpy((void * )dst, (void * )src, pPlane->u_stride); |
| for (i = pPlane->u_width; i < pC->m_width; i++) |
| { |
| dst[i] = 0; |
| } |
| src = (M4OSA_UInt16*)((M4OSA_UInt8*)src + pPlane->u_stride); |
| dst += pC->m_width; |
| } |
| } |
| else |
| { |
| CHECK_PTR(VBcallback, NULL, err, M4ERR_PARAMETER); |
| } |
| |
| VBcallback_cleanUp: |
| |
| return; |
| } |
| |
| M4OSA_ERR ThumbnailOpen(M4OSA_Context *pPContext, |
| const M4OSA_Char *pString, |
| M4OSA_Bool bRender) |
| { |
| |
| M4OSA_ERR err; |
| ThumbnailContext *pContext = M4OSA_NULL; |
| VideoBrowser_VideoColorType vbColorType; |
| |
| CHECK_PTR(ThumbnailOpen, pString, err, M4ERR_BAD_CONTEXT); |
| |
| /*--- Create context ---*/ |
| pContext = (ThumbnailContext*)M4OSA_malloc(sizeof(ThumbnailContext), VIDEOBROWSER, |
| (M4OSA_Char*)"Thumbnail context") ; |
| M4OSA_TRACE3_1("context value is = %d",pContext); |
| CHECK_PTR(ThumbnailOpen, pContext, err, M4ERR_ALLOC); |
| |
| memset((void *)pContext, 0,sizeof(ThumbnailContext)); |
| |
| M4OSA_FileReadPointer optFP; |
| M4OSA_FileReadPointer llFP; |
| |
| NXPSW_FileReaderOptim_init(&llFP, &optFP); |
| M4OSA_TRACE1_2("ThumbnailOpen: entering videoBrowserCreate with 0x%x %s", |
| &pContext->m_pVideoBrowser, pString) ; |
| |
| pContext->m_bRender = bRender; |
| if (bRender == M4OSA_TRUE) { |
| //Open is called for rendering the frame. |
| //So set YUV420 as the output color format. |
| vbColorType = VideoBrowser_kYUV420; |
| } else { |
| //Open is called for thumbnail Extraction |
| //So set BGR565 as the output. |
| vbColorType = VideoBrowser_kGB565; |
| } |
| |
| err = videoBrowserCreate(&pContext->m_pVideoBrowser, (M4OSA_Char*)pString, |
| VideoBrowser_kVBNormalBliting, &optFP, VBcallback, pContext, vbColorType); |
| |
| M4OSA_TRACE1_1("err value is = 0x%x",err); |
| CHECK_ERR(ThumbnailOpen, err); |
| CHECK_PTR(ThumbnailOpen, pContext->m_pVideoBrowser, err, M4ERR_ALLOC); |
| |
| *pPContext = pContext; |
| M4OSA_TRACE1_1("context value is = %d",*pPContext); |
| |
| return M4NO_ERROR; |
| |
| ThumbnailOpen_cleanUp: |
| |
| M4OSA_TRACE1_0("i am inside cleanUP"); |
| if (M4OSA_NULL != pContext) |
| { |
| if (M4OSA_NULL != pContext->m_pVideoBrowser) |
| { |
| videoBrowserCleanUp(pContext->m_pVideoBrowser) ; |
| } |
| M4OSA_free((M4OSA_MemAddr32)pContext) ; |
| } |
| return err; |
| } |
| |
| M4OSA_ERR ThumbnailGetPixels(const M4OSA_Context pContext, |
| M4OSA_Int32* pixelArray, |
| M4OSA_UInt32 width, M4OSA_UInt32 height, |
| M4OSA_UInt32* pTimeMS) |
| { |
| M4OSA_ERR err; |
| |
| ThumbnailContext* pC = (ThumbnailContext*)pContext; |
| |
| if ((pC->m_width != width) || (pC->m_height != height)) |
| { |
| err = videoBrowserSetWindow(pC->m_pVideoBrowser, pixelArray, |
| 0, 0, width, height); |
| CHECK_ERR(ThumbnailGetPixels, err); |
| pC->m_width = width; |
| pC->m_height = height; |
| } |
| |
| // Alter the pTimeMS to a valid value at which a frame is found |
| // m_currentCTS has the actual frame time stamp just ahead of the |
| // pTimeMS supplied. |
| if ((((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS != 0) && |
| (*pTimeMS >= pC->m_previousTime) && |
| (*pTimeMS < ((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS)) |
| { |
| pC->m_previousTime = *pTimeMS; |
| *pTimeMS = ((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS; |
| } |
| else |
| { |
| pC->m_previousTime = *pTimeMS; |
| } |
| |
| err = videoBrowserPrepareFrame(pC->m_pVideoBrowser, pTimeMS); |
| CHECK_ERR(ThumbnailGetPixels, err); |
| |
| if (pC->m_bRender != M4OSA_TRUE) { |
| err = videoBrowserDisplayCurrentFrame(pC->m_pVideoBrowser); |
| CHECK_ERR(ThumbnailGetPixels, err); |
| } |
| |
| ThumbnailGetPixels_cleanUp: |
| |
| return err; |
| } |
| |
| M4OSA_ERR ThumbnailGetPixels32(const M4OSA_Context pContext, |
| M4OSA_Int32* pixelArray, M4OSA_UInt32 width, |
| M4OSA_UInt32 height, M4OSA_UInt32* timeMS) |
| { |
| |
| M4OSA_ERR err = M4NO_ERROR; |
| |
| ThumbnailContext* pC = (ThumbnailContext*)pContext; |
| |
| CHECK_PTR(ThumbnailGetPixels32, pC->m_pVideoBrowser, err, M4ERR_ALLOC) ; |
| CHECK_PTR(ThumbnailGetPixels32, pixelArray, err, M4ERR_ALLOC) ; |
| |
| pC->m_dst16 = NULL; |
| pC->m_dst32 = pixelArray; |
| |
| err = ThumbnailGetPixels(pContext, pixelArray, width, height, timeMS); |
| |
| ThumbnailGetPixels32_cleanUp: |
| |
| return err; |
| } |
| |
| M4OSA_ERR ThumbnailGetPixels16(const M4OSA_Context pContext, |
| M4OSA_Int16* pixelArray, M4OSA_UInt32 width, |
| M4OSA_UInt32 height, M4OSA_UInt32* timeMS) |
| { |
| M4OSA_ERR err = M4NO_ERROR; |
| |
| ThumbnailContext* pC = (ThumbnailContext*)pContext; |
| |
| CHECK_PTR(ThumbnailGetPixels16, pC->m_pVideoBrowser, err, M4ERR_ALLOC); |
| CHECK_PTR(ThumbnailGetPixels16, pixelArray, err, M4ERR_ALLOC); |
| |
| pC->m_dst16 = pixelArray; |
| pC->m_dst32 = NULL; |
| |
| err = ThumbnailGetPixels(pContext, (M4OSA_Int32*)pixelArray, width, height, timeMS); |
| |
| ThumbnailGetPixels16_cleanUp: |
| |
| return err; |
| } |
| |
| |
| void ThumbnailClose(const M4OSA_Context pContext) |
| { |
| M4OSA_ERR err; |
| |
| ThumbnailContext* pC = (ThumbnailContext*)pContext; |
| |
| CHECK_PTR(ThumbnailClose, pC, err, M4ERR_ALLOC); |
| |
| if (M4OSA_NULL != pC) |
| { |
| if (M4OSA_NULL != pC->m_pVideoBrowser) |
| { |
| videoBrowserCleanUp(pC->m_pVideoBrowser); |
| } |
| M4OSA_free((M4OSA_MemAddr32)pC); |
| } |
| |
| ThumbnailClose_cleanUp: |
| |
| return; |
| } |
| |