音频---把采集的PCM音频数据填充到AVFrame中

1.AVFrame结构体中部分音频参数说明

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
    uint8_t *data[AV_NUM_DATA_POINTERS]; //指向音频数据的指针数组

    int linesize[AV_NUM_DATA_POINTERS]; //每一个音频通道的行大小,即每行的字节数

    int nb_samples; //样本数量

    /**
     * format of the frame, -1 if unknown or unset
     * Values correspond to enum AVPixelFormat for video frames,
     * enum AVSampleFormat for audio)
     */
    int format; //样本格式

    int64_t pts;

    int64_t pkt_dts;

    AVRational time_base; 

    int sample_rate; //采样率

    AVBufferRef *buf[AV_NUM_DATA_POINTERS];

    AVChannelLayout ch_layout; //音频通道数

    int64_t duration;
} AVFrame;

2.和实际录音时音频属性的对应关系

  • 假设有个mic录音设备,它的参数:1.双声道录音设备。2.每秒钟可以采集44100次数据。3.每次的数据需要用1个字节保存,为planar格式。
    创建一个AVFrame来保存这个mic录1s的音频数据,设置如下:
//计算时间戳
int64_t timestamp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
auto pts = av_rescale_q(timestamp, {1, 44100}, {1, 1000});

AVFrame frame;
frame.sample_rate = 44100;
frame.time_base = AVRational{1, 44100};

//此参数根据实际传入的样本数量设置
frame.nb_samples = 44100;

//这里使用系统时间(根据自己的需要设置),注意转换时间基。
frame.pts = pts;
frame.duration = av_rescale(frame.nb_samples / frame.sample_rate, frame.time_base.den, frame.time_base.num);

//按照通道数,设置ch_layout
av_channel_layout_default(&frame.ch_layout, 2);

frame.format = AV_SAMPLE_FMT_U8P; //unsigned 8 bits panlar平面格式

//分配了linesize,data(这个data是用AVBuffer管理的)
//0表示按默认方式做字节对齐,在ffmpeg6.1中为32。这里计算出来的linesize为44128
//手动计算:44100 / 32 = 1378,余4,所以一个声道需要的大小为 (1378 + 1) * 32 = 44128
av_frame_get_buffer(mframe, 0);
frame.data[0] = memcpy(第1个声道的平面数据);
frame.data[1] = memcpy(第2个声道的平面数据);

#if 0  //列出平面格式
frame.format = AV_SAMPLE_FMT_U8; //unsigned 8 bits packet交错格式

//分配了linesize,data(这个data是用AVBuffer管理的)
//0表示按默认方式做字节对齐,在ffmpeg6.1中为32。这里计算出来的linesize为88256
av_frame_get_buffer(mframe, 0);
frame.data[0] = 2个声道交错的数据;
#endif 

posted on 2024-07-02 16:51  林西索  阅读(11)  评论(0编辑  收藏  举报