Hello,
I need to write C++ function to transcode any mp3 file to G.711 encoded wav
file using LibAV API.I wrote the function and it seems working without errors,
the only problemis that instead of music in original mp3 file I am getting
random noise in G.711 encoded wav file.Obviously I'm doing something wrong, but
I can't understand what is wrong
Could you please review code segment below and point me out ifyou see any LibAv
related errors there. Your input is greatly appreciated.
Thanks
******************************************************
// sMp3FileName the path to input file // sOutFileName the path to
output file
av_register_all();
///////////////////////// // Prepare input context AVFormatContext*
format = avformat_alloc_context(); if (avformat_open_input(&format,
sMp3FileName, NULL, NULL) != 0) { CUDump("CMP3Decoder: Could not open
input file %s\n", (PCTSTR)sMp3FileName);
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
if (avformat_find_stream_info(format, NULL) < 0) {
avformat_free_context(format);
CUDump("CMP3Decoder: Could not retrieve stream info from file %s\n",
(PCTSTR)sMp3FileName);
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
// Find the index of the first audio stream int stream_index =- 1;
for (int i=0; i < format->nb_streams; i++) { if
(format->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
stream_index = i; break; } }
if (stream_index == -1) { avformat_free_context(format);
CUDump("CMP3Decoder: Could not retrieve audio stream from file %s\n",
(PCTSTR)sMp3FileName);
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
AVStream* stream = format->streams[stream_index];
// Find & open codec AVCodecContext* pMp3CodecCtx = stream->codec; if
(avcodec_open2(pMp3CodecCtx, avcodec_find_decoder(pMp3CodecCtx->codec_id),
NULL) < 0) { avformat_free_context(format);
CUDump("CMP3Decoder: Failed to open decoder for stream #%u in file
%s\n", stream_index, (PCTSTR)sMp3FileName);
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
AVPacket packet; av_init_packet(&packet); AVFrame* frame =
avcodec_alloc_frame(); if (!frame) { avcodec_close(pMp3CodecCtx);
avformat_free_context(format);
CUDump("CMP3Decoder: Error allocating the frame\n");
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
///////////////////////// // Prepare Output context AVFormatContext
*output_ctx; avformat_alloc_output_context2(&output_ctx, NULL, "wav",
sOutFileName); output_ctx->oformat->audio_codec = CODEC_ID_PCM_MULAW;
AVCodec* pCodec = avcodec_find_encoder(CODEC_ID_PCM_MULAW); if (pCodec
== NULL) { av_free(frame); avcodec_close(pMp3CodecCtx);
avformat_free_context(format);
CUDump("CMP3Decoder: Could not find CODEC_ID_PCM_MULAW codec\n");
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
AVStream *out_stream = avformat_new_stream(output_ctx, pCodec); if
(!out_stream) { CUDump("CMP3Decoder: Failed to allocate output
stream\n"); pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE));
return TRUE; }
AVCodecContext* pCodecCtx = avcodec_alloc_context3(pCodec); if
(!pCodecCtx) { av_free(frame); avcodec_close(pMp3CodecCtx);
avformat_free_context(format);
CUDump("CMP3Decoder: Could not allocate audio codec context\n");
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
pCodecCtx->channels = 1; pCodecCtx->channel_layout = AV_CH_LAYOUT_MONO;
pCodecCtx->sample_rate = 8000; pCodecCtx->bit_rate = 64000;
pCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { av_free(frame);
avcodec_close(pMp3CodecCtx); avformat_free_context(format);
CUDump("CMP3Decoder: Could not open codec\n");
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
if (avio_open(&output_ctx->pb, sOutFileName, AVIO_FLAG_WRITE) < 0) {
CUDump("CMP3Decoder: Could not open output file %s", (PCTSTR)sOutFileName);
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return
TRUE; }
// The following line allows to write the file header. Why initialisation
doesn't set it up? output_ctx->streams[0]->codec = pCodecCtx;
// Write file header if (avformat_write_header(output_ctx, NULL) < 0)
{ CUDump("CMP3Decoder: Error occurred when writing header to output file
%s\n", (PCTSTR)sOutFileName);
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return TRUE;
}
// iterate through frames while (av_read_frame(format, &packet) >= 0)
{ // decode one frame int gotFrame; if
(avcodec_decode_audio4(pMp3CodecCtx, frame, &gotFrame, &packet) < 0) {
CUDump("CMP3Decoder: avcodec_decode_audio4 failed\n"); break;
}
if (!gotFrame) { continue; }
av_init_packet(&packet_out); packet_out.data = NULL;
packet_out.size = 0; if(avcodec_encode_audio2(pCodecCtx, &packet_out,
frame, &gotFrame) < 0) { CUDump("CMP3Decoder:
avcodec_encode_audio2 failed\n");
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return
TRUE; }
if (!gotFrame) { continue; }
packet_out.stream_index = stream_index;
// Write the encoded audio frame to the output file. if
(av_interleaved_write_frame(output_ctx, &packet_out) < 0) {
CUDump("CMP3Decoder: av_interleaved_write_frame failed\n");
pContext->SetReturnValueNoRef(CCSGdBoolean::Allocate(FALSE)); return
TRUE; }
av_free_packet(&packet_out); }
av_write_trailer(output_ctx); avio_close(output_ctx->pb);
// clean up av_free(frame); avcodec_close(pMp3CodecCtx);
avformat_free_context(format);
_______________________________________________
Libav-user mailing list
[email protected]
https://ffmpeg.org/mailman/listinfo/libav-user
To unsubscribe, visit link above, or email
[email protected] with subject "unsubscribe".