mp3 encoding --PCM transfer MP3, PCM encoded as MP3, how to achieve multiple simultaneous MP3 encoding -VC, MFC realize --- QQ35744025

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/xjb2006/article/details/78404523

You're watching a hurry

Do not worry, let's warm up pictures

Used to seeing beautiful pictures

Trip to Zhang Meng baby



Previous article, to achieve a mp3 decoder, tested at the same time also have the ability to multi-channel decoding.

Prior to this, I have been using a dynamic library BladeMP3EncDLL encode, in fact, no problem, it is not multi-threaded code. . .

__declspec(dllexport) BE_ERRbeInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream);
__declspec(dllexport) BE_ERR beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples, PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput);
// added for floating point audio  -- DSPguru, jd
__declspec(dllexport) BE_ERR beEncodeChunkFloatS16NI(HBE_STREAM hbeStream, DWORD nSamples, PFLOAT buffer_l, PFLOAT buffer_r, PBYTE pOutput, PDWORD pdwOutput);
__declspec(dllexport) BE_ERR beDeinitStream(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput);
__declspec(dllexport) BE_ERR beCloseStream(HBE_STREAM hbeStream);
__declspec(dllexport) VOID beVersion(PBE_VERSION pbeVersion);
__declspec(dllexport) BE_ERR beWriteVBRHeader(LPCSTR lpszFileName);
__declspec(dllexport) BE_ERR beFlushNoGap(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput);
__declspec(dllexport) BE_ERR beWriteInfoTag( HBE_STREAM hbeStream, LPCSTR lpszFileName );

In fact, multi-threading work it can do, is too much trouble, multiple copies DLL, LOAD a dll is a coding. . . If the 255, it is necessary to copy 255 copies, which is too pit father it !!! As a virgin, I, oh, slip of the tongue, is a Virgo, I will not be tolerated. Well, write it yourself online to find the next, really a lot, but not a fly. Finally a good package based on LAME encoder, because the former author adds too much global or static thing, can only support a single code, we wanted to change multiple simultaneous encodes estimates have a big head. . .

We had to try something else, that with ipp it, intel ipp is provided by efficient media library, processed for audio and video, pictures, etc., quite powerful.

I do not want to type, and posted the code point of it:

/*//////////////////////////////////////////////////////////////////////////////
//
//                  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-2008 Intel Corporation. All Rights Reserved.
//
*/


#include "umc_defs.h"
#if defined (UMC_ENABLE_MP3_AUDIO_ENCODER)


#ifndef __UMC_MP3_ENCODER_H__
#define __UMC_MP3_ENCODER_H__


#include "umc_media_data.h"
#include "umc_audio_codec.h"
#include "audio_codec_params.h"
#include "mp3_status.h"


struct _MP3Enc;


namespace UMC {




/* /////////////////////////////////////////////////////////////////////////////
//  Class:       MP3Encoder
//
//  Notes:       Implementation of MPEG-I layer 3 encoder.
//
*/
class   MP3Encoder:public AudioCodec 
{


public:


virtual Status  Init(BaseCodecParams * init);
virtual Status  Close();


virtual Status  GetFrame(MediaData * in, MediaData * out);
virtual Status  GetFrame(char * in,int nInLen, char * out,int &nOutLen);


virtual Status  GetInfo(BaseCodecParams * init);
virtual Status  GetDuration(Ipp32f *p_duration);


MP3Encoder(void);
virtual ~ MP3Encoder ();


virtual Status  SetParams(BaseCodecParams * params);
virtual Status  Reset();


virtual IppBool CheckBitRate(Ipp32s sample_rate,
Ipp32s layer,
Ipp32s bitrate,
Ipp32s stereo);


protected:
struct _MP3Enc  *state;
Ipp32s  m_stereo;
Ipp32s  m_freq;
Ipp32s  m_layer;
Ipp32s  m_bitrate;
Ipp32s  m_br_mode;
Ipp32s  m_stereo_mode;
Ipp32s  m_ns_mode;
Ipp32s  m_id;
Ipp32s  m_frame_size;
Ipp32s  m_upsample;
Ipp32s  m_force_mpeg1;
Ipp32s  m_mc_matrix_procedure;
Ipp32s  m_mc_lfe_filter_off;
Ipp64f  m_pts_prev;
MemID  stateMemId;
Ipp32s m_initialized;


Status StatusMP3_2_UMC(MP3Status st);
Status MemLock();
Status MemUnlock();
};


};      // namespace UMC


#endif /* __UMC_MP3_ENCODER_H__ */


#endif //UMC_ENABLE_MP3_AUDIO_ENCODER

I've been packaged in a OCX, the process is very difficult, but eventually succeeded. A yin swing to giggle laughing out loud. . .

#pragma once
#include "Mp3Enc.h"


// Mp3encoderCtrl.h : CMp3encoderCtrl ActiveX 控件类的声明。




// CMp3encoderCtrl : 有关实现的信息,请参阅 Mp3encoderCtrl.cpp。


class CMp3encoderCtrl : public COleControl
{
DECLARE_DYNCREATE(CMp3encoderCtrl)


// 构造函数
public:
CMp3encoderCtrl();


// 重写
public:
virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
virtual void DoPropExchange(CPropExchange* pPX);
virtual void OnResetState();


// 实现
protected:
~CMp3encoderCtrl();


DECLARE_OLECREATE_EX(CMp3encoderCtrl)    // 类工厂和 guid
DECLARE_OLETYPELIB(CMp3encoderCtrl)      // GetTypeInfo
DECLARE_PROPPAGEIDS(CMp3encoderCtrl)     // 属性页 ID
DECLARE_OLECTLTYPE(CMp3encoderCtrl)// 类型名称和杂项状态


// 消息映射
DECLARE_MESSAGE_MAP()


// 调度映射
DECLARE_DISPATCH_MAP()


afx_msg void AboutBox();


// 事件映射
DECLARE_EVENT_MAP()


// 调度和事件 ID
public:
enum {
dispidFreeAll = 5L,
dispidClose = 4L,
dispidEncode = 3L,
dispidInit = 2L,
dispidInitCount = 1L
};


#define MP3COUNT 300
protected:
int m_nCount;
CMp3Enc *m_mp3[MP3COUNT];
void InitCount(LONG nCount);
void Init(LONG nIndex, LONG sample_frequency, LONG channel, LONG bitrate);
LONG Encode(LONG nIndex, BYTE* pInPCM, LONG nPCMLen, BYTE* pOutMp3);
void Close(LONG nIndex);
void FreeAll(void);
};
最多支持300路,当然再多也可以,这个看你自己需要啊,但是太多,多半CPU吃不消吧。。。

最后,贴下编码封装代码

#include "stdafx.h"
#include "Mp3Enc.h"


CMp3Enc::CMp3Enc(void)
{
m_pAudioEncoder=0;
m_pcmen=0;
m_mp3len=0;
int nSize=sizeof(MP3EncoderParams);
}


CMp3Enc::~CMp3Enc(void)
{
Close();
}


void CMp3Enc::Close()
{
if(m_pAudioEncoder)
{
delete m_pAudioEncoder;
m_pAudioEncoder=0;
}
m_pcmen=0;
m_mp3len=0;
}


void CMp3Enc::Init(int sample_frequency,int channel,int bitrate)
{
m_pcmen=0;
m_mp3len=0;
mp3enc_params.m_info_out.bitrate=bitrate;
AudioEncoderParams* par = (AudioEncoderParams*)(&mp3enc_params);

par->m_info.channel_mask = 0;
par->m_info.bitPerSample=16;
par->m_info.channels=channel;
par->m_info.sample_frequency=sample_frequency;
par->m_info.bitrate=bitrate;
par->m_info.stream_type=PCM_AUDIO;
m_pAudioEncoder=new MP3Encoder();
m_pAudioEncoder->Init(par);
}


BYTE* CMp3Enc::EncodeMp3(BYTE * in,int nInLen,int &nOutLen)
{
if(m_pcmen+nInLen<=sizeof(PCMBuf))
{
memcpy(PCMBuf+m_pcmen,in,nInLen);
m_pcmen+=nInLen;
}
AudioEncoderParams* par = (AudioEncoderParams*)(&mp3enc_params);
int nApplyPcmLen=2304*par->m_info.channels*par->m_info.sample_frequency/44100;
if(m_pcmen<nApplyPcmLen)//不够
{
nOutLen=0;
return Mp3Buf;
}
int nRead=0;
int nMp3Len=0;
BYTE BufMp3[1024*8];
for(;;)
{
BYTE *p=PCMBuf+nRead;
int nOut=4096;
BYTE *pOut=EncodeMp3_(p,nApplyPcmLen,nOut);
if(nOut>0)
{
memcpy(BufMp3+nMp3Len,pOut,nOut);
nMp3Len+=nOut;
}
nRead+=nApplyPcmLen;
m_pcmen-=nApplyPcmLen;
if(m_pcmen<nApplyPcmLen)
break;

}
if(m_pcmen>0)
memmove(PCMBuf,PCMBuf+nRead,m_pcmen);


nOutLen=nMp3Len;
return BufMp3;

}


BYTE* CMp3Enc::EncodeMp3_(BYTE * in,int nInLen,int &nOutLen)
{
char Buf[1024*4];
int nOut=sizeof(Buf);
try
{
Status s=m_pAudioEncoder->GetFrame((char*)in,nInLen,Buf,nOut);//只能输入2304*2=4608
if(s!=0)
{
nOutLen=0;
return Mp3Buf;
}
}
catch(...)
{
nOutLen=0;
return Mp3Buf;
}


memcpy(Mp3Buf+m_mp3len,Buf,nOut);
m_mp3len+=nOut;
MPADecodeContext ms;
if(m_mp3len)
{
int nReadLen=0;
nOutLen=0;
for(;;)
{
if(nReadLen>m_mp3len)
break;
int nCheck=check_header(*(uint32_t*)(Mp3Buf+nReadLen));
if(nCheck==-1)
break;
int nMp3FrameLen=decode_header(&ms,*(uint32_t*)(Mp3Buf+nReadLen));
if(m_mp3len>=nMp3FrameLen&&nMp3FrameLen>0&&nCheck==0)
{
memcpy(Buf+nReadLen,Mp3Buf+nReadLen,nMp3FrameLen);
nReadLen+=nMp3FrameLen;
m_mp3len-=nMp3FrameLen;
}
else
break;
}
nOutLen=nReadLen;
if(m_mp3len>0)
memmove(Mp3Buf,Mp3Buf+nReadLen,m_mp3len);
}


return (BYTE*)Buf;
}
编码看上去怎么这么复杂,先不害怕,理解好了其实一点也不复杂:

因为为了配合之前做的mp3解码库,解码需要输入完整的一帧或者多帧,我们也就需要这种编码器。编码后是完整的一帧或者多帧。

Status s=m_pAudioEncoder->GetFrame((char*)in,nInLen,Buf,nOut);//这句是核心编码语句,必须输入特定的PCM长度,才能编码成功!(你问我为什么知道,调试啊,经验啊),而这个大小就是下面这个公式计算出来的。

int nApplyPcmLen=2304*par->m_info.channels*par->m_info.sample_frequency/44100;

如输出44100,双声道的mp3,输入大小就是2304*2=4608Byte(下面都是这个参数来表述的哦)

但是不能保证每次输入的都是4608啊,所以,我们开一个全局变量保存PCM数据,没有就等,有4608就编码并输出。OK,输入解决了。再来解决输出吧

,输出我们要保证完整的一帧或者多帧,怎样保证呢,查了下mp3数据结构,(并没有很深入,我喜欢点到为止,并不是什么都要知道,需要什么了解什么,快速解决问题创造效益才是硬道理!),mp3一帧的前4个byte保存了这一帧的声道,采样率,帧大小等信息,所以我们根据这个,可以判断一帧后面的大小,如果编码出来一帧不够417,那么就等下一次编码,下一次累加到上一次的buf。如果编码出来超过417,那就输出完整的一帧或者多帧。看我上面的代码你就明白了。看下输出结果:

MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;16,长度:417
MP3编码时间;16,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;16,长度:417
MP3编码时间;16,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417
MP3编码时间;0,长度:417

标准的417,看上去好美,这一刻,感觉回到了初恋。。。shyshyshyshyshyshy


When uploading the code to find time to go, and finally make ads:

The need for cooperation to contact QQ35744025, I have 03 years working, "proficient" audio and video applications programming techniques (plus barely proficient, to attract attention, ha ha), proficient in VC, MFC, multimedia educational software, recording and broadcasting software, broadcast software core technology most have been mastered, such as ffmpeg technology, MP4, FLV synthesis coding, H264, AAC, MP3, IPP can use efficient space conversion image, and can use INTEL cuda hardware H264 codec, can achieve real-time encoding 240 1080P, full synchronization and a high degree of smoothness, rtmp live push, rtmp server, YV12, YUV422, NV12, RGB24, RGB32 familiar with the conversion, scaling, wav, AAC, mp3 codec, the video transition effects algorithms, video watermarking, LOGO, text. Video screen capture, video capture camera, a video image display The D3D efficient, OPENCV, image library ximage, GDI, GDIPLUS skilled application, a voice recognition and text conversion, recognition and matching, LAN remote control, real-time audio and video call, capture card playback, in addition to the SQL database, ACCESS, EXCEL database, DOC, PDF file open to extract, FTPServer, Client, all of the above codes have been commercial.

Ah ah ah ah ah ah ah ah ah ah ah ah ah ah ah, there has been no detailed statistics, that I have learned so many things, ah, I really admire his ah




Guess you like

Origin blog.csdn.net/xjb2006/article/details/78404523