关于OpenSL ES播放音频数据的一个奇怪的问题

Author:lihaiping1603@aliyun.com

最近用业余时间做了一个android平台的播放器sdk,其中视频用的opengl es,音频用的opensl es 做渲染,其中整个播放器在音视频同步的过程中,使用的视频同步到音频的方式,以音频作为主时钟。

今天在测试的过程中发现一个奇怪的问题,我音频数据的填充,使用了单独的音频线程,这其中的实现,主要参考ijk的实现代码和方式。

整个流程方式:我在音频播放的过程中设置的200ms的播放缓冲区给底层队列,当我把音频数据缓冲区填满以后,就wait_timeout(1s),如果在wait的过程中,底层有回调,就会signal,从而唤醒wait函数,然后再查询缓冲区大小,是否可以填充数据,如果可以填充数据的话,就填充数据进去,同时在填充数据的函数中,通过计算音频的pts和缓冲区的剩余数据大小,来更新当前的音频播放时钟位置。其中问题就是出在更新音频时钟位置的这个地方,我们计算剩余缓冲区的数据大小的时候,通过调用这个函数来获取底层数据的缓冲区延时:

通过计算state.count的计数来获取这个延时时间。

那么现在的问题现象是这样的,在视频正常播放的过程中,我填充了200ms满的缓冲区音频数据去播放,在填充数据线程中wait,然后在大概过了120ms之后,底层回调:

发送信号唤醒wait函数,然后我去拷贝音频数据,拷贝完数据之后,计算时钟,这个时候查询底层缓冲区数据还剩多少,发现state.count=17,也就是说填满的时候20,现在获取还剩17,意思是中间难道只消耗了30ms的音频数据?不太可能啊,正常播放的情况下,120ms应该消耗120ms的音频数据才对啊,为啥这个地方只消耗了30ms的数据呢?

经过进一步的排查和分析,发现了问题,如果经过了120ms的播放时间,底层实际消耗的音频数据是为120ms,而他开始回调,并连续回调12次。但第一次回调的时候,我们就唤醒了wait函数,这个时候我们去拷贝数据,而从唤醒到拷贝数据完成,并重新获取底层缓冲区大小的的这个过程,因为时间很短,短到他12次的连续回调,实际上只完成了3次回调,这个时候我们就去获取了state.count,发现它比之前只少了3次,所以误认为这个时间他只消耗了30ms的数据。因为state.count这个底层计数,他回调一次-1,并不会真正的实时反映实际的数据消耗过程。

那么我的代码和ijk的貌似看上去一致啊,为啥他的不会出现这个问题?后面思考发现问题所在,ijk在播放填充的数据线程中,通过回调给上层,他在上层的实现中实现了音频数据的解码,也就是正是这个解码函数产生的影响,他的这个耗时,完全足以让底层的音频连续回调,回调完毕,所以再去拿数据以后,就是正确的结果。

本人主要是个人对调试的理解和记录,仅供参考。

转载请注明出处:https://www.cnblogs.com/lihaiping/p/11739836.html

(原)关于OpenSL ES播放音频数据的一个奇怪的问题的更多相关文章

  1. Android OpenSL ES 开发:Android OpenSL 录制 PCM 音频数据

    一.实现说明 OpenSL ES的录音要比播放简单一些,在创建好引擎后,再创建好录音接口基本就可以录音了.在这里我们做的是流式录音,所以需要用至少2个buffer来缓存录制好的PCM数据,这里我们可以 ...

  2. Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)

    项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...

  3. iOS 9音频应用播放音频之第一个ios9音频实例2

    iOS 9音频应用播放音频之第一个ios9音频实例2 ios9音频应用关联 iOS9音频应用中对于在主视图上添加的视图或控件,在使用它们时必须要与插座变量进行关联.ios9插座变量其实就是为主视图中的 ...

  4. iOS 9音频应用播放音频之第一个ios9音频实例

    iOS 9音频应用播放音频之第一个ios9音频实例 第一个ios9音频实例 为了让开发者可以对上面的内容有更加深入的了解,本节将实现播放音频的第一个实例.在此实例中会涉及到项目的创建.界面设计.关联以 ...

  5. Android音视频学习第7章:使用OpenSL ES进行音频解码

    /* * *这里使用了transcode-1.1.7对wav文件进行解码.然后使用opensl es进行播放 * */ //用到的变量和结构体 WAV wav; //wav文件指针 SLObjectI ...

  6. OpenSL ES: 利用OpenSL ES播放一个存在于SDcard上的PCM文件

    native-lib.cpp #include <jni.h> #include <string> #include <SLES/OpenSLES.h> #incl ...

  7. 【Android 多媒体应用】使用MediaCodec解码使用AudioTrack播放音频数据

    1.MainActivity.java import android.app.Activity; import android.os.Bundle; import android.os.Environ ...

  8. 【Android 多媒体应用】使用MediaRecoder录制,MediaPlayer播放音频数据

    1.MainActivity.java import android.annotation.TargetApi; import android.app.Activity; import android ...

  9. Android OpenSL ES 开发:OpenSL ES利用SoundTouch实现PCM音频的变速和变调

    缘由 OpenSL ES 学习到现在已经知道 OpenSL ES 不仅能播放和录制PCM音频数据,还能改变声音大小.设置左声道或右声道播放.还能变速播放,可谓是播放音频的王者.但是变速有一点不好的就是 ...

随机推荐

  1. V-rep(1)

    第一次课堂作业,需要导入网格三维模型,对齐坐标系,然后在各个关节添加jiont,实现外观模型和运动仿真模型的分离. 1.首先导入模型.导入模型可能是一个整体模型(装配好的),也可能是单个(mesh)网 ...

  2. 1.探索性数据分析(EDA,Exploratory Data Analysis)

    一.数据探索 1.数据读取 遍历文件夹,读取文件夹下各个文件的名字:os.listdir() 方法:用于返回指定的文件夹包含的文件或文件夹的名字的列表.这个列表以字母顺序. 它不包括 '.' 和'.. ...

  3. Django如何与JQuery进行数据通信?

    index.html: 下面form的action属性表示当提交表单时,向何处发送表单数据 <script src="https://code.jquery.com/jquery-3. ...

  4. 理解迭代器,生成器,yield,可迭代对象

    原文:https://foofish.net/iterators-vs-generators.html 本文源自RQ作者的一篇博文,原文是Iterables vs. Iterators vs. Gen ...

  5. 图论 - PAT甲级 1013 Battle Over Cities C++

    PAT甲级 1013 Battle Over Cities C++ It is vitally important to have all the cities connected by highwa ...

  6. maven 查看依赖树结构命令mvn dependency:tree

    使用maven 管理项目的依赖,可以使用如下命令查看依赖树结构: mvn dependency:tree 如下图是使用idea的终端执行命令的局部图: 也可以使用如下命令将输出定向到某个文件,这样就可 ...

  7. CGLIB和Java动态代理的区别(笔记)

    java常用知识点: 1.Java动态代理只能够对接口进行代理,不能对普通的类进行代理(因为所有生成的代理类的父类为Proxy,Java类继承机制不允许多重继承):CGLIB能够代理普通类:2.Jav ...

  8. nginx rewrite规则说明

    格式:rewrite regex replacement [flag] * rewrite配置可以在server.location以及if配置段内生效 * regex是用于匹配URI的正则表达式,其不 ...

  9. Mercurial 的hook使用

    1. Handling repository events with hooks可以通过Mercurial版本管理工具提供的hooks机制来处理repo的各种事件,从而实现对Mercurial的扩展, ...

  10. OpenFOAM——冲击斜坡

    本算例来自<ANSYS Fluid Dynamics Verification Manual>中的VMFL045: Oblique Shock Over an Inclined Ramp ...