openstage转

Android-StageFright之数据流的封装和AwesomePlayer流程  

2012-01-06 18:04:01|  分类: android media |  标签:awesomeplayer  |字号 订阅

数据流的封装

一、

由数据源DataSource生成MediaExtractor。

通过MediaExtractor::Create(dataSource)来实现。Create方法通过两步来生成相应的MediaExtractor:

1、通过dataSource->sniff来探测数据类型

2、生成相应的Extractor:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 
if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)               || !strcasecmp(mime, "audio/mp4")) {           return new MPEG4Extractor(source);       } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {           return new MP3Extractor(source, meta);       } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)               || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {           return new AMRExtractor(source);       } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {           return new WAVExtractor(source);       } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {           return new OggExtractor(source);       } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {           return new MatroskaExtractor(source);       } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {           return new MPEG2TSExtractor(source);       }

二、

接下来,通过以下代码把音视频轨道分离:

1 2 3 4 5 6 7 8 9 10 11 
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;

生成mVideoTrack和mAudioTrack两个MediaSource。

三、

到目前为止我们得到的这两个MediaSource只具有parser功能,没有decode功能。还需要对这两个MediaSource做进一步的包装:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 
mVideoSource = OMXCodec::Create(               mClient.interface(), mVideoTrack->getFormat(),               false, // createEncoder               mVideoTrack,               NULL, flags);   mAudioSource = OMXCodec::Create(                   mClient.interface(), mAudioTrack->getFormat(),                   false, // createEncoder                   mAudioTrack);

这回又获取了两个MediaSource。它们具有parse和decode功能。当调用MediaSource.start()方法后,它的内部就会开始从数据源获取数据并解析,等到缓冲区满后便停止。在AwesomePlayer里就可以调用MediaSource的read方法读取解码后的数据。

对于mVideoSource来说:

读取的数据。

1 
mVideoSource->read(&mVideoBuffer, &options)

交给显示模块进行渲染。

1 
mVideoRenderer->render(mVideoBuffer);

对mAudioSource来说:

用mAudioPlayer对mAudioSource进行封装,然后由mAudioPlayer负责读取数据和播放控制。

AwesomePlayer流程

URI,FD

DataSource

MediaExtractor

|

mVideoTrack mAudioTrack//音视频数据流

mVideoSource mAudioSource//音视频解码器

| |

mVideoBuffer mAudioPlayer

上面示意了数据由源到最终解码后的流程。

1、设置DataSource,数据源可以两种URI和FD。URI可以http://,rtsp://等。FD是一个本地文件描述符,能过FD,可以找到对应的文件。

2、由DataSource生成MediaExtractor。通过sp extractor = MediaExtractor::Create(dataSource);来实现。 MediaExtractor::Create(dataSource)会根据不同的数据内容创建不同的数据读取对象。

3、通过调用setVideoSource由MediaExtractor分解生成音频数据流(mAudioTrack)和视频数据流(mVideoTrack)。

4、 onPrepareAsyncEvent()

如果DataSource是URL的话,根据地址获取数据,并开始缓冲,直到获取到mVideoTrack和mAudioTrack。

mVideoTrack和mAudioTrack通过调用initVideoDecoder()和initAudioDecoder()来生成mVideoSource和mAudioSource这两个音视频解码器。

然后调用postBufferingEvent_l()提交事件开启缓冲。数据缓冲的执行函数是onBufferingUpdate()。

缓冲区有足够的数据可以播放时,调用play_l()开始播放。play_l()中关键是调用了postVideoEvent_l(),提交了 mVideoEvent。这个事件执行时会调用函数onVideoEvent()。这个函数通过调用 mVideoSource->read(&mVideoBuffer, &options)进行视频解码。音频解码通过mAudioPlayer实现。

视频解码器解码后通过mVideoSource->read读取一帧帧的数据,放到mVideoBuffer中,最后通过mVideoRenderer->render(mVideoBuffer)把视频数据发送到显示模块。

当需要暂停或停止时,调用cancelPlayerEvents来提交事件用来停止解码,还可以选择是否继续缓冲数据。

分享到:         
阅读(78) |  评论(0) |  引用  (0)  | 举报
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值