[Libav-user] How to transcode mp3 file to G.711 encoded wav file
Robert Smith
wmk587 at yahoo.com
Sat Dec 4 00:36:03 EET 2021
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);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20211203/a227e5cc/attachment.htm>
More information about the Libav-user
mailing list