Ticket #3557: decode_audio_test.cpp

File decode_audio_test.cpp, 7.8 KB (added by Oleg, 12 years ago)
Line 
1
2#include "stdafx.h"
3#include <iostream>
4
5extern "C"
6{
7#include "libavcodec/avcodec.h"
8#include "libavformat/avformat.h"
9//#include "swscale.h"
10#include "libswresample/swresample.h"
11};
12
13FILE *fin,
14 *fout;
15
16int ffmpeg_audio_decode( const char * inFile, const char * outFile)
17{
18 // Initialize FFmpeg
19 av_register_all();
20
21 AVFrame* frame = avcodec_alloc_frame();
22 if (!frame)
23 {
24 std::cout << "Error allocating the frame" << std::endl;
25 return 1;
26 }
27
28 // you can change the file name "01 Push Me to the Floor.wav" to whatever the file is you're reading, like "myFile.ogg" or
29 // "someFile.webm" and this should still work
30 AVFormatContext* formatContext = NULL;
31 //if (avformat_open_input(&formatContext, "01 Push Me to the Floor.wav", NULL, NULL) != 0)
32 if (avformat_open_input(&formatContext, inFile, NULL, NULL) != 0)
33 {
34 av_free(frame);
35 std::cout << "Error opening the file" << std::endl;
36 return 1;
37 }
38
39 if (avformat_find_stream_info(formatContext, NULL) < 0)
40 {
41 av_free(frame);
42 av_close_input_file(formatContext);
43 std::cout << "Error finding the stream info" << std::endl;
44 return 1;
45 }
46
47 AVStream* audioStream = NULL;
48 // Find the audio stream (some container files can have multiple streams in them)
49 for (unsigned int i = 0; i < formatContext->nb_streams; ++i)
50 {
51 if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
52 {
53 audioStream = formatContext->streams[i];
54 break;
55 }
56 }
57
58 if (audioStream == NULL)
59 {
60 av_free(frame);
61 av_close_input_file(formatContext);
62 std::cout << "Could not find any audio stream in the file" << std::endl;
63 return 1;
64 }
65
66 AVCodecContext* codecContext = audioStream->codec;
67
68 codecContext->codec = avcodec_find_decoder(codecContext->codec_id);
69 if (codecContext->codec == NULL)
70 {
71 av_free(frame);
72 av_close_input_file(formatContext);
73 std::cout << "Couldn't find a proper decoder" << std::endl;
74 return 1;
75 }
76 else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0)
77 {
78 av_free(frame);
79 av_close_input_file(formatContext);
80 std::cout << "Couldn't open the context with the decoder" << std::endl;
81 return 1;
82 }
83
84 std::cout << "This stream has " << codecContext->channels << " channels and a sample rate of " << codecContext->sample_rate << "Hz" << std::endl;
85 std::cout << "The data is in the format " << av_get_sample_fmt_name(codecContext->sample_fmt) << std::endl;
86
87 //codecContext->sample_fmt = AV_SAMPLE_FMT_S16;
88
89 int64_t outChannelLayout = AV_CH_LAYOUT_MONO; //AV_CH_LAYOUT_STEREO;
90 AVSampleFormat outSampleFormat = AV_SAMPLE_FMT_S16; // Packed audio, non-planar (this is the most common format, and probably what you want; also, WAV needs it)
91 int outSampleRate = 8000;//44100;
92/*
93 Wav wav;
94 wav.sampleRate = outSampleRate;
95 wav.sampleSize = av_get_bytes_per_sample(outSampleFormat);
96 wav.channels = av_get_channel_layout_nb_channels(outChannelLayout);
97*/
98 // Note that AVCodecContext::channel_layout may or may not be set by libavcodec. Because of this,
99 // we won't use it, and will instead try to guess the layout from the number of channels.
100 SwrContext* swrContext = swr_alloc_set_opts(NULL,
101 outChannelLayout,
102 outSampleFormat,
103 outSampleRate,
104 av_get_default_channel_layout(codecContext->channels),
105 codecContext->sample_fmt,
106 codecContext->sample_rate,
107 0,
108 NULL);
109
110 if (swrContext == NULL)
111 {
112 av_free(frame);
113 avcodec_close(codecContext);
114 avformat_close_input(&formatContext);
115 std::cout << "Couldn't create the SwrContext" << std::endl;
116 return 1;
117 }
118
119 if (swr_init(swrContext) != 0)
120 {
121 av_free(frame);
122 avcodec_close(codecContext);
123 avformat_close_input(&formatContext);
124 swr_free(&swrContext);
125 std::cout << "Couldn't initialize the SwrContext" << std::endl;
126 return 1;
127 }
128
129 fout = fopen(outFile, "wb+");
130
131 AVPacket packet;
132 av_init_packet(&packet);
133
134 // Read the packets in a loop
135 while (av_read_frame(formatContext, &packet) == 0)
136 {
137 if (packet.stream_index == audioStream->index)
138 {
139 AVPacket decodingPacket = packet;
140
141 while (decodingPacket.size > 0)
142 {
143 // Try to decode the packet into a frame
144 int frameFinished = 0;
145 int result = avcodec_decode_audio4(codecContext, frame, &frameFinished, &decodingPacket);
146
147 if (result < 0 || frameFinished == 0)
148 {
149 break;
150 }
151
152 //std::vector<unsigned char> buffer(wav.channels * wav.sampleRate * wav.sampleSize);
153
154 unsigned char buffer[100000] = {NULL};
155 unsigned char* pointers[SWR_CH_MAX] = {NULL};
156 pointers[0] = &buffer[0];
157
158 int numSamplesOut = swr_convert(swrContext,
159 pointers,
160 outSampleRate, //wav.sampleRate,
161 (const unsigned char**)frame->extended_data,
162 //(const uint8_t**)frame->extended_data[0],
163 frame->nb_samples);
164
165 //processFrame(frame, swrContext, wav);
166
167 //fwrite( frame->data[0], sizeof(short), (size_t)(frame->nb_samples), fout);
168 //fwrite( frame->extended_data, sizeof(short), (size_t)(frame->nb_samples), fout);
169 //uint16_t uiCnt_1 = (uint16_t )frame->extended_data[0];
170 //uint16_t uiCnt_2 = (uint16_t )frame->extended_data[1];
171
172 /*
173 ReSampleContext *rs_ctx = NULL;
174 // resample to 44100, stereo, s16
175 rs_ctx = av_audio_resample_init(
176 1, codecContext->channels,
177 8000, codecContext->sample_rate,
178 AV_SAMPLE_FMT_S16, codecContext->sample_fmt,
179 16, 10, 0, 1);
180
181 //outbuff = (uint8_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
182 short bufferSh[100000] = {NULL};
183 // resampling
184 //int after_sampled_len = audio_resample(rs_ctx, (short *)buffer, (short *)frame->extended_data[0], frame->nb_samples);
185 int after_sampled_len = audio_resample(rs_ctx, bufferSh, (short *)frame->extended_data, frame->nb_samples);
186 */
187
188 fwrite( (short *)buffer, sizeof(short), (size_t)numSamplesOut, fout);
189
190 decodingPacket.size -= result;
191 decodingPacket.data += result;
192 }
193
194 /*
195 // Try to decode the packet into a frame
196 int frameFinished = 0;
197 avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
198
199 // Some frames rely on multiple packets, so we have to make sure the frame is finished before
200 // we can use it
201 if (frameFinished)
202 {
203
204 //fwrite( (short *)&(frame->data[0]), sizeof(short), (size_t)(frame->nb_samples*2), fout);
205 fwrite( (short *)&(frame->data[0]), sizeof(short), (size_t)(frame->nb_samples*2), fout);
206
207 // frame now has usable audio data in it. How it's stored in the frame depends on the format of
208 // the audio. If it's packed audio, all the data will be in frame->data[0]. If it's in planar format,
209 // the data will be in frame->data and possibly frame->extended_data. Look at frame->data, frame->nb_samples,
210 // frame->linesize, and other related fields on the FFmpeg docs. I don't know how you're actually using
211 // the audio data, so I won't add any junk here that might confuse you. Typically, if I want to find
212 // documentation on an FFmpeg structure or function, I just type "<name> doxygen" into google (like
213 // "AVFrame doxygen" for AVFrame's docs)
214 }
215 */
216 }
217
218 // You *must* call av_free_packet() after each call to av_read_frame() or else you'll leak memory
219 av_free_packet(&packet);
220 }
221
222 // Some codecs will cause frames to be buffered up in the decoding process. If the CODEC_CAP_DELAY flag
223 // is set, there can be buffered up frames that need to be flushed, so we'll do that
224 if (codecContext->codec->capabilities & CODEC_CAP_DELAY)
225 {
226 av_init_packet(&packet);
227 // Decode all the remaining frames in the buffer, until the end is reached
228 int frameFinished = 0;
229 while (avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet) >= 0 && frameFinished)
230 {
231 }
232 }
233
234 // Clean up!
235 av_free(frame);
236 avcodec_close(codecContext);
237 av_close_input_file(formatContext);
238 fclose(fout);
239}
240
241