status_t RawDecoder::Decode(void *buffer, int64 *frameCount, media_header *mediaHeader, media_decode_info *info /* = 0 */) { char *output_buffer = (char *)buffer; mediaHeader->start_time = fStartTime; *frameCount = 0; while (*frameCount < fOutputBufferFrameCount) { if (fChunkSize == 0) { media_header mh; status_t err; err = GetNextChunk(&fChunkBuffer, &fChunkSize, &mh); if (err != B_OK || fChunkSize < fInputFrameSize) { fChunkSize = 0; break; } if (fSwapInput) fSwapInput(const_cast<void *>(fChunkBuffer), fChunkSize / fInputSampleSize); // XXX TODO! FIX THIS, we write to a const buffer!!! fStartTime = mh.start_time; continue; } int32 frames = min_c(fOutputBufferFrameCount - *frameCount, fChunkSize / fInputFrameSize); if (frames == 0) break; int32 samples = frames * fInputFormat.u.raw_audio.channel_count; fConvert(output_buffer, fChunkBuffer, samples); fChunkBuffer = (const char *)fChunkBuffer + frames * fInputFrameSize; fChunkSize -= frames * fInputFrameSize; output_buffer += frames * fOutputFrameSize; *frameCount += frames; fStartTime += (1000000LL * frames) / fFrameRate; } // XXX should change channel order here for // B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE and B_AUDIO_FORMAT_CHANNEL_ORDER_AIFF if (fSwapOutput) fSwapOutput(buffer, *frameCount * fInputFormat.u.raw_audio.channel_count); TRACE("framecount %Ld, time %Ld\n",*frameCount, mediaHeader->start_time); return *frameCount ? B_OK : B_ERROR; }
long dbCaPutLinkCallback(struct link *plink,short dbrType, const void *pbuffer,long nRequest,dbCaCallback callback,void *userPvt) { caLink *pca = (caLink *)plink->value.pv_link.pvt; long status = 0; short link_action = 0; assert(pca); /* put the new value in */ epicsMutexMustLock(pca->lock); assert(pca->plink); if (!pca->isConnected || !pca->hasWriteAccess) { epicsMutexUnlock(pca->lock); return -1; } if (pca->dbrType == DBR_ENUM && dbDBRnewToDBRold[dbrType] == DBR_STRING) { long (*fConvert)(const void *from, void *to, struct dbAddr *paddr); /* Send as DBR_STRING */ if (!pca->pputString) { pca->pputString = dbCalloc(1, MAX_STRING_SIZE); /* Disabled by ANJ, needs a link flag to allow user to control this. * Setting these makes the reconnect callback re-do the last CA put. plink->value.pv_link.pvlMask |= pvlOptOutString; */ } fConvert = dbFastPutConvertRoutine[dbrType][dbDBRoldToDBFnew[DBR_STRING]]; status = fConvert(pbuffer, pca->pputString, 0); link_action |= CA_WRITE_STRING; pca->gotOutString = TRUE; if (pca->newOutString) pca->nNoWrite++; pca->newOutString = TRUE; } else { int newType = dbDBRoldToDBFnew[pca->dbrType]; if (!pca->pputNative) { pca->pputNative = dbCalloc(pca->nelements, dbr_value_size[ca_field_type(pca->chid)]); /* Fixed and disabled by ANJ, see comment above. plink->value.pv_link.pvlMask |= pvlOptOutNative; */ } if (nRequest == 1 && pca->nelements==1){ long (*fConvert)(const void *from, void *to, struct dbAddr *paddr); fConvert = dbFastPutConvertRoutine[dbrType][newType]; status = fConvert(pbuffer, pca->pputNative, 0); } else { struct dbAddr dbAddr; long (*aConvert)(struct dbAddr *paddr, const void *from, long nreq, long nfrom, long off); aConvert = dbPutConvertRoutine[dbrType][newType]; memset((void *)&dbAddr, 0, sizeof(dbAddr)); dbAddr.pfield = pca->pputNative; /*Following only used for DBF_STRING*/ dbAddr.field_size = MAX_STRING_SIZE; if(nRequest>pca->nelements) nRequest = pca->nelements; status = aConvert(&dbAddr, pbuffer, nRequest, pca->nelements, 0); if(nRequest<pca->nelements) { long elemsize = dbr_value_size[ca_field_type(pca->chid)]; memset(nRequest*elemsize+(char*)pca->pputNative, 0, (pca->nelements-nRequest)*elemsize); } } link_action |= CA_WRITE_NATIVE; pca->gotOutNative = TRUE; if (pca->newOutNative) pca->nNoWrite++; pca->newOutNative = TRUE; } if (callback) { pca->putType = CA_PUT_CALLBACK; pca->putCallback = callback; pca->putUserPvt = userPvt; } else { pca->putType = CA_PUT; pca->putCallback = 0; } addAction(pca, link_action); epicsMutexUnlock(pca->lock); return status; }
long dbCaGetLink(struct link *plink,short dbrType, void *pdest, epicsEnum16 *pstat, epicsEnum16 *psevr, long *nelements) { caLink *pca = (caLink *)plink->value.pv_link.pvt; long status = 0; short link_action = 0; int newType; assert(pca); epicsMutexMustLock(pca->lock); assert(pca->plink); if (!pca->isConnected || !pca->hasReadAccess) { pca->sevr = INVALID_ALARM; pca->stat = LINK_ALARM; status = -1; goto done; } if (pca->dbrType == DBR_ENUM && dbDBRnewToDBRold[dbrType] == DBR_STRING){ long (*fConvert)(const void *from, void *to, struct dbAddr *paddr); /* Subscribe as DBR_STRING */ if (!pca->pgetString) { plink->value.pv_link.pvlMask |= pvlOptInpString; link_action |= CA_MONITOR_STRING; } if (!pca->gotInString) { pca->sevr = INVALID_ALARM; pca->stat = LINK_ALARM; status = -1; goto done; } if (nelements) *nelements = 1; fConvert = dbFastGetConvertRoutine[dbDBRoldToDBFnew[DBR_STRING]][dbrType]; status = fConvert(pca->pgetString, pdest, 0); goto done; } if (!pca->pgetNative) { plink->value.pv_link.pvlMask |= pvlOptInpNative; link_action |= CA_MONITOR_NATIVE; } if (!pca->gotInNative){ pca->sevr = INVALID_ALARM; pca->stat = LINK_ALARM; status = -1; goto done; } newType = dbDBRoldToDBFnew[pca->dbrType]; if (!nelements || *nelements == 1) { long (*fConvert)(const void *from, void *to, struct dbAddr *paddr); fConvert = dbFastGetConvertRoutine[newType][dbrType]; assert(pca->pgetNative); status = fConvert(pca->pgetNative, pdest, 0); } else { long ntoget = *nelements; struct dbAddr dbAddr; long (*aConvert)(struct dbAddr *paddr, void *to, long nreq, long nto, long off); aConvert = dbGetConvertRoutine[newType][dbrType]; assert(pca->pgetNative); if (ntoget > pca->nelements) ntoget = pca->nelements; *nelements = ntoget; memset((void *)&dbAddr, 0, sizeof(dbAddr)); dbAddr.pfield = pca->pgetNative; /*Following will only be used for pca->dbrType == DBR_STRING*/ dbAddr.field_size = MAX_STRING_SIZE; /*Ignore error return*/ aConvert(&dbAddr, pdest, ntoget, ntoget, 0); } done: if (pstat) *pstat = pca->stat; if (psevr) *psevr = pca->sevr; if (link_action) addAction(pca, link_action); epicsMutexUnlock(pca->lock); return status; }