标注:
    本文代码直接修改了ffmpeg的example,可直接编译使用

    1. /**
    2. * @file
    3. * audio decoding with libavcodec API example
    4. *
    5. * @example decode_audio.c
    6. */
    7. #include <stdio.h>
    8. #include <stdlib.h>
    9. #include <string.h>
    10. extern "C"
    11. {
    12. #include <libavutil/frame.h>
    13. #include <libavutil/mem.h>
    14. #include <libavcodec/avcodec.h>
    15. }
    16. #define AUDIO_INBUF_SIZE 20480
    17. #define AUDIO_REFILL_THRESH 4096
    18. static int get_format_from_sample_fmt(const char** fmt,
    19. enum AVSampleFormat sample_fmt)
    20. {
    21. int i;
    22. struct sample_fmt_entry {
    23. enum AVSampleFormat sample_fmt; const char* fmt_be, * fmt_le;
    24. } sample_fmt_entries[] = {
    25. { AV_SAMPLE_FMT_U8, "u8", "u8" },
    26. { AV_SAMPLE_FMT_S16, "s16be", "s16le" },
    27. { AV_SAMPLE_FMT_S32, "s32be", "s32le" },
    28. { AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
    29. { AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
    30. };
    31. *fmt = NULL;
    32. for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
    33. struct sample_fmt_entry* entry = &sample_fmt_entries[i];
    34. if (sample_fmt == entry->sample_fmt) {
    35. *fmt = AV_NE(entry->fmt_be, entry->fmt_le);
    36. return 0;
    37. }
    38. }
    39. fprintf(stderr,
    40. "sample format %s is not supported as output format\n",
    41. av_get_sample_fmt_name(sample_fmt));
    42. return -1;
    43. }
    44. static void decode(AVCodecContext* dec_ctx, AVPacket* pkt, AVFrame* frame,
    45. FILE* outfile)
    46. {
    47. int i, ch;
    48. int ret, data_size;
    49. /* send the packet with the compressed data to the decoder */
    50. ret = avcodec_send_packet(dec_ctx, pkt);
    51. if (ret < 0) {
    52. fprintf(stderr, "Error submitting the packet to the decoder\n");
    53. exit(1);
    54. }
    55. /* read all the output frames (in general there may be any number of them */
    56. while (ret >= 0) {
    57. ret = avcodec_receive_frame(dec_ctx, frame);
    58. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
    59. return;
    60. else if (ret < 0) {
    61. fprintf(stderr, "Error during decoding\n");
    62. exit(1);
    63. }
    64. data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
    65. if (data_size < 0) {
    66. /* This should not occur, checking just for paranoia */
    67. fprintf(stderr, "Failed to calculate data size\n");
    68. exit(1);
    69. }
    70. for (i = 0; i < frame->nb_samples; i++)
    71. for (ch = 0; ch < dec_ctx->channels; ch++)
    72. fwrite(frame->data[ch] + data_size * i, 1, data_size, outfile);
    73. }
    74. }
    75. int main()
    76. {
    77. const char* outfilename = "out.pcm";
    78. const char* filename = "test.aac";
    79. const AVCodec* codec;
    80. AVCodecContext* codec_ctx = NULL;
    81. AVCodecParserContext* parser = NULL;
    82. int len, ret;
    83. FILE* f, * outfile;
    84. uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
    85. uint8_t* data;
    86. size_t data_size;
    87. AVPacket* pkt;
    88. AVFrame* decoded_frame = NULL;
    89. enum AVSampleFormat sfmt;
    90. int n_channels = 0;
    91. const char* fmt;
    92. pkt = av_packet_alloc();
    93. /* find the MPEG audio decoder */
    94. codec = avcodec_find_decoder(AV_CODEC_ID_AAC);
    95. if (!codec) {
    96. fprintf(stderr, "Codec not found\n");
    97. exit(1);
    98. }
    99. parser = av_parser_init(codec->id);
    100. if (!parser) {
    101. fprintf(stderr, "Parser not found\n");
    102. exit(1);
    103. }
    104. codec_ctx = avcodec_alloc_context3(codec);
    105. if (!codec_ctx) {
    106. fprintf(stderr, "Could not allocate audio codec context\n");
    107. exit(1);
    108. }
    109. /* open it */
    110. if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
    111. fprintf(stderr, "Could not open codec\n");
    112. exit(1);
    113. }
    114. f = fopen(filename, "rb");
    115. if (!f) {
    116. fprintf(stderr, "Could not open %s\n", filename);
    117. exit(1);
    118. }
    119. outfile = fopen(outfilename, "wb");
    120. if (!outfile) {
    121. av_free(codec_ctx);
    122. exit(1);
    123. }
    124. /* decode until eof */
    125. data = inbuf;
    126. data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
    127. while (data_size > 0) {
    128. if (!decoded_frame) {
    129. if (!(decoded_frame = av_frame_alloc())) {
    130. fprintf(stderr, "Could not allocate audio frame\n");
    131. exit(1);
    132. }
    133. }
    134. ret = av_parser_parse2(parser, codec_ctx, &pkt->data, &pkt->size,
    135. data, data_size,
    136. AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
    137. if (ret < 0) {
    138. fprintf(stderr, "Error while parsing\n");
    139. exit(1);
    140. }
    141. data += ret;
    142. data_size -= ret;
    143. if (pkt->size)
    144. decode(codec_ctx, pkt, decoded_frame, outfile);
    145. if (data_size < AUDIO_REFILL_THRESH) {
    146. memmove(inbuf, data, data_size);
    147. data = inbuf;
    148. len = fread(data + data_size, 1,
    149. AUDIO_INBUF_SIZE - data_size, f);
    150. if (len > 0)
    151. data_size += len;
    152. }
    153. }
    154. /* flush the decoder */
    155. pkt->data = NULL;
    156. pkt->size = 0;
    157. decode(codec_ctx, pkt, decoded_frame, outfile);
    158. /* print output pcm infomations, because there have no metadata of pcm */
    159. sfmt = codec_ctx->sample_fmt;
    160. if (av_sample_fmt_is_planar(sfmt)) {
    161. const char* packed = av_get_sample_fmt_name(sfmt);
    162. printf("Warning: the sample format the decoder produced is planar "
    163. "(%s). This example will output the first channel only.\n",
    164. packed ? packed : "?");
    165. sfmt = av_get_packed_sample_fmt(sfmt);
    166. }
    167. n_channels = codec_ctx->channels;
    168. if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
    169. goto end;
    170. printf("Play the output audio file with the command:\n"
    171. "ffplay -f %s -ac %d -ar %d %s\n",
    172. fmt, n_channels, codec_ctx->sample_rate,
    173. outfilename);
    174. end:
    175. fclose(outfile);
    176. fclose(f);
    177. avcodec_free_context(&codec_ctx);
    178. av_parser_close(parser);
    179. av_frame_free(&decoded_frame);
    180. av_packet_free(&pkt);
    181. return 0;
    182. }