亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

【金秋打卡】第21天 AAC 編碼器編碼

標簽:
Android

课程名称音视频基础+ffmpeg原理 入门音视频技术开发
课程章节:【实战】音频编码
课程讲师李超

课程内容

创建 AVFrame

查找编码器,分配上下文,设置上下文参数,打开编码器后。接下来就应该将数据输入编码器。

由于以下的原因,需要把 AVPacket 数据存进AVFrame当中。

  • ffmpeg 的 avformat_open_input() 是将多媒体文件打开。
  • avformat_open_input() 既可以打开文件,也可以打开设备。
  • avformat_open_input() 就是将所有的东西当做多媒体文件打开,所以通过 av_read_frame() 读出 AVPacket 数据,按道理说 AVPacket 存的是编码后的数据,可是这里存储的是PCM原始数据。
  • 编码器需要的是AVFrame原始数据。

创建 AVFrame 的关键代码:

AVFrame* create_frame(){
    AVFrame *frame = av_frame_alloc(); //其中的buffer才是存着主要的数据
    if(!frame){
        return NULL;
    }
    frame->nb_samples = 512; //这里每个包的大小是2048/位深32位(4个字节)/1个通道 所以就是2048/4/1=512
    frame->format = AV_SAMPLE_FMT_S16;//AAC需要的位深
    frame->channel_layout = AV_CH_LAYOUT_STEREO; //AAC需要的通道
    av_frame_get_buffer(frame, 0);
    if(!frame->data[0]){
        printf("Error, Failed to alloc buf in frame!\n");
        //内存泄漏
        goto __ERROR;
    }
    return frame;
__ERROR:
    if(frame){
        av_frame_free(&frame);
    }
    return NULL;
}

创建 AVFrame 主要用到了两个函数,av_frame_alloc() 和 av_frame_get_buffer(),实际上数据是存在AVFrame 中 buffer 当中,会根据设置的 frame 的采样大小(位深),通道个数,采样个数进行分配 buffer。

将 AVPacket 数据存进 AVFrame

1.创建缓存区

 av_samples_alloc_array_and_samples(&dst_data,
                                       &dst_linesize,
                                       2,
                                       512,
                                       AV_SAMPLE_FMT_S16,
                                       0);

2.将AVPacket中的数据放进缓存区

memcpy((void *)dst_data[0], (void *)pkt.data, pkt.size);

3.将缓存区的数据放进AVFrame

memcpy((void *)frame->data[0], (void*)dst_data[0], dst_linesize);

4.将frame数据送给编码器

ret = avcodec_send_frame(codec_ctx, frame);

5.接受编码后的数据AVPacket

ret = avcodec_receive_packet(codec_ctx, pkt);

由于 avcodec_send_frame() 传入要编码的数据不一定传入就会马上返回编码后的数据,而是编码好多数据后多次返回。所以获取编码后的数据需要用while循环来处理 avcodec_receive_packet()的状态。直到avcodec_receive_packet()的返回值 <= 0,说明当前没有要处理的数据了,可以接受下一个AVFrame数据进行处理了。

 while(ret > 0){
        ret = avcodec_receive_packet(codec_ctx, pkt);
        if(ret < 0 ){
            if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){
                break;
            }else{
                printf("error encodeing avframe");
                exit(-1);
            }
        }
        fwrite(pkt->data,pkt->size, 1, outFile);
        fflush(outFile);
        av_packet_unref(&pkt);
    }

6.读取到编码后的数据后写入文件

fwrite(pkt->data,pkt->size, 1, outFile);
fflush(outFile);

图片描述

图片描述

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
移動開發工程師
手記
粉絲
12
獲贊與收藏
17

關注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消