[C/C++] ffmpeg_play on ubuntu 9.10

在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(可选)
完成编译和安装后,开始编码,代码如下:
  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, 0sizeof(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}
或者点击此处 下载源码文件。
编译程序,运行命令:
#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!

你可能感兴趣的:([C/C++] ffmpeg_play on ubuntu 9.10)