diff options
| -rwxr-xr-x | media/jni/mediaeditor/Android.mk | 92 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoBrowserInternal.h | 131 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoBrowserMain.c | 593 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoBrowserMain.h | 163 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorClasses.cpp | 3174 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorClasses.h | 589 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorJava.cpp | 885 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorJava.h | 506 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorLogging.h | 55 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorMain.cpp | 3056 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorMain.h | 69 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorOsal.cpp | 359 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorOsal.h | 65 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorPropertiesMain.cpp | 502 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorThumbnailMain.cpp | 330 | ||||
| -rwxr-xr-x | media/jni/mediaeditor/VideoEditorThumbnailMain.h | 76 |
16 files changed, 10645 insertions, 0 deletions
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk new file mode 100755 index 000000000000..9d6e7d4073ca --- /dev/null +++ b/media/jni/mediaeditor/Android.mk @@ -0,0 +1,92 @@ +# +# 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. +# + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + VideoEditorMain.cpp \ + VideoEditorClasses.cpp \ + VideoEditorOsal.cpp \ + VideoEditorJava.cpp \ + VideoEditorPropertiesMain.cpp \ + VideoEditorThumbnailMain.cpp \ + VideoBrowserMain.c + +LOCAL_C_INCLUDES += \ + $(TOP)/frameworks/base/core/jni \ + $(TOP)/frameworks/base/include \ + $(TOP)/frameworks/base/include/media \ + $(TOP)/frameworks/base/media/libmediaplayerservice \ + $(TOP)/frameworks/base/media/libstagefright \ + $(TOP)/frameworks/base/media/libstagefright/include \ + $(TOP)/frameworks/base/media/libstagefright/rtsp \ + $(JNI_H_INCLUDE) \ + $(call include-path-for, corecg graphics) \ + $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \ + $(TOP)/external/opencore/android \ + $(TOP)/vendor/qcom/proprietary/qdsp6/mm-core/omxcore/inc \ + $(TOP)/frameworks/base/core/jni/mediaeditor \ + $(TOP)/frameworks/media/libvideoeditor/vss/inc \ + $(TOP)/frameworks/media/libvideoeditor/vss/common/inc \ + $(TOP)/frameworks/media/libvideoeditor/vss/mcs/inc \ + $(TOP)/frameworks/media/libvideoeditor/vss/stagefrightshells/inc \ + $(TOP)/frameworks/media/libvideoeditor/lvpp \ + $(TOP)/frameworks/media/libvideoeditor/osal/inc + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libutils \ + libandroid_runtime \ + libnativehelper \ + libmedia \ + libbinder \ + libstagefright \ + libstagefright_omx \ + libsurfaceflinger_client \ + libvideoeditorplayer + + +LOCAL_CFLAGS += \ + -DUSE_STAGEFRIGHT_CODECS \ + -DUSE_STAGEFRIGHT_AUDIODEC \ + -DUSE_STAGEFRIGHT_VIDEODEC \ + -DUSE_STAGEFRIGHT_AUDIOENC \ + -DUSE_STAGEFRIGHT_VIDEOENC \ + -DUSE_STAGEFRIGHT_READERS \ + -DUSE_STAGEFRIGHT_3GPP_READER + + +LOCAL_LDFLAGS += -fuse-ld=bfd + +LOCAL_STATIC_LIBRARIES := \ + libvideoeditor_core \ + libstagefright_color_conversion \ + libvideoeditor_3gpwriter \ + libvideoeditor_mcs \ + libvideoeditor_videofilters \ + libvideoeditor_stagefrightshells \ + libvideoeditor_osal + +LOCAL_MODULE:= libvideoeditor_jni + +# Don't prelink this library. For more efficient code, you may want +# to add this library to the prelink map and set this to true. +LOCAL_PRELINK_MODULE := false + +LOCAL_MODULE_TAGS := eng development + +include $(BUILD_SHARED_LIBRARY) diff --git a/media/jni/mediaeditor/VideoBrowserInternal.h b/media/jni/mediaeditor/VideoBrowserInternal.h new file mode 100755 index 000000000000..ed63129ca3cd --- /dev/null +++ b/media/jni/mediaeditor/VideoBrowserInternal.h @@ -0,0 +1,131 @@ +/* + * 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. + */ + + +#ifndef VIDEO_BROWSER_INTERNAL_H +#define VIDEO_BROWSER_INTERNAL_H + +#include "VideoBrowserMain.h" + +#include "M4READER_Common.h" +#include "M4DECODER_Common.h" + + +#define VIDEO_BROWSER_BGR565 + + +#define VIDEO_BROWSER_PREDECODE_TIME 2000 /* In miliseconds */ + +/*---------------------------- MACROS ----------------------------*/ +#define CHECK_PTR(fct, p, err, errValue) \ +{ \ + if (M4OSA_NULL == p) \ + { \ + err = errValue ; \ + M4OSA_TRACE1_1("" #fct "(L%d): " #p " is NULL, returning " #errValue "", __LINE__) ; \ + goto fct##_cleanUp; \ + } \ +} + +#define CHECK_ERR(fct, err) \ +{ \ + if (M4OSA_ERR_IS_ERROR(err)) \ + { \ + M4OSA_TRACE1_2("" #fct "(L%d): ERROR 0x%.8x returned", __LINE__,err) ; \ + goto fct##_cleanUp; \ + } \ + else if (M4OSA_ERR_IS_WARNING(err)) \ + { \ + M4OSA_TRACE2_2("" #fct "(L%d): WARNING 0x%.8x returned", __LINE__,err) ; \ + } \ +} + +#define CHECK_STATE(fct, state, pC) \ +{ \ + if (state != pC->m_state) \ + { \ + M4OSA_TRACE1_1("" #fct " called in bad state %d", pC->m_state) ; \ + err = M4ERR_STATE ; \ + goto fct##_cleanUp; \ + } \ +} + +#define SAFE_FREE(p) \ +{ \ + if (M4OSA_NULL != p) \ + { \ + M4OSA_free((M4OSA_MemAddr32)p) ; \ + p = M4OSA_NULL ; \ + } \ +} + +/*--- Video Browser state ---*/ +typedef enum +{ + VideoBrowser_kVBCreating, + VideoBrowser_kVBOpened, + VideoBrowser_kVBBrowsing +} VideoBrowser_videoBrowerState; + + +/*--- Video Browser execution context. ---*/ +typedef struct +{ + VideoBrowser_videoBrowerState m_state ; + VideoBrowser_videoBrowerDrawMode m_drawmode; + + M4OSA_Context g_hbmp2; + M4OSA_Context dc; + M4OSA_Int16* g_bmPixels2; + + /*--- Reader parameters ---*/ + M4OSA_FileReadPointer m_fileReadPtr; + M4READER_GlobalInterface* m_3gpReader ; + M4READER_DataInterface* m_3gpData ; + M4READER_MediaType m_mediaType ; + M4OSA_Context m_pReaderCtx ; + + M4_StreamHandler* m_pStreamHandler ; + M4_AccessUnit m_accessUnit ; + + /*--- Decoder parameters ---*/ + M4DECODER_VideoInterface* m_pDecoder ; + M4OSA_Context m_pDecoderCtx ; + + /*--- Common display parameters ---*/ + M4OSA_UInt32 m_x ; + M4OSA_UInt32 m_y ; + M4VIFI_ImagePlane m_outputPlane[3] ; + + /*--- Current browsing time ---*/ + M4OSA_UInt32 m_currentCTS ; + + /*--- Platform dependent display parameters ---*/ + M4OSA_Context m_pCoreContext ; + + /*--- Callback function settings ---*/ + videoBrowser_Callback m_pfCallback; + M4OSA_Void* m_pCallbackUserData; + + /*--- Codec Loader core context ---*/ + M4OSA_Context m_pCodecLoaderContext; + + /*--- Required color type ---*/ + VideoBrowser_VideoColorType m_frameColorType; + +} VideoBrowserContext; + +#endif /* VIDEO_BROWSER_INTERNAL_H */ diff --git a/media/jni/mediaeditor/VideoBrowserMain.c b/media/jni/mediaeditor/VideoBrowserMain.c new file mode 100755 index 000000000000..0d40f5638ec6 --- /dev/null +++ b/media/jni/mediaeditor/VideoBrowserMain.c @@ -0,0 +1,593 @@ +/* + * 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_malloc( + 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_malloc( + sizeof(VideoBrowserContext), + VIDEOBROWSER, (M4OSA_Char*)"Video browser context"); + + CHECK_PTR(videoBrowserCreate, pContext,err, M4ERR_ALLOC); + M4OSA_memset((M4OSA_MemAddr8)pContext, sizeof(VideoBrowserContext), 0); + + /*--- Initialize the context parameters ---*/ + pContext->m_state = VideoBrowser_kVBCreating ; + pContext->m_frameColorType = clrType; + + /*--- Copy the file reader functions ---*/ + M4OSA_memcpy((M4OSA_MemAddr8)&pContext->m_fileReadPtr, + (M4OSA_MemAddr8)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 == M4ERR_READER_UNKNOWN_STREAM_TYPE) || + (err == 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; + + err = VideoEditorVideoDecoder_getInterface_MPEG4( + &decoderType, &pContext->m_pDecoder); + + CHECK_ERR(videoBrowserCreate, err) ; + + err = pContext->m_pDecoder->m_pFctCreate( + &pContext->m_pDecoderCtx, + pContext->m_pStreamHandler, + 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; + err = VideoEditorVideoDecoder_getInterface_H264( + &decoderType, &pContext->m_pDecoder); + CHECK_ERR(videoBrowserCreate, err) ; + + err = pContext->m_pDecoder->m_pFctCreate( + &pContext->m_pDecoderCtx, + pContext->m_pStreamHandler, + 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 +* @return M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC +******************************************************************************/ +M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime) +{ + VideoBrowserContext* pC = (VideoBrowserContext*)pContext; + M4OSA_ERR err = M4NO_ERROR; + M4OSA_UInt32 targetTime = 0; + M4OSA_UInt32 jumpTime = 0; + M4_MediaTime timeMS = 0; + M4OSA_Int32 rapTime = 0; + M4OSA_Bool isBackward = M4OSA_FALSE; + 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; + } + + /*--- Check the duration ---*/ + /*--- If we jump backward, we need to jump ---*/ + if (targetTime < pC->m_currentCTS) + { + isBackward = M4OSA_TRUE; + bJumpNeeded = M4OSA_TRUE; + } + /*--- If we jumpt to a time greater than "currentTime" + "predecodeTime" + we need to jump ---*/ + else if (targetTime > (pC->m_currentCTS + VIDEO_BROWSER_PREDECODE_TIME)) + { + bJumpNeeded = M4OSA_TRUE; + } + + if (M4OSA_TRUE == bJumpNeeded) + { + rapTime = targetTime; + /*--- Retrieve the previous RAP time ---*/ + err = pC->m_3gpReader->m_pFctGetPrevRapTime( + pC->m_pReaderCtx, pC->m_pStreamHandler, &rapTime); + + CHECK_ERR(videoBrowserPrepareFrame, err); + + jumpTime = rapTime; + + err = pC->m_3gpReader->m_pFctJump(pC->m_pReaderCtx, + pC->m_pStreamHandler, + (M4OSA_Int32*)&jumpTime); + CHECK_ERR(videoBrowserPrepareFrame, err); + } + + timeMS = (M4_MediaTime)targetTime; + err = pC->m_pDecoder->m_pFctDecode( + pC->m_pDecoderCtx, &timeMS, bJumpNeeded); + + if ((err != M4NO_ERROR) && (err != M4WAR_NO_MORE_AU)) + { + return err; + } + + // FIXME: + // Not sure that I understand why we need a second jump logic here + if ((timeMS >= pC->m_currentCTS) && (M4OSA_TRUE == isBackward)) + { + jumpTime = rapTime; + err = pC->m_3gpReader->m_pFctJump( + pC->m_pReaderCtx, pC->m_pStreamHandler, (M4OSA_Int32*)&jumpTime); + + CHECK_ERR(videoBrowserPrepareFrame, err); + + timeMS = (M4_MediaTime)rapTime; + err = pC->m_pDecoder->m_pFctDecode( + pC->m_pDecoderCtx, &timeMS, M4OSA_TRUE); + + 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) + { + err = M4NO_ERROR; + } + 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; +} diff --git a/media/jni/mediaeditor/VideoBrowserMain.h b/media/jni/mediaeditor/VideoBrowserMain.h new file mode 100755 index 000000000000..5156ebb2ff50 --- /dev/null +++ b/media/jni/mediaeditor/VideoBrowserMain.h @@ -0,0 +1,163 @@ +/* + * 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. + */ + + +#ifndef VIDEO_BROWSER_MAIN_H +#define VIDEO_BROWSER_MAIN_H + +/** + ************************************************************************ + * @file VideoBrowserMain.h + * @brief Video browser Interface functions + ************************************************************************ +*/ + +#define VIDEOBROWSER 0x423 + +#include "M4OSA_Memory.h" +#include "M4OSA_CharStar.h" +#include "M4OSA_OptionID.h" +#include "M4OSA_Debug.h" +#include "M4VIFI_FiltersAPI.h" +#include "M4OSA_FileReader.h" + + +/** + ************************************************************************ + * @brief Error codes definition. + * @note These value are the Browser engine specific error codes. + ************************************************************************ +*/ +#define M4ERR_VB_MEDIATYPE_NOT_SUPPORTED M4OSA_ERR_CREATE(M4_ERR, VIDEOBROWSER, 0x01) +#define M4ERR_VB_NO_VIDEO M4OSA_ERR_CREATE(M4_ERR, VIDEOBROWSER, 0x02) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Video Browser draw mode, extension for angle based bliting can be done + */ +typedef enum +{ + VideoBrowser_kVBNormalBliting +} VideoBrowser_videoBrowerDrawMode; + + +/*--- Video Browser output frame color type ---*/ +typedef enum +{ + VideoBrowser_kYUV420, + VideoBrowser_kGB565 +} VideoBrowser_VideoColorType; + +/** + ************************************************************************ + * enumeration VideoBrowser_Notification + * @brief Video Browser notification type. + * @note This callback mechanism must be used to wait the completion of an asynchronous + * operation, before calling another API function. + ************************************************************************ +*/ +typedef enum +{ + /** + * A frame is ready to be displayed, it should be displayed in the callback function + * pCbData type = M4VIFI_ImagePlane* + */ + VIDEOBROWSER_DISPLAY_FRAME = 0x00000001, + VIDEOBROWSER_NOTIFICATION_NONE = 0xffffffff +}VideoBrowser_Notification; + + +/** + ************************************************************************ + * @brief videoBrowser_Callback type definition + * @param pInstance (IN) Video Browser 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 + ************************************************************************ +*/ +typedef M4OSA_Void (*videoBrowser_Callback) (M4OSA_Context pInstance, + VideoBrowser_Notification notificationID, + M4OSA_ERR errCode, + M4OSA_Void* pCbData, + M4OSA_Void* pCallbackUserData); + + +/****************************************************************************** +* @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); + +/****************************************************************************** +* @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) ; + + +/****************************************************************************** +* @brief This function allocates the resources needed for browsing a video file. +* @param pContext (IN) : Video browser context +* @param pTime (IN/OUT) : Pointer on the time to reach. Updated by +* this function with the reached time +* @return M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC +******************************************************************************/ +M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime); + +/****************************************************************************** +* @brief This function sets the size and the position of the display. +* @param pContext (IN) : Video Browser context +* @param pixelArray (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* pixelArray, + M4OSA_UInt32 x, M4OSA_UInt32 y, + M4OSA_UInt32 dx, M4OSA_UInt32 dy); + +/****************************************************************************** +* @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); + +#ifdef __cplusplus +} +#endif + +#endif /* VIDEO_BROWSER_MAIN_H */ diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp new file mode 100755 index 000000000000..52e032a2a882 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorClasses.cpp @@ -0,0 +1,3174 @@ +/* + * 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 <VideoEditorClasses.h> +#include <VideoEditorJava.h> +#include <VideoEditorLogging.h> +#include <VideoEditorOsal.h> + +extern "C" { +#include <M4OSA_Clock.h> +#include <M4OSA_CharStar.h> +#include <M4OSA_FileCommon.h> +#include <M4OSA_FileReader.h> +#include <M4OSA_FileWriter.h> +#include <M4OSA_Memory.h> +#include <M4OSA_Debug.h> +#include <M4OSA_String.h> +#include <M4OSA_Thread.h> +#include <M4VSS3GPP_API.h> +#include <M4xVSS_API.h> +#include <M4VSS3GPP_ErrorCodes.h> +#include <M4MCS_ErrorCodes.h> +#include <M4READER_Common.h> +#include <M4WRITER_common.h> +#include <M4DECODER_Common.h> +}; + +#define VIDEOEDIT_PROP_JAVA_RESULT_STRING_MAX (128) + +#define VIDEOEDIT_JAVA__RESULT_STRING_MAX (128) + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(AudioEffect) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("NONE", M4VSS3GPP_kAudioEffectType_None), + VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_IN", M4VSS3GPP_kAudioEffectType_FadeIn), + VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_OUT", M4VSS3GPP_kAudioEffectType_FadeOut) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(AudioEffect, AUDIO_EFFECT_CLASS_NAME, M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(AudioFormat) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("NO_AUDIO", M4VIDEOEDITING_kNoneAudio), + VIDEOEDIT_JAVA_CONSTANT_INIT("AMR_NB", M4VIDEOEDITING_kAMR_NB), + VIDEOEDIT_JAVA_CONSTANT_INIT("AAC", M4VIDEOEDITING_kAAC), + VIDEOEDIT_JAVA_CONSTANT_INIT("AAC_PLUS", M4VIDEOEDITING_kAACplus), + VIDEOEDIT_JAVA_CONSTANT_INIT("ENHANCED_AAC_PLUS", M4VIDEOEDITING_keAACplus), + VIDEOEDIT_JAVA_CONSTANT_INIT("MP3", M4VIDEOEDITING_kMP3), + VIDEOEDIT_JAVA_CONSTANT_INIT("EVRC", M4VIDEOEDITING_kEVRC), + VIDEOEDIT_JAVA_CONSTANT_INIT("PCM", M4VIDEOEDITING_kPCM), + VIDEOEDIT_JAVA_CONSTANT_INIT("NULL_AUDIO", M4VIDEOEDITING_kNullAudio), + VIDEOEDIT_JAVA_CONSTANT_INIT("UNSUPPORTED_AUDIO", M4VIDEOEDITING_kUnsupportedAudio) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(AudioFormat, AUDIO_FORMAT_CLASS_NAME, M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(AudioSamplingFrequency) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_DEFAULT", M4VIDEOEDITING_kDefault_ASF), + VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_8000", M4VIDEOEDITING_k8000_ASF), + VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_16000", M4VIDEOEDITING_k16000_ASF), + VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_22050", M4VIDEOEDITING_k22050_ASF), + VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_24000", M4VIDEOEDITING_k24000_ASF), + VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_32000", M4VIDEOEDITING_k32000_ASF), + VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_44100", M4VIDEOEDITING_k44100_ASF), + VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_48000", M4VIDEOEDITING_k48000_ASF) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(AudioSamplingFrequency,AUDIO_SAMPLING_FREQUENCY_CLASS_NAME, + M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(AudioTransition) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("NONE", M4VSS3GPP_kAudioTransitionType_None), + VIDEOEDIT_JAVA_CONSTANT_INIT("CROSS_FADE", M4VSS3GPP_kAudioTransitionType_CrossFade) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(AudioTransition, AUDIO_TRANSITION_CLASS_NAME, M4OSA_NULL, + M4OSA_NULL) + + +static const char* +videoEditClasses_getUnknownBitrateString(int bitrate) +{ + static char string[VIDEOEDIT_JAVA__RESULT_STRING_MAX] = ""; + + M4OSA_chrSPrintf((M4OSA_Char *)string, sizeof(string) - 1, (M4OSA_Char*)"%d", bitrate); + + // Return the bitrate string. + return(string); +} + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(Bitrate) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("VARIABLE", M4VIDEOEDITING_kVARIABLE_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("UNDEFINED", M4VIDEOEDITING_kUndefinedBitrate), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_9_2_KBPS", M4VIDEOEDITING_k9_2_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_12_2_KBPS", M4VIDEOEDITING_k12_2_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_16_KBPS", M4VIDEOEDITING_k16_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_24_KBPS", M4VIDEOEDITING_k24_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_32_KBPS", M4VIDEOEDITING_k32_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_48_KBPS", M4VIDEOEDITING_k48_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_64_KBPS", M4VIDEOEDITING_k64_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_96_KBPS", M4VIDEOEDITING_k96_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_128_KBPS", M4VIDEOEDITING_k128_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_192_KBPS", M4VIDEOEDITING_k192_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_256_KBPS", M4VIDEOEDITING_k256_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_288_KBPS", M4VIDEOEDITING_k288_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_384_KBPS", M4VIDEOEDITING_k384_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_512_KBPS", M4VIDEOEDITING_k512_KBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_800_KBPS", M4VIDEOEDITING_k800_KBPS), +/*+ New Encoder bitrates */ + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_2_MBPS", M4VIDEOEDITING_k2_MBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_5_MBPS", M4VIDEOEDITING_k5_MBPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("BR_8_MBPS", M4VIDEOEDITING_k8_MBPS) +/*- New Encoder bitrates */ +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(Bitrate, BITRATE_CLASS_NAME, + videoEditClasses_getUnknownBitrateString, videoEditClasses_getUnknownBitrateString) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(ClipType) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("THREE_GPP", M4VIDEOEDITING_kFileType_3GPP), + VIDEOEDIT_JAVA_CONSTANT_INIT("MP4", M4VIDEOEDITING_kFileType_MP4), + VIDEOEDIT_JAVA_CONSTANT_INIT("AMR", M4VIDEOEDITING_kFileType_AMR), + VIDEOEDIT_JAVA_CONSTANT_INIT("MP3", M4VIDEOEDITING_kFileType_MP3), + VIDEOEDIT_JAVA_CONSTANT_INIT("PCM", M4VIDEOEDITING_kFileType_PCM), + VIDEOEDIT_JAVA_CONSTANT_INIT("JPG", M4VIDEOEDITING_kFileType_JPG), + VIDEOEDIT_JAVA_CONSTANT_INIT("UNSUPPORTED", M4VIDEOEDITING_kFileType_Unsupported) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(ClipType, FILE_TYPE_CLASS_NAME, M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(Engine) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("TASK_LOADING_SETTINGS", TASK_LOADING_SETTINGS), + VIDEOEDIT_JAVA_CONSTANT_INIT("TASK_ENCODING", TASK_ENCODING) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(Engine, MANUAL_EDIT_ENGINE_CLASS_NAME, M4OSA_NULL, + M4OSA_NULL) + + +static const char* +videoEditClasses_getUnknownErrorName(int error) +{ + static char string[VIDEOEDIT_JAVA__RESULT_STRING_MAX] = "ERR_INTERNAL"; + + // Format the unknown error string. + M4OSA_chrSPrintf((M4OSA_Char *)string, sizeof(string) - 1, (M4OSA_Char*)"ERR_INTERNAL(%s)", + videoEditOsal_getResultString(error)); + + // Return the error string. + return(string); +} + +static const char* +videoEditClasses_getUnknownErrorString(int error) +{ + // Return the result string. + return(videoEditOsal_getResultString(error)); +} + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(Error) +{ + // M4OSA_Clock.h + VIDEOEDIT_JAVA_CONSTANT_INIT("WAR_TIMESCALE_TOO_BIG", \ + M4WAR_TIMESCALE_TOO_BIG ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_CLOCK_BAD_REF_YEAR", \ + M4ERR_CLOCK_BAD_REF_YEAR ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_FILE_NOT_FOUND", \ + M4ERR_FILE_NOT_FOUND ), + VIDEOEDIT_JAVA_CONSTANT_INIT("WAR_TRANSCODING_NECESSARY", \ + M4VSS3GPP_WAR_TRANSCODING_NECESSARY ), + VIDEOEDIT_JAVA_CONSTANT_INIT("WAR_MAX_OUTPUT_SIZE_EXCEEDED", \ + M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_BUFFER_OUT_TOO_SMALL", \ + M4xVSSWAR_BUFFER_OUT_TOO_SMALL ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_NOMORE_SPACE_FOR_FILE", \ + M4xVSSERR_NO_MORE_SPACE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_FILE_TYPE", \ + M4VSS3GPP_ERR_INVALID_FILE_TYPE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_EFFECT_KIND", \ + M4VSS3GPP_ERR_INVALID_EFFECT_KIND ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_VIDEO_EFFECT_TYPE", \ + M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_AUDIO_EFFECT_TYPE", \ + M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_VIDEO_TRANSITION_TYPE", \ + M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_AUDIO_TRANSITION_TYPE", \ + M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_VIDEO_ENCODING_FRAME_RATE", \ + M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EXTERNAL_EFFECT_NULL", \ + M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EXTERNAL_TRANSITION_NULL", \ + M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_BEGIN_CUT_LARGER_THAN_DURATION", \ + M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_BEGIN_CUT_LARGER_THAN_END_CUT", \ + M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_OVERLAPPING_TRANSITIONS", \ + M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS ), +#ifdef M4VSS3GPP_ERR_ANALYSIS_DATA_SIZE_TOO_SMALL + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ANALYSIS_DATA_SIZE_TOO_SMALL", \ + M4VSS3GPP_ERR_ANALYSIS_DATA_SIZE_TOO_SMALL ), +#endif + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_3GPP_FILE", \ + M4VSS3GPP_ERR_INVALID_3GPP_FILE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT", \ + M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT", \ + M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_AMR_EDITING_UNSUPPORTED", \ + M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INPUT_VIDEO_AU_TOO_LARGE", \ + M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INPUT_AUDIO_AU_TOO_LARGE", \ + M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INPUT_AUDIO_CORRUPTED_AU", \ + M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU ), +#ifdef M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INPUT_AUDIO_CORRUPTED_AU", \ + M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU ), +#endif + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ENCODER_ACCES_UNIT_ERROR", \ + M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT", \ + M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_H263_PROFILE", \ + M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE", \ + M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_MPEG4_RVLC", \ + M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT", \ + M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE", \ + M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE",\ + M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_CLIP_ANALYSIS_VERSION", \ + M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION ), +#ifdef M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_PLATFORM + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_CLIP_ANALYSIS_PLATFORM", \ + M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_PLATFORM ), +#endif + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INCOMPATIBLE_VIDEO_FORMAT", \ + M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE", \ + M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INCOMPATIBLE_VIDEO_TIME_SCALE", \ + M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING", \ + M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNSUPPORTED_MP3_ASSEMBLY", \ + M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_NO_SUPPORTED_STREAM_IN_FILE", \ + M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ADDVOLUME_EQUALS_ZERO", \ + M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION", \ + M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT", \ + M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNSUPPORTED_ADDED_AUDIO_STREAM", \ + M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_AUDIO_MIXING_UNSUPPORTED", \ + M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED ), +#ifdef M4VSS3GPP_ERR_AUDIO_MIXING_MP3_UNSUPPORTED + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_AUDIO_MIXING_MP3_UNSUPPORTED", \ + M4VSS3GPP_ERR_AUDIO_MIXING_MP3_UNSUPPORTED ), +#endif + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK", \ + M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK ), +#ifdef M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AAC + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_FEATURE_UNSUPPORTED_WITH_AAC", \ + M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AAC ), +#endif + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_AUDIO_CANNOT_BE_MIXED", \ + M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED ), +#ifdef M4VSS3GPP_ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED", \ + M4VSS3GPP_ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED ), +#endif +#ifdef M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_EVRC + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_FEATURE_UNSUPPORTED_WITH_EVRC", \ + M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_EVRC ), +#endif + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_H263_PROFILE_NOT_SUPPORTED", \ + M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE", \ + M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE ), + VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INTERNAL", \ + M4NO_ERROR ), +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(Error, ERROR_CLASS_NAME, + videoEditClasses_getUnknownErrorName, videoEditClasses_getUnknownErrorString) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(FileType) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("THREE_GPP", VideoEditClasses_kFileType_3GPP), + VIDEOEDIT_JAVA_CONSTANT_INIT("MP4", VideoEditClasses_kFileType_MP4), + VIDEOEDIT_JAVA_CONSTANT_INIT("AMR", VideoEditClasses_kFileType_AMR), + VIDEOEDIT_JAVA_CONSTANT_INIT("MP3", VideoEditClasses_kFileType_MP3), + VIDEOEDIT_JAVA_CONSTANT_INIT("PCM", VideoEditClasses_kFileType_PCM), + VIDEOEDIT_JAVA_CONSTANT_INIT("JPG", VideoEditClasses_kFileType_JPG), + VIDEOEDIT_JAVA_CONSTANT_INIT("GIF", VideoEditClasses_kFileType_GIF), + VIDEOEDIT_JAVA_CONSTANT_INIT("PNG", VideoEditClasses_kFileType_PNG), + VIDEOEDIT_JAVA_CONSTANT_INIT("UNSUPPORTED", VideoEditClasses_kFileType_Unsupported) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(FileType, FILE_TYPE_CLASS_NAME, M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(MediaRendering) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("RESIZING", M4xVSS_kResizing), + VIDEOEDIT_JAVA_CONSTANT_INIT("CROPPING", M4xVSS_kCropping), + VIDEOEDIT_JAVA_CONSTANT_INIT("BLACK_BORDERS", M4xVSS_kBlackBorders) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(MediaRendering, MEDIA_RENDERING_CLASS_NAME, + M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(SlideDirection) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("RIGHT_OUT_LEFT_IN", M4xVSS_SlideTransition_RightOutLeftIn), + VIDEOEDIT_JAVA_CONSTANT_INIT("LEFT_OUT_RIGTH_IN", M4xVSS_SlideTransition_LeftOutRightIn), + VIDEOEDIT_JAVA_CONSTANT_INIT("TOP_OUT_BOTTOM_IN", M4xVSS_SlideTransition_TopOutBottomIn), + VIDEOEDIT_JAVA_CONSTANT_INIT("BOTTOM_OUT_TOP_IN", M4xVSS_SlideTransition_BottomOutTopIn) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(SlideDirection, SLIDE_DIRECTION_CLASS_NAME, + M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(TransitionBehaviour) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("SPEED_UP", M4VSS3GPP_TransitionBehaviour_SpeedUp), + VIDEOEDIT_JAVA_CONSTANT_INIT("LINEAR", M4VSS3GPP_TransitionBehaviour_Linear), + VIDEOEDIT_JAVA_CONSTANT_INIT("SPEED_DOWN", M4VSS3GPP_TransitionBehaviour_SpeedDown), + VIDEOEDIT_JAVA_CONSTANT_INIT("SLOW_MIDDLE", M4VSS3GPP_TransitionBehaviour_SlowMiddle), + VIDEOEDIT_JAVA_CONSTANT_INIT("FAST_MIDDLE", M4VSS3GPP_TransitionBehaviour_FastMiddle) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(TransitionBehaviour, TRANSITION_BEHAVIOUR_CLASS_NAME, + M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoEffect) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("NONE", M4VSS3GPP_kVideoEffectType_None), + VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_FROM_BLACK", M4VSS3GPP_kVideoEffectType_FadeFromBlack), + VIDEOEDIT_JAVA_CONSTANT_INIT("CURTAIN_OPENING", M4VSS3GPP_kVideoEffectType_CurtainOpening), + VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_TO_BLACK", M4VSS3GPP_kVideoEffectType_FadeToBlack), + VIDEOEDIT_JAVA_CONSTANT_INIT("CURTAIN_CLOSING", M4VSS3GPP_kVideoEffectType_CurtainClosing), + VIDEOEDIT_JAVA_CONSTANT_INIT("EXTERNAL", M4VSS3GPP_kVideoEffectType_External), + VIDEOEDIT_JAVA_CONSTANT_INIT("BLACK_AND_WHITE", M4xVSS_kVideoEffectType_BlackAndWhite), + VIDEOEDIT_JAVA_CONSTANT_INIT("PINK", M4xVSS_kVideoEffectType_Pink), + VIDEOEDIT_JAVA_CONSTANT_INIT("GREEN", M4xVSS_kVideoEffectType_Green), + VIDEOEDIT_JAVA_CONSTANT_INIT("SEPIA", M4xVSS_kVideoEffectType_Sepia), + VIDEOEDIT_JAVA_CONSTANT_INIT("NEGATIVE", M4xVSS_kVideoEffectType_Negative), + VIDEOEDIT_JAVA_CONSTANT_INIT("FRAMING", M4xVSS_kVideoEffectType_Framing), + VIDEOEDIT_JAVA_CONSTANT_INIT("TEXT", M4xVSS_kVideoEffectType_Text), + VIDEOEDIT_JAVA_CONSTANT_INIT("ZOOM_IN", M4xVSS_kVideoEffectType_ZoomIn), + VIDEOEDIT_JAVA_CONSTANT_INIT("ZOOM_OUT", M4xVSS_kVideoEffectType_ZoomOut), + VIDEOEDIT_JAVA_CONSTANT_INIT("FIFTIES", M4xVSS_kVideoEffectType_Fifties), + VIDEOEDIT_JAVA_CONSTANT_INIT("COLORRGB16", M4xVSS_kVideoEffectType_ColorRGB16), + VIDEOEDIT_JAVA_CONSTANT_INIT("GRADIENT", M4xVSS_kVideoEffectType_Gradient), +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoEffect, VIDEO_EFFECT_CLASS_NAME, M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoFormat) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("NO_VIDEO", M4VIDEOEDITING_kNoneVideo), + VIDEOEDIT_JAVA_CONSTANT_INIT("H263", M4VIDEOEDITING_kH263), + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4", M4VIDEOEDITING_kMPEG4), + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4_EMP", M4VIDEOEDITING_kMPEG4_EMP), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264", M4VIDEOEDITING_kH264), + VIDEOEDIT_JAVA_CONSTANT_INIT("NULL_VIDEO", M4VIDEOEDITING_kNullVideo), + VIDEOEDIT_JAVA_CONSTANT_INIT("UNSUPPORTED", M4VIDEOEDITING_kUnsupportedVideo), +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoFormat, VIDEO_FORMAT_CLASS_NAME, M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoFrameRate) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("FR_5_FPS", M4VIDEOEDITING_k5_FPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("FR_7_5_FPS", M4VIDEOEDITING_k7_5_FPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("FR_10_FPS", M4VIDEOEDITING_k10_FPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("FR_12_5_FPS", M4VIDEOEDITING_k12_5_FPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("FR_15_FPS", M4VIDEOEDITING_k15_FPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("FR_20_FPS", M4VIDEOEDITING_k20_FPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("FR_25_FPS", M4VIDEOEDITING_k25_FPS), + VIDEOEDIT_JAVA_CONSTANT_INIT("FR_30_FPS", M4VIDEOEDITING_k30_FPS) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoFrameRate, VIDEO_FRAME_RATE_CLASS_NAME, + M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoFrameSize) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("SQCIF", M4VIDEOEDITING_kSQCIF), + VIDEOEDIT_JAVA_CONSTANT_INIT("QQVGA", M4VIDEOEDITING_kQQVGA), + VIDEOEDIT_JAVA_CONSTANT_INIT("QCIF", M4VIDEOEDITING_kQCIF), + VIDEOEDIT_JAVA_CONSTANT_INIT("QVGA", M4VIDEOEDITING_kQVGA), + VIDEOEDIT_JAVA_CONSTANT_INIT("CIF", M4VIDEOEDITING_kCIF), + VIDEOEDIT_JAVA_CONSTANT_INIT("VGA", M4VIDEOEDITING_kVGA), + VIDEOEDIT_JAVA_CONSTANT_INIT("WVGA", M4VIDEOEDITING_kWVGA), + VIDEOEDIT_JAVA_CONSTANT_INIT("NTSC", M4VIDEOEDITING_kNTSC), + VIDEOEDIT_JAVA_CONSTANT_INIT("nHD", M4VIDEOEDITING_k640_360), + VIDEOEDIT_JAVA_CONSTANT_INIT("WVGA16x9", M4VIDEOEDITING_k854_480), + VIDEOEDIT_JAVA_CONSTANT_INIT("V720p", M4VIDEOEDITING_kHD1280), + VIDEOEDIT_JAVA_CONSTANT_INIT("W720p", M4VIDEOEDITING_kHD1080), + VIDEOEDIT_JAVA_CONSTANT_INIT("S720p", M4VIDEOEDITING_kHD960) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoFrameSize, VIDEO_FRAME_SIZE_CLASS_NAME, + M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoProfile) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4_SP_LEVEL_0", \ + M4VIDEOEDITING_kMPEG4_SP_Level_0), + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4_SP_LEVEL_0B", \ + M4VIDEOEDITING_kMPEG4_SP_Level_0b), + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4_SP_LEVEL_1", \ + M4VIDEOEDITING_kMPEG4_SP_Level_1), + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4_SP_LEVEL_2", \ + M4VIDEOEDITING_kMPEG4_SP_Level_2), + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4_SP_LEVEL_3", \ + M4VIDEOEDITING_kMPEG4_SP_Level_3), + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4_SP_LEVEL_4A", \ + M4VIDEOEDITING_kMPEG4_SP_Level_4a), + VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4_SP_LEVEL_5", \ + M4VIDEOEDITING_kMPEG4_SP_Level_5), + VIDEOEDIT_JAVA_CONSTANT_INIT("H263_PROFILE_0_LEVEL_10",\ + M4VIDEOEDITING_kH263_Profile_0_Level_10), + VIDEOEDIT_JAVA_CONSTANT_INIT("H263_PROFILE_0_LEVEL_20",\ + M4VIDEOEDITING_kH263_Profile_0_Level_20), + VIDEOEDIT_JAVA_CONSTANT_INIT("H263_PROFILE_0_LEVEL_30",\ + M4VIDEOEDITING_kH263_Profile_0_Level_30), + VIDEOEDIT_JAVA_CONSTANT_INIT("H263_PROFILE_0_LEVEL_40",\ + M4VIDEOEDITING_kH263_Profile_0_Level_40), + VIDEOEDIT_JAVA_CONSTANT_INIT("H263_PROFILE_0_LEVEL_45",\ + M4VIDEOEDITING_kH263_Profile_0_Level_45), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_1", \ + M4VIDEOEDITING_kH264_Profile_0_Level_1), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_1b",\ + M4VIDEOEDITING_kH264_Profile_0_Level_1b), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_1_1",\ + M4VIDEOEDITING_kH264_Profile_0_Level_1_1), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_1_2",\ + M4VIDEOEDITING_kH264_Profile_0_Level_1_2), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_1_3",\ + M4VIDEOEDITING_kH264_Profile_0_Level_1_3), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_2", \ + M4VIDEOEDITING_kH264_Profile_0_Level_2), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_2_1",\ + M4VIDEOEDITING_kH264_Profile_0_Level_2_1), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_2_2",\ + M4VIDEOEDITING_kH264_Profile_0_Level_2_2), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_3", \ + M4VIDEOEDITING_kH264_Profile_0_Level_3), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_3_1",\ + M4VIDEOEDITING_kH264_Profile_0_Level_3_1), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_3_2",\ + M4VIDEOEDITING_kH264_Profile_0_Level_3_2), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_4", \ + M4VIDEOEDITING_kH264_Profile_0_Level_4), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_4_1",\ + M4VIDEOEDITING_kH264_Profile_0_Level_4_1), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_4_2",\ + M4VIDEOEDITING_kH264_Profile_0_Level_4_2), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_5", \ + M4VIDEOEDITING_kH264_Profile_0_Level_5), + VIDEOEDIT_JAVA_CONSTANT_INIT("H264_PROFILE_0_LEVEL_5_1",\ + M4VIDEOEDITING_kH264_Profile_0_Level_5_1), + VIDEOEDIT_JAVA_CONSTANT_INIT("OUT_OF_RANGE", \ + M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoProfile, VIDEO_PROFILE_CLASS_NAME, M4OSA_NULL, + M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoTransition) +{ + VIDEOEDIT_JAVA_CONSTANT_INIT("NONE", M4VSS3GPP_kVideoTransitionType_None), + VIDEOEDIT_JAVA_CONSTANT_INIT("CROSS_FADE", M4VSS3GPP_kVideoTransitionType_CrossFade), + VIDEOEDIT_JAVA_CONSTANT_INIT("EXTERNAL", M4VSS3GPP_kVideoTransitionType_External), + VIDEOEDIT_JAVA_CONSTANT_INIT("ALPHA_MAGIC", M4xVSS_kVideoTransitionType_AlphaMagic), + VIDEOEDIT_JAVA_CONSTANT_INIT("SLIDE_TRANSITION", M4xVSS_kVideoTransitionType_SlideTransition), + VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_BLACK", M4xVSS_kVideoTransitionType_FadeBlack) +}; + +VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoTransition, VIDEO_TRANSITION_CLASS_NAME, + M4OSA_NULL, M4OSA_NULL) + + +VIDEOEDIT_JAVA_DEFINE_FIELDS(AlphaMagic) +{ + VIDEOEDIT_JAVA_FIELD_INIT("file", "Ljava/lang/String;"), + VIDEOEDIT_JAVA_FIELD_INIT("blendingPercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("invertRotation", "Z" ), + VIDEOEDIT_JAVA_FIELD_INIT("rgbWidth", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("rgbHeight", "I" ) +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(AlphaMagic, ALPHA_MAGIC_SETTINGS_CLASS_NAME) + +VIDEOEDIT_JAVA_DEFINE_FIELDS(Properties) +{ + VIDEOEDIT_JAVA_FIELD_INIT("duration", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("fileType", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("videoFormat", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("videoDuration", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("videoBitrate", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("width", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("height", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("averageFrameRate", "F"), + VIDEOEDIT_JAVA_FIELD_INIT("profileAndLevel", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("audioFormat", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("audioDuration", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("audioBitrate", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("audioChannels", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("audioSamplingFrequency", "I") +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(Properties, PROPERTIES_CLASS_NAME) + +VIDEOEDIT_JAVA_DEFINE_FIELDS(BackgroundMusic) +{ + VIDEOEDIT_JAVA_FIELD_INIT("file", "Ljava/lang/String;"), + VIDEOEDIT_JAVA_FIELD_INIT("fileType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("insertionTime", "J" ), + VIDEOEDIT_JAVA_FIELD_INIT("volumePercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("beginLoop", "J" ), + VIDEOEDIT_JAVA_FIELD_INIT("endLoop", "J" ), + VIDEOEDIT_JAVA_FIELD_INIT("enableDucking", "Z" ), + VIDEOEDIT_JAVA_FIELD_INIT("duckingThreshold","I" ), + VIDEOEDIT_JAVA_FIELD_INIT("lowVolume", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("isLooping", "Z" ) +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(BackgroundMusic, BACKGROUND_MUSIC_SETTINGS_CLASS_NAME) + +/* +VIDEOEDIT_JAVA_DEFINE_FIELDS(BestEditSettings) +{ + VIDEOEDIT_JAVA_FIELD_INIT("videoFormat", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("videoFrameSize", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("audioFormat", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("audioChannels", "I") +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(BestEditSettings, BEST_EDIT_SETTINGS_CLASS_NAME) +*/ + +VIDEOEDIT_JAVA_DEFINE_FIELDS(ClipSettings) +{ + VIDEOEDIT_JAVA_FIELD_INIT("clipPath", "Ljava/lang/String;"), + VIDEOEDIT_JAVA_FIELD_INIT("fileType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("beginCutTime", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("endCutTime", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("beginCutPercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("endCutPercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("panZoomEnabled", "Z" ), + VIDEOEDIT_JAVA_FIELD_INIT("panZoomPercentStart", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("panZoomTopLeftXStart", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("panZoomTopLeftYStart", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("panZoomPercentEnd", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("panZoomTopLeftXEnd", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("panZoomTopLeftYEnd", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("mediaRendering", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("rgbWidth", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("rgbHeight", "I" ) +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(ClipSettings, CLIP_SETTINGS_CLASS_NAME) + + +VIDEOEDIT_JAVA_DEFINE_FIELDS(EditSettings) +{ + VIDEOEDIT_JAVA_FIELD_INIT("clipSettingsArray", "[L"CLIP_SETTINGS_CLASS_NAME";" ), + VIDEOEDIT_JAVA_FIELD_INIT("transitionSettingsArray", "[L"TRANSITION_SETTINGS_CLASS_NAME";" ), + VIDEOEDIT_JAVA_FIELD_INIT("effectSettingsArray", "[L"EFFECT_SETTINGS_CLASS_NAME";" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoFrameRate", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("outputFile", "Ljava/lang/String;" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoFrameSize", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoFormat", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioFormat", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioSamplingFreq", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("maxFileSize", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioChannels", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoBitrate", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioBitrate", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("backgroundMusicSettings",\ + "L"BACKGROUND_MUSIC_SETTINGS_CLASS_NAME";"), + VIDEOEDIT_JAVA_FIELD_INIT("primaryTrackVolume", "I" ) +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(EditSettings, EDIT_SETTINGS_CLASS_NAME) + + +VIDEOEDIT_JAVA_DEFINE_FIELDS(EffectSettings) +{ + VIDEOEDIT_JAVA_FIELD_INIT("startTime", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("duration", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoEffectType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioEffectType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("startPercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("durationPercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("framingFile", "Ljava/lang/String;"), + VIDEOEDIT_JAVA_FIELD_INIT("framingBuffer", "[I" ), + VIDEOEDIT_JAVA_FIELD_INIT("bitmapType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("width", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("height", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("topLeftX", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("topLeftY", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("framingResize", "Z" ), + VIDEOEDIT_JAVA_FIELD_INIT("framingScaledSize", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("text", "Ljava/lang/String;"), + VIDEOEDIT_JAVA_FIELD_INIT("textRenderingData", "Ljava/lang/String;"), + VIDEOEDIT_JAVA_FIELD_INIT("textBufferWidth", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("textBufferHeight", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("fiftiesFrameRate", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("rgb16InputColor", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingStartPercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingMiddlePercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingEndPercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingFadeInTimePercent", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingFadeOutTimePercent", "I" ) +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(EffectSettings, EFFECT_SETTINGS_CLASS_NAME) + + +VIDEOEDIT_JAVA_DEFINE_FIELDS(Engine) +{ + VIDEOEDIT_JAVA_FIELD_INIT("mManualEditContext", "I") +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(Engine, MANUAL_EDIT_ENGINE_CLASS_NAME) + + +VIDEOEDIT_JAVA_DEFINE_FIELDS(SlideTransitionSettings) +{ + VIDEOEDIT_JAVA_FIELD_INIT("direction", "I") +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(SlideTransitionSettings, SLIDE_TRANSITION_SETTINGS_CLASS_NAME) + + +VIDEOEDIT_JAVA_DEFINE_FIELDS(TransitionSettings) +{ + VIDEOEDIT_JAVA_FIELD_INIT("duration", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoTransitionType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioTransitionType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("transitionBehaviour", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("alphaSettings", "L"ALPHA_MAGIC_SETTINGS_CLASS_NAME";" ), + VIDEOEDIT_JAVA_FIELD_INIT("slideSettings", "L"SLIDE_TRANSITION_SETTINGS_CLASS_NAME";") +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(TransitionSettings, TRANSITION_SETTINGS_CLASS_NAME) + + +VIDEOEDIT_JAVA_DEFINE_FIELDS(Version) +{ + VIDEOEDIT_JAVA_FIELD_INIT("major", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("minor", "I"), + VIDEOEDIT_JAVA_FIELD_INIT("revision", "I") +}; + +VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(Version, VERSION_CLASS_NAME) + + +VIDEOEDIT_JAVA_DEFINE_METHODS(Engine) +{ + VIDEOEDIT_JAVA_METHOD_INIT("onProgressUpdate", "(II)V") +}; + +VIDEOEDIT_JAVA_DEFINE_METHOD_CLASS(Engine, MANUAL_EDIT_ENGINE_CLASS_NAME) + + +static const char* +videoEditClasses_getBrandString(M4OSA_UInt32 brand) +{ + static char brandString[11] = "0x00000000"; + const char* pBrandString = M4OSA_NULL; + M4OSA_UInt8* pBrand = (M4OSA_UInt8*)&brand; + M4OSA_UInt32 brandHost = 0; + + // Convert the brand from big endian to host. + brandHost = pBrand[0]; + brandHost = brandHost << 8; + brandHost += pBrand[1]; + brandHost = brandHost << 8; + brandHost += pBrand[2]; + brandHost = brandHost << 8; + brandHost += pBrand[3]; + + switch (brandHost) + { + case M4VIDEOEDITING_BRAND_0000: + pBrandString = "0000"; + break; + case M4VIDEOEDITING_BRAND_3G2A: + pBrandString = "3G2A"; + break; + case M4VIDEOEDITING_BRAND_3GP4: + pBrandString = "3GP4"; + break; + case M4VIDEOEDITING_BRAND_3GP5: + pBrandString = "3GP5"; + break; + case M4VIDEOEDITING_BRAND_3GP6: + pBrandString = "3GP6"; + break; + case M4VIDEOEDITING_BRAND_AVC1: + pBrandString = "AVC1"; + break; + case M4VIDEOEDITING_BRAND_EMP: + pBrandString = "EMP"; + break; + case M4VIDEOEDITING_BRAND_ISOM: + pBrandString = "ISOM"; + break; + case M4VIDEOEDITING_BRAND_MP41: + pBrandString = "MP41"; + break; + case M4VIDEOEDITING_BRAND_MP42: + pBrandString = "MP42"; + break; + case M4VIDEOEDITING_BRAND_VFJ1: + pBrandString = "VFJ1"; + break; + default: + M4OSA_chrSPrintf((M4OSA_Char *)brandString, + sizeof(brandString) - 1, + (M4OSA_Char*)"0x%08X", brandHost); + pBrandString = brandString; + break; + } + + // Return the brand string. + return(pBrandString); +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +static void +videoEditClasses_logFtypBox( + M4VIDEOEDITING_FtypBox* pBox, + int indentation) +{ + // Check if memory was allocated for the FtypBox. + if (M4OSA_NULL != pBox) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c major_brand: %s", indentation, ' ', + videoEditClasses_getBrandString(pBox->major_brand)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c minor_version: %08X", indentation, ' ', + (unsigned int)pBox->minor_version); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c nbCompatibleBrands: %u", indentation, ' ', + (unsigned int)pBox->nbCompatibleBrands); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c compatible_brands:", indentation, ' '); + indentation += VIDEOEDIT_LOG_INDENTATION; + for (int i = 0; (i < (int)pBox->nbCompatibleBrands) &&\ + (i < M4VIDEOEDITING_MAX_COMPATIBLE_BRANDS); i++) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c compatible_brand[%d]: %s", indentation, ' ', + i, videoEditClasses_getBrandString(pBox->compatible_brands[i])); + } + indentation -= VIDEOEDIT_LOG_INDENTATION; + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c <null>", + indentation, ' '); + } +} +#endif + + +void +videoEditClasses_init( + bool* pResult, + JNIEnv* pEnv) +{ + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",\ + "videoEditClasses_init()"); + + // Initialize the constants. + videoEditJava_initAudioEffectConstants(pResult, pEnv); + videoEditJava_initAudioFormatConstants(pResult, pEnv); + videoEditJava_initAudioSamplingFrequencyConstants(pResult, pEnv); + videoEditJava_initAudioTransitionConstants(pResult, pEnv); + videoEditJava_initBitrateConstants(pResult, pEnv); + videoEditJava_initClipTypeConstants(pResult, pEnv); + videoEditJava_initEngineConstants(pResult, pEnv); + videoEditJava_initErrorConstants(pResult, pEnv); + videoEditJava_initFileTypeConstants(pResult, pEnv); + videoEditJava_initMediaRenderingConstants(pResult, pEnv); + videoEditJava_initSlideDirectionConstants(pResult, pEnv); + videoEditJava_initTransitionBehaviourConstants(pResult, pEnv); + videoEditJava_initVideoEffectConstants(pResult, pEnv); + videoEditJava_initVideoFormatConstants(pResult, pEnv); + videoEditJava_initVideoFrameRateConstants(pResult, pEnv); + videoEditJava_initVideoFrameSizeConstants(pResult, pEnv); + videoEditJava_initVideoProfileConstants(pResult, pEnv); + videoEditJava_initVideoTransitionConstants(pResult, pEnv); + + // Initialize the fields. + videoEditJava_initAlphaMagicFields(pResult, pEnv); + videoEditJava_initBackgroundMusicFields(pResult, pEnv); + videoEditJava_initClipSettingsFields(pResult, pEnv); + videoEditJava_initEditSettingsFields(pResult, pEnv); + videoEditJava_initEffectSettingsFields(pResult, pEnv); + videoEditJava_initEngineFields(pResult, pEnv); + videoEditJava_initSlideTransitionSettingsFields(pResult, pEnv); + videoEditJava_initTransitionSettingsFields(pResult, pEnv); + videoEditJava_initVersionFields(pResult, pEnv); + // Initialize the methods. + videoEditJava_initEngineMethods(pResult, pEnv); + } +} + +void +videoEditPropClass_init( + bool* pResult, + JNIEnv* pEnv) +{ + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",\ + "videoEditPropClass_init()"); + + // Initialize the constants. + videoEditJava_initAudioFormatConstants(pResult, pEnv); + videoEditJava_initErrorConstants(pResult, pEnv); + videoEditJava_initFileTypeConstants(pResult, pEnv); + videoEditJava_initVideoFormatConstants(pResult, pEnv); + videoEditJava_initVideoProfileConstants(pResult, pEnv); + + // Initialize the fields. + videoEditJava_initPropertiesFields(pResult, pEnv); + } +} + +void +videoEditClasses_getAlphaMagicSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4xVSS_AlphaMagicSettings** ppSettings) +{ + VideoEditJava_AlphaMagicFieldIds fieldIds = {NULL, NULL, NULL, NULL, NULL}; + M4xVSS_AlphaMagicSettings* pSettings = M4OSA_NULL; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_getAlphaMagicSettings()"); + + // Retrieve the field ids. + videoEditJava_getAlphaMagicFieldIds(pResult, pEnv, &fieldIds); + } + + // Only validate the AlphaMagicSettings if the fields could be located. + if (*pResult) + { + // Check if the clip is set. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (NULL == object), + "alphaSettings is null"); + } + + // Only retrieve the AlphaMagicSettings if the fields could be located and validated. + if (*pResult) + { + // Allocate memory for the AlphaMagicSettings. + pSettings = (M4xVSS_AlphaMagicSettings*)videoEditOsal_alloc(pResult, pEnv, + sizeof(M4xVSS_AlphaMagicSettings), "AlphaMagicSettings"); + + // Check if memory could be allocated for the AlphaMagicSettings. + if (*pResult) + { + // Set the alpha magic file path (JPG file). + pSettings->pAlphaFilePath = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, object, + fieldIds.file, M4OSA_NULL); + + // Check if the alpha magic file path is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (M4OSA_NULL == pSettings->pAlphaFilePath), "alphaSettings.file is null"); + } + + // Check if the alpha file path could be retrieved. + if (*pResult) + { + // Set the blending percentage between 0 and 100. + pSettings->blendingPercent = (M4OSA_UInt8)pEnv->GetIntField(object, + fieldIds.blendingPercent); + + // Set the direct effect or reverse. + pSettings->isreverse = (M4OSA_Bool)pEnv->GetBooleanField(object, + fieldIds.invertRotation); + + // Get the rgb width + pSettings->width = (M4OSA_UInt32) pEnv->GetIntField(object, fieldIds.rgbWidth ); + + pSettings->height = (M4OSA_UInt32) pEnv->GetIntField(object, fieldIds.rgbHeight ); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "((((((((((path %s", pSettings->pAlphaFilePath); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "------- getAlphaMagicSettings width %d", pEnv->GetIntField(object, + fieldIds.rgbWidth )); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "-------- getAlphaMagicSettings Height %d", + pEnv->GetIntField(object, fieldIds.rgbHeight )); + } + + // Check if settings could be set. + if (*pResult) + { + // Return the settings. + (*ppSettings) = pSettings; + } + else + { + // Free the settings. + videoEditClasses_freeAlphaMagicSettings(&pSettings); + } + } +} + +void +videoEditClasses_freeAlphaMagicSettings( + M4xVSS_AlphaMagicSettings** ppSettings) +{ + // Check if memory was allocated for the AlphaMagicSettings. + if (M4OSA_NULL != (*ppSettings)) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_freeAlphaMagicSettings()"); + + // Free the alpha file path. + videoEditOsal_free((*ppSettings)->pAlphaFilePath); + (*ppSettings)->pAlphaFilePath = M4OSA_NULL; + + // Free the settings structure. + videoEditOsal_free((*ppSettings)); + (*ppSettings) = M4OSA_NULL; + } +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logAlphaMagicSettings( + M4xVSS_AlphaMagicSettings* pSettings, + int indentation) +{ + // Check if memory was allocated for the AlphaMagicSettings. + if (M4OSA_NULL != pSettings) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pAlphaFilePath: %s", indentation, ' ', + (M4OSA_NULL != pSettings->pAlphaFilePath) ? \ + (char *)pSettings->pAlphaFilePath : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c blendingPercent: %u %%", indentation, ' ', + (unsigned int)pSettings->blendingPercent); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c isreverse: %s", indentation, ' ', + pSettings->isreverse ? "true" : "false"); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c <null>", indentation, ' '); + } +} +#endif + + +void +videoEditClasses_getBackgroundMusicSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4xVSS_BGMSettings** ppSettings) +{ + VideoEditJava_BackgroundMusicFieldIds fieldIds = {NULL, NULL, NULL, NULL, + NULL, NULL,NULL,NULL,NULL,NULL}; + M4xVSS_BGMSettings* pSettings = M4OSA_NULL; + bool converted = true; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_getBackgroundMusicSettings()"); + + // Retrieve the field ids. + videoEditJava_getBackgroundMusicFieldIds(pResult, pEnv, &fieldIds); + } + + // Only retrieve the BackgroundMusicSettings if the fields could be located. + if (*pResult) + { + // Check if the object is valid. + if (NULL != object) + { + // Allocate memory for the BackgroundMusicSettings. + pSettings = (M4xVSS_BGMSettings*)videoEditOsal_alloc(pResult, pEnv, + sizeof(M4xVSS_BGMSettings), "BackgroundMusicSettings"); + + // Check if memory could be allocated for the BackgroundMusicSettings. + if (*pResult) + { + // Set the input file path. + pSettings->pFile = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, object, + fieldIds.file, M4OSA_NULL); + + // Check if the input file path is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (M4OSA_NULL == pSettings->pFile), "backgroundMusicSettings.file is null"); + } + + // Check if the input file path could be retrieved. + if (*pResult) + { + // Set the file type .3gp, .amr, .mp3. + pSettings->FileType = M4VIDEOEDITING_kFileType_PCM; + /*(M4VIDEOEDITING_FileType)videoEditJava_getClipTypeJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.fileType));*/ + + // Check if the file type is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "backgroundMusicSettings.fileType is invalid"); + } + + // Check if the file type could be retrieved. + if (*pResult) + { + // Set the time, in milliseconds, at which the added audio track is inserted. + pSettings->uiAddCts = (M4OSA_UInt32)pEnv->GetLongField(object, + fieldIds.insertionTime); + + // Set the volume, in percentage (0..100), of the added audio track. + pSettings->uiAddVolume = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.volumePercent); + + // Set the start time of the loop in milli seconds. + pSettings->uiBeginLoop = (M4OSA_UInt32)pEnv->GetLongField(object, + fieldIds.beginLoop); + + // Set the end time of the loop in milli seconds. + pSettings->uiEndLoop = (M4OSA_UInt32)pEnv->GetLongField(object, + fieldIds.endLoop); + // Set the end time of the loop in milli seconds. + pSettings->b_DuckingNeedeed = + (M4OSA_Bool)pEnv->GetBooleanField(object, fieldIds.enableDucking); + + // Set the end time of the loop in milli seconds. + pSettings->InDucking_threshold = + (M4OSA_Int32)pEnv->GetIntField(object, fieldIds.duckingThreshold); + + // Set the end time of the loop in milli seconds. + pSettings->lowVolume = + (M4OSA_Float)(((M4OSA_Float)pEnv->GetIntField(object, fieldIds.lowVolume))); + + // Set the end time of the loop in milli seconds. + pSettings->bLoop = (M4OSA_Bool)pEnv->GetBooleanField(object, fieldIds.isLooping); + + // Set sampling freq and channels + pSettings->uiSamplingFrequency = M4VIDEOEDITING_k32000_ASF; + pSettings->uiNumChannels = 2; + } + + // Check if settings could be set. + if (*pResult) + { + // Return the settings. + (*ppSettings) = pSettings; + } + else + { + // Free the settings. + videoEditClasses_freeBackgroundMusicSettings(&pSettings); + } + } + } +} + +void +videoEditClasses_freeBackgroundMusicSettings( + M4xVSS_BGMSettings** ppSettings) +{ + // Check if memory was allocated for the BackgroundMusicSettings. + if (M4OSA_NULL != (*ppSettings)) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_freeBackgroundMusicSettings()"); + + // Free the input file path. + videoEditOsal_free((*ppSettings)->pFile); + (*ppSettings)->pFile = M4OSA_NULL; + + // Free the settings structure. + videoEditOsal_free((*ppSettings)); + (*ppSettings) = M4OSA_NULL; + } +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logBackgroundMusicSettings( + M4xVSS_BGMSettings* pSettings, + int indentation) +{ + // Check if memory was allocated for the BackgroundMusicSettings. + if (M4OSA_NULL != pSettings) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c pFile: %s", + indentation, ' ', + (M4OSA_NULL != pSettings->pFile) ? (char *)pSettings->pFile : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c FileType: %s", indentation, ' ', + videoEditJava_getClipTypeString(pSettings->FileType)); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c uiAddCts: %u ms", + indentation, ' ', (unsigned int)pSettings->uiAddCts); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c uiAddVolume: %u %%", + indentation, ' ', (unsigned int)pSettings->uiAddVolume); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c uiBeginLoop: %u ms", + indentation, ' ', (unsigned int)pSettings->uiBeginLoop); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c uiEndLoop: %u ms", + indentation, ' ', (unsigned int)pSettings->uiEndLoop); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c b_DuckingNeedeed:\ + %u ", indentation, ' ', (bool)pSettings->b_DuckingNeedeed); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c InDucking_threshold: \ + %u ms", indentation, ' ', (unsigned int)pSettings->InDucking_threshold); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c lowVolume: %2.2f ",\ + indentation, ' ', (float)pSettings->lowVolume); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c bLoop: %u ms",\ + indentation, ' ', (bool)pSettings->bLoop); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c <null>", + indentation, ' '); + } +} +#endif + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logClipProperties( + M4VIDEOEDITING_ClipProperties* pProperties, + int indentation) +{ + // Check if memory was allocated for the ClipProperties. + if (M4OSA_NULL != pProperties) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bAnalysed: %s", indentation, ' ', + pProperties->bAnalysed ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c Version: %d.%d.%d", indentation, ' ', + pProperties->Version[0], pProperties->Version[1], pProperties->Version[2]); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiClipDuration: %u", indentation, ' ', + (unsigned int)pProperties->uiClipDuration); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c FileType: %s", indentation, ' ', + videoEditJava_getClipTypeString(pProperties->FileType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c ftyp:", + indentation, ' '); + videoEditClasses_logFtypBox(&pProperties->ftyp, indentation + VIDEOEDIT_LOG_INDENTATION); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c VideoStreamType: %s", indentation, ' ', + videoEditJava_getVideoFormatString(pProperties->VideoStreamType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiClipVideoDuration: %u", indentation, ' ', + (unsigned int)pProperties->uiClipVideoDuration); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiVideoBitrate: %s", indentation, ' ', + videoEditJava_getBitrateString(pProperties->uiVideoBitrate)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiVideoMaxAuSize: %u", indentation, ' ', + (unsigned int)pProperties->uiVideoMaxAuSize); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiVideoWidth: %u", indentation, ' ', + (unsigned int)pProperties->uiVideoWidth); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiVideoHeight: %u", indentation, ' ', + (unsigned int)(unsigned int)pProperties->uiVideoHeight); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiVideoTimeScale: %u", indentation, ' ', + (unsigned int)pProperties->uiVideoTimeScale); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c fAverageFrameRate: %.3f", indentation, ' ', + pProperties->fAverageFrameRate); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c ProfileAndLevel: %s", indentation, ' ', + videoEditJava_getVideoProfileString(pProperties->ProfileAndLevel)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiH263level: %d", indentation, ' ', + pProperties->uiH263level); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiVideoProfile: %d", indentation, ' ', + pProperties->uiVideoProfile); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bMPEG4dataPartition: %s", indentation, ' ', + pProperties->bMPEG4dataPartition ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bMPEG4rvlc: %s", indentation, ' ', + pProperties->bMPEG4rvlc ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bMPEG4resynchMarker: %s", indentation, ' ', + pProperties->bMPEG4resynchMarker ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c AudioStreamType: %s", indentation, ' ', + videoEditJava_getAudioFormatString(pProperties->AudioStreamType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiClipAudioDuration: %u", indentation, ' ', + (unsigned int)pProperties->uiClipAudioDuration); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiAudioBitrate: %s", indentation, ' ', + videoEditJava_getBitrateString(pProperties->uiAudioBitrate)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiAudioMaxAuSize: %u", indentation, ' ', + (unsigned int)pProperties->uiAudioMaxAuSize); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiNbChannels: %u", indentation, ' ', + (unsigned int)pProperties->uiNbChannels); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiSamplingFrequency: %u", indentation, ' ', + (unsigned int)pProperties->uiSamplingFrequency); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiExtendedSamplingFrequency: %u", indentation, ' ', + (unsigned int)pProperties->uiExtendedSamplingFrequency); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiDecodedPcmSize: %u", indentation, ' ', + (unsigned int)pProperties->uiDecodedPcmSize); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bVideoIsEditable: %s", indentation, ' ', + pProperties->bVideoIsEditable ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bAudioIsEditable: %s", indentation, ' ', + pProperties->bAudioIsEditable ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bVideoIsCompatibleWithMasterClip: %s", indentation, ' ', + pProperties->bVideoIsCompatibleWithMasterClip ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bAudioIsCompatibleWithMasterClip: %s", indentation, ' ', + pProperties->bAudioIsCompatibleWithMasterClip ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiClipAudioVolumePercentage: %d", indentation, ' ', + pProperties->uiClipAudioVolumePercentage); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c <null>", + indentation, ' '); + } +} +#endif + +void +videoEditClasses_getClipSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_ClipSettings** ppSettings) +{ + VideoEditJava_ClipSettingsFieldIds fieldIds = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + M4VSS3GPP_ClipSettings* pSettings = M4OSA_NULL; + M4OSA_ERR result = M4NO_ERROR; + bool converted = true; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_getClipSettings()"); + + // Retrieve the field ids. + videoEditJava_getClipSettingsFieldIds(pResult, pEnv, &fieldIds); + } + + // Only validate the ClipSettings if the fields could be located. + if (*pResult) + { + // Check if the clip is set. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (NULL == object), + "clip is null"); + } + + // Only retrieve the ClipSettings if the fields could be located and validated. + if (*pResult) + { + // Allocate memory for the ClipSettings. + pSettings = (M4VSS3GPP_ClipSettings *)videoEditOsal_alloc(pResult, pEnv, + sizeof(M4VSS3GPP_ClipSettings), "ClipSettings"); + + // Check if memory could be allocated for the ClipSettings. + if (*pResult) + { + // Log the API call. + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4xVSS_CreateClipSettings()"); + + // Initialize the ClipSettings. + result = M4xVSS_CreateClipSettings(pSettings, NULL, 0, 0); + + // Log the result. + VIDEOEDIT_LOG_RESULT(ANDROID_LOG_INFO, "VIDEO_EDITOR", + videoEditOsal_getResultString(result)); + + // Check if the initialization succeeded. + videoEditJava_checkAndThrowRuntimeException(pResult, pEnv, + (M4NO_ERROR != result), result); + } + + // Check if the allocation and initialization succeeded + //(required because pSettings is dereferenced). + if (*pResult) + { + // Set the input file path. + pSettings->pFile = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, object, + fieldIds.clipPath, &pSettings->filePathSize); + + // Check if the file path is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (M4OSA_NULL == pSettings->pFile), "clip.clipPath is null"); + } + + // Check if the input file could be retrieved. + if (*pResult) + { + // Set the file type .3gp, .amr, .mp3. + pSettings->FileType = (M4VIDEOEDITING_FileType)videoEditJava_getClipTypeJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.fileType)); + + if ( pSettings->FileType == M4VIDEOEDITING_kFileType_JPG) + { + pSettings->FileType = M4VIDEOEDITING_kFileType_ARGB8888; + } + + // Check if the file type is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "clip.fileType is invalid"); + } + + // Check if the file type could be retrieved. + if (*pResult) + { + // Set the begin cut time, in milliseconds. + pSettings->uiBeginCutTime = + (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.beginCutTime); + + // Set the end cut time, in milliseconds. + pSettings->uiEndCutTime = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.endCutTime); + + // Set the begin cut time, in percent of clip duration (only for 3GPP clip !). + pSettings->xVSS.uiBeginCutPercent = + (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.beginCutPercent); + + // Set the end cut time, in percent of clip duration (only for 3GPP clip !). + pSettings->xVSS.uiEndCutPercent = + (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.endCutPercent); + + // Set the duration of the clip, if different from 0, + // has priority on uiEndCutTime or uiEndCutPercent. + pSettings->xVSS.uiDuration = 0; + + // Set whether or not the pan and zoom mode is enabled. + pSettings->xVSS.isPanZoom = + (M4OSA_Bool)pEnv->GetBooleanField(object, fieldIds.panZoomEnabled); + + // Set the pan and zoom start zoom percentage. + pSettings->xVSS.PanZoomXa = + (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomPercentStart); + + // Set the pan and zoom start x. + pSettings->xVSS.PanZoomTopleftXa = + (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomTopLeftXStart); + + // Set the pan and zoom start y. + pSettings->xVSS.PanZoomTopleftYa = + (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomTopLeftYStart); + + // Set the pan and zoom end zoom percentage. + pSettings->xVSS.PanZoomXb = + (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomPercentEnd); + + // Set the pan and zoom end x. + pSettings->xVSS.PanZoomTopleftXb = + (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomTopLeftXEnd); + + // Set the pan and zoom end y. + pSettings->xVSS.PanZoomTopleftYb = + (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomTopLeftYEnd); + + // Set the media rendering mode, only used with JPEG to crop, resize, + // or render black borders. + pSettings->xVSS.MediaRendering = + (M4xVSS_MediaRendering)videoEditJava_getMediaRenderingJavaToC( + &converted, pEnv->GetIntField(object,fieldIds.mediaRendering)); + + // Check if the media rendering is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, !converted, + "clip.mediaRendering is invalid"); + + // Capture the rgb file width and height + pSettings->ClipProperties.uiStillPicWidth = + (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.rgbFileWidth); + pSettings->ClipProperties.uiStillPicHeight = + (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.rgbFileHeight); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", \ + "getClipSettings-- rgbFileWidth %d ", + pSettings->ClipProperties.uiStillPicWidth); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", \ + "getClipSettings-- rgbFileHeight %d ", + pSettings->ClipProperties.uiStillPicHeight); + } + + // Check if settings could be set. + if (*pResult) + { + // Return the settings. + (*ppSettings) = pSettings; + } + else + { + // Free the settings. + videoEditClasses_freeClipSettings(&pSettings); + } + } +} + +void +videoEditClasses_createClipSettings( + bool* pResult, + JNIEnv* pEnv, + M4VSS3GPP_ClipSettings* pSettings, + jobject* pObject) +{ + VideoEditJava_ClipSettingsFieldIds fieldIds = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL}; + jclass clazz = NULL; + jobject object = NULL; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_createClipSettings()"); + + // Retrieve the class. + videoEditJava_getClipSettingsClass(pResult, pEnv, &clazz); + + // Retrieve the field ids. + videoEditJava_getClipSettingsFieldIds(pResult, pEnv, &fieldIds); + } + + // Only create an object if the class and fields could be located. + if (*pResult) + { + // Allocate a new object. + object = pEnv->AllocObject(clazz); + if (NULL != object) + { + // Set the clipPath field. + pEnv->SetObjectField(object, fieldIds.clipPath, NULL); + + // Set the fileType field. + pEnv->SetIntField(object, fieldIds.fileType, videoEditJava_getClipTypeCToJava( + pSettings->FileType)); + + // Set the beginCutTime field. + pEnv->SetIntField(object, fieldIds.beginCutTime, pSettings->uiBeginCutTime); + + // Set the endCutTime field. + pEnv->SetIntField(object, fieldIds.endCutTime, pSettings->uiEndCutTime); + + // Set the beginCutPercent field. + pEnv->SetIntField(object, fieldIds.beginCutPercent, pSettings->xVSS.uiBeginCutPercent); + + // Set the endCutPercent field. + pEnv->SetIntField(object, fieldIds.endCutPercent, pSettings->xVSS.uiEndCutPercent); + + // Set the panZoomEnabled field. + pEnv->SetBooleanField(object, fieldIds.panZoomEnabled, pSettings->xVSS.isPanZoom); + + // Set the panZoomPercentStart field. + pEnv->SetIntField(object, fieldIds.panZoomPercentStart, + (100 - pSettings->xVSS.PanZoomXa)); + + // Set the panZoomTopLeftXStart field. + pEnv->SetIntField(object, fieldIds.panZoomTopLeftXStart, + pSettings->xVSS.PanZoomTopleftXa); + + // Set the panZoomTopLeftYStart field. + pEnv->SetIntField(object, fieldIds.panZoomTopLeftYStart, + pSettings->xVSS.PanZoomTopleftYa); + + // Set the panZoomPercentEnd field. + pEnv->SetIntField(object, fieldIds.panZoomPercentEnd, + (100 - pSettings->xVSS.PanZoomXb)); + + // Set the panZoomTopLeftXEnd field. + pEnv->SetIntField(object, fieldIds.panZoomTopLeftXEnd, + pSettings->xVSS.PanZoomTopleftXb); + + // Set the panZoomTopLeftYEnd field. + pEnv->SetIntField(object, fieldIds.panZoomTopLeftYEnd, + pSettings->xVSS.PanZoomTopleftYb); + + // Set the mediaRendering field. + pEnv->SetIntField(object, fieldIds.mediaRendering, + videoEditJava_getMediaRenderingCToJava(pSettings->xVSS.MediaRendering)); + + // Set the rgb file width and height + pEnv->SetIntField(object, fieldIds.rgbFileWidth, + pSettings->ClipProperties.uiStillPicWidth ); + + pEnv->SetIntField(object, fieldIds.rgbFileHeight, + pSettings->ClipProperties.uiStillPicHeight ); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "rgbFileWeight %d rgbFileHeight %d ", + pSettings->ClipProperties.uiStillPicWidth , + pSettings->ClipProperties.uiStillPicHeight); + + // Return the object. + (*pObject) = object; + } + } +} +void +videoEditPropClass_createProperties( + bool* pResult, + JNIEnv* pEnv, + VideoEditPropClass_Properties* pProperties, + jobject* pObject) +{ + VideoEditJava_PropertiesFieldIds fieldIds = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + jclass clazz = NULL; + jobject object = NULL; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "videoEditPropClass_createProperties()"); + + // Retrieve the class. + videoEditJava_getPropertiesClass(pResult, pEnv, &clazz); + + // Retrieve the field ids. + videoEditJava_getPropertiesFieldIds(pResult, pEnv, &fieldIds); + } + + // Only create an object if the class and fields could be located. + if (*pResult) + { + // Allocate a new object. + object = pEnv->AllocObject(clazz); + if (NULL != object) + { + // Set the duration field. + pEnv->SetIntField(object, fieldIds.duration, pProperties->uiClipDuration); + + // Set the fileType field. + pEnv->SetIntField(object, fieldIds.fileType, + videoEditJava_getFileTypeCToJava(pProperties->FileType)); + + // Set the videoFormat field. + pEnv->SetIntField(object, fieldIds.videoFormat, + videoEditJava_getVideoFormatCToJava(pProperties->VideoStreamType)); + + // Set the videoDuration field. + pEnv->SetIntField(object, fieldIds.videoDuration, pProperties->uiClipVideoDuration); + + // Set the videoBitrate field. + pEnv->SetIntField(object, fieldIds.videoBitrate, pProperties->uiVideoBitrate); + + // Set the width field. + pEnv->SetIntField(object, fieldIds.width, pProperties->uiVideoWidth); + + // Set the height field. + pEnv->SetIntField(object, fieldIds.height, pProperties->uiVideoHeight); + + // Set the averageFrameRate field. + pEnv->SetFloatField(object, fieldIds.averageFrameRate, pProperties->fAverageFrameRate); + + // Set the profileAndLevel field. + pEnv->SetIntField(object, fieldIds.profileAndLevel, + videoEditJava_getVideoProfileCToJava(pProperties->ProfileAndLevel)); + + // Set the audioFormat field. + pEnv->SetIntField(object, fieldIds.audioFormat, + videoEditJava_getAudioFormatCToJava(pProperties->AudioStreamType)); + + // Set the audioDuration field. + pEnv->SetIntField(object, fieldIds.audioDuration, pProperties->uiClipAudioDuration); + + // Set the audioBitrate field. + pEnv->SetIntField(object, fieldIds.audioBitrate, pProperties->uiAudioBitrate); + + // Set the audioChannels field. + pEnv->SetIntField(object, fieldIds.audioChannels, pProperties->uiNbChannels); + + // Set the audioSamplingFrequency field. + pEnv->SetIntField(object, fieldIds.audioSamplingFrequency, + pProperties->uiSamplingFrequency); + + // Return the object. + (*pObject) = object; + } + } +} + +void +videoEditClasses_freeClipSettings( + M4VSS3GPP_ClipSettings** ppSettings) +{ + // Check if memory was allocated for the ClipSettings. + if (M4OSA_NULL != (*ppSettings)) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_freeClipSettings()"); + + // Free the input file path. + videoEditOsal_free((*ppSettings)->pFile); + (*ppSettings)->pFile = M4OSA_NULL; + (*ppSettings)->filePathSize = 0; + + // Free the clip settings. + M4xVSS_FreeClipSettings((*ppSettings)); + + // Free the settings structure. + videoEditOsal_free((*ppSettings)); + (*ppSettings) = M4OSA_NULL; + } +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logClipSettings( + M4VSS3GPP_ClipSettings* pSettings, + int indentation) +{ + // Check if memory was allocated for the ClipSettings. + if (M4OSA_NULL != pSettings) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pFile: %s", indentation, ' ', + (M4OSA_NULL != pSettings->pFile) ? (char*)pSettings->pFile : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c FileType: %s", indentation, ' ', + videoEditJava_getClipTypeString(pSettings->FileType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c filePathSize: %u", indentation, ' ', + (unsigned int)pSettings->filePathSize); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c ClipProperties:", indentation, ' '); + videoEditClasses_logClipProperties(&pSettings->ClipProperties, + indentation + VIDEOEDIT_LOG_INDENTATION); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiBeginCutTime: %u ms", indentation, ' ', + (unsigned int)pSettings->uiBeginCutTime); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiEndCutTime: %u ms", indentation, ' ', + (unsigned int)pSettings->uiEndCutTime); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiBeginCutPercent: %u %%", indentation, ' ', + (unsigned int)pSettings->xVSS.uiBeginCutPercent); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiEndCutPercent: %u %%", indentation, ' ', + (unsigned int)pSettings->xVSS.uiEndCutPercent); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiDuration: %u ms", indentation, ' ', + (unsigned int)pSettings->xVSS.uiDuration); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c isPanZoom: %s", indentation, ' ', + pSettings->xVSS.isPanZoom ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c PanZoomXa: %d ms", indentation, ' ', + pSettings->xVSS.PanZoomXa); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c PanZoomTopleftXa: %d ms", indentation, ' ', + pSettings->xVSS.PanZoomTopleftXa); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c PanZoomTopleftYa: %d ms", indentation, ' ', + pSettings->xVSS.PanZoomTopleftYa); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c PanZoomXb: %d ms", indentation, ' ', + pSettings->xVSS.PanZoomXb); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c PanZoomTopleftXb: %d ms", indentation, ' ', + pSettings->xVSS.PanZoomTopleftXb); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c PanZoomTopleftYb: %d ms", indentation, ' ', + pSettings->xVSS.PanZoomTopleftYb); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c MediaRendering: %s", indentation, ' ', + videoEditJava_getMediaRenderingString(pSettings->xVSS.MediaRendering)); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c <null>", indentation, ' '); + } +} +#endif + + +void +videoEditClasses_getEditSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_EditSettings** ppSettings, + bool flag) +{ + VideoEditJava_EditSettingsFieldIds fieldIds ={NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL,NULL}; + jobjectArray clipSettingsArray = NULL; + jsize clipSettingsArraySize = 0; + jobject clipSettings = NULL; + jobjectArray transitionSettingsArray = NULL; + jsize transitionSettingsArraySize = 0; + jobject transitionSettings = NULL; + jobjectArray effectSettingsArray = NULL; + jsize effectSettingsArraySize = 0; + jobject effectSettings = NULL; + jobject backgroundMusicSettings = NULL; + int audioChannels = 0; + M4VSS3GPP_EditSettings* pSettings = M4OSA_NULL; + bool converted = true; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_getEditSettings()"); + + // Retrieve the field ids. + videoEditJava_getEditSettingsFieldIds(pResult, pEnv, &fieldIds); + } + + // Only retrieve the EditSettings if the previous action succeeded. + if (*pResult) + { + // Check if the object is valid. + if (NULL != object) + { + // Retrieve the clipSettingsArray. + videoEditJava_getArray(pResult, pEnv, object, + fieldIds.clipSettingsArray, + &clipSettingsArray, + &clipSettingsArraySize); + + // Retrieve the transitionSettingsArray. + videoEditJava_getArray(pResult, pEnv, object, + fieldIds.transitionSettingsArray, + &transitionSettingsArray, + &transitionSettingsArraySize); + + // Retrieve the effectSettingsArray. + videoEditJava_getArray(pResult, pEnv, object, + fieldIds.effectSettingsArray, + &effectSettingsArray, + &effectSettingsArraySize); + + // Retrieve the backgroundMusicSettings. + videoEditJava_getObject(pResult, pEnv, object, fieldIds.backgroundMusicSettings, + &backgroundMusicSettings); + + // Check if the arrays and background music settings object could be retrieved. + if (*pResult) + { + // Retrieve the number of channels. + audioChannels = pEnv->GetIntField(object, fieldIds.audioChannels); + } + } + } + + // Only validate the EditSettings if the fields could be located. + if (*pResult) + { + // Check if there is at least one clip. + //videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + // (clipSettingsArraySize < 1), + // "there should be at least one clip"); + if(clipSettingsArraySize < 1) { + return; + } + if(flag) + { + // Check if there are clips. + if ((clipSettingsArraySize != 0) || (transitionSettingsArraySize != 0)) + { + // The number of transitions must be equal to the number of clips - 1. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (clipSettingsArraySize != (transitionSettingsArraySize + 1)), + "the number of transitions should be equal to the number of clips - 1"); + } + } + } + + // Only retrieve the EditSettings if the fields could be located. + if (*pResult) + { + // Check if the object is valid. + if (NULL != object) + { + // Allocate memory for the EditSettings. + pSettings = (M4VSS3GPP_EditSettings*)videoEditOsal_alloc(pResult, pEnv, + sizeof(M4VSS3GPP_EditSettings), "EditSettings"); + + // Check if memory could be allocated for the EditSettings. + if (*pResult) + { + // Set the number of clips that will be edited. + pSettings->uiClipNumber = clipSettingsArraySize; + + // Check if the clip settings array contains items. + if (clipSettingsArraySize > 0) + { + // Allocate memory for the clip settings array. + pSettings->pClipList = (M4VSS3GPP_ClipSettings **)videoEditOsal_alloc(pResult, + pEnv, + clipSettingsArraySize * sizeof(M4VSS3GPP_ClipSettings *), + "ClipSettingsArray"); + if (*pResult) + { + // Loop over all clip settings objects. + for (int i = 0; ((*pResult) && (i < clipSettingsArraySize)); i++) + { + // Get the clip settings object. + clipSettings = pEnv->GetObjectArrayElement(clipSettingsArray, i); + + // Get the clip settings. + videoEditClasses_getClipSettings(pResult, pEnv, clipSettings, + &pSettings->pClipList[i]); + } + } + } + + // Check if the transition settings array contains items. + if (transitionSettingsArraySize > 0) + { + // Allocate memory for the transition settings array. + pSettings->pTransitionList = + (M4VSS3GPP_TransitionSettings **)videoEditOsal_alloc(pResult, + pEnv, transitionSettingsArraySize * sizeof(M4VSS3GPP_TransitionSettings *), + "TransitionSettingsArray"); + if (*pResult) + { + // Loop over all transition settings objects. + for (int i = 0; ((*pResult) && (i < transitionSettingsArraySize)); i++) + { + // Get the transition settings object. + transitionSettings = + pEnv->GetObjectArrayElement(transitionSettingsArray, i); + + // Get the transition settings. + videoEditClasses_getTransitionSettings(pResult, pEnv, + transitionSettings, &pSettings->pTransitionList[i]); + } + } + } + + // Check if the effect settings array contains items. + if (effectSettingsArraySize > 0) + { + // Allocate memory for the effect settings array. + pSettings->Effects = (M4VSS3GPP_EffectSettings*)videoEditOsal_alloc(pResult, + pEnv, + effectSettingsArraySize * sizeof(M4VSS3GPP_EffectSettings), + "EffectSettingsArray"); + if (*pResult) + { + // Loop over all effect settings objects. + for (int i = 0; ((*pResult) && (i < effectSettingsArraySize)); i++) + { + // Get the effect settings object. + effectSettings = pEnv->GetObjectArrayElement(effectSettingsArray, i); + + // Get the effect settings. + videoEditClasses_getEffectSettings(pResult, pEnv, effectSettings, + &pSettings->Effects[i]); + } + } + } + + // Check if the clips, transitions and effects could be set. + if (*pResult) + { + // Set the number of effects in the clip. + pSettings->nbEffects = (M4OSA_UInt8)effectSettingsArraySize; + + // Set the frame rate of the output video. + pSettings->videoFrameRate = + (M4VIDEOEDITING_VideoFramerate)videoEditJava_getVideoFrameRateJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.videoFrameRate)); + + // Check if the frame rate is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "editSettings.videoFrameRate is invalid"); + } + + // Check if the frame rate could be set. + if (*pResult) + { + // Set the path of the output file. + pSettings->pOutputFile = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, + object, fieldIds.outputFile, &pSettings->uiOutputPathSize); + } + + // Check if path of the output file could be set. + if (*pResult) + { + // Set the path of the temporary file produced when using + // the constant memory 3gp writer. + pSettings->pTemporaryFile = M4OSA_NULL; + + // Set the output video size. + pSettings->xVSS.outputVideoSize = + (M4VIDEOEDITING_VideoFrameSize)videoEditJava_getVideoFrameSizeJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.videoFrameSize)); + + // Check if the output video size is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "editSettings.videoFrameSize is invalid"); + } + + // Check if the output video size could be set. + if (*pResult) + { + // Set the output video format. + pSettings->xVSS.outputVideoFormat = + (M4VIDEOEDITING_VideoFormat)videoEditJava_getVideoFormatJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.videoFormat)); + + // Check if the output video format is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "editSettings.videoFormat is invalid"); + } + + // Check if the output video format could be set. + if (*pResult) + { + // Set the output audio format. + pSettings->xVSS.outputAudioFormat = + (M4VIDEOEDITING_AudioFormat)videoEditJava_getAudioFormatJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.audioFormat)); + + // Check if the output audio format is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "editSettings.audioFormat is invalid"); + } + + // Check if the output audio format could be set. + if (*pResult) + { + // Set the output audio sampling frequency when not replacing the audio, + // or replacing it with MP3 audio. + pSettings->xVSS.outputAudioSamplFreq = + (M4VIDEOEDITING_AudioSamplingFrequency)\ + videoEditJava_getAudioSamplingFrequencyJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.audioSamplingFreq)); + + // Check if the output audio sampling frequency is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "editSettings.audioSamplingFreq is invalid"); + } + + // Check if the output audio sampling frequency could be set. + if (*pResult) + { + // Check if the number of audio channels is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + ((0 != audioChannels ) || + ((M4VIDEOEDITING_kNoneAudio != pSettings->xVSS.outputAudioFormat) && + (M4VIDEOEDITING_kNullAudio != pSettings->xVSS.outputAudioFormat) ) ) && + (1 != audioChannels ) && + (2 != audioChannels ), + "editSettings.audioChannels must be set to 0, 1 or 2"); + } + + // Check if the number of audio channels is valid. + if (*pResult) + { + // Set the maximum output file size (MMS usecase). + pSettings->xVSS.outputFileSize = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.maxFileSize); + + // Whether or not the audio is mono, only valid for AAC. + pSettings->xVSS.bAudioMono = (M4OSA_Bool)(1 == audioChannels); + + // Set the output video bitrate. + pSettings->xVSS.outputVideoBitrate = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.videoBitrate); + + // Set the output audio bitrate. + pSettings->xVSS.outputAudioBitrate = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.audioBitrate); + + // Set the background music settings. + videoEditClasses_getBackgroundMusicSettings(pResult, pEnv, + backgroundMusicSettings, &pSettings->xVSS.pBGMtrack); + + // Set the text rendering function (will be set elsewhere). + pSettings->xVSS.pTextRenderingFct = M4OSA_NULL; + pSettings->PTVolLevel = + (M4OSA_Float)pEnv->GetIntField(object, fieldIds.primaryTrackVolume); + } + } + + // Check if settings could be set. + if (*pResult) + { + // Return the settings. + (*ppSettings) = pSettings; + } + else + { + // Free the settings. + videoEditClasses_freeEditSettings(&pSettings); + } + } + } +} + +void +videoEditClasses_freeEditSettings( + M4VSS3GPP_EditSettings** ppSettings) +{ + // Check if memory was allocated for the EditSettings. + if (M4OSA_NULL != (*ppSettings)) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_freeEditSettings()"); + + // Free the background music settings. + videoEditClasses_freeBackgroundMusicSettings(&(*ppSettings)->xVSS.pBGMtrack); + + // Free the path of the output file. + videoEditOsal_free((*ppSettings)->pOutputFile); + (*ppSettings)->pOutputFile = M4OSA_NULL; + (*ppSettings)->uiOutputPathSize = 0; + + // Check if the EffectSettings should be freed. + if (M4OSA_NULL != (*ppSettings)->Effects) + { + // Loop over all effect settings. + for (int i = 0; i < (*ppSettings)->nbEffects; i++) + { + // Free the effect settings. + videoEditClasses_freeEffectSettings(&(*ppSettings)->Effects[i]); + } + + // Free the memory for the effect settings array. + videoEditOsal_free((*ppSettings)->Effects); + (*ppSettings)->Effects = M4OSA_NULL; + } + + // Reset the number of effects in the clip. + (*ppSettings)->nbEffects = 0; + + // Check if there are clips. + if (0 < (*ppSettings)->uiClipNumber) + { + // Check if the TransitionSettings should be freed. + if (M4OSA_NULL != (*ppSettings)->pTransitionList) + { + // Loop over all transition settings. + for (int i = 0; i < ((*ppSettings)->uiClipNumber - 1); i++) + { + // Free the transition settings. + videoEditClasses_freeTransitionSettings(&(*ppSettings)->pTransitionList[i]); + } + + // Free the memory for the transition settings array. + videoEditOsal_free((*ppSettings)->pTransitionList); + (*ppSettings)->pTransitionList = M4OSA_NULL; + } + + // Check if the ClipSettings should be freed. + if (M4OSA_NULL != (*ppSettings)->pClipList) + { + // Loop over all clip settings. + for (int i = 0; i < (*ppSettings)->uiClipNumber; i++) + { + // Free the clip settings. + videoEditClasses_freeClipSettings(&(*ppSettings)->pClipList[i]); + } + + // Free the memory for the clip settings array. + videoEditOsal_free((*ppSettings)->pClipList); + (*ppSettings)->pClipList = M4OSA_NULL; + } + } + + // Reset the number of clips. + (*ppSettings)->uiClipNumber = 0; + + // Free the settings structure. + videoEditOsal_free((*ppSettings)); + (*ppSettings) = M4OSA_NULL; + } +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logEditSettings( + M4VSS3GPP_EditSettings* pSettings, + int indentation) +{ + // Check if memory was allocated for the EditSettings. + if (M4OSA_NULL != pSettings) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiClipNumber: %d", indentation, ' ', + pSettings->uiClipNumber); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiMasterClip: %d", indentation, ' ', + pSettings->uiMasterClip); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pClipList: %s", indentation, ' ', + (M4OSA_NULL != pSettings->pClipList) ? " " : "<null>"); + if (M4OSA_NULL != pSettings->pClipList) + { + indentation += VIDEOEDIT_LOG_INDENTATION; + for (int i = 0; i < pSettings->uiClipNumber; i++) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pClipList[%d]:", indentation, ' ', + i); + videoEditClasses_logClipSettings(pSettings->pClipList[i], + indentation + VIDEOEDIT_LOG_INDENTATION); + } + indentation -= VIDEOEDIT_LOG_INDENTATION; + } + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pTransitionList: %s", indentation, ' ', + (M4OSA_NULL != pSettings->pTransitionList) ? " " : "<null>"); + if (M4OSA_NULL != pSettings->pTransitionList) + { + indentation += VIDEOEDIT_LOG_INDENTATION; + for (int i = 0; i < (pSettings->uiClipNumber - 1); i++) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pTransitionList[%d]:", indentation, ' ', i); + videoEditClasses_logTransitionSettings(pSettings->pTransitionList[i], + indentation + VIDEOEDIT_LOG_INDENTATION); + } + indentation -= VIDEOEDIT_LOG_INDENTATION; + } + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c Effects: %s", indentation, ' ', + (M4OSA_NULL != pSettings->Effects) ? " " : "<null>"); + if (M4OSA_NULL != pSettings->Effects) + { + indentation += VIDEOEDIT_LOG_INDENTATION; + for (int i = 0; i < pSettings->nbEffects; i++) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c Effects[%d]:", indentation, ' ', i); + videoEditClasses_logEffectSettings(&pSettings->Effects[i], + indentation + VIDEOEDIT_LOG_INDENTATION); + } + indentation -= VIDEOEDIT_LOG_INDENTATION; + } + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c nbEffects: %d", indentation, ' ', + pSettings->nbEffects); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c videoFrameRate: %s", indentation, ' ', + videoEditJava_getVideoFrameRateString(pSettings->videoFrameRate)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pOutputFile: %s", indentation, ' ', + (M4OSA_NULL != pSettings->pOutputFile) ? (char*)pSettings->pOutputFile : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiOutputPathSize: %u", indentation, ' ', + (unsigned int)pSettings->uiOutputPathSize); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pTemporaryFile: %s", indentation, ' ', + (M4OSA_NULL != pSettings->pTemporaryFile) ?\ + (char*)pSettings->pTemporaryFile : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c outputVideoSize: %s", indentation, ' ', + videoEditJava_getVideoFrameSizeString(pSettings->xVSS.outputVideoSize)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c outputVideoFormat: %s", indentation, ' ', + videoEditJava_getVideoFormatString(pSettings->xVSS.outputVideoFormat)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c outputAudioFormat: %s", indentation, ' ', + videoEditJava_getAudioFormatString(pSettings->xVSS.outputAudioFormat)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c outputAudioSamplFreq: %s", indentation, ' ', + videoEditJava_getAudioSamplingFrequencyString(pSettings->xVSS.outputAudioSamplFreq)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c outputFileSize: %u", indentation, ' ', + (unsigned int)pSettings->xVSS.outputFileSize); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bAudioMono: %s", indentation, ' ', + pSettings->xVSS.bAudioMono ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c outputVideoBitrate: %s", indentation, ' ', + videoEditJava_getBitrateString(pSettings->xVSS.outputVideoBitrate)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c outputAudioBitrate: %s", indentation, ' ', + videoEditJava_getBitrateString(pSettings->xVSS.outputAudioBitrate)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pBGMtrack:", indentation, ' '); + videoEditClasses_logBackgroundMusicSettings(pSettings->xVSS.pBGMtrack, + indentation + VIDEOEDIT_LOG_INDENTATION); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pTextRenderingFct: %s", indentation, ' ', + (M4OSA_NULL != pSettings->xVSS.pTextRenderingFct) ? "set" : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c PTVolLevel: %u", indentation, ' ', + (unsigned int)pSettings->PTVolLevel); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c <null>", indentation, ' '); + } +} +#endif + + +void +videoEditClasses_getEffectSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_EffectSettings* pSettings) +{ + VideoEditJava_EffectSettingsFieldIds fieldIds = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + bool converted = true; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_getEffectSettings()"); + + // Retrieve the field ids. + videoEditJava_getEffectSettingsFieldIds(pResult, pEnv, &fieldIds); + } + + // Only validate the EffectSettings if the fields could be located. + if (*pResult) + { + // Check if the effect is set. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (NULL == object), + "effect is null"); + } + + // Only retrieve the EffectSettings if the fields could be located and validated. + if (*pResult) + { + // Set the start time in milliseconds. + pSettings->uiStartTime = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.startTime); + + // Set the duration in milliseconds. + pSettings->uiDuration = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.duration); + + // Set the video effect type, None, FadeIn, FadeOut, etc. + pSettings->VideoEffectType = + (M4VSS3GPP_VideoEffectType)videoEditJava_getVideoEffectJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.videoEffectType)); + + // Check if the video effect type is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "effect.videoEffectType is invalid"); + } + + // Check if the video effect type could be set. + if (*pResult) + { + // Set the external effect function. + pSettings->ExtVideoEffectFct = M4OSA_NULL; + + // Set the context given to the external effect function. + pSettings->pExtVideoEffectFctCtxt = M4OSA_NULL; + + // Set the audio effect type, None, FadeIn, FadeOut. + pSettings->AudioEffectType = + (M4VSS3GPP_AudioEffectType)videoEditJava_getAudioEffectJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.audioEffectType)); + + // Check if the audio effect type is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "effect.audioEffectType is invalid"); + } + + // Check if the audio effect type could be set. + if (*pResult) + { + // Set the start in percentage of the cut clip duration. + pSettings->xVSS.uiStartPercent = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.startPercent); + + // Set the duration in percentage of the ((clip duration) - (effect starttime)). + pSettings->xVSS.uiDurationPercent = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.durationPercent); + + // Set the framing file path (GIF/PNG file). + pSettings->xVSS.pFramingFilePath = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, + object, fieldIds.framingFile, M4OSA_NULL); + + // Check if this is a framing effect. + if (M4xVSS_kVideoEffectType_Framing == (M4xVSS_VideoEffectType)pSettings->VideoEffectType) + { + // Check if the framing file path is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (M4OSA_NULL == pSettings->xVSS.pFramingFilePath), "effect.framingFile is null"); + } + } + + // Check if the framing file path could be retrieved. + if (*pResult) + { + // Set the Framing RGB565 buffer. + pSettings->xVSS.pFramingBuffer = M4OSA_NULL; + + // Set the top-left X coordinate in the output picture + // where the added frame will be displayed. + pSettings->xVSS.topleft_x = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.topLeftX); + + // Set the top-left Y coordinate in the output picture + // where the added frame will be displayed. + pSettings->xVSS.topleft_y = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.topLeftY); + + // Set whether or not the framing image is resized to output video size. + pSettings->xVSS.bResize = + (M4OSA_Bool)pEnv->GetBooleanField(object, fieldIds.framingResize); + + // Set the new size to which framing buffer needs to be resized to + pSettings->xVSS.framingScaledSize = + (M4VIDEOEDITING_VideoFrameSize)pEnv->GetIntField(object, fieldIds.framingScaledSize); + + // Set the text buffer. + pSettings->xVSS.pTextBuffer = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, object, + fieldIds.text, &pSettings->xVSS.textBufferSize); + } + + // Check if the text buffer could be retrieved. + if (*pResult) + { + // Set the data used by the font engine (size, color...). + pSettings->xVSS.pRenderingData = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, + object, fieldIds.textRenderingData, M4OSA_NULL); + } + + // Check if the text rendering data could be retrieved. + if (*pResult) + { + // Set the text plane width. + pSettings->xVSS.uiTextBufferWidth = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.textBufferWidth); + + // Set the text plane height. + pSettings->xVSS.uiTextBufferHeight = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.textBufferHeight); + + // Set the processing rate of the effect added when using the Fifties effect. + pSettings->xVSS.uiFiftiesOutFrameRate = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.fiftiesFrameRate); + + // Set the RGB16 input color of the effect added when using the rgb16 color effect. + pSettings->xVSS.uiRgb16InputColor = (M4OSA_UInt16)pEnv->GetIntField(object, + fieldIds.rgb16InputColor); + + // Set the start percentage of Alpha blending. + pSettings->xVSS.uialphaBlendingStart = (M4OSA_UInt8)pEnv->GetIntField(object, + fieldIds.alphaBlendingStartPercent); + + // Set the middle percentage of Alpha blending. + pSettings->xVSS.uialphaBlendingMiddle = (M4OSA_UInt8)pEnv->GetIntField(object, + fieldIds.alphaBlendingMiddlePercent); + + // Set the end percentage of Alpha blending. + pSettings->xVSS.uialphaBlendingEnd = (M4OSA_UInt8)pEnv->GetIntField(object, + fieldIds.alphaBlendingEndPercent); + + // Set the duration, in percentage of effect duration, of the FadeIn phase. + pSettings->xVSS.uialphaBlendingFadeInTime = (M4OSA_UInt8)pEnv->GetIntField(object, + fieldIds.alphaBlendingFadeInTimePercent); + + // Set the duration, in percentage of effect duration, of the FadeOut phase. + pSettings->xVSS.uialphaBlendingFadeOutTime = (M4OSA_UInt8)pEnv->GetIntField(object, + fieldIds.alphaBlendingFadeOutTimePercent); + + if (pSettings->xVSS.pFramingFilePath != M4OSA_NULL) + { + pSettings->xVSS.pFramingBuffer = + (M4VIFI_ImagePlane *)M4OSA_malloc(sizeof(M4VIFI_ImagePlane), + 0x00,(M4OSA_Char *)"framing buffer"); + } + + if (pSettings->xVSS.pFramingBuffer != M4OSA_NULL) + { + // OverFrame height and width + pSettings->xVSS.pFramingBuffer->u_width = pEnv->GetIntField(object, + fieldIds.width); + + pSettings->xVSS.pFramingBuffer->u_height = pEnv->GetIntField(object, + fieldIds.height); + + pSettings->xVSS.width = pSettings->xVSS.pFramingBuffer->u_width; + pSettings->xVSS.height = pSettings->xVSS.pFramingBuffer->u_height; + pSettings->xVSS.rgbType = M4VSS3GPP_kRGB888; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "pFramingBuffer u_width %d ", pSettings->xVSS.pFramingBuffer->u_width); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "pFramingBuffer u_height %d", pSettings->xVSS.pFramingBuffer->u_height); + + } + + // Check if settings could be set. + if (!(*pResult)) + { + // Free the settings. + videoEditClasses_freeEffectSettings(pSettings); + } + } +} + +void +videoEditClasses_freeEffectSettings( + M4VSS3GPP_EffectSettings* pSettings) +{ + // Check if memory was allocated for the EffectSettings. + if (M4OSA_NULL != pSettings) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_freeEffectSettings()"); + + // Free the data used by the font engine (size, color...). + videoEditOsal_free(pSettings->xVSS.pRenderingData); + pSettings->xVSS.pRenderingData = M4OSA_NULL; + + // Free the text buffer. + videoEditOsal_free(pSettings->xVSS.pTextBuffer); + pSettings->xVSS.pTextBuffer = M4OSA_NULL; + pSettings->xVSS.textBufferSize = 0; + + // Free the framing file path. + videoEditOsal_free(pSettings->xVSS.pFramingFilePath); + pSettings->xVSS.pFramingFilePath = M4OSA_NULL; + } +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logEffectSettings( + M4VSS3GPP_EffectSettings* pSettings, + int indentation) +{ + // Check if memory was allocated for the EffectSettings. + if (M4OSA_NULL != pSettings) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiStartTime: %u ms", indentation, ' ', + (unsigned int)pSettings->uiStartTime); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiDuration: %u ms", indentation, ' ', + (unsigned int)pSettings->uiDuration); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c VideoEffectType: %s", indentation, ' ', + videoEditJava_getVideoEffectString(pSettings->VideoEffectType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c ExtVideoEffectFct: %s", indentation, ' ', + (M4OSA_NULL != pSettings->ExtVideoEffectFct) ? "set" : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pExtVideoEffectFctCtxt: %s", indentation, ' ', + (M4OSA_NULL != pSettings->pExtVideoEffectFctCtxt) ? "set" : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c AudioEffectType: %s", indentation, ' ', + videoEditJava_getAudioEffectString(pSettings->AudioEffectType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiStartPercent: %u %%", indentation, ' ', + (unsigned int)pSettings->xVSS.uiStartPercent); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiDurationPercent: %u %%", indentation, ' ', + (unsigned int)pSettings->xVSS.uiDurationPercent); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pFramingFilePath: %s", indentation, ' ', + (M4OSA_NULL != pSettings->xVSS.pFramingFilePath) ?\ + (char*)pSettings->xVSS.pFramingFilePath : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pFramingBuffer: %s", indentation, ' ', + (M4OSA_NULL != pSettings->xVSS.pFramingBuffer) ? "set" : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c topleft_x: %u", indentation, ' ', + (unsigned int)pSettings->xVSS.topleft_x); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c topleft_y: %u", indentation, ' ', + (unsigned int)pSettings->xVSS.topleft_y); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c bResize: %s", indentation, ' ', + pSettings->xVSS.bResize ? "true" : "false"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pTextBuffer: %s", indentation, ' ', + (M4OSA_NULL != pSettings->xVSS.pTextBuffer) ?\ + (char*)pSettings->xVSS.pTextBuffer : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c textBufferSize: %u", indentation, ' ', + (unsigned int)pSettings->xVSS.textBufferSize); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pRenderingData: %s", indentation, ' ', + (M4OSA_NULL != pSettings->xVSS.pRenderingData) ?\ + (char*)pSettings->xVSS.pRenderingData : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiTextBufferWidth: %u", indentation, ' ', + (unsigned int)pSettings->xVSS.uiTextBufferWidth); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiTextBufferHeight: %u", indentation, ' ', + (unsigned int)pSettings->xVSS.uiTextBufferHeight); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiFiftiesOutFrameRate: %u", indentation, ' ', + (unsigned int)pSettings->xVSS.uiFiftiesOutFrameRate); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiRgb16InputColor: %d", indentation, ' ', + pSettings->xVSS.uiRgb16InputColor); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uialphaBlendingStart: %d %%", indentation, ' ', + pSettings->xVSS.uialphaBlendingStart); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uialphaBlendingMiddle: %d %%", indentation, ' ', + pSettings->xVSS.uialphaBlendingMiddle); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uialphaBlendingEnd: %d %%", indentation, ' ', + pSettings->xVSS.uialphaBlendingEnd); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uialphaBlendingFadeInTime: %d %%", indentation, ' ', + pSettings->xVSS.uialphaBlendingFadeInTime); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uialphaBlendingFadeOutTime: %d %%", indentation, ' ', + pSettings->xVSS.uialphaBlendingFadeOutTime); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c <null>", indentation, ' '); + } +} +#endif + + +void +videoEditClasses_getSlideTransitionSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4xVSS_SlideTransitionSettings** ppSettings) +{ + VideoEditJava_SlideTransitionSettingsFieldIds fieldIds = {NULL}; + M4xVSS_SlideTransitionSettings* pSettings = M4OSA_NULL; + bool converted = true; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_getSlideTransitionSettings()"); + + // Retrieve the field ids. + videoEditJava_getSlideTransitionSettingsFieldIds(pResult, pEnv, &fieldIds); + } + + + // Only validate the SlideTransitionSettings if the fields could be located. + if (*pResult) + { + // Check if the clip is set. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (NULL == object), + "slideSettings is null"); + } + + // Only retrieve the SlideTransitionSettings if the fields could be located and validated. + if (*pResult) + { + // Allocate memory for the SlideTransitionSettings. + pSettings = (M4xVSS_SlideTransitionSettings*)videoEditOsal_alloc(pResult, pEnv, + sizeof(M4xVSS_SlideTransitionSettings), "SlideTransitionSettings"); + + // Check if memory could be allocated for the SlideTransitionSettings. + if (*pResult) + { + // Set the direction of the slide. + pSettings->direction = + (M4xVSS_SlideTransition_Direction)videoEditJava_getSlideDirectionJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.direction)); + + // Check if the direction is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + !converted, "slideSettings.direction is invalid"); + } + + // Check if settings could be set. + if (*pResult) + { + // Return the settings. + (*ppSettings) = pSettings; + } + else + { + // Free the settings. + videoEditClasses_freeSlideTransitionSettings(&pSettings); + } + } +} + +void +videoEditClasses_freeSlideTransitionSettings( + M4xVSS_SlideTransitionSettings** ppSettings) +{ + // Check if memory was allocated for the SlideTransitionSettings. + if (M4OSA_NULL != (*ppSettings)) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_freeSlideTransitionSettings()"); + + // Free the settings structure. + videoEditOsal_free((*ppSettings)); + (*ppSettings) = M4OSA_NULL; + } +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logSlideTransitionSettings( + M4xVSS_SlideTransitionSettings* pSettings, + int indentation) +{ + // Check if memory was allocated for the SlideTransitionSettings. + if (M4OSA_NULL != pSettings) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c direction: %s", indentation, ' ', + videoEditJava_getSlideDirectionString(pSettings->direction)); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c <null>", indentation, ' '); + } +} +#endif + + +void +videoEditClasses_getTransitionSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_TransitionSettings** ppSettings) +{ + VideoEditJava_TransitionSettingsFieldIds fieldIds = {NULL, NULL, NULL, NULL, NULL, NULL}; + jobject alphaSettings = NULL; + jobject slideSettings = NULL; + M4VSS3GPP_TransitionSettings* pSettings = M4OSA_NULL; + bool converted = true; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_getTransitionSettings()"); + + // Retrieve the field ids. + videoEditJava_getTransitionSettingsFieldIds(pResult, pEnv, &fieldIds); + } + + // Only validate the TransitionSettings if the fields could be located. + if (*pResult) + { + // Check if the transition is set. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (NULL == object), + "transition is null"); + } + + // Check if the field ids could be located and validated. + if (*pResult) + { + // Retrieve the alphaSettings. + videoEditJava_getObject(pResult, pEnv, object, fieldIds.alphaSettings, &alphaSettings); + + // Retrieve the slideSettings. + videoEditJava_getObject(pResult, pEnv, object, fieldIds.slideSettings, &slideSettings); + } + + // Only retrieve the TransitionSettings if the fields could be located. + if (*pResult) + { + // Allocate memory for the TransitionSettings. + pSettings = (M4VSS3GPP_TransitionSettings*)videoEditOsal_alloc(pResult, + pEnv, sizeof(M4VSS3GPP_TransitionSettings), "TransitionSettings"); + + // Check if memory could be allocated for the TransitionSettings. + if (*pResult) + { + // Set the duration of the transition, in milliseconds (set to 0 to get no transition). + pSettings->uiTransitionDuration = (M4OSA_UInt32)pEnv->GetIntField(object, + fieldIds.duration); + + // Set the type of the video transition. + pSettings->VideoTransitionType = + (M4VSS3GPP_VideoTransitionType)videoEditJava_getVideoTransitionJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.videoTransitionType)); + + // Check if the video transition type is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, !converted, + "transition.videoTransitionType is invalid"); + } + + // Check if the video transition type could be set. + if (*pResult) + { + // Set the external transition video effect function. + pSettings->ExtVideoTransitionFct = M4OSA_NULL; + + // Set the context of the external transition video effect function. + pSettings->pExtVideoTransitionFctCtxt = M4OSA_NULL; + + // Set the type of the audio transition. + pSettings->AudioTransitionType = + (M4VSS3GPP_AudioTransitionType)videoEditJava_getAudioTransitionJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.audioTransitionType)); + + // Check if the audio transition type is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, !converted, + "transition.audioTransitionType is invalid"); + } + + // Check if the audio transition type could be set. + if (*pResult) + { + // Set the transition behaviour. + pSettings->TransitionBehaviour = + (M4VSS3GPP_TransitionBehaviour)videoEditJava_getTransitionBehaviourJavaToC( + &converted, pEnv->GetIntField(object, fieldIds.transitionBehaviour)); + + // Check if the transition behaviour is valid. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, !converted, + "transition.transitionBehaviour is invalid"); + } + + // Check if the audio transition behaviour could be set. + if (*pResult) + { + // Check if a slide transition or alpha magic setting object is expected. + if ((int)pSettings->VideoTransitionType == M4xVSS_kVideoTransitionType_SlideTransition) + { + // Set the slide transition settings. + videoEditClasses_getSlideTransitionSettings(pResult, pEnv, slideSettings, + &pSettings->xVSS.transitionSpecific.pSlideTransitionSettings); + } + else if ((int)pSettings->VideoTransitionType == M4xVSS_kVideoTransitionType_AlphaMagic) + { + // Set the alpha magic settings. + videoEditClasses_getAlphaMagicSettings(pResult, pEnv, alphaSettings, + &pSettings->xVSS.transitionSpecific.pAlphaMagicSettings); + } + } + + // Check if settings could be set. + if (*pResult) + { + // Return the settings. + (*ppSettings) = pSettings; + } + else + { + // Free the settings. + videoEditClasses_freeTransitionSettings(&pSettings); + } + } +} + +void +videoEditClasses_freeTransitionSettings( + M4VSS3GPP_TransitionSettings** ppSettings) +{ + // Check if memory was allocated for the TransitionSettings. + if (M4OSA_NULL != (*ppSettings)) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_freeTransitionSettings()"); + + // Check if a slide transition or alpha magic setting structure is expected. + if ((int)(*ppSettings)->VideoTransitionType == M4xVSS_kVideoTransitionType_SlideTransition) + { + // Free the slide transition settings. + videoEditClasses_freeSlideTransitionSettings( + &(*ppSettings)->xVSS.transitionSpecific.pSlideTransitionSettings); + } + else + { + // Free the alpha magic settings. + videoEditClasses_freeAlphaMagicSettings( + &(*ppSettings)->xVSS.transitionSpecific.pAlphaMagicSettings); + } + + // Free the settings structure. + videoEditOsal_free((*ppSettings)); + (*ppSettings) = M4OSA_NULL; + } +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logTransitionSettings( + M4VSS3GPP_TransitionSettings* pSettings, + int indentation) +{ + // Check if memory was allocated for the TransitionSettings. + if (M4OSA_NULL != pSettings) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c uiTransitionDuration: %u ms", indentation, ' ', + (unsigned int)pSettings->uiTransitionDuration); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c VideoTransitionType: %s", indentation, ' ', + videoEditJava_getVideoTransitionString(pSettings->VideoTransitionType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c ExtVideoTransitionFct: %s", indentation, ' ', + (M4OSA_NULL != pSettings->ExtVideoTransitionFct) ? "set" : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pExtVideoTransitionFctCtxt: %s", indentation, ' ', + (M4OSA_NULL != pSettings->pExtVideoTransitionFctCtxt) ? "set" : "<null>"); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c AudioTransitionType: %s", indentation, ' ', + videoEditJava_getAudioTransitionString(pSettings->AudioTransitionType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c TransitionBehaviour: %s", indentation, ' ', + videoEditJava_getTransitionBehaviourString(pSettings->TransitionBehaviour)); + + // Check if a slide transition or alpha magic setting structure is expected. + if ((int)pSettings->VideoTransitionType == M4xVSS_kVideoTransitionType_SlideTransition) + { + // Log the slide transition settings. + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pSlideTransitionSettings:", indentation, ' '); + videoEditClasses_logSlideTransitionSettings\ + (pSettings->xVSS.transitionSpecific.pSlideTransitionSettings, + indentation + VIDEOEDIT_LOG_INDENTATION); + } + else + { + // Log the alpha magic settings. + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c pAlphaMagicSettings:", indentation, ' '); + videoEditClasses_logAlphaMagicSettings\ + (pSettings->xVSS.transitionSpecific.pAlphaMagicSettings, + indentation + VIDEOEDIT_LOG_INDENTATION); + } + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c <null>", indentation, ' '); + } +} +#endif +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditPropClass_logProperties( + VideoEditPropClass_Properties* pProperties, + int indentation) +{ + // Check if memory was allocated for the Properties. + if (M4OSA_NULL != pProperties) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiClipDuration: %u", indentation, ' ', + (unsigned int)pProperties->uiClipDuration); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c FileType: %s", indentation, ' ', + videoEditJava_getFileTypeString(pProperties->FileType)); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c VideoStreamType: %s", indentation, ' ', + videoEditJava_getVideoFormatString(pProperties->VideoStreamType)); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiClipVideoDuration: %u", indentation, ' ', + (unsigned int)pProperties->uiClipVideoDuration); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiVideoBitrate: %s", indentation, ' ', + videoEditJava_getBitrateString(pProperties->uiVideoBitrate)); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiVideoWidth: %u", indentation, ' ', + (unsigned int)pProperties->uiVideoWidth); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiVideoHeight: %u", indentation, ' ', + (unsigned int)(unsigned int)pProperties->uiVideoHeight); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c fAverageFrameRate: %.3f", indentation, ' ', + pProperties->fAverageFrameRate); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c ProfileAndLevel: %s", indentation, ' ', + videoEditJava_getVideoProfileString(pProperties->ProfileAndLevel)); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c AudioStreamType: %s", indentation, ' ', + videoEditJava_getAudioFormatString(pProperties->AudioStreamType)); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiClipAudioDuration: %u", indentation, ' ', + (unsigned int)pProperties->uiClipAudioDuration); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiAudioBitrate: %s", indentation, ' ', + videoEditJava_getBitrateString(pProperties->uiAudioBitrate)); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiNbChannels: %u", indentation, ' ', + (unsigned int)pProperties->uiNbChannels); + + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c uiSamplingFrequency: %u", indentation, ' ', + (unsigned int)pProperties->uiSamplingFrequency); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES", + "%*c <null>", indentation, ' '); + } +} +#endif + + +void +videoEditClasses_createVersion( + bool* pResult, + JNIEnv* pEnv, + M4_VersionInfo* pVersionInfo, + jobject* pObject) +{ + VideoEditJava_VersionFieldIds fieldIds = {NULL, NULL, NULL}; + jclass clazz = NULL; + jobject object = NULL; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_createVersion()"); + + // Retrieve the class. + videoEditJava_getVersionClass(pResult, pEnv, &clazz); + + // Retrieve the field ids. + videoEditJava_getVersionFieldIds(pResult, pEnv, &fieldIds); + } + + // Only create an object if the class and fields could be located. + if (*pResult) + { + // Allocate a new object. + object = pEnv->AllocObject(clazz); + + // check if alloc is done + videoEditJava_checkAndThrowRuntimeException(pResult, pEnv, + (NULL == object), + M4ERR_ALLOC); + if (NULL != object) + { + // Set the major field. + pEnv->SetIntField(object, fieldIds.major, pVersionInfo->m_major); + + // Set the minor field. + pEnv->SetIntField(object, fieldIds.minor, pVersionInfo->m_minor); + + // Set the revision field. + pEnv->SetIntField(object, fieldIds.revision, pVersionInfo->m_revision); + + // Return the object. + (*pObject) = object; + } + } +} + +#ifdef VIDEOEDIT_LOGGING_ENABLED +void +videoEditClasses_logVersion( + M4_VersionInfo* pVersionInfo, + int indentation) +{ + // Check if memory was allocated for the Version. + if (M4OSA_NULL != pVersionInfo) + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c major: %u ms", indentation, ' ', + (unsigned int)pVersionInfo->m_major); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c minor: %u", indentation, ' ', + (unsigned int)pVersionInfo->m_minor); + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c revision: %u", indentation, ' ', + (unsigned int)pVersionInfo->m_revision); + } + else + { + VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "%*c <null>", indentation, ' '); + } +} +#endif + + +void* +videoEditClasses_getContext( + bool* pResult, + JNIEnv* pEnv, + jobject object) +{ + void* pContext = M4OSA_NULL; + jclass clazz = NULL; + VideoEditJava_EngineFieldIds fieldIds = {NULL}; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_getContext()"); + + // Retrieve the class. + videoEditJava_getEngineClass(pResult, pEnv, &clazz); + + // Retrieve the field ids. + videoEditJava_getEngineFieldIds(pResult, pEnv, &fieldIds); + } + + // Check if the class and field ids could be located. + if (*pResult) + { + // Retrieve the context pointer. + pContext = (void *)pEnv->GetIntField(object, fieldIds.context); + } + + // Return the context pointer. + return(pContext); +} + +void +videoEditClasses_setContext( + bool* pResult, + JNIEnv* pEnv, + jobject object, + void* pContext) +{ + jclass clazz = NULL; + VideoEditJava_EngineFieldIds fieldIds = {NULL}; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "videoEditClasses_setContext()"); + + // Retrieve the class. + videoEditJava_getEngineClass(pResult, pEnv, &clazz); + + // Retrieve the field ids. + videoEditJava_getEngineFieldIds(pResult, pEnv, &fieldIds); + } + + // Check if the class and field ids could be located. + if (*pResult) + { + // Set the context field. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "The context value from JAVA before setting is = 0x%x", + pEnv->GetIntField(object, fieldIds.context)); + + pEnv->SetIntField(object, fieldIds.context, (int)pContext); + M4OSA_TRACE1_1("The context value in JNI is = 0x%x",pContext); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", + "The context value from JAVA after setting is = 0x%x", + pEnv->GetIntField(object, fieldIds.context)); + } +} + diff --git a/media/jni/mediaeditor/VideoEditorClasses.h b/media/jni/mediaeditor/VideoEditorClasses.h new file mode 100755 index 000000000000..3c8f05588b04 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorClasses.h @@ -0,0 +1,589 @@ +/* + * 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. + */ + +#ifndef VIDEO_EDITOR_CLASSES_H +#define VIDEO_EDITOR_CLASSES_H + +#include <VideoEditorJava.h> +#include <VideoEditorClasses.h> +/** + ************************************************************************ + * @file VideoEditorClasses.h + * @brief Interface for JNI methods/defines that have specific + * access to class, objects and method Ids defined in Java layer + ************************************************************************ +*/ + + +extern "C" { +#include <M4xVSS_API.h> +#include <M4VSS3GPP_API.h> +#include <M4VSS3GPP_ErrorCodes.h> +#include <M4MCS_ErrorCodes.h> +#include <M4READER_Common.h> +#include <M4WRITER_common.h> +}; + +/* + * Java layer class/object name strings + */ +#define PACKAGE_NAME "android/media/videoeditor" + +#define MANUAL_EDIT_ENGINE_CLASS_NAME PACKAGE_NAME"/MediaArtistNativeHelper" +#define MEDIA_PROPERTIES_ENGINE_CLASS_NAME PACKAGE_NAME"/MediaArtistNativeHelper" + +#define AUDIO_FORMAT_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioFormat" +#define RESULTS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$Results" +#define VERSION_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$Version" +#define AUDIO_SAMPLING_FREQUENCY_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioSamplingFrequency" +#define BITRATE_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$Bitrate" +#define ERROR_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$Result" +#define FILE_TYPE_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$FileType" +#define MEDIA_RENDERING_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$MediaRendering" +#define VIDEO_FORMAT_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoFormat" +#define VIDEO_FRAME_RATE_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoFrameRate" +#define VIDEO_FRAME_SIZE_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoFrameSize" +#define VIDEO_PROFILE_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoProfile" +#define ALPHA_MAGIC_SETTINGS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$AlphaMagicSettings" +#define AUDIO_EFFECT_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioEffect" +#define AUDIO_TRANSITION_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioTransition" +#define BACKGROUND_MUSIC_SETTINGS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$BackgroundMusicSettings" +#define CLIP_SETTINGS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$ClipSettings" +#define EDIT_SETTINGS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$EditSettings" +#define EFFECT_SETTINGS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$EffectSettings" +#define SLIDE_DIRECTION_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$SlideDirection" +#define SLIDE_TRANSITION_SETTINGS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$SlideTransitionSettings" +#define TRANSITION_BEHAVIOUR_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$TransitionBehaviour" +#define TRANSITION_SETTINGS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$TransitionSettings" +#define VIDEO_EFFECT_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoEffect" +#define VIDEO_TRANSITION_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoTransition" +#define PREVIEW_CLIPS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$PreviewClips" +#define PREVIEW_SETTING_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$PreviewSettings" +#define PREVIEW_PROPERTIES_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$PreviewClipProperties" +#define AUDIO_SETTINGS_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioSettings" +#define PROPERTIES_CLASS_NAME MANUAL_EDIT_ENGINE_CLASS_NAME"$Properties" + +#define TASK_IDLE 0 +#define TASK_LOADING_SETTINGS 1 +#define TASK_ENCODING 2 + +/* + * File type enum + */ +typedef enum +{ + VideoEditClasses_kFileType_3GPP, + VideoEditClasses_kFileType_MP4, + VideoEditClasses_kFileType_AMR, + VideoEditClasses_kFileType_MP3, + VideoEditClasses_kFileType_PCM, + VideoEditClasses_kFileType_JPG, + VideoEditClasses_kFileType_GIF, + VideoEditClasses_kFileType_PNG, + VideoEditClasses_kFileType_Unsupported +} VideoEditClasses_FileType; + +/* + * Alpha magic transition structure + */ +typedef struct +{ + jfieldID file; + jfieldID blendingPercent; + jfieldID invertRotation; + jfieldID rgbWidth; + jfieldID rgbHeight; +} VideoEditJava_AlphaMagicFieldIds; + +typedef struct +{ + jfieldID file; + jfieldID fileType; + jfieldID insertionTime; + jfieldID volumePercent; + jfieldID beginLoop; + jfieldID endLoop; + jfieldID enableDucking; + jfieldID duckingThreshold; + jfieldID lowVolume; + jfieldID isLooping; +} VideoEditJava_BackgroundMusicFieldIds; +/* + * Structure to hold media properties from native layer + */ +typedef struct { + M4OSA_UInt32 uiClipDuration; + VideoEditClasses_FileType FileType; + M4VIDEOEDITING_VideoFormat VideoStreamType; + M4OSA_UInt32 uiClipVideoDuration; + M4OSA_UInt32 uiVideoBitrate; + M4OSA_UInt32 uiVideoWidth; + M4OSA_UInt32 uiVideoHeight; + M4OSA_Float fAverageFrameRate; + M4VIDEOEDITING_VideoProfileAndLevel ProfileAndLevel; + M4VIDEOEDITING_AudioFormat AudioStreamType; + M4OSA_UInt32 uiClipAudioDuration; + M4OSA_UInt32 uiAudioBitrate; + M4OSA_UInt32 uiNbChannels; + M4OSA_UInt32 uiSamplingFrequency; +} VideoEditPropClass_Properties; + +typedef struct +{ + jfieldID duration; + jfieldID fileType; + jfieldID videoFormat; + jfieldID videoDuration; + jfieldID videoBitrate; + jfieldID width; + jfieldID height; + jfieldID averageFrameRate; + jfieldID profileAndLevel; + jfieldID audioFormat; + jfieldID audioDuration; + jfieldID audioBitrate; + jfieldID audioChannels; + jfieldID audioSamplingFrequency; +} VideoEditJava_PropertiesFieldIds; + + +typedef struct +{ + jfieldID clipPath; + jfieldID fileType; + jfieldID beginCutTime; + jfieldID endCutTime; + jfieldID beginCutPercent; + jfieldID endCutPercent; + jfieldID panZoomEnabled; + jfieldID panZoomPercentStart; + jfieldID panZoomTopLeftXStart; + jfieldID panZoomTopLeftYStart; + jfieldID panZoomPercentEnd; + jfieldID panZoomTopLeftXEnd; + jfieldID panZoomTopLeftYEnd; + jfieldID mediaRendering; + jfieldID rgbFileWidth; + jfieldID rgbFileHeight; +} VideoEditJava_ClipSettingsFieldIds; + +typedef struct +{ + jfieldID clipSettingsArray; + jfieldID transitionSettingsArray; + jfieldID effectSettingsArray; + jfieldID videoFrameRate; + jfieldID outputFile; + jfieldID videoFrameSize; + jfieldID videoFormat; + jfieldID audioFormat; + jfieldID audioSamplingFreq; + jfieldID maxFileSize; + jfieldID audioChannels; + jfieldID videoBitrate; + jfieldID audioBitrate; + jfieldID backgroundMusicSettings; + jfieldID primaryTrackVolume; +} VideoEditJava_EditSettingsFieldIds; + + +typedef struct +{ + jfieldID startTime; + jfieldID duration; + jfieldID videoEffectType; + jfieldID audioEffectType; + jfieldID startPercent; + jfieldID durationPercent; + jfieldID framingFile; + jfieldID framingBuffer; + jfieldID bitmapType; + jfieldID width; + jfieldID height; + jfieldID topLeftX; + jfieldID topLeftY; + jfieldID framingResize; + jfieldID framingScaledSize; + jfieldID text; + jfieldID textRenderingData; + jfieldID textBufferWidth; + jfieldID textBufferHeight; + jfieldID fiftiesFrameRate; + jfieldID rgb16InputColor; + jfieldID alphaBlendingStartPercent; + jfieldID alphaBlendingMiddlePercent; + jfieldID alphaBlendingEndPercent; + jfieldID alphaBlendingFadeInTimePercent; + jfieldID alphaBlendingFadeOutTimePercent; +} VideoEditJava_EffectSettingsFieldIds; + +typedef struct +{ + jfieldID context; +} VideoEditJava_EngineFieldIds; + +typedef struct +{ + jfieldID direction; +} VideoEditJava_SlideTransitionSettingsFieldIds; + +typedef struct +{ + jfieldID duration; + jfieldID videoTransitionType; + jfieldID audioTransitionType; + jfieldID transitionBehaviour; + jfieldID alphaSettings; + jfieldID slideSettings; +} VideoEditJava_TransitionSettingsFieldIds; + +typedef struct +{ + jfieldID major; + jfieldID minor; + jfieldID revision; +} VideoEditJava_VersionFieldIds; + + +typedef struct +{ + jmethodID onProgressUpdate; +} VideoEditJava_EngineMethodIds; + + +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(AudioEffect ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(AudioFormat ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(AudioSamplingFrequency) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(AudioTransition ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(Bitrate ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(Engine ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(Error ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(FileType ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(MediaRendering ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(SlideDirection ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(TransitionBehaviour ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoEffect ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoFormat ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoFrameRate ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoFrameSize ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoProfile ) +VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoTransition ) + + +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(AlphaMagic ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(BackgroundMusic ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(ClipSettings ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(ClipSettings ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(EditSettings ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(EffectSettings ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(Engine ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(SlideTransitionSettings ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(TransitionSettings ) +VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(Version ) + +VIDEOEDIT_JAVA_DECLARE_METHOD_CLASS(Engine ) + +/* + * Init all Edit settings related structures + */ +void +videoEditClasses_init( + bool* pResult, + JNIEnv* pEnv); +/** + ************************************************************************ + * @brief Media Properties init function. + * @param pResult (OUT) Pointer to hold result + * @param pEnv (IN) JVM Interface pointer + ************************************************************************ +*/ +void +videoEditPropClass_init( + bool* pResult, + JNIEnv* pEnv); +/** + ************************************************************************ + * @brief Interface to populate Media Properties. + * @param pResult (IN/OUT) Pointer to hold result + * @param pEnv (IN) JVM Interface pointer + * @param pProperties (IN) Media propeties structure pointer + * @param pObject (OUT) Java object to hold media + * properties for java layer. + ************************************************************************ +*/ +void +videoEditPropClass_createProperties( + bool* pResult, + JNIEnv* pEnv, + VideoEditPropClass_Properties* pProperties, + jobject* pObject); + +/** + ************************************************************************ + * @brief Interface to log/display media properties. + * @param pProperties (IN) Pointer holding media properties + * @param indentation (IN) Indentation to follow in display + ************************************************************************ +*/ +void +videoEditPropClass_logProperties( + VideoEditPropClass_Properties* pProperties, + int indentation); + +/* + * Get alpha magic transition settings + */ +void +videoEditClasses_getAlphaMagicSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4xVSS_AlphaMagicSettings** ppSettings); + +/* + * Free alpha magic transition settings structure + */ +void +videoEditClasses_freeAlphaMagicSettings( + M4xVSS_AlphaMagicSettings** ppSettings); + +/* + * Log alpha magic transition settings + */ +void +videoEditClasses_logAlphaMagicSettings( + M4xVSS_AlphaMagicSettings* pSettings, + int indentation); + +/* + * Get Background Track settings + */ +void +videoEditClasses_getBackgroundMusicSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4xVSS_BGMSettings** ppSettings); + +/* + * Free Background Track settings structure + */ +void +videoEditClasses_freeBackgroundMusicSettings( + M4xVSS_BGMSettings** ppSettings); + +/* + * Log Background Track settings + */ +void +videoEditClasses_logBackgroundMusicSettings( + M4xVSS_BGMSettings* pSettings, + int indentation); + +/* + * Log clip properties + */ +void +videoEditClasses_logClipProperties( + M4VIDEOEDITING_ClipProperties* pProperties, + int indentation); + +/* + * Get clip settings from Java + */ +void +videoEditClasses_getClipSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_ClipSettings** ppSettings); +/** + ************************************************************************ + * @brief Interface function to retrieve media properties for a given + * file. + * @param pEnv (IN) Pointer holding media properties + * @param thiz (IN) Indentation to follow in display + * @param file (IN) File path for which media properties has + * to be retrieved. + ************************************************************************ +*/ +jobject +videoEditProp_getProperties( + JNIEnv* pEnv, + jobject thiz, + jstring file); + +/* + * Create/Set the clip settings to java Object + */ +void +videoEditClasses_createClipSettings( + bool* pResult, + JNIEnv* pEnv, + M4VSS3GPP_ClipSettings* pSettings, + jobject* pObject); + +/* + * Free clip settings structure + */ +void +videoEditClasses_freeClipSettings( + M4VSS3GPP_ClipSettings** ppSettings); + +/* + * Log clip settings structure + */ +void +videoEditClasses_logClipSettings( + M4VSS3GPP_ClipSettings* pSettings, + int indentation); + +/* + * Get Edit settings from Java + */ +void +videoEditClasses_getEditSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_EditSettings** ppSettings, + bool flag); + +/* + * Free Edit Settings structure + */ +void +videoEditClasses_freeEditSettings( + M4VSS3GPP_EditSettings** ppSettings); + +/* + * Log Edit settings structure + */ +void +videoEditClasses_logEditSettings( + M4VSS3GPP_EditSettings* pSettings, + int indentation); + +/* + * Get Effect settings from Java + */ +void +videoEditClasses_getEffectSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_EffectSettings* pSettings); + +/* + * Free Effect settings structure + */ +void +videoEditClasses_freeEffectSettings( + M4VSS3GPP_EffectSettings* pSettings); + +/* + * Log Effect settings + */ +void +videoEditClasses_logEffectSettings( + M4VSS3GPP_EffectSettings* pSettings, + int indentation); + +/* + * Get Transition-Sliding settings from Java + */ +void +videoEditClasses_getSlideTransitionSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4xVSS_SlideTransitionSettings** ppSettings); + +/* + * Free Transition-Sliding structure + */ +void +videoEditClasses_freeSlideTransitionSettings( + M4xVSS_SlideTransitionSettings** ppSettings); + +/* + * Free Transition-Sliding structure + */ +void +videoEditClasses_logSlideTransitionSettings( + M4xVSS_SlideTransitionSettings* pSettings, + int indentation); + +/* + * Get Transition settings from Java + */ +void +videoEditClasses_getTransitionSettings( + bool* pResult, + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_TransitionSettings** ppSettings); + +/* + * Free Transition settings structure + */ +void +videoEditClasses_freeTransitionSettings( + M4VSS3GPP_TransitionSettings** ppSettings); + +/* + * Log Transition settings + */ +void +videoEditClasses_logTransitionSettings( + M4VSS3GPP_TransitionSettings* pSettings, + int indentation); + +/* + * Set version information to Java object + */ +void +videoEditClasses_createVersion( + bool* pResult, + JNIEnv* pEnv, + M4_VersionInfo* pVersionInfo, + jobject* pObject); + +/* + * Log Version information + */ +void +videoEditClasses_logVersion( + M4_VersionInfo* pVersionInfo, + int indentation); + + +void* +videoEditClasses_getContext( + bool* pResult, + JNIEnv* pEnv, + jobject object); + +void +videoEditClasses_setContext( + bool* pResult, + JNIEnv* pEnv, + jobject object, + void* pContext); + + +#endif // VIDEO_EDITOR_CLASSES_H + diff --git a/media/jni/mediaeditor/VideoEditorJava.cpp b/media/jni/mediaeditor/VideoEditorJava.cpp new file mode 100755 index 000000000000..1d610f69c48b --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorJava.cpp @@ -0,0 +1,885 @@ +/* + * 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 <VideoEditorClasses.h> +#include <VideoEditorJava.h> +#include <VideoEditorLogging.h> +#include <VideoEditorOsal.h> + +extern "C" { +#include <M4OSA_CharStar.h> +}; + + +void +videoEditJava_checkAndThrowIllegalArgumentException( + bool* pResult, + JNIEnv* pEnv, + bool condition, + const char* pMessage) +{ + // Check if the previous action succeeded. + if (*pResult) + { + // Check if the condition is true. + if (condition) + { + // Log the exception. + VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",\ + "videoEditJava_checkAndThrowIllegalArgumentException, %s", pMessage); + + // Reset the result flag. + (*pResult) = false; + + // Throw an exception. + jniThrowException(pEnv, "java/lang/IllegalArgumentException", pMessage); + } + } +} + +void +videoEditJava_checkAndThrowRuntimeException( + bool* pResult, + JNIEnv* pEnv, + bool condition, + M4OSA_ERR result) +{ + const char* pMessage = NULL; + + // Check if the previous action succeeded. + if (*pResult) + { + // Check if the condition is true. + if (condition) + { + // Get the error string. + pMessage = videoEditJava_getErrorName(result); + + // Log the exception. + VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA", + "videoEditJava_checkAndThrowRuntimeException, %s", pMessage); + + // Reset the result flag. + (*pResult) = false; + + // Throw an exception. + jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); + } + } +} + +void +videoEditJava_checkAndThrowIllegalStateException( + bool* pResult, + JNIEnv* pEnv, + bool condition, + const char* pMessage) +{ + // Check if the previous action succeeded. + if (*pResult) + { + // Check if the condition is true. + if (condition) + { + // Log the exception. + VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA", + "videoEditJava_checkAndThrowIllegalStateException, %s", pMessage); + + // Reset the result flag. + (*pResult) = false; + + // Throw an exception. + jniThrowException(pEnv, "java/lang/IllegalStateException", pMessage); + } + } +} + +void +videoEditJava_getClass( + bool* pResult, + JNIEnv* pEnv, + const char* pName, + jclass* pClazz) +{ + // Only look for the class if locating the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_getClass(%s)", pName); + + // Look up the class. + jclass clazz = pEnv->FindClass(pName); + + // Clear any resulting exceptions. + pEnv->ExceptionClear(); + + // Check if the class could be located. + if (NULL != clazz) + { + // Return the class. + (*pClazz) = clazz; + } + else + { + // Reset the result flag. + (*pResult) = false; + + // Log the error. + VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA", + "videoEditJava_getClass, error: unable to locate class %s", pName); + + // Throw an exception. + jniThrowException(pEnv, "java/lang/ClassNotFoundException", + "unable to locate class"); + } + } +} + +void +videoEditJava_getMethodId( + bool* pResult, + JNIEnv* pEnv, + jclass clazz, + const char* pName, + const char* pType, + jmethodID* pMethodId) +{ + // Only look for the class if locating the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_getMethodId(%s,%s)", pName, pType); + + // Look up the method id. + jmethodID methodId = pEnv->GetMethodID(clazz, pName, pType); + + // Clear any resulting exceptions. + pEnv->ExceptionClear(); + + // Check if the method could be located. + if (NULL != methodId) + { + // Return the method id. + (*pMethodId) = methodId; + } + else + { + // Reset the result flag. + (*pResult) = false; + + // Log the error. + VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA", + "videoEditJava_getMethodId, error: unable to locate method %s with type %s", + pName, pType); + + // Throw an exception. + jniThrowException(pEnv, "java/lang/NoSuchMethodException", "unable to locate method"); + } + } +} + +void +videoEditJava_getFieldId( + bool* pResult, + JNIEnv* pEnv, + jclass clazz, + const char* pName, + const char* pType, + jfieldID* pFieldId) +{ + // Only look for the class if locating the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_getFieldId(%s,%s)", pName, pType); + + // Look up the field id. + jfieldID fieldId = pEnv->GetFieldID(clazz, pName, pType); + + // Clear any resulting exceptions. + pEnv->ExceptionClear(); + + // Check if the field could be located. + if (NULL != fieldId) + { + // Return the field id. + (*pFieldId) = fieldId; + } + else + { + // Reset the result flag. + (*pResult) = false; + + // Log the error. + VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA", + "videoEditJava_getFieldId, error: unable to locate field %s with type %s", + pName, pType); + + // Throw an exception. + jniThrowException(pEnv, "java/lang/NoSuchFieldException", "unable to locate field"); + } + } +} + +void +videoEditJava_getObject( + bool* pResult, + JNIEnv* pEnv, + jobject object, + jfieldID objectFieldId, + jobject* pObject) +{ + // Only retrieve the array object and size if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_getObject()"); + + // Retrieve the object. + (*pObject) = pEnv->GetObjectField(object, objectFieldId); + + // Clear any resulting exceptions. + pEnv->ExceptionClear(); + } +} + +void +videoEditJava_getArray( + bool* pResult, + JNIEnv* pEnv, + jobject object, + jfieldID arrayFieldId, + jobjectArray* pArray, + jsize* pArraySize) +{ + // Only retrieve the array object and size if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", "videoEditJava_getArray()"); + + // Retrieve the array object. + jobjectArray array = (jobjectArray)pEnv->GetObjectField(object, arrayFieldId); + jsize arraySize = 0; + + // Clear any resulting exceptions. + pEnv->ExceptionClear(); + + // Check if the array could be retrieved. + if (NULL != array) + { + // Retrieve the array size. + arraySize = pEnv->GetArrayLength(array); + } + + // Return the array and its size. + (*pArray) = array; + (*pArraySize) = arraySize; + } +} + +void* +videoEditJava_getString( + bool* pResult, + JNIEnv* pEnv, + jobject object, + jfieldID stringFieldId, + M4OSA_UInt32* pLength) +{ + void* pString = M4OSA_NULL; + jstring string = NULL; + M4OSA_UInt32 length = 0; + M4OSA_Char* pLocal = M4OSA_NULL; + M4OSA_ERR result = M4NO_ERROR; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", "videoEditJava_getString()"); + + // Check if an object containing a string was specified. + if (NULL != stringFieldId) + { + // Retrieve the string object. + string = (jstring)pEnv->GetObjectField(object, stringFieldId); + + // Clear any resulting exceptions. + pEnv->ExceptionClear(); + } + else + { + // The string itself was specified. + string = (jstring)object; + } + + // Check if the string could be retrieved. + if (NULL != string) + { + // Get a local copy of the string. + pLocal = (M4OSA_Char*)pEnv->GetStringUTFChars(string, M4OSA_NULL); + if (M4OSA_NULL != pLocal) + { + // Determine the length of the path + // (add one extra character for the zero terminator). + length = M4OSA_chrLength(pLocal) + 1; + + // Allocate memory for the string. + pString = videoEditOsal_alloc(pResult, pEnv, length, "String"); + if (*pResult) + { + // Copy the string. + result = M4OSA_chrNCopy((M4OSA_Char*)pString, pLocal, length); + + // Check if the copy succeeded. + videoEditJava_checkAndThrowRuntimeException(pResult, pEnv, + (M4NO_ERROR != result), result); + + // Check if the string could not be copied. + if (!(*pResult)) + { + // Free the allocated memory. + videoEditOsal_free(pString); + pString = M4OSA_NULL; + } + } + + // Release the local copy of the string. + pEnv->ReleaseStringUTFChars(string, (const char *)pLocal); + } + } + + // Check if the string was empty or could be copied. + if (*pResult) + { + // Check if the length was requested. + if (M4OSA_NULL != pLength) + { + // Return the length. + (*pLength) = length; + } + } + } + + // Return the string. + return(pString); +} + +void +videoEditJava_getStaticIntField( + bool* pResult, + JNIEnv* pEnv, + jclass clazz, + const char* pName, + int* pValue) +{ + // Only look for the class if locating the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_getStaticIntField(%s)", pName); + + // Look up the field id. + jfieldID fieldId = pEnv->GetStaticFieldID(clazz, pName, "I"); + + // Clear any resulting exceptions. + pEnv->ExceptionClear(); + + // Check if the field could be located. + if (NULL != fieldId) + { + // Retrieve the field value. + (*pValue) = pEnv->GetStaticIntField(clazz, fieldId); + + // Log the value. + VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_getStaticIntField, %s = %d", pName, (*pValue)); + } + else + { + // Reset the result flag. + (*pResult) = false; + + // Log the error. + VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA", + "videoEditJava_getStaticIntField, error: unable to locate field %s", pName); + + // Throw an exception. + jniThrowException(pEnv, "java/lang/NoSuchFieldException", + "unable to locate static field"); + } + } +} + +void +videoEditJava_initConstantClass( + bool* pResult, + JNIEnv* pEnv, + VideoEditJava_ConstantsClass* pClass) +{ + bool gotten = true; + jclass clazz = NULL; + int index = 0; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_initConstantClass(%s)", pClass->pName); + + // Only initialize the class once. + if (!pClass->initialized) + { + // Look up the class. + videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz); + + // Loop over the constants. + for (index = 0; index < pClass->count; index++) + { + // Look up the constant. + videoEditJava_getStaticIntField(pResult, pEnv, clazz, + pClass->pConstants[index].pName, + &pClass->pConstants[index].java); + } + + // Check if all constants could be located. + if (*pResult) + { + // Set the initialized flag. + pClass->initialized = true; + } + } + } +} + +const char* +videoEditJava_getConstantClassName( + const VideoEditJava_ConstantsClass* pClass, + int value, + VideoEditJava_UnknownConstant unknown) +{ + const char* pName = M4OSA_NULL; + int index = 0; + + // Loop over the list with constants. + for (index = 0; + ((M4OSA_NULL == pName) && (index < pClass->count)); + index++) + { + // Check if the specified value matches the c value of the constant. + if (value == pClass->pConstants[index].c) + { + // Set the name. + pName = pClass->pConstants[index].pName; + } + } + + // Check if no constant was found. + if (M4OSA_NULL == pName) + { + // Check if a function was specified to handle this case. + if (M4OSA_NULL != unknown) + { + // Pass the constant to the specified unknown function. + pName = unknown(value); + } + else + { + // Set the description to a default value. + pName = "<unknown>"; + } + } + + // Return the result. + return(pName); +} + +const char* +videoEditJava_getConstantClassString( + const VideoEditJava_ConstantsClass* pClass, + int value, + VideoEditJava_UnknownConstant unknown) +{ + const char* pString = M4OSA_NULL; + int index = 0; + + // Loop over the list with constants. + for (index = 0; + ((M4OSA_NULL == pString) && (index < pClass->count)); + index++) + { + // Check if the specified value matches the c value of the constant. + if (value == pClass->pConstants[index].c) + { + // Set the description. + pString = pClass->pConstants[index].pDescription; + } + } + + // Check if no constant was found. + if (M4OSA_NULL == pString) + { + // Check if a function was specified to handle this case. + if (M4OSA_NULL != unknown) + { + // Pass the constant to the specified unknown function. + pString = unknown(value); + } + else + { + // Set the description to a default value. + pString = "<unknown>"; + } + } + + // Return the result. + return(pString); +} + +int +videoEditJava_getConstantClassJavaToC( + bool* pResult, + const VideoEditJava_ConstantsClass* pClass, + int value) +{ + bool gotten = false; + int index = 0; + + // Check if the previous action succeeded. + if (*pResult) + { + // Loop over the list with constants. + for (index = 0; ((!gotten) && (index < pClass->count)); index++) + { + // Check if the specified value matches the java value of the constant. + if (value == pClass->pConstants[index].java) + { + // Set the value to the c value. + value = pClass->pConstants[index].c; + + // Set the gotten flag. + gotten = true; + } + } + + // Check if the value was not found. + if (!gotten) + { + (*pResult) = false; + } + } + + // Return the translated value. + return(value); +} + +int +videoEditJava_getConstantClassJavaToC( + bool* pResult, + const VideoEditJava_ConstantsClass* pClass, + int value, + int unknown) +{ + bool gotten = false; + int index = 0; + + // Check if the previous action succeeded. + if (*pResult) + { + // Loop over the list with constants. + for (index = 0; ((!gotten) && (index < pClass->count)); index++) + { + // Check if the specified value matches the java value of the constant. + if (value == pClass->pConstants[index].java) + { + // Set the value to the c value. + value = pClass->pConstants[index].c; + + // Set the gotten flag. + gotten = true; + } + } + + // If the constant was not found, look for the specified unknown. + if (!gotten) + { + // Set the value to the c value. + value = unknown; + } + } + + // Return the translated value. + return(value); +} + +int +videoEditJava_getConstantClassCToJava( + const VideoEditJava_ConstantsClass* pClass, + int value) +{ + bool gotten = false; + int index = 0; + + // Loop over the list with constants. + for (index = 0; ((!gotten) && (index < pClass->count)); index++) + { + // Check if the specified value matches the c value of the constant. + if (value == pClass->pConstants[index].c) + { + // Set the value to the java value. + value = pClass->pConstants[index].java; + + // Set the gotten flag. + gotten = true; + } + } + + // Return the translated value. + return(value); +} + +int +videoEditJava_getConstantClassCToJava( + const VideoEditJava_ConstantsClass* pClass, + int value, + int unknown) +{ + bool gotten = false; + int index = 0; + + // Loop over the list with constants. + for (index = 0; ((!gotten) && (index < pClass->count)); index++) + { + // Check if the specified value matches the c value of the constant. + if (value == pClass->pConstants[index].c) + { + // Set the value to the java value. + value = pClass->pConstants[index].java; + + // Set the gotten flag. + gotten = true; + } + } + + // If the constant was not found, look for the specified unknown. + if (!gotten) + { + // Loop over the list with constants. + for (index = 0; ((!gotten) && (index < pClass->count)); index++) + { + // Check if the specified value matches the java value of the constant. + if (unknown == pClass->pConstants[index].c) + { + // Set the value to the c value. + value = pClass->pConstants[index].java; + + // Set the gotten flag. + gotten = true; + } + } + } + + // Return the translated value. + return(value); +} + +void +videoEditJava_initFieldClass( + bool* pResult, + JNIEnv* pEnv, + VideoEditJava_FieldsClass* pClass) +{ + bool gotten = true; + jclass clazz = NULL; + int index = 0; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_initFieldClass(%s)", pClass->pName); + + // Only initialize the class once. + if (!pClass->initialized) + { + // Look up the class. + videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz); + + // Loop over the fields. + for (index = 0; index < pClass->count; index++) + { + // Look up the field id. + videoEditJava_getFieldId( + pResult, + pEnv, + clazz, + pClass->pFields[index].pName, + pClass->pFields[index].pType, + &pClass->pFields[index].fieldId); + } + + // Check if all fields could be located. + if (*pResult) + { + // Set the initialized flag. + pClass->initialized = true; + } + } + } +} + +void +videoEditJava_fieldClassClass( + bool* pResult, + JNIEnv* pEnv, + const VideoEditJava_FieldsClass* pClass, + jclass* pClazz) +{ + // Check if the previous action succeeded. + if (*pResult) + { + // Check if the class is initialized. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized), + "field class not initialized"); + + // Get the class. + videoEditJava_getClass(pResult, pEnv, pClass->pName, pClazz); + } +} + +void +videoEditJava_fieldClassFieldIds( + bool* pResult, + JNIEnv* pEnv, + const VideoEditJava_FieldsClass* pClass, + int count, + VideoEditJava_FieldIds* pIds) +{ + int index = 0; + + // Check if the previous action succeeded. + if (*pResult) + { + // Check if the class is initialized. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized), + "field class not initialized"); + + // Check if the number of fields matches. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, + (pClass->count != count), + "field class type mismatch"); + + // Check if the class and object are valid. + if (*pResult) + { + // Loop over the class fields. + for (index = 0; index < count; index++) + { + // Copy the field ids. + pIds->fieldIds[index] = pClass->pFields[index].fieldId; + } + } + } +} + +void +videoEditJava_initMethodClass( + bool* pResult, + JNIEnv* pEnv, + VideoEditJava_MethodsClass* pClass) +{ + bool gotten = true; + jclass clazz = NULL; + int index = 0; + + // Check if the previous action succeeded. + if (*pResult) + { + // Log the function call. + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", + "videoEditJava_initMethodClass(%s)", pClass->pName); + + // Only initialize the class once. + if (!pClass->initialized) + { + // Look up the class. + videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz); + + // Loop over the methods. + for (index = 0; index < pClass->count; index++) + { + // Look up the method id. + videoEditJava_getMethodId( + pResult, + pEnv, + clazz, + pClass->pMethods[index].pName, + pClass->pMethods[index].pType, + &pClass->pMethods[index].methodId); + } + + // Check if all methods could be located. + if (*pResult) + { + // Set the initialized flag. + pClass->initialized = true; + } + } + } +} + +void +videoEditJava_methodClassMethodIds( + bool* pResult, + JNIEnv* pEnv, + const VideoEditJava_MethodsClass* pClass, + int count, + VideoEditJava_MethodIds* pIds) +{ + int index = 0; + + // Check if the previous action succeeded. + if (*pResult) + { + // Check if the class is initialized. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized), + "method class not initialized"); + + // Check if the number of methods matches. + videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,\ + (pClass->count != count), + "method class type mismatch"); + + // Check if the class and object are valid. + if (*pResult) + { + // Loop over the class methods. + for (index = 0; index < count; index++) + { + // Copy the method ids. + pIds->methodIds[index] = pClass->pMethods[index].methodId; + } + } + } +} + diff --git a/media/jni/mediaeditor/VideoEditorJava.h b/media/jni/mediaeditor/VideoEditorJava.h new file mode 100755 index 000000000000..9d7f096bae77 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorJava.h @@ -0,0 +1,506 @@ +/* + * 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. + */ + +#ifndef VIDEO_EDiTOR_JAVA_H +#define VIDEO_EDiTOR_JAVA_H + +#include <jni.h> +#include <JNIHelp.h> + +/** + ************************************************************************ + * @file VideoEditorJava.h + * @brief Interface for JNI methods that have specific access to + * class, objects and method Ids defined in Java layer + ************************************************************************ +*/ + +extern "C" { +#include <M4OSA_Types.h> +#include <M4OSA_Error.h> +} + +#define VIDEOEDIT_JAVA_CONSTANT_INIT(m_name, m_c) \ + { m_name, \ + 0, \ + m_c, \ + #m_c } + +#define VIDEOEDIT_JAVA_DEFINE_CONSTANTS(m_class) \ +static \ +VideoEditJava_Constant g##m_class##Constants [] = + +#define VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS( \ + m_class, \ + m_name, \ + m_unknownName, \ + m_unknownString) \ + \ +static VideoEditJava_ConstantsClass g##m_class##ConstantsClass = \ +{ m_name, \ + &g##m_class##Constants[0], \ + (sizeof(g##m_class##Constants) / sizeof(VideoEditJava_Constant)), \ + false \ +}; \ + \ + \ +void videoEditJava_init##m_class##Constants( \ + bool* pResult, \ + JNIEnv* pEnv) \ +{ \ + videoEditJava_initConstantClass( \ + pResult, \ + pEnv, \ + &g##m_class##ConstantsClass); \ +} \ + \ +const char* videoEditJava_get##m_class##Name( \ + int value) \ +{ \ + return(videoEditJava_getConstantClassName( \ + &g##m_class##ConstantsClass, \ + value, \ + m_unknownName)); \ +} \ + \ +const char* videoEditJava_get##m_class##String( \ + int value) \ +{ \ + return(videoEditJava_getConstantClassString( \ + &g##m_class##ConstantsClass, \ + value, \ + m_unknownString)); \ +} \ + \ +int \ +videoEditJava_get##m_class##JavaToC( \ + bool* pResult, \ + int value) \ +{ \ + return(videoEditJava_getConstantClassJavaToC( \ + pResult, \ + &g##m_class##ConstantsClass, \ + value)); \ +} \ + \ +int \ +videoEditJava_get##m_class##JavaToC( \ + bool* pResult, \ + int value, \ + int unknown) \ +{ \ + return(videoEditJava_getConstantClassJavaToC( \ + pResult, \ + &g##m_class##ConstantsClass, \ + value, \ + unknown)); \ +} \ + \ +int \ +videoEditJava_get##m_class##CToJava( \ + int value) \ +{ \ + return(videoEditJava_getConstantClassCToJava( \ + &g##m_class##ConstantsClass, \ + value)); \ +} \ + \ +int \ +videoEditJava_get##m_class##CToJava( \ + int value, \ + int unknown) \ +{ \ + return(videoEditJava_getConstantClassCToJava( \ + &g##m_class##ConstantsClass, \ + value, \ + unknown)); \ +} + + +#define VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(m_class) \ +void \ +videoEditJava_init##m_class##Constants( \ + bool* pResult, \ + JNIEnv* pEnv); \ + \ +const char* \ +videoEditJava_get##m_class##Name( \ + int value); \ + \ +const char* \ +videoEditJava_get##m_class##String( \ + int value); \ + \ +int \ +videoEditJava_get##m_class##JavaToC( \ + bool* pResult, \ + int value, \ + int unknown); \ + \ +int \ +videoEditJava_get##m_class##JavaToC( \ + bool* pResult, \ + int value); \ + \ +int \ +videoEditJava_get##m_class##CToJava( \ + int value); \ + \ +int \ +videoEditJava_get##m_class##CToJava( \ + int value, \ + int unknown); + +#define VIDEOEDIT_JAVA_FIELD_INIT(m_name, m_type) \ + { m_name, \ + m_type, \ + NULL } + +#define VIDEOEDIT_JAVA_DEFINE_FIELDS(m_class) \ +static \ +VideoEditJava_Field g##m_class##Fields [] = + +#define VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(m_class, m_name) \ +static VideoEditJava_FieldsClass g##m_class##FieldsClass = \ + { m_name, \ + &g##m_class##Fields[0], \ + (sizeof(g##m_class##Fields) / sizeof(VideoEditJava_Field)), \ + false }; \ + \ +void \ +videoEditJava_init##m_class##Fields( \ + bool* pResult, \ + JNIEnv* pEnv) \ +{ \ + videoEditJava_initFieldClass( \ + pResult, \ + pEnv, \ + &g##m_class##FieldsClass); \ +} \ + \ +void \ +videoEditJava_get##m_class##Class( \ + bool* pResult, \ + JNIEnv* pEnv, \ + jclass* pClazz) \ +{ \ + videoEditJava_fieldClassClass( \ + pResult, \ + pEnv, \ + &g##m_class##FieldsClass, \ + pClazz); \ +} \ + \ +void \ +videoEditJava_get##m_class##FieldIds( \ + bool* pResult, \ + JNIEnv* pEnv, \ + VideoEditJava_##m_class##FieldIds* pIds) \ +{ \ + videoEditJava_fieldClassFieldIds( \ + pResult, \ + pEnv, \ + &g##m_class##FieldsClass, \ + (sizeof(VideoEditJava_##m_class##FieldIds) / \ + sizeof(jfieldID)), \ + (VideoEditJava_FieldIds*)pIds); \ +} + +#define VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(m_class) \ +void \ +videoEditJava_init##m_class##Fields( \ + bool* pResult, \ + JNIEnv* pEnv); \ + \ +void \ +videoEditJava_get##m_class##Class( \ + bool* pResult, \ + JNIEnv* pEnv, \ + jclass* pClazz); \ + \ +void \ +videoEditJava_get##m_class##FieldIds( \ + bool* pResult, \ + JNIEnv* pEnv, \ + VideoEditJava_##m_class##FieldIds* pIds); + + +#define VIDEOEDIT_JAVA_METHOD_INIT(m_name, m_type) \ + { m_name, \ + m_type, \ + NULL } + +#define VIDEOEDIT_JAVA_DEFINE_METHODS(m_class) \ +static \ +VideoEditJava_Method g##m_class##Methods [] = + +#define VIDEOEDIT_JAVA_DEFINE_METHOD_CLASS(m_class, m_name) \ +static VideoEditJava_MethodsClass g##m_class##MethodsClass = \ + { m_name, \ + &g##m_class##Methods[0], \ + (sizeof(g##m_class##Methods) / sizeof(VideoEditJava_Method)), \ + false }; \ + \ +void \ +videoEditJava_init##m_class##Methods( \ + bool* pResult, \ + JNIEnv* pEnv) \ +{ \ + videoEditJava_initMethodClass( \ + pResult, \ + pEnv, \ + &g##m_class##MethodsClass); \ +} \ + \ +void \ +videoEditJava_get##m_class##MethodIds( \ + bool* pResult, \ + JNIEnv* pEnv, \ + VideoEditJava_##m_class##MethodIds* pIds) \ +{ \ + videoEditJava_methodClassMethodIds( \ + pResult, \ + pEnv, \ + &g##m_class##MethodsClass, \ + (sizeof(VideoEditJava_##m_class##MethodIds) / \ + sizeof(jmethodID)), \ + (VideoEditJava_MethodIds*)pIds); \ +} + +#define VIDEOEDIT_JAVA_DECLARE_METHOD_CLASS(m_class) \ +void \ +videoEditJava_init##m_class##Methods( \ + bool* pResult, \ + JNIEnv* pEnv); \ + \ +void \ +videoEditJava_get##m_class##MethodIds( \ + bool* pResult, \ + JNIEnv* pEnv, \ + VideoEditJava_##m_class##MethodIds* pIds); + + +typedef struct +{ + const char* pName; + int java; + int c; + const char* pDescription; +} VideoEditJava_Constant; + +typedef struct +{ + const char* pName; + VideoEditJava_Constant* pConstants; + int count; + bool initialized; +} VideoEditJava_ConstantsClass; + +typedef const char* (*VideoEditJava_UnknownConstant)(int constant); + +typedef struct +{ + const char* pName; + const char* pType; + jfieldID fieldId; +} VideoEditJava_Field; + +typedef struct +{ + const char* pName; + VideoEditJava_Field* pFields; + int count; + bool initialized; +} VideoEditJava_FieldsClass; + +typedef struct +{ + jfieldID fieldIds[]; +} VideoEditJava_FieldIds; + +typedef struct +{ + const char* pName; + const char* pType; + jmethodID methodId; +} VideoEditJava_Method; + +typedef struct +{ + const char* pName; + VideoEditJava_Method* pMethods; + int count; + bool initialized; +} VideoEditJava_MethodsClass; + +typedef struct +{ + jmethodID methodIds[]; +} VideoEditJava_MethodIds; + +void +videoEditJava_checkAndThrowIllegalArgumentException( + bool* pResult, + JNIEnv* pEnv, + bool condition, + const char* pMessage); + +void +videoEditJava_checkAndThrowRuntimeException( + bool* pResult, + JNIEnv* pEnv, + bool condition, + M4OSA_ERR result); + +void +videoEditJava_checkAndThrowIllegalStateException( + bool* pResult, + JNIEnv* pEnv, + bool condition, + const char* pMessage); + +void +videoEditJava_getClass( + bool* pResult, + JNIEnv* pEnv, + const char* pName, + jclass* pClazz); + +void +videoEditJava_getMethodId( + bool* pResult, + JNIEnv* pEnv, + jclass clazz, + const char* pName, + const char* pType, + jmethodID* pMethodId); + +void videoEditJava_getFieldId( + bool* pResult, + JNIEnv* pEnv, + jclass clazz, + const char* pName, + const char* pType, + jfieldID* pFieldId); + +void videoEditJava_getObject( + bool* pResult, + JNIEnv* pEnv, + jobject object, + jfieldID objectFieldId, + jobject* pObject); + +void videoEditJava_getArray( + bool* pResult, + JNIEnv* pEnv, + jobject object, + jfieldID arrayFieldId, + jobjectArray* pArray, + jsize* pArraySize); + +void* videoEditJava_getString( + bool* pResult, + JNIEnv* pEnv, + jobject object, + jfieldID stringFieldId, + M4OSA_UInt32* pLength); + +void videoEditJava_getStaticIntField( + bool* pResult, + JNIEnv* env, + jclass clazz, + const char* pName, + int* pValue); + +void +videoEditJava_initConstantClass( + bool* pResult, + JNIEnv* pEnv, + VideoEditJava_ConstantsClass* pClass); + +const char* +videoEditJava_getConstantClassName( + const VideoEditJava_ConstantsClass* pClass, + int value, + VideoEditJava_UnknownConstant unknown); + +const char* +videoEditJava_getConstantClassString( + const VideoEditJava_ConstantsClass* pClass, + int value, + VideoEditJava_UnknownConstant unknown); + +int +videoEditJava_getConstantClassJavaToC( + bool* pResult, + const VideoEditJava_ConstantsClass* pClass, + int value); + +int +videoEditJava_getConstantClassJavaToC( + bool* pResult, + const VideoEditJava_ConstantsClass* pClass, + int value, + int unknown); + +int +videoEditJava_getConstantClassCToJava( + const VideoEditJava_ConstantsClass* pClass, + int value); + +int +videoEditJava_getConstantClassCToJava( + const VideoEditJava_ConstantsClass* pClass, + int value, + int unknown); + +void +videoEditJava_initFieldClass( + bool* pResult, + JNIEnv* pEnv, + VideoEditJava_FieldsClass* pClass); + +void +videoEditJava_fieldClassClass( + bool* pResult, + JNIEnv* pEnv, + const VideoEditJava_FieldsClass* pClass, + jclass* pClazz); + +void +videoEditJava_fieldClassFieldIds( + bool* pResult, + JNIEnv* pEnv, + const VideoEditJava_FieldsClass* pClass, + int count, + VideoEditJava_FieldIds* pIds); + +void +videoEditJava_initMethodClass( + bool* pResult, + JNIEnv* pEnv, + VideoEditJava_MethodsClass* pClass); + +void +videoEditJava_methodClassMethodIds( + bool* pResult, + JNIEnv* pEnv, + const VideoEditJava_MethodsClass* pClass, + int count, + VideoEditJava_MethodIds* pIds); + +#endif // VIDEO_EDiTOR_JAVA_H + diff --git a/media/jni/mediaeditor/VideoEditorLogging.h b/media/jni/mediaeditor/VideoEditorLogging.h new file mode 100755 index 000000000000..ca8c0474d9da --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorLogging.h @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#ifndef VIDEO_EDITOR_LOGGING_H +#define VIDEO_EDITOR_LOGGING_H + +//#define VIDEOEDIT_LOGGING_ENABLED + +#define VIDEOEDIT_LOG_INDENTATION (3) + +#ifdef VIDEOEDIT_LOGGING_ENABLED + +#define VIDEOEDIT_LOG_ALLOCATION __android_log_print +#define VIDEOEDIT_LOG_API __android_log_print +#define VIDEOEDIT_LOG_ERROR __android_log_print +#define VIDEOEDIT_LOG_EXCEPTION __android_log_print +#define VIDEOEDIT_LOG_FUNCTION __android_log_print +#define VIDEOEDIT_LOG_RESULT(x,y, ...) LOGI(y, __VA_ARGS__ ) +#define VIDEOEDIT_LOG_SETTING __android_log_print +#define VIDEOEDIT_LOG_EDIT_SETTINGS(m_settings) videoEditClasses_logEditSettings\ + (m_settings, VIDEOEDIT_LOG_INDENTATION) +#define VIDEOEDIT_PROP_LOG_PROPERTIES(m_properties) videoEditPropClass_logProperties\ + (m_properties, VIDEOEDIT_LOG_INDENTATION) +#define VIDEOEDIT_PROP_LOG_RESULT __android_log_print + +#else + +#define VIDEOEDIT_LOG_ALLOCATION (void) +#define VIDEOEDIT_LOG_API (void) +#define VIDEOEDIT_LOG_ERROR (void) +#define VIDEOEDIT_LOG_EXCEPTION (void) +#define VIDEOEDIT_LOG_FUNCTION (void) +#define VIDEOEDIT_LOG_RESULT (void) +#define VIDEOEDIT_LOG_SETTING (void) +#define VIDEOEDIT_LOG_EDIT_SETTINGS(m_settings) (void)m_settings +#define VIDEOEDIT_PROP_LOG_PROPERTIES(m_properties) (void)m_properties +#define VIDEOEDIT_PROP_LOG_RESULT (void) + +#endif + +#endif // VIDEO_EDITOR_LOGGING_H + diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp new file mode 100755 index 000000000000..e66e4b90fbc3 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorMain.cpp @@ -0,0 +1,3056 @@ +/* + * 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 <dlfcn.h> +#include <stdio.h> +#include <unistd.h> +#include <utils/Log.h> +#include <utils/threads.h> +#include <VideoEditorClasses.h> +#include <VideoEditorJava.h> +#include <VideoEditorOsal.h> +#include <VideoEditorLogging.h> +#include <marker.h> +#include <VideoEditorClasses.h> +#include <VideoEditorThumbnailMain.h> +#include <M4OSA_Debug.h> +#include <M4xVSS_Internal.h> +#include <surfaceflinger/Surface.h> +#include <surfaceflinger/ISurface.h> +#include "VideoEditorPreviewController.h" + +#include "VideoEditorMain.h" + +extern "C" { +#include <M4OSA_Clock.h> +#include <M4OSA_CharStar.h> +#include <M4OSA_Error.h> +#include <M4OSA_FileCommon.h> +#include <M4OSA_FileReader.h> +#include <M4OSA_FileWriter.h> +#include <M4OSA_FileExtra.h> +#include <M4OSA_Memory.h> +#include <M4OSA_String.h> +#include <M4OSA_Thread.h> +#include <M4xVSS_API.h> +#include <M4VSS3GPP_ErrorCodes.h> +#include <M4MCS_API.h> +#include <M4MCS_ErrorCodes.h> +#include <M4MDP_API.h> +#include <M4READER_Common.h> +#include <M4WRITER_common.h> +}; + + +using namespace android; + +#define THREAD_STACK_SIZE (65536) + +#define VIDEOEDITOR_VERSION_MAJOR 0 +#define VIDEOEDITOR_VERSION_MINOR 0 +#define VIDEOEDITOR_VERSION_REVISION 1 + + +typedef enum +{ + ManualEditState_NOT_INITIALIZED, + ManualEditState_INITIALIZED, + ManualEditState_ANALYZING, + ManualEditState_ANALYZING_ERROR, + ManualEditState_OPENED, + ManualEditState_SAVING, + ManualEditState_SAVING_ERROR, + ManualEditState_SAVED, + ManualEditState_STOPPING +} ManualEditState; + +typedef struct +{ + JavaVM* pVM; + jobject engine; + jmethodID onCompletionMethodId; + jmethodID onErrorMethodId; + jmethodID onWarningMethodId; + jmethodID onProgressUpdateMethodId; + jmethodID onPreviewProgressUpdateMethodId; + M4xVSS_InitParams initParams; + void* pTextRendererHandle; + M4xVSS_getTextRgbBufferFct pTextRendererFunction; + M4OSA_Context engineContext; + ManualEditState state; + M4VSS3GPP_EditSettings* pEditSettings; + M4OSA_Context threadContext; + M4OSA_ERR threadResult; + M4OSA_UInt8 threadProgress; + VideoEditorPreviewController *mPreviewController; + M4xVSS_AudioMixingSettings *mAudioSettings; + /* Audio Graph changes */ + M4OSA_Context pAudioGraphMCSCtx; + M4OSA_Bool bSkipState; + jmethodID onAudioGraphProgressUpdateMethodId; + Mutex mLock; +} ManualEditContext; + +extern "C" M4OSA_ERR M4MCS_open_normalMode( + M4MCS_Context pContext, + M4OSA_Void* pFileIn, + M4VIDEOEDITING_FileType InputFileType, + M4OSA_Void* pFileOut, + M4OSA_Void* pTempFile); + +static M4OSA_ERR videoEditor_toUTF8Fct( + M4OSA_Void* pBufferIn, + M4OSA_UInt8* pBufferOut, + M4OSA_UInt32* bufferOutSize); + +static M4OSA_ERR videoEditor_fromUTF8Fct( + M4OSA_UInt8* pBufferIn, + M4OSA_Void* pBufferOut, + M4OSA_UInt32* bufferOutSize); + +static M4OSA_ERR videoEditor_getTextRgbBufferFct( + M4OSA_Void* pRenderingData, + M4OSA_Void* pTextBuffer, + M4OSA_UInt32 textBufferSize, + M4VIFI_ImagePlane** pOutputPlane); + +static void videoEditor_callOnProgressUpdate( + ManualEditContext* pContext, + int task, + int progress); + +static void videoEditor_freeContext( + JNIEnv* pEnv, + ManualEditContext** ppContext); + +static M4OSA_ERR videoEditor_threadProc( + M4OSA_Void* param); + +static jobject videoEditor_getVersion( + JNIEnv* pEnv, + jobject thiz); + +static void videoEditor_init( + JNIEnv* pEnv, + jobject thiz, + jstring tempPath, + jstring textRendererPath); + +static void videoEditor_loadSettings( + JNIEnv* pEnv, + jobject thiz, + jobject settings); + +static void videoEditor_unloadSettings( + JNIEnv* pEnv, + jobject thiz); + + +static void videoEditor_stopEncoding( + JNIEnv* pEnv, + jobject thiz); + +static void videoEditor_release( + JNIEnv* pEnv, + jobject thiz); +static int videoEditor_getPixels( + JNIEnv* env, + jobject thiz, + jstring path, + jintArray pixelArray, + M4OSA_UInt32 width, + M4OSA_UInt32 height, + M4OSA_UInt32 timeMS); +static int videoEditor_getPixelsList( + JNIEnv* env, + jobject thiz, + jstring path, + jintArray pixelArray, + M4OSA_UInt32 width, + M4OSA_UInt32 height, + M4OSA_UInt32 deltatimeMS, + M4OSA_UInt32 noOfThumbnails, + M4OSA_UInt32 startTime, + M4OSA_UInt32 endTime); + +static void +videoEditor_startPreview( + JNIEnv* pEnv, + jobject thiz, + jobject mSurface, + jlong fromMs, + jlong toMs, + jint callbackInterval, + jboolean loop); + +static void +videoEditor_populateSettings( + JNIEnv* pEnv, + jobject thiz, + jobject settings, + jobject object, + jobject audioSettingObject); + +static void videoEditor_stopPreview(JNIEnv* pEnv, + jobject thiz); + +static jobject +videoEditor_getProperties( + JNIEnv* pEnv, + jobject thiz, + jstring file); + +static int videoEditor_renderPreviewFrame(JNIEnv* pEnv, + jobject thiz, + jobject mSurface, + jlong fromMs, + jint surfaceWidth, + jint surfaceHeight); + +static int videoEditor_registerManualEditMethods( + JNIEnv* pEnv); + +static void jniPreviewProgressCallback(void* cookie, M4OSA_UInt32 msgType, + M4OSA_UInt32 argc); + +static int videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv, + jobject thiz, + jobject mSurface, + jstring filePath, + jint frameWidth, + jint frameHeight, + jint surfaceWidth, + jint surfaceHeight, + jlong fromMs); + +static int videoEditor_generateAudioWaveFormSync ( JNIEnv* pEnv, + jobject thiz, + jstring pcmfilePath, + jstring outGraphfilePath, + jint frameDuration, + jint channels, + jint samplesCount); + +static int videoEditor_generateAudioRawFile(JNIEnv* pEnv, + jobject thiz, + jstring infilePath, + jstring pcmfilePath ); + +M4OSA_ERR videoEditor_generateAudio(JNIEnv* pEnv,ManualEditContext* pContext, + M4OSA_Char* infilePath, + M4OSA_Char* pcmfilePath ); + +static int +videoEditor_generateClip( + JNIEnv* pEnv, + jobject thiz, + jobject settings); + + +static JNINativeMethod gManualEditMethods[] = { + {"getVersion", "()L"VERSION_CLASS_NAME";", + (void *)videoEditor_getVersion }, + {"_init", "(Ljava/lang/String;Ljava/lang/String;)V", + (void *)videoEditor_init }, + {"nativeStartPreview", "(Landroid/view/Surface;JJIZ)V", + (void *)videoEditor_startPreview }, + {"nativePopulateSettings", + "(L"EDIT_SETTINGS_CLASS_NAME";L"PREVIEW_PROPERTIES_CLASS_NAME";L" + AUDIO_SETTINGS_CLASS_NAME";)V", + (void *)videoEditor_populateSettings }, + {"nativeRenderPreviewFrame", "(Landroid/view/Surface;JII)I", + (int *)videoEditor_renderPreviewFrame }, + {"nativeRenderMediaItemPreviewFrame", + "(Landroid/view/Surface;Ljava/lang/String;IIIIJ)I", + (int *)videoEditor_renderMediaItemPreviewFrame }, + {"nativeStopPreview", "()V", + (void *)videoEditor_stopPreview }, + {"stopEncoding", "()V", + (void *)videoEditor_stopEncoding }, + {"release", "()V", + (void *)videoEditor_release }, + {"nativeGetPixels", "(Ljava/lang/String;[IIIJ)I", + (void*)videoEditor_getPixels }, + {"nativeGetPixelsList", "(Ljava/lang/String;[IIIIIJJ)I", + (void*)videoEditor_getPixelsList }, + {"getMediaProperties", + "(Ljava/lang/String;)Landroid/media/videoeditor/MediaArtistNativeHelper$Properties;", + (void *)videoEditor_getProperties }, + {"nativeGenerateAudioGraph","(Ljava/lang/String;Ljava/lang/String;III)I", + (int *)videoEditor_generateAudioWaveFormSync }, + {"nativeGenerateRawAudio", "(Ljava/lang/String;Ljava/lang/String;)I", + (int *)videoEditor_generateAudioRawFile }, + {"nativeGenerateClip", "(L"EDIT_SETTINGS_CLASS_NAME";)I", + (void *)videoEditor_generateClip }, +}; + +// temp file name of VSS out file +#define TEMP_MCS_OUT_FILE_PATH "/tmpOut.3gp" + +void +getClipSetting( + JNIEnv* pEnv, + jobject object, + M4VSS3GPP_ClipSettings* pSettings) +{ + + jfieldID fid; + int field = 0; + bool needToBeLoaded = true; + jclass clazz = pEnv->FindClass(PROPERTIES_CLASS_NAME); + + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == clazz), + "not initialized"); + + fid = pEnv->GetFieldID(clazz,"duration","I"); + pSettings->ClipProperties.uiClipDuration = pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("duration = %d",pSettings->ClipProperties.uiClipDuration); + + fid = pEnv->GetFieldID(clazz,"videoFormat","I"); + pSettings->ClipProperties.VideoStreamType = + (M4VIDEOEDITING_VideoFormat)pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("videoFormat = %d",pSettings->ClipProperties.VideoStreamType); + + fid = pEnv->GetFieldID(clazz,"videoDuration","I"); + pSettings->ClipProperties.uiClipVideoDuration = pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("videoDuration = %d", + pSettings->ClipProperties.uiClipVideoDuration); + + fid = pEnv->GetFieldID(clazz,"width","I"); + pSettings->ClipProperties.uiVideoWidth = pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("width = %d",pSettings->ClipProperties.uiVideoWidth); + + fid = pEnv->GetFieldID(clazz,"height","I"); + pSettings->ClipProperties.uiVideoHeight = pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("height = %d",pSettings->ClipProperties.uiVideoHeight); + + fid = pEnv->GetFieldID(clazz,"audioFormat","I"); + pSettings->ClipProperties.AudioStreamType = + (M4VIDEOEDITING_AudioFormat)pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("audioFormat = %d",pSettings->ClipProperties.AudioStreamType); + + fid = pEnv->GetFieldID(clazz,"audioDuration","I"); + pSettings->ClipProperties.uiClipAudioDuration = pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("audioDuration = %d", + pSettings->ClipProperties.uiClipAudioDuration); + + fid = pEnv->GetFieldID(clazz,"audioBitrate","I"); + pSettings->ClipProperties.uiAudioBitrate = pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("audioBitrate = %d",pSettings->ClipProperties.uiAudioBitrate); + + fid = pEnv->GetFieldID(clazz,"audioChannels","I"); + pSettings->ClipProperties.uiNbChannels = pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("audioChannels = %d",pSettings->ClipProperties.uiNbChannels); + + fid = pEnv->GetFieldID(clazz,"audioSamplingFrequency","I"); + pSettings->ClipProperties.uiSamplingFrequency = pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("audioSamplingFrequency = %d", + pSettings->ClipProperties.uiSamplingFrequency); + + fid = pEnv->GetFieldID(clazz,"audioVolumeValue","I"); + pSettings->ClipProperties.uiClipAudioVolumePercentage = + pEnv->GetIntField(object,fid); + M4OSA_TRACE1_1("audioVolumeValue = %d", + pSettings->ClipProperties.uiClipAudioVolumePercentage); +} + +static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType, + M4OSA_UInt32 argc) +{ + ManualEditContext *pContext = (ManualEditContext *)cookie; + JNIEnv* pEnv = NULL; + bool isFinished = false; + int currentMs = 0; + int error = M4NO_ERROR; + + // Attach the current thread. + pContext->pVM->AttachCurrentThread(&pEnv, NULL); + switch(msgType) + { + case MSG_TYPE_PROGRESS_INDICATION: + currentMs = argc; + break; + case MSG_TYPE_PLAYER_ERROR: + currentMs = -1; + error = argc; + break; + case MSG_TYPE_PREVIEW_END: + isFinished = true; + break; + default: + break; + } + + pEnv->CallVoidMethod(pContext->engine, + pContext->onPreviewProgressUpdateMethodId, + currentMs,isFinished); + + // Detach the current thread. + pContext->pVM->DetachCurrentThread(); + +} +static void videoEditor_stopPreview(JNIEnv* pEnv, + jobject thiz) +{ + ManualEditContext* pContext = M4OSA_NULL; + bool needToBeLoaded = true; + // Get the context. + pContext = + (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + pContext->mPreviewController->stopPreview(); +} + +static int videoEditor_renderPreviewFrame(JNIEnv* pEnv, + jobject thiz, + jobject mSurface, + jlong fromMs, + jint surfaceWidth, + jint surfaceHeight ) +{ + bool needToBeLoaded = true; + M4OSA_ERR result = M4NO_ERROR; + M4OSA_UInt32 timeMs = (M4OSA_UInt32)fromMs; + M4OSA_UInt32 i=0,tnTimeMs = 0, framesizeYuv =0; + M4VIFI_UInt8 *pixelArray = M4OSA_NULL; + M4OSA_UInt32 iCurrentClipIndex = 0, uiNumberOfClipsInStoryBoard =0, + uiClipDuration = 0, uiTotalClipDuration = 0, + iIncrementedDuration = 0; + VideoEditor_renderPreviewFrameStr frameStr; + M4OSA_Context tnContext = M4OSA_NULL; + const char* pMessage = NULL; + M4VIFI_ImagePlane *yuvPlane; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, + "VIDEO_EDITOR", "surfaceWidth = %d",surfaceWidth); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, + "VIDEO_EDITOR", "surfaceHeight = %d",surfaceHeight); + ManualEditContext* pContext = M4OSA_NULL; + // Get the context. + pContext = + (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, + "VIDEO_EDITOR","pContext = 0x%x",pContext); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext->mPreviewController), + "not initialized"); + + // Validate the mSurface parameter. + videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, + (NULL == mSurface), + "mSurface is null"); + jclass surfaceClass = pEnv->FindClass("android/view/Surface"); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == surfaceClass), + "not initialized"); + + jfieldID surface_native = + pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == surface_native), + "not initialized"); + + Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); + sp<Surface> previewSurface = sp<Surface>(p); + + /* Determine the total number of clips, total duration*/ + uiNumberOfClipsInStoryBoard = pContext->pEditSettings->uiClipNumber; + + for (i = 0; i < uiNumberOfClipsInStoryBoard; i++) { + uiClipDuration = pContext->pEditSettings->pClipList[i]->uiEndCutTime - + pContext->pEditSettings->pClipList[i]->uiBeginCutTime; + uiTotalClipDuration += uiClipDuration; + } + + /* determine the clip whose thumbnail needs to be rendered*/ + if (timeMs == 0) { + iCurrentClipIndex = 0; + i=0; + } else { + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_renderPreviewFrame() timeMs=%d", timeMs); + + if (timeMs > uiTotalClipDuration) { + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_renderPreviewFrame() timeMs > uiTotalClipDuration"); + pMessage = videoEditJava_getErrorName(M4ERR_PARAMETER); + jniThrowException(pEnv, "java/lang/IllegalArgumentException", pMessage); + return -1; + } + + for (i = 0; i < uiNumberOfClipsInStoryBoard; i++) { + if (timeMs < (iIncrementedDuration + + (pContext->pEditSettings->pClipList[i]->uiEndCutTime - + pContext->pEditSettings->pClipList[i]->uiBeginCutTime))) + { + iCurrentClipIndex = i; + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_renderPreviewFrame() iCurrentClipIndex=%d for timeMs=%d", + iCurrentClipIndex, timeMs); + break; + } + else { + iIncrementedDuration = iIncrementedDuration + + (pContext->pEditSettings->pClipList[i]->uiEndCutTime - + pContext->pEditSettings->pClipList[i]->uiBeginCutTime); + } + } + } + /* If timestamp is beyond story board duration, return*/ + if (i >= uiNumberOfClipsInStoryBoard) { + if (timeMs == iIncrementedDuration) { + iCurrentClipIndex = i-1; + } else { + return -1; + } + } + + /*+ Handle the image files here */ + if (pContext->pEditSettings->pClipList[iCurrentClipIndex]->FileType == + /*M4VIDEOEDITING_kFileType_JPG*/ M4VIDEOEDITING_kFileType_ARGB8888 ) { + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", " iCurrentClipIndex %d ", iCurrentClipIndex); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + " Height = %d", + pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoHeight); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + " Width = %d", + pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoWidth); + + LvGetImageThumbNail((const char *)pContext->pEditSettings->\ + pClipList[iCurrentClipIndex]->pFile, + pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoHeight, + pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoWidth, + (M4OSA_Void **)&frameStr.pBuffer); + } else { + /* Handle 3gp/mp4 Clips here */ + /* get thumbnail*/ + result = ThumbnailOpen(&tnContext, + (const M4OSA_Char*)pContext->pEditSettings->\ + pClipList[iCurrentClipIndex]->pFile, M4OSA_TRUE); + if (result != M4NO_ERROR || tnContext == M4OSA_NULL) { + return -1; + } + + /* timeMs is relative to storyboard; in this api it shud be relative to this clip */ + if ((i >= uiNumberOfClipsInStoryBoard) && + (timeMs == iIncrementedDuration)) { + tnTimeMs = pContext->pEditSettings->\ + pClipList[iCurrentClipIndex]->uiEndCutTime; + } else { + tnTimeMs = pContext->pEditSettings->\ + pClipList[iCurrentClipIndex]->uiBeginCutTime + + (timeMs - iIncrementedDuration); + } + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "video width = %d",pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoWidth); + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "video height = %d",pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoHeight); + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "current clip index = %d",iCurrentClipIndex); + + M4OSA_UInt32 width = pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoWidth; + M4OSA_UInt32 height = pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoHeight; + + framesizeYuv = width * height * 1.5; + + pixelArray = (M4VIFI_UInt8 *)M4OSA_malloc(framesizeYuv, M4VS, + (M4OSA_Char*)"videoEditor pixelArray"); + if (pixelArray == M4OSA_NULL) { + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_renderPreviewFrame() malloc error"); + ThumbnailClose(tnContext); + pMessage = videoEditJava_getErrorName(M4ERR_ALLOC); + jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); + return -1; + } + + result = ThumbnailGetPixels16(tnContext, (M4OSA_Int16 *)pixelArray, + pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoWidth, + pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoHeight, + &tnTimeMs); + if (result != M4NO_ERROR) { + M4OSA_free((M4OSA_MemAddr32)pixelArray); + ThumbnailClose(tnContext); + return -1; + } + + ThumbnailClose(tnContext); + tnContext = M4OSA_NULL; + +#ifdef DUMPTOFILE + { + M4OSA_Context fileContext; + M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/FirstRGB565.raw"; + M4OSA_fileExtraDelete((const M4OSA_Char *)fileName); + M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\ + M4OSA_kFileWrite|M4OSA_kFileCreate); + M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) pixelArray, + framesizeYuv); + M4OSA_fileWriteClose(fileContext); + } +#endif + + /** + * Allocate output YUV planes + */ + yuvPlane = (M4VIFI_ImagePlane*)M4OSA_malloc(3*sizeof(M4VIFI_ImagePlane), M4VS, + (M4OSA_Char*)"videoEditor_renderPreviewFrame Output plane YUV"); + if (yuvPlane == M4OSA_NULL) { + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_renderPreviewFrame() malloc error for yuv plane"); + M4OSA_free((M4OSA_MemAddr32)pixelArray); + pMessage = videoEditJava_getErrorName(M4ERR_ALLOC); + jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); + return -1; + } + + yuvPlane[0].u_width = width; + yuvPlane[0].u_height = height; + yuvPlane[0].u_topleft = 0; + yuvPlane[0].u_stride = width; + yuvPlane[0].pac_data = (M4VIFI_UInt8*)pixelArray; + + yuvPlane[1].u_width = width>>1; + yuvPlane[1].u_height = height>>1; + yuvPlane[1].u_topleft = 0; + yuvPlane[1].u_stride = width>>1; + yuvPlane[1].pac_data = yuvPlane[0].pac_data + + yuvPlane[0].u_width * yuvPlane[0].u_height; + yuvPlane[2].u_width = (width)>>1; + yuvPlane[2].u_height = (height)>>1; + yuvPlane[2].u_topleft = 0; + yuvPlane[2].u_stride = (width)>>1; + yuvPlane[2].pac_data = yuvPlane[1].pac_data + + yuvPlane[1].u_width * yuvPlane[1].u_height; + +#ifdef DUMPTOFILE + { + M4OSA_Context fileContext; + M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/ConvertedYuv.yuv"; + M4OSA_fileExtraDelete((const M4OSA_Char *)fileName); + M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\ + M4OSA_kFileWrite|M4OSA_kFileCreate); + M4OSA_fileWriteData(fileContext, + (M4OSA_MemAddr8) yuvPlane[0].pac_data, framesizeYuv); + M4OSA_fileWriteClose(fileContext); + } +#endif + + /* Fill up the render structure*/ + frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data; + } + + frameStr.timeMs = timeMs; /* timestamp on storyboard*/ + frameStr.uiSurfaceWidth = + pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoWidth; + frameStr.uiSurfaceHeight = + pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoHeight; + frameStr.uiFrameWidth = + pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoWidth; + frameStr.uiFrameHeight = + pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ + ClipProperties.uiVideoHeight; + if (pContext->pEditSettings->nbEffects > 0) { + frameStr.bApplyEffect = M4OSA_TRUE; + } else { + frameStr.bApplyEffect = M4OSA_FALSE; + } + frameStr.clipBeginCutTime = iIncrementedDuration; + frameStr.clipEndCutTime = + iIncrementedDuration + + (pContext->pEditSettings->pClipList[iCurrentClipIndex]->uiEndCutTime -\ + pContext->pEditSettings->pClipList[iCurrentClipIndex]->uiBeginCutTime); + + pContext->mPreviewController->setPreviewFrameRenderingMode( + pContext->pEditSettings->\ + pClipList[iCurrentClipIndex]->xVSS.MediaRendering, + pContext->pEditSettings->xVSS.outputVideoSize); + + result = pContext->mPreviewController->renderPreviewFrame(previewSurface, + &frameStr); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + + if (pContext->pEditSettings->pClipList[iCurrentClipIndex]->FileType ==\ + /*M4VIDEOEDITING_kFileType_JPG */ M4VIDEOEDITING_kFileType_ARGB8888) { + M4OSA_free((M4OSA_MemAddr32)frameStr.pBuffer); + } else { + M4OSA_free((M4OSA_MemAddr32)yuvPlane[0].pac_data); + M4OSA_free((M4OSA_MemAddr32)yuvPlane); + } + return tnTimeMs; +} + +static int videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv, + jobject thiz, + jobject mSurface, + jstring filePath, + jint frameWidth, + jint frameHeight, + jint surfaceWidth, + jint surfaceHeight, + jlong fromMs) +{ + bool needToBeLoaded = true; + M4OSA_ERR result = M4NO_ERROR; + M4OSA_UInt32 timeMs = (M4OSA_UInt32)fromMs; + M4OSA_UInt32 framesizeYuv =0; + M4VIFI_UInt8 *pixelArray = M4OSA_NULL; + VideoEditor_renderPreviewFrameStr frameStr; + M4OSA_Context tnContext = M4OSA_NULL; + const char* pMessage = NULL; + M4VIFI_ImagePlane yuvPlane[3], rgbPlane; + + ManualEditContext* pContext = M4OSA_NULL; + // Get the context. + pContext = + (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, + pEnv, thiz); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext->mPreviewController), + "not initialized"); + + // Validate the mSurface parameter. + videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, + (NULL == mSurface), + "mSurface is null"); + jclass surfaceClass = pEnv->FindClass("android/view/Surface"); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == surfaceClass), + "not initialized"); + + jfieldID surface_native = + pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == surface_native), + "not initialized"); + + Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); + sp<Surface> previewSurface = sp<Surface>(p); + + + const char *pString = pEnv->GetStringUTFChars(filePath, NULL); + if (pString == M4OSA_NULL) { + if (pEnv != NULL) { + jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null"); + } + } + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_renderMediaItemPreviewFrame() timeMs=%d", timeMs); + /* get thumbnail*/ + result = ThumbnailOpen(&tnContext,(const M4OSA_Char*)pString, M4OSA_TRUE); + if (result != M4NO_ERROR || tnContext == M4OSA_NULL) { + return timeMs; + } + + framesizeYuv = ((frameWidth)*(frameHeight)*1.5); + + pixelArray = (M4VIFI_UInt8 *)M4OSA_malloc(framesizeYuv, M4VS,\ + (M4OSA_Char*)"videoEditor pixelArray"); + if (pixelArray == M4OSA_NULL) { + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_renderPreviewFrame() malloc error"); + ThumbnailClose(tnContext); + pMessage = videoEditJava_getErrorName(M4ERR_ALLOC); + jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); + return timeMs; + } + + result = ThumbnailGetPixels16(tnContext, (M4OSA_Int16 *)pixelArray, + frameWidth, + frameHeight, &timeMs); + if (result != M4NO_ERROR) { + M4OSA_free((M4OSA_MemAddr32)pixelArray); + ThumbnailClose(tnContext); + return fromMs; + } + +#ifdef DUMPTOFILESYSTEM + { + M4OSA_Context fileContext; + M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/FirstRGB565.rgb"; + M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\ + M4OSA_kFileWrite|M4OSA_kFileCreate); + M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) pixelArray, + framesizeRgb); + M4OSA_fileWriteClose(fileContext); + } +#endif + + yuvPlane[0].pac_data = (M4VIFI_UInt8*)pixelArray; + yuvPlane[0].u_height = frameHeight; + yuvPlane[0].u_width = frameWidth; + yuvPlane[0].u_stride = yuvPlane[0].u_width; + yuvPlane[0].u_topleft = 0; + + yuvPlane[1].u_height = frameHeight/2; + yuvPlane[1].u_width = frameWidth/2; + yuvPlane[1].u_stride = yuvPlane[1].u_width; + yuvPlane[1].u_topleft = 0; + yuvPlane[1].pac_data = yuvPlane[0].pac_data + + yuvPlane[0].u_width*yuvPlane[0].u_height; + + yuvPlane[2].u_height = frameHeight/2; + yuvPlane[2].u_width = frameWidth/2; + yuvPlane[2].u_stride = yuvPlane[2].u_width; + yuvPlane[2].u_topleft = 0; + yuvPlane[2].pac_data = yuvPlane[0].pac_data + + yuvPlane[0].u_width*yuvPlane[0].u_height + \ + (yuvPlane[0].u_width/2)*(yuvPlane[0].u_height/2); +#ifdef DUMPTOFILESYSTEM + { + M4OSA_Context fileContext; + M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/ConvertedYuv.yuv"; + M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\ + M4OSA_kFileWrite|M4OSA_kFileCreate); + M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) yuvPlane[0].pac_data, + framesizeYuv); + M4OSA_fileWriteClose(fileContext); + } +#endif + + /* Fill up the render structure*/ + frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data; + frameStr.timeMs = timeMs; /* timestamp on storyboard*/ + frameStr.uiSurfaceWidth = frameWidth; + frameStr.uiSurfaceHeight = frameHeight; + frameStr.uiFrameWidth = frameWidth; + frameStr.uiFrameHeight = frameHeight; + frameStr.bApplyEffect = M4OSA_FALSE; + // clip begin cuttime and end cuttime set to 0 + // as its only required when effect needs to be applied while rendering + frameStr.clipBeginCutTime = 0; + frameStr.clipEndCutTime = 0; + + /* pContext->mPreviewController->setPreviewFrameRenderingMode(M4xVSS_kBlackBorders, + (M4VIDEOEDITING_VideoFrameSize)(M4VIDEOEDITING_kHD960+1));*/ + result + = pContext->mPreviewController->renderPreviewFrame(previewSurface,&frameStr); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + + /* free the pixelArray and yuvPlane[0].pac_data */ + M4OSA_free((M4OSA_MemAddr32)yuvPlane[0].pac_data); + + ThumbnailClose(tnContext); + + return timeMs; +} + +int videoEditor_generateAudioRawFile( JNIEnv* pEnv, + jobject thiz, + jstring infilePath, + jstring pcmfilePath) +{ + M4OSA_ERR result = M4NO_ERROR; + bool loaded = true; + ManualEditContext* pContext = M4OSA_NULL; + + + + const char *pInputFile = pEnv->GetStringUTFChars(infilePath, NULL); + if (pInputFile == M4OSA_NULL) { + if (pEnv != NULL) { + jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null"); + } + } + + const char *pStringOutPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL); + if (pStringOutPCMFilePath == M4OSA_NULL) { + if (pEnv != NULL) { + jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null"); + } + } + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, + "VIDEO_EDITOR", "videoEditor_generateAudioRawFile infilePath %s", + pInputFile); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, + "VIDEO_EDITOR", "videoEditor_generateAudioRawFile pcmfilePath %s", + pStringOutPCMFilePath); + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz); + + result = videoEditor_generateAudio( pEnv, pContext, (M4OSA_Char*)pInputFile, + (M4OSA_Char*)pStringOutPCMFilePath); + + return result; +} + +M4OSA_ERR videoEditor_generateAudio(JNIEnv* pEnv,ManualEditContext* pContext, + M4OSA_Char* infilePath, + M4OSA_Char* pcmfilePath ) +{ + bool needToBeLoaded = true; + M4OSA_ERR result = M4NO_ERROR; + M4MCS_Context mcsContext; + M4OSA_Char* pInputFile = M4OSA_NULL; + M4OSA_Char* pOutputFile = M4OSA_NULL; + M4OSA_Char* pTempPath = M4OSA_NULL; + M4MCS_OutputParams* pOutputParams = M4OSA_NULL; + M4MCS_EncodingParams* pEncodingParams = M4OSA_NULL; + M4OSA_Int32 pInputFileType = 0; + M4OSA_UInt8 threadProgress = 0; + M4OSA_Char* pTemp3gpFilePath = M4OSA_NULL; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_generateAudio()"); + + videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, + (NULL == pContext), + "ManualEditContext is null"); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_init()"); + + pOutputParams = (M4MCS_OutputParams *)M4OSA_malloc( + sizeof(M4MCS_OutputParams),0x00, + (M4OSA_Char *)"M4MCS_OutputParams"); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pOutputParams), + "not initialized"); + + pEncodingParams = (M4MCS_EncodingParams *)M4OSA_malloc( + sizeof(M4MCS_EncodingParams),0x00, + (M4OSA_Char *)"M4MCS_EncodingParams"); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pEncodingParams), + "not initialized"); + // Initialize the MCS library. + result = M4MCS_init(&mcsContext, pContext->initParams.pFileReadPtr, + pContext->initParams.pFileWritePtr); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,\ + (M4NO_ERROR != result), result); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == mcsContext), + "not initialized"); + // generate the path for temp 3gp output file + pTemp3gpFilePath = (M4OSA_Char*) M4OSA_malloc ( + (M4OSA_chrLength((M4OSA_Char*)pContext->initParams.pTempPath) + + M4OSA_chrLength ((M4OSA_Char*)TEMP_MCS_OUT_FILE_PATH)) , 0x0, + (M4OSA_Char*) "Malloc for temp 3gp file"); + if ( pTemp3gpFilePath != M4OSA_NULL ) + { + M4OSA_memset(pTemp3gpFilePath , + M4OSA_chrLength((M4OSA_Char*)pContext->initParams.pTempPath) + + M4OSA_chrLength((M4OSA_Char*)TEMP_MCS_OUT_FILE_PATH), 0); + M4OSA_chrNCat ( (M4OSA_Char*)pTemp3gpFilePath, + (M4OSA_Char*)pContext->initParams.pTempPath , + M4OSA_chrLength ((M4OSA_Char*)pContext->initParams.pTempPath)); + M4OSA_chrNCat ( pTemp3gpFilePath , (M4OSA_Char*)TEMP_MCS_OUT_FILE_PATH, + M4OSA_chrLength ((M4OSA_Char*)TEMP_MCS_OUT_FILE_PATH)); + } + + pInputFile = (M4OSA_Char *) infilePath; //pContext->mAudioSettings->pFile; + //Delete this file later + pOutputFile = (M4OSA_Char *) pTemp3gpFilePath; + // Temp folder path for VSS use = ProjectPath + pTempPath = (M4OSA_Char *) pContext->initParams.pTempPath; + pInputFileType = (M4VIDEOEDITING_FileType)pContext->mAudioSettings->fileType; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "TEMP_MCS_OUT_FILE_PATH len %d", + M4OSA_chrLength ((M4OSA_Char*)TEMP_MCS_OUT_FILE_PATH)); + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pTemp3gpFilePath %s", + pOutputFile); + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_open()"); + + result = M4MCS_open(mcsContext, pInputFile, + (M4VIDEOEDITING_FileType)pInputFileType, + pOutputFile, pTempPath); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + + pOutputParams->OutputFileType + = (M4VIDEOEDITING_FileType)M4VIDEOEDITING_kFileType_3GPP; + // Set the video format. + pOutputParams->OutputVideoFormat = + (M4VIDEOEDITING_VideoFormat)M4VIDEOEDITING_kNoneVideo;//M4VIDEOEDITING_kNoneVideo; + // Set the frame size. + pOutputParams->OutputVideoFrameSize + = (M4VIDEOEDITING_VideoFrameSize)M4VIDEOEDITING_kQCIF; + // Set the frame rate. + pOutputParams->OutputVideoFrameRate + = (M4VIDEOEDITING_VideoFramerate)M4VIDEOEDITING_k5_FPS; + + // Set the audio format. + pOutputParams->OutputAudioFormat + = (M4VIDEOEDITING_AudioFormat)M4VIDEOEDITING_kAAC; + // Set the audio sampling frequency. + pOutputParams->OutputAudioSamplingFrequency = + (M4VIDEOEDITING_AudioSamplingFrequency)M4VIDEOEDITING_k32000_ASF; + // Set the audio mono. + pOutputParams->bAudioMono = false; + // Set the pcm file; null for now. + pOutputParams->pOutputPCMfile = (M4OSA_Char *)pcmfilePath; + //(M4OSA_Char *)"/sdcard/Output/AudioPcm.pcm"; + // Set the audio sampling frequency. + pOutputParams->MediaRendering = (M4MCS_MediaRendering)M4MCS_kCropping; + // new params after integrating MCS 2.0 + // Set the number of audio effects; 0 for now. + pOutputParams->nbEffects = 0; + // Set the audio effect; null for now. + pOutputParams->pEffects = NULL; + // Set the audio effect; null for now. + pOutputParams->bDiscardExif = M4OSA_FALSE; + // Set the audio effect; null for now. + pOutputParams->bAdjustOrientation = M4OSA_FALSE; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_setOutputParams()"); + result = M4MCS_setOutputParams(mcsContext, pOutputParams); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + + // Set the video bitrate. + pEncodingParams->OutputVideoBitrate = + (M4VIDEOEDITING_Bitrate)M4VIDEOEDITING_kUndefinedBitrate; + // Set the audio bitrate. + pEncodingParams->OutputAudioBitrate + = (M4VIDEOEDITING_Bitrate)M4VIDEOEDITING_k128_KBPS; + // Set the end cut time in milliseconds. + pEncodingParams->BeginCutTime = 0; + // Set the end cut time in milliseconds. + pEncodingParams->EndCutTime = 0; + // Set the output file size in bytes. + pEncodingParams->OutputFileSize = 0; + // Set video time scale. + pEncodingParams->OutputVideoTimescale = 0; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "M4MCS_setEncodingParams()"); + result = M4MCS_setEncodingParams(mcsContext, pEncodingParams); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "M4MCS_checkParamsAndStart()"); + result = M4MCS_checkParamsAndStart(mcsContext); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_step()"); + + /*+ PROGRESS CB */ + M4OSA_UInt8 curProgress = 0; + int lastProgress = 0; + + LOGV("LVME_generateAudio Current progress is =%d", curProgress); + pEnv->CallVoidMethod(pContext->engine, + pContext->onProgressUpdateMethodId, 1/*task status*/, + curProgress/*progress*/); + do { + result = M4MCS_step(mcsContext, &curProgress); + + if (result != M4NO_ERROR) { + LOGV("LVME_generateAudio M4MCS_step returned 0x%x",result); + + if (result == M4MCS_WAR_TRANSCODING_DONE) { + LOGV("LVME_generateAudio MCS process ended"); + + // Send a progress notification. + curProgress = 100; + pEnv->CallVoidMethod(pContext->engine, + pContext->onProgressUpdateMethodId, 1/*task status*/, + curProgress); + LOGV("LVME_generateAudio Current progress is =%d", curProgress); + } + } else { + // Send a progress notification if needed + if (curProgress != lastProgress) { + lastProgress = curProgress; + pEnv->CallVoidMethod(pContext->engine, + pContext->onProgressUpdateMethodId, 0/*task status*/, + curProgress/*progress*/); + LOGV("LVME_generateAudio Current progress is =%d",curProgress); + } + } + } while (result == M4NO_ERROR); + /*- PROGRESS CB */ + + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4MCS_WAR_TRANSCODING_DONE != result), result); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_abort()"); + result = M4MCS_abort(mcsContext); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + + //pContext->mAudioSettings->pFile = pOutputParams->pOutputPCMfile; + M4OSA_fileExtraDelete((const M4OSA_Char *) pTemp3gpFilePath); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_generateAudio() EXIT "); + + M4OSA_free((M4OSA_MemAddr32)pTemp3gpFilePath); + M4OSA_free((M4OSA_MemAddr32)pOutputParams); + M4OSA_free((M4OSA_MemAddr32)pEncodingParams); + return result; +} + +static int removeAlphafromRGB8888 ( + M4OSA_Char* pFramingFilePath, + M4xVSS_FramingStruct *pFramingCtx) +{ + M4OSA_UInt32 frameSize_argb = (pFramingCtx->width * pFramingCtx->height * 4); // aRGB data + M4OSA_Context lImageFileFp = M4OSA_NULL; + M4OSA_ERR err = M4NO_ERROR; + + LOGV("removeAlphafromRGB8888: width %d", pFramingCtx->width); + + M4OSA_UInt8 *pTmpData = (M4OSA_UInt8*) M4OSA_malloc(frameSize_argb, M4VS, (M4OSA_Char*)"Image argb data"); + if (pTmpData == M4OSA_NULL) { + LOGE("Failed to allocate memory for Image clip"); + return M4ERR_ALLOC; + } + + /** Read the argb data from the passed file. */ + M4OSA_ERR lerr = M4OSA_fileReadOpen(&lImageFileFp, (M4OSA_Void *) pFramingFilePath, M4OSA_kFileRead); + + + if ((lerr != M4NO_ERROR) || (lImageFileFp == M4OSA_NULL)) + { + LOGE("removeAlphafromRGB8888: Can not open the file "); + M4OSA_free((M4OSA_MemAddr32)pTmpData); + return M4ERR_FILE_NOT_FOUND; + } + + + lerr = M4OSA_fileReadData(lImageFileFp, (M4OSA_MemAddr8)pTmpData, &frameSize_argb); + if (lerr != M4NO_ERROR) + { + LOGE("removeAlphafromRGB8888: can not read the data "); + M4OSA_fileReadClose(lImageFileFp); + M4OSA_free((M4OSA_MemAddr32)pTmpData); + return lerr; + } + M4OSA_fileReadClose(lImageFileFp); + + M4OSA_UInt32 frameSize = (pFramingCtx->width * pFramingCtx->height * 3); //Size of RGB 888 data. + + pFramingCtx->FramingRgb = (M4VIFI_ImagePlane*)M4OSA_malloc( + sizeof(M4VIFI_ImagePlane), M4VS, (M4OSA_Char*)"Image clip RGB888 data"); + pFramingCtx->FramingRgb->pac_data = (M4VIFI_UInt8*)M4OSA_malloc( + frameSize, M4VS, (M4OSA_Char*)"Image clip RGB888 data"); + + if (pFramingCtx->FramingRgb == M4OSA_NULL) + { + LOGE("Failed to allocate memory for Image clip"); + M4OSA_free((M4OSA_MemAddr32)pTmpData); + return M4ERR_ALLOC; + } + + /** Remove the alpha channel */ + for (int i = 0, j = 0; i < frameSize_argb; i++) { + if ((i % 4) == 0) continue; + pFramingCtx->FramingRgb->pac_data[j] = pTmpData[i]; + j++; + } + M4OSA_free((M4OSA_MemAddr32)pTmpData); + return M4NO_ERROR; +} + +static void +videoEditor_populateSettings( + JNIEnv* pEnv, + jobject thiz, + jobject settings, + jobject object, + jobject audioSettingObject) +{ + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_populateSettings()"); + + bool needToBeLoaded = true; + ManualEditContext* pContext = M4OSA_NULL; + M4OSA_ERR result = M4NO_ERROR; + jstring str = M4OSA_NULL; + jobjectArray propertiesClipsArray = M4OSA_NULL; + jobject properties = M4OSA_NULL; + jint* bitmapArray = M4OSA_NULL; + jobjectArray effectSettingsArray = M4OSA_NULL; + jobject effectSettings = M4OSA_NULL; + jintArray pixelArray = M4OSA_NULL; + int width = 0; + int height = 0; + int nbOverlays = 0; + int i,j = 0; + int *pOverlayIndex = M4OSA_NULL; + + // Add a code marker (the condition must always be true). + ADD_CODE_MARKER_FUN(NULL != pEnv) + + // Validate the settings parameter. + videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, + (NULL == settings), + "settings is null"); + // Get the context. + pContext = + (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext->mPreviewController), + "not initialized"); + jclass mPreviewClipPropClazz = pEnv->FindClass(PREVIEW_PROPERTIES_CLASS_NAME); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == mPreviewClipPropClazz), + "not initialized"); + + jfieldID fid = pEnv->GetFieldID(mPreviewClipPropClazz,"clipProperties", + "[L"PROPERTIES_CLASS_NAME";" ); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == fid), + "not initialized"); + + propertiesClipsArray = (jobjectArray)pEnv->GetObjectField(object, fid); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == propertiesClipsArray), + "not initialized"); + + jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == engineClass), + "not initialized"); + + pContext->onPreviewProgressUpdateMethodId = pEnv->GetMethodID(engineClass, + "onPreviewProgressUpdate", "(IZ)V"); + // Check if the context is valid (required because the context is dereferenced). + if (needToBeLoaded) { + // Make sure that we are in a correct state. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (pContext->state != ManualEditState_INITIALIZED), + "settings already loaded"); + // Retrieve the edit settings. + if (pContext->pEditSettings != M4OSA_NULL) { + videoEditClasses_freeEditSettings(&pContext->pEditSettings); + pContext->pEditSettings = M4OSA_NULL; + } + videoEditClasses_getEditSettings(&needToBeLoaded, pEnv, + settings, &pContext->pEditSettings,false); + } + M4OSA_TRACE1_0("videoEditorC_getEditSettings done"); + + if ( pContext->pEditSettings != NULL ) + { + // Check if the edit settings could be retrieved. + jclass mEditClazz = pEnv->FindClass(EDIT_SETTINGS_CLASS_NAME); + if(mEditClazz == M4OSA_NULL) + { + M4OSA_TRACE1_0("cannot find object field for mEditClazz"); + return; + } + jclass mEffectsClazz = pEnv->FindClass(EFFECT_SETTINGS_CLASS_NAME); + if(mEffectsClazz == M4OSA_NULL) + { + M4OSA_TRACE1_0("cannot find object field for mEffectsClazz"); + return; + } + fid = pEnv->GetFieldID(mEditClazz,"effectSettingsArray", "[L"EFFECT_SETTINGS_CLASS_NAME";" ); + if(fid == M4OSA_NULL) + { + M4OSA_TRACE1_0("cannot find field for effectSettingsArray Array"); + return; + } + effectSettingsArray = (jobjectArray)pEnv->GetObjectField(settings, fid); + if(effectSettingsArray == M4OSA_NULL) + { + M4OSA_TRACE1_0("cannot find object field for effectSettingsArray"); + return; + } + i = 0; + j = 0; + //int overlayIndex[pContext->pEditSettings->nbEffects]; + if ( pContext->pEditSettings->nbEffects ) + { + pOverlayIndex + = (int*) M4OSA_malloc(pContext->pEditSettings->nbEffects, 0, + (M4OSA_Char*)"pOverlayIndex"); + } + + M4OSA_TRACE1_1("no of effects = %d",pContext->pEditSettings->nbEffects); + while (j < pContext->pEditSettings->nbEffects) + { + if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL) + { + pOverlayIndex[nbOverlays] = j; + nbOverlays++; + M4xVSS_FramingStruct *aFramingCtx = M4OSA_NULL; + aFramingCtx + = (M4xVSS_FramingStruct*)M4OSA_malloc(sizeof(M4xVSS_FramingStruct), M4VS, + (M4OSA_Char*)"M4xVSS_internalDecodeGIF: Context of the framing effect"); + if (aFramingCtx == M4OSA_NULL) + { + M4OSA_TRACE1_0("Allocation error in videoEditor_populateSettings"); + } + aFramingCtx->pCurrent = M4OSA_NULL; /* Only used by the first element of the chain */ + aFramingCtx->previousClipTime = -1; + aFramingCtx->FramingYuv = M4OSA_NULL; + aFramingCtx->FramingRgb = M4OSA_NULL; + aFramingCtx->topleft_x + = pContext->pEditSettings->Effects[j].xVSS.topleft_x; + aFramingCtx->topleft_y + = pContext->pEditSettings->Effects[j].xVSS.topleft_y; + + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF u_width %d", + pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF u_height() %d", + pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF rgbType() %d", + pContext->pEditSettings->Effects[j].xVSS.rgbType); + + aFramingCtx->width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width; + aFramingCtx->height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height; + + + result = M4xVSS_internalConvertARGB888toYUV420_FrammingEffect(pContext->engineContext, + &(pContext->pEditSettings->Effects[j]),aFramingCtx, + pContext->pEditSettings->Effects[j].xVSS.framingScaledSize); + if (result != M4NO_ERROR) + { + M4OSA_TRACE1_1("M4xVSS_internalConvertARGB888toYUV420_FrammingEffect returned 0x%x", result); + } + + //framing buffers are resized to fit the output video resolution. + pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width = + aFramingCtx->FramingRgb->u_width; + pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height = + aFramingCtx->FramingRgb->u_height; + + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "A framing Context aFramingCtx->width = %d", + aFramingCtx->FramingRgb->u_width); + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "A framing Context aFramingCtx->height = %d", + aFramingCtx->FramingRgb->u_height); + + + width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width; + height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height; + + pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_stride = width*3; + + //for RGB888 + pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_topleft = 0; + + pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->pac_data = + (M4VIFI_UInt8 *)M4OSA_malloc(width*height*3, + 0x00,(M4OSA_Char *)"pac_data buffer"); + + M4OSA_memcpy((M4OSA_Int8 *)&pContext->pEditSettings->\ + Effects[j].xVSS.pFramingBuffer->\ + pac_data[0],(M4OSA_Int8 *)&aFramingCtx->FramingRgb->pac_data[0],(width*height*3)); + + //As of now rgb type is always rgb888, can be changed in future for rgb 565 + pContext->pEditSettings->Effects[j].xVSS.rgbType = + (M4VSS3GPP_RGBType)M4VSS3GPP_kRGB888; //M4VSS3GPP_kRGB565; + + if (aFramingCtx->FramingYuv != M4OSA_NULL ) + { + if (aFramingCtx->FramingYuv->pac_data != M4OSA_NULL) { + M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingYuv->pac_data); + aFramingCtx->FramingYuv->pac_data = M4OSA_NULL; + } + } + if (aFramingCtx->FramingYuv != M4OSA_NULL) { + M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingYuv); + aFramingCtx->FramingYuv = M4OSA_NULL; + } + if (aFramingCtx->FramingRgb->pac_data != M4OSA_NULL) { + M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingRgb->pac_data); + aFramingCtx->FramingRgb->pac_data = M4OSA_NULL; + } + if (aFramingCtx->FramingRgb != M4OSA_NULL) { + M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingRgb); + aFramingCtx->FramingRgb = M4OSA_NULL; + } + if (aFramingCtx != M4OSA_NULL) { + M4OSA_free((M4OSA_MemAddr32)aFramingCtx); + aFramingCtx = M4OSA_NULL; + } + } + j++; + } + + // Check if the edit settings could be retrieved. + M4OSA_TRACE1_1("total clips are = %d",pContext->pEditSettings->uiClipNumber); + for (i = 0; i < pContext->pEditSettings->uiClipNumber; i++) { + M4OSA_TRACE1_1("clip no = %d",i); + properties = pEnv->GetObjectArrayElement(propertiesClipsArray, i); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == properties), + "not initialized"); + getClipSetting(pEnv,properties, pContext->pEditSettings->pClipList[i]); + } + + if (needToBeLoaded) { + // Log the edit settings. + VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings); + } + } + + if (audioSettingObject != M4OSA_NULL) { + jclass audioSettingClazz = pEnv->FindClass(AUDIO_SETTINGS_CLASS_NAME); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == audioSettingClazz), + "not initialized"); + + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext->mAudioSettings), + "not initialized"); + + fid = pEnv->GetFieldID(audioSettingClazz,"bRemoveOriginal","Z"); + pContext->mAudioSettings->bRemoveOriginal = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("bRemoveOriginal = %d",pContext->mAudioSettings->bRemoveOriginal); + + fid = pEnv->GetFieldID(audioSettingClazz,"channels","I"); + pContext->mAudioSettings->uiNbChannels = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("uiNbChannels = %d",pContext->mAudioSettings->uiNbChannels); + + fid = pEnv->GetFieldID(audioSettingClazz,"Fs","I"); + pContext->mAudioSettings->uiSamplingFrequency = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("uiSamplingFrequency = %d",pContext->mAudioSettings->uiSamplingFrequency); + + fid = pEnv->GetFieldID(audioSettingClazz,"ExtendedFs","I"); + pContext->mAudioSettings->uiExtendedSamplingFrequency = + pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("uiExtendedSamplingFrequency = %d", + pContext->mAudioSettings->uiExtendedSamplingFrequency); + + fid = pEnv->GetFieldID(audioSettingClazz,"startMs","J"); + pContext->mAudioSettings->uiAddCts + = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("uiAddCts = %d",pContext->mAudioSettings->uiAddCts); + + fid = pEnv->GetFieldID(audioSettingClazz,"volume","I"); + pContext->mAudioSettings->uiAddVolume + = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("uiAddVolume = %d",pContext->mAudioSettings->uiAddVolume); + + fid = pEnv->GetFieldID(audioSettingClazz,"loop","Z"); + pContext->mAudioSettings->bLoop + = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("bLoop = %d",pContext->mAudioSettings->bLoop); + + fid = pEnv->GetFieldID(audioSettingClazz,"beginCutTime","J"); + pContext->mAudioSettings->beginCutMs + = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("begin cut time = %d",pContext->mAudioSettings->beginCutMs); + + fid = pEnv->GetFieldID(audioSettingClazz,"endCutTime","J"); + pContext->mAudioSettings->endCutMs + = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("end cut time = %d",pContext->mAudioSettings->endCutMs); + + fid = pEnv->GetFieldID(audioSettingClazz,"fileType","I"); + pContext->mAudioSettings->fileType + = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("fileType = %d",pContext->mAudioSettings->fileType); + fid = pEnv->GetFieldID(audioSettingClazz,"pFile","Ljava/lang/String;"); + str = (jstring)pEnv->GetObjectField(audioSettingObject,fid); + pContext->mAudioSettings->pFile + = (M4OSA_Char*)pEnv->GetStringUTFChars(str, M4OSA_NULL); + M4OSA_TRACE1_1("file name = %s",pContext->mAudioSettings->pFile); + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio() file name = %s",\ + pContext->mAudioSettings->pFile); + fid = pEnv->GetFieldID(audioSettingClazz,"pcmFilePath","Ljava/lang/String;"); + str = (jstring)pEnv->GetObjectField(audioSettingObject,fid); + pContext->mAudioSettings->pPCMFilePath = + (M4OSA_Char*)pEnv->GetStringUTFChars(str, M4OSA_NULL); + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "pPCMFilePath -- %s ",\ + pContext->mAudioSettings->pPCMFilePath); + fid = pEnv->GetFieldID(engineClass,"mRegenerateAudio","Z"); + bool regenerateAudio = pEnv->GetBooleanField(thiz,fid); + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio -- %d ",\ + regenerateAudio); + if (regenerateAudio) { + M4OSA_TRACE1_0("Calling Generate Audio now"); + result = videoEditor_generateAudio(pEnv, + pContext, + (M4OSA_Char*)pContext->mAudioSettings->pFile, + (M4OSA_Char*)pContext->mAudioSettings->pPCMFilePath); + regenerateAudio = false; + pEnv->SetBooleanField(thiz,fid,regenerateAudio); + } + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio()"); + + /* Audio mix and duck */ + fid = pEnv->GetFieldID(audioSettingClazz,"ducking_threshold","I"); + pContext->mAudioSettings->uiInDucking_threshold + = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("ducking threshold = %d", + pContext->mAudioSettings->uiInDucking_threshold); + + fid = pEnv->GetFieldID(audioSettingClazz,"ducking_lowVolume","I"); + pContext->mAudioSettings->uiInDucking_lowVolume + = pEnv->GetIntField(audioSettingObject,fid); + M4OSA_TRACE1_1("ducking lowVolume = %d", + pContext->mAudioSettings->uiInDucking_lowVolume); + + fid = pEnv->GetFieldID(audioSettingClazz,"bInDucking_enable","Z"); + pContext->mAudioSettings->bInDucking_enable + = pEnv->GetBooleanField(audioSettingObject,fid); + M4OSA_TRACE1_1("ducking lowVolume = %d", + pContext->mAudioSettings->bInDucking_enable); + } else { + if (pContext->mAudioSettings != M4OSA_NULL) { + pContext->mAudioSettings->pFile = M4OSA_NULL; + pContext->mAudioSettings->bRemoveOriginal = 0; + pContext->mAudioSettings->uiNbChannels = 0; + pContext->mAudioSettings->uiSamplingFrequency = 0; + pContext->mAudioSettings->uiExtendedSamplingFrequency = 0; + pContext->mAudioSettings->uiAddCts = 0; + pContext->mAudioSettings->uiAddVolume = 0; + pContext->mAudioSettings->beginCutMs = 0; + pContext->mAudioSettings->endCutMs = 0; + pContext->mAudioSettings->fileType = 0; + pContext->mAudioSettings->bLoop = 0; + pContext->mAudioSettings->uiInDucking_lowVolume = 0; + pContext->mAudioSettings->bInDucking_enable = 0; + pContext->mAudioSettings->uiBTChannelCount = 0; + pContext->mAudioSettings->uiInDucking_threshold = 0; + + fid = pEnv->GetFieldID(engineClass,"mRegenerateAudio","Z"); + bool regenerateAudio = pEnv->GetBooleanField(thiz,fid); + if(!regenerateAudio) { + regenerateAudio = true; + pEnv->SetBooleanField(thiz,fid,regenerateAudio); + } + } + } + if (pContext->pEditSettings != NULL ) + { + result = pContext->mPreviewController->loadEditSettings(pContext->pEditSettings, + pContext->mAudioSettings); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + + pContext->mPreviewController->setJniCallback((void*)pContext, + (jni_progress_callback_fct)jniPreviewProgressCallback); + + j = 0; + while (j < nbOverlays) + { + if (pContext->pEditSettings->Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data != \ + M4OSA_NULL) { + M4OSA_free((M4OSA_MemAddr32)pContext->pEditSettings->\ + Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data); + pContext->pEditSettings->\ + Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data = M4OSA_NULL; + } + if (pContext->pEditSettings->Effects[pOverlayIndex[j]].xVSS.pFramingBuffer != M4OSA_NULL) { + M4OSA_free((M4OSA_MemAddr32)pContext->pEditSettings->\ + Effects[pOverlayIndex[j]].xVSS.pFramingBuffer); + pContext->pEditSettings->Effects[pOverlayIndex[j]].xVSS.pFramingBuffer = M4OSA_NULL; + } + j++; + } + } + if (pOverlayIndex != M4OSA_NULL) + { + M4OSA_free((M4OSA_MemAddr32)pOverlayIndex); + pOverlayIndex = M4OSA_NULL; + } + return; +} + +static void +videoEditor_startPreview( + JNIEnv* pEnv, + jobject thiz, + jobject mSurface, + jlong fromMs, + jlong toMs, + jint callbackInterval, + jboolean loop) +{ + bool needToBeLoaded = true; + M4OSA_ERR result = M4NO_ERROR; + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_startPreview()"); + + ManualEditContext* pContext = M4OSA_NULL; + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext->mAudioSettings), + "not initialized"); + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext->mPreviewController), + "not initialized"); + + // Validate the mSurface parameter. + videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, + (NULL == mSurface), + "mSurface is null"); + + jclass surfaceClass = pEnv->FindClass("android/view/Surface"); + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == surfaceClass), + "not initialized"); + //jfieldID surface_native = pEnv->GetFieldID(surfaceClass, "mSurface", "I"); + jfieldID surface_native + = pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); + + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == surface_native), + "not initialized"); + + Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); + + sp<Surface> previewSurface = sp<Surface>(p); + + result = pContext->mPreviewController->setSurface(previewSurface); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "fromMs=%ld, toMs=%ld", + (M4OSA_UInt32)fromMs, (M4OSA_Int32)toMs); + + result = pContext->mPreviewController->startPreview((M4OSA_UInt32)fromMs, + (M4OSA_Int32)toMs, + (M4OSA_UInt16)callbackInterval, + (M4OSA_Bool)loop); + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, (M4NO_ERROR != result), result); +} + + +static jobject +videoEditor_getProperties( + JNIEnv* pEnv, + jobject thiz, + jstring file) +{ + jobject object = M4OSA_NULL; + object = videoEditProp_getProperties(pEnv,thiz,file); + + return object; + +} +static int videoEditor_getPixels( + JNIEnv* env, + jobject thiz, + jstring path, + jintArray pixelArray, + M4OSA_UInt32 width, + M4OSA_UInt32 height, + M4OSA_UInt32 timeMS) +{ + + M4OSA_ERR err = M4NO_ERROR; + M4OSA_Context mContext = M4OSA_NULL; + jint* m_dst32 = M4OSA_NULL; + + + // Add a text marker (the condition must always be true). + ADD_TEXT_MARKER_FUN(NULL != env) + + const char *pString = env->GetStringUTFChars(path, NULL); + if (pString == M4OSA_NULL) { + if (env != NULL) { + jniThrowException(env, "java/lang/RuntimeException", "Input string null"); + } + return M4ERR_ALLOC; + } + + err = ThumbnailOpen(&mContext,(const M4OSA_Char*)pString, M4OSA_FALSE); + if (err != M4NO_ERROR || mContext == M4OSA_NULL) { + if (pString != NULL) { + env->ReleaseStringUTFChars(path, pString); + } + if (env != NULL) { + jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed"); + } + } + + m_dst32 = env->GetIntArrayElements(pixelArray, NULL); + + err = ThumbnailGetPixels32(mContext, (M4OSA_Int32 *)m_dst32, width,height,&timeMS); + if (err != M4NO_ERROR ) { + if (env != NULL) { + jniThrowException(env, "java/lang/RuntimeException",\ + "ThumbnailGetPixels32 failed"); + } + } + env->ReleaseIntArrayElements(pixelArray, m_dst32, 0); + + ThumbnailClose(mContext); + if (pString != NULL) { + env->ReleaseStringUTFChars(path, pString); + } + + return timeMS; +} + +static int videoEditor_getPixelsList( + JNIEnv* env, + jobject thiz, + jstring path, + jintArray pixelArray, + M4OSA_UInt32 width, + M4OSA_UInt32 height, + M4OSA_UInt32 deltatimeMS, + M4OSA_UInt32 noOfThumbnails, + M4OSA_UInt32 startTime, + M4OSA_UInt32 endTime) +{ + + M4OSA_ERR err; + M4OSA_Context mContext = M4OSA_NULL; + jint* m_dst32; + M4OSA_UInt32 timeMS = startTime; + int arrayOffset = 0; + + + + // Add a text marker (the condition must always be true). + ADD_TEXT_MARKER_FUN(NULL != env) + + const char *pString = env->GetStringUTFChars(path, NULL); + if (pString == M4OSA_NULL) { + if (env != NULL) { + jniThrowException(env, "java/lang/RuntimeException", "Input string null"); + } + return M4ERR_ALLOC; + } + + err = ThumbnailOpen(&mContext,(const M4OSA_Char*)pString, M4OSA_FALSE); + if (err != M4NO_ERROR || mContext == M4OSA_NULL) { + if (env != NULL) { + jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed"); + } + if (pString != NULL) { + env->ReleaseStringUTFChars(path, pString); + } + return err; + } + + m_dst32 = env->GetIntArrayElements(pixelArray, NULL); + + do { + err = ThumbnailGetPixels32(mContext, ((M4OSA_Int32 *)m_dst32 + arrayOffset), + width,height,&timeMS); + if (err != M4NO_ERROR ) { + if (env != NULL) { + jniThrowException(env, "java/lang/RuntimeException",\ + "ThumbnailGetPixels32 failed"); + } + return err; + } + timeMS += deltatimeMS; + arrayOffset += (width * height * 4); + noOfThumbnails--; + } while(noOfThumbnails > 0); + + env->ReleaseIntArrayElements(pixelArray, m_dst32, 0); + + ThumbnailClose(mContext); + if (pString != NULL) { + env->ReleaseStringUTFChars(path, pString); + } + + return err; + +} + +static M4OSA_ERR +videoEditor_toUTF8Fct( + M4OSA_Void* pBufferIn, + M4OSA_UInt8* pBufferOut, + M4OSA_UInt32* bufferOutSize) +{ + M4OSA_ERR result = M4NO_ERROR; + M4OSA_UInt32 length = 0; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_toUTF8Fct()"); + + // Determine the length of the input buffer. + if (M4OSA_NULL != pBufferIn) + { + length = M4OSA_chrLength((M4OSA_Char *)pBufferIn); + } + + // Check if the output buffer is large enough to hold the input buffer. + if ((*bufferOutSize) > length) + { + // Check if the input buffer is not M4OSA_NULL. + if (M4OSA_NULL != pBufferIn) + { + // Copy the temp path, ignore the result. + M4OSA_chrNCopy((M4OSA_Char *)pBufferOut, (M4OSA_Char *)pBufferIn, length); + } + else + { + // Set the output buffer to an empty string. + (*(M4OSA_Char *)pBufferOut) = 0; + } + } + else + { + // The buffer is too small. + result = M4xVSSWAR_BUFFER_OUT_TOO_SMALL; + } + + // Return the buffer output size. + (*bufferOutSize) = length + 1; + + // Return the result. + return(result); +} + +static M4OSA_ERR +videoEditor_fromUTF8Fct( + M4OSA_UInt8* pBufferIn, + M4OSA_Void* pBufferOut, + M4OSA_UInt32* bufferOutSize) +{ + M4OSA_ERR result = M4NO_ERROR; + M4OSA_UInt32 length = 0; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_fromUTF8Fct()"); + + // Determine the length of the input buffer. + if (M4OSA_NULL != pBufferIn) + { + length = M4OSA_chrLength((M4OSA_Char *)pBufferIn); + } + + // Check if the output buffer is large enough to hold the input buffer. + if ((*bufferOutSize) > length) + { + // Check if the input buffer is not M4OSA_NULL. + if (M4OSA_NULL != pBufferIn) + { + // Copy the temp path, ignore the result. + M4OSA_chrNCopy((M4OSA_Char *)pBufferOut, (M4OSA_Char *)pBufferIn, length); + } + else + { + // Set the output buffer to an empty string. + (*(M4OSA_Char *)pBufferOut) = 0; + } + } + else + { + // The buffer is too small. + result = M4xVSSWAR_BUFFER_OUT_TOO_SMALL; + } + + // Return the buffer output size. + (*bufferOutSize) = length + 1; + + // Return the result. + return(result); +} + +static M4OSA_ERR +videoEditor_getTextRgbBufferFct( + M4OSA_Void* pRenderingData, + M4OSA_Void* pTextBuffer, + M4OSA_UInt32 textBufferSize, + M4VIFI_ImagePlane** pOutputPlane) +{ + M4OSA_ERR result = M4NO_ERROR; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getTextRgbBufferFct()"); + + // Return the result. + return(result); +} + +static void +videoEditor_callOnProgressUpdate( + ManualEditContext* pContext, + int task, + int progress) +{ + JNIEnv* pEnv = NULL; + + + // Attach the current thread. + pContext->pVM->AttachCurrentThread(&pEnv, NULL); + + + // Call the on completion callback. + pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId, + videoEditJava_getEngineCToJava(task), progress); + + + // Detach the current thread. + pContext->pVM->DetachCurrentThread(); +} + +static void +videoEditor_freeContext( + JNIEnv* pEnv, + ManualEditContext** ppContext) +{ + ManualEditContext* pContext = M4OSA_NULL; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_freeContext"); + + // Set the context pointer. + pContext = (*ppContext); + + // Check if the context was set. + if (M4OSA_NULL != pContext) + { + // Check if a global reference to the engine object was set. + if (NULL != pContext->engine) + { + // Free the global reference. + pEnv->DeleteGlobalRef(pContext->engine); + pContext->engine = NULL; + } + + // Check if the temp path was set. + if (M4OSA_NULL != pContext->initParams.pTempPath) + { + // Free the memory allocated for the temp path. + videoEditOsal_free(pContext->initParams.pTempPath); + pContext->initParams.pTempPath = M4OSA_NULL; + } + + // Check if the file writer was set. + if (M4OSA_NULL != pContext->initParams.pFileWritePtr) + { + // Free the memory allocated for the file writer. + videoEditOsal_free(pContext->initParams.pFileWritePtr); + pContext->initParams.pFileWritePtr = M4OSA_NULL; + } + + // Check if the file reader was set. + if (M4OSA_NULL != pContext->initParams.pFileReadPtr) + { + // Free the memory allocated for the file reader. + videoEditOsal_free(pContext->initParams.pFileReadPtr); + pContext->initParams.pFileReadPtr = M4OSA_NULL; + } + + // Free the memory allocated for the context. + videoEditOsal_free(pContext); + pContext = M4OSA_NULL; + + // Reset the context pointer. + (*ppContext) = M4OSA_NULL; + } +} + +static jobject +videoEditor_getVersion( + JNIEnv* pEnv, + jobject thiz) +{ + bool isSuccessful = true; + jobject version = NULL; + M4_VersionInfo versionInfo = {0, 0, 0, 0}; + M4OSA_ERR result = M4NO_ERROR; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getVersion()"); + + versionInfo.m_structSize = sizeof(versionInfo); + versionInfo.m_major = VIDEOEDITOR_VERSION_MAJOR; + versionInfo.m_minor = VIDEOEDITOR_VERSION_MINOR; + versionInfo.m_revision = VIDEOEDITOR_VERSION_REVISION; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getVersion() major %d,\ + minor %d, revision %d", versionInfo.m_major, versionInfo.m_minor, versionInfo.m_revision); + + // Create a version object. + videoEditClasses_createVersion(&isSuccessful, pEnv, &versionInfo, &version); + + // Return the version object. + return(version); +} + +static void +videoEditor_init( + JNIEnv* pEnv, + jobject thiz, + jstring tempPath, + jstring libraryPath) +{ + bool initialized = true; + ManualEditContext* pContext = M4OSA_NULL; + VideoEditJava_EngineMethodIds methodIds = {NULL}; + M4OSA_Char* pLibraryPath = M4OSA_NULL; + M4OSA_Char* pTextRendererPath = M4OSA_NULL; + M4OSA_UInt32 textRendererPathLength = 0; + M4OSA_ERR result = M4NO_ERROR; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_init()"); + + // Add a text marker (the condition must always be true). + ADD_TEXT_MARKER_FUN(NULL != pEnv) + + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&initialized, pEnv, thiz); + + // Get the engine method ids. + videoEditJava_getEngineMethodIds(&initialized, pEnv, &methodIds); + + // Validate the tempPath parameter. + videoEditJava_checkAndThrowIllegalArgumentException(&initialized, pEnv, + (NULL == tempPath), + "tempPath is null"); + + // Make sure that the context was not set already. + videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv, + (M4OSA_NULL != pContext), + "already initialized"); + + // Check if the initialization succeeded (required because of dereferencing of psContext, + // and freeing when initialization fails). + if (initialized) + { + // Allocate a new context. + pContext = new ManualEditContext; + + // Check if the initialization succeeded (required because of dereferencing of psContext). + //if (initialized) + if (pContext != NULL) + { + // Set the state to not initialized. + pContext->state = ManualEditState_NOT_INITIALIZED; + + // Allocate a file read pointer structure. + pContext->initParams.pFileReadPtr = + (M4OSA_FileReadPointer*)videoEditOsal_alloc(&initialized, pEnv, + sizeof(M4OSA_FileReadPointer), "FileReadPointer"); + + // Allocate a file write pointer structure. + pContext->initParams.pFileWritePtr = + (M4OSA_FileWriterPointer*)videoEditOsal_alloc(&initialized, pEnv, + sizeof(M4OSA_FileWriterPointer), "FileWriterPointer"); + + // Get the temp path. + M4OSA_Char* tmpString = + (M4OSA_Char *)videoEditJava_getString(&initialized, pEnv, tempPath, + NULL, M4OSA_NULL); + pContext->initParams.pTempPath = (M4OSA_Char *) + M4OSA_malloc(M4OSA_chrLength(tmpString) + 1, 0x0, + (M4OSA_Char *)"tempPath"); + //initialize the first char. so that strcat works. + M4OSA_Char *ptmpChar = (M4OSA_Char*)pContext->initParams.pTempPath; + ptmpChar[0] = 0x00; + M4OSA_chrNCat((M4OSA_Char*)pContext->initParams.pTempPath, tmpString, M4OSA_chrLength(tmpString)); + M4OSA_chrNCat((M4OSA_Char*)pContext->initParams.pTempPath, (M4OSA_Char*)"/", 1); + M4OSA_free((M4OSA_MemAddr32)tmpString); + } + + // Check if the initialization succeeded + // (required because of dereferencing of pContext, pFileReadPtr and pFileWritePtr). + if (initialized) + { + + // Initialize the OSAL file system function pointers. + videoEditOsal_getFilePointers(pContext->initParams.pFileReadPtr , + pContext->initParams.pFileWritePtr); + + // Set the UTF8 conversion functions. + pContext->initParams.pConvToUTF8Fct = videoEditor_toUTF8Fct; + pContext->initParams.pConvFromUTF8Fct = videoEditor_fromUTF8Fct; + + // Set the callback method ids. + pContext->onProgressUpdateMethodId = methodIds.onProgressUpdate; + + // Set the virtual machine. + pEnv->GetJavaVM(&(pContext->pVM)); + + // Create a global reference to the engine object. + pContext->engine = pEnv->NewGlobalRef(thiz); + + // Check if the global reference could be created. + videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv, + (NULL == pContext->engine), M4NO_ERROR); + } + + // Check if the initialization succeeded (required because of dereferencing of pContext). + if (initialized) + { + // Log the API call. + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4xVSS_Init()"); + + // Initialize the visual studio library. + result = M4xVSS_Init(&pContext->engineContext, &pContext->initParams); + + // Log the result. + VIDEOEDIT_LOG_RESULT(ANDROID_LOG_INFO, "VIDEO_EDITOR", + videoEditOsal_getResultString(result)); + + // Check if the library could be initialized. + videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv, + (M4NO_ERROR != result), result); + } + + if(initialized) + { + pContext->mPreviewController = new VideoEditorPreviewController(); + videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv, + (M4OSA_NULL == pContext->mPreviewController), + "not initialized"); + pContext->mAudioSettings = + (M4xVSS_AudioMixingSettings *) + M4OSA_malloc(sizeof(M4xVSS_AudioMixingSettings),0x0, + (M4OSA_Char *)"mAudioSettings"); + videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv, + (M4OSA_NULL == pContext->mAudioSettings), + "not initialized"); + pContext->mAudioSettings->pFile = M4OSA_NULL; + pContext->mAudioSettings->bRemoveOriginal = 0; + pContext->mAudioSettings->uiNbChannels = 0; + pContext->mAudioSettings->uiSamplingFrequency = 0; + pContext->mAudioSettings->uiExtendedSamplingFrequency = 0; + pContext->mAudioSettings->uiAddCts = 0; + pContext->mAudioSettings->uiAddVolume = 0; + pContext->mAudioSettings->beginCutMs = 0; + pContext->mAudioSettings->endCutMs = 0; + pContext->mAudioSettings->fileType = 0; + pContext->mAudioSettings->bLoop = 0; + pContext->mAudioSettings->uiInDucking_lowVolume = 0; + pContext->mAudioSettings->bInDucking_enable = 0; + pContext->mAudioSettings->uiBTChannelCount = 0; + pContext->mAudioSettings->uiInDucking_threshold = 0; + } + // Check if the library could be initialized. + if (initialized) + { + // Set the state to initialized. + pContext->state = ManualEditState_INITIALIZED; + } + + // Set the context. + videoEditClasses_setContext(&initialized, pEnv, thiz, (void* )pContext); + pLibraryPath = M4OSA_NULL; + + pContext->pEditSettings = M4OSA_NULL; + // Cleanup if anything went wrong during initialization. + if (!initialized) + { + // Free the context. + videoEditor_freeContext(pEnv, &pContext); + } + } +} + +/*+ PROGRESS CB */ +static +M4OSA_ERR videoEditor_processClip( + JNIEnv* pEnv, + jobject thiz, + int unuseditemID) { + + bool loaded = true; + ManualEditContext* pContext = NULL; + M4OSA_UInt8 progress = 0; + M4OSA_UInt8 progressBase = 0; + M4OSA_UInt8 lastProgress = 0; + M4OSA_ERR result = M4NO_ERROR; + + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + + // We start in Analyzing state + pContext->state = ManualEditState_ANALYZING; + M4OSA_ERR completionResult = M4VSS3GPP_WAR_ANALYZING_DONE; + ManualEditState completionState = ManualEditState_OPENED; + ManualEditState errorState = ManualEditState_ANALYZING_ERROR; + + // While analyzing progress goes from 0 to 50 + progressBase = 0; + + // Set the text rendering function. + if (M4OSA_NULL != pContext->pTextRendererFunction) + { + // Use the text renderer function in the library. + pContext->pEditSettings->xVSS.pTextRenderingFct = pContext->pTextRendererFunction; + } + else + { + // Use the internal text renderer function. + pContext->pEditSettings->xVSS.pTextRenderingFct = videoEditor_getTextRgbBufferFct; + } + + // Send the command. + LOGV("videoEditor_processClip ITEM %d Calling M4xVSS_SendCommand()", unuseditemID); + result = M4xVSS_SendCommand(pContext->engineContext, pContext->pEditSettings); + LOGV("videoEditor_processClip ITEM %d M4xVSS_SendCommand() returned 0x%x", + unuseditemID, (unsigned int) result); + + // Remove warnings indications (we only care about errors here) + if ((result == M4VSS3GPP_WAR_TRANSCODING_NECESSARY) + || (result == M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED)) { + result = M4NO_ERROR; + } + + // Send the first progress indication (=0) + LOGV("VERY FIRST PROGRESS videoEditor_processClip ITEM %d Progress indication %d", + unuseditemID, progress); + pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId, + unuseditemID, progress); + + // Check if a task is being performed. + // ??? ADD STOPPING MECHANISM + LOGV("videoEditor_processClip Entering processing loop"); + while((result == M4NO_ERROR) + &&(pContext->state!=ManualEditState_SAVED) + &&(pContext->state!=ManualEditState_STOPPING)) { + + // Perform the next processing step. + //LOGV("LVME_processClip Entering M4xVSS_Step()"); + result = M4xVSS_Step(pContext->engineContext, &progress); + //LOGV("LVME_processClip M4xVSS_Step() returned 0x%x", (unsigned int)result); + + // Log the the 1 % .. 100 % progress after processing. + progress = progressBase + progress/2; + if (progress != lastProgress) + { + // Send a progress notification. + LOGV("videoEditor_processClip ITEM %d Progress indication %d", + unuseditemID, progress); + pEnv->CallVoidMethod(pContext->engine, + pContext->onProgressUpdateMethodId, + unuseditemID, progress); + lastProgress = progress; + } + + // Check if processing has been completed. + if (result == completionResult) + { + // Set the state to the completions state. + pContext->state = completionState; + LOGV("videoEditor_processClip ITEM %d STATE changed to %d", + unuseditemID, pContext->state); + + // Reset progress indication, as we switch to next state + lastProgress = 0; + + // Reset error code, as we start a new round of processing + result = M4NO_ERROR; + + // Check if we are analyzing input + if (pContext->state == ManualEditState_OPENED) { + // File is opened, we must start saving it + LOGV("videoEditor_processClip Calling M4xVSS_SaveStart()"); + result = M4xVSS_SaveStart(pContext->engineContext, + (M4OSA_Char*)pContext->pEditSettings->pOutputFile, + (M4OSA_UInt32)pContext->pEditSettings->uiOutputPathSize); + LOGV("videoEditor_processClip ITEM %d SaveStart() returned 0x%x", + unuseditemID, (unsigned int) result); + + // Set the state to saving. + pContext->state = ManualEditState_SAVING; + completionState = ManualEditState_SAVED; + completionResult = M4VSS3GPP_WAR_SAVING_DONE; + errorState = ManualEditState_SAVING_ERROR; + + // While saving progress goes from 50 to 100 + progressBase = 50; + } + // Check if we encoding is ongoing + else if (pContext->state == ManualEditState_SAVED) { + if (progress != 100) { + // Send a progress notification. + progress = 100; + LOGI("videoEditor_processClip ITEM %d Last progress indication %d", + unuseditemID, progress); + pEnv->CallVoidMethod(pContext->engine, + pContext->onProgressUpdateMethodId, + unuseditemID, progress); + } + + // Stop the encoding. + LOGV("videoEditor_processClip Calling M4xVSS_SaveStop()"); + result = M4xVSS_SaveStop(pContext->engineContext); + LOGV("videoEditor_processClip M4xVSS_SaveStop() returned 0x%x", result); + } + // Other states are unexpected + else { + result = M4ERR_STATE; + LOGE("videoEditor_processClip ITEM %d State ERROR 0x%x", + unuseditemID, (unsigned int) result); + } + } + + // Check if an error occurred. + if (result != M4NO_ERROR) + { + // Set the state to the error state. + pContext->state = errorState; + + // Log the result. + LOGE("videoEditor_processClip ITEM %d Processing ERROR 0x%x", + unuseditemID, (unsigned int) result); + } + } + + // Return the error result + LOGE("videoEditor_processClip ITEM %d END 0x%x", unuseditemID, (unsigned int) result); + return result; +} +/*+ PROGRESS CB */ + +static int +videoEditor_generateClip( + JNIEnv* pEnv, + jobject thiz, + jobject settings) { + bool loaded = true; + ManualEditContext* pContext = M4OSA_NULL; + M4OSA_ERR result = M4NO_ERROR; + + LOGV("videoEditor_generateClip START"); + + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz); + + Mutex::Autolock autoLock(pContext->mLock); + + // Validate the settings parameter. + videoEditJava_checkAndThrowIllegalArgumentException(&loaded, pEnv, + (NULL == settings), + "settings is null"); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + + // Load the clip settings + LOGV("videoEditor_generateClip Calling videoEditor_loadSettings"); + videoEditor_loadSettings(pEnv, thiz, settings); + LOGV("videoEditor_generateClip videoEditor_loadSettings returned"); + + // Generate the clip + LOGV("videoEditor_generateClip Calling LVME_processClip"); + result = videoEditor_processClip(pEnv, thiz, 0 /*item id is unused*/); + LOGV("videoEditor_generateClip videoEditor_processClip returned 0x%x", result); + + // Free up memory (whatever the result) + videoEditor_unloadSettings(pEnv, thiz); + //LVME_release(pEnv, thiz); + + LOGV("videoEditor_generateClip END 0x%x", (unsigned int) result); + return result; +} + +static void +videoEditor_loadSettings( + JNIEnv* pEnv, + jobject thiz, + jobject settings) +{ + bool needToBeLoaded = true; + ManualEditContext* pContext = M4OSA_NULL; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_loadSettings()"); + + // Add a code marker (the condition must always be true). + ADD_CODE_MARKER_FUN(NULL != pEnv) + + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, + pEnv, thiz); + + // Validate the settings parameter. + videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, + (NULL == settings), + "settings is null"); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + + // Check if the context is valid (required because the context is dereferenced). + if (needToBeLoaded) + { + // Make sure that we are in a correct state. + videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, + (pContext->state != ManualEditState_INITIALIZED), + "settings already loaded"); + + // Retrieve the edit settings. + if(pContext->pEditSettings != M4OSA_NULL) { + videoEditClasses_freeEditSettings(&pContext->pEditSettings); + pContext->pEditSettings = M4OSA_NULL; + } + videoEditClasses_getEditSettings(&needToBeLoaded, pEnv, settings, + &pContext->pEditSettings,true); + } + + // Check if the edit settings could be retrieved. + if (needToBeLoaded) + { + // Log the edit settings. + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "inside load settings"); + VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings); + } + LOGV("videoEditor_loadSettings END"); +} + + + +static void +videoEditor_unloadSettings( + JNIEnv* pEnv, + jobject thiz) +{ + bool needToBeUnLoaded = true; + ManualEditContext* pContext = M4OSA_NULL; + M4OSA_ERR result = M4NO_ERROR; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_unloadSettings()"); + + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeUnLoaded, pEnv, thiz); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + + // Check if the context is valid (required because the context is dereferenced). + if (needToBeUnLoaded) + { + LOGV("videoEditor_unloadSettings state %d", pContext->state); + // Make sure that we are in a correct state. + videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv, + ((pContext->state != ManualEditState_ANALYZING ) && + (pContext->state != ManualEditState_ANALYZING_ERROR) && + (pContext->state != ManualEditState_OPENED ) && + (pContext->state != ManualEditState_SAVING_ERROR ) && + (pContext->state != ManualEditState_SAVED ) && + (pContext->state != ManualEditState_STOPPING ) ), + "videoEditor_unloadSettings no load settings in progress"); + } + + // Check if we are in a correct state. + if (needToBeUnLoaded) + { + // Check if the thread could be stopped. + if (needToBeUnLoaded) + { + // Close the command. + LOGV("videoEditor_unloadSettings Calling M4xVSS_CloseCommand()"); + result = M4xVSS_CloseCommand(pContext->engineContext); + LOGV("videoEditor_unloadSettings M4xVSS_CloseCommand() returned 0x%x", + (unsigned int)result); + + // Check if the command could be closed. + videoEditJava_checkAndThrowRuntimeException(&needToBeUnLoaded, pEnv, + (M4NO_ERROR != result), result); + } + + // Check if the command could be closed. + if (needToBeUnLoaded) + { + // Free the edit settings. + //videoEditClasses_freeEditSettings(&pContext->pEditSettings); + + // Reset the thread result. + pContext->threadResult = M4NO_ERROR; + + // Reset the thread progress. + pContext->threadProgress = 0; + + // Set the state to initialized. + pContext->state = ManualEditState_INITIALIZED; + } + } +} + +static void +videoEditor_stopEncoding( + JNIEnv* pEnv, + jobject thiz) +{ + bool stopped = true; + ManualEditContext* pContext = M4OSA_NULL; + M4OSA_ERR result = M4NO_ERROR; + + LOGV("videoEditor_stopEncoding START"); + + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&stopped, pEnv, thiz); + + // Change state and get Lock + // This will ensure the generateClip function exits + pContext->state = ManualEditState_STOPPING; + Mutex::Autolock autoLock(pContext->mLock); + + // Make sure that the context was set. + videoEditJava_checkAndThrowIllegalStateException(&stopped, pEnv, + (M4OSA_NULL == pContext), + "not initialized"); + + if (stopped) { + + // Check if the command should be closed. + if (pContext->state != ManualEditState_INITIALIZED) + { + // Close the command. + LOGV("videoEditor_stopEncoding Calling M4xVSS_CloseCommand()"); + result = M4xVSS_CloseCommand(pContext->engineContext); + LOGV("videoEditor_stopEncoding M4xVSS_CloseCommand() returned 0x%x", + (unsigned int)result); + } + + // Check if the command could be closed. + videoEditJava_checkAndThrowRuntimeException(&stopped, pEnv, + (M4NO_ERROR != result), result); + + // Free the edit settings. + videoEditClasses_freeEditSettings(&pContext->pEditSettings); + + // Set the state to initialized. + pContext->state = ManualEditState_INITIALIZED; + } + +} + +static void +videoEditor_release( + JNIEnv* pEnv, + jobject thiz) +{ + bool released = true; + ManualEditContext* pContext = M4OSA_NULL; + M4OSA_ERR result = M4NO_ERROR; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_release()"); + + // Add a text marker (the condition must always be true). + ADD_TEXT_MARKER_FUN(NULL != pEnv) + + // Get the context. + pContext = (ManualEditContext*)videoEditClasses_getContext(&released, pEnv, thiz); + + // If context is not set, return (we consider release already happened) + if (pContext == NULL) { + LOGV("videoEditor_release Nothing to do, context is aleady NULL"); + return; + } + + + // Check if the context is valid (required because the context is dereferenced). + if (released) + { + if (pContext->state != ManualEditState_INITIALIZED) + { + // Change state and get Lock + // This will ensure the generateClip function exits if it is running + pContext->state = ManualEditState_STOPPING; + Mutex::Autolock autoLock(pContext->mLock); + } + + // Reset the context. + videoEditClasses_setContext(&released, pEnv, thiz, (void *)M4OSA_NULL); + + // Check if the command should be closed. + if (pContext->state != ManualEditState_INITIALIZED) + { + // Close the command. + LOGV("videoEditor_release Calling M4xVSS_CloseCommand() state =%d", + pContext->state); + result = M4xVSS_CloseCommand(pContext->engineContext); + LOGV("videoEditor_release M4xVSS_CloseCommand() returned 0x%x", + (unsigned int)result); + + // Check if the command could be closed. + videoEditJava_checkAndThrowRuntimeException(&released, pEnv, + (M4NO_ERROR != result), result); + } + + // Cleanup the engine. + LOGV("videoEditor_release Calling M4xVSS_CleanUp()"); + result = M4xVSS_CleanUp(pContext->engineContext); + LOGV("videoEditor_release M4xVSS_CleanUp() returned 0x%x", (unsigned int)result); + + // Check if the cleanup succeeded. + videoEditJava_checkAndThrowRuntimeException(&released, pEnv, + (M4NO_ERROR != result), result); + + // Free the edit settings. + videoEditClasses_freeEditSettings(&pContext->pEditSettings); + pContext->pEditSettings = M4OSA_NULL; + + + if(pContext->mPreviewController != M4OSA_NULL) + { + delete pContext->mPreviewController; + pContext->mPreviewController = M4OSA_NULL; + } + + // Free the context. + if(pContext->mAudioSettings != M4OSA_NULL) + { + M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings); + pContext->mAudioSettings = M4OSA_NULL; + } + videoEditor_freeContext(pEnv, &pContext); + } +} + +static int +videoEditor_registerManualEditMethods( + JNIEnv* pEnv) +{ + int result = -1; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_registerManualEditMethods()"); + + // Look up the engine class + jclass engineClazz = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME); + + // Clear any resulting exceptions. + pEnv->ExceptionClear(); + + // Check if the engine class was found. + if (NULL != engineClazz) + { + // Register all the methods. + if (pEnv->RegisterNatives(engineClazz, gManualEditMethods, + sizeof(gManualEditMethods) / sizeof(gManualEditMethods[0])) == JNI_OK) + { + // Success. + result = 0; + } + } + + // Return the result. + return(result); +} + +/*******Audio Graph*******/ + +static M4OSA_UInt32 getDecibelSound(M4OSA_UInt32 value) +{ + int dbSound = 1; + + if (value == 0) return 0; + + if (value > 0x4000 && value <= 0x8000) // 32768 + dbSound = 90; + else if (value > 0x2000 && value <= 0x4000) // 16384 + dbSound = 84; + else if (value > 0x1000 && value <= 0x2000) // 8192 + dbSound = 78; + else if (value > 0x0800 && value <= 0x1000) // 4028 + dbSound = 72; + else if (value > 0x0400 && value <= 0x0800) // 2048 + dbSound = 66; + else if (value > 0x0200 && value <= 0x0400) // 1024 + dbSound = 60; + else if (value > 0x0100 && value <= 0x0200) // 512 + dbSound = 54; + else if (value > 0x0080 && value <= 0x0100) // 256 + dbSound = 48; + else if (value > 0x0040 && value <= 0x0080) // 128 + dbSound = 42; + else if (value > 0x0020 && value <= 0x0040) // 64 + dbSound = 36; + else if (value > 0x0010 && value <= 0x0020) // 32 + dbSound = 30; + else if (value > 0x0008 && value <= 0x0010) //16 + dbSound = 24; + else if (value > 0x0007 && value <= 0x0008) //8 + dbSound = 24; + else if (value > 0x0003 && value <= 0x0007) // 4 + dbSound = 18; + else if (value > 0x0001 && value <= 0x0003) //2 + dbSound = 12; + else if (value > 0x000 && value == 0x0001) // 1 + dbSound = 6; + else + dbSound = 0; + + return dbSound; +} + +typedef struct +{ + M4OSA_UInt8 *m_dataAddress; + M4OSA_UInt32 m_bufferSize; +} M4AM_Buffer; + + +M4OSA_UInt8 logLookUp[256]{ +0,120,137,146,154,159,163,167,171,173,176,178,181,182,184,186,188,189,190,192,193, +194,195,196,198,199,199,200,201,202,203,204,205,205,206,207,207,208,209,209,210, +211,211,212,212,213,213,214,215,215,216,216,216,217,217,218,218,219,219,220,220, +220,221,221,222,222,222,223,223,223,224,224,224,225,225,225,226,226,226,227,227, +227,228,228,228,229,229,229,229,230,230,230,230,231,231,231,232,232,232,232,233, +233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236,236,237,237,237, +237,237,238,238,238,238,238,239,239,239,239,239,240,240,240,240,240,240,241,241, +241,241,241,241,242,242,242,242,242,242,243,243,243,243,243,243,244,244,244,244, +244,244,245,245,245,245,245,245,245,246,246,246,246,246,246,246,247,247,247,247, +247,247,247,247,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,250, +250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,252,252,252,252, +252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254, +254,254,254,254,255,255,255,255,255,255,255,255,255,255,255}; + +M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL, + M4OSA_Char* pOutFileURL, + M4OSA_UInt32 samplesPerValue, + M4OSA_UInt32 channels, + M4OSA_UInt32 frameDuration, + ManualEditContext* pContext) +{ + M4OSA_ERR err; + M4OSA_Context outFileHandle = M4OSA_NULL; + M4OSA_Context inputFileHandle = M4OSA_NULL; + M4AM_Buffer bufferIn = {0, 0}; + M4OSA_UInt32 peakVolumeDbValue = 0; + M4OSA_UInt32 samplesCountInBytes= 0 , numBytesToRead = 0, index = 0; + M4OSA_UInt32 writeCount = 0, samplesCountBigEndian = 0, volumeValuesCount = 0; + M4OSA_Int32 seekPos = 0; + M4OSA_UInt32 fileSize = 0; + M4OSA_UInt32 totalBytesRead = 0; + M4OSA_UInt32 prevProgress = 0; + bool threadStarted = true; + + int dbValue = 0; + M4OSA_Int16 *ptr16 ; + + jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME); + videoEditJava_checkAndThrowIllegalStateException(&threadStarted, pEnv, + (M4OSA_NULL == engineClass), + "not initialized"); + + /* register the call back function pointer */ + pContext->onAudioGraphProgressUpdateMethodId = + pEnv->GetMethodID(engineClass, "onAudioGraphExtractProgressUpdate", "(IZ)V"); + + + /* ENTER */ + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "ENTER - M4MA_generateAudioGraphFile"); + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "Audio Graph samplesPerValue %d channels %d", samplesPerValue, channels); + + /****************************************************************************** + OPEN INPUT AND OUTPUT FILES + *******************************************************************************/ + err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead); + if (inputFileHandle == M4OSA_NULL) { + VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "M4MA_generateAudioGraphFile: Cannot open input file 0x%x", err); + return err; + } + + /* get the file size for progress */ + err = M4OSA_fileReadGetOption(inputFileHandle, M4OSA_kFileReadGetFileSize, + (M4OSA_Void**)&fileSize); + if ( err != M4NO_ERROR) { + //LVMEL_LOG_ERROR("M4MA_generateAudioGraphFile : File write failed \n"); + jniThrowException(pEnv, "java/lang/IOException", "file size get option failed"); + //return -1; + } + + err = M4OSA_fileWriteOpen (&outFileHandle,(M4OSA_Char*) pOutFileURL, + M4OSA_kFileCreate | M4OSA_kFileWrite); + if (outFileHandle == M4OSA_NULL) { + if (inputFileHandle != NULL) + { + M4OSA_fileReadClose(inputFileHandle); + } + return err; + } + + /****************************************************************************** + PROCESS THE SAMPLES + *******************************************************************************/ + samplesCountInBytes = (samplesPerValue * sizeof(M4OSA_UInt16) * channels); + + bufferIn.m_dataAddress = (M4OSA_UInt8*)M4OSA_malloc(samplesCountInBytes*sizeof(M4OSA_UInt16), 0, + (M4OSA_Char*)"AudioGraph" ); + if ( bufferIn.m_dataAddress != M4OSA_NULL) { + bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16); + } else { + VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%x",\ + M4ERR_ALLOC); + return M4ERR_ALLOC; + } + /* sample to be converted to BIG endian ; store the frame duration */ + samplesCountBigEndian = ((frameDuration>>24)&0xff) | // move byte 3 to byte 0 + ((frameDuration<<8)&0xff0000) | // move byte 1 to byte 2 + ((frameDuration>>8)&0xff00) | // move byte 2 to byte 1 + ((frameDuration<<24)&0xff000000); // byte 0 to byte 3 + + /* write the samples per value supplied to out file */ + err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian, + sizeof(M4OSA_UInt32) ); + if (err != M4NO_ERROR) { + jniThrowException(pEnv, "java/lang/IOException", "file write failed"); + } + + + /* write UIn32 value 0 for no of values as place holder */ + samplesCountBigEndian = 0; /* reusing local var */ + err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian, + sizeof(M4OSA_UInt32) ); + if (err != M4NO_ERROR) { + jniThrowException(pEnv, "java/lang/IOException", "file write failed"); + } + + /* loop until EOF */ + do + { + M4OSA_memset((M4OSA_MemAddr8)bufferIn.m_dataAddress,bufferIn.m_bufferSize, 0); + + numBytesToRead = samplesCountInBytes; + + err = M4OSA_fileReadData( inputFileHandle, + (M4OSA_MemAddr8)bufferIn.m_dataAddress, + &numBytesToRead ); + + if (err != M4NO_ERROR) { + // if out value of bytes-read is 0, break + if ( numBytesToRead == 0) { + VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%x",\ + numBytesToRead); + break; /* stop if file is empty or EOF */ + } + } + + ptr16 = (M4OSA_Int16*)bufferIn.m_dataAddress; + + peakVolumeDbValue = 0; + index = 0; + + // loop through half the lenght frame bytes read 'cause its 16 bits samples + while (index < (numBytesToRead / 2)) { + /* absolute values of 16 bit sample */ + if (ptr16[index] < 0) { + ptr16[index] = -(ptr16[index]); + } + peakVolumeDbValue = (peakVolumeDbValue > (M4OSA_UInt32)ptr16[index] ?\ + peakVolumeDbValue : (M4OSA_UInt32)ptr16[index]); + index++; + } + + // move 7 bits , ignore sign bit + dbValue = (peakVolumeDbValue >> 7); + dbValue = logLookUp[(M4OSA_UInt8)dbValue]; + + err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&dbValue, sizeof(M4OSA_UInt8) ); + if (err != M4NO_ERROR) { + VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "M4MA_generateAudioGraphFile : File write failed"); + break; + } + + volumeValuesCount ++; + totalBytesRead += numBytesToRead; + + if ((((totalBytesRead*100)/fileSize)) != prevProgress) { + if ( (pContext->threadProgress != prevProgress) && (prevProgress != 0 )) { + //pContext->threadProgress = prevProgress; + //onWveformProgressUpdateMethodId(prevProgress, 0); + //LVME_callAudioGraphOnProgressUpdate(pContext, 0, prevProgress); + pEnv->CallVoidMethod(pContext->engine, + pContext->onAudioGraphProgressUpdateMethodId, + prevProgress, 0); + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pContext->threadProgress %d", + prevProgress); + } + } + prevProgress = (((totalBytesRead*100)/fileSize)); + + } while (numBytesToRead != 0); + + VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%x", volumeValuesCount); + + /* if some error occured in fwrite */ + if (numBytesToRead != 0) { + //err = -1; + jniThrowException(pEnv, "java/lang/IOException", "numBytesToRead != 0 ; file write failed"); + } + + /* write the count in place holder after seek */ + seekPos = sizeof(M4OSA_UInt32); + err = M4OSA_fileWriteSeek(outFileHandle, M4OSA_kFileSeekBeginning, + &seekPos /* after samples per value */); + if ( err != M4NO_ERROR) { + jniThrowException(pEnv, "java/lang/IOException", "file seek failed"); + } else { + volumeValuesCount = ((volumeValuesCount>>24)&0xff) | // move byte 3 to byte 0 + ((volumeValuesCount<<8)&0xff0000) | // move byte 1 to byte 2 + ((volumeValuesCount>>8)&0xff00) | // move byte 2 to byte 1 + ((volumeValuesCount<<24)&0xff000000); // byte 0 to byte 3 + + err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&volumeValuesCount, + sizeof(M4OSA_UInt32) ); + if ( err != M4NO_ERROR) { + jniThrowException(pEnv, "java/lang/IOException", "file write failed"); + } + } + + /****************************************************************************** + CLOSE AND FREE ALLOCATIONS + *******************************************************************************/ + M4OSA_free((M4OSA_MemAddr32)bufferIn.m_dataAddress); + M4OSA_fileReadClose(inputFileHandle); + M4OSA_fileWriteClose(outFileHandle); + /* final finish callback */ + pEnv->CallVoidMethod(pContext->engine, pContext->onAudioGraphProgressUpdateMethodId, 100, 0); + + /* EXIT */ + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "EXIT - M4MA_generateAudioGraphFile"); + + return err; +} + +static int videoEditor_generateAudioWaveFormSync (JNIEnv* pEnv, jobject thiz, + jstring pcmfilePath, + jstring outGraphfilePath, + jint frameDuration, jint channels, + jint samplesCount) +{ + M4OSA_ERR result = M4NO_ERROR; + ManualEditContext* pContext = M4OSA_NULL; + bool needToBeLoaded = true; + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_generateAudioWaveFormSync() "); + + /* Get the context. */ + pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); + if (pContext == M4OSA_NULL) { + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_generateAudioWaveFormSync() - pContext is NULL "); + } + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_generateAudioWaveFormSync Retrieving pStringOutAudioGraphFile"); + + const char *pPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL); + if (pPCMFilePath == M4OSA_NULL) { + if (pEnv != NULL) { + jniThrowException(pEnv, "java/lang/RuntimeException", + "Input string PCMFilePath is null"); + } + } + + const char *pStringOutAudioGraphFile = pEnv->GetStringUTFChars(outGraphfilePath, NULL); + if (pStringOutAudioGraphFile == M4OSA_NULL) { + if (pEnv != NULL) { + jniThrowException(pEnv, "java/lang/RuntimeException", + "Input string outGraphfilePath is null"); + } + } + + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_generateAudioWaveFormSync Generate the waveform data %s %d %d %d", + pStringOutAudioGraphFile, frameDuration, channels, samplesCount); + + /* Generate the waveform */ + result = M4MA_generateAudioGraphFile(pEnv, (M4OSA_Char*) pPCMFilePath, + (M4OSA_Char*) pStringOutAudioGraphFile, + (M4OSA_UInt32) samplesCount, + (M4OSA_UInt32) channels, + (M4OSA_UInt32)frameDuration, + pContext); + + if (pStringOutAudioGraphFile != NULL) { + pEnv->ReleaseStringUTFChars(outGraphfilePath, pStringOutAudioGraphFile); + } + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", + "videoEditor_generateAudioWaveFormSync pContext->bSkipState "); + + return result; +} + +/******** End Audio Graph *******/ +jint JNI_OnLoad( + JavaVM* pVm, + void* pReserved) +{ + void* pEnv = NULL; + bool needToBeInitialized = true; + jint result = -1; + + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "JNI_OnLoad()"); + + // Add a text marker (the condition must always be true). + ADD_TEXT_MARKER_FUN(NULL != pVm) + + // Check the JNI version. + if (pVm->GetEnv(&pEnv, JNI_VERSION_1_4) == JNI_OK) + { + // Add a code marker (the condition must always be true). + ADD_CODE_MARKER_FUN(NULL != pEnv) + + // Register the manual edit JNI methods. + if (videoEditor_registerManualEditMethods((JNIEnv*)pEnv) == 0) + { + // Initialize the classes. + videoEditClasses_init(&needToBeInitialized, (JNIEnv*)pEnv); + if (needToBeInitialized) + { + // Success, return valid version number. + result = JNI_VERSION_1_4; + } + } + } + + // Return the result. + return(result); +} + diff --git a/media/jni/mediaeditor/VideoEditorMain.h b/media/jni/mediaeditor/VideoEditorMain.h new file mode 100755 index 000000000000..b73913a07f99 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorMain.h @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#ifndef __VIDEO_EDITOR_API_H__ +#define __VIDEO_EDITOR_API_H__ + +#include "M4OSA_Types.h" + +typedef enum +{ + MSG_TYPE_PROGRESS_INDICATION, /* Playback progress indication event*/ + MSG_TYPE_PLAYER_ERROR, /* Playback error*/ + MSG_TYPE_PREVIEW_END, /* Preview of clips is complete */ +} progress_callback_msg_type; + +typedef struct +{ + M4OSA_Void *pFile; /** PCM file path */ + M4OSA_Bool bRemoveOriginal; /** If true, the original audio track + is not taken into account */ + M4OSA_UInt32 uiNbChannels; /** Number of channels (1=mono, 2=stereo) of BGM clip*/ + M4OSA_UInt32 uiSamplingFrequency; /** Sampling audio frequency (8000 for amr, 16000 or + more for aac) of BGM clip*/ + M4OSA_UInt32 uiExtendedSamplingFrequency; /** Extended frequency for AAC+, + eAAC+ streams of BGM clip*/ + M4OSA_UInt32 uiAddCts; /** Time, in milliseconds, at which the added + audio track is inserted */ + M4OSA_UInt32 uiAddVolume; /** Volume, in percentage, of the added audio track */ + M4OSA_UInt32 beginCutMs; + M4OSA_UInt32 endCutMs; + M4OSA_Int32 fileType; + M4OSA_Bool bLoop; /** Looping on/off **/ + /* Audio ducking */ + M4OSA_UInt32 uiInDucking_threshold; /** Threshold value at which + background music shall duck */ + M4OSA_UInt32 uiInDucking_lowVolume; /** lower the background track to + this factor of current level */ + M4OSA_Bool bInDucking_enable; /** enable ducking */ + M4OSA_UInt32 uiBTChannelCount; /** channel count for BT */ + M4OSA_Void *pPCMFilePath; +} M4xVSS_AudioMixingSettings; + +typedef struct +{ + M4OSA_Void *pBuffer; /* YUV420 buffer of frame to be rendered*/ + M4OSA_UInt32 timeMs; /* time stamp of the frame to be rendered*/ + M4OSA_UInt32 uiSurfaceWidth; /* Surface display width*/ + M4OSA_UInt32 uiSurfaceHeight; /* Surface display height*/ + M4OSA_UInt32 uiFrameWidth; /* Frame width*/ + M4OSA_UInt32 uiFrameHeight; /* Frame height*/ + M4OSA_Bool bApplyEffect; /* Apply video effects before render*/ + M4OSA_UInt32 clipBeginCutTime; /* Clip begin cut time relative to storyboard */ + M4OSA_UInt32 clipEndCutTime; /* Clip end cut time relative to storyboard */ + +} VideoEditor_renderPreviewFrameStr; +#endif /*__VIDEO_EDITOR_API_H__*/ diff --git a/media/jni/mediaeditor/VideoEditorOsal.cpp b/media/jni/mediaeditor/VideoEditorOsal.cpp new file mode 100755 index 000000000000..423e93f4c023 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorOsal.cpp @@ -0,0 +1,359 @@ +/* + * 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 <VideoEditorJava.h> +#include <VideoEditorLogging.h> +#include <VideoEditorOsal.h> + +extern "C" { +#include <M4OSA_Clock.h> +#include <M4OSA_CharStar.h> +#include <M4OSA_FileCommon.h> +#include <M4OSA_FileReader.h> +#include <M4OSA_FileWriter.h> +#include <M4OSA_Memory.h> +#include <M4OSA_String.h> +#include <M4OSA_Thread.h> +#include <M4xVSS_API.h> +#include <M4VSS3GPP_ErrorCodes.h> +#include <M4MCS_ErrorCodes.h> +#include <M4READER_Common.h> +#include <M4WRITER_common.h> +#include <M4VSS3GPP_API.h> +#include <M4DECODER_Common.h> +}; + + +#define VIDEOEDIT_OSAL_RESULT_STRING_MAX (32) + +#define VIDEOEDIT_OSAL_RESULT_INIT(m_result) { m_result, #m_result } + + +typedef struct +{ + M4OSA_ERR result; + const char* pName; +} VideoEdit_Osal_Result; + +static const VideoEdit_Osal_Result gkRESULTS[] = +{ + // M4OSA_Clock.h + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_TIMESCALE_TOO_BIG ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_CLOCK_BAD_REF_YEAR ), + + // M4OSA_Error.h + VIDEOEDIT_OSAL_RESULT_INIT(M4NO_ERROR ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_PARAMETER ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_STATE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_ALLOC ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_BAD_CONTEXT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_CONTEXT_FAILED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_BAD_STREAM_ID ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_BAD_OPTION_ID ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_WRITE_ONLY ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_READ_ONLY ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_NOT_IMPLEMENTED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_UNSUPPORTED_MEDIA_TYPE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_NO_DATA_YET ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_NO_MORE_STREAM ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_INVALID_TIME ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_NO_MORE_AU ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_TIME_OUT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_BUFFER_FULL ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_REDIRECT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_TOO_MUCH_STREAMS ), + + // M4OSA_FileCommon.h + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_FILE_NOT_FOUND ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_FILE_LOCKED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_FILE_BAD_MODE_ACCESS ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_FILE_INVALID_POSITION ), + + // M4OSA_String.h + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_STR_BAD_STRING ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_STR_CONV_FAILED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_STR_OVERFLOW ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_STR_BAD_ARGS ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_STR_OVERFLOW ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_STR_NOT_FOUND ), + + // M4OSA_Thread.h + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_THREAD_NOT_STARTED ), + + // M4xVSS_API.h + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_ANALYZING_DONE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_PREVIEW_READY ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_SAVING_DONE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_TRANSCODING_NECESSARY ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_JPG_TOO_BIG ), + VIDEOEDIT_OSAL_RESULT_INIT(M4xVSSWAR_BUFFER_OUT_TOO_SMALL ), + VIDEOEDIT_OSAL_RESULT_INIT(M4xVSSERR_NO_MORE_SPACE ), + + // M4VSS3GPP_ErrorCodes.h + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_FILE_TYPE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_EFFECT_KIND ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS ), +#ifdef M4VSS3GPP_ERR_ANALYSIS_DATA_SIZE_TOO_SMALL + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ANALYSIS_DATA_SIZE_TOO_SMALL ), +#endif + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_3GPP_FILE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU ), +#ifdef M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU ), +#endif + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION ), +#ifdef M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_PLATFORM + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_PLATFORM ), +#endif + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_BEGINLOOP_HIGHER_ENDLOOP ), +#ifdef M4VSS3GPP_ERR_AUDIO_MIXING_MP3_UNSUPPORTED + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_MIXING_MP3_UNSUPPORTED ), +#endif +#ifdef M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AAC + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AAC ), +#endif +#ifdef M4VSS3GPP_ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED ), +#endif +#ifdef M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_EVRC + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_EVRC ), +#endif + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INTERNAL_STATE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_LUMA_FILTER_ERROR ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_CURTAIN_FILTER_ERROR ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_TRANSITION_FILTER_ERROR ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_DECODER_INIT_FAILED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_DECODED_PCM_SIZE_ISSUE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_OUTPUT_FILE_TYPE_ERROR ), + + // M4MCS_ErrorCodes.h + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_WAR_TRANSCODING_DONE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INVALID_INPUT_FILE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263 ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263 ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_DURATION_IS_NULL ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_AUDIO_CONVERSION_FAILED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_MAXFILESIZE_TOO_SMALL ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_VIDEOBITRATE_TOO_LOW ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_AUDIOBITRATE_TOO_LOW ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_VIDEOBITRATE_TOO_HIGH ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_AUDIOBITRATE_TOO_HIGH ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL ), + VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_NOMORE_SPACE ), + + // M4READER_Common.h + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_READER_UNKNOWN_STREAM_TYPE ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_READER_NO_METADATA ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_READER_INFORMATION_NOT_PRESENT ), + + // M4WRITER_Common.h + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_WRITER_STOP_REQ ), + // M4DECODER_Common.h + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_VIDEORENDERER_NO_NEW_FRAME ), + VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_DEBLOCKING_FILTER_NOT_IMPLEMENTED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED ), + VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_DECODER_H263_NOT_BASELINE ) +}; + +static const int gkRESULTS_COUNT = (sizeof(gkRESULTS) / sizeof(VideoEdit_Osal_Result)); + +#ifdef OSAL_MEM_LEAK_DEBUG +static int gAllocatedBlockCount = 0; +#endif + +const char* +videoEditOsal_getResultString( + M4OSA_ERR result) +{ + static char string[VIDEOEDIT_OSAL_RESULT_STRING_MAX] = ""; + const char* pString = M4OSA_NULL; + int index = 0; + + // Loop over the list with constants. + for (index = 0; + ((M4OSA_NULL == pString) && (index < gkRESULTS_COUNT)); + index++) + { + // Check if the specified result matches. + if (result == gkRESULTS[index].result) + { + // Set the description. + pString = gkRESULTS[index].pName; + } + } + + // Check if no result was found. + if (M4OSA_NULL == pString) + { + // Set the description to a default value. + M4OSA_chrSPrintf((M4OSA_Char *)string, sizeof(string) - 1, + (M4OSA_Char*)"<unknown(0x%08X)>", result); + pString = string; + } + + // Return the result. + return(pString); +} + +void * +videoEditOsal_alloc( + bool* pResult, + JNIEnv* pEnv, + size_t size, + const char* pDescription) +{ + void *pData = M4OSA_NULL; + + // Check if the previous action succeeded. + if (*pResult) + { + // Allocate memory for the settings. + pData = (M4VSS3GPP_EditSettings*)M4OSA_malloc(size, 0, (M4OSA_Char*)pDescription); + if (M4OSA_NULL != pData) + { + // Reset the allocated memory. + M4OSA_memset((M4OSA_MemAddr8)pData, size, 0); +#ifdef OSAL_MEM_LEAK_DEBUG + // Update the allocated block count. + gAllocatedBlockCount++; +#endif + } + else + { + // Reset the result flag. + (*pResult) = false; + + // Log the error. + VIDEOEDIT_LOG_ERROR(ANDROID_LOG_ERROR, "VIDEO_EDITOR_OSAL", "videoEditOsal_alloc,\ + error: unable to allocate memory for %s", pDescription); + + // Throw an exception. + jniThrowException(pEnv, "java/lang/OutOfMemoryError", "unable to allocate memory"); + } + } + + // Return the allocated memory. + return(pData); +} + +void +videoEditOsal_free( + void* pData) +{ + // Check if memory was allocated. + if (M4OSA_NULL != pData) + { + VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_OSAL", "videoEditOsal_free()"); + + // Log the API call. + VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR_OSAL", "M4OSA_free()"); + + // Free the memory. + M4OSA_free((M4OSA_MemAddr32)pData); +#ifdef OSAL_MEM_LEAK_DEBUG + // Update the allocated block count. + gAllocatedBlockCount--; + + // Log the number of allocated blocks. + VIDEOEDIT_LOG_ALLOCATION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_OSAL", "allocated, %d blocks",\ + gAllocatedBlockCount); +#endif + } +} + + +void +videoEditOsal_getFilePointers ( M4OSA_FileReadPointer *pOsaFileReadPtr, + M4OSA_FileWriterPointer *pOsaFileWritePtr) +{ + if (pOsaFileReadPtr != M4OSA_NULL) + { + // Initialize the filereader function pointers. + pOsaFileReadPtr->openRead = M4OSA_fileReadOpen; + pOsaFileReadPtr->readData = M4OSA_fileReadData; + pOsaFileReadPtr->seek = M4OSA_fileReadSeek; + pOsaFileReadPtr->closeRead = M4OSA_fileReadClose; + pOsaFileReadPtr->setOption = M4OSA_fileReadSetOption; + pOsaFileReadPtr->getOption = M4OSA_fileReadGetOption; + } + + if (pOsaFileWritePtr != M4OSA_NULL) + { + // Initialize the filewriter function pointers. + pOsaFileWritePtr->openWrite = M4OSA_fileWriteOpen; + pOsaFileWritePtr->writeData = M4OSA_fileWriteData; + pOsaFileWritePtr->seek = M4OSA_fileWriteSeek; + pOsaFileWritePtr->Flush = M4OSA_fileWriteFlush; + pOsaFileWritePtr->closeWrite = M4OSA_fileWriteClose; + pOsaFileWritePtr->setOption = M4OSA_fileWriteSetOption; + pOsaFileWritePtr->getOption = M4OSA_fileWriteGetOption; + } +} + diff --git a/media/jni/mediaeditor/VideoEditorOsal.h b/media/jni/mediaeditor/VideoEditorOsal.h new file mode 100755 index 000000000000..7a6f5ea59227 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorOsal.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#ifndef VIDEO_EDITOR_OSAL_H +#define VIDEO_EDITOR_OSAL_H + +#include <jni.h> +#include <JNIHelp.h> + +extern "C" { +#include <M4OSA_Error.h> +#include <M4OSA_Thread.h> +#include <M4OSA_FileReader.h> +#include <M4OSA_FileWriter.h> +}; + +const char* +videoEditOsal_getResultString( + M4OSA_ERR result); + +void* +videoEditOsal_alloc( + bool* pResult, + JNIEnv* pEnv, + size_t size, + const char* pDescription); + +void +videoEditOsal_free( + void* pData); + +void +videoEditOsal_startThread( + bool* pResult, + JNIEnv* pEnv, + int stackSize, + M4OSA_ThreadDoIt callback, + M4OSA_Context* pContext, + void* pParam); + +void +videoEditOsal_stopThread( + bool* pResult, + JNIEnv* pEnv, + M4OSA_Context* pContext); + +void +videoEditOsal_getFilePointers ( M4OSA_FileReadPointer *pOsaFileReadPtr, + M4OSA_FileWriterPointer *pOsaFileWritePtr); + +#endif // VIDEO_EDITOR_OSAL_H + diff --git a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp new file mode 100755 index 000000000000..7bf76da229f8 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp @@ -0,0 +1,502 @@ +/* + * 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 <dlfcn.h> +#include <stdio.h> +#include <unistd.h> +#include <utils/Log.h> +#include <utils/threads.h> +#include <VideoEditorClasses.h> +#include <VideoEditorJava.h> +#include <VideoEditorOsal.h> +#include <VideoEditorLogging.h> +#include <VideoEditorOsal.h> +#include <marker.h> + +extern "C" { +#include <M4OSA_Clock.h> +#include <M4OSA_CharStar.h> +#include <M4OSA_Error.h> +#include <M4OSA_FileCommon.h> +#include <M4OSA_FileReader.h> +#include <M4OSA_FileWriter.h> +#include <M4OSA_Memory.h> +#include <M4OSA_String.h> +#include <M4OSA_Thread.h> +#include <M4VSS3GPP_API.h> +#include <M4VSS3GPP_ErrorCodes.h> +#include <M4MCS_API.h> +#include <M4MCS_ErrorCodes.h> +#include <M4MDP_API.h> +#include <M4READER_Common.h> +#include <M4WRITER_common.h> +#include <M4DECODER_Common.h> +#include <M4AD_Common.h> +}; + +extern "C" M4OSA_ERR M4MCS_open_normalMode( + M4MCS_Context pContext, + M4OSA_Void* pFileIn, + M4VIDEOEDITING_FileType InputFileType, + M4OSA_Void* pFileOut, + M4OSA_Void* pTempFile); + +jobject videoEditProp_getProperties( + JNIEnv* pEnv, + jobject thiz, + jstring file); + +static void +getFileAndMediaTypeFromExtension ( + M4OSA_Char* pExtension, + VideoEditClasses_FileType *pFileType, + M4VIDEOEDITING_FileType *pClipType); + +static M4OSA_ERR +getClipProperties( JNIEnv* pEnv, + jobject thiz, + M4OSA_Char* pFile, + M4VIDEOEDITING_FileType clipType, + M4VIDEOEDITING_ClipProperties* pClipProperties); + +M4OSA_UInt32 +VideoEdit_chrCompare(M4OSA_Char* pStrIn1, + M4OSA_Char* pStrIn2, + M4OSA_Int32* pCmpResult); + +jobject videoEditProp_getProperties( + JNIEnv* pEnv, + jobject thiz, + jstring file) +{ + bool gotten = true; + M4OSA_Char* pFile = M4OSA_NULL; + M4OSA_Char* pExtension = M4OSA_NULL; + M4OSA_UInt32 index = 0; + M4OSA_Int32 cmpResult = 0; + VideoEditPropClass_Properties* pProperties = M4OSA_NULL; + M4VIDEOEDITING_ClipProperties* pClipProperties = M4OSA_NULL; + M4OSA_ERR result = M4NO_ERROR; + M4MCS_Context context = M4OSA_NULL; + M4OSA_FilePosition size = 0; + M4OSA_UInt32 width = 0; + M4OSA_UInt32 height = 0; + jobject properties = NULL; + M4OSA_Context pOMXContext = M4OSA_NULL; + M4DECODER_VideoInterface* pOMXVidDecoderInterface = M4OSA_NULL; + M4AD_Interface* pOMXAudDecoderInterface = M4OSA_NULL; + + bool initialized = true; + VideoEditClasses_FileType fileType = VideoEditClasses_kFileType_Unsupported; + M4VIDEOEDITING_FileType clipType = M4VIDEOEDITING_kFileType_Unsupported; + + VIDEOEDIT_LOG_API( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", + "videoEditProp_getProperties()"); + + // Add a text marker (the condition must always be true). + ADD_TEXT_MARKER_FUN(NULL != pEnv) + + // Initialize the classes. + videoEditPropClass_init(&initialized, (JNIEnv*)pEnv); + + // Validate the tempPath parameter. + videoEditJava_checkAndThrowIllegalArgumentException( + &gotten, pEnv, (NULL == file), "file is null"); + + // Get the file path. + pFile = (M4OSA_Char *)videoEditJava_getString( + &gotten, pEnv, file, NULL, M4OSA_NULL); + + result = M4OSA_fileReadOpen(&context, (M4OSA_Void*)pFile, M4OSA_kFileRead); + videoEditJava_checkAndThrowIllegalArgumentException(&gotten, pEnv, + (M4NO_ERROR != result), "file not found"); + if(M4NO_ERROR != result) + return(properties); + result = M4OSA_fileReadClose(context); + context = M4OSA_NULL; + + // Check if the file path is valid. + if (gotten) + { + // Retrieve the extension. + result = M4OSA_chrReverseFindChar(pFile, '.', &pExtension); + if ((M4NO_ERROR == result) && (M4OSA_NULL != pExtension)) + { + // Skip the dot. + pExtension++; + + // Get the file type and Media type from extension + getFileAndMediaTypeFromExtension( + pExtension ,&fileType, &clipType); + } + } + + // Check if the file type could be determined. + videoEditJava_checkAndThrowIllegalArgumentException( + &gotten, pEnv, + (VideoEditClasses_kFileType_Unsupported == fileType), + "file type is not supported"); + + // Allocate a new properties structure. + pProperties = (VideoEditPropClass_Properties*)videoEditOsal_alloc( + &gotten, pEnv, + sizeof(VideoEditPropClass_Properties), "Properties"); + + // Check if the context is valid and allocation succeeded + // (required because of dereferencing of pProperties). + if (gotten) + { + // Check if this type of file needs to be analyzed using MCS. + if ((VideoEditClasses_kFileType_MP3 == fileType) || + (VideoEditClasses_kFileType_MP4 == fileType) || + (VideoEditClasses_kFileType_3GPP == fileType) || + (VideoEditClasses_kFileType_AMR == fileType) || + (VideoEditClasses_kFileType_PCM == fileType)) + { + // Allocate a new clip properties structure. + pClipProperties = + (M4VIDEOEDITING_ClipProperties*)videoEditOsal_alloc( + &gotten, pEnv, + sizeof(M4VIDEOEDITING_ClipProperties), "ClipProperties"); + + // Check if allocation succeeded (required because of + // dereferencing of pClipProperties). + if (gotten) + { + // Add a code marker (the condition must always be true). + ADD_CODE_MARKER_FUN(NULL != pClipProperties) + + // Log the API call. + VIDEOEDIT_LOG_API( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", + "getClipProperties"); + + // Get Video clip properties + result = getClipProperties( + pEnv, thiz, pFile, clipType, pClipProperties); + + // Check if the creation succeeded. + videoEditJava_checkAndThrowIllegalArgumentException( + &gotten, pEnv,(M4NO_ERROR != result), + "Invalid File or File not found"); + + if (pClipProperties->uiVideoWidth >= 1920) + { + result = M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM; + videoEditJava_checkAndThrowIllegalArgumentException( + &gotten, pEnv, (M4NO_ERROR != result), + "HD Content (1080p) is not supported"); + } + } + + // Check if the properties could be retrieved. + if (gotten) + { + // Set the properties. + pProperties->uiClipDuration = pClipProperties->uiClipDuration; + if (M4VIDEOEDITING_kFileType_Unsupported == pClipProperties->FileType) + { + pProperties->FileType = VideoEditClasses_kFileType_Unsupported; + } + else + { + pProperties->FileType = fileType; + } + pProperties->VideoStreamType = pClipProperties->VideoStreamType; + pProperties->uiClipVideoDuration = pClipProperties->uiClipVideoDuration; + pProperties->uiVideoBitrate = pClipProperties->uiVideoBitrate; + pProperties->uiVideoWidth = pClipProperties->uiVideoWidth; + pProperties->uiVideoHeight = pClipProperties->uiVideoHeight; + pProperties->fAverageFrameRate = pClipProperties->fAverageFrameRate; + pProperties->ProfileAndLevel = pClipProperties->ProfileAndLevel; + pProperties->AudioStreamType = pClipProperties->AudioStreamType; + pProperties->uiClipAudioDuration = pClipProperties->uiClipAudioDuration; + pProperties->uiAudioBitrate = pClipProperties->uiAudioBitrate; + pProperties->uiNbChannels = pClipProperties->uiNbChannels; + pProperties->uiSamplingFrequency = pClipProperties->uiSamplingFrequency; + } + + // Free the clip properties. + videoEditOsal_free(pClipProperties); + pClipProperties = M4OSA_NULL; + } + else if ((VideoEditClasses_kFileType_JPG == fileType) || + (VideoEditClasses_kFileType_GIF == fileType) || + (VideoEditClasses_kFileType_PNG == fileType)) + { + pProperties->uiClipDuration = 0; + pProperties->FileType = fileType; + pProperties->VideoStreamType = M4VIDEOEDITING_kNoneVideo; + pProperties->uiClipVideoDuration = 0; + pProperties->uiVideoBitrate = 0; + pProperties->uiVideoWidth = width; + pProperties->uiVideoHeight = height; + pProperties->fAverageFrameRate = 0.0f; + pProperties->ProfileAndLevel = M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range; + pProperties->AudioStreamType = M4VIDEOEDITING_kNoneAudio; + pProperties->uiClipAudioDuration = 0; + pProperties->uiAudioBitrate = 0; + pProperties->uiNbChannels = 0; + pProperties->uiSamplingFrequency = 0; + + // Added for Handling invalid paths and non existent image files + // Open the file for reading. + result = M4OSA_fileReadOpen(&context, (M4OSA_Void*)pFile, M4OSA_kFileRead); + if (M4NO_ERROR != result) + { + pProperties->FileType = VideoEditClasses_kFileType_Unsupported; + } + result = M4OSA_fileReadClose(context); + context = M4OSA_NULL; + } + } + + // Create a properties object. + videoEditPropClass_createProperties(&gotten, pEnv, pProperties, &properties); + + // Log the properties. + VIDEOEDIT_PROP_LOG_PROPERTIES(pProperties); + + // Free the properties. + videoEditOsal_free(pProperties); + pProperties = M4OSA_NULL; + + // Free the file path. + videoEditOsal_free(pFile); + pFile = M4OSA_NULL; + + // Add a text marker (the condition must always be true). + ADD_TEXT_MARKER_FUN(NULL != pEnv) + + // Return the Properties object. + return(properties); +} + +static void getFileAndMediaTypeFromExtension ( + M4OSA_Char *pExtension, + VideoEditClasses_FileType *pFileType, + M4VIDEOEDITING_FileType *pClipType) +{ + M4OSA_Char extension[5] = {0, 0, 0, 0, 0}; + VideoEditClasses_FileType fileType = + VideoEditClasses_kFileType_Unsupported; + + M4VIDEOEDITING_FileType clipType = + M4VIDEOEDITING_kFileType_Unsupported; + + M4OSA_UInt32 index = 0; + M4OSA_ERR result = M4NO_ERROR; + M4OSA_Int32 cmpResult = 0; + M4OSA_UInt32 extLength = M4OSA_chrLength(pExtension); + + // Assign default + *pFileType = VideoEditClasses_kFileType_Unsupported; + *pClipType = M4VIDEOEDITING_kFileType_Unsupported; + + // Check if the length of the extension is valid. + if ((3 == extLength) || (4 == extLength)) + { + // Convert the extension to lowercase. + for (index = 0; index < extLength ; index++) + { + extension[index] = M4OSA_chrToLower(pExtension[index]); + } + + // Check if the extension is ".mp3". + if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"mp3", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_MP3; + *pClipType = M4VIDEOEDITING_kFileType_MP3; + } // Check if the extension is ".mp4". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"mp4", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_MP4; + *pClipType = M4VIDEOEDITING_kFileType_MP4; + } + // Check if the extension is ".3gp". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"3gp", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_3GPP; + *pClipType = M4VIDEOEDITING_kFileType_3GPP; + } + // Check if the extension is ".3gp". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"m4a", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_3GPP; + *pClipType = M4VIDEOEDITING_kFileType_3GPP; + } + // Check if the extension is ".3gpp". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"3gpp", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_3GPP; + *pClipType = M4VIDEOEDITING_kFileType_3GPP; + } + // Check if the extension is ".amr". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"amr", &cmpResult))) + { + + *pFileType = VideoEditClasses_kFileType_AMR; + *pClipType = M4VIDEOEDITING_kFileType_AMR; + } + // Check if the extension is ".pcm". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"pcm", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_PCM; + *pClipType = M4VIDEOEDITING_kFileType_PCM; + } + // Check if the extension is ".jpg". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"jpg", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_JPG; + } + // Check if the extension is ".jpeg". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"jpeg", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_JPG; + } + // Check if the extension is ".gif". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"gif", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_GIF; + } + // Check if the extension is ".png". + else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"png", &cmpResult))) + { + *pFileType = VideoEditClasses_kFileType_PNG; + } + + } + +} + +static M4OSA_ERR getClipProperties( + JNIEnv* pEnv, + jobject thiz, + M4OSA_Char* pFile, + M4VIDEOEDITING_FileType clipType, + M4VIDEOEDITING_ClipProperties* pClipProperties) +{ + bool gotten = true; + M4OSA_ERR result = M4NO_ERROR; + M4OSA_ERR resultAbort = M4NO_ERROR; + M4MCS_Context context = M4OSA_NULL; + + M4OSA_FileReadPointer fileReadPtr = + { M4OSA_NULL, M4OSA_NULL, M4OSA_NULL, + M4OSA_NULL, M4OSA_NULL, M4OSA_NULL }; + + M4OSA_FileWriterPointer fileWritePtr = + { M4OSA_NULL, M4OSA_NULL, M4OSA_NULL, + M4OSA_NULL, M4OSA_NULL, M4OSA_NULL, M4OSA_NULL }; + + // Initialize the OSAL file system function pointers. + videoEditOsal_getFilePointers(&fileReadPtr , &fileWritePtr); + + // Log the API call. + VIDEOEDIT_LOG_API( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",\ + "getClipProperties - M4MCS_init()"); + + // Initialize the MCS context. + result = M4MCS_init(&context, &fileReadPtr, &fileWritePtr); + + // Log the result. + VIDEOEDIT_PROP_LOG_RESULT( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s", + videoEditOsal_getResultString(result)); + + // Check if the creation succeeded. + videoEditJava_checkAndThrowRuntimeException( + &gotten, pEnv, (M4NO_ERROR != result), result); + + // Check if opening the MCS context succeeded. + if (gotten) + { + // Log the API call. + VIDEOEDIT_LOG_API( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", + "getClipProperties - M4MCS_open_normalMode()"); + + // Open the MCS in the normal opening mode to + // retrieve the exact duration + result = M4MCS_open_normalMode( + context, pFile, clipType, M4OSA_NULL, M4OSA_NULL); + + // Log the result. + VIDEOEDIT_PROP_LOG_RESULT( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s", + videoEditOsal_getResultString(result)); + + // Check if the creation succeeded. + videoEditJava_checkAndThrowRuntimeException( + &gotten, pEnv, (M4NO_ERROR != result), result); + + // Check if the MCS could be opened. + if (gotten) + { + // Log the API call. + VIDEOEDIT_LOG_API( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", + "getClipProperties - M4MCS_getInputFileProperties()"); + + // Get the properties. + result = M4MCS_getInputFileProperties(context, pClipProperties); + + // Log the result. + VIDEOEDIT_PROP_LOG_RESULT( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s", + videoEditOsal_getResultString(result)); + + // Check if the creation succeeded. + videoEditJava_checkAndThrowRuntimeException( + &gotten, pEnv, (M4NO_ERROR != result), result); + } + + // Log the API call. + VIDEOEDIT_LOG_API( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", + "getClipProperties - M4MCS_abort()"); + + // Close the MCS session. + resultAbort = M4MCS_abort(context); + + if (result == M4NO_ERROR) { + // Log the result. + VIDEOEDIT_PROP_LOG_RESULT( + ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s", + videoEditOsal_getResultString(resultAbort)); + + // Check if the abort succeeded. + videoEditJava_checkAndThrowRuntimeException( + &gotten, pEnv, (M4NO_ERROR != resultAbort), resultAbort); + result = resultAbort; + } + } + + return result; +} + +M4OSA_UInt32 +VideoEdit_chrCompare(M4OSA_Char* pStrIn1, + M4OSA_Char* pStrIn2, + M4OSA_Int32* pCmpResult) +{ + M4OSA_chrCompare(pStrIn1, pStrIn2, pCmpResult); + return *pCmpResult; +} + + diff --git a/media/jni/mediaeditor/VideoEditorThumbnailMain.cpp b/media/jni/mediaeditor/VideoEditorThumbnailMain.cpp new file mode 100755 index 000000000000..b1f9fe465401 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorThumbnailMain.cpp @@ -0,0 +1,330 @@ +/* + * 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++) + { + M4OSA_memcpy((M4OSA_MemAddr8 )dst, (M4OSA_MemAddr8 )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); + + M4OSA_memset((M4OSA_MemAddr8)pContext, sizeof(ThumbnailContext), 0); + + 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; +} + diff --git a/media/jni/mediaeditor/VideoEditorThumbnailMain.h b/media/jni/mediaeditor/VideoEditorThumbnailMain.h new file mode 100755 index 000000000000..14c60dd6de21 --- /dev/null +++ b/media/jni/mediaeditor/VideoEditorThumbnailMain.h @@ -0,0 +1,76 @@ +/* + * 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. + */ + +#ifndef VIDEOEDITOR_THUMBNAIL_MAIN_H +#define VIDEOEDITOR_THUMBNAIL_MAIN_H + +/** + ************************************************************************ + * @file VideoEditorThumbnailMain.h + * @brief Thumbnail extract interface. + ************************************************************************ +*/ + +/** + ************************************************************************ + * @brief Interface to open a Thumbnail session. + * @param pContext (OUT) Thumbnail Context. + * @param pString (IN) File path from which thumbnail will be + * retrieved + * @param M4OSA_Bool (IN) true if this is for rendering at native layer. + ************************************************************************ +*/ +M4OSA_ERR ThumbnailOpen(M4OSA_Context *pPContext, + const M4OSA_Char *pString, + M4OSA_Bool bRender); + +/** + ************************************************************************ + * @brief Interface to retrieve a RGB888 format thumbnail pixels + * @param pContext (IN) Thumbnail Context. + * @param pixelArray (OUT) Pointer to array in which pixels data to return + * @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 ThumbnailGetPixels32(const M4OSA_Context pContext, + M4OSA_Int32* pixelArray, M4OSA_UInt32 width, + M4OSA_UInt32 height, M4OSA_UInt32 *timeMS); + +/** + ************************************************************************ + * @brief Interface to retrieve a RGB565 format thumbnail pixels + * @param pContext (IN) Thumbnail Context. + * @param pixelArray (OUT) Pointer to array in which pixcel data to return + * @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 ThumbnailGetPixels16(const M4OSA_Context pContext, + M4OSA_Int16* pixelArray, M4OSA_UInt32 width, + M4OSA_UInt32 height, M4OSA_UInt32 *timeMS); + +/** + ************************************************************************ + * @brief Interface to close the Thumbnail session. + * @param pContext (IN) Thumbnail Context. + ************************************************************************ +*/ +void ThumbnailClose(const M4OSA_Context pContext); + +#endif // VIDEOEDITOR_THUMBNAIL_MAIN_H |