android视频播放数据读取的流程

上传人:第*** 文档编号:32806822 上传时间:2018-02-12 格式:DOC 页数:15 大小:71.50KB
返回 下载 相关 举报
android视频播放数据读取的流程_第1页
第1页 / 共15页
android视频播放数据读取的流程_第2页
第2页 / 共15页
android视频播放数据读取的流程_第3页
第3页 / 共15页
android视频播放数据读取的流程_第4页
第4页 / 共15页
android视频播放数据读取的流程_第5页
第5页 / 共15页
点击查看更多>>
资源描述

《android视频播放数据读取的流程》由会员分享,可在线阅读,更多相关《android视频播放数据读取的流程(15页珍藏版)》请在金锄头文库上搜索。

1、Android视频播放数据读取的流程http:/ Android4.0.1本地视频数据读取的流程,其他过程类似 当播放条件准备妥当之后,就要循环进行读取视频的原始数据放到MediaBuffer,将 MediaBuffer中的数据输送到解码器中解码,解码后的数据放到 MediaBuffer中,在将这 MediaBuffer中的数据进行 render显示。本文主要侧重读取原始数据的流程,主要是代码跟踪,不夹杂个人分析,有些mpeg4的算法不懂。1:onVideoEvent 中开始读取数据,具体代码如下:void AwesomePlayer:onVideoEvent() if (!mVideoBuf

2、fer) MediaSource:ReadOptions options;if (mSeeking != NO_SEEK) LOGV(seeking to %lld us (%.2f secs), mSeekTimeUs, mSeekTimeUs / 1E6);options.setSeekTo(mSeekTimeUs,mSeeking = SEEK_VIDEO_ONLY? MediaSource:ReadOptions:SEEK_NEXT_SYNC: MediaSource:ReadOptions:SEEK_CLOSEST_SYNC); for (;) status_t err = mVid

3、eoSource-read(&mVideoBuffer, 蓝色为核心代码,如果是正常读取,options 为 null,否则这个结构体中包含了 seek到的时间和 seek的模式,用于具体从文件中哪里开始读取,传入的mVideoBuffer引用用来装解码后的数据2:蓝色部分调用的是 OMXCodec:read函数,这个函数中核心的代码如下:status_t OMXCodec:read(MediaBuffer *buffer, const ReadOptions *options) status_t err = OK;*buffer = NULL;bool seeking = false;int

4、64_t seekTimeUs;ReadOptions:SeekMode seekMode;if (options & options-getSeekTo(&seekTimeUs, &seekMode) seeking = true;if (seeking) CODEC_LOGV(seeking to %lld us (%.2f secs), seekTimeUs, seekTimeUs / 1E6);CHECK(seekTimeUs = 0);mSeekTimeUs = seekTimeUs;mSeekMode = seekMode;drainInputBuffers();size_t in

5、dex = *mFilledBuffers.begin(); / A list of indices into mPortStatuskPortIndexOutput filled with data.mFilledBuffers.erase(mFilledBuffers.begin();BufferInfo *info = CHECK_EQ(int)info-mStatus, (int)OWNED_BY_US);info-mStatus = OWNED_BY_CLIENT;info-mMediaBuffer-add_ref();*buffer = info-mMediaBuffer;retu

6、rn OK;两点:a,drainInputBuffers 开始了数据的读取;b,mFilledBuffers 从这个队列中读取已经解码后的数据放入到传入的MediaBuffer中,mFilledBuffers 队列中的 MediaBuffer就是drainInputBuffers中写进去的3:跟到 drainInputBuffer中看看bool OMXCodec:drainInputBuffer(BufferInfo *info) CODEC_LOGV(calling emptyBuffer with codec specific data);status_t err = mOMX-empty

7、Buffer(mNode, info-mBuffer, 0, size,OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,0);CHECK_EQ(err, (status_t)OK);info-mStatus = OWNED_BY_COMPONENT;status_t err;bool signalEOS = false;int64_t timestampUs = 0;size_t offset = 0;int32_t n = 0;for (;) MediaBuffer *srcBuffer;if (mSeekTimeUs = 0)

8、MediaSource:ReadOptions options; options.setSeekTo(mSeekTimeUs, mSeekMode);mSeekTimeUs = -1;mSeekMode = ReadOptions:SEEK_CLOSEST_SYNC;err = mSource-read(if (err = OK) int64_t targetTimeUs;if (srcBuffer-meta_data()-findInt64(kKeyTargetTime, &targetTimeUs)& targetTimeUs = 0) CODEC_LOGV(targetTimeUs =

9、%lld us, targetTimeUs);mTargetTimeUs = targetTimeUs; else mTargetTimeUs = -1;CODEC_LOGV(Calling emptyBuffer on buffer %p (length %d), timestamp %lld us (%.2f secs),info-mBuffer, offset, timestampUs, timestampUs / 1E6);err = mOMX-emptyBuffer(mNode, info-mBuffer, 0, offset,flags, timestampUs);info-mSt

10、atus = OWNED_BY_COMPONENT;return true;两点:a,调用 err = mSource-read(从原始文件中读取原始数据,b,往 srcBuffer中读取数据前后,都调用 omx转移已经读取到该 info中的数据,目的是解码,解码后的数据就房子了 mFilledBuffers这个队列中;4:针对 mpeg4类型的视频,上面的 read函数调用的是 MPEG4Source的 read函数,核心代码如下:status_t MPEG4Source:read(MediaBuffer *out, const ReadOptions *options) *out = NU

11、LL;int64_t seekTimeUs;ReadOptions:SeekMode mode;if (options & options-getSeekTo(&seekTimeUs, &mode) if分支是用于有 seek的流程1:首先找到 seektime附近的 sampleIndex; 2:然后找到 sampleIndex附近的关键帧的 syncSampleIndex;3:然后 syncSampleIndex找到具体的 sampleTime,sampleTime 就是目前需要播放到的位置;4:mSampleTable-getMetaDataForSample 调用这个函数找到sampl

12、eTime时间的 offset和 size;5:有了 offset和 size之后剩下就是调用 mDataSource-readAt(offset, (uint8_t *)mBuffer-data(), size);读取数据放到 buffer中去了;uint32_t findFlags = 0;switch (mode) case ReadOptions:SEEK_PREVIOUS_SYNC:findFlags = SampleTable:kFlagBefore;break;case ReadOptions:SEEK_NEXT_SYNC:findFlags = SampleTable:kFla

13、gAfter;break;case ReadOptions:SEEK_CLOSEST_SYNC:case ReadOptions:SEEK_CLOSEST:findFlags = SampleTable:kFlagClosest;break;default:CHECK(!Should not be here.);break; uint32_t sampleIndex;status_t err = mSampleTable-findSampleAtTime(seekTimeUs * mTimescale / 1000000,uint32_t syncSampleIndex;if (err = O

14、K) err = mSampleTable-findSyncSampleNear(sampleIndex, uint32_t sampleTime;if (err = OK) err = mSampleTable-getMetaDataForSample(sampleIndex, NULL, NULL, if (mode = ReadOptions:SEEK_CLOSEST) targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;mCurrentSampleIndex = syncSampleIndex; off64_t offs

15、et;size_t size;uint32_t cts;bool isSyncSample;bool newBuffer = false;if (mBuffer = NULL) newBuffer = true;status_t err =mSampleTable-getMetaDataForSample(mCurrentSampleIndex, &offset, &size, &cts, if (err != OK) return err;err = mGroup-acquire_buffer(if (err != OK) CHECK(mBuffer = NULL);return err; if (!mIsAVC | mWantsNALFragments) if (newBuffer) ssize_t num_bytes_read =mDataSource-readAt(offset, (uint8_t *)mBuffer-data(), size);CHECK(mBuffer != NULL);mBuffer-set_range(0, size);mBuffer-meta_data()-clear

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 工程造价

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号