void AudioCode::ENcode(AVCodecContext *cdc_ctx, AVFrame *frame, AVPacket *pkt){
int ret=0;
ret = avcodec_send_frame(cdc_ctx, frame);
if (ret < 0) {
qDebug() << "Error sending the frame to the encoder\n";
return;
}
while (ret >= 0) {
ret = avcodec_receive_packet(cdc_ctx, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
continue;
else if (ret < 0) {
qDebug() << "Error encoding audio frame\n";
continue;
}
socket->writeDatagram((char *)pkt->data,pkt->size,QHostAddress(m_strTargetIP),m_iTargetPort);
if(mp3OutFILE.isOpen())
mp3OutFILE.write((char *)pkt->data,pkt->size);
av_packet_unref(pkt);
}
return;
}
void AudioCode::PCM2MP3(){
AVFormatContext *fmtCtx = nullptr;
AVCodecContext *codecCtx =nullptr;
const AVCodec *codec = nullptr;
AVFrame *frame = nullptr;
AVPacket *pkt = nullptr;
fmtCtx = avformat_alloc_context();
frame = av_frame_alloc();
pkt = av_packet_alloc();
codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
if(codec==nullptr){
qInfo() <<"Cannot find audio encoder.\n";
}
codecCtx = avcodec_alloc_context3(codec);
codecCtx->bit_rate = 64000;
codecCtx->sample_fmt = AV_SAMPLE_FMT_S16P;
if (!check_sample_fmt(codec, codecCtx->sample_fmt)) {
qInfo() << "Encoder does not support sample format %s",
av_get_sample_fmt_name(codecCtx->sample_fmt);
exit(1);
}
codecCtx->sample_rate = Samplerate;
codecCtx->ch_layout =AV_CHANNEL_LAYOUT_STEREO;
if(avcodec_open2(codecCtx,codec,nullptr) < 0)
qInfo() << "Open encode error!";
frame->nb_samples = codecCtx->frame_size;
frame->format = codecCtx->sample_fmt;
av_channel_layout_copy(&frame->ch_layout, &codecCtx->ch_layout);
qInfo() << "start init swr";
struct SwrContext *swrContext = swr_alloc();
swr_alloc_set_opts2(&swrContext,
&codecCtx->ch_layout,
AV_SAMPLE_FMT_S16P,
Samplerate,
&codecCtx->ch_layout,
AV_SAMPLE_FMT_S16,
Samplerate,0,nullptr);
swr_init(swrContext);
qInfo() << "end init swr";
uint8_t **convert_data = static_cast<uint8_t**>(calloc(2, static_cast<int>(sizeof(convert_data))));
av_samples_alloc(convert_data,nullptr,2,codecCtx->frame_size,
codecCtx->sample_fmt,0);
uint8_t *frameBuf = static_cast<uint8_t *>(av_malloc(sizeof(uint8_t *)));
int length = av_samples_get_buffer_size(nullptr, codecCtx->ch_layout.nb_channels, codecCtx->frame_size, codecCtx->sample_fmt, 1);
int readsize = length / (codecCtx->ch_layout.nb_channels * av_get_bytes_per_sample(codecCtx->sample_fmt));
QByteArray arrayAll;
qInfo() << "start encode";
while(che){
QByteArray array = audioDevice->read(length);
arrayAll += array;
if(arrayAll.size() > length)
{
array = arrayAll.left(length);
arrayAll.remove(0,length);
frameBuf = reinterpret_cast<uint8_t *>(array.data()) ;
const uint8_t *tmpframe = frameBuf;
swr_convert(swrContext,
convert_data,codecCtx->frame_size,
&tmpframe,readsize);
frame->data[0] = convert_data[0];
frame->data[1] = convert_data[1];
ENcode(codecCtx,frame,pkt);
}
}
qInfo() << "end encode";
ENcode(codecCtx,nullptr,pkt);
swr_free(&swrContext);
avcodec_free_context(&codecCtx);
av_free(frame);
avio_close(fmtCtx->pb);
avformat_free_context(fmtCtx);
return;
}