C++ffmpeg编码的音频失真



我制作了一个解复用器/复用器程序,它将视频作为输入,获取音频和视频,然后对红色信息进行编码。到目前为止,视频运行良好,但音频有问题。我可以在背景中听到输入的原始音频,但前面有失真的静态声音。我正在设置从解复用器得到的AVFrame和编码器中关于AVCodecContext的一些信息。剩下的是一些类似于ffmpegs复用示例的内容

以下是我迄今为止所做的:

int video_encoder::write_audio_frame(AVFormatContext *oc, OutputStream *ost)
{
AVCodecContext *c;
AVFrame *frame;
int ret;
int dst_nb_samples;
c = ost->enc;
#if __AUDIO_ENABLED
c->bit_rate = input_sample_fmt.bit_rate;
c->sample_rate = input_sample_fmt.sample_rate;
c->time_base = input_sample_fmt.time_base;
c->sample_fmt =  input_sample_fmt.sample_fmt;
c->channel_layout =  input_sample_fmt.channel_layout;
//c-> =  input_sample_fmt.channel_layout
#endif
frame = get_audio_frame(ost);
if (frame) {
/* convert samples from native format to destination codec format, using the resampler */
/* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
c->sample_rate, c->sample_rate, AV_ROUND_UP);
//av_assert0(dst_nb_samples == frame->nb_samples);
/* when we pass a frame to the encoder, it may keep a reference to it
* internally;
* make sure we do not overwrite it here
*/
ret = av_frame_make_writable(ost->frame);
if (ret < 0)
exit(1);
/* convert to destination format */
ret = swr_convert(ost->swr_ctx,
ost->frame->data, dst_nb_samples,
(const uint8_t **)frame->data, frame->nb_samples);
if (ret < 0) {
fprintf(stderr, "Error while convertingn");
exit(1);
}
frame = ost->frame;
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
ost->samples_count += dst_nb_samples;
}

return write_frame(oc, c, ost->st, frame, ost->tmp_pkt);
}

void video_encoder::set_audio_frame(AVFrame* audio, AVCodecContext* c_ctx)
{
audio_data = *audio;
input_sample_fmt = *c_ctx;
//std::cout << audio-> << std::endl;
}
AVFrame* video_encoder::get_audio_frame(OutputStream *ost)
{
AVFrame *frame = &audio_data;
int j, i, v;
int16_t *q = (int16_t*)frame->data[0];

//(int16_t)*audio_frame->data[0];
/* check if we want to generate more frames */
if (av_compare_ts(ost->next_pts, ost->enc->time_base,
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
return NULL;
for (j = 0; j <frame->nb_samples; j++) {
#if !__AUDIO_ENABLED
v = (int)(sin(ost->t) * 10000);
#endif
for (i = 0; i < ost->enc->channels; i++)
#if !__AUDIO_ENABLED
*q++ = v;
#endif
ost->t     += ost->tincr;
ost->tincr += ost->tincr2;
}
frame->pts = ost->next_pts;
ost->next_pts  += frame->nb_samples;
#if __AUDIO_ENABLED        
return frame;
#else
return frame;
#endif
}

您应该匹配输入和输出采样率。

您的输出缓冲区是根据您的输出音频规格分配的。

然而,由于它们与您的输入音频规范不同;要么是下溢,无法以与输入兼容的方式填充缓冲区,要么是溢出。

后一种可能性不大,因为你提到你听到的音频是失真的。

最新更新