【问题标题】:FFmpeg audio encoder new encode functionFFmpeg 音频编码器新增编码功能
【发布时间】:2023-03-24 06:42:01
【问题描述】:

我想将一个使用avcodec_encode_audio (deprecated)功能的AV音频编码器更新为avcodec_encode_audio2,而不修改现有编码器的结构:

 outBytes = avcodec_encode_audio(m_handle, dst, sizeBytes, (const short int*)m_samBuf);

地点:

1) m_handle AVCodecContext

2) dst, uint8_t * 目标缓冲区

3) sizeBytes, uint32_t 目标缓冲区大小

4) m_samBuf void * 到要编码的输入数据块(这被转换为:const short int*)

有简单的方法吗?

我正在尝试:

int gotPack = 1;
memset (&m_Packet, 0, sizeof (m_Packet));
m_Frame = av_frame_alloc();

av_init_packet(&m_Packet);
m_Packet.data = dst;
m_Packet.size = sizeBytes;

uint8_t* buffer = (uint8_t*)m_samBuf;
m_Frame->nb_samples = m_handle->frame_size;

avcodec_fill_audio_frame(m_Frame,m_handle->channels,m_handle->sample_fmt,buffer,m_FrameSize,1);

outBytes = avcodec_encode_audio2(m_handle, &m_Packet, m_Frame, &gotPack);
char error[256];
av_strerror(outBytes,error,256);

if (outBytes<0){
    m_server->log(1,1,"Input data: %d, encode function call error: %s \n",gotPack, error);
    return AUDIOWRAPPER_ERROR;
}
av_frame_free(&m_Frame);

它可以编译,但它不编码任何东西,如果我在 mplayer 上通过管道传输输出流,我不会在输出端播放音频,这在升级之前一直在运行。

我做错了什么?

编码器只接受两种样本格式:

AV_SAMPLE_FMT_S16,         ///< signed 16 bits
AV_SAMPLE_FMT_FLT,         ///< float

这是缓冲区的分配方式:

free(m_samBuf);
int bps = 2;
if(m_handle->codec->sample_fmts[0] == AV_SAMPLE_FMT_FLT) {
    bps = 4;
}
m_FrameSize = bps * m_handle->frame_size * m_handle->channels;
m_samBuf = malloc(m_FrameSize);
m_numSam = 0;

【问题讨论】:

    标签: c++ ffmpeg libavcodec avcodec


    【解决方案1】:

    avcodec_fill_audio_frame 应该可以带您到那里

    memset (&m_Packet, 0, sizeof (m_Packet));
    memset (&m_Frame, 0, sizeof (m_Frame));
    
    av_init_packet(&m_Packet);
    
    m_Packet.data = dst;
    m_Packet.size = sizeBytes;
    
    m_Frame->nb_samples = //you need to get this value from somewhere, it is the number of samples (per channel) this frame represents
    avcodec_fill_audio_frame(m_Frame, m_handle->channels, m_handle->sample_fmt,
            buffer,
            sizeBytes, 1);
    
    
    int gotPack = 1;
    
    avcodec_encode_audio2(m_handle, &m_Packet, &m_Frame, &gotPack);
    

    【讨论】:

    • 您可能会遇到m_samBuf中的音频格式与输入格式不同的问题。 avcodec_encode_audio() 采用交错的 16 位整数音频,avcodec_encode_audio2() 采用任何格式的交错或平面音频,编码器选择您应该使用哪一个。您可能需要使用 libswresample 在交错的 16 位整数和编码器格式之间进行转换。
    • 谢谢你!我可以计算每个通道的样本,例如:m_Frame-&gt;nb_samples = m_handle-&gt;sample_rate / m_handle-&gt;channels; 或类似的吗?
    • 如何将样本转换为 avcodec_encode_audio2(),不可能这么复杂...
    • 我按照 user3770489 的建议更改了代码,现在它在 AVfunction 上崩溃了:AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type) { ... if (frame-&gt;side_data[i]-&gt;type == type) return frame-&gt;side_data[i]; } 很可能在询问 side_data[i] 任何建议时?
    • 边数据是什么?
    猜你喜欢
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多