JACKY_ZZ[猫猫爱吃鱼]

春风拂面两颊红,秋叶洒地一片金。 夏荷摇曳一身轻,冬雪覆盖大地银。
posts - 30, comments - 123, trackbacks - 0, articles - 0

[C/C++] ffmpeg小试

Posted on 2009-11-24 17:44 jacky_zz 阅读(4904) 评论(13)  编辑 收藏 引用 所属分类: C/C++
此代码在vs2008下编译,基于最新的ffmpeg版本(svn下载),搭建MSYS+MinGW编译环境编译,如何搭建,在google上能搜索到。 源码可在此下载
但除了aac和ogg格式播放出错,其余格式正常,不知为何,有ffmpeg开发经验的朋友请给予帮助,谢谢。代码贴于下方。
  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
  9extern "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
 24HWAVEOUT hWaveOut = NULL;
 25
 26static void CALLBACK waveOutProc(HWAVEOUT, UINT, DWORD, DWORD, DWORD);
 27static WAVEHDR* allocateBlocks(int size, int count);
 28static void freeBlocks(WAVEHDR* blockArray);
 29static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size);
 30
 31static CRITICAL_SECTION waveCriticalSection;
 32static WAVEHDR*         waveBlocks;
 33static volatile unsigned int     waveFreeBlockCount;
 34static int              waveCurrentBlock;
 35
 36typedef 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
 51int 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
 91int 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, 0sizeof(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
254static 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
304static 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
337static 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
345static 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}

Feedback

# re: ffmpeg小试  回复  更多评论   

2009-11-24 17:47 by cexer
最近开始研究 ffmpeg,关注一下博主。

# re: ffmpeg小试[未登录]  回复  更多评论   

2009-11-24 20:05 by Bill Hsu
FFmpeg有个耻辱名单,LZ听所过吗(⊙_⊙)?

# re: ffmpeg小试  回复  更多评论   

2009-11-24 21:02 by jacky_zz
和我的程序有关系吗?况且我的这个程序附带了源码,虽然简单。

# re: ffmpeg小试  回复  更多评论   

2009-11-24 21:19 by 毛毛
不错,收藏,学习

# re: ffmpeg小试  回复  更多评论   

2009-11-25 11:03 by jacky_zz
找到不能播放aac和ogg的问题了,原因是在ffmpeg里分配内存需要用av_malloc,释放内存要用av_free,因为windows和linux下内存分配存在不同,而ffmpeg在解码的时候是要检查内存是否对齐(内存对齐可以加快CPU的处理速度),所以在程序里在window环境下通过malloc或者通过数组的方式分配的内存不完全是内存对齐的,所以在遇到aac和ogg这种帧长度与其它音频格式帧长度不一致时,就有可能在运行时出错。修改后的代码如下,读者参照着自己修改即可。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <mmsystem.h>

#pragma comment(lib, "winmm.lib")

#ifdef __cplusplus
extern "C" {
#endif

#include "./include/avcodec.h"
#include "./include/avformat.h"
#include "./include/avutil.h"
#include "./include/mem.h"

#ifdef __cplusplus
}
#endif

#define BLOCK_SIZE 4608
#define BLOCK_COUNT 20

HWAVEOUT hWaveOut = NULL;

static void CALLBACK waveOutProc(HWAVEOUT, UINT, DWORD, DWORD, DWORD);
static WAVEHDR* allocateBlocks(int size, int count);
static void freeBlocks(WAVEHDR* blockArray);
static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size);

static CRITICAL_SECTION waveCriticalSection;
static WAVEHDR* waveBlocks;
static volatile unsigned int waveFreeBlockCount;
static int waveCurrentBlock;

typedef struct AudioState {
AVFormatContext* pFmtCtx;
AVCodecContext* pCodecCtx;
AVCodec* pCodec;
//uint8_t* audio_buf1[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
uint8_t* audio_buf1;
uint8_t* audio_buf;
unsigned int audio_buf_size; /* in bytes */
unsigned int buffer_size;
int audio_buf_index; /* in bytes */
AVPacket audio_pkt_temp;
AVPacket audio_pkt;
uint8_t* audio_pkt_data;
int audio_pkt_size;

int stream_index;
} AudioState;

int audio_decode_frame(AudioState* pState) {

AVPacket* pkt_temp = &pState->audio_pkt_temp;
AVPacket* pkt = &pState->audio_pkt;
AVCodecContext* dec= pState->pCodecCtx;
int len = 0, data_size = sizeof(pState->audio_buf1);
int err = 0;

for( ; ; ) {
while (pkt_temp->size > 0) {
// data_size = sizeof(pState->audio_buf1);
data_size = pState->buffer_size;
len = avcodec_decode_audio3(dec, (int16_t*)pState->audio_buf1, &data_size, pkt_temp);
if (len < 0) {
pkt_temp->size = 0;
break;
}

pkt_temp->data += len;
pkt_temp->size -= len;

if (data_size <= 0)
continue;

pState->audio_buf = pState->audio_buf1;
return data_size;
}

if (pkt->data)
av_free_packet(pkt);

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

pkt_temp->data = pkt->data;
pkt_temp->size = pkt->size;
}

return -1;
}

int main(int argc, char* argv[]) {
int err = 0;
AudioState audio_state = {0};
unsigned int i = 0;
unsigned int ready = 0;

OPENFILENAME ofn = {0};
char filename[MAX_PATH];
WAVEFORMATEX wfx = {0};
uint8_t buffer[BLOCK_SIZE];
uint8_t* pbuffer = buffer;
AVInputFormat* iformat = NULL;

int audio_size = 0, data_size = 0;
int len = 0, len1 = 0, eof = 0, size = 0;

memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = GetDesktopWindow();
ofn.lpstrFile = filename;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(filename) / sizeof(filename[0]);
ofn.lpstrFilter = _TEXT("All support files\0*.aac;*.ape;*.flac;*.mp3;*.mp4;*.mpc;*.ogg;*.tta;*.wma;*.wav\0");
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

if (GetOpenFileName(&ofn) == FALSE)
return 0;

av_register_all();

err = av_open_input_file(&audio_state.pFmtCtx, filename, NULL, 0, NULL);
if(err < 0) {
printf("can not open file %s.\n", filename);
return -1;
}

err = av_find_stream_info(audio_state.pFmtCtx);
if(err < 0) {
printf("can not find stream info of file %s.\n", filename);
return -1;
}

for(i = 0; i < audio_state.pFmtCtx->nb_streams; i++) {
if(audio_state.pFmtCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
audio_state.pCodecCtx = audio_state.pFmtCtx->streams[i]->codec;
audio_state.stream_index = i;
ready = 1;
break;
}
}

if(!ready)
return -1;

audio_state.pCodec = avcodec_find_decoder(audio_state.pCodecCtx->codec_id);
if(!audio_state.pCodec || avcodec_open(audio_state.pCodecCtx, audio_state.pCodec) < 0)
return -1;

wfx.nSamplesPerSec = audio_state.pCodecCtx->sample_rate;
switch(audio_state.pCodecCtx->sample_fmt)
{
case SAMPLE_FMT_U8:
wfx.wBitsPerSample = 8;
break;
case SAMPLE_FMT_S16:
wfx.wBitsPerSample = 16;
break;
case SAMPLE_FMT_S32:
wfx.wBitsPerSample = 32;
break;
case SAMPLE_FMT_FLT:
wfx.wBitsPerSample = sizeof(double) * 8;
break;
default:
wfx.wBitsPerSample = 0;
break;
}

wfx.nChannels = FFMIN(2, audio_state.pCodecCtx->channels);
wfx.cbSize = 0;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;

waveBlocks = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
waveFreeBlockCount = BLOCK_COUNT;
waveCurrentBlock = 0;

InitializeCriticalSection(&waveCriticalSection);

// open wave out device
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (DWORD_PTR)waveOutProc,
(DWORD_PTR)&waveFreeBlockCount, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
fprintf(stderr, "%s: unable to open wave mapper device\n", argv[0]);
ExitProcess(1);
}

// allocate memory
audio_state.audio_buf1 =(uint8_t*)av_malloc(buffer_size);
audio_state.buffer_size = buffer_size;

// play loop
for( ; ; ) {

len = BLOCK_SIZE;
size = 0;
pbuffer = buffer;

if(eof)
break;

while(len > 0) {
if(audio_state.audio_buf_index >= (int)audio_state.audio_buf_size) {
audio_size = audio_decode_frame(&audio_state);
if(audio_size < 0) {
if(size > 0)
break;

eof = 1;
break;
}

audio_state.audio_buf_size = audio_size;
audio_state.audio_buf_index = 0;
}

len1 = audio_state.audio_buf_size - audio_state.audio_buf_index;
if(len1 > len)
len1 = len;

memcpy(pbuffer, (uint8_t *)audio_state.audio_buf + audio_state.audio_buf_index, len1);

len -= len1;
pbuffer += len1;
size += len1;
audio_state.audio_buf_index += len1;
}

writeAudio(hWaveOut, (char*)buffer, size);
}

// free allocated memory
av_free(audio_state.audio_buf1);
audio_state.audio_buf1 = NULL;

// wait for complete
for( ; ; ) {
if(waveFreeBlockCount >= BLOCK_COUNT)
break;

Sleep(10);
}

for(i = 0; i < waveFreeBlockCount; i++)
if(waveBlocks[i].dwFlags & WHDR_PREPARED)
waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));

DeleteCriticalSection(&waveCriticalSection);
freeBlocks(waveBlocks);
waveOutClose(hWaveOut);

avcodec_close(audio_state.pCodecCtx);

system("pause");
return 0;
}

static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size)
{
WAVEHDR* current;
int remain;

current = &waveBlocks[waveCurrentBlock];

while(size > 0) {
/*
* first make sure the header we're going to use is unprepared
*/
if(current->dwFlags & WHDR_PREPARED)
waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));

if(size < (int)(BLOCK_SIZE - current->dwUser)) {
memcpy(current->lpData + current->dwUser, data, size);
current->dwUser += size;
break;
}

remain = BLOCK_SIZE - current->dwUser;
memcpy(current->lpData + current->dwUser, data, remain);
size -= remain;
data += remain;
current->dwBufferLength = BLOCK_SIZE;

waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));

EnterCriticalSection(&waveCriticalSection);
waveFreeBlockCount--;
LeaveCriticalSection(&waveCriticalSection);

/*
* wait for a block to become free
*/
while(!waveFreeBlockCount)
Sleep(10);

/*
* point to the next block
*/
waveCurrentBlock++;
waveCurrentBlock %= BLOCK_COUNT;

current = &waveBlocks[waveCurrentBlock];
current->dwUser = 0;
}
}

static WAVEHDR* allocateBlocks(int size, int count)
{
char* buffer;
int i;
WAVEHDR* blocks;
DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;

/*
* allocate memory for the entire set in one go
*/
if((buffer = (char*)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
totalBufferSize
)) == NULL) {
fprintf(stderr, "Memory allocation error\n");
ExitProcess(1);
}

/*
* and set up the pointers to each bit
*/
blocks = (WAVEHDR*)buffer;
buffer += sizeof(WAVEHDR) * count;
for(i = 0; i < count; i++) {
blocks[i].dwBufferLength = size;
blocks[i].lpData = buffer;
buffer += size;
}

return blocks;
}

static void freeBlocks(WAVEHDR* blockArray)
{
/*
* and this is why allocateBlocks works the way it does
*/
HeapFree(GetProcessHeap(), 0, blockArray);
}

static void CALLBACK waveOutProc(
HWAVEOUT hWaveOut,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2
)
{
int* freeBlockCounter = (int*)dwInstance;
/*
* ignore calls that occur due to opening and closing the
* device.
*/
if(uMsg != WOM_DONE)
return;

EnterCriticalSection(&waveCriticalSection);
(*freeBlockCounter)++;
LeaveCriticalSection(&waveCriticalSection);
}

# re: ffmpeg小试  回复  更多评论   

2009-12-21 18:44 by TS,MPEG2,dvbc专家
你的下载包里面,没有.avcodec-52.dll 所以无法运行.

# re: ffmpeg小试  回复  更多评论   

2009-12-22 11:41 by seliu
当初我也做了一个MSYS+MinGW,想研究一下ffmpeg.发现MSYS本质不是应用于linux的,如果做windows开发,用ffmpeg sdk好像足够了。
偶没有时间做了,那位大虾搭建了cygwin+MinGW,希望共同研究一下ffmpeg在linux下特别时嵌入式下的应用。

# re: ffmpeg小试  回复  更多评论   

2011-06-17 00:13 by f4s
谢谢你的代码。问题已经解决了。

# re: ffmpeg小试  回复  更多评论   

2011-07-09 23:20 by ffish
感谢楼主的代码。把av_read_frame那两行改成下面这样,就可以直接播绝大部分视频文件了(声音部分)。

pkt->stream_index = -1;
while(pkt->stream_index != pState->stream_index) {
if((err = av_read_frame(pState->pFmtCtx, pkt)) < 0)
return -1;
}

# re: ffmpeg小试  回复  更多评论   

2011-12-13 17:44 by glueless lace wigs
暴风是不是你弄的

# re: ffmpeg小试[未登录]  回复  更多评论   

2011-12-26 15:34 by jacky_zz
@glueless lace wigs
不是,要是有那本事,就不玩了。

# re: ffmpeg小试[未登录]  回复  更多评论   

2012-01-25 01:57 by danny
谢谢jackzz,在我眼里你已经很牛了,刚刚在WinCE上用你的修正后代码测试了一下mp3、flac、ape、ogg、wma、wav,都播得很happy,不错不错。

# re: ffmpeg小试  回复  更多评论   

2013-01-05 21:45 by cheaterlin
我的QQ是475316440~麻烦加一下,关于解码,我有一些疑问~thanks~
简述就是avcodec_decode_audio3((AVCodecContext *avctx, int16_t *samples,int *frame_size_ptr,AVPacket *avpkt))解出一帧的数据,这写数据,不总是在samples的最前面顺序排列?

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理