然后我们的东东就搞定了。
第二个函数:writeFrameBuf这个函数是什么时候用的呢?我们前面看MIO的时候就已经知道MIO的数据传递是通过队列的方式,消息和数据可以再一个队列里传输。在MIO的writeAsync函数中有这样的一个case:
case PVMI_MEDIAXFER_FMT_TYPE_DATA :
switch(aFormatIndex)
{
case PVMI_MEDIAXFER_FMT_INDEX_FMT_SPECIFIC_INFO:
……………………
case PVMI_MEDIAXFER_FMT_INDEX_DATA:
//data contains the media bitstream.
//Verify the state
if (iState!=STATE_STARTED)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
(0,"AndroidSurfaceOutput::writeAsync: Error - Invalid state"));
status=PVMFErrInvalidState;
}
else
{
//printf("V WriteAsync { seq=%d, ts=%d }\n", data_header_info.seq_num, data_header_info.timestamp);
// Call playback to send data to IVA for Color Convert
status = writeFrameBuf(aData, aDataLen, data_header_info);
PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
(0,"AndroidSurfaceOutput::writeAsync: Playback Progress - frame %d",iFrameNumber++));
}
break;
这个地方就开始调用我们的画屏幕的函数。这个时候就是我们接受到一帧数据的时候,注意我们这里基本上音频和视频的同步在NODE框架中已经做了,这里能够收到数据,叫表明一定是要显示的数据,不用考虑什么音视频同步了。
OSCL_EXPORT_REF PVMFStatus AndroidSurfaceOutput::writeFrameBuf(uint8* aData, uint32 aDataLen, const PvmiMediaXferHeader& data_header_info)
{
if (mSurface == 0) return PVMFFailure;
if (++mFrameBufferIndex == kBufferCount) mFrameBufferIndex = 0;
iColorConverter->Convert(aData, static_cast<uint8*>(mFrameHeap->base()) + mFrameBuffers[mFrameBufferIndex]);
// post to SurfaceFlinger
mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);
return PVMFSuccess;
}
这个函数其实很简单,直接把对应的数据转换到我们显示屏支持的,然后直接postBuffer即可显示。
看下面的一个函数:
// post the last video frame to refresh screen after pause
void AndroidSurfaceOutput::postLastFrame()
{
mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);
}
把数据显示在屏幕上。在暂停的时候,这个函数就可以调用,我们的视频会不变。
OSCL_EXPORT_REF void AndroidSurfaceOutput::closeFrameBuf()
{
LOGV("closeFrameBuf");
if (!mInitialized) return;
mInitialized = false;
if (mSurface.get()) {
LOGV("unregisterBuffers");
mSurface->unregisterBuffers();
mSurface.clear();
}
// free frame buffers
LOGV("free frame buffers");
for (int i = 0; i < kBufferCount; i++) {
mFrameBuffers[i] = 0;
}
// free heaps
LOGV("free mFrameHeap");
mFrameHeap.clear();
// free color converter
if (iColorConverter != 0)
{
LOGV("free color converter");
delete iColorConverter;
iColorConverter = 0;
}
}
这个函数前面已经说过,是一个简单的清空操作。
OSCL_EXPORT_REF bool AndroidSurfaceOutput::GetVideoSize(int *w, int *h) {
*w = iVideoDisplayWidth;
*h = iVideoDisplayHeight;
return iVideoDisplayWidth != 0 && iVideoDisplayHeight != 0;
}
返回长宽。