其实,很多关于编解码的音视频例子,都是通过文件来进行操作的。
自己做过的(ffmpeg视频编解码、g726编解码、g723编解码)都是从网上找的例子来进行修改的。其中,最难的地方就是在于把文件读取改为缓存读取。
需要编解码的音视频流,都是通过回调函数回调上来的,一般有用的是两个参数:指针和流的大小长度。这里总结一下g723的方法。
g723是通过读取一个字节,而不是通过读取流的一定长度,来进行编解码的,这可是有点棘手呀!
自己要解决的问题:
1.流的复制:fread函数替换为memcpy函数。(g723每次复制一个字节)
2.每次关于一个字节的编解码:使用指针来进行操作。(直接贴上自己的代码,希望对大家有帮助吧!)
编码:
int CG723Enc::G723Enc_Encode(char *szInBuf, int nInBufLen, char *szOutBuf, int& nOutBufLen)
{
short sSample = 0;
unsigned char szCode = 0;
unsigned char szOut_Byte = 0;
nOutBufLen = 0;
char *szPos = szInBuf;
while ((szPos - szInBuf) < nInBufLen)
{
memcpy(&sSample, (short*)szPos, sizeof(short));
szPos += 2;
szCode = g723_40_encoder(sSample, AUDIO_ENCODING_LINEAR, &m_State);
m_OutBuffer |= (szCode << m_OutBits);
m_OutBits += m_EncBits;
if (m_OutBits >= 8)
{
szOut_Byte = m_OutBuffer & 0xff;
m_OutBits -= 8;
m_OutBuffer >>= 8;
memcpy(szOutBuf + nOutBufLen, &szOut_Byte, sizeof(char));
nOutBufLen++;
}
}
return 0;
}
解码:
int CG723Dec::G723Dec_Decode(char *szInBuf, int nInBufLen, char *szOutBuf, int& nOutBufLen)
{
char *szPos = szInBuf;
nOutBufLen = 0;
while (szPos - szInBuf < nInBufLen)
{
if (m_InBits < m_DecBits)
{
memcpy(&m_InByte, szPos, sizeof(char));
m_InBuffer |= (m_InByte << m_InBits);
m_InBits += 8;
szPos++;
}
unsigned char code = m_InBuffer & ((1 << m_DecBits) - 1);
m_InBuffer >>= m_DecBits;
m_InBits -= m_DecBits;
short sample = g723_40_decoder(code, AUDIO_ENCODING_LINEAR, &m_State);
memcpy(szOutBuf + 2*nOutBufLen, (char*)&sample, sizeof(short));
nOutBufLen++;
}
nOutBufLen--;
nOutBufLen *= 2;
return 0;
}
这次的工作,让自己对指针的理解加深,说实话,自己对指针的运用不算太好,继续努力!这是自己需要注意的。
ps:自己在这里犯的错误是关于逻辑上的失误。代码读懂,逻辑缕清,很重要的。
菜鸟,继续加油吧!