📄 umc_ac3_decoder.cpp
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2002-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_ac3_decoder.h"
#include "ac3_dec.h"
#include "vm_debug.h"
namespace UMC {
/********************************************************************/
AudioCodec *CreateAC3Decoder() { return (new AC3Decoder); }
AC3Decoder::AC3Decoder()
{
state = NULL;
stateMemId = 0;
}
/********************************************************************/
Status AC3Decoder::Init(BaseCodecParams* init)
{
AC3Status result;
Ipp32s size = 0;
result = ac3decInit(NULL, &size);
if (AC3_OK != result)
return StatusAC3_2_UMC(result);
// checks or create memory allocator;
if (BaseCodec::Init(init) != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("Failed to create allocator!\n"));
return UMC_ERR_ALLOC;
}
if (m_pMemoryAllocator->Alloc(&stateMemId, size, UMC_ALLOC_PERSISTENT) != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External allocation failed\n"));
return UMC_ERR_ALLOC;
}
state = (AC3Dec *)m_pMemoryAllocator->Lock(stateMemId);
if (!state) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
return UMC_ERR_ALLOC;
}
result = ac3decInit(state, &size);
MemUnlock();
if (AC3_OK == result) {
if (NULL != init)
SetParams(init);
return UMC_OK;
} else {
return StatusAC3_2_UMC(result);
}
}
/********************************************************************/
Status AC3Decoder::GetFrame(MediaData* in,
MediaData* out)
{
AC3Status result;
Ipp32s nChannelOut, nDecodedBytes, SampleRate;
Ipp32s outBufferSize;
Status status;
if (!in || !out)
return UMC_ERR_NULL_PTR;
outBufferSize = (Ipp32s)out->GetBufferSize() -
(Ipp32s)((Ipp8u *)out->GetDataPointer() -
(Ipp8u *)out->GetBufferPointer());
status = MemLock();
if (status != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return status;
}
result = ac3decGetFrame((Ipp8u *)in->GetDataPointer(),
in->GetDataSize(), &nDecodedBytes,
(Ipp16s *)out->GetDataPointer(),
outBufferSize, state);
ac3decGetNumChannelOut(&nChannelOut, state);
if (AC3_BAD_STREAM == result) {
if (outBufferSize < nChannelOut*256*6*sizeof(Ipp16s)) {
MemUnlock();
return UMC_ERR_NOT_ENOUGH_BUFFER;
}
}
in->MoveDataPointer(nDecodedBytes);
ac3decGetSampleFrequency(&SampleRate, state);
if (nDecodedBytes && (AC3_OK == result || AC3_BAD_STREAM == result)) {
Ipp64f pts_start = in->GetTime();
Ipp64f pts_end;
if (pts_start == -1.0)
pts_start = m_pts_prev;
m_pts_prev = pts_end = pts_start + (256*6)/((Ipp32f)SampleRate);
in->SetTime(pts_end);
if (AC3_BAD_STREAM == result) {
// fill with silent data
memset(out->GetDataPointer(),0,nChannelOut*256*6*2);
}
out->SetDataSize(nChannelOut*256*6*2);
out->SetTime(pts_start, pts_end);
}
if (AC3_OK == result) {
AudioData* pAudio = DynamicCast<AudioData,MediaData>(out);
if (pAudio) {
pAudio->m_info.bitPerSample = 16;
pAudio->m_info.bitrate = 0;
pAudio->m_info.channels = nChannelOut;
pAudio->m_info.sample_frequency = SampleRate;
pAudio->m_info.stream_type = PCM_AUDIO;
}
}
MemUnlock();
return StatusAC3_2_UMC(result);
}
/********************************************************************/
Status AC3Decoder::SetParams(BaseCodecParams * params) {
AC3DecoderParams *info = DynamicCast < AC3DecoderParams > (params);
if (info) {
Status status;
status = MemLock();
if (status != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return status;
}
ac3decSetOutAcmod(info->out_acmod, state);
ac3decSetOuLfeOn(info->outlfeon, state);
ac3decSetDualMonoMode(info->dualmonomode, state);
ac3decSetDrcScaleLow(info->drc_scaleLow, state);
ac3decSetDrcScaleHigh(info->drc_scaleHigh, state);
ac3decSetOutCompMod(info->out_compmod, state);
ac3decSetKaraokeCapable(info->karaokeCapable, state);
ac3decSetCrcMute(info->crc_mute, state);
ac3decSetGainScale(info->gainScale, state);
} else {
return UMC_ERR_NULL_PTR;
}
return UMC_OK;
}
/********************************************************************/
AC3Decoder::~AC3Decoder()
{
Close();
}
/********************************************************************/
Status AC3Decoder::Close()
{
Status status;
status = MemLock();
if (status != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return status;
}
ac3decClose(state);
MemUnlock();
if (state) {
m_pMemoryAllocator->Free(stateMemId);
state = NULL;
}
BaseCodec::Close();
state = NULL;
return UMC_OK;
}
/********************************************************************/
Status AC3Decoder::Reset()
{
Status status;
status = MemLock();
if (status != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return status;
}
ac3decReset(state);
MemUnlock();
return UMC_OK;
}
/********************************************************************/
Status AC3Decoder::GetInfo(BaseCodecParams* info)
{
Status status;
if (!info)
return UMC_ERR_NULL_PTR;
info->m_SuggestedInputSize = 1920 * 2;
info->m_SuggestedOutputSize = 6 * (256 * 6) * sizeof(Ipp16s);
info->level = AC3_LEVEL_MAIN;
info->profile = AC3_PROFILE_MAIN;
AudioCodecParams *p_info =
DynamicCast < AudioCodecParams, BaseCodecParams > (info);
status = MemLock();
if (status != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return status;
}
ac3decGetInfo(¶ms, state);
if (!p_info)
return UMC_OK;
if (p_info) {
p_info->m_info_out.channels = params.m_info_out.channels;
p_info->m_info_in.channels = params.m_info_in.channels;
p_info->m_info_in.stream_type = AC3_AUDIO;
p_info->m_info_out.stream_type = PCM_AUDIO;
if (params.is_valid) {
p_info->m_info_in.bitPerSample = params.m_info_in.bitPerSample;
p_info->m_info_out.bitPerSample = params.m_info_out.bitPerSample;
p_info->m_info_in.bitrate = params.m_info_in.bitrate;
p_info->m_info_out.bitrate = params.m_info_out.bitrate;
p_info->m_info_in.sample_frequency = params.m_info_in.sample_frequency;
p_info->m_info_out.sample_frequency = params.m_info_out.sample_frequency;
p_info->m_frame_num = params.m_frame_num;
p_info->m_info_in.bitrate = params.m_info_in.bitrate;
p_info->m_info_out.bitrate = params.m_info_out.bitrate;
p_info->m_info_in.channel_mask = 0;
if (params.m_info_in.channel_mask & AC3_CHANNEL_FRONT_CENTER)
p_info->m_info_in.channel_mask |= CHANNEL_FRONT_CENTER;
if (params.m_info_in.channel_mask & AC3_CHANNEL_FRONT_LEFT)
p_info->m_info_in.channel_mask |= CHANNEL_FRONT_LEFT;
if (params.m_info_in.channel_mask & AC3_CHANNEL_FRONT_RIGHT)
p_info->m_info_in.channel_mask |= CHANNEL_FRONT_RIGHT;
if (params.m_info_in.channel_mask & AC3_CHANNEL_BACK_CENTER)
p_info->m_info_in.channel_mask |= CHANNEL_BACK_CENTER;
if (params.m_info_in.channel_mask & AC3_CHANNEL_BACK_LEFT)
p_info->m_info_in.channel_mask |= CHANNEL_BACK_LEFT;
if (params.m_info_in.channel_mask & AC3_CHANNEL_BACK_RIGHT)
p_info->m_info_in.channel_mask |= CHANNEL_BACK_RIGHT;
if (params.m_info_in.channel_mask & AC3_CHANNEL_LOW_FREQUENCY)
p_info->m_info_in.channel_mask |= CHANNEL_LOW_FREQUENCY;
p_info->m_info_out.channel_mask = 0;
if (params.m_info_out.channel_mask & AC3_CHANNEL_FRONT_CENTER)
p_info->m_info_out.channel_mask |= CHANNEL_FRONT_CENTER;
if (params.m_info_out.channel_mask & AC3_CHANNEL_FRONT_LEFT)
p_info->m_info_out.channel_mask |= CHANNEL_FRONT_LEFT;
if (params.m_info_out.channel_mask & AC3_CHANNEL_FRONT_RIGHT)
p_info->m_info_out.channel_mask |= CHANNEL_FRONT_RIGHT;
if (params.m_info_out.channel_mask & AC3_CHANNEL_BACK_CENTER)
p_info->m_info_out.channel_mask |= CHANNEL_BACK_CENTER;
if (params.m_info_out.channel_mask & AC3_CHANNEL_BACK_LEFT)
p_info->m_info_out.channel_mask |= CHANNEL_BACK_LEFT;
if (params.m_info_out.channel_mask & AC3_CHANNEL_BACK_RIGHT)
p_info->m_info_out.channel_mask |= CHANNEL_BACK_RIGHT;
if (params.m_info_out.channel_mask & AC3_CHANNEL_LOW_FREQUENCY)
p_info->m_info_out.channel_mask |= CHANNEL_LOW_FREQUENCY;
}
} else {
MemUnlock();
return UMC_WRN_INFO_NOT_READY;
}
MemUnlock();
return UMC_OK;
}
/********************************************************************/
Status AC3Decoder::GetDuration(Ipp32f* p_duration)
{
Status status;
status = MemLock();
if (status != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return status;
}
ac3decGetDuration(p_duration, state);
MemUnlock();
return UMC_OK;
}
/********************************************************************/
Status AC3Decoder::StatusAC3_2_UMC(AC3Status st)
{
Status res;
if (st == AC3_OK)
res = UMC_OK;
else if (st == AC3_NOT_ENOUGH_DATA)
res = UMC_ERR_NOT_ENOUGH_DATA;
else if (st == AC3_FLAGS_ERROR)
res = UMC_ERR_INVALID_PARAMS;
else if (st == AC3_ALLOC)
res = UMC_ERR_ALLOC;
else if (st == AC3_BAD_STREAM)
res = UMC_ERR_INVALID_STREAM;
else if (st == AC3_NULL_PTR)
res = UMC_ERR_NULL_PTR;
else if (st == AC3_NOT_FIND_SYNCWORD)
res = UMC_ERR_SYNC;
else if (st == AC3_NOT_ENOUGH_BUFFER)
res = UMC_ERR_NOT_ENOUGH_BUFFER;
else if (st == AC3_UNSUPPORTED)
res = UMC_ERR_UNSUPPORTED;
else
res = UMC_ERR_UNSUPPORTED;
return res;
}
/****************************************************************************/
Status AC3Decoder::MemLock() {
AC3Dec *pOldState = state;
/* AYA: 07 june 07 failed if this check delete */
if( m_pMemoryAllocator == NULL ) {
return UMC_OK;
}
state = (AC3Dec *)m_pMemoryAllocator->Lock(stateMemId);
if(!state) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
return UMC_ERR_ALLOC;
}
if (state != pOldState) {
ac3decUpdateMemMap(state, (Ipp8u *)state-(Ipp8u *)pOldState);
}
return UMC_OK;
}
/****************************************************************************/
Status AC3Decoder::MemUnlock() {
if (stateMemId) {
/* AYA: 07 june 07 failed if this check delete */
if( m_pMemoryAllocator == NULL ) {
return UMC_OK;
}
if (m_pMemoryAllocator->Unlock(stateMemId) != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Unlock failed\n"));
return UMC_ERR_ALLOC;
}
}
return UMC_OK;
}
/****************************************************************************/
}; // namespace UMC
/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -