我使用isamplegrabber sampleCB回调来获取音频样本,我可以从imediasample获得缓冲区和缓冲区长度,我使用avcodec_fill_audio_frame(frame,ost-> enc-> channels,ost-> enc-> sample_fmt,( uint8_t *)buffer,length,0)来制作一个avframe,但是这个帧不会在我的mux文件中发出任何音频!我认为长度比frame_size小很多。 每个人都能帮帮我吗?或者如果可能的话给我一些例子。 谢谢
这是我的samplecb代码:
HRESULT AudioSampleGrabberCallBack::SampleCB(double Time, IMediaSample*pSample){
BYTE *pBuffer;
pSample->GetPointer(&pBuffer);
long BufferLen = pSample->GetActualDataLength();
muxer->PutAudioFrame(pBuffer,BufferLen);
}
这是samplegrabber pin media type:
AM_MEDIA_TYPE pmt2;
ZeroMemory(&pmt2, sizeof(AM_MEDIA_TYPE));
pmt2.majortype = MEDIATYPE_Audio;
pmt2.subtype = FOURCCMap(0x1602);
pmt2.formattype = FORMAT_WaveFormatEx;
hr = pSampleGrabber_audio->SetMediaType(&pmt2);
之后我使用ffmpeg muxing示例来处理帧,我想我只需要更改信号生成部分代码:
AVFrame *Muxing::get_audio_frame(OutputStream *ost,BYTE* buffer,long length)
{
AVFrame *frame = ost->tmp_frame;
int j, i, v;
uint16_t *q = (uint16_t*)frame->data[0];
int buffer_size = av_samples_get_buffer_size(NULL, ost->enc->channels,
ost->enc->frame_size,
ost->enc->sample_fmt, 0);
// uint8_t *sample = (uint8_t *) av_malloc(buffer_size);
av_samples_alloc(&frame->data[0], frame->linesize, ost->enc->channels, ost->enc->frame_size, ost->enc->sample_fmt, 1);
avcodec_fill_audio_frame(frame, ost->enc->channels, ost->enc->sample_fmt,frame->data[0], buffer_size, 1);
frame->pts = ost->next_pts;
ost->next_pts += frame->nb_samples;
return frame;
}
答案 0 :(得分:1)
代码片段建议您使用Sample Grabber获取AAC数据,并且您正尝试使用FFmpeg的libavformat将其写入文件。这可以解决。
您初始化样本抓取器以获取WAVE_FORMAT_AAC_LATM
格式的音频数据。这种格式不是那么广泛,您有兴趣查看过滤器图表,以确保Sample Grabber上的上游连接符合您的预期。有可能在某种程度上有一个奇怪的过滤器链假装产生AAC-LATM,现实是数据无效(或甚至没有达到抓取器回调)。因此,您需要查看过滤器图表(请参阅Loading a Graph From an External Process和Understanding Your DirectShow Filter Graph),然后使用调试器逐步调试回调,以确保获取数据并且有意义。
接下来,您需要初始化AVFormatContext
,AVStream
以表明您将以AAC LATM格式编写数据。提供的代码并未显示您正在正确执行。 sample you are referring to正在使用默认编解码器。
然后,您需要确保传入数据和FFmpeg输出设置是否同意数据是否具有ADTS标头,提供的代码不会对此有所了解。
此外,我担心您可能会错误地准备音频数据。相关示例生成原始音频数据并应用编码器以使用avcodec_encode_audio2
生成压缩内容。然后使用av_interleaved_write_frame
将压缩音频打包发送到写入。你将代码片段附加到问题的方式让我觉得你做错了。对于初学者,您仍然没有显示相关代码,这使我认为您无法确定哪些代码完全相关。然后,您正在处理您的AAC数据,就好像它是get_audio_frame
代码段中的原始PCM音频,而您有兴趣查看FFmpeg示例代码时考虑到您已经有压缩的AAC数据并且样本到达了点从avcodec_encode_audio2
电话回来后。这是您应该合并代码和示例的地方。