在Windows XP上安裝VMware6.5,下載最新的Ubuntu 9.10桌面版安裝到虛擬機上。系統(tǒng)安裝完成后,設置網絡,從http://ffmpeg.org上下載最新的源碼版本,以root身份解壓到根目錄上,得到目錄ffmpeg-0.5,運行以下命令:
#cd ffmpeg-0.5
#./configure --prefix=/usr --enable-shared --disable-static --enable-memalign-hack
#make
#make install
#make distclean(可選)
完成編譯和安裝后,開始編碼,代碼如下:
編譯程序,運行命令:
#gcc ffmpeg_player.c -o ffmpeg_player -lavcodec -lavformat -lavutil
或者
#gcc -DOUTPUT_INFORMATS ffmpeg_player.c -o ffmpeg_player -lavcodec -lavformat -lavutil
編譯完成后,運行如下命令即可播放音樂文件了
#./ffmpeg_player /music/1.ape
ENJOY!
#cd ffmpeg-0.5
#./configure --prefix=/usr --enable-shared --disable-static --enable-memalign-hack
#make
#make install
#make distclean(可選)
完成編譯和安裝后,開始編碼,代碼如下:
1
#include <unistd.h>
2
#include <fcntl.h>
3
#include <sys/types.h>
4
#include <sys/ioctl.h>
5
#include <linux/soundcard.h>
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <libavcodec/avcodec.h>
9
#include <libavformat/avformat.h>
10
#include <libavutil/mem.h>
11
12
#define BLOCK_SIZE 4608
13
14
typedef struct AudioState
15
{
16
AVFormatContext* pFmtCtx;
17
AVCodecContext* pCodecCtx;
18
AVCodec* pCodec;
19
20
#ifdef OUTPUT_INFORMATS
21
AVInputFormat* ifmt;
22
#endif
23
24
uint8_t* audio_buf1;
25
uint8_t* audio_buf;
26
unsigned int audio_buf_size;
27
unsigned int buffer_size;
28
int audio_buf_index;
29
AVPacket audio_pkt_temp;
30
AVPacket audio_pkt;
31
uint8_t* audio_pkt_data;
32
int audio_pkt_size;
33
int stream_index;
34
} AudioState;
35
36
int audio_decode_frame(AudioState* pState);
37
int read_buffer(AudioState* pState, void* buffer, int buf_size);
38
39
int main(int argc, char* argv[])
40
{
41
int err = 0;
42
int handle = 0;
43
int i = 0;
44
int status = 0;
45
int args = 0;
46
int index = 0;
47
int sample_rate = 0, bits_per_sample = 0, channels = 0;
48
int done = 0;
49
char buffer[BLOCK_SIZE] = {0};
50
AudioState state;
51
int buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
52
53
if(argc == 1)
54
{
55
printf("%s <filename>\n", argv[0]);
56
return 0;
57
}
58
59
// register all codecs.
60
av_register_all();
61
memset(&state, 0, sizeof(AudioState));
62
state.audio_buf1= (uint8_t*)av_mallocz(buffer_size);
63
state.buffer_size = buffer_size;
64
65
#ifdef OUTPUT_INFORMATS
66
state.ifmt = av_iformat_next(NULL);
67
for( ; ; )
68
{
69
if(!state.ifmt)
70
break;
71
72
printf("%s [%s] [%s]\n", state.ifmt->name, state.ifmt->long_name,
73
state.ifmt->extensions);
74
state.ifmt = av_iformat_next(state.ifmt);
75
}
76
#endif
77
78
err = av_open_input_file(&state.pFmtCtx, argv[1], NULL, 0, NULL);
79
if(err < 0)
80
{
81
printf("can not open file %s.\n", argv[1]);
82
return 0;
83
}
84
85
err = av_find_stream_info(state.pFmtCtx);
86
if(err < 0)
87
{
88
printf("can not find stream info of file %s.\n", argv[1]);
89
return 0;
90
}
91
92
for(i = 0; i < state.pFmtCtx->nb_streams; i++)
93
{
94
if(state.pFmtCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
95
{
96
state.pCodecCtx = state.pFmtCtx->streams[i]->codec;
97
index = i;
98
state.stream_index = i;
99
break;
100
}
101
}
102
103
if(!state.pCodecCtx)
104
{
105
printf("can not get codec context.\n");
106
av_close_input_file(state.pFmtCtx);
107
108
return 0;
109
}
110
111
state.pCodec = avcodec_find_decoder(state.pCodecCtx->codec_id);
112
if(!state.pCodec || avcodec_open(state.pCodecCtx, state.pCodec) < 0)
113
{
114
printf("can not open codec.\n");
115
av_close_input_file(state.pFmtCtx);
116
117
return 0;
118
}
119
120
sample_rate = state.pCodecCtx->sample_rate;
121
channels = state.pCodecCtx->channels;
122
switch(state.pCodecCtx->sample_fmt)
123
{
124
case SAMPLE_FMT_U8:
125
bits_per_sample = 8;
126
break;
127
case SAMPLE_FMT_S16:
128
bits_per_sample = 16;
129
break;
130
case SAMPLE_FMT_S32:
131
bits_per_sample = 32;
132
break;
133
default:
134
bits_per_sample = 16;
135
}
136
137
printf("sample_rate: %d Hz\n", sample_rate);
138
printf("channels: %d\n", channels);
139
printf("bits_per_sample: %d bit\n", bits_per_sample);
140
141
handle = open("/dev/dsp", O_RDWR);
142
if(handle < 0)
143
{
144
printf("can not open /dev/dsp.\n");
145
return 0;
146
}
147
148
args = sample_rate;
149
status = ioctl(handle, SOUND_PCM_WRITE_RATE, &args);
150
if(status == -1)
151
{
152
printf("SOUND_PCM_WRITE_RATE ioctl failed.\n");
153
return 0;
154
}
155
156
args = channels;
157
status = ioctl(handle, SOUND_PCM_WRITE_CHANNELS, &args);
158
if(status == -1)
159
{
160
printf("SOUND_PCM_WRITE_CHANNELS ioctl failed.\n");
161
return 0;
162
}
163
164
args = bits_per_sample;
165
status = ioctl(handle, SOUND_PCM_WRITE_BITS, &args);
166
if(status == -1)
167
{
168
printf("SOUND_PCM_WRITE_BITS ioctl failed.\n");
169
return 0;
170
}
171
172
for( ; ; )
173
{
174
int len = BLOCK_SIZE;
175
int size = 0;
176
char* pbuffer = buffer;
177
if(done)
178
break;
179
180
size = read_buffer(&state, buffer, len);
181
if(size == -1)
182
{
183
done = 1;
184
continue;
185
}
186
187
// printf("size=%d\n", size);
188
write(handle, buffer, size);
189
}
190
191
avcodec_close(state.pCodecCtx);
192
av_close_input_file(state.pFmtCtx);
193
av_free(state.audio_buf1);
194
close(handle);
195
return 0;
196
}
197
198
int audio_decode_frame(AudioState* pState)
199
{
200
AVPacket* pkt_temp = &pState->audio_pkt_temp;
201
AVPacket* pkt = &pState->audio_pkt;
202
AVCodecContext* dec = pState->pCodecCtx;
203
int len = 0, data_size = 0;
204
int err = 0;
205
206
for( ; ; )
207
{
208
while(pkt_temp->size > 0)
209
{
210
data_size = pState->buffer_size;
211
len = avcodec_decode_audio2(dec, (int16_t*)pState->audio_buf1, &data_size, pkt_temp->data, pkt_temp->size);
212
if(len < 0)
213
{
214
pkt_temp->size = 0;
215
break;
216
}
217
218
pkt_temp->data += len;
219
pkt_temp->size -= len;
220
221
if(data_size <= 0)
222
continue;
223
224
pState->audio_buf = pState->audio_buf1;
225
return data_size;
226
}
227
228
if(pkt->data)
229
av_free_packet(pkt);
230
231
if((err = av_read_frame(pState->pFmtCtx, pkt)) < 0)
232
return -1;
233
234
pkt_temp->data = pkt->data;
235
pkt_temp->size = pkt->size;
236
}
237
238
return -1;
239
}
240
241
int read_buffer(AudioState* pState, void* buffer, int buf_size)
242
{
243
int len = buf_size;
244
uint8_t* pbuffer = (uint8_t*)buffer;
245
int audio_size = 0;
246
int len1 = 0;
247
int size = 0;
248
249
while(len > 0)
250
{
251
if(pState->audio_buf_index >= pState->audio_buf_size)
252
{
253
audio_size = audio_decode_frame(pState);
254
if(audio_size < 0)
255
return (size > 0) ? size : -1;
256
257
pState->audio_buf_size = audio_size;
258
pState->audio_buf_index = 0;
259
}
260
261
len1 = pState->audio_buf_size - pState->audio_buf_index;
262
if(len1 > len)
263
len1 = len;
264
265
memcpy(pbuffer, (uint8_t*)pState->audio_buf + pState->audio_buf_index, len1);
266
267
len -= len1;
268
pbuffer += len1;
269
size += len1;
270
pState->audio_buf_index += len1;
271
}
272
273
return size;
274
}
或者點擊此處下載源碼文件。
#include <unistd.h>2
#include <fcntl.h>3
#include <sys/types.h>4
#include <sys/ioctl.h>5
#include <linux/soundcard.h>6
#include <stdio.h>7
#include <stdlib.h>8
#include <libavcodec/avcodec.h>9
#include <libavformat/avformat.h>10
#include <libavutil/mem.h>11

12
#define BLOCK_SIZE 460813

14
typedef struct AudioState15
{16
AVFormatContext* pFmtCtx;17
AVCodecContext* pCodecCtx;18
AVCodec* pCodec;19

20
#ifdef OUTPUT_INFORMATS21
AVInputFormat* ifmt;22
#endif23

24
uint8_t* audio_buf1;25
uint8_t* audio_buf;26
unsigned int audio_buf_size;27
unsigned int buffer_size;28
int audio_buf_index;29
AVPacket audio_pkt_temp;30
AVPacket audio_pkt;31
uint8_t* audio_pkt_data;32
int audio_pkt_size;33
int stream_index;34
} AudioState;35

36
int audio_decode_frame(AudioState* pState);37
int read_buffer(AudioState* pState, void* buffer, int buf_size);38

39
int main(int argc, char* argv[])40
{41
int err = 0;42
int handle = 0;43
int i = 0;44
int status = 0;45
int args = 0;46
int index = 0;47
int sample_rate = 0, bits_per_sample = 0, channels = 0;48
int done = 0;49
char buffer[BLOCK_SIZE] = {0};50
AudioState state;51
int buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;52
53
if(argc == 1)54
{55
printf("%s <filename>\n", argv[0]);56
return 0;57
}58

59
// register all codecs.60
av_register_all();61
memset(&state, 0, sizeof(AudioState));62
state.audio_buf1= (uint8_t*)av_mallocz(buffer_size);63
state.buffer_size = buffer_size;64

65
#ifdef OUTPUT_INFORMATS66
state.ifmt = av_iformat_next(NULL);67
for( ; ; )68
{69
if(!state.ifmt)70
break;71

72
printf("%s [%s] [%s]\n", state.ifmt->name, state.ifmt->long_name,73
state.ifmt->extensions);74
state.ifmt = av_iformat_next(state.ifmt);75
}76
#endif77

78
err = av_open_input_file(&state.pFmtCtx, argv[1], NULL, 0, NULL);79
if(err < 0)80
{81
printf("can not open file %s.\n", argv[1]);82
return 0;83
}84

85
err = av_find_stream_info(state.pFmtCtx);86
if(err < 0)87
{88
printf("can not find stream info of file %s.\n", argv[1]);89
return 0;90
}91

92
for(i = 0; i < state.pFmtCtx->nb_streams; i++)93
{94
if(state.pFmtCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)95
{96
state.pCodecCtx = state.pFmtCtx->streams[i]->codec;97
index = i;98
state.stream_index = i;99
break;100
}101
}102

103
if(!state.pCodecCtx)104
{105
printf("can not get codec context.\n");106
av_close_input_file(state.pFmtCtx);107

108
return 0;109
}110

111
state.pCodec = avcodec_find_decoder(state.pCodecCtx->codec_id);112
if(!state.pCodec || avcodec_open(state.pCodecCtx, state.pCodec) < 0)113
{114
printf("can not open codec.\n");115
av_close_input_file(state.pFmtCtx);116

117
return 0;118
}119

120
sample_rate = state.pCodecCtx->sample_rate;121
channels = state.pCodecCtx->channels;122
switch(state.pCodecCtx->sample_fmt)123
{124
case SAMPLE_FMT_U8:125
bits_per_sample = 8;126
break;127
case SAMPLE_FMT_S16:128
bits_per_sample = 16;129
break;130
case SAMPLE_FMT_S32:131
bits_per_sample = 32;132
break;133
default:134
bits_per_sample = 16;135
}136

137
printf("sample_rate: %d Hz\n", sample_rate);138
printf("channels: %d\n", channels);139
printf("bits_per_sample: %d bit\n", bits_per_sample);140

141
handle = open("/dev/dsp", O_RDWR);142
if(handle < 0)143
{144
printf("can not open /dev/dsp.\n");145
return 0;146
}147

148
args = sample_rate;149
status = ioctl(handle, SOUND_PCM_WRITE_RATE, &args);150
if(status == -1)151
{152
printf("SOUND_PCM_WRITE_RATE ioctl failed.\n");153
return 0;154
}155

156
args = channels;157
status = ioctl(handle, SOUND_PCM_WRITE_CHANNELS, &args);158
if(status == -1)159
{160
printf("SOUND_PCM_WRITE_CHANNELS ioctl failed.\n");161
return 0;162
}163

164
args = bits_per_sample;165
status = ioctl(handle, SOUND_PCM_WRITE_BITS, &args);166
if(status == -1)167
{168
printf("SOUND_PCM_WRITE_BITS ioctl failed.\n");169
return 0;170
}171

172
for( ; ; )173
{174
int len = BLOCK_SIZE;175
int size = 0;176
char* pbuffer = buffer;177
if(done)178
break;179

180
size = read_buffer(&state, buffer, len);181
if(size == -1)182
{183
done = 1;184
continue;185
}186

187
// printf("size=%d\n", size);188
write(handle, buffer, size);189
}190

191
avcodec_close(state.pCodecCtx);192
av_close_input_file(state.pFmtCtx);193
av_free(state.audio_buf1);194
close(handle);195
return 0;196
}197

198
int audio_decode_frame(AudioState* pState)199
{200
AVPacket* pkt_temp = &pState->audio_pkt_temp;201
AVPacket* pkt = &pState->audio_pkt;202
AVCodecContext* dec = pState->pCodecCtx;203
int len = 0, data_size = 0;204
int err = 0;205

206
for( ; ; )207
{208
while(pkt_temp->size > 0)209
{210
data_size = pState->buffer_size;211
len = avcodec_decode_audio2(dec, (int16_t*)pState->audio_buf1, &data_size, pkt_temp->data, pkt_temp->size);212
if(len < 0)213
{214
pkt_temp->size = 0;215
break;216
}217

218
pkt_temp->data += len;219
pkt_temp->size -= len;220

221
if(data_size <= 0)222
continue;223

224
pState->audio_buf = pState->audio_buf1;225
return data_size;226
}227

228
if(pkt->data)229
av_free_packet(pkt);230

231
if((err = av_read_frame(pState->pFmtCtx, pkt)) < 0)232
return -1;233

234
pkt_temp->data = pkt->data;235
pkt_temp->size = pkt->size;236
}237

238
return -1;239
}240

241
int read_buffer(AudioState* pState, void* buffer, int buf_size)242
{243
int len = buf_size;244
uint8_t* pbuffer = (uint8_t*)buffer;245
int audio_size = 0;246
int len1 = 0;247
int size = 0;248

249
while(len > 0)250
{251
if(pState->audio_buf_index >= pState->audio_buf_size)252
{253
audio_size = audio_decode_frame(pState);254
if(audio_size < 0)255
return (size > 0) ? size : -1;256

257
pState->audio_buf_size = audio_size;258
pState->audio_buf_index = 0;259
}260

261
len1 = pState->audio_buf_size - pState->audio_buf_index;262
if(len1 > len)263
len1 = len;264

265
memcpy(pbuffer, (uint8_t*)pState->audio_buf + pState->audio_buf_index, len1);266

267
len -= len1;268
pbuffer += len1;269
size += len1;270
pState->audio_buf_index += len1;271
}272

273
return size;274
}編譯程序,運行命令:
#gcc ffmpeg_player.c -o ffmpeg_player -lavcodec -lavformat -lavutil
或者
#gcc -DOUTPUT_INFORMATS ffmpeg_player.c -o ffmpeg_player -lavcodec -lavformat -lavutil
編譯完成后,運行如下命令即可播放音樂文件了
#./ffmpeg_player /music/1.ape
ENJOY!




