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