Hi all,
I am writing a AVStream base PCI driver. I use avshws and avssamp as my sample.
There is an audio pin in my driver. The audio out format is ADPCM.
I use graphedit to test my driver. If the connection is as in following:
audio pin –> Decoder –> Directsound render
(ouotput adpcm) (output PCM)
My problem is as in following:
Sometimes, the audio packet size is larger than the buffer of audio pin. For example, the audio pin packet size from PCI bus is 240 or 120 bytes. But the buffer size of audio pin is only 120 bytes.
So,the audio packet may need to separate into 2 small packets,and every pakcket transfer 120 bytes to the decoder filter.
Unfortunately, if I divide one packet into 2 packets, the audio data become incorrect. In other words, the decompressed audio data sounds abnormally.
I wonder the problem is in the time stamp of audio packets.
The time stamp of audio packet is calculated as following:
When the driver get a audio packet with 240 bytes, the audio process rountine will separate the packet into 2 packets.
Suppose the presentation time of second packet is
pHeader->PresentationTime.Time = llClockTime
Where ‘llClockTime’ is the current stream time and it is as below:
llClockTime = m_Clock->GetCorrelatedTime(&llSystemTime);
Then the presentation of the first packet is
pHeader->PresentationTime.Time = llClockTime - llFrameDuration
where ‘llFrameDuration’ is the duration time of the first packet.
And the duration time is calculated as below:
llFrameDuration= OnePacketLength * 10000000 / AVG_BYTESPRESEC;
If the presentation time is as above, then the audio data is abnormal. However, if I don’t divide the audio packet into 2 packets, it sounds well.
Does anyone know how to fix the audio presentation time? How to separate one audio packet into 2 small packets for AVStream driver?
Any suggestion would be greatly appreciated!
Thanks a lot!
Pan.hsu
The following are my audio process routine:
NTSTATUS
CAudioCapturePin::
Process(
IN LARGE_INTEGER &liTimeout
)
{
pStreamPointer = KsPinGetLeadingEdgeStreamPointer( m_Pin,
KSSTREAM_POINTER_STATE_LOCKED );
…
PKSSTREAM_HEADER pHeader = pStreamPointer->StreamHeader;
PBYTE pData = static_cast< PBYTE >( pHeader->Data );
RtlCopyMemory( pData, pAudio, dwAudioLen);
pHeader->DataUsed = dwAudioLen;
// If a clock has been assigned, timestamp the packets with the
// time shown on the clock.
if( m_Clock != NULL )
{
PKS_FRAME_INFO FrameInfo = reinterpret_cast
<pks_frame_info>(pHeader + 1);
LONGLONG llClockTime ;
//llClockTime : current stream time
llClockTime = m_Clock->GetCorrelatedTime(&llSystemTime);
pHeader -> PresentationTime.Numerator =
pHeader -> PresentationTime.Denominator = 1;
//for adjust time stamp ( OneFrameLength is 120 bytes)
//llFrameDuration= the duratioin of a packet with 120 bytes
LONGLONG llFrameDuration;
llFrameDuration= = OneFrameLength * 10000000 / AVG_BYTESPRESEC;
if( PacketNum==1 )
pHeader->PresentationTime.Time = llClockTime - llFrameDuration; //---------------> first packet
else
pHeader->PresentationTime.Time = llClockTime; //---------------> second packet
}
KsStreamPointerUnlock( pStreamPointer, TRUE );
}
return STATUS_SUCCESS;
}</pks_frame_info>