int Encoder_Interface_Encode(void* s, enum Mode mode, const short* in, unsigned char* out) { struct encoder_state* state = (struct encoder_state*) s; enum Frame_Type_3GPP frame_type = (enum Frame_Type_3GPP) mode; int ret = AMREncode(state->encCtx, state->pidSyncCtx, mode, (Word16*) in, out, &frame_type, AMR_TX_IETF); out[0] |= 0x04; return ret; }
int Encoder_Interface_Encode(void* s, enum Mode mode, const short* speech, unsigned char* out, int forceSpeech) { struct encoder_state* state = (struct encoder_state*) s; enum Frame_Type_3GPP frame_type = (enum Frame_Type_3GPP) mode; /** Word16 AMREncode( void *pEncState, void *pSidSyncState, enum Mode 3gp_frame_type, Word16 *pEncInput, UWord8 *pEncOutput, enum Frame_Type_3GPP *p3gpp_frame_type, Word16 output_format ) */ int ret = AMREncode(state->encCtx, state->pidSyncCtx, mode, (Word16*) speech, out, &frame_type, AMR_TX_IETF); out[0] |= 0x04; return ret; }
OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::Encode(TInputAudioStream& aInStream, TOutputAudioStream& aOutStream) { // check first if mode specified is invalid if (IsModeValid(aInStream.iMode) == false) return GSMAMR_ENC_INVALID_MODE; // set AMR mode for this set of samples iGsmAmrMode = (GSM_AMR_MODES)aInStream.iMode; // get the maximum number of frames // BX int32 bytesPerFrame = iNumSamplesPerFrame * iBytesPerSample; int32 maxNumFrames = aInStream.iSampleLength / bytesPerFrame; uint8 *pFrameIn = aInStream.iSampleBuffer; uint8 *pFrameOut = aOutStream.iBitStreamBuffer; int32 i; // encode samples for (i = 0; i < maxNumFrames; i++) { // ////////////////////////////////////////// // encode this frame // ////////////////////////////////////////// int32 * temp = & iLastModeUsed; Word16 nStatus = AMREncode(iEncState, iSidState, // BX, Word16 instead of int32 to avoid wierd case(IF2 format): the function returns 31, but nStatus ends up with a big wierd number (Mode)iGsmAmrMode, (Word16 *)pFrameIn, (unsigned char *)pFrameOut, (Frame_Type_3GPP*) temp, iBitStreamFormat); if (nStatus < 0) { // an error when encoding was received, so quit return(GSMAMR_ENC_CODEC_ENCODE_FAILURE); } // save nStatus as this indicates the encoded frame size int32 encFrameSize = (int32)nStatus; aOutStream.iSampleFrameSize[i] = encFrameSize; pFrameOut += encFrameSize; pFrameIn += bytesPerFrame; } // set other values to be returned aOutStream.iNumSampleFrames = maxNumFrames; return(GSMAMR_ENC_NO_ERROR); }
int encode(int mode, const char *srcFile, const char *dstFile) { int retVal = EXIT_SUCCESS; FILE *fSrc = NULL; FILE *fDst = NULL; int frameNum = 0; bool eofReached = false; uint16_t *inputBuf = NULL; uint8_t *outputBuf = NULL; AmrNbEncState *amr = NULL; clock_t start, finish; double duration = 0.0; // Open input file. fSrc = fopen(srcFile, "rb"); if (fSrc == NULL) { fprintf(stderr, "Error opening input file\n"); retVal = EXIT_FAILURE; goto safe_exit; } // Open output file. fDst = fopen(dstFile, "wb"); if (fDst == NULL) { fprintf(stderr, "Error opening output file\n"); retVal = EXIT_FAILURE; goto safe_exit; } // Allocate input buffer. inputBuf = (uint16_t*) malloc(kInputSize); assert(inputBuf != NULL); // Allocate output buffer. outputBuf = (uint8_t*) malloc(kOutputSize); assert(outputBuf != NULL); // Initialize encoder. amr = (AmrNbEncState*) malloc(sizeof(AmrNbEncState)); AMREncodeInit(&amr->encCtx, &amr->pidSyncCtx, 0); // Write file header. fwrite("#!AMR\n", 1, 6, fDst); while (1) { // Read next input frame. int bytesRead; bytesRead = fread(inputBuf, 1, kInputSize, fSrc); if (bytesRead != kInputSize && !feof(fSrc)) { retVal = EXIT_FAILURE; // Invalid magic number. fprintf(stderr, "Error reading input file\n"); goto safe_exit; } else if (feof(fSrc) && bytesRead == 0) { eofReached = true; break; } start = clock(); // Encode the frame. Frame_Type_3GPP frame_type = (Frame_Type_3GPP) mode; int bytesGenerated; bytesGenerated = AMREncode(amr->encCtx, amr->pidSyncCtx, (Mode)mode, (Word16*)inputBuf, outputBuf, &frame_type, AMR_TX_WMF); // Convert from WMF to RFC 3267 format. if (bytesGenerated > 0) { outputBuf[0] = ((outputBuf[0] << 3) | 4) & 0x7c; } finish = clock(); duration += finish - start; if (bytesGenerated < 0) { retVal = EXIT_FAILURE; fprintf(stderr, "Encoding error\n"); goto safe_exit; } frameNum++; printf(" Frames processed: %d\n", frameNum); // Write the output. fwrite(outputBuf, 1, bytesGenerated, fDst); } // Dump the time taken by encode. printf("\n%2.5lf seconds\n", (double)duration/CLOCKS_PER_SEC); safe_exit: // Free the encoder instance. if (amr) { AMREncodeExit(&amr->encCtx, &amr->pidSyncCtx); free(amr); } // Free input and output buffer. free(inputBuf); free(outputBuf); // Close the input and output files. if (fSrc) { fclose(fSrc); } if (fDst) { fclose(fDst); } return retVal; }
void SoftAMRNBEncoder::onQueueFilled(OMX_U32 /* portIndex */) { if (mSignalledError) { return; } List<BufferInfo *> &inQueue = getPortQueue(0); List<BufferInfo *> &outQueue = getPortQueue(1); size_t numBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t); for (;;) { // We do the following until we run out of buffers. while (mInputSize < numBytesPerInputFrame) { // As long as there's still input data to be read we // will drain "kNumSamplesPerFrame" samples // into the "mInputFrame" buffer and then encode those // as a unit into an output buffer. if (mSawInputEOS || inQueue.empty()) { return; } BufferInfo *inInfo = *inQueue.begin(); OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; const void *inData = inHeader->pBuffer + inHeader->nOffset; size_t copy = numBytesPerInputFrame - mInputSize; if (copy > inHeader->nFilledLen) { copy = inHeader->nFilledLen; } if (mInputSize == 0) { mInputTimeUs = inHeader->nTimeStamp; } memcpy((uint8_t *)mInputFrame + mInputSize, inData, copy); mInputSize += copy; inHeader->nOffset += copy; inHeader->nFilledLen -= copy; // "Time" on the input buffer has in effect advanced by the // number of audio frames we just advanced nOffset by. inHeader->nTimeStamp += (copy * 1000000ll / kSampleRate) / sizeof(int16_t); if (inHeader->nFilledLen == 0) { if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { ALOGV("saw input EOS"); mSawInputEOS = true; // Pad any remaining data with zeroes. memset((uint8_t *)mInputFrame + mInputSize, 0, numBytesPerInputFrame - mInputSize); mInputSize = numBytesPerInputFrame; } inQueue.erase(inQueue.begin()); inInfo->mOwnedByUs = false; notifyEmptyBufferDone(inHeader); inData = NULL; inHeader = NULL; inInfo = NULL; } } // At this point we have all the input data necessary to encode // a single frame, all we need is an output buffer to store the result // in. if (outQueue.empty()) { return; } BufferInfo *outInfo = *outQueue.begin(); OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; uint8_t *outPtr = outHeader->pBuffer + outHeader->nOffset; size_t outAvailable = outHeader->nAllocLen - outHeader->nOffset; Frame_Type_3GPP frameType; int res = AMREncode( mEncState, mSidState, (Mode)mMode, mInputFrame, outPtr, &frameType, AMR_TX_WMF); CHECK_GE(res, 0); CHECK_LE((size_t)res, outAvailable); // Convert header byte from WMF to IETF format. outPtr[0] = ((outPtr[0] << 3) | 4) & 0x7c; outHeader->nFilledLen = res; outHeader->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; if (mSawInputEOS) { // We also tag this output buffer with EOS if it corresponds // to the final input buffer. outHeader->nFlags = OMX_BUFFERFLAG_EOS; } outHeader->nTimeStamp = mInputTimeUs; #if 0 ALOGI("sending %d bytes of data (time = %lld us, flags = 0x%08lx)", nOutputBytes, mInputTimeUs, outHeader->nFlags); hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen); #endif outQueue.erase(outQueue.begin()); outInfo->mOwnedByUs = false; notifyFillBufferDone(outHeader); outHeader = NULL; outInfo = NULL; mInputSize = 0; } }
status_t AMRNBEncoder::read( MediaBuffer **out, const ReadOptions *options) { status_t err; *out = NULL; int64_t seekTimeUs; ReadOptions::SeekMode mode; CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode)); bool readFromSource = false; int64_t wallClockTimeUs = -1; while (mNumInputSamples < kNumSamplesPerFrame) { if (mInputBuffer == NULL) { err = mSource->read(&mInputBuffer, options); if (err != OK) { if (mNumInputSamples == 0) { return ERROR_END_OF_STREAM; } memset(&mInputFrame[mNumInputSamples], 0, sizeof(int16_t) * (kNumSamplesPerFrame - mNumInputSamples)); mNumInputSamples = kNumSamplesPerFrame; break; } size_t align = mInputBuffer->range_length() % sizeof(int16_t); CHECK_EQ(align, 0); readFromSource = true; int64_t timeUs; if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) { wallClockTimeUs = timeUs; } if (mInputBuffer->meta_data()->findInt64(kKeyAnchorTime, &timeUs)) { mAnchorTimeUs = timeUs; } } else { readFromSource = false; } size_t copy = (kNumSamplesPerFrame - mNumInputSamples) * sizeof(int16_t); if (copy > mInputBuffer->range_length()) { copy = mInputBuffer->range_length(); } memcpy(&mInputFrame[mNumInputSamples], (const uint8_t *)mInputBuffer->data() + mInputBuffer->range_offset(), copy); mNumInputSamples += copy / sizeof(int16_t); mInputBuffer->set_range( mInputBuffer->range_offset() + copy, mInputBuffer->range_length() - copy); if (mInputBuffer->range_length() == 0) { mInputBuffer->release(); mInputBuffer = NULL; } } MediaBuffer *buffer; CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK); uint8_t *outPtr = (uint8_t *)buffer->data(); Frame_Type_3GPP frameType; int res = AMREncode( mEncState, mSidState, (Mode)mMode, mInputFrame, outPtr, &frameType, AMR_TX_WMF); CHECK(res >= 0); CHECK((size_t)res < buffer->size()); // Convert header byte from WMF to IETF format. outPtr[0] = ((outPtr[0] << 3) | 4) & 0x7c; buffer->set_range(0, res); // Each frame of 160 samples is 20ms long. int64_t mediaTimeUs = mNumFramesOutput * 20000LL; buffer->meta_data()->setInt64( kKeyTime, mAnchorTimeUs + mediaTimeUs); if (readFromSource && wallClockTimeUs != -1) { buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs); } ++mNumFramesOutput; *out = buffer; mNumInputSamples = 0; return OK; }