Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1078756
  • 博文数量: 165
  • 博客积分: 3900
  • 博客等级: 中校
  • 技术积分: 1887
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-06 15:15
文章分类

全部博文(165)

文章存档

2020年(3)

2019年(8)

2017年(2)

2016年(8)

2015年(14)

2013年(15)

2012年(32)

2011年(11)

2010年(14)

2009年(7)

2008年(20)

2007年(31)

分类: Android平台

2013-08-09 15:18:31

Android多媒体开发笔记[8]-- AwesomePlayer基本框架及播放流程 2012-10-19 11:04:30     我来说两句       作者:tx3344     我要投稿

1.通过setDataSource 指定播放器的数据源。可以是URI或者fd.可以是http:// 、rtsp://、本地地址或者本地文件描述符fd。其最终调用是将上层传递来的参数转化为DataSource,为下一步的demux提供数据支持。
2.在真正Prepare功能函数onPrepareAsyncEvent()会调用finishSetDataSource_l。通过第一步产生的DataSource来生成extractor,因为封装的格式很多,所以需要通过DataSource的信息,去创建不同的extractor。
[cpp] 
extractor = MediaExtractor::Create( 
                dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str()); 
[cpp] 
if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4) 
        || !strcasecmp(mime, "audio/mp4")) { 
    ret = new MPEG4Extractor(source); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 
    ret = new MP3Extractor(source, meta); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB) 
        || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 
    ret = new AMRExtractor(source); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { 
    ret = new FLACExtractor(source); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) { 
    ret = new WAVExtractor(source); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) { 
    ret = new OggExtractor(source); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) { 
    ret = new MatroskaExtractor(source); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) { 
    ret = new MPEG2TSExtractor(source); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) { 
    // Return now.  WVExtractor should not have the DrmFlag set in the block below. 
    return new WVMExtractor(source); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) { 
    ret = new AACExtractor(source, meta); 
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) { 
    ret = new MPEG2PSExtractor(source); 

3.得到extractor之后,通过setVideoSource() setAudioSource()产生独立的mVideoTrack(视频)、mAudioTrack(音频)数据流,分别为音视频解码器提供有各自需要的数据流。
其实extractor和mVideoTrack、mAudioTrack就组成了播放器模型中的demuxer部分。把封装格式里面的音视频流拆分出来,分别的送给音视频解码器。
4.接下来就是initVideoDecoder() initAudioDecoder().依赖上面产生的mVideoTrack(视频)、mAudioTrack(音频)数据流。生成了mVideoSource和mAudioSource这两个音视频解码器。不同类型匹配不同的解码器。
[cpp] 
mVideoSource = OMXCodec::Create( 
            mClient.interface(), mVideoTrack->getFormat(), 
            false, // createEncoder 
            mVideoTrack, 
            NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL); 
 mAudioSource = OMXCodec::Create( 
                mClient.interface(), mAudioTrack->getFormat(), 
                false, // createEncoder 
                mAudioTrack); 
    } 

mVideoSource、mAudioSource组成了播放器模型中的decoder部分。
android中的编解码器部分用的是openmax,以后会深入了解。openma x是一套标准接口,各家硬件厂商都可以遵循这个标准来做自己的实现,发挥自己芯片特性。然后提供给android系统来用。因为大部分的机顶盒芯片产品硬件的编解码是它的优势,可以把这种优势完全融入到android平台中。以后手机高清视频硬解码也会是个趋势。
5.解码完之后的数据就要输出了。AwesomePlayer分别用了mVideoRenderer做视频输出、mAudioPlayer做音频输出。他们分别调用android图像和音频的相关服务。这俩部分是android平台中十分重要的2块,以后会深入了解。
mVideoRenderer和mAudioPlayer就组成了播放器中output的部分。

综上AwesomePlayer的整体框架和流程就清晰了,其实也脱离不了DataSource、demux、decoder、output这4大部分。接下来会分别了解每个部分是怎么实现的。

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