1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
bool Render_context::load_audio(string &filename){
//load audio into memory and create thumbnail
AVCodec *codec;
AVCodecContext *c= NULL;
int len;
FILE *f;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
AVFrame *decoded_frame = NULL;
av_init_packet(&avpkt);
// http://stackoverflow.com/questions/9799560/decode-audio-using-libavcodec-and-play-using-libao
/* find the mpeg audio decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
if (!codec) {
fprintf(stderr, "Codec not found\n");
return false;
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate audio codec context\n");
return false;
}
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
return false;
}
f = fopen(filename.c_str(), "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename.c_str());
return false;
}
/* decode until eof */
avpkt.data = inbuf;
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
while (avpkt.size > 0) {
int got_frame = 0;
if (!decoded_frame) {
if (!(decoded_frame = avcodec_alloc_frame())) {
printf("Could not allocate audio frame\n");
return false;
}
} else
avcodec_get_frame_defaults(decoded_frame);
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
if (len < 0) {
fprintf(stderr, "Error while decoding\n");
return false;
}
if (got_frame) {
/* if a frame has been decoded, output it */
int data_size = av_samples_get_buffer_size(NULL, c->channels,decoded_frame->nb_samples,c->sample_fmt, 1);
//fwrite(decoded_frame->data[0], 1, data_size, outfile);
//here is where we do something with the data
//is it best to buffer it or do do all processing within a loop like this?
}
avpkt.size -= len;
avpkt.data += len;
avpkt.dts =
avpkt.pts = AV_NOPTS_VALUE;
if (avpkt.size < AUDIO_REFILL_THRESH) {
/* Refill the input buffer, to avoid trying to decode
* incomplete frames. Instead of this, one could also use
* a parser, or use a proper container format through
* libavformat. */
memmove(inbuf, avpkt.data, avpkt.size);
avpkt.data = inbuf;
len = fread(avpkt.data + avpkt.size, 1,AUDIO_INBUF_SIZE - avpkt.size, f);
if (len > 0)
avpkt.size += len;
}
}
fclose(f);
avcodec_close(c);
av_free(c);
avcodec_free_frame(&decoded_frame);
return true;
}
|