Stagefright 之 Audio和Video同步

来源:互联网 发布:华为手机查看网络制式 编辑:程序博客网 时间:2024/05/16 05:41

Stagefright之七

                                                        ——AudioVideo同步

       之前分别介绍了audiovideo的处理流程,那么audiovideo是如何同步的。在Opencore中,通过设置一个主 clock audiovideo就以此为参考输出。而在Stagefright中,audio的输出是透过callback函数来驱动,video则根据audiotimestamp来做同步。以下是详细的说明:

 

(1) callback函数驱动AudioPlayer读取译码后的数据时,AudioPlayer会取得两个时间戳 -- mPositionTimeMediaUsmPositionTimeRealUs

 

 

 

size_t AudioPlayer::fillBuffer(data, size)

{

  ...

 

  mSource->read(&mInputBuffer, ...);

 

  mInputBuffer->meta_data()->findInt64(kKeyTime, &mPositionTimeMediaUs);

  mPositionTimeRealUs = ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) / mSampleRate;

 

  ...

}

 

mPositionTimeMediaUs是数据里面所载明的时间戳(timestamp)mPositionTimeRealUs则是播放此数据的实际时间(依据frame numbersample rate得出)

 

 

(2) Stagefright中的video便依据从AudioPlayer得出来之两个时间戳的差值,作为播放的依据

 

void AwesomePlayer::onVideoEvent()

{

  ...

 

  mVideoSource->read(&mVideoBuffer, ...);

 

 

  mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs);

 

  mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs);

  mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;

 

  nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;

  latenessUs = nowUs - timeUs;

 

  ...

}

 

AwesomePlayer AudioPlayer取得realTimeUs(mPositionTimeRealUs)mediaTimeUs( mPositionTimeMediaUs),并算出其差值mTimeSourceDeltaUs

 

 

(3) 最后我们将该video数据做排程

 

void AwesomePlayer::onVideoEvent()

{

  ...

 

  if (latenessUs > 40000)

  {

    mVideoBuffer->release();

    mVideoBuffer = NULL;

 

    postVideoEvent_l();

    return;

  }

 

  if (latenessUs < -10000)

  {

    postVideoEvent_l(10000);

    return;

  }

 

  mVideoRenderer->render(mVideoBuffer);

 

  ...

}

原创粉丝点击