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

上传人:M****1 文档编号:431974165 上传时间:2022-11-23 格式:DOCX 页数:15 大小:16.43KB
返回 下载 相关 举报
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视频播放数据读取的流程htt p:/ tml这里分析Android4.0.1本地视频数据读取的流程,其他过程类似当播放条件准备妥当之后,就要循环进行读取视频的原始数据放到 MediaBuffer,将MediaBuffer中的数据输送到解码器中解码,解码后的数据放 到MediaBuffer中,在将这MediaBuffer中的数据进行render显示。本文主要侧重读取原始数据的流程,主要是代码跟踪,不夹杂个人分析,有些 mpeg4的算法不懂。1: onVideoEvent中开始读取数据,具体代码如下:void AwesomePlayer:onVideoEvent() if (!mVi

2、deoBuffer) MediaSource:ReadOptions options;if (mSeeking != NO_SEEK) LOGV(seeking to %lld us (%.2f secs), mSeekTimeUs, mSeekTimeUs / 1E6);optio ns.se tSeekTo(mSeekTimeUs,mSeeking = SEEK_VIDE0_0NLY? MediaSource:ReadOptions:SEEK_NEXT_SYNCMediaSource:ReadOptions:SEEK_CLOSEST_SYNC);for (;) statuserr 二 mV

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

4、lse;int64_t seekTimeUs;ReadOptions:SeekMode seekMode;if (options & optionsgetSeekTo(&seekTimeUs, &seekMode) seeking = true;if (seeking) CODEC_LOGV(seeking to %lld us (%.2f secs), seekTimeUs, seekTimeUs / 1E6);CHECK(seekTimeUs = 0);mSeekTimeUs = seekTimeUs;mSeekMode = seekMode;drainInp ut Buffers。;si

5、ze_t index = *mFilledBuffers.begin(); / A list of indices into mPortStatuskPortlndexOutput filled with data.mFilledBuffers.erase(mFilledBuffers.begin();BufferInfo*info二&mPortBufferskPortlndexOutput .editltemAt(index);CHECK_EQ(int)info-mStatus, (int)OWNED_BY_US);info-mStatus = OWNED_BY_CLIENT;info-mM

6、ediaBuffer-add_ref();*buffer = info-mMediaBuffer;return OK;两点:a, drainInputBuffers开始了数据的读取;b , mFilledBuffers从这个队列中读取已经解码后的数据放入到传入的 MediaBuffer 中,mFilledBuffers 队 列 中 的 MediaBuffer 就 是drainlnputBuffers 中写进去的3: 跟到 drainlnputBuffer 中看看bool OMXCodec:drainInputBuffer(BufferInfo *info) CODEC_LOGV(calling

7、 emptyBuffer with codec specific data); statuserr = mOMX-emp ty Buffer(mNode, info-mBuffer, 0, size,OMX_BUFFERFLAG_ENDOFFRAMEOMX_BUFFERFLAG_CODECCONFIG,0);CHECK_EQ(err, (stat us_ t)0K);info-mStatus = 0WNED_BY_C0MP0NENT;status_t err;bool signalEOS = false;int64_t timestampUs = 0;size_t offset 二 0;int

8、32_t n 二 0;for (;) MediaBuffer *srcBuffer;if (mSeekTimeUs = 0) MediaSource:ReadOptions options;options.setSeekTo(mSeekTimeUs, mSeekMode); mSeekTimeUs = T;mSeekMode = ReadOptions:SEEK_CLOSEST_SYNC;err = mSource-read(&srcBuffer, &options);if (err = OK) int64_t targetTimeUs;if (srcBuffer-meta_data()-fi

9、ndlnt64(kKeyTargetTime, &targetTimeUs)& targetTimeUs = 0) CODEC_LOGV(targetTimeUs = %lld us, targetTimeUs); mTargetTimeUs = targetTimeUs; else mTargetTimeUs = -1;CODEC_LOGV(Calling emptyBuffer on buffer %p (length %d),ti mes tamp %lld us (%.2f secs),info-mBuffer, offset,timestampUs, timestampUs / 1E

10、6);err = mOMXemptyBuffer(mNode, infomBuffer, 0, offse t, flags, timestampUs);info-mStatus = 0WNED_BY_C0MP0NENT;return true;两点:a, 调用 err = mSource-read(&srcBuffer, &options);从原始文件中读取原始 数据,b, 往srcBuffer中读取数据前后,都调用omx转移已经读取到该info中的数据, 目的是解码,解码后的数据就房子了 mFilledBuffers这个队列中;4:针对mpeg4类型的视频,上面的read函数调用的是MPE

11、G4Source的read函 数,核心代码如下:status_t MPEG4Source:read(MediaBuffer *out, const ReadOptions *options) *out = NULL;int64_t seekTimeUs;ReadOptions:SeekMode mode;if (options & optionsgetSeekTo(&seekTimeUs, &mode) if分支是用于有seek的流程1: 首先找到 seek time 附近的 samplelndex;2:然后找到samplelndex附近的关键帧的syncSamplelndex; 3:然后 s

12、yncSamplelndex 找到具体的 sampleTime,sampleTime 就是 目前需要播放到的位置;4 : mSampleTable-getMetaDataForSample 调用 这个函 数找到 sampleTime 时间的 offset 和 size;5 : 有了 offset 和 size 之后剩下就是调用 mDataSource-readAt(offset, (uint8_t *)mBuffer-data(), size);读取数据 放到buffer中去了;uint32_t findFlags = 0;switch (mode) case ReadOptions:SEEK

13、_PREVIOUS_SYNC:findFlags = SampleTable:kFlagBefore;break;case ReadOptions:SEEK_NEXT_SYNC:findFlags = SampleTable:kFlagAfter;break;case ReadOptions:SEEK_CLOSEST_SYNC:case ReadOptions:SEEK_CLOSEST:findFlags = SampleTable:kFlagClosest;break;default:CHECK(!Should not be here.);break; uint32_t sampleInde

14、x;status err = mSampleTable-findSampleAtTime(seekTimeUs * mTimescale / 1000000,&sampleindex, findFlags);uint32_t syncSamplelndex;if (err = OK) err = mSampleTable-findSyncSampleNear(sampleindex, &syncSamplelndex, findFlags);uint32_t sampleTime;if (err = OK) err = mSampleTable-getMetaDataForSample(sam

15、pleindex, NULL, NULL, &sampleTime);if (mode = ReadOptions:SEEK_CLOSEST) targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;mCurrentSamplelndex = syncSamplelndex;off64_t offset;size_t size;uint32_t cts;bool isSyncSample;bool newBuffer = false; if (mBuffer = NULL) newBuffer = true;statuserr =mSampleTable-getMeta

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

当前位置:首页 > 机械/制造/汽车 > 综合/其它

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