static install_status_t iterateOverNativeFiles(JNIEnv *env, jstring javaFilePath, jstring javaCpuAbi, jstring javaCpuAbi2, iterFunc callFunc, void* callArg) { ScopedUtfChars filePath(env, javaFilePath); ScopedUtfChars cpuAbi(env, javaCpuAbi); ScopedUtfChars cpuAbi2(env, javaCpuAbi2); ZipFileRO zipFile; if (zipFile.open(filePath.c_str()) != NO_ERROR) { ALOGI("Couldn't open APK %s\n", filePath.c_str()); return INSTALL_FAILED_INVALID_APK; } const int N = zipFile.getNumEntries(); char fileName[PATH_MAX]; bool hasPrimaryAbi = false; #ifdef WITH_HOUDINI bool useSecondaryAbi = false; bool noMatchAbi = false; #endif for (int i = 0; i < N; i++) { const ZipEntryRO entry = zipFile.findEntryByIndex(i); if (entry == NULL) { continue; } // Make sure this entry has a filename. if (zipFile.getEntryFileName(entry, fileName, sizeof(fileName))) { continue; } // Make sure we're in the lib directory of the ZIP. if (strncmp(fileName, APK_LIB, APK_LIB_LEN)) { continue; } // Make sure the filename is at least to the minimum library name size. const size_t fileNameLen = strlen(fileName); static const size_t minLength = APK_LIB_LEN + 2 + LIB_PREFIX_LEN + 1 + LIB_SUFFIX_LEN; if (fileNameLen < minLength) { continue; } const char* lastSlash = strrchr(fileName, '/'); ALOG_ASSERT(lastSlash != NULL, "last slash was null somehow for %s\n", fileName); // Check to make sure the CPU ABI of this file is one we support. const char* cpuAbiOffset = fileName + APK_LIB_LEN; const size_t cpuAbiRegionSize = lastSlash - cpuAbiOffset; ALOGV("Comparing ABIs %s and %s versus %s\n", cpuAbi.c_str(), cpuAbi2.c_str(), cpuAbiOffset); if (cpuAbi.size() == cpuAbiRegionSize && *(cpuAbiOffset + cpuAbi.size()) == '/' && !strncmp(cpuAbiOffset, cpuAbi.c_str(), cpuAbiRegionSize)) { ALOGV("Using primary ABI %s\n", cpuAbi.c_str()); hasPrimaryAbi = true; } else if (cpuAbi2.size() == cpuAbiRegionSize && *(cpuAbiOffset + cpuAbi2.size()) == '/' && !strncmp(cpuAbiOffset, cpuAbi2.c_str(), cpuAbiRegionSize)) { /* * If this library matches both the primary and secondary ABIs, * only use the primary ABI. */ if (hasPrimaryAbi) { ALOGV("Already saw primary ABI, skipping secondary ABI %s\n", cpuAbi2.c_str()); continue; } else { #ifdef WITH_HOUDINI useSecondaryAbi = true; #endif ALOGV("Using secondary ABI %s\n", cpuAbi2.c_str()); } } else { #ifdef WITH_HOUDINI noMatchAbi = true; #endif ALOGV("abi didn't match anything: %s (end at %zd)\n", cpuAbiOffset, cpuAbiRegionSize); continue; } // If this is a .so file, check to see if we need to copy it. if ((!strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN) && !strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN) && isFilenameSafe(lastSlash + 1)) || !strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) { install_status_t ret = callFunc(env, callArg, &zipFile, entry, lastSlash + 1); if (ret != INSTALL_SUCCEEDED) { ALOGV("Failure for entry %s", lastSlash + 1); return ret; } } } #ifdef WITH_HOUDINI if (!hasPrimaryAbi && !useSecondaryAbi && noMatchAbi) return INSTALL_FAILED_CPU_ABI_INCOMPATIBLE; if (!hasPrimaryAbi && useSecondaryAbi) return INSTALL_ABI2_SUCCEEDED; #endif return INSTALL_SUCCEEDED; }
status_t QCameraStream_Rdi::processRdiFrame( mm_camera_ch_data_buf_t *frame) { ALOGV("%s",__func__); int err = 0; int msgType = 0; int i; camera_memory_t *data = NULL; Mutex::Autolock lock(mStopCallbackLock); if(!mActive) { ALOGE("RDI Streaming Stopped. Returning callback"); return NO_ERROR; } if(mHalCamCtrl==NULL) { ALOGE("%s: X: HAL control object not set",__func__); /*Call buf done*/ return BAD_VALUE; } mHalCamCtrl->mRdiMemoryLock.lock(); mNotifyBuffer[frame->def.idx] = *frame; mHalCamCtrl->mRdiMemoryLock.unlock(); mHalCamCtrl->mCallbackLock.lock(); camera_data_callback pcb = mHalCamCtrl->mDataCb; mHalCamCtrl->mCallbackLock.unlock(); ALOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled); mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_RDI); #ifdef USE_ION struct ion_flush_data cache_inv_data; int ion_fd; cache_inv_data.vaddr = (void *)frame->def.frame->buffer; cache_inv_data.fd = frame->def.frame->fd; cache_inv_data.handle = frame->def.frame->fd_data.handle; cache_inv_data.length = frame->def.frame->ion_alloc.len; ion_fd = frame->def.frame->ion_dev_fd; if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_CACHES) < 0) ALOGE("%s: Cache clean for RDI buffer %p fd = %d failed", __func__, cache_inv_data.vaddr, cache_inv_data.fd); #endif if (pcb != NULL) { //Sending rdi callback if corresponding Msgs are enabled if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { msgType |= CAMERA_MSG_PREVIEW_FRAME; data = mHalCamCtrl->mRdiMemory.camera_memory[frame->def.idx]; } else { data = NULL; } if(msgType) { mStopCallbackLock.unlock(); if(mActive) pcb(msgType, data, 0, NULL, mHalCamCtrl->mCallbackCookie); } ALOGD("end of cb"); } if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[frame->def.idx])) { ALOGE("BUF DONE FAILED"); } return NO_ERROR; }
/* * Parse an optimized or unoptimized .dex file sitting in memory. This is * called after the byte-ordering and structure alignment has been fixed up. * * On success, return a newly-allocated DexFile. */ DexFile* dexFileParse(const u1* data, size_t length, int flags) { DexFile* pDexFile = NULL; const DexHeader* pHeader; const u1* magic; int result = -1; if (length < sizeof(DexHeader)) { ALOGE("too short to be a valid .dex"); goto bail; /* bad file format */ } pDexFile = (DexFile*) malloc(sizeof(DexFile)); if (pDexFile == NULL) goto bail; /* alloc failure */ memset(pDexFile, 0, sizeof(DexFile)); /* * Peel off the optimized header. */ if (memcmp(data, DEX_OPT_MAGIC, 4) == 0) { magic = data; if (memcmp(magic+4, DEX_OPT_MAGIC_VERS, 4) != 0) { ALOGE("bad opt version (0x%02x %02x %02x %02x)", magic[4], magic[5], magic[6], magic[7]); goto bail; } pDexFile->pOptHeader = (const DexOptHeader*) data; ALOGV("Good opt header, DEX offset is %d, flags=0x%02x", pDexFile->pOptHeader->dexOffset, pDexFile->pOptHeader->flags); /* parse the optimized dex file tables */ if (!dexParseOptData(data, length, pDexFile)) goto bail; /* ignore the opt header and appended data from here on out */ data += pDexFile->pOptHeader->dexOffset; length -= pDexFile->pOptHeader->dexOffset; if (pDexFile->pOptHeader->dexLength > length) { ALOGE("File truncated? stored len=%d, rem len=%d", pDexFile->pOptHeader->dexLength, (int) length); goto bail; } length = pDexFile->pOptHeader->dexLength; } dexFileSetupBasicPointers(pDexFile, data); pHeader = pDexFile->pHeader; if (!dexHasValidMagic(pHeader)) { goto bail; } /* * Verify the checksum(s). This is reasonably quick, but does require * touching every byte in the DEX file. The base checksum changes after * byte-swapping and DEX optimization. */ if (flags & kDexParseVerifyChecksum) { u4 adler = dexComputeChecksum(pHeader); if (adler != pHeader->checksum) { ALOGE("ERROR: bad checksum (%08x vs %08x)", adler, pHeader->checksum); if (!(flags & kDexParseContinueOnError)) goto bail; } else { ALOGV("+++ adler32 checksum (%08x) verified", adler); } const DexOptHeader* pOptHeader = pDexFile->pOptHeader; if (pOptHeader != NULL) { adler = dexComputeOptChecksum(pOptHeader); if (adler != pOptHeader->checksum) { ALOGE("ERROR: bad opt checksum (%08x vs %08x)", adler, pOptHeader->checksum); if (!(flags & kDexParseContinueOnError)) goto bail; } else { ALOGV("+++ adler32 opt checksum (%08x) verified", adler); } } } /* * Verify the SHA-1 digest. (Normally we don't want to do this -- * the digest is used to uniquely identify the original DEX file, and * can't be computed for verification after the DEX is byte-swapped * and optimized.) */ if (kVerifySignature) { unsigned char sha1Digest[kSHA1DigestLen]; const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum) + kSHA1DigestLen; dexComputeSHA1Digest(data + nonSum, length - nonSum, sha1Digest); if (memcmp(sha1Digest, pHeader->signature, kSHA1DigestLen) != 0) { char tmpBuf1[kSHA1DigestOutputLen]; char tmpBuf2[kSHA1DigestOutputLen]; ALOGE("ERROR: bad SHA1 digest (%s vs %s)", dexSHA1DigestToStr(sha1Digest, tmpBuf1), dexSHA1DigestToStr(pHeader->signature, tmpBuf2)); if (!(flags & kDexParseContinueOnError)) goto bail; } else { ALOGV("+++ sha1 digest verified"); } } if (pHeader->fileSize != length) { ALOGE("ERROR: stored file size (%d) != expected (%d)", (int) pHeader->fileSize, (int) length); if (!(flags & kDexParseContinueOnError)) goto bail; } if (pHeader->classDefsSize == 0) { ALOGE("ERROR: DEX file has no classes in it, failing"); goto bail; } /* * Success! */ result = 0; bail: if (result != 0 && pDexFile != NULL) { dexFileFree(pDexFile); pDexFile = NULL; } return pDexFile; }
void BlockIterator::seek( int64_t seekTimeUs, bool isAudio, int64_t *actualFrameTimeUs) { Mutex::Autolock autoLock(mExtractor->mLock); *actualFrameTimeUs = -1ll; const int64_t seekTimeNs = seekTimeUs * 1000ll; mkvparser::Segment* const pSegment = mExtractor->mSegment; // Special case the 0 seek to avoid loading Cues when the application // extraneously seeks to 0 before playing. if (seekTimeNs <= 0) { ALOGV("Seek to beginning: %lld", seekTimeUs); mCluster = pSegment->GetFirst(); mBlockEntryIndex = 0; do { advance_l(); } while (!eos() && block()->GetTrackNumber() != mTrackNum); return; } ALOGV("Seeking to: %lld", seekTimeUs); // If the Cues have not been located then find them. const mkvparser::Cues* pCues = pSegment->GetCues(); const mkvparser::SeekHead* pSH = pSegment->GetSeekHead(); if (!pCues && pSH) { const size_t count = pSH->GetCount(); const mkvparser::SeekHead::Entry* pEntry; ALOGV("No Cues yet"); for (size_t index = 0; index < count; index++) { pEntry = pSH->GetEntry(index); if (pEntry->id == 0x0C53BB6B) { // Cues ID long len; long long pos; pSegment->ParseCues(pEntry->pos, pos, len); pCues = pSegment->GetCues(); ALOGV("Cues found"); break; } } if (!pCues) { ALOGE("No Cues in file"); return; } } else if (!pSH) { ALOGE("No SeekHead"); return; } const mkvparser::CuePoint* pCP; while (!pCues->DoneParsing()) { pCues->LoadCuePoint(); pCP = pCues->GetLast(); if (pCP->GetTime(pSegment) >= seekTimeNs) { ALOGV("Parsed past relevant Cue"); break; } } // The Cue index is built around video keyframes mkvparser::Tracks const *pTracks = pSegment->GetTracks(); const mkvparser::Track *pTrack = NULL; for (size_t index = 0; index < pTracks->GetTracksCount(); ++index) { pTrack = pTracks->GetTrackByIndex(index); if (pTrack && pTrack->GetType() == 1) { // VIDEO_TRACK ALOGV("Video track located at %d", index); break; } } // Always *search* based on the video track, but finalize based on mTrackNum const mkvparser::CuePoint::TrackPosition* pTP; if (pTrack && pTrack->GetType() == 1) { if (!pCues->Find(seekTimeNs, pTrack, pCP, pTP)) { ALOGE("Did not find cue-point for video track at %lld", seekTimeUs); return; } } else { ALOGE("Did not locate the video track for seeking"); return; } mCluster = pSegment->FindOrPreloadCluster(pTP->m_pos); CHECK(mCluster); CHECK(!mCluster->EOS()); // mBlockEntryIndex starts at 0 but m_block starts at 1 CHECK_GT(pTP->m_block, 0); mBlockEntryIndex = pTP->m_block - 1; for (;;) { advance_l(); if (eos()) break; if (isAudio || block()->IsKey()) { // Accept the first key frame *actualFrameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL; ALOGV("Requested seek point: %lld actual: %lld", seekTimeUs, actualFrameTimeUs); break; } } }
ssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) { if (tid == gettid()) { return unwind_backtrace(backtrace, ignore_depth + 1, max_depth); } ALOGV("Unwinding thread %d from thread %d.", tid, gettid()); #ifdef CORKSCREW_HAVE_ARCH struct sigaction act; struct sigaction oact; memset(&act, 0, sizeof(act)); act.sa_sigaction = unwind_backtrace_thread_signal_handler; act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; sigemptyset(&act.sa_mask); pthread_mutex_lock(&g_unwind_signal_mutex); map_info_t* milist = acquire_my_map_info_list(); ssize_t frames = -1; if (!sigaction(SIGURG, &act, &oact)) { g_unwind_signal_state.map_info_list = milist; g_unwind_signal_state.backtrace = backtrace; g_unwind_signal_state.ignore_depth = ignore_depth; g_unwind_signal_state.max_depth = max_depth; g_unwind_signal_state.returned_frames = 0; android_atomic_release_store(tid, &g_unwind_signal_state.tid_state); // Signal the specific thread that we want to dump. int32_t tid_state = tid; if (tgkill(getpid(), tid, SIGURG)) { ALOGV("Failed to send SIGURG to thread %d.", tid); } else { // Wait for the other thread to start dumping the stack, or time out. int wait_millis = 250; for (;;) { tid_state = android_atomic_acquire_load(&g_unwind_signal_state.tid_state); if (tid_state != tid) { break; } if (wait_millis--) { ALOGV("Waiting for thread %d to start dumping the stack...", tid); usleep(1000); } else { ALOGV("Timed out waiting for thread %d to start dumping the stack.", tid); break; } } } // Try to cancel the dump if it has not started yet. if (tid_state == tid) { if (!android_atomic_acquire_cas(tid, STATE_CANCEL, &g_unwind_signal_state.tid_state)) { ALOGV("Canceled thread %d stack dump.", tid); tid_state = STATE_CANCEL; } else { tid_state = android_atomic_acquire_load(&g_unwind_signal_state.tid_state); } } // Wait indefinitely for the dump to finish or be canceled. // We cannot apply a timeout here because the other thread is accessing state that // is owned by this thread, such as milist. It should not take very // long to take the dump once started. while (tid_state == STATE_DUMPING) { ALOGV("Waiting for thread %d to finish dumping the stack...", tid); usleep(1000); tid_state = android_atomic_acquire_load(&g_unwind_signal_state.tid_state); } if (tid_state == STATE_DONE) { frames = g_unwind_signal_state.returned_frames; } sigaction(SIGURG, &oact, NULL); } release_my_map_info_list(milist); pthread_mutex_unlock(&g_unwind_signal_mutex); return frames; #else return -1; #endif }
status_t WifiDisplaySource::onReceiveClientData(const sp<AMessage> &msg) { int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); sp<RefBase> obj; CHECK(msg->findObject("data", &obj)); sp<ParsedMessage> data = static_cast<ParsedMessage *>(obj.get()); ALOGV("session %d received '%s'", sessionID, data->debugString().c_str()); AString method; AString uri; data->getRequestField(0, &method); int32_t cseq; if (!data->findInt32("cseq", &cseq)) { sendErrorResponse(sessionID, "400 Bad Request", -1 /* cseq */); return ERROR_MALFORMED; } if (method.startsWith("RTSP/")) { // This is a response. ResponseID id; id.mSessionID = sessionID; id.mCSeq = cseq; ssize_t index = mResponseHandlers.indexOfKey(id); if (index < 0) { ALOGW("Received unsolicited server response, cseq %d", cseq); return ERROR_MALFORMED; } HandleRTSPResponseFunc func = mResponseHandlers.valueAt(index); mResponseHandlers.removeItemsAt(index); status_t err = (this->*func)(sessionID, data); if (err != OK) { ALOGW("Response handler for session %d, cseq %d returned " "err %d (%s)", sessionID, cseq, err, strerror(-err)); return err; } return OK; } AString version; data->getRequestField(2, &version); if (!(version == AString("RTSP/1.0"))) { sendErrorResponse(sessionID, "505 RTSP Version not supported", cseq); return ERROR_UNSUPPORTED; } status_t err; if (method == "OPTIONS") { err = onOptionsRequest(sessionID, cseq, data); } else if (method == "SETUP") { err = onSetupRequest(sessionID, cseq, data); } else if (method == "PLAY") { err = onPlayRequest(sessionID, cseq, data); } else if (method == "PAUSE") { err = onPauseRequest(sessionID, cseq, data); } else if (method == "TEARDOWN") { err = onTeardownRequest(sessionID, cseq, data); } else if (method == "GET_PARAMETER") { err = onGetParameterRequest(sessionID, cseq, data); } else if (method == "SET_PARAMETER") { err = onSetParameterRequest(sessionID, cseq, data); } else { sendErrorResponse(sessionID, "405 Method Not Allowed", cseq); err = ERROR_UNSUPPORTED; } return err; }
int bassboost_get_strength(bassboost_context_t *context) { ALOGV("%s: ctxt %p, strength: %d", __func__, context, context->strength); return context->strength; }
void SoftFlacEncoder::onQueueFilled(OMX_U32 portIndex) { //UNUSED_UNLESS_VERBOSE(portIndex); ALOGV("SoftFlacEncoder::onQueueFilled(portIndex=%d)", portIndex); if (mSignalledError) { return; } List<BufferInfo *> &inQueue = getPortQueue(0); List<BufferInfo *> &outQueue = getPortQueue(1); while (!inQueue.empty() && !outQueue.empty()) { BufferInfo *inInfo = *inQueue.begin(); OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; BufferInfo *outInfo = *outQueue.begin(); OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { inQueue.erase(inQueue.begin()); inInfo->mOwnedByUs = false; notifyEmptyBufferDone(inHeader); outHeader->nFilledLen = 0; outHeader->nFlags = OMX_BUFFERFLAG_EOS; outQueue.erase(outQueue.begin()); outInfo->mOwnedByUs = false; notifyFillBufferDone(outHeader); return; } if (inHeader->nFilledLen > kMaxInputBufferSize) { ALOGE("input buffer too large (%d).", inHeader->nFilledLen); mSignalledError = true; notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); return; } assert(mNumChannels != 0); mEncoderWriteData = true; mEncoderReturnedEncodedData = false; mEncoderReturnedNbBytes = 0; mCurrentInputTimeStamp = inHeader->nTimeStamp; const unsigned nbInputFrames = inHeader->nFilledLen / (2 * mNumChannels); const unsigned nbInputSamples = inHeader->nFilledLen / 2; const OMX_S16 * const pcm16 = reinterpret_cast<OMX_S16 *>(inHeader->pBuffer); CHECK_LE(nbInputSamples, 2 * kMaxNumSamplesPerFrame); for (unsigned i=0 ; i < nbInputSamples ; i++) { mInputBufferPcm32[i] = (FLAC__int32) pcm16[i]; } ALOGV(" about to encode %u samples per channel", nbInputFrames); FLAC__bool ok = FLAC__stream_encoder_process_interleaved( mFlacStreamEncoder, mInputBufferPcm32, nbInputFrames /*samples per channel*/ ); if (ok) { if (mEncoderReturnedEncodedData && (mEncoderReturnedNbBytes != 0)) { ALOGV(" dequeueing buffer on output port after writing data"); outInfo->mOwnedByUs = false; outQueue.erase(outQueue.begin()); outInfo = NULL; notifyFillBufferDone(outHeader); outHeader = NULL; mEncoderReturnedEncodedData = false; } else { ALOGV(" encoder process_interleaved returned without data to write"); } } else { ALOGE(" error encountered during encoding"); mSignalledError = true; notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); return; } inInfo->mOwnedByUs = false; inQueue.erase(inQueue.begin()); inInfo = NULL; notifyEmptyBufferDone(inHeader); inHeader = NULL; } }
int32_t mm_camera_open(mm_camera_obj_t *my_obj, mm_camera_op_mode_type_t op_mode) { char dev_name[MM_CAMERA_DEV_NAME_LEN]; int32_t rc = MM_CAMERA_OK; int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES; uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP; uint8_t i; CDBG("%s: begin\n", __func__); if(my_obj->op_mode != MM_CAMERA_OP_MODE_NOTUSED) { CDBG("%s: not allowed in existing op mode %d\n", __func__, my_obj->op_mode); return -MM_CAMERA_E_INVALID_OPERATION; } if(op_mode >= MM_CAMERA_OP_MODE_MAX) { CDBG("%s: invalid input %d\n", __func__, op_mode); return -MM_CAMERA_E_INVALID_INPUT; } snprintf(dev_name, sizeof(dev_name), "/dev/%s", mm_camera_util_get_dev_name(my_obj)); //rc = mm_camera_dev_open(&my_obj->ctrl_fd, dev_name); CDBG("%s: mm_camera_dev_open rc = %d\n", __func__, rc); do { n_try--; my_obj->ctrl_fd = open(dev_name,O_RDWR | O_NONBLOCK); ALOGV("%s: ctrl_fd = %d", __func__, my_obj->ctrl_fd); ALOGV("Errno:%d",errno); if((my_obj->ctrl_fd > 0) || (errno != EIO) || (n_try <= 0 )) { ALOGV("%s: opened, break out while loop", __func__); break; } CDBG("%s:failed with I/O error retrying after %d milli-seconds", __func__,sleep_msec); usleep(sleep_msec*1000); } while(n_try>0); ALOGV("%s: after while loop", __func__); if (my_obj->ctrl_fd <= 0) { CDBG("%s: cannot open control fd of '%s' Errno = %d\n", __func__, mm_camera_util_get_dev_name(my_obj),errno); return -MM_CAMERA_E_GENERAL; } ALOGV("%s: 2\n", __func__); /* open domain socket*/ n_try=MM_CAMERA_DEV_OPEN_TRIES; do { n_try--; my_obj->ds_fd = mm_camera_socket_create(my_obj->my_id, MM_CAMERA_SOCK_TYPE_UDP); // TODO: UDP for now, change to TCP ALOGV("%s: ds_fd = %d", __func__, my_obj->ds_fd); ALOGV("Errno:%d",errno); if((my_obj->ds_fd > 0) || (n_try <= 0 )) { ALOGV("%s: opened, break out while loop", __func__); break; } CDBG("%s:failed with I/O error retrying after %d milli-seconds", __func__,sleep_msec); usleep(sleep_msec*1000); } while(n_try>0); ALOGV("%s: after while loop for domain socket open", __func__); if (my_obj->ds_fd <= 0) { CDBG_ERROR("%s: cannot open domain socket fd of '%s' Errno = %d\n", __func__, mm_camera_util_get_dev_name(my_obj),errno); close(my_obj->ctrl_fd); my_obj->ctrl_fd = -1; return -MM_CAMERA_E_GENERAL; } /* set ctrl_fd to be the mem_mapping fd */ rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, MSM_V4L2_PID_MMAP_INST, 0); if (rc != MM_CAMERA_OK) { CDBG_ERROR("error: ioctl VIDIOC_S_CTRL MSM_V4L2_PID_MMAP_INST failed: %s\n", strerror(errno)); close(my_obj->ctrl_fd); close(my_obj->ds_fd); my_obj->ctrl_fd = -1; my_obj->ds_fd = -1; return -MM_CAMERA_E_GENERAL; } if(op_mode != MM_CAMERA_OP_MODE_NOTUSED) rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, MSM_V4L2_PID_CAM_MODE, op_mode); if(!rc) { my_obj->op_mode = op_mode; my_obj->current_mode = CAMERA_MODE_2D; /* set geo mode to 2D by default */ } /* get camera capabilities */ memset(&my_obj->properties, 0, sizeof(cam_prop_t)); rc = mm_camera_send_native_ctrl_cmd(my_obj, CAMERA_GET_CAPABILITIES, sizeof(cam_prop_t), (void *)& my_obj->properties); if (rc != MM_CAMERA_OK) { CDBG_ERROR("%s: cannot get camera capabilities\n", __func__); close(my_obj->ctrl_fd); close(my_obj->ds_fd); my_obj->ctrl_fd = -1; my_obj->ds_fd = -1; return -MM_CAMERA_E_GENERAL; } mm_camera_poll_threads_init(my_obj); mm_camera_init_ch_stream_count(my_obj); CDBG("%s : Launch Threads in Cam Open",__func__); for(i = 0; i < MM_CAMERA_CH_MAX; i++) { mm_camera_poll_thread_launch(my_obj,(mm_camera_channel_type_t)i); } CDBG("%s: '%s', ctrl_fd=%d,op_mode=%d,rc=%d\n", __func__, dev_name, my_obj->ctrl_fd, my_obj->op_mode, rc); return rc; }
status_t AudioPlayer::start(bool sourceAlreadyStarted) { CHECK(!mStarted); CHECK(mSource != NULL); status_t err; if (!sourceAlreadyStarted) { mSourcePaused = false; err = mSource->start(); if (err != OK) { return err; } } ALOGD("start of Playback, useOffload %d",useOffload()); // We allow an optional INFO_FORMAT_CHANGED at the very beginning // of playback, if there is one, getFormat below will retrieve the // updated format, if there isn't, we'll stash away the valid buffer // of data to be used on the first audio callback. CHECK(mFirstBuffer == NULL); MediaSource::ReadOptions options; if (mSeeking) { options.setSeekTo(mSeekTimeUs); } do { mFirstBufferResult = mSource->read(&mFirstBuffer, &options); } while (mFirstBufferResult == -EAGAIN); if (mFirstBufferResult == INFO_FORMAT_CHANGED) { ALOGV("INFO_FORMAT_CHANGED!!!"); CHECK(mFirstBuffer == NULL); mFirstBufferResult = OK; mIsFirstBuffer = false; if (mSeeking) { mPositionTimeRealUs = 0; mPositionTimeMediaUs = mSeekTimeUs; mSeeking = false; } } else { mIsFirstBuffer = true; if (mSeeking) { mPositionTimeRealUs = 0; if (mFirstBuffer == NULL || !mFirstBuffer->meta_data()->findInt64( kKeyTime, &mPositionTimeMediaUs)) { return UNKNOWN_ERROR; } mSeeking = false; } } sp<MetaData> format = mSource->getFormat(); const char *mime; bool success = format->findCString(kKeyMIMEType, &mime); CHECK(success); CHECK(useOffload() || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); success = format->findInt32(kKeySampleRate, &mSampleRate); CHECK(success); int32_t numChannels, channelMask = 0; success = format->findInt32(kKeyChannelCount, &numChannels); CHECK(success); format->findInt64(kKeyDuration, &mDurationUs); if(!format->findInt32(kKeyChannelMask, &channelMask)) { // log only when there's a risk of ambiguity of channel mask selection ALOGI_IF(numChannels > 2, "source format didn't specify channel mask, using (%d) channel order", numChannels); channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; } else if (channelMask == 0) { channelMask = audio_channel_out_mask_from_count(numChannels); ALOGV("channel mask is zero,update from channel count %d", channelMask); } audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT; int32_t bitWidth = 16; #if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS) format->findInt32(kKeySampleBits, &bitWidth); #endif if (useOffload()) { if (mapMimeToAudioFormat(audioFormat, mime) != OK) { ALOGE("Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format", mime); audioFormat = AUDIO_FORMAT_INVALID; } else if (audio_is_linear_pcm(audioFormat) || audio_is_offload_pcm(audioFormat)) { #if defined(QCOM_HARDWARE) || defined(ENABLE_OFFLOAD_ENHANCEMENTS) // Override audio format for PCM offload if (bitWidth >= 24) { ALOGD("24-bit PCM offload enabled format=%d", audioFormat); audioFormat = AUDIO_FORMAT_PCM_24_BIT_OFFLOAD; } else { audioFormat = AUDIO_FORMAT_PCM_16_BIT_OFFLOAD; } #endif ALOGV("Mime type \"%s\" mapped to audio_format 0x%x", mime, audioFormat); } } int avgBitRate = -1; format->findInt32(kKeyBitRate, &avgBitRate); if (mAudioSink.get() != NULL) { uint32_t flags = AUDIO_OUTPUT_FLAG_NONE; audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; if (allowDeepBuffering()) { flags |= AUDIO_OUTPUT_FLAG_DEEP_BUFFER; } if (useOffload()) { flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; int64_t durationUs; if (format->findInt64(kKeyDuration, &durationUs)) { offloadInfo.duration_us = durationUs; } else { offloadInfo.duration_us = -1; } offloadInfo.sample_rate = mSampleRate; offloadInfo.channel_mask = channelMask; offloadInfo.format = audioFormat; offloadInfo.stream_type = AUDIO_STREAM_MUSIC; offloadInfo.bit_rate = avgBitRate; offloadInfo.has_video = ((mCreateFlags & HAS_VIDEO) != 0); offloadInfo.is_streaming = ((mCreateFlags & IS_STREAMING) != 0); #if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS) offloadInfo.bit_width = bitWidth >= 24 ? 24 : bitWidth; #endif } status_t err = mAudioSink->open( mSampleRate, numChannels, channelMask, audioFormat, DEFAULT_AUDIOSINK_BUFFERCOUNT, &AudioPlayer::AudioSinkCallback, this, (audio_output_flags_t)flags, useOffload() ? &offloadInfo : NULL); if (err == OK) { mLatencyUs = (int64_t)mAudioSink->latency() * 1000; mFrameSize = mAudioSink->frameSize(); if (useOffload()) { // If the playback is offloaded to h/w we pass the // HAL some metadata information // We don't want to do this for PCM because it will be going // through the AudioFlinger mixer before reaching the hardware sendMetaDataToHal(mAudioSink, format); } err = mAudioSink->start(); // do not alter behavior for non offloaded tracks: ignore start status. if (!useOffload()) { err = OK; } } if (err != OK) { if (mFirstBuffer != NULL) { mFirstBuffer->release(); mFirstBuffer = NULL; } if (!sourceAlreadyStarted) { mSource->stop(); } return err; } } else { // playing to an AudioTrack, set up mask if necessary audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ? audio_channel_out_mask_from_count(numChannels) : channelMask; if (0 == audioMask) { return BAD_VALUE; } mAudioTrack = new AudioTrack( AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask, 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0); if ((err = mAudioTrack->initCheck()) != OK) { mAudioTrack.clear(); if (mFirstBuffer != NULL) { mFirstBuffer->release(); mFirstBuffer = NULL; } if (!sourceAlreadyStarted) { mSource->stop(); } return err; } mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; mFrameSize = mAudioTrack->frameSize(); mAudioTrack->start(); } mStarted = true; mPlaying = true; mPinnedTimeUs = -1ll; const char *componentName; if (!(format->findCString(kKeyDecoderComponent, &componentName))) { componentName = "none"; } if (!strncmp(componentName, "OMX.qcom.", 9)) { mPauseRequired = true; } else { mPauseRequired = false; } return OK; }
OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter( OMX_INDEXTYPE index, const OMX_PTR params) { switch (index) { case OMX_IndexParamAudioPcm: { ALOGV("SoftFlacEncoder::internalSetParameter(OMX_IndexParamAudioPcm)"); OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) { ALOGE("SoftFlacEncoder::internalSetParameter() Error #1"); return OMX_ErrorUndefined; } if (pcmParams->nChannels < 1 || pcmParams->nChannels > 2) { return OMX_ErrorUndefined; } mNumChannels = pcmParams->nChannels; mSampleRate = pcmParams->nSamplingRate; ALOGV("will encode %d channels at %dHz", mNumChannels, mSampleRate); return configureEncoder(); } case OMX_IndexParamStandardComponentRole: { ALOGV("SoftFlacEncoder::internalSetParameter(OMX_IndexParamStandardComponentRole)"); const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; if (strncmp((const char *)roleParams->cRole, "audio_encoder.flac", OMX_MAX_STRINGNAME_SIZE - 1)) { ALOGE("SoftFlacEncoder::internalSetParameter(OMX_IndexParamStandardComponentRole)" "error"); return OMX_ErrorUndefined; } return OMX_ErrorNone; } case OMX_IndexParamAudioFlac: { // used only for setting the compression level OMX_AUDIO_PARAM_FLACTYPE *flacParams = (OMX_AUDIO_PARAM_FLACTYPE *)params; mCompressionLevel = flacParams->nCompressionLevel; // range clamping done inside encoder return OMX_ErrorNone; } case OMX_IndexParamPortDefinition: { OMX_PARAM_PORTDEFINITIONTYPE *defParams = (OMX_PARAM_PORTDEFINITIONTYPE *)params; if (defParams->nPortIndex == 0) { if (defParams->nBufferSize > kMaxInputBufferSize) { ALOGE("Input buffer size must be at most %d bytes", kMaxInputBufferSize); return OMX_ErrorUnsupportedSetting; } } // fall through } default: ALOGV("SoftFlacEncoder::internalSetParameter(default)"); return SimpleSoftOMXComponent::internalSetParameter(index, params); } }
size_t AudioPlayer::fillBuffer(void *data, size_t size) { ATRACE_CALL(); if (mNumFramesPlayed == 0) { ALOGV("AudioCallback"); } if (mReachedEOS) { return 0; } bool postSeekComplete = false; bool postEOS = false; int64_t postEOSDelayUs = 0; size_t size_done = 0; size_t size_remaining = size; while (size_remaining > 0) { MediaSource::ReadOptions options; bool refreshSeekTime = false; { Mutex::Autolock autoLock(mLock); if (mSeeking) { if (mIsFirstBuffer) { if (mFirstBuffer != NULL) { mFirstBuffer->release(); mFirstBuffer = NULL; } mIsFirstBuffer = false; } options.setSeekTo(mSeekTimeUs); refreshSeekTime = true; if (mInputBuffer != NULL) { mInputBuffer->release(); mInputBuffer = NULL; } mSeeking = false; if (mObserver) { postSeekComplete = true; } } } if (mInputBuffer == NULL) { status_t err; if (mIsFirstBuffer) { mInputBuffer = mFirstBuffer; mFirstBuffer = NULL; err = mFirstBufferResult; mIsFirstBuffer = false; } else { if(!mSourcePaused) { err = mSource->read(&mInputBuffer, &options); if (err == OK && mInputBuffer == NULL && mSourcePaused) { ALOGV("mSourcePaused, return 0 from fillBuffer"); return 0; } } else { break; } } if(err == -EAGAIN) { if(mSourcePaused){ break; } else { continue; } } CHECK((err == OK && mInputBuffer != NULL) || (err != OK && mInputBuffer == NULL)); Mutex::Autolock autoLock(mLock); if (err != OK && err != INFO_FORMAT_CHANGED) { if (!mReachedEOS) { if (useOffload()) { // After seek there is a possible race condition if // OffloadThread is observing state_stopping_1 before // framesReady() > 0. Ensure sink stop is called // after last buffer is released. This ensures the // partial buffer is written to the driver before // stopping one is observed.The drawback is that // there will be an unnecessary call to the parser // after parser signalled EOS. int64_t playPosition = 0; playPosition = getOutputPlayPositionUs_l(); if ((size_done > 0) && (playPosition < mDurationUs)) { ALOGW("send Partial buffer down\n"); ALOGW("skip calling stop till next fillBuffer\n"); break; } // no more buffers to push - stop() and wait for STREAM_END // don't set mReachedEOS until stream end received if (mAudioSink != NULL) { mAudioSink->stop(); } else { mAudioTrack->stop(); } } else { if (mObserver) { // We don't want to post EOS right away but only // after all frames have actually been played out. // These are the number of frames submitted to the // AudioTrack that you haven't heard yet. uint32_t numFramesPendingPlayout = getNumFramesPendingPlayout(); // These are the number of frames we're going to // submit to the AudioTrack by returning from this // callback. uint32_t numAdditionalFrames = size_done / mFrameSize; numFramesPendingPlayout += numAdditionalFrames; int64_t timeToCompletionUs = (1000000ll * numFramesPendingPlayout) / mSampleRate; ALOGV("total number of frames played: %lld (%lld us)", (mNumFramesPlayed + numAdditionalFrames), 1000000ll * (mNumFramesPlayed + numAdditionalFrames) / mSampleRate); ALOGV("%d frames left to play, %lld us (%.2f secs)", numFramesPendingPlayout, timeToCompletionUs, timeToCompletionUs / 1E6); postEOS = true; if (mAudioSink->needsTrailingPadding()) { postEOSDelayUs = timeToCompletionUs + mLatencyUs; } else { postEOSDelayUs = 0; } } mReachedEOS = true; } } mFinalStatus = err; break; } if (mAudioSink != NULL) { mLatencyUs = (int64_t)mAudioSink->latency() * 1000; } else { mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; } if(mInputBuffer->range_length() != 0) { CHECK(mInputBuffer->meta_data()->findInt64( kKeyTime, &mPositionTimeMediaUs)); } // need to adjust the mStartPosUs for offload decoding since parser // might not be able to get the exact seek time requested. if (refreshSeekTime) { if (useOffload()) { if (postSeekComplete) { ALOGV("fillBuffer is going to post SEEK_COMPLETE"); mObserver->postAudioSeekComplete(); postSeekComplete = false; } mStartPosUs = mPositionTimeMediaUs; ALOGV("adjust seek time to: %.2f", mStartPosUs/ 1E6); } // clear seek time with mLock locked and once we have valid mPositionTimeMediaUs // and mPositionTimeRealUs // before clearing mSeekTimeUs check if a new seek request has been received while // we were reading from the source with mLock released. if (!mSeeking) { mSeekTimeUs = 0; } } if (!useOffload()) { mPositionTimeRealUs = ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) / mSampleRate; ALOGV("buffer->size() = %d, " "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", mInputBuffer->range_length(), mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); } } if (mInputBuffer->range_length() == 0) { mInputBuffer->release(); mInputBuffer = NULL; continue; } size_t copy = size_remaining; if (copy > mInputBuffer->range_length()) { copy = mInputBuffer->range_length(); } memcpy((char *)data + size_done, (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), copy); mInputBuffer->set_range(mInputBuffer->range_offset() + copy, mInputBuffer->range_length() - copy); size_done += copy; size_remaining -= copy; } if (useOffload()) { // We must ask the hardware what it has played mPositionTimeRealUs = getOutputPlayPositionUs_l(); ALOGV("mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); } { Mutex::Autolock autoLock(mLock); mNumFramesPlayed += size_done / mFrameSize; if (mReachedEOS) { mPinnedTimeUs = mNumFramesPlayedSysTimeUs; } else { mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); mPinnedTimeUs = -1ll; } } if (postEOS) { mObserver->postAudioEOS(postEOSDelayUs); } if (postSeekComplete) { mObserver->postAudioSeekComplete(); } return size_done; }
void AudioPlayer::reset() { CHECK(mStarted); ALOGD("reset: mPlaying=%d mReachedEOS=%d useOffload=%d", mPlaying, mReachedEOS, useOffload() ); if (mAudioSink.get() != NULL) { mAudioSink->stop(); // If we're closing and have reached EOS, we don't want to flush // the track because if it is offloaded there could be a small // amount of residual data in the hardware buffer which we must // play to give gapless playback. // But if we're resetting when paused or before we've reached EOS // we can't be doing a gapless playback and there could be a large // amount of data queued in the hardware if the track is offloaded, // so we must flush to prevent a track switch being delayed playing // the buffered data that we don't want now if (!mPlaying || !mReachedEOS) { mAudioSink->flush(); } mAudioSink->close(); } else { mAudioTrack->stop(); if (!mPlaying || !mReachedEOS) { mAudioTrack->flush(); } mAudioTrack.clear(); } // Make sure to release any buffer we hold onto so that the // source is able to stop(). if (mFirstBuffer != NULL) { mFirstBuffer->release(); mFirstBuffer = NULL; } if (mInputBuffer != NULL) { ALOGV("AudioPlayer releasing input buffer."); mInputBuffer->release(); mInputBuffer = NULL; } mSourcePaused = false; mSource->stop(); // The following hack is necessary to ensure that the OMX // component is completely released by the time we may try // to instantiate it again. // When offloading, the OMX component is not used so this hack // is not needed sp<MetaData> format = mSource->getFormat(); const char *mime; format->findCString(kKeyMIMEType, &mime); if (!useOffload() || (useOffload() && !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW))) { wp<MediaSource> tmp = mSource; mSource.clear(); while (tmp.promote() != NULL) { usleep(1000); } } else { mSource.clear(); } IPCThreadState::self()->flushCommands(); mNumFramesPlayed = 0; mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); mPositionTimeMediaUs = -1; mPositionTimeRealUs = -1; mSeeking = false; mSeekTimeUs = 0; mReachedEOS = false; mFinalStatus = OK; mStarted = false; mPlaying = false; mStartPosUs = 0; mPauseRequired = false; }
int offload_reverb_send_params(struct mixer_ctl *ctl, struct reverb_params reverb, unsigned param_send_flags) { int param_values[128] = {0}; int *p_param_values = param_values; ALOGV("%s: flags 0x%x", __func__, param_send_flags); *p_param_values++ = REVERB_MODULE; *p_param_values++ = reverb.device; *p_param_values++ = 0; /* num of commands*/ if (param_send_flags & OFFLOAD_SEND_REVERB_ENABLE_FLAG) { *p_param_values++ = REVERB_ENABLE; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_ENABLE_PARAM_LEN; *p_param_values++ = reverb.enable_flag; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_MODE) { *p_param_values++ = REVERB_MODE; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_MODE_PARAM_LEN; *p_param_values++ = reverb.mode; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_PRESET) { *p_param_values++ = REVERB_PRESET; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_PRESET_PARAM_LEN; *p_param_values++ = reverb.preset; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_WET_MIX) { *p_param_values++ = REVERB_WET_MIX; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_WET_MIX_PARAM_LEN; *p_param_values++ = reverb.wet_mix; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_GAIN_ADJUST) { *p_param_values++ = REVERB_GAIN_ADJUST; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_GAIN_ADJUST_PARAM_LEN; *p_param_values++ = reverb.gain_adjust; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_ROOM_LEVEL) { *p_param_values++ = REVERB_ROOM_LEVEL; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_ROOM_LEVEL_PARAM_LEN; *p_param_values++ = reverb.room_level; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_ROOM_HF_LEVEL) { *p_param_values++ = REVERB_ROOM_HF_LEVEL; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_ROOM_HF_LEVEL_PARAM_LEN; *p_param_values++ = reverb.room_hf_level; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_DECAY_TIME) { *p_param_values++ = REVERB_DECAY_TIME; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_DECAY_TIME_PARAM_LEN; *p_param_values++ = reverb.decay_time; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_DECAY_HF_RATIO) { *p_param_values++ = REVERB_DECAY_HF_RATIO; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_DECAY_HF_RATIO_PARAM_LEN; *p_param_values++ = reverb.decay_hf_ratio; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL) { *p_param_values++ = REVERB_REFLECTIONS_LEVEL; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_REFLECTIONS_LEVEL_PARAM_LEN; *p_param_values++ = reverb.reflections_level; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY) { *p_param_values++ = REVERB_REFLECTIONS_DELAY; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_REFLECTIONS_DELAY_PARAM_LEN; *p_param_values++ = reverb.reflections_delay; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_LEVEL) { *p_param_values++ = REVERB_LEVEL; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_LEVEL_PARAM_LEN; *p_param_values++ = reverb.level; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_DELAY) { *p_param_values++ = REVERB_DELAY; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_DELAY_PARAM_LEN; *p_param_values++ = reverb.delay; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_DIFFUSION) { *p_param_values++ = REVERB_DIFFUSION; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_DIFFUSION_PARAM_LEN; *p_param_values++ = reverb.diffusion; param_values[2] += 1; } if (param_send_flags & OFFLOAD_SEND_REVERB_DENSITY) { *p_param_values++ = REVERB_DENSITY; *p_param_values++ = CONFIG_SET; *p_param_values++ = 0; /* start offset if param size if greater than 128 */ *p_param_values++ = REVERB_DENSITY_PARAM_LEN; *p_param_values++ = reverb.density; param_values[2] += 1; } if (param_values[2] && ctl) mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values)); return 0; }
void AudioSource::waitOutstandingEncodingFrames_l() { ALOGV("waitOutstandingEncodingFrames_l: %lld", mNumClientOwnedBuffers); while (mNumClientOwnedBuffers > 0) { mFrameEncodingCompletionCondition.wait(mLock); } }
int wifi_wait_on_socket(char *buf, size_t buflen) { size_t nread = buflen - 1; int result; char *match, *match2; if (monitor_conn == NULL) { return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed"); } result = wifi_ctrl_recv(buf, &nread); /* Terminate reception on exit socket */ if (result == -2) { return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed"); } if (result < 0) { ALOGD("wifi_ctrl_recv failed: %s\n", strerror(errno)); return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - recv error"); } buf[nread] = '\0'; /* Check for EOF on the socket */ if (result == 0 && nread == 0) { /* Fabricate an event to pass up */ ALOGD("Received EOF on supplicant socket\n"); return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - signal 0 received"); } /* * Events strings are in the format * * IFNAME=iface <N>CTRL-EVENT-XXX * or * <N>CTRL-EVENT-XXX * * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG, * etc.) and XXX is the event name. The level information is not useful * to us, so strip it off. */ if (strncmp(buf, IFNAME, IFNAMELEN) == 0) { match = strchr(buf, ' '); if (match != NULL) { if (match[1] == '<') { match2 = strchr(match + 2, '>'); if (match2 != NULL) { nread -= (match2 - match); memmove(match + 1, match2 + 1, nread - (match - buf) + 1); } } } else { return snprintf(buf, buflen, "%s", WPA_EVENT_IGNORE); } } else if (buf[0] == '<') { match = strchr(buf, '>'); if (match != NULL) { nread -= (match + 1 - buf); memmove(buf, match + 1, nread + 1); ALOGV("supplicant generated event without interface - %s\n", buf); } } else { /* let the event go as is! */ ALOGW("supplicant generated event without interface and without message level - %s\n", buf); } return nread; }
/*=========================================================================== * FUNCTION : allocate * * DESCRIPTION: allocate requested number of buffers of certain size * * PARAMETERS : * @count : number of buffers to be allocated * @size : lenght of the buffer to be allocated * * RETURN : int32_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ int QCameraGrallocMemory::allocate(int count, int /*size*/) { int err = 0; status_t ret = NO_ERROR; int gralloc_usage = 0; struct ion_fd_data ion_info_fd; memset(&ion_info_fd, 0, sizeof(ion_info_fd)); ALOGI(" %s : E ", __FUNCTION__); if (!mWindow) { ALOGE("Invalid native window"); return INVALID_OPERATION; } // Increment buffer count by min undequeued buffer. err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers); if (err != 0) { ALOGE("get_min_undequeued_buffer_count failed: %s (%d)", strerror(-err), -err); ret = UNKNOWN_ERROR; goto end; } count += mMinUndequeuedBuffers; err = mWindow->set_buffer_count(mWindow, count); if (err != 0) { ALOGE("set_buffer_count failed: %s (%d)", strerror(-err), -err); ret = UNKNOWN_ERROR; goto end; } err = mWindow->set_buffers_geometry(mWindow, mWidth, mHeight, mFormat); if (err != 0) { ALOGE("%s: set_buffers_geometry failed: %s (%d)", __func__, strerror(-err), -err); ret = UNKNOWN_ERROR; goto end; } gralloc_usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP; err = mWindow->set_usage(mWindow, gralloc_usage); if(err != 0) { /* set_usage error out */ ALOGE("%s: set_usage rc = %d", __func__, err); ret = UNKNOWN_ERROR; goto end; } ALOGD("%s: usage = %d, geometry: %p, %d, %d, %d", __func__, gralloc_usage, mWindow, mWidth, mHeight, mFormat); //Allocate cnt number of buffers from native window for (int cnt = 0; cnt < count; cnt++) { int stride; err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride); if(!err) { ALOGV("dequeue buf hdl =%p", mBufferHandle[cnt]); mLocalFlag[cnt] = BUFFER_OWNED; } else { mLocalFlag[cnt] = BUFFER_NOT_OWNED; ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err); } ALOGV("%s: dequeue buf: %p\n", __func__, mBufferHandle[cnt]); if(err != 0) { ALOGE("%s: dequeue_buffer failed: %s (%d)", __func__, strerror(-err), -err); ret = UNKNOWN_ERROR; for(int i = 0; i < cnt; i++) { if(mLocalFlag[i] != BUFFER_NOT_OWNED) { err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i])); } mLocalFlag[i] = BUFFER_NOT_OWNED; mBufferHandle[i] = NULL; } memset(&mMemInfo, 0, sizeof(mMemInfo)); goto end; } mPrivateHandle[cnt] = (struct private_handle_t *)(*mBufferHandle[cnt]); mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY); if (mMemInfo[cnt].main_ion_fd < 0) { ALOGE("%s: failed: could not open ion device", __func__); for(int i = 0; i < cnt; i++) { struct ion_handle_data ion_handle; memset(&ion_handle, 0, sizeof(ion_handle)); ion_handle.handle = mMemInfo[i].handle; if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { ALOGE("%s: ion free failed", __func__); } close(mMemInfo[i].main_ion_fd); if(mLocalFlag[i] != BUFFER_NOT_OWNED) { err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i])); } mLocalFlag[i] = BUFFER_NOT_OWNED; mBufferHandle[i] = NULL; } memset(&mMemInfo, 0, sizeof(mMemInfo)); ret = UNKNOWN_ERROR; goto end; } else { ion_info_fd.fd = mPrivateHandle[cnt]->fd; if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_IMPORT, &ion_info_fd) < 0) { ALOGE("%s: ION import failed\n", __func__); for(int i = 0; i < cnt; i++) { struct ion_handle_data ion_handle; memset(&ion_handle, 0, sizeof(ion_handle)); ion_handle.handle = mMemInfo[i].handle; if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { ALOGE("ion free failed"); } close(mMemInfo[i].main_ion_fd); if(mLocalFlag[i] != BUFFER_NOT_OWNED) { err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i])); } mLocalFlag[i] = BUFFER_NOT_OWNED; mBufferHandle[i] = NULL; } close(mMemInfo[cnt].main_ion_fd); memset(&mMemInfo, 0, sizeof(mMemInfo)); ret = UNKNOWN_ERROR; goto end; } } mCameraMemory[cnt] = mGetMemory(mPrivateHandle[cnt]->fd, mPrivateHandle[cnt]->size, 1, (void *)this); ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__, cnt, mPrivateHandle[cnt]->fd, mPrivateHandle[cnt]->size, mPrivateHandle[cnt]->offset); mMemInfo[cnt].fd = mPrivateHandle[cnt]->fd; mMemInfo[cnt].size = mPrivateHandle[cnt]->size; mMemInfo[cnt].handle = ion_info_fd.handle; } mBufferCount = count; //Cancel min_undequeued_buffer buffers back to the window for (int i = 0; i < mMinUndequeuedBuffers; i ++) { err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); mLocalFlag[i] = BUFFER_NOT_OWNED; } end: ALOGI(" %s : X ",__func__); return ret; }
/* * Get some per-thread stats. * * This is currently generated by opening the appropriate "stat" file * in /proc and reading the pile of stuff that comes out. */ bool dvmGetThreadStats(ProcStatData* pData, pid_t tid) { /* int pid; char comm[128]; char state; int ppid, pgrp, session, tty_nr, tpgid; unsigned long flags, minflt, cminflt, majflt, cmajflt, utime, stime; long cutime, cstime, priority, nice, zero, itrealvalue; unsigned long starttime, vsize; long rss; unsigned long rlim, startcode, endcode, startstack, kstkesp, kstkeip; unsigned long signal, blocked, sigignore, sigcatch, wchan, nswap, cnswap; int exit_signal, processor; unsigned long rt_priority, policy; scanf("%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld " "%ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu " "%lu %lu %lu %d %d %lu %lu", &pid, comm, &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, &minflt, &cminflt, &majflt, &cmajflt, &utime, &stime, &cutime, &cstime, &priority, &nice, &zero, &itrealvalue, &starttime, &vsize, &rss, &rlim, &startcode, &endcode, &startstack, &kstkesp, &kstkeip, &signal, &blocked, &sigignore, &sigcatch, &wchan, &nswap, &cnswap, &exit_signal, &processor, &rt_priority, &policy); (new: delayacct_blkio_ticks %llu (since Linux 2.6.18)) */ char nameBuf[64]; int i, fd; /* * Open and read the appropriate file. This is expected to work on * Linux but will fail on other platforms (e.g. Mac sim). */ sprintf(nameBuf, "/proc/self/task/%d/stat", (int) tid); fd = open(nameBuf, O_RDONLY); if (fd < 0) { ALOGV("Unable to open '%s': %s", nameBuf, strerror(errno)); return false; } char lineBuf[512]; /* > 2x typical */ int cc = read(fd, lineBuf, sizeof(lineBuf)-1); if (cc <= 0) { const char* msg = (cc == 0) ? "unexpected EOF" : strerror(errno); ALOGI("Unable to read '%s': %s", nameBuf, msg); close(fd); return false; } close(fd); lineBuf[cc] = '\0'; /* * Skip whitespace-separated tokens. For the most part we can assume * that tokens do not contain spaces, and are separated by exactly one * space character. The only exception is the second field ("comm") * which may contain spaces but is surrounded by parenthesis. */ char* cp = strchr(lineBuf, ')'); if (cp == NULL) goto parse_fail; cp++; for (i = 2; i < 13; i++) { cp = strchr(cp+1, ' '); if (cp == NULL) goto parse_fail; } /* * Grab utime/stime. */ char* endp; pData->utime = strtoul(cp+1, &endp, 10); if (endp == cp+1) ALOGI("Warning: strtoul failed on utime ('%.30s...')", cp); cp = strchr(cp+1, ' '); if (cp == NULL) goto parse_fail; pData->stime = strtoul(cp+1, &endp, 10); if (endp == cp+1) ALOGI("Warning: strtoul failed on stime ('%.30s...')", cp); /* * Skip more stuff we don't care about. */ for (i = 14; i < 38; i++) { cp = strchr(cp+1, ' '); if (cp == NULL) goto parse_fail; } /* * Grab processor number. */ pData->processor = strtol(cp+1, &endp, 10); if (endp == cp+1) ALOGI("Warning: strtoul failed on processor ('%.30s...')", cp); return true; parse_fail: ALOGI("stat parse failed (%s)", lineBuf); return false; }
/* * ת»»»ù±¾Êý¾Ý£¬×°ÏäÊý¾Ý´Ó'srcPtr'µ½'dstPtr' eg. * byte to short, int, long, float, double * short to int, long, float double * char to int, long, float, double * int to long, float, double * long to float, double * float to double */ int dvmConvertPrimitiveValue(PrimitiveType srcType, PrimitiveType dstType, const s4* srcPtr, s4* dstPtr) { enum Conversion { OK4, OK8, ItoJ, ItoD, JtoD, FtoD, ItoF, JtoF, bad }; enum Conversion conv; #ifdef ARCH_HAVE_ALIGNED_DOUBLES double ret; #endif assert((srcType != PRIM_VOID) && (srcType != PRIM_NOT)); assert((dstType != PRIM_VOID) && (dstType != PRIM_NOT)); switch (dstType) { case PRIM_BOOLEAN: case PRIM_CHAR: case PRIM_BYTE: { conv = (srcType == dstType) ? OK4 : bad; break; } case PRIM_SHORT: { switch (srcType) { case PRIM_BYTE: case PRIM_SHORT: conv = OK4; break; default: conv = bad; break; } break; } case PRIM_INT: { switch (srcType) { case PRIM_BYTE: case PRIM_CHAR: case PRIM_SHORT: case PRIM_INT: conv = OK4; break; default: conv = bad; break; } break; } case PRIM_LONG: { switch (srcType) { case PRIM_BYTE: case PRIM_CHAR: case PRIM_SHORT: case PRIM_INT: conv = ItoJ; break; case PRIM_LONG: conv = OK8; break; default: conv = bad; break; } break; } case PRIM_FLOAT: { switch (srcType) { case PRIM_BYTE: case PRIM_CHAR: case PRIM_SHORT: case PRIM_INT: conv = ItoF; break; case PRIM_LONG: conv = JtoF; break; case PRIM_FLOAT: conv = OK4; break; default: conv = bad; break; } break; } case PRIM_DOUBLE: { switch (srcType) { case PRIM_BYTE: case PRIM_CHAR: case PRIM_SHORT: case PRIM_INT: conv = ItoD; break; case PRIM_LONG: conv = JtoD; break; case PRIM_FLOAT: conv = FtoD; break; case PRIM_DOUBLE: conv = OK8; break; default: conv = bad; break; } break; } case PRIM_VOID: case PRIM_NOT: default: { conv = bad; break; } } switch (conv) { case OK4: *dstPtr = *srcPtr; return 1; case OK8: *(s8*) dstPtr = *(s8*)srcPtr; return 2; case ItoJ: *(s8*) dstPtr = (s8) (*(s4*) srcPtr); return 2; #ifndef ARCH_HAVE_ALIGNED_DOUBLES case ItoD: *(double*) dstPtr = (double) (*(s4*) srcPtr); return 2; case JtoD: *(double*) dstPtr = (double) (*(long long*) srcPtr); return 2; case FtoD: *(double*) dstPtr = (double) (*(float*) srcPtr); return 2; #else case ItoD: ret = (double) (*(s4*) srcPtr); memcpy(dstPtr, &ret, 8); return 2; case JtoD: ret = (double) (*(long long*) srcPtr); memcpy(dstPtr, &ret, 8); return 2; case FtoD: ret = (double) (*(float*) srcPtr); memcpy(dstPtr, &ret, 8); return 2; #endif case ItoF: *(float*) dstPtr = (float) (*(int*) srcPtr); return 1; case JtoF: *(float*) dstPtr = (float) (*(long long*) srcPtr); return 1; case bad: { ALOGV("illegal primitive conversion: '%s' to '%s'", dexGetPrimitiveTypeDescriptor(srcType), dexGetPrimitiveTypeDescriptor(dstType)); return -1; } default: { dvmAbort(); return -1; // Keep the compiler happy. } } }
status_t setNativeWindowSizeFormatAndUsage( ANativeWindow *nativeWindow /* nonnull */, int width, int height, int format, int rotation, int usage, bool reconnect) { status_t err = NO_ERROR; // In some cases we need to reconnect so that we can dequeue all buffers if (reconnect) { err = native_window_api_disconnect(nativeWindow, NATIVE_WINDOW_API_MEDIA); if (err != NO_ERROR) { ALOGE("native_window_api_disconnect failed: %s (%d)", strerror(-err), -err); return err; } err = native_window_api_connect(nativeWindow, NATIVE_WINDOW_API_MEDIA); if (err != NO_ERROR) { ALOGE("native_window_api_connect failed: %s (%d)", strerror(-err), -err); return err; } } err = native_window_set_buffers_dimensions(nativeWindow, width, height); if (err != NO_ERROR) { ALOGE("native_window_set_buffers_dimensions failed: %s (%d)", strerror(-err), -err); return err; } err = native_window_set_buffers_format(nativeWindow, format); if (err != NO_ERROR) { ALOGE("native_window_set_buffers_format failed: %s (%d)", strerror(-err), -err); return err; } int transform = 0; if ((rotation % 90) == 0) { switch ((rotation / 90) & 3) { case 1: transform = HAL_TRANSFORM_ROT_90; break; case 2: transform = HAL_TRANSFORM_ROT_180; break; case 3: transform = HAL_TRANSFORM_ROT_270; break; default: transform = 0; break; } } err = native_window_set_buffers_transform(nativeWindow, transform); if (err != NO_ERROR) { ALOGE("native_window_set_buffers_transform failed: %s (%d)", strerror(-err), -err); return err; } int consumerUsage = 0; err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage); if (err != NO_ERROR) { ALOGW("failed to get consumer usage bits. ignoring"); err = NO_ERROR; } // Make sure to check whether either Stagefright or the video decoder // requested protected buffers. if (usage & GRALLOC_USAGE_PROTECTED) { // Check if the ANativeWindow sends images directly to SurfaceFlinger. int queuesToNativeWindow = 0; err = nativeWindow->query( nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &queuesToNativeWindow); if (err != NO_ERROR) { ALOGE("error authenticating native window: %s (%d)", strerror(-err), -err); return err; } // Check if the ANativeWindow uses hardware protected buffers. if (queuesToNativeWindow != 1 && !(consumerUsage & GRALLOC_USAGE_PROTECTED)) { ALOGE("native window could not be authenticated"); return PERMISSION_DENIED; } } int finalUsage = usage | consumerUsage; ALOGV("gralloc usage: %#x(producer) + %#x(consumer) = %#x", usage, consumerUsage, finalUsage); err = native_window_set_usage(nativeWindow, finalUsage); if (err != NO_ERROR) { ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); return err; } err = native_window_set_scaling_mode( nativeWindow, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); if (err != NO_ERROR) { ALOGE("native_window_set_scaling_mode failed: %s (%d)", strerror(-err), -err); return err; } ALOGD("set up nativeWindow %p for %dx%d, color %#x, rotation %d, usage %#x", nativeWindow, width, height, format, rotation, finalUsage); return NO_ERROR; }
void BlockIterator::advance_l() { for (;;) { long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry); ALOGV("GetEntry returned %ld", res); long long pos; long len; if (res < 0) { // Need to parse this cluster some more CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL); res = mCluster->Parse(pos, len); ALOGV("Parse returned %ld", res); if (res < 0) { // I/O error ALOGE("Cluster::Parse returned result %ld", res); mCluster = NULL; break; } continue; } else if (res == 0) { // We're done with this cluster const mkvparser::Cluster *nextCluster; res = mExtractor->mSegment->ParseNext( mCluster, nextCluster, pos, len); ALOGV("ParseNext returned %ld", res); if (res != 0) { // EOF or error mCluster = NULL; break; } CHECK_EQ(res, 0); CHECK(nextCluster != NULL); CHECK(!nextCluster->EOS()); mCluster = nextCluster; res = mCluster->Parse(pos, len); ALOGV("Parse (2) returned %ld", res); CHECK_GE(res, 0); mBlockEntryIndex = 0; continue; } CHECK(mBlockEntry != NULL); CHECK(mBlockEntry->GetBlock() != NULL); ++mBlockEntryIndex; if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { break; } } }
// static sp<VBRISeeker> VBRISeeker::CreateFromSource( const sp<DataSource> &source, off64_t post_id3_pos) { off64_t pos = post_id3_pos; uint8_t header[4]; ssize_t n = source->readAt(pos, header, sizeof(header)); if (n < (ssize_t)sizeof(header)) { return NULL; } uint32_t tmp = U32_AT(&header[0]); size_t frameSize; int sampleRate; if (!GetMPEGAudioFrameSize(tmp, &frameSize, &sampleRate)) { return NULL; } // VBRI header follows 32 bytes after the header _ends_. pos += sizeof(header) + 32; uint8_t vbriHeader[26]; n = source->readAt(pos, vbriHeader, sizeof(vbriHeader)); if (n < (ssize_t)sizeof(vbriHeader)) { return NULL; } if (memcmp(vbriHeader, "VBRI", 4)) { return NULL; } size_t numFrames = U32_AT(&vbriHeader[14]); int64_t durationUs = numFrames * 1000000ll * (sampleRate >= 32000 ? 1152 : 576) / sampleRate; ALOGV("duration = %.2f secs", durationUs / 1E6); size_t numEntries = U16_AT(&vbriHeader[18]); size_t entrySize = U16_AT(&vbriHeader[22]); size_t scale = U16_AT(&vbriHeader[20]); ALOGV("%zu entries, scale=%zu, size_per_entry=%zu", numEntries, scale, entrySize); size_t totalEntrySize = numEntries * entrySize; uint8_t *buffer = new uint8_t[totalEntrySize]; n = source->readAt(pos + sizeof(vbriHeader), buffer, totalEntrySize); if (n < (ssize_t)totalEntrySize) { delete[] buffer; buffer = NULL; return NULL; } sp<VBRISeeker> seeker = new VBRISeeker; seeker->mBasePos = post_id3_pos + frameSize; // only update mDurationUs if the calculated duration is valid (non zero) // otherwise, leave duration at -1 so that getDuration() and getOffsetForTime() // return false when called, to indicate that this vbri tag does not have the // requested information if (durationUs) { seeker->mDurationUs = durationUs; } off64_t offset = post_id3_pos; for (size_t i = 0; i < numEntries; ++i) { uint32_t numBytes; switch (entrySize) { case 1: numBytes = buffer[i]; break; case 2: numBytes = U16_AT(buffer + 2 * i); break; case 3: numBytes = U24_AT(buffer + 3 * i); break; default: { CHECK_EQ(entrySize, 4u); numBytes = U32_AT(buffer + 4 * i); break; } } numBytes *= scale; seeker->mSegments.push(numBytes); ALOGV("entry #%zu: %u offset %#016llx", i, numBytes, (long long)offset); offset += numBytes; } delete[] buffer; buffer = NULL; ALOGI("Found VBRI header."); return seeker; }
void MatroskaExtractor::addTracks() { const mkvparser::Tracks *tracks = mSegment->GetTracks(); for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { const mkvparser::Track *track = tracks->GetTrackByIndex(index); if (track == NULL) { // Apparently this is currently valid (if unexpected) behaviour // of the mkv parser lib. continue; } const char *const codecID = track->GetCodecId(); ALOGV("codec id = %s", codecID); ALOGV("codec name = %s", track->GetCodecNameAsUTF8()); size_t codecPrivateSize; const unsigned char *codecPrivate = track->GetCodecPrivate(codecPrivateSize); enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; sp<MetaData> meta = new MetaData; status_t err = OK; switch (track->GetType()) { case VIDEO_TRACK: { const mkvparser::VideoTrack *vtrack = static_cast<const mkvparser::VideoTrack *>(track); if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); } else if (!strcmp("V_MPEG4/ISO/SP", codecID) || !strcmp("V_MPEG4/ISO/ASP", codecID) || !strcmp("V_MPEG4/ISO/AP", codecID)) { meta->setCString( kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); if (codecPrivateSize > 0) { addESDSFromCodecPrivate( meta, false, codecPrivate, codecPrivateSize); } else { ALOGW("%s is detected, but does not have configuration.", codecID); } } else if (!strcmp("V_VP8", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); } else if (!strcmp("V_VP9", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); } else { ALOGW("%s is not supported.", codecID); continue; } meta->setInt32(kKeyWidth, vtrack->GetWidth()); meta->setInt32(kKeyHeight, vtrack->GetHeight()); break; } case AUDIO_TRACK: { const mkvparser::AudioTrack *atrack = static_cast<const mkvparser::AudioTrack *>(track); if (!strcmp("A_AAC", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); CHECK(codecPrivateSize >= 2); addESDSFromCodecPrivate( meta, true, codecPrivate, codecPrivateSize); } else if (!strcmp("A_VORBIS", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); err = addVorbisCodecInfo( meta, codecPrivate, codecPrivateSize); } else if (!strcmp("A_MPEG/L3", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); } else { ALOGW("%s is not supported.", codecID); continue; } meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); meta->setInt32(kKeyChannelCount, atrack->GetChannels()); break; } default: continue; } if (err != OK) { ALOGE("skipping track, codec specific data was malformed."); continue; } long long durationNs = mSegment->GetDuration(); meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); mTracks.push(); TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); trackInfo->mTrackNum = track->GetNumber(); trackInfo->mMeta = meta; } }
CallbackDataSource::~CallbackDataSource() { ALOGV("~CallbackDataSource"); mIDataSource->close(); }
status_t QCameraStream_Rdi::initRdiBuffers() { status_t ret = NO_ERROR; int width = 0; /* width of channel */ int height = 0; /* height of channel */ uint32_t frame_len = 0; /* frame planner length */ int buffer_num = 4; /* number of buffers for display */ const char *pmem_region; uint8_t num_planes = 0; uint32_t planes[VIDEO_MAX_PLANES]; cam_ctrl_dimension_t dim; ALOGE("%s:BEGIN",__func__); mHalCamCtrl->mRdiMemoryLock.lock(); memset(&mHalCamCtrl->mRdiMemory, 0, sizeof(mHalCamCtrl->mRdiMemory)); mHalCamCtrl->mRdiMemoryLock.unlock(); /* get rdi size, by qury mm_camera*/ memset(&dim, 0, sizeof(cam_ctrl_dimension_t)); ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim); if (MM_CAMERA_OK != ret) { ALOGE("%s: error - can't get camera dimension!", __func__); ALOGE("%s: X", __func__); return BAD_VALUE; }else { width = dim.rdi0_width; height = dim.rdi0_height; } ret = getBufferRdi( ); if(ret != NO_ERROR) { ALOGE("%s: cannot get memory from heap, ret = %d", __func__, ret); return ret; } /* set 4 buffers for display */ memset(&mRdiStreamBuf, 0, sizeof(mRdiStreamBuf)); mHalCamCtrl->mRdiMemoryLock.lock(); this->mRdiStreamBuf.num = mHalCamCtrl->mRdiMemory.buffer_count; this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/ frame_len = mm_camera_get_msm_frame_len(CAMERA_RDI, myMode, dim.rdi0_width, dim.rdi0_height, OUTPUT_TYPE_R, &num_planes, planes); this->mRdiStreamBuf.frame_len = frame_len; memset(&mRdiBuf, 0, sizeof(mRdiBuf)); mRdiBuf.def.buf.mp = new mm_camera_mp_buf_t[mRdiStreamBuf.num]; if (!mRdiBuf.def.buf.mp) { ALOGE("%s Error allocating memory for mplanar struct ", __func__); } memset(mRdiBuf.def.buf.mp, 0, mRdiStreamBuf.num * sizeof(mm_camera_mp_buf_t)); /*allocate memory for the buffers*/ void *vaddr = NULL; for(int i = 0; i < mRdiStreamBuf.num; i++){ if (mHalCamCtrl->mRdiMemory.camera_memory[i] == NULL) continue; mRdiStreamBuf.frame[i].fd = mHalCamCtrl->mRdiMemory.fd[i]; mRdiStreamBuf.frame[i].cbcr_off = planes[0]; mRdiStreamBuf.frame[i].y_off = 0; mRdiStreamBuf.frame[i].path = OUTPUT_TYPE_R; mRdiStreamBuf.frame[i].buffer = (long unsigned int)mHalCamCtrl->mRdiMemory.camera_memory[i]->data; mRdiStreamBuf.frame[i].ion_alloc.len = mHalCamCtrl->mRdiMemory.alloc[i].len; ALOGE("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, " "vaddr = 0x%x", __func__, i, mRdiStreamBuf.frame[i].fd, frame_len, mRdiStreamBuf.frame[i].cbcr_off, mRdiStreamBuf.frame[i].y_off, (uint32_t)mRdiStreamBuf.frame[i].buffer); if (NO_ERROR != mHalCamCtrl->sendMappingBuf( MSM_V4L2_EXT_CAPTURE_MODE_RDI, i, mRdiStreamBuf.frame[i].fd, mHalCamCtrl->mRdiMemory.size, mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) { ALOGE("%s: sending mapping data Msg Failed", __func__); } mRdiBuf.def.buf.mp[i].frame = mRdiStreamBuf.frame[i]; mRdiBuf.def.buf.mp[i].frame_offset = mRdiStreamBuf.frame[i].y_off; mRdiBuf.def.buf.mp[i].num_planes = num_planes; /* Plane 0 needs to be set seperately. Set other planes * in a loop. */ mRdiBuf.def.buf.mp[i].planes[0].length = planes[0]; mRdiBuf.def.buf.mp[i].planes[0].m.userptr = mRdiStreamBuf.frame[i].fd; mRdiBuf.def.buf.mp[i].planes[0].data_offset = 0; mRdiBuf.def.buf.mp[i].planes[0].reserved[0] = mRdiBuf.def.buf.mp[i].frame_offset; for (int j = 1; j < num_planes; j++) { mRdiBuf.def.buf.mp[i].planes[j].length = planes[j]; mRdiBuf.def.buf.mp[i].planes[j].m.userptr = mRdiStreamBuf.frame[i].fd; mRdiBuf.def.buf.mp[i].planes[j].data_offset = 0; mRdiBuf.def.buf.mp[i].planes[j].reserved[0] = mRdiBuf.def.buf.mp[i].planes[j-1].reserved[0] + mRdiBuf.def.buf.mp[i].planes[j-1].length; } for (int j = 0; j < num_planes; j++) ALOGE("Planes: %d length: %d userptr: %lu offset: %d\n", j, mRdiBuf.def.buf.mp[i].planes[j].length, mRdiBuf.def.buf.mp[i].planes[j].m.userptr, mRdiBuf.def.buf.mp[i].planes[j].reserved[0]); }/*end of for loop*/ /* register the streaming buffers for the channel*/ mRdiBuf.ch_type = MM_CAMERA_CH_RDI; mRdiBuf.def.num = mRdiStreamBuf.num; mHalCamCtrl->mRdiMemoryLock.unlock(); ALOGE("%s:END",__func__); return NO_ERROR; end: if (MM_CAMERA_OK == ret ) { ALOGV("%s: X - NO_ERROR ", __func__); return NO_ERROR; } ALOGV("%s: out of memory clean up", __func__); /* release the allocated memory */ ALOGV("%s: X - BAD_VALUE ", __func__); return BAD_VALUE; }
MetadataRetrieverClient::~MetadataRetrieverClient() { ALOGV("MetadataRetrieverClient destructor"); disconnect(); }
status_t QCameraStream_Rdi::start() { ALOGV("%s: E", __func__); status_t ret = NO_ERROR; uint32_t stream_info; Mutex::Autolock lock(mStopCallbackLock); /* call start() in parent class to start the monitor thread*/ //QCameraStream::start (); stream_info = mHalCamCtrl->getChannelInterface(); setFormat(MM_CAMERA_CH_RDI_MASK, (cam_format_t)0); initRdiBuffers(); ret = cam_config_prepare_buf(mCameraId, &mRdiBuf); if(ret != MM_CAMERA_OK) { ret = BAD_VALUE; } else ret = NO_ERROR; /* For preview, the OP_MODE we set is dependent upon whether we are starting camera or camcorder. For snapshot, anyway we disable preview. However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of ZSL we skip setting Mode here */ if (!(myMode & CAMERA_ZSL_MODE)) { ALOGE("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO"); mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO; ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE, &op_mode); ALOGE("OP Mode Set"); if(MM_CAMERA_OK != ret) { ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret); ret = BAD_VALUE; goto error; } }else { ALOGE("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL"); mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL; ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE, &op_mode); if(MM_CAMERA_OK != ret) { ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret); ret = BAD_VALUE; goto error; } } /* call mm_camera action start(...) */ ALOGE("Starting RDI Stream. "); ret = cam_ops_action(mCameraId, TRUE, MM_CAMERA_OPS_RDI, 0); if (MM_CAMERA_OK != ret) { ALOGE ("%s: rdi streaming start err=%d\n", __func__, ret); ret = BAD_VALUE; freeBufferRdi(); goto end; } ret = NO_ERROR; mActive = true; goto end; error: freeBufferRdi(); end: ALOGE("%s: X", __func__); return ret; }
status_t AACDecoder::read( MediaBuffer **out, const ReadOptions *options) { /* ** end of aac audio stream in the case of initCheck is not OK, ** avoid abnormal playing later. @Jun 16, 2011. by hbb */ if(mInitCheck != OK) { ALOGE("mInitCheck is not OK, so end aac audio stream"); return ERROR_END_OF_STREAM; } status_t err; *out = NULL; int64_t seekTimeUs; ReadOptions::SeekMode mode; if (options && options->getSeekTo(&seekTimeUs, &mode)) { CHECK(seekTimeUs >= 0); mNumSamplesOutput = 0; if (mInputBuffer) { mInputBuffer->release(); mInputBuffer = NULL; } // Make sure that the next buffer output does not still // depend on fragments from the last one decoded. PVMP4AudioDecoderResetBuffer(mDecoderBuf); } else { seekTimeUs = -1; } repeat: if (mInputBuffer == NULL) { err = mSource->read(&mInputBuffer, options); if (err != OK) { return err; } int64_t timeUs; if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { if(mAnchorTimeUs != timeUs) { mAnchorTimeUs = timeUs; mNumSamplesOutput = 0; } } else { // We must have a new timestamp after seeking. CHECK(seekTimeUs < 0); } } MediaBuffer *buffer; CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), (status_t)OK); mConfig->pInputBuffer = (UChar *)mInputBuffer->data() + mInputBuffer->range_offset(); mConfig->inputBufferCurrentLength = mInputBuffer->range_length(); mConfig->inputBufferMaxLength = 0; mConfig->inputBufferUsedLength = 0; mConfig->remainderBits = 0; mConfig->pOutputBuffer = static_cast<Int16 *>(buffer->data()); mConfig->pOutputBuffer_plus = &mConfig->pOutputBuffer[2048]; #if WRITE_FILE if(aacFp) fwrite(mConfig->pInputBuffer,1, mConfig->inputBufferCurrentLength,aacFp); #endif //ALOGE("inputlen %d input[0] = %x input[1]%x", mConfig->inputBufferCurrentLength,(mConfig->pInputBuffer)[0],(mConfig->pInputBuffer)[1]); Int decoderErr = MP4AUDEC_SUCCESS; if(mConfig->isMutilChannle) { decoderErr = PVMP4AudioDecodeFrameSixChannel(mConfig, mDecoderBuf); } else { decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf); } if (mInputBuffer != NULL) { mInputBuffer->set_range( mInputBuffer->range_offset() + mConfig->inputBufferUsedLength, mInputBuffer->range_length() - mConfig->inputBufferUsedLength); if (mInputBuffer->range_length() <= 3) { mInputBuffer->release(); mInputBuffer = NULL; } } //if the input data no enough,will drop this frame inputdata. get the next frame data. if(decoderErr != MP4AUDEC_SUCCESS) { if(mInputBuffer) { mInputBuffer->release(); mInputBuffer = NULL; } if(buffer) { buffer->release(); buffer = NULL; } goto repeat; } /* * AAC+/eAAC+ streams can be signalled in two ways: either explicitly * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual * rate system and the sampling rate in the final output is actually * doubled compared with the core AAC decoder sampling rate. * * Explicit signalling is done by explicitly defining SBR audio object * type in the bitstream. Implicit signalling is done by embedding * SBR content in AAC extension payload specific to SBR, and hence * requires an AAC decoder to perform pre-checks on actual audio frames. * * Thus, we could not say for sure whether a stream is * AAC+/eAAC+ until the first data frame is decoded. */ if (++mNumDecodedBuffers <= 2) { ALOGV("audio/extended audio object type: %d + %d", mConfig->audioObjectType, mConfig->extendedAudioObjectType); ALOGV("aac+ upsampling factor: %d desired channels: %d", mConfig->aacPlusUpsamplingFactor, mConfig->desiredChannels); CHECK(mNumDecodedBuffers > 0); if (mNumDecodedBuffers == 1) { mUpsamplingFactor = mConfig->aacPlusUpsamplingFactor; // Check on the sampling rate to see whether it is changed. int32_t sampleRate; CHECK(mMeta->findInt32(kKeySampleRate, &sampleRate)); ALOGV("--->aac samplerae %d",sampleRate); if (mConfig->samplingRate != sampleRate) { mMeta->setInt32(kKeySampleRate, mConfig->samplingRate); ALOGV("Sample rate was %d Hz, but now is %d Hz", sampleRate, mConfig->samplingRate); buffer->release(); // mInputBuffer->release(); // mInputBuffer = NULL; return INFO_FORMAT_CHANGED; } } else { // mNumDecodedBuffers == 2 if (mConfig->extendedAudioObjectType == MP4AUDIO_AAC_LC || mConfig->extendedAudioObjectType == MP4AUDIO_LTP) { if (mUpsamplingFactor == 2) { // The stream turns out to be not aacPlus mode anyway ALOGV("Disable AAC+/eAAC+ since extended audio object type is %d", mConfig->extendedAudioObjectType); mConfig->aacPlusEnabled = 0; } } else { if (mUpsamplingFactor == 1) { // aacPlus mode does not buy us anything, but to cause // 1. CPU load to increase, and // 2. a half speed of decoding ALOGV("Disable AAC+/eAAC+ since upsampling factor is 1"); mConfig->aacPlusEnabled = 0; } } } } size_t numOutBytes = mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels; if (mUpsamplingFactor == 2) { if (mConfig->desiredChannels == 1) { memcpy(&mConfig->pOutputBuffer[1024], &mConfig->pOutputBuffer[2048], numOutBytes * 2); } numOutBytes *= 2; } if (decoderErr != MP4AUDEC_SUCCESS) { ALOGW("AAC decoder returned error %d, substituting silence", decoderErr); memset(buffer->data(), 0, numOutBytes); // Discard input buffer. if(mInputBuffer) { mInputBuffer->release(); mInputBuffer = NULL; } // fall through } buffer->set_range(0, numOutBytes); buffer->meta_data()->setInt64( kKeyTime, mAnchorTimeUs + (mNumSamplesOutput * 1000000) / mConfig->samplingRate); mNumSamplesOutput += mConfig->frameLength; *out = buffer; return OK; }
/* * private static int openDexFile(String sourceName, String outputName, * int flags) throws IOException * * Open a DEX file, returning a pointer to our internal data structure. * * "sourceName" should point to the "source" jar or DEX file. * * If "outputName" is NULL, the DEX code will automatically find the * "optimized" version in the cache directory, creating it if necessary. * If it's non-NULL, the specified file will be used instead. * * TODO: at present we will happily open the same file more than once. * To optimize this away we could search for existing entries in the hash * table and refCount them. Requires atomic ops or adding "synchronized" * to the non-native code that calls here. * * TODO: should be using "long" for a pointer. */ static void Dalvik_dalvik_system_DexFile_openDexFile(const u4* args, JValue* pResult) { StringObject* sourceNameObj = (StringObject*) args[0]; StringObject* outputNameObj = (StringObject*) args[1]; DexOrJar* pDexOrJar = NULL; JarFile* pJarFile; RawDexFile* pRawDexFile; char* sourceName; char* outputName; if (sourceNameObj == NULL) { dvmThrowNullPointerException("sourceName == null"); RETURN_VOID(); } sourceName = dvmCreateCstrFromString(sourceNameObj); if (outputNameObj != NULL) outputName = dvmCreateCstrFromString(outputNameObj); else outputName = NULL; /* * We have to deal with the possibility that somebody might try to * open one of our bootstrap class DEX files. The set of dependencies * will be different, and hence the results of optimization might be * different, which means we'd actually need to have two versions of * the optimized DEX: one that only knows about part of the boot class * path, and one that knows about everything in it. The latter might * optimize field/method accesses based on a class that appeared later * in the class path. * * We can't let the user-defined class loader open it and start using * the classes, since the optimized form of the code skips some of * the method and field resolution that we would ordinarily do, and * we'd have the wrong semantics. * * We have to reject attempts to manually open a DEX file from the boot * class path. The easiest way to do this is by filename, which works * out because variations in name (e.g. "/system/framework/./ext.jar") * result in us hitting a different dalvik-cache entry. It's also fine * if the caller specifies their own output file. */ if (dvmClassPathContains(gDvm.bootClassPath, sourceName)) { ALOGW("Refusing to reopen boot DEX '%s'", sourceName); dvmThrowIOException( "Re-opening BOOTCLASSPATH DEX files is not allowed"); free(sourceName); free(outputName); RETURN_VOID(); } /* * Try to open it directly as a DEX if the name ends with ".dex". * If that fails (or isn't tried in the first place), try it as a * Zip with a "classes.dex" inside. */ if (hasDexExtension(sourceName) && dvmRawDexFileOpen(sourceName, outputName, &pRawDexFile, false) == 0) { ALOGV("Opening DEX file '%s' (DEX)", sourceName); pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar)); pDexOrJar->isDex = true; pDexOrJar->pRawDexFile = pRawDexFile; pDexOrJar->pDexMemory = NULL; } else if (dvmJarFileOpen(sourceName, outputName, &pJarFile, false) == 0) { ALOGV("Opening DEX file '%s' (Jar)", sourceName); pDexOrJar = (DexOrJar*) malloc(sizeof(DexOrJar)); pDexOrJar->isDex = false; pDexOrJar->pJarFile = pJarFile; pDexOrJar->pDexMemory = NULL; } else { ALOGV("Unable to open DEX file '%s'", sourceName); dvmThrowIOException("unable to open DEX file"); } if (pDexOrJar != NULL) { pDexOrJar->fileName = sourceName; addToDexFileTable(pDexOrJar); } else { free(sourceName); } free(outputName); RETURN_PTR(pDexOrJar); }
/* * Copy the native library if needed. * * This function assumes the library and path names passed in are considered safe. */ static install_status_t copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName) { jstring* javaNativeLibPath = (jstring*) arg; ScopedUtfChars nativeLibPath(env, *javaNativeLibPath); size_t uncompLen; long when; long crc; time_t modTime; if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, &when, &crc)) { ALOGD("Couldn't read zip entry info\n"); return INSTALL_FAILED_INVALID_APK; } else { struct tm t; ZipFileRO::zipTimeToTimespec(when, &t); modTime = mktime(&t); } // Build local file path const size_t fileNameLen = strlen(fileName); char localFileName[nativeLibPath.size() + fileNameLen + 2]; if (strlcpy(localFileName, nativeLibPath.c_str(), sizeof(localFileName)) != nativeLibPath.size()) { ALOGD("Couldn't allocate local file name for library"); return INSTALL_FAILED_INTERNAL_ERROR; } *(localFileName + nativeLibPath.size()) = '/'; if (strlcpy(localFileName + nativeLibPath.size() + 1, fileName, sizeof(localFileName) - nativeLibPath.size() - 1) != fileNameLen) { ALOGD("Couldn't allocate local file name for library"); return INSTALL_FAILED_INTERNAL_ERROR; } // Only copy out the native file if it's different. struct stat st; if (!isFileDifferent(localFileName, uncompLen, modTime, crc, &st)) { return INSTALL_SUCCEEDED; } char localTmpFileName[nativeLibPath.size() + TMP_FILE_PATTERN_LEN + 2]; if (strlcpy(localTmpFileName, nativeLibPath.c_str(), sizeof(localTmpFileName)) != nativeLibPath.size()) { ALOGD("Couldn't allocate local file name for library"); return INSTALL_FAILED_INTERNAL_ERROR; } *(localFileName + nativeLibPath.size()) = '/'; if (strlcpy(localTmpFileName + nativeLibPath.size(), TMP_FILE_PATTERN, TMP_FILE_PATTERN_LEN - nativeLibPath.size()) != TMP_FILE_PATTERN_LEN) { ALOGI("Couldn't allocate temporary file name for library"); return INSTALL_FAILED_INTERNAL_ERROR; } int fd = mkstemp(localTmpFileName); if (fd < 0) { ALOGI("Couldn't open temporary file name: %s: %s\n", localTmpFileName, strerror(errno)); return INSTALL_FAILED_CONTAINER_ERROR; } if (!zipFile->uncompressEntry(zipEntry, fd)) { ALOGI("Failed uncompressing %s to %s\n", fileName, localTmpFileName); close(fd); unlink(localTmpFileName); return INSTALL_FAILED_CONTAINER_ERROR; } close(fd); // Set the modification time for this file to the ZIP's mod time. struct timeval times[2]; times[0].tv_sec = st.st_atime; times[1].tv_sec = modTime; times[0].tv_usec = times[1].tv_usec = 0; if (utimes(localTmpFileName, times) < 0) { ALOGI("Couldn't change modification time on %s: %s\n", localTmpFileName, strerror(errno)); unlink(localTmpFileName); return INSTALL_FAILED_CONTAINER_ERROR; } // Set the mode to 755 static const mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; if (chmod(localTmpFileName, mode) < 0) { ALOGI("Couldn't change permissions on %s: %s\n", localTmpFileName, strerror(errno)); unlink(localTmpFileName); return INSTALL_FAILED_CONTAINER_ERROR; } // Finally, rename it to the final name. if (rename(localTmpFileName, localFileName) < 0) { ALOGI("Couldn't rename %s to %s: %s\n", localTmpFileName, localFileName, strerror(errno)); unlink(localTmpFileName); return INSTALL_FAILED_CONTAINER_ERROR; } ALOGV("Successfully moved %s to %s\n", localTmpFileName, localFileName); return INSTALL_SUCCEEDED; }