Ticket #10710: ffmpeg-decode_wav.c

File ffmpeg-decode_wav.c, 3.8 KB (added by fabi78, 2 years ago)
Line 
1/* Simple wav audio player */
2
3#include <stdint.h>
4#include <stdbool.h>
5#include <libavcodec/avcodec.h>
6#include <libavformat/avformat.h>
7
8int main(int argc, char *argv[])
9{
10 int ret = 0;
11 int ret_packet, ret_frame;
12 int audio_stream_index;
13 int total_samples = 0;
14 int channels_n = 0;
15 int bytes_per_sample = 0;
16
17 if( argc < 2 )
18 {
19 printf( "Please choose an input file\n" );
20 exit(0);
21 }
22
23 FILE *pfile = fopen( "ffmpeg_decode_wav_out.raw", "w" );
24 if ( pfile == NULL )
25 {
26 printf( "Output file not open\n" );
27 exit(1);
28 }
29 AVFormatContext *pFormatContext = avformat_alloc_context();
30
31 if ( avformat_open_input( &pFormatContext, argv[1], NULL, NULL ) != 0)
32 {
33 fprintf(stderr, "ERROR could not open the source\n");
34 return -1;
35 }
36
37 avformat_find_stream_info( pFormatContext, NULL );
38
39 const AVCodec *pCodec;
40 ret = av_find_best_stream( pFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1, &pCodec, 0);
41
42 if ( ret == AVERROR_STREAM_NOT_FOUND )
43 {
44 av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the input file\n");
45 return ret;
46 }
47
48 else if( ret == AVERROR_DECODER_NOT_FOUND )
49 {
50 av_log(NULL, AV_LOG_ERROR, "Audio stream found but decoder not found\n");
51 return ret;
52 }
53
54 audio_stream_index = ret;
55 AVCodecParameters *pCodecParameters = pFormatContext->streams[ audio_stream_index ]->codecpar;
56 AVCodecContext *pCodecContext = avcodec_alloc_context3( pCodec );
57 avcodec_parameters_to_context( pCodecContext, pCodecParameters );
58
59 if ( avcodec_open2( pCodecContext, pCodec, NULL ) < 0 )
60 {
61 fprintf( stderr, "Could not open codec\n" );
62 exit(1);
63 }
64
65 if ( !pCodecContext )
66 {
67 fprintf( stderr, "Failed to allocated memory for AVCodecContext\n" );
68 return -1;
69 }
70
71 fprintf( stderr, "format %s, codec id = %i, duration %li µs, bit_rate %li\n",
72 pFormatContext->iformat->name, pCodecContext->codec_id, pFormatContext->duration,
73 pFormatContext->bit_rate );
74
75 bytes_per_sample = av_get_bytes_per_sample( pCodecContext->sample_fmt );
76 channels_n = pCodecContext->ch_layout.nb_channels;
77
78 AVFrame *pFrame = av_frame_alloc();
79 if (!pFrame)
80 {
81 fprintf( stderr,"Failed to allocated memory for AVFrame\n" );
82 return -1;
83 }
84
85 AVPacket *pPacket = av_packet_alloc();
86 if ( !pPacket )
87 {
88 fprintf( stderr,"Failed to allocated memory for AVPacket\n" );
89 return -1;
90 }
91
92 ret_packet = 0;
93 while ( ret_packet == 0 )
94 {
95 ret_packet = av_read_frame( pFormatContext, pPacket );
96 if ( ret_packet < 0 )
97 continue;
98 if( pPacket->stream_index == audio_stream_index )
99 {
100 if ( avcodec_send_packet( pCodecContext, pPacket ) < 0 )
101 {
102 fprintf( stderr, "Error submitting the packet to the decoder\n" );
103 break;
104 }
105
106 ret_frame = 0;
107 while( ret_frame >= 0 )
108 {
109 ret_frame = avcodec_receive_frame( pCodecContext, pFrame );
110 if ( ret_frame < 0)
111 {
112 if( ret_frame == AVERROR_EOF || ret_frame == AVERROR(EAGAIN) )
113 {
114 break;
115 }
116
117 else
118 {
119 fprintf(stderr, "Error during decoding\n");
120 av_frame_unref( pFrame );
121 return -1;
122 }
123 }
124 else
125 {
126
127 fwrite( pFrame->data, 1,
128 pFrame->nb_samples * channels_n *
129 bytes_per_sample,
130 pfile );
131 total_samples += pFrame->nb_samples;
132 }
133
134 }
135 }
136
137 }
138 fclose( pfile );
139 printf( "Total samples = %i\n", total_samples );
140
141 /* clean up */
142 avformat_close_input( &pFormatContext );
143 av_frame_free( &pFrame );
144 av_packet_free( &pPacket );
145
146 return 0;
147}