• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            JACKY_ZZ[貓貓愛(ài)吃魚(yú)]

            春風(fēng)拂面兩頰紅,秋葉灑地一片金。 夏荷搖曳一身輕,冬雪覆蓋大地銀。
            posts - 30, comments - 123, trackbacks - 0, articles - 0

            [C/C++] ffmpeg小試

            Posted on 2009-11-24 17:44 jacky_zz 閱讀(4936) 評(píng)論(13)  編輯 收藏 引用 所屬分類(lèi): C/C++
            此代碼在vs2008下編譯,基于最新的ffmpeg版本(svn下載),搭建MSYS+MinGW編譯環(huán)境編譯,如何搭建,在google上能搜索到。 源碼可在此下載
            但除了aac和ogg格式播放出錯(cuò),其余格式正常,不知為何,有ffmpeg開(kāi)發(fā)經(jīng)驗(yàn)的朋友請(qǐ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
              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小試  回復(fù)  更多評(píng)論   

            2009-11-24 17:47 by cexer
            最近開(kāi)始研究 ffmpeg,關(guān)注一下博主。

            # re: ffmpeg小試[未登錄](méi)  回復(fù)  更多評(píng)論   

            2009-11-24 20:05 by Bill Hsu
            FFmpeg有個(gè)恥辱名單,LZ聽(tīng)所過(guò)嗎(⊙_⊙)?

            # re: ffmpeg小試  回復(fù)  更多評(píng)論   

            2009-11-24 21:02 by jacky_zz
            和我的程序有關(guān)系嗎?況且我的這個(gè)程序附帶了源碼,雖然簡(jiǎn)單。

            # re: ffmpeg小試  回復(fù)  更多評(píng)論   

            2009-11-24 21:19 by 毛毛
            不錯(cuò),收藏,學(xué)習(xí)

            # re: ffmpeg小試  回復(fù)  更多評(píng)論   

            2009-11-25 11:03 by jacky_zz
            找到不能播放aac和ogg的問(wèn)題了,原因是在ffmpeg里分配內(nèi)存需要用av_malloc,釋放內(nèi)存要用av_free,因?yàn)閣indows和linux下內(nèi)存分配存在不同,而ffmpeg在解碼的時(shí)候是要檢查內(nèi)存是否對(duì)齊(內(nèi)存對(duì)齊可以加快CPU的處理速度),所以在程序里在window環(huán)境下通過(guò)malloc或者通過(guò)數(shù)組的方式分配的內(nèi)存不完全是內(nèi)存對(duì)齊的,所以在遇到aac和ogg這種幀長(zhǎng)度與其它音頻格式幀長(zhǎng)度不一致時(shí),就有可能在運(yùn)行時(shí)出錯(cuò)。修改后的代碼如下,讀者參照著自己修改即可。

            #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小試  回復(fù)  更多評(píng)論   

            2009-12-21 18:44 by TS,MPEG2,dvbc專(zhuān)家
            你的下載包里面,沒(méi)有.avcodec-52.dll 所以無(wú)法運(yùn)行.

            # re: ffmpeg小試  回復(fù)  更多評(píng)論   

            2009-12-22 11:41 by seliu
            當(dāng)初我也做了一個(gè)MSYS+MinGW,想研究一下ffmpeg.發(fā)現(xiàn)MSYS本質(zhì)不是應(yīng)用于linux的,如果做windows開(kāi)發(fā),用ffmpeg sdk好像足夠了。
            偶沒(méi)有時(shí)間做了,那位大蝦搭建了cygwin+MinGW,希望共同研究一下ffmpeg在linux下特別時(shí)嵌入式下的應(yīng)用。

            # re: ffmpeg小試  回復(fù)  更多評(píng)論   

            2011-06-17 00:13 by f4s
            謝謝你的代碼。問(wèn)題已經(jīng)解決了。

            # re: ffmpeg小試  回復(fù)  更多評(píng)論   

            2011-07-09 23:20 by ffish
            感謝樓主的代碼。把a(bǔ)v_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小試  回復(fù)  更多評(píng)論   

            2011-12-13 17:44 by glueless lace wigs
            暴風(fēng)是不是你弄的

            # re: ffmpeg小試[未登錄](méi)  回復(fù)  更多評(píng)論   

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

            # re: ffmpeg小試[未登錄](méi)  回復(fù)  更多評(píng)論   

            2012-01-25 01:57 by danny
            謝謝jackzz,在我眼里你已經(jīng)很牛了,剛剛在WinCE上用你的修正后代碼測(cè)試了一下mp3、flac、ape、ogg、wma、wav,都播得很happy,不錯(cuò)不錯(cuò)。

            # re: ffmpeg小試  回復(fù)  更多評(píng)論   

            2013-01-05 21:45 by cheaterlin
            我的QQ是475316440~麻煩加一下,關(guān)于解碼,我有一些疑問(wèn)~thanks~
            簡(jiǎn)述就是avcodec_decode_audio3((AVCodecContext *avctx, int16_t *samples,int *frame_size_ptr,AVPacket *avpkt))解出一幀的數(shù)據(jù),這寫(xiě)數(shù)據(jù),不總是在samples的最前面順序排列?
            日本精品久久久中文字幕| 婷婷伊人久久大香线蕉AV| 2021国内久久精品| 精品久久久噜噜噜久久久| 久久亚洲2019中文字幕| 亚洲av日韩精品久久久久久a | 伊人色综合久久天天| 一本久久综合亚洲鲁鲁五月天| 久久超碰97人人做人人爱| 久久最新免费视频| 丁香五月网久久综合| 无码人妻久久一区二区三区蜜桃| 精品久久久久久成人AV| 少妇久久久久久被弄到高潮| 97久久香蕉国产线看观看| 国产69精品久久久久APP下载 | 久久久久九九精品影院| 久久亚洲私人国产精品| 亚洲欧美日韩精品久久亚洲区 | 蜜臀久久99精品久久久久久小说 | 久久久久久久免费视频| 伊人色综合久久| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 久久婷婷国产综合精品| 久久天天婷婷五月俺也去| 国产精品免费看久久久香蕉| 精品久久久久久无码专区不卡 | 国产成人久久久精品二区三区| 99蜜桃臀久久久欧美精品网站 | 国产午夜精品理论片久久影视 | 久久精品国产69国产精品亚洲| 亚洲日本va中文字幕久久| 青青热久久国产久精品 | 久久久久免费视频| 欧美精品一区二区精品久久| 激情伊人五月天久久综合| 国内精品久久久久影院薰衣草| 色欲综合久久躁天天躁| 免费精品久久久久久中文字幕| 99久久国产综合精品网成人影院| 99久久无码一区人妻a黑|