2016-12-29 3 views
0

私は2つのGSSFフィルタを使用しています.1つはBGRAフレームを送信するもので、もう1つはPCMの16ビット48KHzオーディオサンプルをDirectShowグラフに送ります。音声のために何千回も呼び出されたGSSFコールバック

画像フィルタのコールバックは、29.97fpsで作業しているため、30ms以上離れた適切な頻度で呼び出されます。 しかし、音声の場合、グラフが開始されると音声コールバックは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); 

ほとんどGSSFの例と同じであるので、私は完全なコードを投稿していません。しかし、私はあなたが必要と感じるものは何でも投稿できます。

誰もが、なぜこれが起こっているのか考えていますか?

は、私はこの上で動作を停止しましたが、私は、私は再びそれを試してみると考えていたと私は「問題」を見つけ、あなたに

+0

サウンドデザインのような動作。必ずしも間違っているとは限りません。 –

+0

@ RomanR.設計上の行動はどういう意味ですか?これは何度も呼ばれるのは普通でしょうか?私は何とかこれを絞ることができませんか? – tweellt

+0

圧縮されたオーディオフレームの長さは20-30msで、デコーダは40-50秒のコールバックを生成します。しかし、ビデオとは異なり、特定のコールバックの頻度はありません。サンプルは何らかの理由で、音声の滑らかさと品質を損なうことなく48,000コールバックを1秒間に48kHzのオーディオに再グループ化します。あなたが5000回の電話を受けるということだけで何かが間違っていたというわけではありません。 –

答えて

0

ありがとうございます。他の誰かがこの問題を抱えているなら、ここに行く...

事はRomanRが言ったように、私は要求を絞るべきだが、私はオーディオのいくつかの要求を追加するので何が起こっているのか理解できなかった。ビデオはほとんどありません。

私は掘り起こして、犯人を見つけました。 Mpeg Layer IIでオーディオをエンコードしていたので、このparicularコーデックは、1920サンプルを配信する場合でも、一度にチャネルあたり1152サンプルを要求します。だから私はサンプルを正しい方法で供給していませんでした。 私は適切な数のサンプルを配信し、それに応じてタイムを取るサンプルマネージャを作成しました。

関連する問題