2010-12-20 116 views
4

我是ffmpeg的新手,我尝试使用api-example.c解码wma文件。但是,当我运行该程序,它给了我一个错误,说使用ffmpeg进行Wma解码

“frame_len溢出”。有谁知道如何解决这个错误?

这里是我的代码:

extern "C" { 
#include <avcodec.h> 
#include "../libavcodec/avcodec.h" 
#include <avformat.h> 
} 

#include <iostream> 
#include <assert.h> 
#include <windows.h> 
#include <mmsystem.h> 
#define INBUF_SIZE 4096 
#define AUDIO_INBUF_SIZE 20480 
#define AUDIO_REFILL_THRESH 4096 

int main(int argc, char *argv[]) { 
    avcodec_init(); 
    avcodec_register_all(); 
    //avdevice_register_all(); 
    av_register_all(); 

    AVCodec *codec; 
    AVCodecContext *c= NULL; 

    AVCodec *ocodec; 
    AVCodecContext *oc= NULL; 

    int out_size, len,out_size2; 
    FILE *f, *outfile; 
    uint8_t *outbuf; 
    uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; 

    AVPacket avpkt; 
    char* outfilename="test.wma"; 
    char* filename="Beethoven's.wma"; 
    AVFormatContext *pFormatCtx; 

    WAVEFORMATEX* wfx=new WAVEFORMATEX; 

    int ret; 
    ret=av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL); 

    if(ret!=0) 
    { 
     std::cout<<"cannot open file!"<<std::endl; 
     exit(1); 
    } 

    if(av_find_stream_info(pFormatCtx)<0) 
    { 
     std::cout<<"cannot find stream!"<<std::endl; 
     exit(1); 
    } 

    int audioStream; 
    AVCodecContext *pCodecCtx; 
    // Find the first video stream 
    audioStream=-1; 
    for(int i=0; i<pFormatCtx->nb_streams; i++) 
     if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) 
     { 
      audioStream=i; 
      break; 
     } 
    if(audioStream==-1) 
    { 
     std::cout<<"cannot find audio!"<<std::endl; 
    } 

    // Get a pointer to the codec context for the audio stream 
    pCodecCtx=pFormatCtx->streams[audioStream]->codec; 
    av_init_packet(&avpkt); 

    printf("Audio decoding\n"); 

    /* find the suitable audio decoder */ 
    codec = avcodec_find_decoder(pCodecCtx->codec_id); 

    if (!codec) { 
     fprintf(stderr, "codec not found\n"); 
     exit(1); 
    } 

    if(codec->capabilities & CODEC_CAP_TRUNCATED) 
     pCodecCtx->flags|=CODEC_FLAG_TRUNCATED; 

    //open the codec (for decoding) 
    int test = avcodec_open(pCodecCtx, codec); 
    if (test < 0) { 
     fprintf(stderr, "could not open codec\n"); 
     exit(1); 
    } 

    //find mp3 encoder 
    ocodec = avcodec_find_encoder(CODEC_ID_MP3); 
    if (!ocodec) { 
     fprintf(stderr, "codec not found\n"); 
     exit(1); 
    } 

    //allocate context 
    oc= avcodec_alloc_context(); 
    /* put sample parameters */ 
    oc->bit_rate = 64000; 
    oc->sample_rate = 44100; 
    oc->channels = 1; 
    /* open it */ 
    if (avcodec_open(oc, ocodec) < 0) { 
     fprintf(stderr, "could not open encoding codec\n"); 
     exit(1); 
    } 

    //buffer 
    outbuf = (uint8_t*)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); 

    //open inputfile 
    f = fopen(filename, "rb"); 
    if (!f) { 
     fprintf(stderr, "could not open %s\n", filename); 
     exit(1); 
    } 

    //open outputfile 
    outfile = fopen(outfilename, "wb"); 

    if (!outfile) { 
     av_free(c); 
     exit(1); 
    } 

    /* decode until eof */ 
    avpkt.data = inbuf; 
    avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); 

    //while there is still data 
    while (avpkt.size > 0) { 
     std::cout<<"decoding..."<<std::endl; 
     out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; 
     //decode 
     len = avcodec_decode_audio3(pCodecCtx, (short *)outbuf, &out_size, &avpkt); 

     if (len < 0) { 
      fprintf(stderr, "Error while decoding\n"); 
      exit(1); 
     } 

     if (out_size > 0) { 
      /* if a frame has been decoded, output it */ 
      std::cout<<"1 frame decoded!"<<std::endl; 
      out_size2 = avcodec_encode_audio(oc, outbuf, out_size, (short*)outbuf); 
      fwrite(outbuf, 1, out_size2, outfile); 
     } 

     //subtract data from whatever decode function returns 

     avpkt.size -= len; 

     avpkt.data += len; 

     if (avpkt.size < AUDIO_REFILL_THRESH) { 

      /* Refill the input buffer, to avoid trying to decode 

      * incomplete frames. Instead of this, one could also use 

      * a parser, or use a proper container format through 

      * libavformat. */ 

      memmove(inbuf, avpkt.data, avpkt.size); 

      avpkt.data = inbuf; 

      len = fread(avpkt.data + avpkt.size, 1, 

         AUDIO_INBUF_SIZE - avpkt.size, f); 

      if (len > 0) 

       avpkt.size += len; 

     } 



    } 

    fclose(outfile); 

    fclose(f); 

    free(outbuf); 

    avcodec_close(c); 

    av_free(c); 



} 

我一直停留在这个相当长的一段时间。请帮帮我。 任何人都知道我的代码有什么问题?

感谢,

Izak

+0

请使用适当的缩进和空白,以便它是可读的......你在哪里得到“frame_len溢出”? – ronag 2010-12-20 06:12:06

+0

当我运行程序时,它返回一个错误,说“frame_len溢出”。 – Izak 2010-12-20 06:28:44

+0

你主要想解码WMA还是学习使用ffmpeg?对于WMA,如果您在Windows上运行,那么ffmpeg有一个很好的选择。 – 2010-12-20 06:33:15

回答

0

使用调试消息,以确定故障点。 尽管我强烈认为编码时发生此错误,因为您使用的是相同的缓冲区和相应的缓冲区大小。