[FFmpeg-devel] [PATCH 2/2] examples: demuxing: simplify audio output

Stefano Sabatini stefasab at gmail.com
Sun Jul 14 20:14:10 CEST 2013


On date Saturday 2013-07-13 15:53:20 +0200, wm4 encoded:
> There is no reason why this should copy the audio data in a very
> complicated way. Also, strictly write the first plane, instead of
> writing the whole buffer. This is more helpful in context of the
> example. This way a user can clearly confirm that it works by playing
> the written data as raw audio.
> ---
>  doc/examples/demuxing.c | 29 +++++++++--------------------
>  1 file changed, 9 insertions(+), 20 deletions(-)
> 
> diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing.c
> index 1c0f1ff..089b5b0 100644
> --- a/doc/examples/demuxing.c
> +++ b/doc/examples/demuxing.c
> @@ -104,26 +104,15 @@ static int decode_packet(int *got_frame, int cached)
>                     audio_frame_count++, frame->nb_samples,
>                     av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
>  
> -            ret = av_samples_alloc(audio_dst_data, &audio_dst_linesize, av_frame_get_channels(frame),
> -                                   frame->nb_samples, frame->format, 1);
> -            if (ret < 0) {
> -                fprintf(stderr, "Could not allocate audio buffer\n");
> -                return AVERROR(ENOMEM);
> -            }
> -
> -            /* TODO: extend return code of the av_samples_* functions so that this call is not needed */
> -            audio_dst_bufsize =
> -                av_samples_get_buffer_size(NULL, av_frame_get_channels(frame),
> -                                           frame->nb_samples, frame->format, 1);
> -
> -            /* copy audio data to destination buffer:
> -             * this is required since rawaudio expects non aligned data */
> -            av_samples_copy(audio_dst_data, frame->data, 0, 0,
> -                            frame->nb_samples, av_frame_get_channels(frame), frame->format);
> -
> -            /* write to rawaudio file */
> -            fwrite(audio_dst_data[0], 1, audio_dst_bufsize, audio_dst_file);
> -            av_freep(&audio_dst_data[0]);
> +            /* Write the raw audio data samples of the first plane. This works
> +             * fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
> +             * most audio decoders output planar audio, which uses a separate
> +             * plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
> +             * In other words, this code will write only the first audio channel
> +             * in these cases.
> +             * You should use libswresample or libavfilter to convert the frame
> +             * to packed data. */
> +            fwrite(frame->extended_data[0], 1, frame->linesize[0], audio_dst_file);

Doesn't work if you have padded data, as it happens when data is
aligned, which will result in audible sound artifacts.

You can keep the previous logic in case of packed data (copy to
non-aligned buffer, and copy to file), or always put only the first
plane of data, which could contain one or more channels depending on
the packed/non-packed path.
-- 
FFmpeg = Fostering & Freak Merciful Plastic Elitarian Gorilla


More information about the ffmpeg-devel mailing list