Android8.0平台Camera monkey拷机卡死异常

最近在处理一个camera monkey拷机卡死的问题,卡死在停止录像的画面。

monkey测试命令

monkey -p com.android.camera2 --throttle 300 --ignore-crashes --ignore-timeouts --ignore-security-exceptions -v -v -v 50000000 &

camera卡住的时候,把mediaserver进程的backtrace打印可发现卡在AudioSource::waitOutstandingEncodingFrames_l函数中,异常LOG:

debugger -b [pid]

...

[04-28 16:35:43]"Binder:237_4" sysTid=2571

[04-28 16:35:43] #00 pc 00018cd8 /system/lib/libc.so (syscall+28)

[04-28 16:35:43] #01 pc 00047529 /system/lib/libc.so (__pthread_cond_timedwait(pthread_cond_internal_t*, pthread_mutex_t*, bool, timespec const*)+102)

[04-28 16:35:43] #02 pc 000a7adb /system/lib/libstagefright.so (android::AudioSource::waitOutstandingEncodingFrames_l()+54)

[04-28 16:35:43] #03 pc 000a787b /system/lib/libstagefright.so (android::AudioSource::reset()+82)

[04-28 16:35:43] #04 pc 000a77e9 /system/lib/libstagefright.so (android::AudioSource::~AudioSource()+44)

[04-28 16:35:43] #05 pc 000a794d /system/lib/libstagefright.so (android::AudioSource::~AudioSource()+12)

[04-28 16:35:43] #06 pc 0000ac5b /system/lib/libutils.so (android::RefBase::decStrong(void const*) const+70)

[04-28 16:35:43] #07 pc 00049c4f /system/lib/libmediaplayerservice.so (android::StagefrightRecorder::~StagefrightRecorder()+206)

[04-28 16:35:43] #08 pc 00049e7b /system/lib/libmediaplayerservice.so (android::StagefrightRecorder::~StagefrightRecorder()+2)

[04-28 16:35:43] #09 pc 00047eef /system/lib/libmediaplayerservice.so (android::MediaRecorderClient::release()+34)

...

把调试LOG打开,并跟踪其代码流程如下

238 1538 V AudioSource: Set stoptime: 80223601 us

代码:

StagefrightRecorder.cpp

status_t StagefrightRecorder::stop() {

int64_t stopTimeUs = systemTime() / 1000;

for (const auto &source : { mAudioEncoderSource, mVideoEncoderSource }) {

if (source != nullptr && OK != source->setStopTimeUs(stopTimeUs)) {

ALOGW("Failed to set stopTime %lld us for %s",

(long long)stopTimeUs, source->isVideo() ? "Video" : "Audio");

}

}

AudioSource.cpp

status_t AudioSource::setStopTimeUs(int64_t stopTimeUs) {

mStopSystemTimeUs = stopTimeUs;

return OK;

}

238 1523 V AudioSource: dataCallbackTimestamp: 80264993 us

238 1523 V AudioSource: Drop Audio frame at 80264993 stop time: 80223601 us

代码:

AudioSource.cpp

if (mStopSystemTimeUs != -1 && timeUs >= mStopSystemTimeUs) {

ALOGV("Drop Audio frame at %lld stop time: %lld us",

(long long)timeUs, (long long)mStopSystemTimeUs);

mNoMoreFramesToRead = true;

mFrameAvailableCondition.signal();

return OK;

}

238 1538 I AudioSource: read: mBuffersReceived is empty and mNoMoreFramesToRead

代码

AudioSource.cpp

status_t AudioSource::read(

MediaBuffer **out, const ReadOptions * /* options */) {

Mutex::Autolock autoLock(mLock);

*out = NULL;

if (mInitCheck != OK) {

ALOGI("read: mInitCheck not OK");

return NO_INIT;

}

while (mStarted && mBuffersReceived.empty()) {

mFrameAvailableCondition.wait(mLock);

if (mNoMoreFramesToRead) {

ALOGI("read: mBuffersReceived is empty and mNoMoreFramesToRead");

return OK;

}

}

此处当mBuffersReceived为空且mNoMoreFramesToRead被设置时候,直接返回.

04-30 07:57:53.687 238 1538 V MediaCodecSource: puller (audio) posting EOS

04-30 07:57:53.730 238 1513 V MediaCodecSource: puller (audio) reached EOS

04-30 07:57:53.730 238 1513 V MediaCodecSource: encoder (audio) reached EOS

代码

MediaCodecSource.cpp

case kWhatPull:

status_t err = mSource->read(&mbuf);

if (mbuf != NULL) {

mNotify->post();

msg->post();

} else {

handleEOS();

}

MediaCodecSource.cpp

void MediaCodecSource::Puller::handleEOS() {

ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video");

// android::CallStack cs("Puller::handleEOS");

sp msg = mNotify->dup();

msg->setInt32("eos", 1);

msg->post();

}

因为从source获取到的buffer为空,于是判定为EOS,并进行EOS处理。

04-30 07:57:54.126 238 1513 I MediaCodecSource: encoder (audio) stopping

04-30 07:57:54.126 238 1513 I MediaCodecSource: encoder (audio) already stopped

代码

MediaCodecSource.cpp

case kWhatStop:

{

ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio");

if (mOutput.lock()->mEncoderReachedEOS) {

// if we already reached EOS, reply and return now

ALOGI("encoder (%s) already stopped",

mIsVideo ? "video" : "audio");

(new AMessage)->postReply(replyID);

break;

}

mPuller->stop();

由于先前已经接收到EOS信息,因此MediaCodecSource在处理kWhatStop时候直接返回。

此次问题发生的流程大致如下

应用层发出停止录像的请求

AudioSource把该停止录像的请求之后的音频数据丢弃,并设置mNoMoreFramesToRead

MediaCodecSource从AudioSource读取到buffer为NULL,于是判定为EOS,并进行相关处理,但并不清除MediaCodecSource::Puller::Queue.mReadBuffers

MediaCodecSource接收到kWhatStop消息,发现已经进行了EOS处理,于是放弃执行Puller.stop(它会对Puller::Queue.mReadBuffers执行flush操作),直接返回。

AudioSource最后进行reset时候,调用waitOutstandingEncodingFrames_l去等待直到所有buffer被释放,但有些buffer在Audio Puller::Queue.mReadBuffers没有释放,于是在进程被hold在此处。

暂时的修改方案是

在第4步处理kWhatStop消息时候,即使已经进行过EOS处理,仍然执行Puller.stop,以确保Puller::Queue.mReadBuffers为空。

android烤机按键变慢,Android8.0平台Camera monkey拷机卡死异常相关推荐

  1. android拷机工具,Android8.0平台Camera monkey拷机卡死异常解决方案

    android8.0平台camera monkey拷机卡死异常 最近在处理一个camera monkey拷机卡死的问题,卡死在停止录像的画面. monkey测试命令 monkey -p com.and ...

  2. android摄像头监控打电话卡死,Android应用开发Android8.0平台Camera monkey拷机卡死异常解决方案...

    本文将带你了解Android应用开发Android8.0平台Camera monkey拷机卡死异常解决方案,希望本文对大家学Android有所帮助. Android8.0平台Camera monkey ...

  3. Android8.0平台Camera monkey拷机卡死异常

    Android8.0平台Camera monkey拷机卡死异常 最近在处理一个camera monkey拷机卡死的问题,卡死在停止录像的画面. monkey测试命令 monkey -p com.and ...

  4. Android8.0前后Camera架构对比(二十三)

    Android 的相机硬件抽象层 (HAL) 可将Camera2中较高层级的相机框架 API 连接到底层的相机驱动程序和硬件.相机子系统包括相机管道组件的实现,而相机 HAL 可提供用于实现您的这些组 ...

  5. android 跳转动画黑屏,Android8.0 适配解决页面跳转过程出现短暂黑屏的问题

    小菜在适配 Android8.0 过程中,遇到很多问题,有很多很常见的问题,今天来整理一下页面跳转时黑屏的问题. 问题猜测 猜测一: 显示 Activity 页面之前会优先开启一个 Starting ...

  6. 小米4刷Android8.0过程,小米一代神机抢先刷入Android8.0 体验震惊了

    纵观国内的手机厂商,能够打造出出色硬件的很多,但在系统层面却很难这么说.作为国内公认最出色的Android第三方定制系统之一,MIUI绝对是小米手机的一大法宝,即使是几年前的小米手机都能够得到官方系统 ...

  7. Android 8.0 学习(22) Android8.0平台Eng版本中显示界面切换闪红框

    Android O平台Eng版本中显示界面切换闪红框 1.问题 Version >= Android O1 在Android O平台Eng版本中,在切换显示界面.开任何apk.操作按钮等操作时, ...

  8. android百度地图 okhttp,阳光沙滩-Android8.0用OkHttp3报错,而andoird9.0和10.0不报错

    仅管报错,但程序仍然能正常运行. 用红线标出来的是它认为有错的地方 2020-03-14 12:33:18.747 5759-5759/com.cxb.webshop I/zygote: Reject ...

  9. android打开本地音乐播放器,Android8.0打开手机所有的音乐播放器

    上篇文章录取的电话音频,这是用来读取播放方法 //path 文件路径 public void play(String path) { Intent intent = new Intent(Intent ...

最新文章

  1. python设计选择题代码_《Python程序设计》试题库
  2. 配置纯净版Debian
  3. KDD2021 放榜,6 篇论文带你了解阿里妈妈AI技术
  4. openssh rpm包_100台CentOS7要升级OpenSSH怎么办?
  5. 网页左右怎么划分_UI基础汇总——网页设计规范
  6. list 转 json,以及 json 解析
  7. python可以实现那些功能_30 个Python代码实现的常用功能,精心整理版
  8. Matlab求解空间曲线的切线和法平面
  9. 社交电商概念与特点,十大社交电商平台及产业链模式图解
  10. tif文件在html打开,tif格式怎么打开(打开tif文件的操作方法)
  11. 数组中a与a[0]的区别
  12. “你公众号被封了!”
  13. 软件工程毕业设计选题java_2021年计算机专业Java相关毕业设计如何选题更容易通过...
  14. 云集微店亿级交易额下的Order子系统架构演变
  15. Dhrystone简介
  16. Linux系统安装开源版PyMOL
  17. 网络安全防守方应该遵循得建设原则有哪些
  18. 万龙链——广应用场景,强价值背书,催生无限可能
  19. can和could的用法_can和could的用法
  20. 乐鑫科技2021提前批软件类笔试题

热门文章

  1. kafka-topics.sh工具:查看/删除/修改/创建主题
  2. java基础知识之加强
  3. java aspose.words 生成word目录和更新目录
  4. OS + Unix FreeBSD / MacOSX Snow Leopard 10.6.3-8 / MacBook Pro / apple / MC373
  5. IE浏览器低版本判断及升级提示
  6. 【产品经理学习笔记 | 巨详细】2.规划阶段——2.1需求收集:用户访谈和问卷调查方式
  7. java 中实现一行一行地读文件和一行一行地追加写文件
  8. 【Filecoin周报-62】倒计时1天,太空竞赛准备怎么样了?
  9. 2020.8.26丨Nanopore甲基化测序产品概述
  10. 【老九学堂】【C++】编码命名规范