在Windows XP上安裝VMware6.5,下載最新的Ubuntu 9.10桌面版安裝到虛擬機上。系統安裝完成后,設置網絡,從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
}
或者點擊此處下載源碼文件。
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

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

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!