📄 umc_mp3_encoder.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_mp3_encoder.h"
#include "umc_mp3_encoder_params.h"
#include "mp3enc.h"
#include "vm_debug.h"
namespace UMC {
AudioCodec *CreateMP3Encoder() { return (new MP3Encoder); }
MP3Encoder::MP3Encoder()
{
state = NULL;
m_freq = 0;
m_bitrate = 0;
m_stereo = 0;
m_id = 0;
m_frame_size = 0;
m_layer = 0;
m_stereo_mode = 0;
m_ns_mode = 0;
m_force_mpeg1 = 0;
m_mc_matrix_procedure = 0;
stateMemId = 0;
}
MP3Encoder::~MP3Encoder()
{
Close();
}
IppBool MP3Encoder::CheckBitRate(Ipp32s sample_rate,
Ipp32s layer,
Ipp32s bitrate,
Ipp32s stereo)
{
Ipp32s ind;
Ipp32s id;
if (sample_rate == 44100 || sample_rate == 48000 || sample_rate == 32000)
id = 1;
else if (sample_rate == 22050 || sample_rate == 24000 || sample_rate == 16000)
id = 0;
else return ippFalse;
if (mp3enc_checkBitRate(id, layer, stereo, bitrate / 1000, &ind))
return ippTrue;
return ippFalse;
}
#undef VM_DEBUG_FUNC_NAME
#define VM_DEBUG_FUNC_NAME VM_STRING("MP3Encoder::Init")
Status MP3Encoder::Init(BaseCodecParams * init)
{
Ipp32s size;
Ipp32s st, br, fr, chm, channel_mask;
Ipp32s stereo_mode;
MP3Status res;
MP3EncoderParams* pMP3EncoderParams;
// 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;
}
AudioCodecParams* pAudioCodecInit =
DynamicCast<AudioCodecParams, BaseCodecParams>(init);
if (!pAudioCodecInit)
return UMC_ERR_NULL_PTR;
fr = pAudioCodecInit->m_info_in.sample_frequency;
st = pAudioCodecInit->m_info_in.channels;
chm = pAudioCodecInit->m_info_in.channel_mask;
br = pAudioCodecInit->m_info_out.bitrate / 1000;
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("sample_frequency = %d"), fr);
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("channels = %d"), st);
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("bitrate = %d"), br);
m_frame_num = 0;
m_pts_prev = 0;
pMP3EncoderParams = DynamicCast<MP3EncoderParams, BaseCodecParams>(init);
if (pMP3EncoderParams) {
m_stereo_mode = pMP3EncoderParams->stereo_mode;
m_ns_mode = pMP3EncoderParams->ns_mode;
m_layer = pMP3EncoderParams->layer;
m_force_mpeg1 = pMP3EncoderParams->force_mpeg1;
m_mc_matrix_procedure = pMP3EncoderParams->mc_matrix_procedure;
m_mc_lfe_filter_off = pMP3EncoderParams->mc_lfe_filter_off;
m_br_mode = pMP3EncoderParams->mode;
} else {
m_stereo_mode = UMC_MPA_LR_STEREO;
m_ns_mode = 0;
m_layer = 3;
m_force_mpeg1 = 0;
m_mc_matrix_procedure = 0;
m_mc_lfe_filter_off = 0;
m_br_mode = MPAENC_CBR;
}
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("m_layer = %d"), m_layer);
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("m_force_mpeg1 = %d"), m_force_mpeg1);
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("m_ns_mode = %d"), m_ns_mode);
if (st == 1)
m_stereo_mode = UMC_MPA_MONO;
switch (m_stereo_mode) {
case UMC_MPA_MONO:
stereo_mode = MPA_MONO; break;
case UMC_MPA_LR_STEREO:
stereo_mode = MPA_LR_STEREO; break;
case UMC_MPA_MS_STEREO:
stereo_mode = MPA_MS_STEREO; break;
case UMC_MPA_JOINT_STEREO:
stereo_mode = MPA_JOINT_STEREO; break;
default:
stereo_mode = MPA_LR_STEREO; break;
};
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("stereo_mode = %d"), stereo_mode);
channel_mask = 0;
if (chm & (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT))
channel_mask |= MP3_CHANNEL_STEREO;
if (chm & CHANNEL_FRONT_CENTER)
channel_mask |= MP3_CHANNEL_CENTER;
if (chm & CHANNEL_LOW_FREQUENCY)
channel_mask |= MP3_CHANNEL_LOW_FREQUENCY;
if (chm & CHANNEL_BACK_CENTER)
channel_mask |= MP3_CHANNEL_SURROUND_MONO;
if (chm & (CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT))
channel_mask |= MP3_CHANNEL_SURROUND_STEREO;
/* if (chm & (CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT))
channel_mask |= MP3_CHANNEL_SURROUND_STEREO_P2;*/
res = mp3encInit(NULL, fr, st, channel_mask, m_layer, br, m_br_mode, stereo_mode, m_ns_mode,
m_force_mpeg1, m_mc_matrix_procedure, m_mc_lfe_filter_off, &size);
if (res != MP3_OK)
return StatusMP3_2_UMC(res);
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 = (MP3Enc *)m_pMemoryAllocator->Lock(stateMemId);
if(!state) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
return UMC_ERR_ALLOC;
}
res = mp3encInit(state, fr, st, channel_mask, m_layer, br, m_br_mode, stereo_mode, m_ns_mode,
m_force_mpeg1, m_mc_matrix_procedure, m_mc_lfe_filter_off, &size);
if (res == MP3_OK) {
m_stereo = st;
m_freq = fr;
m_bitrate = br;
mp3encGetMpegId(state, &m_id);
vm_debug_trace1(VM_DEBUG_INFO, VM_STRING("MPEG1/2 = %d"), 2 - m_id);
mp3encGetUpsample(state, &m_upsample);
mp3encGetFrameSize(&m_frame_size, m_id, m_layer, m_upsample);
}
MemUnlock();
return StatusMP3_2_UMC(res);
}
#undef VM_DEBUG_FUNC_NAME
#define VM_DEBUG_FUNC_NAME NULL
Status MP3Encoder::Close()
{
Status res = MemLock();
if (res != UMC_OK) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("MemLock failed\n"));
return UMC_OK;
}
mp3encClose(state);
MemUnlock();
if(state) {
m_pMemoryAllocator->Free(stateMemId);
state = NULL;
}
BaseCodec::Close();
return UMC_OK;
}
Status MP3Encoder::GetFrame(MediaData * in, MediaData * out) {
Ipp32s inSamples;
Ipp32s bytes;
MP3Status res;
Ipp32s out_size, slot_size;
Status status;
Ipp64f pts_start, pts_end;
if (!in || !in->GetDataPointer() || !out || !out->GetDataPointer())
return UMC_ERR_NULL_PTR;
inSamples = (in->GetDataSize() / sizeof(Ipp16s));
if (inSamples < m_stereo * m_frame_size)
return UMC_ERR_NOT_ENOUGH_DATA;
out_size = (out->GetBufferSize() - ((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;
}
mp3encGetSlotSize(state, &slot_size);
if (out_size < slot_size + (m_layer == 3 ? 1024 : 0)) {
MemUnlock();
return UMC_ERR_NOT_ENOUGH_BUFFER;
}
if ((m_stereo * m_frame_size) < inSamples)
inSamples = m_stereo * m_frame_size;
res = mp3encGetFrame((Ipp16s *)in->GetDataPointer(), &bytes,
(Ipp8u *)out->GetDataPointer(), state);
if (res == MP3_OK) {
pts_start = in->GetTime();
if (pts_start < 0)
pts_start = m_pts_prev;
m_pts_prev = pts_end = pts_start+(Ipp32f)(inSamples/m_stereo)/(Ipp32f)(m_freq);
out->SetTime(pts_start, pts_end);
out->SetDataSize(bytes);
in->MoveDataPointer(inSamples*sizeof(Ipp16s));
in->SetTime(pts_end);
m_frame_num++;
}
MemUnlock();
return StatusMP3_2_UMC(res);
}
Status MP3Encoder::GetInfo(BaseCodecParams * info)
{
if (!info)
return UMC_ERR_NULL_PTR;
info->m_SuggestedInputSize = m_stereo * sizeof(Ipp16s) * m_frame_size;
//info->m_SuggestedOutputSize = 4096;
info->m_SuggestedOutputSize = m_stereo * sizeof(Ipp16s) * m_frame_size;
if (m_layer == 3)
info->m_SuggestedOutputSize += 1024;
AudioCodecParams *pAudioCodecInfo =
DynamicCast < AudioCodecParams, BaseCodecParams > (info);
if (!pAudioCodecInfo)
return UMC_OK;
pAudioCodecInfo->m_info_in.bitPerSample = 16;
pAudioCodecInfo->m_info_out.bitPerSample = 16;
pAudioCodecInfo->m_info_in.bitrate = 0;
pAudioCodecInfo->m_info_out.bitrate = 1000*m_bitrate;
pAudioCodecInfo->m_info_in.channels = m_stereo;
pAudioCodecInfo->m_info_out.channels = m_stereo;
pAudioCodecInfo->m_info_in.sample_frequency = m_freq;
pAudioCodecInfo->m_info_out.sample_frequency = m_freq << m_upsample;
pAudioCodecInfo->m_info_in.stream_type = PCM_AUDIO;
pAudioCodecInfo->m_info_out.stream_type = UNDEF_AUDIO;
if (m_layer == 3) {
if (m_id == 1)
pAudioCodecInfo->m_info_out.stream_type = MP1L3_AUDIO;
else if (m_id == 0)
pAudioCodecInfo->m_info_out.stream_type = MP2L3_AUDIO;
}
else if (m_layer == 2) {
if (m_id == 1)
pAudioCodecInfo->m_info_out.stream_type = MP1L2_AUDIO;
else if (m_id == 0)
pAudioCodecInfo->m_info_out.stream_type = MP2L2_AUDIO;
}
else if (m_layer == 1) {
if (m_id == 1)
pAudioCodecInfo->m_info_out.stream_type = MP1L1_AUDIO;
else if (m_id == 0)
pAudioCodecInfo->m_info_out.stream_type = MP2L1_AUDIO;
}
return UMC_OK;
}
Status MP3Encoder::GetDuration(Ipp32f *p_duration)
{
Ipp32f duration;
if (!p_duration)
return UMC_ERR_NULL_PTR;
duration = (Ipp32f)m_frame_num * m_frame_size;
duration /= (Ipp32f)(m_freq);
p_duration[0] = duration;
return UMC_OK;
}
Status MP3Encoder::SetParams(BaseCodecParams * /* params */) {
return UMC_ERR_NOT_IMPLEMENTED;
}
Status MP3Encoder::Reset() {
return UMC_ERR_NOT_IMPLEMENTED;
}
Status MP3Encoder::StatusMP3_2_UMC(MP3Status st)
{
Status res;
if (st == MP3_OK)
res = UMC_OK;
else if (st == MP3_NOT_ENOUGH_DATA)
res = UMC_ERR_NOT_ENOUGH_DATA;
else if (st == MP3_BAD_FORMAT)
res = UMC_ERR_INVALID_STREAM;
else if (st == MP3_ALLOC)
res = UMC_ERR_ALLOC;
else if (st == MP3_BAD_STREAM)
res = UMC_ERR_INVALID_STREAM;
else if (st == MP3_NULL_PTR)
res = UMC_ERR_NULL_PTR;
else if (st == MP3_NOT_FIND_SYNCWORD)
res = UMC_ERR_SYNC;
else if (st == MP3_NOT_ENOUGH_BUFFER)
res = UMC_ERR_NOT_ENOUGH_BUFFER;
else if (st == MP3_UNSUPPORTED)
res = UMC_ERR_UNSUPPORTED;
else if (st == MP3_FAILED_TO_INITIALIZE)
res = UMC_ERR_INIT;
else
res = UMC_ERR_UNSUPPORTED;
return res;
}
Status MP3Encoder::MemLock() {
MP3Enc *pOldState = state;
if (!m_pMemoryAllocator) {
vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed: m_pMemoryAllocator is NULL\n"));
return UMC_ERR_ALLOC;
}
state = (MP3Enc *)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) {
mp3encUpdateMemMap(state, (Ipp8u *)state-(Ipp8u *)pOldState);
}
return UMC_OK;
}
Status MP3Encoder::MemUnlock() {
if (stateMemId) {
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 + -