2 * copyright (c) 2001 Fabrice Bellard
4 * This file is part of Libav.
6 * Libav is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * Libav is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Libav; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * audio decoding with libavcodec API example
25 * @example decode_audio.c
32 #include "libavutil/channel_layout.h"
33 #include "libavutil/frame.h"
34 #include "libavutil/mem.h"
36 #include "libavcodec/avcodec.h"
38 #define AUDIO_INBUF_SIZE 20480
39 #define AUDIO_REFILL_THRESH 4096
41 static void decode(AVCodecContext
*dec_ctx
, AVPacket
*pkt
, AVFrame
*frame
,
44 int16_t *interleave_buf
;
45 int ret
, data_size
, i
;
47 /* send the packet with the compressed data to the decoder */
48 ret
= avcodec_send_packet(dec_ctx
, pkt
);
50 fprintf(stderr
, "Error submitting the packet to the decoder\n");
54 /* read all the output frames (in general there may be any number of them */
56 ret
= avcodec_receive_frame(dec_ctx
, frame
);
57 if (ret
== AVERROR(EAGAIN
) || ret
== AVERROR_EOF
)
60 fprintf(stderr
, "Error during decoding\n");
64 /* the stream parameters may change at any time, check that they are
66 if (av_get_channel_layout_nb_channels(frame
->channel_layout
) != 2 ||
67 frame
->format
!= AV_SAMPLE_FMT_S16P
) {
68 fprintf(stderr
, "Unsupported frame parameters\n");
72 /* The decoded data is signed 16-bit planar -- each channel in its own
73 * buffer. We interleave the two channels manually here, but using
74 * libavresample is recommended instead. */
75 data_size
= sizeof(*interleave_buf
) * 2 * frame
->nb_samples
;
76 interleave_buf
= av_malloc(data_size
);
80 for (i
= 0; i
< frame
->nb_samples
; i
++) {
81 interleave_buf
[2 * i
] = ((int16_t*)frame
->data
[0])[i
];
82 interleave_buf
[2 * i
+ 1] = ((int16_t*)frame
->data
[1])[i
];
84 fwrite(interleave_buf
, 1, data_size
, outfile
);
85 av_freep(&interleave_buf
);
89 int main(int argc
, char **argv
)
91 const char *outfilename
, *filename
;
93 AVCodecContext
*c
= NULL
;
94 AVCodecParserContext
*parser
= NULL
;
97 uint8_t inbuf
[AUDIO_INBUF_SIZE
+ AV_INPUT_BUFFER_PADDING_SIZE
];
101 AVFrame
*decoded_frame
= NULL
;
104 fprintf(stderr
, "Usage: %s <input file> <output file>\n", argv
[0]);
108 outfilename
= argv
[2];
110 /* register all the codecs */
111 avcodec_register_all();
113 av_init_packet(&avpkt
);
115 /* find the MPEG audio decoder */
116 codec
= avcodec_find_decoder(AV_CODEC_ID_MP2
);
118 fprintf(stderr
, "codec not found\n");
122 parser
= av_parser_init(codec
->id
);
124 fprintf(stderr
, "parser not found\n");
128 c
= avcodec_alloc_context3(codec
);
131 if (avcodec_open2(c
, codec
, NULL
) < 0) {
132 fprintf(stderr
, "could not open codec\n");
136 f
= fopen(filename
, "rb");
138 fprintf(stderr
, "could not open %s\n", filename
);
141 outfile
= fopen(outfilename
, "wb");
147 /* decode until eof */
149 data_size
= fread(inbuf
, 1, AUDIO_INBUF_SIZE
, f
);
151 while (data_size
> 0) {
152 if (!decoded_frame
) {
153 if (!(decoded_frame
= av_frame_alloc())) {
154 fprintf(stderr
, "out of memory\n");
159 ret
= av_parser_parse2(parser
, c
, &avpkt
.data
, &avpkt
.size
,
161 AV_NOPTS_VALUE
, AV_NOPTS_VALUE
, 0);
163 fprintf(stderr
, "Error while parsing\n");
170 decode(c
, &avpkt
, decoded_frame
, outfile
);
172 if (data_size
< AUDIO_REFILL_THRESH
) {
173 memmove(inbuf
, data
, data_size
);
175 len
= fread(data
+ data_size
, 1,
176 AUDIO_INBUF_SIZE
- data_size
, f
);
185 avcodec_free_context(&c
);
186 av_parser_close(parser
);
187 av_frame_free(&decoded_frame
);