为音频调用 GSSF 回调数千次

GSSF callback called thousands of times for audio

我正在使用两个 GSSF 过滤器,一个用于发送 BGRA 帧,另一个用于将 PCM 16 位 48KHz 音频样本发送到 directshow 图。

图像过滤器回调以正确的频率调用,大约相隔 30 毫秒,因为我在 29.97fps 下工作。 但是对于音频,一旦图表开始,音频回调就会被调用超过 5000 次。

视频设置:

BitmapInfoHeader bmi = new BitmapInfoHeader();
bmi.Size = Marshal.SizeOf(typeof(BitmapInfoHeader));
bmi.Width = width; //1920
bmi.Height = height * -1; //1080
bmi.Planes = 1;
bmi.BitCount = (short)bpp; //32
bmi.Compression = 0;
bmi.ImageSize = (bmi.BitCount / 8) * bmi.Width * bmi.Height; //8294400
bmi.XPelsPerMeter = 0;
bmi.YPelsPerMeter = 0;
bmi.ClrUsed = 0;
bmi.ClrImportant = 0;

int hr = ssi.SetMediaTypeFromBitmap(bmi, (long)fps); // (long)(10000000 / 29.97)
DsError.ThrowExceptionForHR(hr);

音频设置

WaveFormatEx wfex = new WaveFormatEx();
wfex.wFormatTag = 1; //PCM
wfex.nSamplesPerSec = samplerate; //48000;
wfex.wBitsPerSample = (ushort)bps; //16
wfex.nChannels = (ushort)numChannels; //2
wfex.nAvgBytesPerSec = samplerate * (bps * numChannels / 8); //192000
wfex.nBlockAlign = (ushort)(numChannels * bps / 8); //4
wfex.cbSize = 0;

//Keep Data
bytesPerSample = wfex.nAvgBytesPerSec;
frequency = samplerate;
channels = numChannels;
bits = bps;

AMMediaType amt = new AMMediaType();
amt.majorType = MediaType.Audio;
amt.subType = MediaSubType.PCM;
amt.formatType = FormatType.WaveEx;
amt.temporalCompression = false;
amt.fixedSizeSamples = true;
amt.sampleSize = wfex.nBlockAlign;
amt.formatSize = Marshal.SizeOf(wfex);
amt.formatPtr = Marshal.AllocCoTaskMem(amt.formatSize);
Marshal.StructureToPtr(wfex, amt.formatPtr, false);

int hr = ssa.SetMediaTypeEx(amt, wfex.nAvgBytesPerSec);
DsError.ThrowExceptionForHR(hr);

Tools.FreeAMMediaType(amt);

我正在这样设置时间戳:

对于视频:

// fps is (long)(10000000/29.97)
DsLong rtStart = new DsLong(frameNumber * fps);
DsLong rtStop = new DsLong(rtStart + fps);
int hr = pSample.SetTime(rtStart, rtStop);
frameNumber++;

对于音频:

//size is the number os audio samples written in bytes
//bits = 16
//channles = 2
//frequency = 48000
//timeUnit = 10000000
// lastTime starts from 0
long sampleCount = size * 8 / bits / channels;
long frameLength = timeUnit * sampleCount / frequency;
DsLong rtStart = new DsLong(lastTime);
lastTime = rtStart + frameLength;
DsLong rtStop = new DsLong(lastTime);
int hr = pSample.SetTime(rtStart, rtStop);

我还没有 post 编辑完整的代码,因为它与 GSSF 的示例大部分相同。但我可以post任何你觉得有必要的东西。

有人知道为什么会这样吗?

谢谢

我已经停止了这方面的工作,但我想我可以再试一次,我找到了 "problem"。如果其他人遇到此问题,请继续...

问题是,就像 RomanR 所说的那样,我应该限制请求,但我不知道发生了什么,因为我添加了几个音频请求和很少的视频请求。

所以我一直在挖掘,找出了罪魁祸首。由于我在 Mpeg Layer II 中对音频进行编码,因此这个特定的编解码器一次请求每个通道 1152 个样本,即使你有 1920 个样本要传送。所以我没有以正确的方式喂食样品。 我创建了一个样本管理器,它提供正确数量的样本并相应地对它们进行计时。