此代碼在vs2008下編譯,基于最新的ffmpeg版本(svn下載),搭建MSYS+MinGW編譯環(huán)境編譯,如何搭建,在google上能搜索到。 源碼可在此下載。
但除了aac和ogg格式播放出錯,其余格式正常,不知為何,有ffmpeg開發(fā)經(jīng)驗的朋友請給予幫助,謝謝。代碼貼于下方。
但除了aac和ogg格式播放出錯,其余格式正常,不知為何,有ffmpeg開發(fā)經(jīng)驗的朋友請給予幫助,謝謝。代碼貼于下方。
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <windows.h>
4
#include <mmsystem.h>
5
6
#pragma comment(lib, "winmm.lib")
7
8
#ifdef __cplusplus
9
extern "C" {
10
#endif
11
12
#include "./include/avcodec.h"
13
#include "./include/avformat.h"
14
#include "./include/avutil.h"
15
#include "./include/mem.h"
16
17
#ifdef __cplusplus
18
}
19
#endif
20
21
#define BLOCK_SIZE 4608
22
#define BLOCK_COUNT 20
23
24
HWAVEOUT hWaveOut = NULL;
25
26
static void CALLBACK waveOutProc(HWAVEOUT, UINT, DWORD, DWORD, DWORD);
27
static WAVEHDR* allocateBlocks(int size, int count);
28
static void freeBlocks(WAVEHDR* blockArray);
29
static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size);
30
31
static CRITICAL_SECTION waveCriticalSection;
32
static WAVEHDR* waveBlocks;
33
static volatile unsigned int waveFreeBlockCount;
34
static int waveCurrentBlock;
35
36
typedef struct AudioState {
37
AVFormatContext* pFmtCtx;
38
AVCodecContext* pCodecCtx;
39
AVCodec* pCodec;
40
uint8_t audio_buf1[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
41
uint8_t* audio_buf;
42
unsigned int audio_buf_size;
43
int audio_buf_index;
44
AVPacket audio_pkt_temp;
45
AVPacket audio_pkt;
46
uint8_t* audio_pkt_data;
47
int audio_pkt_size;
48
int stream_index;
49
} AudioState;
50
51
int audio_decode_frame(AudioState* pState) {
52
53
AVPacket* pkt_temp = &pState->audio_pkt_temp;
54
AVPacket* pkt = &pState->audio_pkt;
55
AVCodecContext* dec= pState->pCodecCtx;
56
int len = 0, data_size = sizeof(pState->audio_buf1);
57
int err = 0;
58
59
for( ; ; ) {
60
while (pkt_temp->size > 0) {
61
data_size = sizeof(pState->audio_buf1);
62
len = avcodec_decode_audio3(dec, (int16_t*)pState->audio_buf1, &data_size, pkt_temp);
63
if (len < 0) {
64
pkt_temp->size = 0;
65
break;
66
}
67
68
pkt_temp->data += len;
69
pkt_temp->size -= len;
70
71
if (data_size <= 0)
72
continue;
73
74
pState->audio_buf = pState->audio_buf1;
75
return data_size;
76
}
77
78
if (pkt->data)
79
av_free_packet(pkt);
80
81
if((err = av_read_frame(pState->pFmtCtx, pkt)) < 0)
82
return -1;
83
84
pkt_temp->data = pkt->data;
85
pkt_temp->size = pkt->size;
86
}
87
88
return -1;
89
}
90
91
int main(int argc, char* argv[]) {
92
int err = 0;
93
AudioState audio_state = {0};
94
unsigned int i = 0;
95
unsigned int ready = 0;
96
97
OPENFILENAME ofn = {0};
98
char filename[MAX_PATH];
99
WAVEFORMATEX wfx = {0};
100
uint8_t buffer[BLOCK_SIZE];
101
uint8_t* pbuffer = buffer;
102
AVInputFormat* iformat = NULL;
103
104
int audio_size = 0, data_size = 0;
105
int len = 0, len1 = 0, eof = 0, size = 0;
106
107
memset(&ofn, 0, sizeof(OPENFILENAME));
108
ofn.lStructSize = sizeof(ofn);
109
ofn.hwndOwner = GetDesktopWindow();
110
ofn.lpstrFile = filename;
111
ofn.lpstrFile[0] = '\0';
112
ofn.nMaxFile = sizeof(filename) / sizeof(filename[0]);
113
ofn.lpstrFilter = _TEXT("All support files\0*.aac;*.ape;*.flac;*.mp3;*.mp4;*.mpc;*.ogg;*.tta;*.wma;*.wav\0");
114
ofn.nFilterIndex = 1;
115
ofn.lpstrFileTitle = NULL;
116
ofn.nMaxFileTitle = 0;
117
ofn.lpstrInitialDir = NULL;
118
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
119
120
if (GetOpenFileName(&ofn) == FALSE)
121
return 0;
122
123
av_register_all();
124
125
err = av_open_input_file(&audio_state.pFmtCtx, filename, NULL, 0, NULL);
126
if(err < 0) {
127
printf("can not open file %s.\n", filename);
128
return -1;
129
}
130
131
err = av_find_stream_info(audio_state.pFmtCtx);
132
if(err < 0) {
133
printf("can not find stream info of file %s.\n", filename);
134
return -1;
135
}
136
137
for(i = 0; i < audio_state.pFmtCtx->nb_streams; i++) {
138
if(audio_state.pFmtCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
139
audio_state.pCodecCtx = audio_state.pFmtCtx->streams[i]->codec;
140
audio_state.stream_index = i;
141
ready = 1;
142
break;
143
}
144
}
145
146
if(!ready)
147
return -1;
148
149
audio_state.pCodec = avcodec_find_decoder(audio_state.pCodecCtx->codec_id);
150
if(!audio_state.pCodec || avcodec_open(audio_state.pCodecCtx, audio_state.pCodec) < 0)
151
return -1;
152
153
wfx.nSamplesPerSec = audio_state.pCodecCtx->sample_rate;
154
switch(audio_state.pCodecCtx->sample_fmt)
155
{
156
case SAMPLE_FMT_U8:
157
wfx.wBitsPerSample = 8;
158
break;
159
case SAMPLE_FMT_S16:
160
wfx.wBitsPerSample = 16;
161
break;
162
case SAMPLE_FMT_S32:
163
wfx.wBitsPerSample = 32;
164
break;
165
case SAMPLE_FMT_FLT:
166
wfx.wBitsPerSample = sizeof(double) * 8;
167
break;
168
default:
169
wfx.wBitsPerSample = 0;
170
break;
171
}
172
173
wfx.nChannels = FFMIN(2, audio_state.pCodecCtx->channels);
174
wfx.cbSize = 0;
175
wfx.wFormatTag = WAVE_FORMAT_PCM;
176
wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
177
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
178
179
waveBlocks = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
180
waveFreeBlockCount = BLOCK_COUNT;
181
waveCurrentBlock = 0;
182
183
InitializeCriticalSection(&waveCriticalSection);
184
185
// open wave out device
186
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (DWORD_PTR)waveOutProc,
187
(DWORD_PTR)&waveFreeBlockCount, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
188
fprintf(stderr, "%s: unable to open wave mapper device\n", argv[0]);
189
ExitProcess(1);
190
}
191
192
// play loop
193
for( ; ; ) {
194
195
len = BLOCK_SIZE;
196
size = 0;
197
pbuffer = buffer;
198
199
if(eof)
200
break;
201
202
while(len > 0) {
203
if(audio_state.audio_buf_index >= (int)audio_state.audio_buf_size) {
204
audio_size = audio_decode_frame(&audio_state);
205
if(audio_size < 0) {
206
if(size > 0)
207
break;
208
209
eof = 1;
210
break;
211
}
212
213
audio_state.audio_buf_size = audio_size;
214
audio_state.audio_buf_index = 0;
215
}
216
217
len1 = audio_state.audio_buf_size - audio_state.audio_buf_index;
218
if(len1 > len)
219
len1 = len;
220
221
memcpy(pbuffer, (uint8_t *)audio_state.audio_buf + audio_state.audio_buf_index, len1);
222
223
len -= len1;
224
pbuffer += len1;
225
size += len1;
226
audio_state.audio_buf_index += len1;
227
}
228
229
writeAudio(hWaveOut, (char*)buffer, size);
230
}
231
232
// wait for complete
233
for( ; ; ) {
234
if(waveFreeBlockCount >= BLOCK_COUNT)
235
break;
236
237
Sleep(10);
238
}
239
240
for(i = 0; i < waveFreeBlockCount; i++)
241
if(waveBlocks[i].dwFlags & WHDR_PREPARED)
242
waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));
243
244
DeleteCriticalSection(&waveCriticalSection);
245
freeBlocks(waveBlocks);
246
waveOutClose(hWaveOut);
247
248
avcodec_close(audio_state.pCodecCtx);
249
250
system("pause");
251
return 0;
252
}
253
254
static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size)
255
{
256
WAVEHDR* current;
257
int remain;
258
259
current = &waveBlocks[waveCurrentBlock];
260
261
while(size > 0) {
262
/*
263
* first make sure the header we're going to use is unprepared
264
*/
265
if(current->dwFlags & WHDR_PREPARED)
266
waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
267
268
if(size < (int)(BLOCK_SIZE - current->dwUser)) {
269
memcpy(current->lpData + current->dwUser, data, size);
270
current->dwUser += size;
271
break;
272
}
273
274
remain = BLOCK_SIZE - current->dwUser;
275
memcpy(current->lpData + current->dwUser, data, remain);
276
size -= remain;
277
data += remain;
278
current->dwBufferLength = BLOCK_SIZE;
279
280
waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
281
waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
282
283
EnterCriticalSection(&waveCriticalSection);
284
waveFreeBlockCount--;
285
LeaveCriticalSection(&waveCriticalSection);
286
287
/*
288
* wait for a block to become free
289
*/
290
while(!waveFreeBlockCount)
291
Sleep(10);
292
293
/*
294
* point to the next block
295
*/
296
waveCurrentBlock++;
297
waveCurrentBlock %= BLOCK_COUNT;
298
299
current = &waveBlocks[waveCurrentBlock];
300
current->dwUser = 0;
301
}
302
}
303
304
static WAVEHDR* allocateBlocks(int size, int count)
305
{
306
char* buffer;
307
int i;
308
WAVEHDR* blocks;
309
DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
310
311
/*
312
* allocate memory for the entire set in one go
313
*/
314
if((buffer = (char*)HeapAlloc(
315
GetProcessHeap(),
316
HEAP_ZERO_MEMORY,
317
totalBufferSize
318
)) == NULL) {
319
fprintf(stderr, "Memory allocation error\n");
320
ExitProcess(1);
321
}
322
323
/*
324
* and set up the pointers to each bit
325
*/
326
blocks = (WAVEHDR*)buffer;
327
buffer += sizeof(WAVEHDR) * count;
328
for(i = 0; i < count; i++) {
329
blocks[i].dwBufferLength = size;
330
blocks[i].lpData = buffer;
331
buffer += size;
332
}
333
334
return blocks;
335
}
336
337
static void freeBlocks(WAVEHDR* blockArray)
338
{
339
/*
340
* and this is why allocateBlocks works the way it does
341
*/
342
HeapFree(GetProcessHeap(), 0, blockArray);
343
}
344
345
static void CALLBACK waveOutProc(
346
HWAVEOUT hWaveOut,
347
UINT uMsg,
348
DWORD dwInstance,
349
DWORD dwParam1,
350
DWORD dwParam2
351
)
352
{
353
int* freeBlockCounter = (int*)dwInstance;
354
/*
355
* ignore calls that occur due to opening and closing the
356
* device.
357
*/
358
if(uMsg != WOM_DONE)
359
return;
360
361
EnterCriticalSection(&waveCriticalSection);
362
(*freeBlockCounter)++;
363
LeaveCriticalSection(&waveCriticalSection);
364
}

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

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364
