Chinaunix首页 | 论坛 | 博客
  • 博客访问: 355817
  • 博文数量: 107
  • 博客积分: 927
  • 博客等级: 大尉
  • 技术积分: 865
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-13 17:50
文章分类

全部博文(107)

文章存档

2014年(2)

2013年(13)

2012年(16)

2011年(76)

分类: Java

2011-04-13 18:00:37

講完了audiovideo的處理流程,接下來要看的是audiovideo同步化(synchronization)的問題。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;

  ...
}


AwesomePlayerAudioPlayer取得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);

  ...
}


阅读(781) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~