输出流下溢后无法接收到MaoscPlayCompete()回调
文章信息
KIS000622
- 开发伙伴平台:
S60 2nd Edition and FP1, FP2, FP3
S60 3rd Edition and FP1
- 详细描述
CMdaAudioOutputStream使用回调函数(MMdaAudioOutputStreamCallback)通知客户端执行回调。根据SDK文档记载,MaoscPlayComplete的回调将在所有缓冲都发送完毕后执行。但MaoscPlayComplete()在实际执行时只能通过显式调用CMdaAudioOutputStream::Stop()激活,并不是文档中所记载的当所有buffer都发送完毕,输出流已经下溢后才产生的。
- 如何解决
当输出流下溢后,将继续等待新的buffer到来。这时唯一释放流的方式就是调用CMdaAudioOutputStream::Stop()。因为下溢时也没有通知,因此客户端需要做一些判断以便了解流是否停止。特别需要了解buffer是否是最后缓冲。当知道已经是最后缓冲时,在使用MaoscBufferCopied拷贝到服务器端之后就需要检测,并处理流的停止。
在S60第二版手机上,不能直接在MaoscBufferCopied()调用CMdaAudioOutputStream::Stop()方法。相反客户端需要启动一个低优先级的活动对象(CIdle),当它完成时再调用Stop()方法。
下列代码演示了如何使用活动对象停止输出流
void CAudioStreamEngine::ConstructL()
{
...
// Construct the active object (CIdle) used for stopping the stream
iStop = CIdle::NewL( EPriorityIdle );
}
void CAudioStreamEngine::MaoscBufferCopied( TInt aError, const TDesC8& aBuffer )
{
if( aError == KErrNone )
{
// Compare the copied buffer to the known last buffer
if( &aBuffer == iLastBuffer )
{
// Playback is complete:
// Start the active object that will stop the stream
iStop->Start( TCallBack(BackgroundStop, this) );
return;
}
// Write the next playback buffer to the stream
else
{
iOutputStream->WriteL( GetNextBuffer() );
}
}
else
{
// Error handling
}
}
TInt CAudioStreamEngine::BackgroundStop( TAny *aStream ) // static member function
{
return ((CAudioStreamEngine*)aStream)->Stop();
}
TBool CAudioStreamEngine::Stop()
{
iOutputStream->Stop(); // will result in MaoscPlayComplete() call
return EFalse;
}
注意:S60第三版中,CMdaAudioOutputStream::Stop()方法可以直接在MaoscBufferCopied()中调用。


(no comments yet)