首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ffmpeg进行Wma解码

使用ffmpeg进行Wma解码
EN

Stack Overflow用户
提问于 2010-12-20 13:56:05
回答 1查看 3.2K关注 0票数 4

我是第一次接触ffmpeg,我尝试过使用api-example.c来解码wma文件。然而,当我运行这个程序时,它给了我一个错误:

"frame_len溢出“。有人知道如何修复这个错误吗?

下面是我的代码:

代码语言:javascript
复制
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);



}

我在这方面已经坚持了很长一段时间了。请帮帮我。有人知道我的代码出了什么问题吗?

谢谢,

伊扎克

EN

回答 1

Stack Overflow用户

发布于 2012-01-21 07:46:31

使用调试消息确定故障点。虽然我强烈认为这个错误是在编码时发生的,因为您使用的是相同的缓冲区和各自的缓冲区大小。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4487263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档