Rust binding https://github.com/larksuite/rsmpeg of ffmpeg.
I try to fill AVFrame
with samples as below.
<code>let bgm_samples : AVSamples = ...;
assert_eq!(bgm_samples.nb_channels, 1);
assert_eq!(bgm_samples.sample_fmt, AV_SAMPLE_FMT_FLTP);
let mut frame = AVFrame::new();
frame.set_nb_samples(bgm_samples.nb_samples);
frame.set_ch_layout(AVChannelLayout::from_nb_channels(1).into_inner());
frame.set_format(bgm_samples.sample_fmt);
frame.set_sample_rate(22050);
frame
.alloc_buffer()
.context("Could not allocate frame buffer")?;
let raw_ptr = frame.into_raw();
unsafe {
let err = ffi::avcodec_fill_audio_frame(
raw_ptr.as_ptr(),
1,
bgm_samples.sample_fmt,
bgm_samples.audio_data[0].as_mut().unwrap(),
bgm_samples.nb_samples
* ffi::av_get_bytes_per_sample(bgm_samples.sample_fmt),
0,
);
if err < 0 {
bail!("avcodec_fill_audio_frame failed with {}", err);
}
}
let frame = unsafe { AVFrame::from_raw(raw_ptr) };
</code>
<code>let bgm_samples : AVSamples = ...;
assert_eq!(bgm_samples.nb_channels, 1);
assert_eq!(bgm_samples.sample_fmt, AV_SAMPLE_FMT_FLTP);
let mut frame = AVFrame::new();
frame.set_nb_samples(bgm_samples.nb_samples);
frame.set_ch_layout(AVChannelLayout::from_nb_channels(1).into_inner());
frame.set_format(bgm_samples.sample_fmt);
frame.set_sample_rate(22050);
frame
.alloc_buffer()
.context("Could not allocate frame buffer")?;
let raw_ptr = frame.into_raw();
unsafe {
let err = ffi::avcodec_fill_audio_frame(
raw_ptr.as_ptr(),
1,
bgm_samples.sample_fmt,
bgm_samples.audio_data[0].as_mut().unwrap(),
bgm_samples.nb_samples
* ffi::av_get_bytes_per_sample(bgm_samples.sample_fmt),
0,
);
if err < 0 {
bail!("avcodec_fill_audio_frame failed with {}", err);
}
}
let frame = unsafe { AVFrame::from_raw(raw_ptr) };
</code>
let bgm_samples : AVSamples = ...;
assert_eq!(bgm_samples.nb_channels, 1);
assert_eq!(bgm_samples.sample_fmt, AV_SAMPLE_FMT_FLTP);
let mut frame = AVFrame::new();
frame.set_nb_samples(bgm_samples.nb_samples);
frame.set_ch_layout(AVChannelLayout::from_nb_channels(1).into_inner());
frame.set_format(bgm_samples.sample_fmt);
frame.set_sample_rate(22050);
frame
.alloc_buffer()
.context("Could not allocate frame buffer")?;
let raw_ptr = frame.into_raw();
unsafe {
let err = ffi::avcodec_fill_audio_frame(
raw_ptr.as_ptr(),
1,
bgm_samples.sample_fmt,
bgm_samples.audio_data[0].as_mut().unwrap(),
bgm_samples.nb_samples
* ffi::av_get_bytes_per_sample(bgm_samples.sample_fmt),
0,
);
if err < 0 {
bail!("avcodec_fill_audio_frame failed with {}", err);
}
}
let frame = unsafe { AVFrame::from_raw(raw_ptr) };
The frame from above code would cause an error in encoder:
[aac @ 0000021A08201AC0] Input contains (near) NaN/+-Inf
If I change the above code as below, to copy samples into an AVAudioFifo
and then read samples from AVAudioFifo
into AVFrame
, it works! It means the bgm_samples
contains valid samples. But somehow avcodec_fill_audio_frame
does not copy the samples correctly.
Can someone help? thanks in advance.
<code>let mut fifo: AVAudioFifo = AVAudioFifo::new(
bgm_samples.sample_fmt,
1,
bgm_samples.nb_samples,
);
unsafe {
fifo.write(bgm_samples.audio_data.as_ptr(), bgm_samples.nb_samples)?;
}
// create frame from samples
let mut frame = AVFrame::new();
frame.set_nb_samples(bgm_samples.nb_samples);
frame.set_ch_layout(AVChannelLayout::from_nb_channels(1).into_inner());
frame.set_format(bgm_samples.sample_fmt);
frame.set_sample_rate(22050);
frame
.alloc_buffer()
.context("Could not allocate frame buffer")?;
if unsafe { fifo.read(frame.data_mut().as_mut_ptr(), bgm_samples.nb_samples)? }
< bgm_samples.nb_samples
{
bail!("Could not read data from FIFO");
}
</code>
<code>let mut fifo: AVAudioFifo = AVAudioFifo::new(
bgm_samples.sample_fmt,
1,
bgm_samples.nb_samples,
);
unsafe {
fifo.write(bgm_samples.audio_data.as_ptr(), bgm_samples.nb_samples)?;
}
// create frame from samples
let mut frame = AVFrame::new();
frame.set_nb_samples(bgm_samples.nb_samples);
frame.set_ch_layout(AVChannelLayout::from_nb_channels(1).into_inner());
frame.set_format(bgm_samples.sample_fmt);
frame.set_sample_rate(22050);
frame
.alloc_buffer()
.context("Could not allocate frame buffer")?;
if unsafe { fifo.read(frame.data_mut().as_mut_ptr(), bgm_samples.nb_samples)? }
< bgm_samples.nb_samples
{
bail!("Could not read data from FIFO");
}
</code>
let mut fifo: AVAudioFifo = AVAudioFifo::new(
bgm_samples.sample_fmt,
1,
bgm_samples.nb_samples,
);
unsafe {
fifo.write(bgm_samples.audio_data.as_ptr(), bgm_samples.nb_samples)?;
}
// create frame from samples
let mut frame = AVFrame::new();
frame.set_nb_samples(bgm_samples.nb_samples);
frame.set_ch_layout(AVChannelLayout::from_nb_channels(1).into_inner());
frame.set_format(bgm_samples.sample_fmt);
frame.set_sample_rate(22050);
frame
.alloc_buffer()
.context("Could not allocate frame buffer")?;
if unsafe { fifo.read(frame.data_mut().as_mut_ptr(), bgm_samples.nb_samples)? }
< bgm_samples.nb_samples
{
bail!("Could not read data from FIFO");
}