StageFright

news/2024/7/5 23:16:39 标签: playback, audio, header, api

StageFright的目录所在:2.3.3_src/frameworks/base/media/libstagefright中。

1.Video Playback的流程。

stagefright中AwesomePlayer可用来播放音视频。AwesomePlayer提供许多API,可以让上层的应用程序来调用。

在Stagefright中,播放音视频的处理流程如下。

(1)将档案的绝对路径指定给mUri


status_t AwesomePlayer::setDataSource(const char* uri, ...)
{
  return setDataSource_l(uri, ...);
}

status_t AwesomePlayer::setDataSource_l(const char* uri, ...)
{
  mUri = uri;
}

(2)启动mQueue,作为event handler

status_t AwesomePlayer::prepare()
{
  return prepare_l();
}

status_t AwesomePlayer::prepare_l()
{
  prepareAsync_l();

  while (mFlags & PREPARING)
  
{
   
mPreparedCondition.wait(mLock);
  }
}

status_t AwesomePlayer::prepareAsync_l()
{
  mQueue.start();

  mFlags |= PREPARING;
  mAsyncPrepareEvent = new AwesomeEvent(
                             this
                             &AwesomePlayer::onPrepareAsyncEvent);
  mQueue.postEvent(mAsyncPrepareEvent);
}


(3) onPrepareAsyncEvent被触发。

void AwesomePlayer::onPrepareAsyncEvent()
{
  finishSetDataSource_l();

  initVideoDecoder(); ...... (3.3)
  initAudioDecoder();

}

status_t AwesomePlayer::finishSetDataSource_l()
{
  dataSource = DataSource::CreateFromURI(mUri.string(), ...);
  sp<MediaExtractor> extractor =
                     MediaExtractor::Create(dataSource); ..... (3.1)

  return setDataSource_l(extractor); .........................(3.2)
}

(3.1)解析mUri所指定的文件,并且根据其header来选择extractor(解析器)

sp<MediaExtractor> MediaExtractor::Create(const sp<DataSource> &source, ...)
{
  source->sniff(&tmp, ...);
  mime = tmp.string();

  
if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
  
{
    return new MPEG4Extractor(source);
  }
  
else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG))
  
{
    return new MP3Extractor(source);
  }
  
else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
  
{
    return new AMRExtractor(source);
  }
}

(3.2)使用extractor对文件做音视频分离。(mVideo Track/mAudio Track)

status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor)
{
  for (size_t i = 0; i < extractor->countTracks(); ++i)
  {
    sp<MetaData> meta = extractor->getTrackMetaData(i);

    CHECK(meta->findCString(kKeyMIMEType, &mime));

    if (!haveVideo && !strncasecmp(mime, "video/", 6))
    {
      setVideoSource(extractor->getTrack(i));
      haveVideo = true;
    }
    else if (!haveAudio && !strncasecmp(mime, "audio/", 6))
    {
      setAudioSource(extractor->getTrack(i));
      haveAudio = true;

    }
  }
}

void AwesomePlayer::setVideoSource(sp<MediaSource> source)
{
  mVideoTrack = source;
}


(3.3)根据mVideoTrack中的编码类型来选择视频解码器。

status_t AwesomePlayer::initVideoDecoder()
{
  mVideoSource = OMXCodec::Create(mClient.interface(),
                                  mVideoTrack->getFormat(),
                                  false,
                                  mVideoTrack
);

}

(4)将mVideoEvent放入mQueue中,开始解码播放,并交给mVideoRenderer来画出。、


status_t AwesomePlayer::play()
{
  return play_l();
}

status_t AwesomePlayer::play_l()
{
  postVideoEvent_l();
}

void AwesomePlayer::postVideoEvent_l(int64_t delayUs)
{
  mQueue.postEventWithDelay(mVideoEvent, delayUs);
}

void AwesomePlayer::onVideoEvent()
{
  mVideoSource->read(&mVideoBuffer, &options);
  [Check Timestamp]
  mVideoRenderer->render(mVideoBuffer);

  postVideoEvent_l();
}

http://www.niftyadmin.cn/n/1285045.html

相关文章

经典面试题-什么是Spring inner beans?

在Spring框架中&#xff0c;无论何时bean被使用时&#xff0c;当仅被调用了一个属性。一个明智的做法是将这个bean声明为内部bean。内部bean可以用setter注入“属性”和构造方法注入“构造参数”的方式来实现。 比如&#xff0c;在我们的应用程序中&#xff0c;一个Customer类…

Codeforces Round #619 (Div. 2)

A 题目 You are given three strings a, b and c of the same length n. The strings consist of lowercase English letters only. The i-th letter of a is ai, the i-th letter of b is bi, the i-th letter of c is ci. For every i (1≤i≤n) you must swap (i.e. exchan…

经典面试题-Spring框架中的单例Beans是线程安全的么?

Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。 但实际上&#xff0c;大部分的Spring bean并没有可变的状态(比如Service类和DAO类)&#xff0c;所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean…

HDU 1495 非常可乐 最简单的的解决方案

Description 大家一定觉的运动以后喝可乐是一件很惬意的事情&#xff0c;但是seeyou却不这么认为。因为每次当seeyou买了可乐以后&#xff0c;阿牛就要求和seeyou一起分享这一瓶可乐&#xff0c;而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子&#xff0c;它们的容…

int,int32_t,int64_t

这些事跨平台编程导致的&#xff1b; 一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小&#xff0c;只规定级别。作下比较&#xff1a; 16位平台 char 1个字节8位 short 2个字节16位 int 2…

问题 1255: [蓝桥杯][算法提高]能量项链

在Mars星球上&#xff0c;每个Mars人都随身佩带着一串能量项链。在项链上有 N颗能量珠。能量珠是一颗有头标记与尾标记的珠子&#xff0c;这些标记对应着某个正整数。并且&#xff0c;对于相邻的两颗珠子&#xff0c;前一颗珠子的尾标记一定等于后一颗珠子的头标 记。因为只有这…

stagefright + omx小结

StageFright工作流程 1 先简单的看一下stagefright是怎么工作的, stagefright使用event来进行驱动,event调度器和event运行在同一个线程中,播放器向队列插入event来驱动整个解码流程,event调度器的工作抽象流程如下: 1&#xff0e; 检测队列是否为空,为空则等待event的插入 …

输入十六进制转十进制输出

#include <stdio.h> int main() { int x,y; for(;scanf("%x%x",&x,&y) ! EOF;) { printf("%d\n",xy); } return 0; } &#xff08;输入字符&#xff0c;用if 或 switch 一一匹配&#xff0c;但不能AC&#xff09;