使用ffmpeg进行Wma解码

发布于 2024-10-08 13:51:57 字数 4909 浏览 9 评论 0原文

我是 ffmpeg 的新手,我尝试使用 api-example.c 来解码 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);



}

我已经被困在这个问题上很长一段时间了。请帮我。 有人知道我的代码有什么问题吗?

谢谢,

伊扎克

I am new to ffmpeg and I tried using api-example.c to decode wma files. However when I run the program, it gave me an error saying

"frame_len overflow". Does anyone know how to fix this error?

Here is my code:

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);



}

I have been stuck on this for quite a long time. Please help me.
anyone know whats wrong with my code?

Thanks,

Izak

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南冥有猫 2024-10-15 13:51:57

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

Use debug messages to determine the point of failure.
Though I am of the strong opinion that this error occurs while encoding, because you are using the same buffer and respective buffer size.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文