[Libav-user] Encoding/Decoding Audio

Cesareo Fernandez cesareof at gmail.com
Tue Jan 24 18:38:57 EET 2017


Thanks for the quick reply.

I open the file and allocate out_buffer each time because this is just a
snippet of code that I slapped together to show the basic process I am
attempting, I will be sending stream of audio frames in a websocket to be
played back on a webpage in practice. I am writing to a file now just to
test whether or not I can decode a frame of audio and get it to playback in
a file. A task that is proving difficult enough. I am not really sure how
to work with audio though. I tested your suggestion and it produces no
better results:

uint8_t *out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE*2);
int data_size = swr_convert(au_convert_ctx,&out_buffer,
MAX_AUDIO_FRAME_SIZE,(const uint8_t **)pFrame->data , pFrame->nb_samples);
fwrite(out_buffer, 1, data_size, fOut);

This is the file I am testing this function against:

ffmpeg.exe -i \\Handel.mp3
[mp3 @ 027dda40] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from '\\Handel.mp3':
  Metadata:
    artist          : Quinn String Quartet
    album           : Israeli Concertino
    genre           : Classical
  Duration: 00:00:51.55, start: 0.000000, bitrate: 127 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
At least one output file must be specified


When I inspect the resulting pcm after decoding file via ffmpeg.exe -i
<fOut>

I see a lot of this:
[aac @ 002e77e0] Dependent coupling is not supported together with LTP Last
message repeated 35 times
[aac @ 002e77e0] Invalid Predictor Reset Group.
[aac @ 002e77e0] Pulse data corrupt or invalid.
[aac @ 002e77e0] Reserved bit set.
[aac @ 002e77e0] Input buffer exhausted before END element found
[aac @ 002e77e0] Reserved bit set.
Last message repeated 3 times
[aac @ 0440da40] Estimating duration from bitrate, this may be inaccurate
[aac @ 0440da40] Could not find codec parameters for stream 0 (Audio: aac,
4.0,
fltp, 1535 kb/s): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize'
options
\\audio_out.pcm: could not find codec parameters
Input #0, aac, from '\\audio_out.pcm':
  Duration: 00:00:11.94, bitrate: 1535 kb/s
    Stream #0:0: Audio: aac, 4.0, fltp, 1535 kb/s
At least one output file must be specified



On Mon, Jan 23, 2017 at 8:04 PM, Steve Myers <musicspeedchanger at gmail.com>
wrote:

>
> On Jan 23, 2017, at 5:38 PM, Cesareo Fernandez <cesareof at gmail.com> wrote:
>
> I have been attempting to use the ffmpeg libraries to take as input a RTMP
> stream consisting of a video stream and an audio stream, and decode the
> respective streams in order to push the contents out to a website via a
> websocket. The video portion of this task is complete and works fine
> without issue. Converting frames of h.264 video to single motion jpeg
> images and pushing those on without a problem. I am attempting to do
> something similar with audio, takes frames of aac audio and passing those
> out through a websocket to be played back in chunks, this portion of the
> task is proving to be a lot more difficult than I thought it would be.
>
> The way I am testing this is simply learning the way to decode an encode
> audio (if necessary) to a file before trying to implement it practically
> via websockets and even this is proving more difficult than I expected, I
> found some examples via google, but I can't get any of these to work:
>
>
> int PullAudioFrames( char input[], char output[] )
> {
> const int MAX_AUDIO_FRAME_SIZE = 192000;
>     bool bRet = false;
> bool bFileOpened = false;
> bool bAudioCodecOpen = false;
> bool abort = false;
>
> int nVideoStream = -1;
> int nAudioStream = -1;
> AVDictionary *optionsDict = NULL;
> //-- Register all formats and codecs and network tools
> avcodec_register_all();
> av_register_all();
> avformat_network_init();
> //--
>
> AVCodecContext *pIn_AudioCodecCtx = NULL;
> AVCodec *pIn_AudioCodec = NULL;
> struct SwrContext *au_convert_ctx;
>
> AVFormatContext *pFormatCtx = avformat_alloc_context();
> if(avformat_open_input(&pFormatCtx, input, NULL, &optionsDict) == 0 ) //Open
> Stream
> {
> bFileOpened = true;
> if(avformat_find_stream_info(pFormatCtx, &optionsDict) >= 0 ) //Get
> Stream information (video, audio, subtitle)
> {
> for(int i=0; i<(int)pFormatCtx->nb_streams; i++) //Find the video stream
> {
> if(pFormatCtx->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_AUDIO)
> nAudioStream=i;
> if( nAudioStream >= 0 )
> break;
> }
> bool bCleanUp = false;
> if( nAudioStream >= 0 )
> {
> pIn_AudioCodec = avcodec_find_decoder( pFormatCtx->streams[
> nAudioStream]->codecpar->codec_id );
> if(pIn_AudioCodec  != NULL)
> {
> pIn_AudioCodecCtx = avcodec_alloc_context3(pIn_AudioCodec);
> // Fill the codecCtx with the parameters of the codec used in the read
> file.
> if( avcodec_parameters_to_context(pIn_AudioCodecCtx, pFormatCtx->streams[nAudioStream]->codecpar)
> == 0  )
> {
> if( avcodec_open2(pIn_AudioCodecCtx, pIn_AudioCodec, NULL) >= 0 ) //Open
> Audio codec
> bAudioCodecOpen = true;
> else
> bCleanUp = true;
> }
> else
> bCleanUp = true;
> }
> }
> if( bCleanUp )
> {
> avcodec_close( pIn_AudioCodecCtx );
> avcodec_free_context( &pIn_AudioCodecCtx );
> }
>
> if( bAudioCodecOpen )
> {
> au_convert_ctx = swr_alloc();
> au_convert_ctx=swr_alloc_set_opts(au_convert_ctx, AV_CH_LAYOUT_STEREO,
> AV_SAMPLE_FMT_S16, 44100, av_get_default_channel_layout(pIn_AudioCodecCtx->channels),
> pIn_AudioCodecCtx->sample_fmt , pIn_AudioCodecCtx->sample_rate,0, NULL);
> swr_init(au_convert_ctx);
>
> AVFrame *pFrame=av_frame_alloc();
> AVPacket packet;
> av_init_packet(&packet);
>
> while( !abort )
> {
> av_packet_unref(&packet);
> av_frame_unref(pFrame);
> int result = av_read_frame( pFormatCtx, &packet);
> if( result < 0 )
> {
> if( result == AVERROR(EAGAIN) )
> continue;
> else if( result == AVERROR(EPIPE) )
> printf( "[\"Error\", {\"message\" : \"Unable to read Frame pipe error.
> [%d] [%d]\"}]", result, AVERROR(result) );
> else if (result == AVERROR_EOF)
> printf( "[\"Error\", {\"message\" : \"Unable to read Frame end of File.
> [%d] [%d]\"}]", result, AVERROR(result) );
> else
> printf( "[\"Error\", {\"message\" : \"Unable to read Frame. [%d] [%d]\"}]
> ", result, AVERROR(result) );
> abort = true;
> }
> else
> {
> if(packet.stream_index==nAudioStream)
> {
> int frameFinished=0;
> int nResult = avcodec_send_packet(pIn_AudioCodecCtx, &packet);
> if( nResult == 0 )
> nResult = avcodec_receive_frame( pIn_AudioCodecCtx, pFrame );
>
> if( nResult == 0 )
> {
> uint8_t *out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE*2);
> int data_size = av_samples_get_buffer_size(NULL,
> pIn_AudioCodecCtx->channels, pFrame->nb_samples,
> pIn_AudioCodecCtx->sample_fmt, 1);
> swr_convert(au_convert_ctx,&out_buffer, MAX_AUDIO_FRAME_SIZE,(const
> uint8_t **)pFrame->data , pFrame->nb_samples);
>
> FILE *fOut;
> if( fopen_s( &fOut, output, "a+" ) == 0 )
> {
> fwrite(out_buffer, 1, data_size, fOut);
> fclose(fOut);
> }
> }
> }
> }
> av_packet_unref(&packet);
> }
> av_frame_free(&pFrame);
> }
> else
> printf( "Unable to open Codec in %s", input );
> }
> else
> printf( "No stream information found in %s", input );
> }
> else
> printf("Unable to open live video stream %s", input );
>
>
> if( bAudioCodecOpen )
> {
> avcodec_close(pIn_AudioCodecCtx);
> avcodec_free_context(&pIn_AudioCodecCtx);
> swr_free(&au_convert_ctx);
> bAudioCodecOpen  = false;
> }
>
> if(bFileOpened)
> {
> if( pFormatCtx )
> avformat_close_input(&pFormatCtx);
> bFileOpened = false;
> }
> return 0;
> }
>
>
> The resulting file is not playable and passing it back through CLI
> ffmpeg.exe doesn't give a whole lot of useful information why that is. Any
> help, or point in the right direction would be greatly appreciated.
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
>
> uint8_t *out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE*2);
> int data_size = av_samples_get_buffer_size(NULL,
> pIn_AudioCodecCtx->channels, pFrame->nb_samples,
> pIn_AudioCodecCtx->sample_fmt, 1);
> swr_convert(au_convert_ctx,&out_buffer, MAX_AUDIO_FRAME_SIZE,(const
> uint8_t **)pFrame->data , pFrame->nb_samples);
>
> FILE *fOut;
> if( fopen_s( &fOut, output, "a+" ) == 0 )
> {
> fwrite(out_buffer, 1, data_size, fOut);
> fclose(fOut);
> }
> This looks wrong, you should be using the return of swr_convert to base
> the number of bytes to write. Also, why allocate out_buffer, and open and
> close the file on every frame?
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20170124/1b610e3a/attachment.html>


More information about the Libav-user mailing list