M4OSA_ERR M4OSA_SetThreadSyncName(M4OSA_Context context, M4OSA_DataOption optionValue) { M4OSA_ThreadContext* threadContext = (M4OSA_ThreadContext*)context; M4OSA_Char* name = (M4OSA_Char*)optionValue; M4OSA_UInt32 nameSize ; M4OSA_TRACE2_2("M4OSA_SetThreadSyncName\t\tM4OSA_Context 0x%x\t" "M4OSA_DataOption 0x%x", context, optionValue); if(threadContext->name != NULL) { free(threadContext->name); threadContext->name = M4OSA_NULL; } if(optionValue != M4OSA_NULL) { nameSize = strlen((const char *)name)+1; threadContext->name = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(nameSize, M4OSA_THREAD, (M4OSA_Char*)"M4OSA_SetThreadSyncName: thread name"); if(threadContext == M4OSA_NULL) { return M4ERR_ALLOC; } memcpy((void *)threadContext->name, (void *)name, nameSize); } return M4NO_ERROR; }
/** ************************************************************************ * @brief create an instance of the reader * @note allocates the context * @param pContext: (OUT) pointer on a reader context * @return M4NO_ERROR there is no error * @return M4ERR_ALLOC a memory allocation has failed * @return M4ERR_PARAMETER at least one parameter is not properly set (in DEBUG only) ************************************************************************ */ M4OSA_ERR M4READER_AMR_create(M4OSA_Context *pContext) { M4READER_AMR_Context* pReaderContext; /* Check function parameters */ M4OSA_DEBUG_IF1((pContext == 0), M4ERR_PARAMETER, "M4READER_AMR_create: invalid context pointer"); pReaderContext = (M4READER_AMR_Context*)M4OSA_32bitAlignedMalloc(sizeof(M4READER_AMR_Context), M4READER_AMR, (M4OSA_Char *)"M4READER_AMR_Context"); if (pReaderContext == M4OSA_NULL) { return M4ERR_ALLOC; } pReaderContext->m_pAudioStream = M4OSA_NULL; pReaderContext->m_audioAu.dataAddress = M4OSA_NULL; pReaderContext->m_maxDuration = 0; pReaderContext->m_pCoreContext = M4OSA_NULL; pReaderContext->m_pOsaFileReaderFcts = M4OSA_NULL; *pContext = pReaderContext; return M4NO_ERROR; }
/****************************************************************************** * M4OSA_ERR M4WRITER_3GP_openWrite(M4WRITER_Context* pContext, void* pWhat, * M4OSA_FileWriterPointer* pFileWriterPointer) * @brief Open a writer session. * @note * @param pContext: (OUT) Execution context of the 3GP writer, allocated by this function. * @param outputFileDescriptor (IN) Descriptor of the output file to create. * @param fileWriterFunction (IN) Pointer to structure containing the set of OSAL * file write functions. * @param tempFileDescriptor (IN) Descriptor of the temporary file to open * (NULL if not used) * @param fileReaderFunction (IN) Pointer to structure containing the set of OSAL file read * functions (NULL if not used) * @return M4NO_ERROR: there is no error * @return M4ERR_ALLOC: there is no more available memory * @return M4ERR_PARAMETER: pContext or pFilePtrFct is M4OSA_NULL (debug only) * @return any error returned by the MP4 core writer openWrite (Its coreID is M4MP4_WRITER) ****************************************************************************** */ M4OSA_ERR M4WRITER_3GP_openWrite( M4WRITER_Context* pContext, void* outputFileDescriptor, M4OSA_FileWriterPointer* pFileWriterPointer, void* tempFileDescriptor, M4OSA_FileReadPointer* pFileReaderPointer ) { M4WRITER_3GP_InternalContext* apContext; M4OSA_ERR err; M4OSA_TRACE1_0("M4WRITER_3GP_openWrite"); /** * Check input parameters */ M4OSA_DEBUG_IF2((M4OSA_NULL == pContext),M4ERR_PARAMETER, "M4WRITER_3GP_openWrite: pContext is M4OSA_NULL"); M4OSA_DEBUG_IF2((M4OSA_NULL == pFileWriterPointer),M4ERR_PARAMETER, "M4WRITER_3GP_openWrite: pFileWriterPointer is M4OSA_NULL"); /** * Allocate memory for the context */ *pContext=M4OSA_NULL; apContext = (M4WRITER_3GP_InternalContext*)M4OSA_32bitAlignedMalloc( sizeof(M4WRITER_3GP_InternalContext), M4WRITER_3GP, (M4OSA_Char *)"M4WRITER_3GP_InternalContext"); if (M4OSA_NULL == apContext) { M4OSA_TRACE1_0("M4WRITER_3GP_openWrite:\ unable to allocate context, returning M4ERR_ALLOC"); return (M4OSA_ERR)M4ERR_ALLOC; }
/** ************************************************************************ * @brief This function gets the file URL (associated to the context). * @note * @param context: (IN) Context of the core file reader * @param url: (OUT) The buffer containing the URL (allocated by * M4OSA_fileCommonGetURL) * @return M4NO_ERROR: there is no error * @return M4ERR_PARAMETER: at least one parameter is NULL * @return M4ERR_BAD_CONTEXT: provided context is not a valid one * @return M4ERR_ALLOC: there is no more memory available ************************************************************************ */ M4OSA_ERR M4OSA_fileCommonGetURL(M4OSA_Context pContext, M4OSA_Char** pUrl) { M4OSA_FileContext* pFileContext = pContext; M4OSA_UInt32 uiLength; M4OSA_TRACE3_2("M4OSA_fileCommonGetURL\tM4OSA_Context 0x%x\tM4OSA_Char** 0x%x", pContext, pUrl); M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER, "M4OSA_fileCommonGetURL: pContext is M4OSA_NULL"); M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl, M4ERR_PARAMETER, "M4OSA_fileCommonGetURL: pUrl is M4OSA_NULL"); uiLength = strlen((const char *)pFileContext->url_name)+1; /* Allocate the memory to store the url_name */ *pUrl = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(uiLength, M4OSA_FILE_COMMON, (M4OSA_Char*)"M4OSA_fileCommonGetURL: url"); if(M4OSA_NULL == *pUrl) { M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonGetURL"); return M4ERR_ALLOC; } M4OSA_chrNCopy(*pUrl, pFileContext->url_name, uiLength); return M4NO_ERROR; }
/** ************************************************************************ * @brief Creates an instance of the null decoder * @note Allocates the context * * @param pContext: (OUT) Context of the decoder * @param pStreamHandler: (IN) Pointer to an audio stream description * @param pUserData: (IN) Pointer to User data * * @return M4NO_ERROR there is no error * @return M4ERR_STATE State automaton is not applied * @return M4ERR_ALLOC a memory allocation has failed * @return M4ERR_PARAMETER at least one parameter is not properly set (in DEBUG only) ************************************************************************ */ M4OSA_ERR M4AD_NULL_create( M4AD_Context* pContext, M4_AudioStreamHandler *pStreamHandler, void* pUserData) { M4AD_NullContext* pC; M4OSA_DEBUG_IF1((pContext == 0), M4ERR_PARAMETER, "M4AD_NULL_create: invalid context pointer"); M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, "M4AD_NULL_create: invalid pointer pStreamHandler"); pC = (M4AD_NullContext*)M4OSA_32bitAlignedMalloc(sizeof(M4AD_NullContext), M4DECODER_AUDIO, (M4OSA_Char *)"M4AD_NullContext"); if (pC == (M4AD_NullContext*)0) { M4OSA_TRACE1_0("Can not allocate null decoder context"); return M4ERR_ALLOC; } *pContext = pC; pC->m_pAudioStreamhandler = pStreamHandler; return M4NO_ERROR; }
M4OSA_ERR VIDEOEDITOR_BUFFER_initPoolBuffers(VIDEOEDITOR_BUFFER_Pool* pool, M4OSA_UInt32 lSize) { M4OSA_ERR err = M4NO_ERROR; M4OSA_UInt32 index, j; /** * Initialize all the buffers in the pool */ for(index = 0; index < pool->NB; index++) { pool->pNXPBuffer[index].pData = M4OSA_NULL; pool->pNXPBuffer[index].pData = (M4OSA_Void*)M4OSA_32bitAlignedMalloc( lSize, VIDEOEDITOR_BUFFER_EXTERNAL, (M4OSA_Char*)("BUFFER_initPoolBuffers: Buffer data")); if(M4OSA_NULL == pool->pNXPBuffer[index].pData) { for (j = 0; j < index; j++) { if(M4OSA_NULL != pool->pNXPBuffer[j].pData) { free(pool->pNXPBuffer[j].pData); pool->pNXPBuffer[j].pData = M4OSA_NULL; } } err = M4ERR_ALLOC; return err; } pool->pNXPBuffer[index].size = 0; pool->pNXPBuffer[index].state = VIDEOEDITOR_BUFFER_kEmpty; pool->pNXPBuffer[index].idx = index; pool->pNXPBuffer[index].buffCTS = -1; } return err; }
/** ************************************************************************ * @brief This method creates a new thread. After this call the thread is * identified by its "context". The thread function is provided by * the "func" parameter. This function creates & allocates a unique * context. It's the OSAL real time responsibility for managing its * context. It must be freed by the M4OSA_threadSyncClose function. * The context parameter will be sent back to any OSAL core thread * functions to allow retrieving data associated to the opened * thread. * @note This function creates the thread, but the thread is not running. * @note Once the thread is created, the state is M4OSA_kThreadOpened. * @param context:(OUT) Context of the created thread * @param func:(IN) "doIt" function pointer to run * @return M4NO_ERROR: there is no error * @return M4ERR_PARAMETER: at least one parameter is NULL * @return M4ERR_ALLOC: there is no more available memory * @return M4ERR_CONTEXT_FAILED: the context creation failed ************************************************************************ */ M4OSA_ERR M4OSA_threadSyncOpen(M4OSA_Context* context, M4OSA_ThreadDoIt func) { M4OSA_ThreadContext* threadContext = M4OSA_NULL; M4OSA_ERR err_code; M4OSA_TRACE1_2("M4OSA_threadSyncOpen\t\tM4OSA_Context* 0x%x\t" "M4OSA_ThreadDoIt 0x%x", context, func); M4OSA_DEBUG_IF2(context == M4OSA_NULL, M4ERR_PARAMETER, "M4OSA_threadSyncOpen"); M4OSA_DEBUG_IF2(func == M4OSA_NULL, M4ERR_PARAMETER, "M4OSA_threadSyncOpen"); *context = M4OSA_NULL; threadContext = (M4OSA_ThreadContext*)M4OSA_32bitAlignedMalloc(sizeof(M4OSA_ThreadContext), M4OSA_THREAD, (M4OSA_Char*)"M4OSA_threadSyncOpen: thread context"); if(threadContext == M4OSA_NULL) { M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_threadSyncOpen"); return M4ERR_ALLOC; } threadContext->func = func; threadContext->stackSize = 64 * 1024; threadContext->name = M4OSA_NULL; threadContext->threadID = 0; threadContext->coreID = M4OSA_THREAD; threadContext->state = M4OSA_kThreadOpened; threadContext->priority = M4OSA_kThreadNormalPriority ; err_code = M4OSA_mutexOpen(&(threadContext->stateMutex)); if(M4OSA_ERR_IS_ERROR(err_code)) { M4OSA_DEBUG(err_code, "M4OSA_threadSyncOpen: M4OSA_mutexOpen"); return err_code; } err_code = M4OSA_semaphoreOpen(&(threadContext->semStartStop), 0); if(M4OSA_ERR_IS_ERROR(err_code)) { M4OSA_DEBUG(err_code, "M4OSA_threadSyncOpen: M4OSA_semaphoreOpen"); return err_code; } *context = threadContext; return M4NO_ERROR; }
void* M4MP4W_realloc(M4OSA_MemAddr32 ptr, M4OSA_UInt32 oldSize, M4OSA_UInt32 newSize) /*******************************************************************************/ { M4OSA_MemAddr32 ptr2 = (M4OSA_MemAddr32)M4OSA_32bitAlignedMalloc(newSize, M4MP4_WRITER, (M4OSA_Char *)"realloc"); if (M4OSA_NULL != ptr2) { memcpy((void *)ptr2, (void *)ptr, oldSize); } free(ptr); return ptr2; }
/** ****************************************************************************** * M4OSA_ERR M4AIR_create(M4OSA_Context* pContext,M4AIR_InputFormatType inputFormat) * @brief This function initialize an instance of the AIR. * @param pContext: (IN/OUT) Address of the context to create * @param inputFormat: (IN) input format type. * @return M4NO_ERROR: there is no error * @return M4ERR_PARAMETER: pContext is M4OSA_NULL (debug only). Invalid formatType * @return M4ERR_ALLOC: No more memory is available ****************************************************************************** */ M4OSA_ERR M4AIR_create(M4OSA_Context* pContext,M4AIR_InputFormatType inputFormat) { M4OSA_ERR err = M4NO_ERROR ; M4AIR_InternalContext* pC = M4OSA_NULL ; /* Check that the address on the context is not NULL */ M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pContext) ; *pContext = M4OSA_NULL ; /* Internal Context creation */ pC = (M4AIR_InternalContext*)M4OSA_32bitAlignedMalloc(sizeof(M4AIR_InternalContext), M4AIR,(M4OSA_Char *)"AIR internal context") ; M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_ALLOC, pC) ; /* Check if the input format is supported */ switch(inputFormat) { #ifdef M4AIR_YUV420_FORMAT_SUPPORTED case M4AIR_kYUV420P: break ; #endif #ifdef M4AIR_YUV420A_FORMAT_SUPPORTED case M4AIR_kYUV420AP: break ; #endif default: err = M4ERR_AIR_FORMAT_NOT_SUPPORTED; goto M4AIR_create_cleanup ; } /**< Save input format and update state */ pC->m_inputFormat = inputFormat; pC->m_state = M4AIR_kCreated; /* Return the context to the caller */ *pContext = pC ; return M4NO_ERROR ; M4AIR_create_cleanup: /* Error management : we destroy the context if needed */ if(M4OSA_NULL != pC) { free(pC) ; } *pContext = M4OSA_NULL ; return err ; }
/** ************************************************************************ * @brief This function gets a string containing the file name associated * to the input URL. * @note The user should not forget to delete the output string using * M4OSA_strDestroy * @param pUrl: (IN) The buffer containing the URL * @param pFileName: (OUT) The string containing the URL. It is * allocated inside this function * @return M4NO_ERROR: there is no error * @return M4ERR_NOT_IMPLEMENTED: the URL does not match with the supported * file * @return M4ERR_ALLOC: there is no more memory available ************************************************************************ */ M4OSA_ERR M4OSA_fileCommonGetFilename(M4OSA_Char* pUrl, M4OSA_Char** pFileName) { M4OSA_Int32 i = 0; M4OSA_Int32 iUrlLen = 0; M4OSA_Int32 FileNameLen = 0; M4OSA_Char* ptrUrl = M4OSA_NULL; M4OSA_Char* ptrFilename = M4OSA_NULL; M4OSA_TRACE3_2("M4OSA_fileCommonGetURL\tM4OSA_Char* %s\tM4OSA_Char** 0x%x", pUrl, pFileName); M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl, M4ERR_PARAMETER, "M4OSA_fileCommonGetFilename: pUrl is M4OSA_NULL"); M4OSA_DEBUG_IF2(M4OSA_NULL == pFileName, M4ERR_PARAMETER, "M4OSA_fileCommonGetFilename: pFileName is M4OSA_NULL"); *pFileName = M4OSA_NULL; /*Parse URL*/ iUrlLen = strlen((const char *)pUrl); for(i=iUrlLen-1; i>=0; i--) { if (pUrl[i] != '\\' && pUrl[i] != '/') { FileNameLen++; } else { break; /* find the beginning of the file name */ } } ptrFilename = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(FileNameLen+1, M4OSA_FILE_COMMON, (M4OSA_Char*)"M4OSA_fileCommonGetFilename: Filename string"); if (ptrFilename == M4OSA_NULL) { M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonGetFilename"); return M4ERR_ALLOC; } ptrUrl = pUrl + (iUrlLen - FileNameLen); M4OSA_chrNCopy(ptrFilename, ptrUrl, FileNameLen+1); *pFileName = ptrFilename; return M4NO_ERROR; }
M4OSA_ERR M4VSS3GPP_internalConvertAndResizeARGB8888toNV12(M4OSA_Void* pFileIn, M4OSA_FileReadPointer* pFileReadPtr, M4VIFI_ImagePlane* pImagePlanes, M4OSA_UInt32 width, M4OSA_UInt32 height) { M4OSA_Context pARGBIn; M4VIFI_ImagePlane rgbPlane1 ,rgbPlane2; M4OSA_UInt32 frameSize_argb = width * height * 4; M4OSA_UInt32 frameSize_rgb888 = width * height * 3; M4OSA_UInt32 i = 0,j= 0; M4OSA_ERR err = M4NO_ERROR; M4OSA_UInt8 *pArgbPlane = (M4OSA_UInt8*) M4OSA_32bitAlignedMalloc(frameSize_argb, M4VS, (M4OSA_Char*)"argb data"); if (pArgbPlane == M4OSA_NULL) { M4OSA_TRACE1_0("M4VSS3GPP_internalConvertAndResizeARGB8888toNV12: \ Failed to allocate memory for ARGB plane"); return M4ERR_ALLOC; }
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_32bitAlignedMalloc(size, 0, (M4OSA_Char*)pDescription); if (M4OSA_NULL != pData) { // Reset the allocated memory. memset((void *)pData, 0,size); #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); }
/** ************************************************************************ * @brief This method creates a new semaphore with the "initialCounter" * value. * @note This function creates and allocates a unique context. It's the * OSAL real time responsibility for managing its context. It must * be freed by the M4OSA_semaphoreClose function. The context * parameter will be sent back to any OSAL core semaphore functions * to allow retrieving data associated to the opened semaphore. * @param context:(OUT) Context of the created semaphore * @param initial_count:(IN) Initial counter of the semaphore * @return M4NO_ERROR: there is no error * @return M4ERR_PARAMETER: provided context is NULL * @return M4ERR_ALLOC: there is no more available memory * @return M4ERR_CONTEXT_FAILED: the context creation failed ************************************************************************ */ M4OSA_ERR M4OSA_semaphoreOpen(M4OSA_Context* context, M4OSA_UInt32 initial_count) { M4OSA_SemaphoreContext* semaphoreContext = M4OSA_NULL; M4OSA_TRACE1_2("M4OSA_semaphoreOpen\t\tM4OSA_Context* 0x%x\tM4OSA_UInt32 " "%d", context, initial_count); M4OSA_DEBUG_IF2(context == M4OSA_NULL, M4ERR_PARAMETER, "M4OSA_semaphoreOpen"); *context = M4OSA_NULL; semaphoreContext = (M4OSA_SemaphoreContext*) M4OSA_32bitAlignedMalloc( sizeof(M4OSA_SemaphoreContext), M4OSA_SEMAPHORE, (M4OSA_Char*)"M4OSA_semaphoreOpen: semaphore context"); if(semaphoreContext == M4OSA_NULL) { M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_semaphoreOpen"); return M4ERR_ALLOC; } if (0 != sem_init(&semaphoreContext->semaphore, 0, initial_count)) { free(semaphoreContext); M4OSA_DEBUG(M4ERR_CONTEXT_FAILED, "M4OSA_semaphoreOpen: OS semaphore creation failed"); return M4ERR_CONTEXT_FAILED; } semaphoreContext->coreID = M4OSA_SEMAPHORE ; *context = (M4OSA_Context)semaphoreContext; return M4NO_ERROR; }
/** ************************************************************************ * @brief This function opens the provided URL and returns its context. * If an error occured, the context is set to NULL. * @param core_id: (IN) Core ID of the caller (M4OSA_FILE_READER or M4OSA_FILE_WRITER) * @param context: (OUT) Context of the core file reader * @param url: (IN) URL of the input file * @param fileModeAccess: (IN) File mode access * @return M4NO_ERROR: there is no error * @return M4ERR_PARAMETER: at least one parameter is NULL * @return M4ERR_ALLOC: there is no more memory available * @return M4ERR_NOT_IMPLEMENTED: the URL does not match with the supported * file * @return M4ERR_FILE_NOT_FOUND: the file cannot be found * @return M4ERR_FILE_LOCKED: the file is locked by an other * application/process * @return M4ERR_FILE_BAD_MODE_ACCESS: the file mode access is not correct ************************************************************************ */ M4OSA_ERR M4OSA_fileCommonOpen(M4OSA_UInt16 core_id, M4OSA_Context* pContext, M4OSA_Char* pUrl, M4OSA_FileModeAccess fileModeAccess) { M4OSA_Int32 i = 0; M4OSA_Int32 iMode = 0; M4OSA_Int32 iSize = 0; M4OSA_Int32 iSavePos = 0; M4OSA_Char mode[4] = ""; M4OSA_Char* pReadString = (M4OSA_Char*)"r"; M4OSA_Char* pWriteString = (M4OSA_Char*)"w"; M4OSA_Char* pAppendString = (M4OSA_Char*)"a"; M4OSA_Char* pBinaryString = (M4OSA_Char*)"b"; M4OSA_Char* pPlusString = (M4OSA_Char*)"+"; M4OSA_ERR err = M4NO_ERROR; FILE* pFileHandler = M4OSA_NULL; M4OSA_FileContext *pFileContext = M4OSA_NULL; #ifdef UTF_CONVERSION /*FB: to test the UTF16->UTF8 conversion into Video Artist*/ /*Convert the URL from UTF16 to UTF8*/ M4OSA_Void* tempConversionBuf; M4OSA_UInt32 tempConversionSize = 1000; tempConversionBuf = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(tempConversionSize +1, 0, "conversion buf"); if(tempConversionBuf == M4OSA_NULL) { M4OSA_TRACE1_0("Error when allocating conversion buffer\n"); return M4ERR_PARAMETER; } M4OSA_ToUTF8_OSAL(pUrl, tempConversionBuf, &tempConversionSize); ((M4OSA_Char*)tempConversionBuf)[tempConversionSize ] = '\0'; printf("file open %s\n", tempConversionBuf); #endif /*UTF CONVERSION*/ M4OSA_TRACE3_4("M4OSA_fileCommonOpen\t\tM4OSA_UInt16 %d\tM4OSA_Context* 0x%x\t" "M4OSA_Char* %s\tfileModeAccess %d", core_id, pContext, pUrl, fileModeAccess); M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER, "M4OSA_fileCommonOpen: pContext is M4OSA_NULL"); M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl, M4ERR_PARAMETER, "M4OSA_fileCommonOpen: pUrl is M4OSA_NULL"); M4OSA_DEBUG_IF2(0 == fileModeAccess, M4ERR_PARAMETER, "M4OSA_fileCommonOpen: fileModeAccess is 0"); /* Read mode not set for the reader */ M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && !(fileModeAccess & M4OSA_kFileRead), M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileRead"); /* Read mode not set for the reader */ M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && !(fileModeAccess & M4OSA_kFileRead), M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileRead"); /* M4OSAfileReadOpen cannot be used with Write file mode access */ M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileWrite), M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileWrite"); /* Append and Create flags cannot be used with Read */ M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileAppend), M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileAppend"); M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileCreate), M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileCreate"); /* Write mode not set for the writer */ M4OSA_DEBUG_IF1((M4OSA_FILE_WRITER == core_id) && !(fileModeAccess & M4OSA_kFileWrite), M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileWrite"); /* Create flag necessary for opening file */ if ((fileModeAccess & M4OSA_kFileRead) && (fileModeAccess & M4OSA_kFileWrite)&&(fileModeAccess & M4OSA_kFileCreate)) { strncat((char *)mode, (const char *)pWriteString, (size_t)1); strncat((char *)mode, (const char *)pPlusString, (size_t)1); } else { if(fileModeAccess & M4OSA_kFileAppend) { strncat((char *)mode, (const char *)pAppendString, (size_t)1); } else if(fileModeAccess & M4OSA_kFileRead) { strncat((char *)mode, (const char *)pReadString, (size_t)1); } else if(fileModeAccess & M4OSA_kFileWrite) { strncat((char *)mode, (const char *)pWriteString, (size_t)1); } if((fileModeAccess & M4OSA_kFileRead)&&(fileModeAccess & M4OSA_kFileWrite)) { strncat((char *)mode,(const char *)pPlusString, (size_t)1); } } if(!(fileModeAccess & M4OSA_kFileIsTextMode)) { strncat((char *)mode, (const char *)pBinaryString,(size_t)1); } /*Open the file*/ #ifdef UTF_CONVERSION /*Open the converted path*/ pFileHandler = fopen((const char *)tempConversionBuf, (const char *)mode); /*Free the temporary decoded buffer*/ free(tempConversionBuf); #else /* UTF_CONVERSION */ pFileHandler = fopen((const char *)pUrl, (const char *)mode); #endif /* UTF_CONVERSION */ if (M4OSA_NULL == pFileHandler) { switch(errno) { case ENOENT: { M4OSA_DEBUG(M4ERR_FILE_NOT_FOUND, "M4OSA_fileCommonOpen: No such file or directory"); M4OSA_TRACE1_1("File not found: %s", pUrl); return M4ERR_FILE_NOT_FOUND; } case EACCES: { M4OSA_DEBUG(M4ERR_FILE_LOCKED, "M4OSA_fileCommonOpen: Permission denied"); return M4ERR_FILE_LOCKED; } case EINVAL: { M4OSA_DEBUG(M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: Invalid Argument"); return M4ERR_FILE_BAD_MODE_ACCESS; } case EMFILE: case ENOSPC: case ENOMEM: { M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen: Too many open files"); return M4ERR_ALLOC; } default: { M4OSA_DEBUG(M4ERR_NOT_IMPLEMENTED, "M4OSA_fileCommonOpen"); return M4ERR_NOT_IMPLEMENTED; } } } /* Allocate the file context */ pFileContext = (M4OSA_FileContext*) M4OSA_32bitAlignedMalloc(sizeof(M4OSA_FileContext), core_id, (M4OSA_Char*)"M4OSA_fileCommonOpen: file context"); if (M4OSA_NULL == pFileContext) { fclose(pFileHandler); M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen"); return M4ERR_ALLOC; } pFileContext->file_desc = pFileHandler; #ifndef ANDROID_DEFAULT_CODE M4OSA_TRACE1_2("open file %s:%x", (char*)pUrl, pFileHandler); #endif pFileContext->access_mode = fileModeAccess; pFileContext->current_seek = SeekNone; pFileContext->b_is_end_of_file = M4OSA_FALSE; /** * Note: Never use this expression "i = (value1 == value2) ? x: y;" * because that doens't compile on other platforms (ADS for example) * Use: if(value1 == value2) * { i= x; ..etc */ pFileContext->coreID_write = 0; pFileContext->coreID_read = 0; pFileContext->m_DescrModeAccess = M4OSA_kDescNoneAccess; if (M4OSA_FILE_READER == core_id) { pFileContext->coreID_read = core_id; pFileContext->m_DescrModeAccess = M4OSA_kDescReadAccess; } else if (M4OSA_FILE_WRITER == core_id) { pFileContext->coreID_write = core_id; pFileContext->m_DescrModeAccess = M4OSA_kDescWriteAccess; } pFileContext->read_position = 0; pFileContext->write_position = 0; /* Allocate the memory to store the URL string */ pFileContext->url_name = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(strlen((const char *)pUrl)+1, core_id, (M4OSA_Char*)"M4OSA_fileCommonOpen: URL name"); if (M4OSA_NULL == pFileContext->url_name) { fclose(pFileHandler); free(pFileContext); M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen"); return M4ERR_ALLOC; } M4OSA_chrNCopy(pFileContext->url_name, pUrl, strlen((const char *)pUrl)+1); /* Get the file name */ err = M4OSA_fileCommonGetFilename(pUrl, &pFileContext->file_name); if(M4NO_ERROR != err) { fclose(pFileHandler); free(pFileContext->url_name); free(pFileContext); M4OSA_DEBUG(err, "M4OSA_fileCommonOpen"); return err; } #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE M4OSA_semaphoreOpen(&(pFileContext->semaphore_context), 1); /* Allocate the semaphore */ #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */ #ifdef USE_STAGEFRIGHT_CODECS // Workaround for file system bug on Stingray/Honeycomb where a file re-created will keep // the original file's size filled with 0s. Do not seek to the end to avoid ill effects if(fileModeAccess & M4OSA_kFileAppend) { /* Get the file size */ iSavePos = ftell(pFileHandler); /* 1- Check the first position */ fseek(pFileHandler, 0, SEEK_END); /* 2- Go to the end of the file*/ iSize = ftell(pFileHandler); /* 3- Check the file size */ fseek(pFileHandler, iSavePos, SEEK_SET);/* 4- go to the first position */ } else { iSize = 0; } #else /* USE_STAGEFRIGHT_CODECS */ /* Get the file size */ iSavePos = ftell(pFileHandler); /* 1- Check the first position */ fseek(pFileHandler, 0, SEEK_END); /* 2- Go to the end of the file*/ iSize = ftell(pFileHandler); /* 3- Check the file size */ fseek(pFileHandler, iSavePos, SEEK_SET);/* 4- go to the first position */ #endif /* USE_STAGEFRIGHT_CODECS */ /* Warning possible overflow if the file is higher than 2GBytes */ pFileContext->file_size = iSize; *pContext = pFileContext; return M4NO_ERROR; }
/** ************************************************************************ M4OSA_ERR VIDEOEDITOR_BUFFER_allocatePool(VIDEOEDITOR_BUFFER_Pool** ppool, * M4OSA_UInt32 nbBuffers) * @brief Allocate a pool of nbBuffers buffers * * @param ppool : IN The buffer pool to create * @param nbBuffers : IN The number of buffers in the pool * @param poolName : IN a name given to the pool * @return Error code ************************************************************************ */ M4OSA_ERR VIDEOEDITOR_BUFFER_allocatePool(VIDEOEDITOR_BUFFER_Pool** ppool, M4OSA_UInt32 nbBuffers, M4OSA_Char* poolName) { M4OSA_ERR lerr = M4NO_ERROR; VIDEOEDITOR_BUFFER_Pool* pool; M4OSA_UInt32 index; ALOGV("VIDEOEDITOR_BUFFER_allocatePool : ppool = 0x%x nbBuffers = %d ", ppool, nbBuffers); pool = M4OSA_NULL; pool = (VIDEOEDITOR_BUFFER_Pool*)M4OSA_32bitAlignedMalloc( sizeof(VIDEOEDITOR_BUFFER_Pool), VIDEOEDITOR_BUFFER_EXTERNAL, (M4OSA_Char*)("VIDEOEDITOR_BUFFER_allocatePool: pool")); if (M4OSA_NULL == pool) { lerr = M4ERR_ALLOC; goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup; } ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Allocating Pool buffers"); pool->pNXPBuffer = M4OSA_NULL; pool->pNXPBuffer = (VIDEOEDITOR_BUFFER_Buffer*)M4OSA_32bitAlignedMalloc( sizeof(VIDEOEDITOR_BUFFER_Buffer)*nbBuffers, VIDEOEDITOR_BUFFER_EXTERNAL, (M4OSA_Char*)("BUFFER_allocatePool: pNXPBuffer")); if(M4OSA_NULL == pool->pNXPBuffer) { lerr = M4ERR_ALLOC; goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup; } for (index = 0; index < nbBuffers; index++) { pool->pNXPBuffer[index].pData = M4OSA_NULL; } ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Allocating Pool name buffer"); pool->poolName = M4OSA_NULL; pool->poolName = (M4OSA_Char*)M4OSA_32bitAlignedMalloc( VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE,VIDEOEDITOR_BUFFER_EXTERNAL, (M4OSA_Char*)("VIDEOEDITOR_BUFFER_allocatePool: poolname")); if(pool->poolName == M4OSA_NULL) { lerr = M4ERR_ALLOC; goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup; } ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Assigning Pool name buffer"); memset((void *)pool->poolName, 0,VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE); memcpy((void *)pool->poolName, (void *)poolName, VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE-1); pool->NB = nbBuffers; VIDEOEDITOR_BUFFER_allocatePool_Cleanup: if(M4NO_ERROR != lerr) { VIDEOEDITOR_SAFE_FREE(pool->pNXPBuffer); VIDEOEDITOR_SAFE_FREE(pool->poolName); VIDEOEDITOR_SAFE_FREE(pool); } *ppool = pool; ALOGV("VIDEOEDITOR_BUFFER_allocatePool END"); return lerr; }
size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) { if (mReachedEOS) { return 0; } size_t size_done = 0; size_t size_remaining = size; M4OSA_ERR err = M4NO_ERROR; M4AM_Buffer16 bgFrame = {NULL, 0}; M4AM_Buffer16 mixFrame = {NULL, 0}; M4AM_Buffer16 ptFrame = {NULL, 0}; int64_t currentSteamTS = 0; int64_t startTimeForBT = 0; M4OSA_Float fPTVolLevel = ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal)/100; M4OSA_Int16 *pPTMdata=NULL; M4OSA_UInt32 uiPCMsize = 0; bool postSeekComplete = false; bool postEOS = false; while ((size_remaining > 0)&&(err==M4NO_ERROR)) { MediaSource::ReadOptions options; { Mutex::Autolock autoLock(mLock); if (mSeeking) { if (mIsFirstBuffer) { if (mFirstBuffer != NULL) { mFirstBuffer->release(); mFirstBuffer = NULL; } mIsFirstBuffer = false; } options.setSeekTo(mSeekTimeUs); if (mInputBuffer != NULL) { mInputBuffer->release(); mInputBuffer = NULL; } mSeeking = false; if (mObserver) { postSeekComplete = true; } } } if (mInputBuffer == NULL) { status_t status = OK; if (mIsFirstBuffer) { mInputBuffer = mFirstBuffer; mFirstBuffer = NULL; status = mFirstBufferResult; mIsFirstBuffer = false; } else { { Mutex::Autolock autoLock(mLock); status = mSource->read(&mInputBuffer, &options); } // Data is Primary Track, mix with background track // after reading same size from Background track PCM file if (status == OK) { // Mix only when skim point is after startTime of BT if (((mBGAudioStoryBoardSkimTimeStamp* 1000) + (mPositionTimeMediaUs - mSeekTimeUs)) >= (int64_t)(mAudioMixSettings->uiAddCts * 1000)) { ALOGV("VideoEditorAudioPlayer::INSIDE MIXING"); ALOGV("Checking %lld <= %lld", mBGAudioPCMFileSeekPoint-mBGAudioPCMFileOriginalSeekPoint, mBGAudioPCMFileTrimmedLength); M4OSA_Void* ptr; ptr = (M4OSA_Void*)((unsigned int)mInputBuffer->data() + mInputBuffer->range_offset()); M4OSA_UInt32 len = mInputBuffer->range_length(); M4OSA_Context fp = M4OSA_NULL; uiPCMsize = (mInputBuffer->range_length())/2; pPTMdata = (M4OSA_Int16*) ((uint8_t*) mInputBuffer->data() + mInputBuffer->range_offset()); ALOGV("mix with background malloc to do len %d", len); bgFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc( len, 1, (M4OSA_Char*)"bgFrame"); bgFrame.m_bufferSize = len; mixFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc(len, 1, (M4OSA_Char*)"mixFrame"); mixFrame.m_bufferSize = len; ALOGV("mix with bgm with size %lld", mBGAudioPCMFileLength); CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, &mPositionTimeMediaUs)); if (mBGAudioPCMFileSeekPoint - mBGAudioPCMFileOriginalSeekPoint <= (mBGAudioPCMFileTrimmedLength - len)) { ALOGV("Checking mBGAudioPCMFileHandle %d", (unsigned int)mBGAudioPCMFileHandle); if (mBGAudioPCMFileHandle != M4OSA_NULL) { ALOGV("fillBuffer seeking file to %lld", mBGAudioPCMFileSeekPoint); // TODO : 32bits required for OSAL M4OSA_UInt32 tmp32 = (M4OSA_UInt32)mBGAudioPCMFileSeekPoint; err = M4OSA_fileReadSeek(mBGAudioPCMFileHandle, M4OSA_kFileSeekBeginning, (M4OSA_FilePosition*)&tmp32); mBGAudioPCMFileSeekPoint = tmp32; if (err != M4NO_ERROR){ ALOGE("M4OSA_fileReadSeek err %d",(int)err); } err = M4OSA_fileReadData(mBGAudioPCMFileHandle, (M4OSA_Int8*)bgFrame.m_dataAddress, (M4OSA_UInt32*)&len); if (err == M4WAR_NO_DATA_YET ) { ALOGV("fillBuffer End of file reached"); err = M4NO_ERROR; // We reached the end of file // move to begin cut time equal value if (mAudioMixSettings->bLoop) { mBGAudioPCMFileSeekPoint = (((int64_t)(mAudioMixSettings->beginCutMs) * mAudioMixSettings->uiSamplingFrequency) * mAudioMixSettings->uiNbChannels * sizeof(M4OSA_UInt16)) / 1000; ALOGV("fillBuffer Looping \ to mBGAudioPCMFileSeekPoint %lld", mBGAudioPCMFileSeekPoint); } else { // No mixing; // take care of volume of primary track if (fPTVolLevel < 1.0) { setPrimaryTrackVolume(pPTMdata, uiPCMsize, fPTVolLevel); } } } else if (err != M4NO_ERROR ) { ALOGV("fileReadData for audio err %d", err); } else { mBGAudioPCMFileSeekPoint += len; ALOGV("fillBuffer mBGAudioPCMFileSeekPoint \ %lld", mBGAudioPCMFileSeekPoint); // Assign the ptr data to primary track ptFrame.m_dataAddress = (M4OSA_UInt16*)ptr; ptFrame.m_bufferSize = len; // Call to mix and duck mAudioProcess->mixAndDuck( &ptFrame, &bgFrame, &mixFrame); // Overwrite the decoded buffer memcpy((void *)ptr, (void *)mixFrame.m_dataAddress, len); } } } else if (mAudioMixSettings->bLoop){ // Move to begin cut time equal value mBGAudioPCMFileSeekPoint = mBGAudioPCMFileOriginalSeekPoint; } else { // No mixing; // take care of volume level of primary track if(fPTVolLevel < 1.0) { setPrimaryTrackVolume( pPTMdata, uiPCMsize, fPTVolLevel); } } if (bgFrame.m_dataAddress) { free(bgFrame.m_dataAddress); } if (mixFrame.m_dataAddress) { free(mixFrame.m_dataAddress); } } else {
/** ******************************************************************************* * @brief Gets an access unit (AU) from the stream handler source. * @note AU is the smallest possible amount of data to be decoded by decoder * * @param context: (IN) Context of the reader * @param pStreamHandler (IN) The stream handler of the stream to make jump * @param pAccessUnit (I/O)Pointer to an access unit to fill with read data * @return M4NO_ERROR there is no error * @return M4ERR_PARAMETER at least one parameter is not properly set * @returns M4ERR_ALLOC memory allocation failed * @returns M4WAR_NO_MORE_AU there are no more access unit in the stream ******************************************************************************* */ M4OSA_ERR VideoEditorMp3Reader_getNextAu(M4OSA_Context context, M4_StreamHandler *pStreamHandler, M4_AccessUnit *pAccessUnit) { VideoEditorMp3Reader_Context *pReaderContext = (VideoEditorMp3Reader_Context*)context; M4OSA_ERR err = M4NO_ERROR; M4SYS_AccessUnit* pAu; MediaBuffer *mAudioBuffer; MediaSource::ReadOptions options; ALOGV("VideoEditorMp3Reader_getNextAu start"); M4OSA_DEBUG_IF1((pReaderContext == 0), M4ERR_PARAMETER, "VideoEditorMp3Reader_getNextAu: invalid context"); M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER, "VideoEditorMp3Reader_getNextAu: invalid pointer to M4_StreamHandler"); M4OSA_DEBUG_IF1((pAccessUnit == 0), M4ERR_PARAMETER, "VideoEditorMp3Reader_getNextAu: invalid pointer to M4_AccessUnit"); if (pStreamHandler == (M4_StreamHandler*)pReaderContext->\ mAudioStreamHandler) { pAu = &pReaderContext->mAudioAu; } else { ALOGV("VideoEditorMp3Reader_getNextAu: StreamHandler is not known\n"); return M4ERR_PARAMETER; } if (pReaderContext->mSeeking) { options.setSeekTo(pReaderContext->mSeekTime); } pReaderContext->mMediaSource->read(&mAudioBuffer, &options); if (mAudioBuffer != NULL) { if ((pAu->dataAddress == NULL) || (pAu->size < mAudioBuffer->range_length())) { if (pAu->dataAddress != NULL) { free((M4OSA_Int32*)pAu->dataAddress); pAu->dataAddress = NULL; } pAu->dataAddress = (M4OSA_Int32*)M4OSA_32bitAlignedMalloc( (mAudioBuffer->range_length() + 3) & ~0x3, M4READER_MP3, (M4OSA_Char*)"pAccessUnit->m_dataAddress" ); if (pAu->dataAddress == NULL) { ALOGV("VideoEditorMp3Reader_getNextAu malloc failed"); pReaderContext->mMediaSource->stop(); pReaderContext->mMediaSource.clear(); pReaderContext->mDataSource.clear(); return M4ERR_ALLOC; } } pAu->size = mAudioBuffer->range_length(); memcpy((M4OSA_MemAddr8)pAu->dataAddress, (const char *)mAudioBuffer->data() + mAudioBuffer->range_offset(), mAudioBuffer->range_length()); mAudioBuffer->meta_data()->findInt64(kKeyTime, (int64_t*)&pAu->CTS); pAu->CTS = pAu->CTS / 1000; /*converting the microsec to millisec */ pAu->DTS = pAu->CTS; pAu->attribute = M4SYS_kFragAttrOk; mAudioBuffer->release(); ALOGV("VideoEditorMp3Reader_getNextAu AU CTS = %ld",pAu->CTS); pAccessUnit->m_dataAddress = (M4OSA_Int8*) pAu->dataAddress; pAccessUnit->m_size = pAu->size; pAccessUnit->m_CTS = pAu->CTS; pAccessUnit->m_DTS = pAu->DTS; pAccessUnit->m_attribute = pAu->attribute; } else { ALOGV("VideoEditorMp3Reader_getNextAu EOS reached."); pAccessUnit->m_size=0; err = M4WAR_NO_MORE_AU; } pAu->nbFrag = 0; options.clearSeekTo(); pReaderContext->mSeeking = M4OSA_FALSE; mAudioBuffer = NULL; ALOGV("VideoEditorMp3Reader_getNextAu end"); return err; }
/** ******************************************************************************* * @brief Get the next stream found in the media file * * @param context: (IN) Context of the reader * @param pMediaFamily: (OUT) pointer to a user allocated * M4READER_MediaFamily that will be filled with * the media family of the found stream * @param pStreamHandler: (OUT) pointer to a stream handler that will be * allocated and filled with stream description * * @return M4NO_ERROR there is no error * @return M4WAR_NO_MORE_STREAM no more available stream in the media * @return M4ERR_PARAMETER at least one parameter is not properly set ******************************************************************************* */ M4OSA_ERR VideoEditorMp3Reader_getNextStream(M4OSA_Context context, M4READER_MediaFamily *pMediaFamily, M4_StreamHandler **pStreamHandlerParam) { VideoEditorMp3Reader_Context *pReaderContext = (VideoEditorMp3Reader_Context*)context; M4OSA_ERR err = M4NO_ERROR; M4SYS_StreamID streamIdArray[2]; M4SYS_StreamDescription streamDesc; M4_AudioStreamHandler* pAudioStreamHandler; M4_StreamHandler* pStreamHandler; M4OSA_UInt8 type, temp; M4OSA_Bool haveAudio = M4OSA_FALSE; sp<MetaData> meta = NULL; int64_t Duration; #ifndef ANDROID_DEFAULT_CODE int32_t sampleperframe =0; #endif ALOGV("VideoEditorMp3Reader_getNextStream begin"); M4OSA_DEBUG_IF1((pReaderContext == 0), M4ERR_PARAMETER, "VideoEditorMp3Reader_getNextStream: invalid context"); M4OSA_DEBUG_IF1((pMediaFamily == 0), M4ERR_PARAMETER, "VideoEditorMp3Reader_getNextStream: invalid pointer to MediaFamily"); M4OSA_DEBUG_IF1((pStreamHandlerParam == 0), M4ERR_PARAMETER, "VideoEditorMp3Reader_getNextStream: invalid pointer to StreamHandler"); ALOGV("VideoEditorMp3Reader_getNextStream stream number = %d", pReaderContext->mStreamNumber); if (pReaderContext->mStreamNumber >= 1) { ALOGV("VideoEditorMp3Reader_getNextStream max number of stream reached"); return M4WAR_NO_MORE_STREAM; } pReaderContext->mStreamNumber = pReaderContext->mStreamNumber + 1; ALOGV("VideoEditorMp3Reader_getNextStream number of Tracks%d", pReaderContext->mExtractor->countTracks()); for (temp = 0; temp < pReaderContext->mExtractor->countTracks(); temp++) { meta = pReaderContext->mExtractor->getTrackMetaData(temp); const char *mime; CHECK(meta->findCString(kKeyMIMEType, &mime)); if (!haveAudio && !strncasecmp(mime, "audio/", 6)) { pReaderContext->mMediaSource = pReaderContext->mExtractor->getTrack(temp); pReaderContext->mMediaSource->start(); haveAudio = true; } if (haveAudio) { break; } } if (!haveAudio) { ALOGV("VideoEditorMp3Reader_getNextStream no more stream "); pReaderContext->mDataSource.clear(); return M4WAR_NO_MORE_STREAM; } pReaderContext->mExtractorFlags = pReaderContext->mExtractor->flags(); *pMediaFamily = M4READER_kMediaFamilyAudio; streamDesc.duration = meta->findInt64(kKeyDuration, &Duration); streamDesc.duration = (M4OSA_Time)Duration/1000; meta->findInt32(kKeyBitRate, (int32_t*)&streamDesc.averageBitrate); meta->findInt32(kKeySampleRate, (int32_t*)&streamDesc.timeScale); ALOGV("Bitrate = %d, SampleRate = %d duration = %lld", streamDesc.averageBitrate,streamDesc.timeScale,Duration/1000); streamDesc.streamType = M4SYS_kMP3; streamDesc.profileLevel = 0xFF ; streamDesc.streamID = pReaderContext->mStreamNumber; streamDesc.decoderSpecificInfo = M4OSA_NULL; streamDesc.decoderSpecificInfoSize = 0; streamDesc.maxBitrate = streamDesc.averageBitrate; /* Allocate the audio stream handler and set its parameters */ pAudioStreamHandler = (M4_AudioStreamHandler*)M4OSA_32bitAlignedMalloc( sizeof(M4_AudioStreamHandler), M4READER_MP3, (M4OSA_Char*)"M4_AudioStreamHandler"); if (pAudioStreamHandler == M4OSA_NULL) { ALOGV("VideoEditorMp3Reader_getNextStream malloc failed"); pReaderContext->mMediaSource->stop(); pReaderContext->mMediaSource.clear(); pReaderContext->mDataSource.clear(); return M4ERR_ALLOC; } pStreamHandler =(M4_StreamHandler*)(pAudioStreamHandler); *pStreamHandlerParam = pStreamHandler; pReaderContext->mAudioStreamHandler = pAudioStreamHandler; pAudioStreamHandler->m_structSize = sizeof(M4_AudioStreamHandler); if (meta == NULL) { ALOGV("VideoEditorMp3Reader_getNextStream meta is NULL"); } pAudioStreamHandler->m_samplingFrequency = streamDesc.timeScale; pStreamHandler->m_pDecoderSpecificInfo = (M4OSA_UInt8*)(streamDesc.decoderSpecificInfo); pStreamHandler->m_decoderSpecificInfoSize = streamDesc.decoderSpecificInfoSize; meta->findInt32(kKeyChannelCount, (int32_t*)&pAudioStreamHandler->m_nbChannels); #ifndef ANDROID_DEFAULT_CODE if(meta->findInt32(kKeySamplesperframe,&sampleperframe) && sampleperframe>0){ pAudioStreamHandler->m_byteFrameLength = sampleperframe; }else{ pAudioStreamHandler->m_byteFrameLength = 1152; } #else pAudioStreamHandler->m_byteFrameLength = 1152; #endif pAudioStreamHandler->m_byteSampleSize = 2; pStreamHandler->m_pUserData = NULL; pStreamHandler->m_streamId = streamDesc.streamID; pStreamHandler->m_duration = streamDesc.duration; pReaderContext->mMaxDuration = streamDesc.duration; pStreamHandler->m_averageBitRate = streamDesc.averageBitrate; pStreamHandler->m_maxAUSize = 0; pStreamHandler->m_streamType = M4DA_StreamTypeAudioMp3; ALOGV("VideoEditorMp3Reader_getNextStream end "); return err; }