197 lines
5.8 KiB
C++
197 lines
5.8 KiB
C++
/*
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*/
|
|
|
|
//#define LOG_NDEBUG 0
|
|
#define LOG_TAG "DummyDec"
|
|
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <cerrno>
|
|
#include <stdlib.h>
|
|
#include <utils/Log.h>
|
|
#include "rt_error.h"
|
|
#include "DummyDec.h"
|
|
#include "RockitExtAdec.h"
|
|
|
|
namespace android {
|
|
|
|
typedef struct _ExtDummyContext {
|
|
HANDLE_XXXDECODER mHandle;
|
|
int32_t mOutDataOffset;
|
|
int32_t mOutDataLeftLen;
|
|
int64_t mTimeStamp;
|
|
AUDIO_BIT_WIDTH_E enBitwidth;
|
|
} ExtDummyContext;
|
|
|
|
static uint32_t getBytesPerSample(AUDIO_BIT_WIDTH_E enBitwidth) {
|
|
uint32_t u32BytesPerSample = -1;
|
|
|
|
switch(enBitwidth) {
|
|
case AUDIO_BIT_WIDTH_8:
|
|
u32BytesPerSample = 1; break;
|
|
case AUDIO_BIT_WIDTH_16:
|
|
u32BytesPerSample = 2; break;
|
|
case AUDIO_BIT_WIDTH_24:
|
|
u32BytesPerSample = 3; break;
|
|
case AUDIO_BIT_WIDTH_32:
|
|
u32BytesPerSample = 4; break;
|
|
default:
|
|
ALOGD("Unsupported enBitwidth %d", enBitwidth);
|
|
break;
|
|
}
|
|
|
|
return u32BytesPerSample;
|
|
}
|
|
|
|
int32_t DummyDec::open(void *pDecoderAttr, void **ppDecoder) {
|
|
ADEC_ATTR_CODEC_S *attr = (ADEC_ATTR_CODEC_S *)pDecoderAttr;
|
|
TRANSPORT_TYPE transportFmt = (TRANSPORT_TYPE)attr->u32Resv[0];
|
|
XXX_DECODER_ERROR err = XXX_DEC_OK;
|
|
ExtDummyContext *ctx = (ExtDummyContext *)malloc(sizeof(ExtDummyContext));
|
|
memset(ctx, 0, sizeof(ExtDummyContext));
|
|
|
|
ctx->mHandle = xxxDecoder_Open(transportFmt, 1);
|
|
if(!ctx->mHandle) {
|
|
ALOGD("xxxDecoder_Open failed");
|
|
goto _FAIL;
|
|
}
|
|
|
|
if (attr->u32ExtraDataSize > 0 && attr->pExtraData != NULL) {
|
|
ALOGD("config extradata size:%d", attr->u32ExtraDataSize);
|
|
err = xxxDecoder_ConfigRaw(ctx->mHandle, (uint8_t **)&attr->pExtraData, &attr->u32ExtraDataSize);
|
|
if (err != XXX_DEC_OK) {
|
|
ALOGD("xxxDecoder_ConfigRaw fail : 0x%x", err);
|
|
goto _FAIL;
|
|
}
|
|
}
|
|
ctx->enBitwidth = AUDIO_BIT_WIDTH_16;
|
|
*ppDecoder = (void *)ctx;
|
|
return RT_OK;
|
|
|
|
_FAIL:
|
|
if (ctx->mHandle) {
|
|
xxxDecoder_Close(ctx->mHandle);
|
|
}
|
|
free(ctx);
|
|
*ppDecoder = NULL;
|
|
return RT_ERR_UNSUPPORT;
|
|
}
|
|
|
|
int32_t DummyDec::decode(void *pDecoder, void *pDecParam) {
|
|
XXX_DECODER_ERROR ret = XXX_DEC_OK;
|
|
ExtDummyContext *ctx = (ExtDummyContext *)pDecoder;
|
|
if (ctx == NULL || ctx->mHandle == NULL || pDecParam == NULL)
|
|
return RT_ERR_UNKNOWN;
|
|
|
|
AUDIO_ADENC_PARAM_S *pParam = (AUDIO_ADENC_PARAM_S *)pDecParam;
|
|
uint8_t *pInput = pParam->pu8InBuf;
|
|
uint32_t inLength = pParam->u32InLen;
|
|
uint32_t validLength = inLength;
|
|
bool eos = false;
|
|
|
|
if ((pInput == NULL) || (inLength == 0))
|
|
eos = true;
|
|
|
|
// send input data to XXX dec
|
|
ret = xxxDecoder_Fill(ctx->mHandle, &pInput, &inLength, &validLength);
|
|
if (ret != XXX_DEC_OK) {
|
|
ALOGD("xxxDecoder_Fill failed[%d]", ret);
|
|
return RT_ERR_UNKNOWN;
|
|
}
|
|
pParam->u32InLen = validLength;
|
|
// XXX decode frame
|
|
ret = xxxDecoder_DecodeFrame(ctx->mHandle, (INT_PCM *)pParam->pu8OutBuf, pParam->u32OutLen / sizeof(INT_PCM), 0);
|
|
if(ret != XXX_DEC_OK) {
|
|
pParam->u32OutLen = 0;
|
|
if(ret == XXX_DEC_NOT_ENOUGH_BITS) {
|
|
if(eos) {
|
|
return ADEC_DECODER_EOS;
|
|
} else {
|
|
ALOGD("data not enough");
|
|
return ADEC_DECODER_TRY_AGAIN;
|
|
}
|
|
} else if (ret == XXX_DEC_OUTPUT_BUFFER_TOO_SMALL) {
|
|
ALOGD("output buffer is too small");
|
|
return ADEC_DECODER_ERROR;
|
|
}
|
|
|
|
ALOGD("xxxDecoder_DecodeFrame failed[%d]", ret);
|
|
return ADEC_DECODER_ERROR;
|
|
}
|
|
|
|
CStreamInfo* info = xxxDecoder_GetStreamInfo(ctx->mHandle);
|
|
if(!info) {
|
|
ALOGD("xxxDecoder_GetStreamInfo failed[%d]", ret);
|
|
return ADEC_DECODER_ERROR;
|
|
}
|
|
|
|
pParam->u64OutTimeStamp = ctx->mTimeStamp;
|
|
ctx->mTimeStamp += ((int64_t)info->frameSize*1000000)/info->sampleRate;
|
|
|
|
uint32_t u32BytesPerSample = getBytesPerSample(ctx->enBitwidth);
|
|
if(u32BytesPerSample == -1)
|
|
return ADEC_DECODER_ERROR;
|
|
|
|
pParam->u32OutLen = info->frameSize * info->numChannels * u32BytesPerSample;
|
|
return ADEC_DECODER_OK;
|
|
}
|
|
|
|
int32_t DummyDec::getFrameInfo(void *pDecoder, void *pInfo) {
|
|
ADEC_FRAME_INFO_S stFrameInfo;
|
|
ExtDummyContext *ctx = (ExtDummyContext *)pDecoder;
|
|
|
|
if (ctx == NULL || pInfo == NULL)
|
|
return RT_ERR_UNKNOWN;
|
|
|
|
CStreamInfo *pstStreamInfo = xxxDecoder_GetStreamInfo(ctx->mHandle);
|
|
if(!pstStreamInfo) {
|
|
ALOGD("xxxDecoder_GetStreamInfo failed");
|
|
return RT_ERR_UNKNOWN;
|
|
}
|
|
|
|
memset(&stFrameInfo, 0, sizeof(ADEC_FRAME_INFO_S));
|
|
stFrameInfo.u32Channels = pstStreamInfo->numChannels;
|
|
stFrameInfo.u32SampleRate = pstStreamInfo->sampleRate;
|
|
stFrameInfo.u32FrameSize = pstStreamInfo->frameSize;
|
|
stFrameInfo.enBitWidth = ctx->enBitwidth;
|
|
|
|
memcpy(pInfo, &stFrameInfo, sizeof(ADEC_FRAME_INFO_S));
|
|
return RT_OK;
|
|
}
|
|
|
|
int32_t DummyDec::close(void *pDecoder) {
|
|
ExtDummyContext *ctx = (ExtDummyContext *)pDecoder;
|
|
if (ctx == NULL)
|
|
return RT_ERR_UNKNOWN;
|
|
|
|
xxxDecoder_Close(ctx->mHandle);
|
|
free(ctx);
|
|
return RT_OK;
|
|
}
|
|
|
|
int32_t DummyDec::reset(void *pDecoder) {
|
|
ExtDummyContext *ctx = reinterpret_cast<ExtDummyContext *>(pDecoder);
|
|
|
|
if (ctx == NULL || ctx->mHandle == NULL)
|
|
return RT_ERR_UNKNOWN;
|
|
|
|
return RT_OK;
|
|
}
|
|
|
|
}
|