zoukankan      html  css  js  c++  java
  • [ffmpeg]deocde audio(v3.3.2)

    /*
     * Copyright (c) 2001 Fabrice Bellard
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    
    /**
     * @file
     * audio decoding with libavcodec API example
     *
     * @example decode_audio.c
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <libavutil/frame.h>
    #include <libavutil/mem.h>
    
    #include <libavcodec/avcodec.h>
    
    #define AUDIO_INBUF_SIZE 20480
    #define AUDIO_REFILL_THRESH 4096
    
    int main(int argc, char **argv)
    {
      //定义输入输出文件名字
    const char *outfilename, *filename;
      //定义编码器和编码器上下文
    const AVCodec *codec; AVCodecContext *c= NULL; int len; FILE *f, *outfile; uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; AVPacket avpkt; AVFrame *decoded_frame = NULL; if (argc <= 2) { fprintf(stderr, "Usage: %s <input file> <output file> ", argv[0]); exit(0); } filename = argv[1]; outfilename = argv[2]; /* register all the codecs */ avcodec_register_all(); av_init_packet(&avpkt); /* find the MPEG audio decoder */ codec = avcodec_find_decoder(AV_CODEC_ID_MP2); if (!codec) { fprintf(stderr, "Codec not found "); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate audio codec context "); exit(1); } /* open it */ if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "Could not open codec "); exit(1); } f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "Could not open %s ", filename); exit(1); } 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 (avpkt.size > 0) { int i, ch; int got_frame = 0;
         //如果未定义解码帧,则申请一个用来存储解码后的数据
    if (!decoded_frame) { if (!(decoded_frame = av_frame_alloc())) { fprintf(stderr, "Could not allocate audio frame "); exit(1); } }      //解码失败,或者解码接受,解码到了文件EOF位置 len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); if (len < 0) { fprintf(stderr, "Error while decoding "); exit(1); } if (got_frame) { /* if a frame has been decoded, output it */ int data_size = av_get_bytes_per_sample(c->sample_fmt); if (data_size < 0) { /* This should not occur, checking just for paranoia */ fprintf(stderr, "Failed to calculate data size "); exit(1); }
           //将解码后的数据写入到文件中,按通道写入,data_size是一个音频sample的大小
    for (i=0; i<decoded_frame->nb_samples; i++) for (ch=0; ch<c->channels; ch++) fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile); } avpkt.size -= len; avpkt.data += len; avpkt.dts = avpkt.pts = AV_NOPTS_VALUE; 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. */ //将一个packet后剩余的内容移动到缓冲区的头部
           memmove(inbuf, avpkt.data, avpkt.size); avpkt.data
    = inbuf;
           //在移动后将文件中的内容继续拷贝到packet中以提供下次解码 len
    = fread(avpkt.data + avpkt.size, 1, AUDIO_INBUF_SIZE - avpkt.size, f); if (len > 0) avpkt.size += len; } } fclose(outfile); fclose(f); avcodec_free_context(&c); av_frame_free(&decoded_frame); return 0; }
    作者:长风 Email:844064492@qq.com QQ群:607717453 Git:https://github.com/zhaohu19910409Dz 开源项目:https://github.com/OriginMEK/MEK 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 感谢您的阅读。如果觉得有用的就请各位大神高抬贵手“推荐一下”吧!你的精神支持是博主强大的写作动力。 如果觉得我的博客有意思,欢迎点击首页左上角的“+加关注”按钮关注我!
  • 相关阅读:
    Leetcode Substring with Concatenation of All Words
    Leetcode Divide Two Integers
    Leetcode Edit Distance
    Leetcode Longest Palindromic Substring
    Leetcode Longest Substring Without Repeating Characters
    Leetcode 4Sum
    Leetcode 3Sum Closest
    Leetcode 3Sum
    Leetcode Candy
    Leetcode jump Game II
  • 原文地址:https://www.cnblogs.com/zhaohu/p/7221551.html
Copyright © 2011-2022 走看看